IOSS 2.0
Ioss_GroupingEntity.h
Go to the documentation of this file.
1// Copyright(C) 1999-2025 National Technology & Engineering Solutions
2// of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
3// NTESS, the U.S. Government retains certain rights in this software.
4//
5// See packages/seacas/LICENSE for details
6
7#pragma once
8
9#include "ioss_export.h"
10
11#include "Ioss_CodeTypes.h" // for Complex
12#include "Ioss_DatabaseIO.h" // for DatabaseIO
13#include "Ioss_EntityType.h" // for EntityType
14#include "Ioss_Field.h" // for Field, Field::RoleType, etc
15#include "Ioss_FieldManager.h" // for FieldManager, NameList
16#include "Ioss_Property.h" // for Property
17#include "Ioss_PropertyManager.h" // for PropertyManager
18#include "Ioss_State.h" // for State
19#include "Ioss_VariableType.h" // for component_count()
20#include <cstddef> // for size_t, nullptr
21#include <cstdint> // for int64_t
22#include <string> // for string
23#include <vector> // for vector
24
25#ifdef SEACAS_HAVE_KOKKOS
26#include <Kokkos_Core.hpp> // for Kokkos::View
27#endif
28
29namespace Ioss {
30
31 /** \brief Base class for all 'grouping' entities.
32 * The following derived classes are typical:
33 *
34 * -- NodeSet -- grouping of nodes (0d topology)
35 *
36 * -- EdgeSet -- grouping of edges (1d topology)
37 *
38 * -- FaceSet -- grouping of faces (2d topology) [Surface]
39 *
40 * Similarly, there is:
41 *
42 * -- NodeBlock -- grouping of 'similar' nodes (same degree of freedom, ...)
43 *
44 * -- ElementBlock -- grouping of 'similar' elements (same element topology,
45 * attributes, ...)
46 * 0d, 1d, 2d, 3d topology possible -- e.g., sphere, bar, quad, hex
47 *
48 * A Region is also a grouping entity, except that its list of subentites
49 * are other GroupingEntities. That is, it maintains a list of NodeBlocks,
50 * ElementBlocks, NodeLists, CommLists and Surfaces. [Similar to the
51 * "Composite Pattern" in Design Patterns] All interface to GroupingEntities
52 * is through the Region class; clients of the IO subsystem have no direct
53 * access to the underlying GroupingEntities (other than the Region).
54 *
55 * Each GroupingEntity contains:
56 *
57 * -- name
58 *
59 * -- MeshEntities of the specified topological dimension
60 *
61 * -- Optional attributes, either global (applied to the groupingentity), or
62 * unique value(s) to be applied to each subentity.
63 *
64 * -- Data items
65 */
66 class IOSS_EXPORT GroupingEntity
67 {
68 public:
69 friend class Property;
70
71 GroupingEntity() = default;
72 GroupingEntity(DatabaseIO *io_database, const std::string &my_name, int64_t entity_count);
73 GroupingEntity(const GroupingEntity &other);
75
76 virtual ~GroupingEntity();
77
79
81 void set_database(DatabaseIO *io_database);
82 void reset_database(DatabaseIO *io_database);
83 virtual void delete_database();
84
85 /** Return the GroupingEntity pointer of the "object" that this
86 * entity is contained in. For example, a SideBlock would
87 * return the SideSet that "owns" the SideBlock.
88 * Most GroupingEntities would return the containing Region
89 * A region would return itself(?)
90 * A NodeBlock containing the subset of nodes in a StructuredBlock
91 * would return that StructuredBlock.
92 */
93 IOSS_NODISCARD virtual const GroupingEntity *contained_in() const;
94
95 /** \brief Get name of entity.
96 *
97 * This short-circuits the process of getting the name via the property.
98 * \returns The same information as: entity->get_property("name").get_string()
99 */
100 IOSS_NODISCARD const std::string &name() const { return entityName; }
101
102 /** \brief Set the name of the entity.
103 *
104 * \param[in] new_name The new name of the entity.
105 */
106 void set_name(const std::string &new_name) { entityName = new_name; }
107
108 /** \brief Get a generated name based on the type of the entity and the id.
109 *
110 * For example, element block 10 would return "block_10"
111 * This is the default name if no name is assigned in the mesh database.
112 * \returns The generic name.
113 */
114 IOSS_NODISCARD std::string generic_name() const;
115
116 /** Determine whether a name is an alias for this entity.
117 *
118 * \param[in] my_name Determine whether this name is an alias for this entity.
119 * \returns True if input name is an alias for this entity.
120 */
121 IOSS_NODISCARD bool is_alias(const std::string &my_name) const;
122
123 /** \brief Get list of blocks that the entities in this GroupingEntity "touch".
124 *
125 * For a SideSet, returns a list of the element blocks that the
126 * elements in the set belong to.
127 * For others, it returns an empty vector.
128 * Entries are pushed onto the "block_members" vector, so it will be
129 * appended to if it is not empty at entry to the function.
130 */
131 virtual void block_membership(Ioss::NameList & /* block_members */) {}
132
133 IOSS_NODISCARD std::string get_filename() const;
134
135 /** \brief Get the name of the particular type of entity.
136 *
137 * \returns The name of the particular type of entity.
138 */
139 IOSS_NODISCARD virtual std::string type_string() const = 0;
140
141 /** \brief Get a short name of the particular type of entity.
142 *
143 * \returns The short name of the particular type of entity.
144 */
145 IOSS_NODISCARD virtual std::string short_type_string() const = 0;
146
147 /** \brief What does this entity contain
148 *
149 * \returns The name of the thing this entity contains.
150 */
151 IOSS_NODISCARD virtual std::string contains_string() const = 0;
152
153 /** \brief Get the EntityType, which indicates the particular type of GroupingEntity this is.
154 *
155 * \returns The particular EntityType of this GroupingEntity.
156 */
157 IOSS_NODISCARD virtual EntityType type() const = 0;
158
159 // ========================================================================
160 // PROPERTIES
161 // ========================================================================
162 // Property-related information....
163 // Just forward it through to the property manager...
164 void property_add(const Property &new_prop);
165 void property_erase(const std::string &property_name);
166 IOSS_NODISCARD bool property_exists(const std::string &property_name) const;
167 IOSS_NODISCARD Property get_property(const std::string &property_name) const;
168 IOSS_NODISCARD int64_t get_optional_property(const std::string &property,
169 int64_t optional_value) const;
170 IOSS_NODISCARD std::string get_optional_property(const std::string &property_name,
171 const std::string &optional_value) const;
173 int property_describe(NameList *names) const;
175 int property_describe(Ioss::Property::Origin origin, NameList *names) const;
176 IOSS_NODISCARD size_t property_count() const;
177 /** Add a property, or change its value if it already exists with
178 a different value */
179 void property_update(const std::string &property, int64_t value) const;
180 void property_update(const std::string &property, const std::string &value) const;
181
182 // ========================================================================
183 // FIELDS
184 // ========================================================================
185 // Just forward these through to the field manager...
186 void field_add(Field new_field);
187 void field_erase(const std::string &field_name);
188 void field_erase(Field::RoleType role);
189 IOSS_NODISCARD bool field_exists(const std::string &field_name) const;
190 IOSS_NODISCARD Field get_field(const std::string &field_name) const;
191 IOSS_NODISCARD const Field &get_fieldref(const std::string &field_name) const;
192 int field_describe(NameList *names) const;
194 int field_describe(Field::RoleType role, NameList *names) const;
196 IOSS_NODISCARD size_t field_count() const;
197 IOSS_NODISCARD size_t field_count(Field::RoleType role) const;
198
199 IOSS_NODISCARD bool check_for_duplicate(const Ioss::Field &new_field) const;
200
201 // Put this fields data into 'data'.
202
203 // Returns number of entities for which the field was read.
204 // Assumes 'data' is large enough to hold all values.
205 int64_t get_field_data(const std::string &field_name, void *data, size_t data_size) const;
206
207 int64_t put_field_data(const std::string &field_name, void *data, size_t data_size) const;
208
209 // Zero-copy API. *IF* a field is zero-copyable, then this function will set the `data`
210 // pointer to point to a chunk of memory of size `data_size` bytes containing the field
211 // data for the specified field. If the field is not zero-copyable, then the `data`
212 // pointer will point to `nullptr` and `data_size` will be 0.
213 int64_t get_field_data(const std::string &field_name, void **data, size_t *data_size) const;
214
215 // Put this fields data into the specified std::vector space.
216 // Returns number of entities for which the field was read.
217 // Resizes 'data' to size needed to hold all values.
218 template <typename T>
219 int64_t get_field_data(const std::string &field_name, std::vector<T> &data) const;
220
221 template <typename T>
222 int64_t put_field_data(const std::string &field_name, const std::vector<T> &data) const;
223 template <typename T>
224 int64_t put_field_data(const std::string &field_name, std::vector<T> &data) const;
225
226#ifdef SEACAS_HAVE_KOKKOS
227 // Get and put this field's data into the specified Kokkos::View.
228 // Returns the number of entities for which the field was read.
229 // Resizes 'data' to size needed to hold all values;
230 // however, any Views that were previously created referencing the same
231 // underlying memory allocation as 'data' will remain the original size.
232 template <typename T, typename... Args>
233 int64_t get_field_data(const std::string &field_name, Kokkos::View<T *, Args...> &data) const;
234
235 template <typename T, typename... Args>
236 int64_t get_field_data(const std::string &field_name, Kokkos::View<T **, Args...> &data) const;
237
238 template <typename T, typename... Args>
239 int64_t put_field_data(const std::string &field_name, Kokkos::View<T *, Args...> &data) const;
240
241 template <typename T, typename... Args>
242 int64_t put_field_data(const std::string &field_name, Kokkos::View<T **, Args...> &data) const;
243#endif
244
245 /** Get the number of bytes used to store the INT data type
246 *
247 * \returns The number of bytes.
248 */
250 {
251 if (database_ == nullptr || get_database()->int_byte_size_api() == 4) {
252 return Ioss::Field::INT32;
253 }
254
255 return Ioss::Field::INT64;
256 }
257
258 IOSS_NODISCARD unsigned int hash() const { return hash_; }
259
260 IOSS_NODISCARD int64_t entity_count() const;
261 int64_t reset_entity_count(int64_t new_entity_count) const;
262
263 // COMPARE GroupingEntities
264 IOSS_NODISCARD bool operator!=(const GroupingEntity &rhs) const;
265 IOSS_NODISCARD bool operator==(const GroupingEntity &rhs) const;
266 IOSS_NODISCARD bool equal(const GroupingEntity &rhs) const;
267
268 protected:
269 void count_attributes() const;
270
271 bool set_state(State new_state)
272 {
273 entityState = new_state;
274 return true;
275 }
276
277 // Protected to give access to Region which is the only
278 // class that should delete the database. May have to make
279 // private and provide friend...
280 void really_delete_database();
281
282 // Handle implicit properties -- These are calculated from data stored
283 // in the grouping entity instead of having an explicit value assigned.
284 // An example would be 'element_block_count' for a region.
285 // Note that even though this is a pure virtual function, an implementation
286 // is provided to return properties that are common to all grouping entities.
287 // Derived classes should call 'GroupingEntity::get_implicit_property'
288 // if the requested property is not specific to their type.
289 IOSS_NODISCARD virtual Property get_implicit_property(const std::string &my_name) const = 0;
290
293
294 virtual int64_t internal_get_field_data(const Field &field, void *data,
295 size_t data_size = 0) const = 0;
296 virtual int64_t internal_put_field_data(const Field &field, void *data,
297 size_t data_size = 0) const = 0;
298
299 virtual int64_t internal_get_zc_field_data(const Field &field, void **data,
300 size_t *data_size) const = 0;
301
302#if defined(IOSS_THREADSAFE)
303 mutable std::mutex m_;
304#endif
305
306 IOSS_NODISCARD bool equal_(const GroupingEntity &rhs, bool quiet) const;
307
308 private:
309 void verify_field_exists(const std::string &field_name, const std::string &inout) const;
310
311 std::string entityName{};
312
314
315 mutable int64_t entityCount = 0;
316 mutable int64_t attributeCount = 0;
318 unsigned int hash_ = 0;
319 };
320} // namespace Ioss
321
322/** \brief Add a property to the entity's property manager.
323 *
324 * \param[in] new_prop The property to add.
325 */
327{
328 properties.add(new_prop);
329}
330
331/** \brief Remove a property from the entity's property manager.
332 *
333 * Assumes that the property with the given name already exists in the property manager.
334 *
335 * \param[in] property_name The name of the property to remove.
336 *
337 */
338inline void Ioss::GroupingEntity::property_erase(const std::string &property_name)
339{
340 properties.erase(property_name);
341}
342
343/** \brief Checks if a property exists in the entity's property manager.
344 *
345 * \param[in] property_name The property to check
346 * \returns True if the property exists.
347 */
348inline bool Ioss::GroupingEntity::property_exists(const std::string &property_name) const
349{
350 return properties.exists(property_name);
351}
352
353/** \brief Get the Property from the property manager associated with the entity.
354 *
355 * \param[in] property_name The name of the property to get
356 * \returns The property
357 *
358 */
359inline Ioss::Property Ioss::GroupingEntity::get_property(const std::string &property_name) const
360{
361 return properties.get(property_name);
362}
363
364inline int64_t Ioss::GroupingEntity::get_optional_property(const std::string &property_name,
365 int64_t optional_value) const
366{
367 return properties.get_optional(property_name, optional_value);
368}
369
370inline std::string
371Ioss::GroupingEntity::get_optional_property(const std::string &property_name,
372 const std::string &optional_value) const
373{
374 return properties.get_optional(property_name, optional_value);
375}
376
377inline int64_t Ioss::GroupingEntity::entity_count() const { return entityCount; }
378
379inline int64_t Ioss::GroupingEntity::reset_entity_count(int64_t new_entity_count) const
380{
381 int64_t save_entity_count = entityCount;
382 entityCount = new_entity_count;
383 return save_entity_count;
384}
385
386/** \brief Get the names of all properties in the property manager for this entity.
387 *
388 * \returns The property names in the property manager.
389 */
391{
392 return properties.describe();
393}
394
395/** \brief Get the names of all properties in the property manager for this entity.
396 *
397 * \param[out] names All the property names in the property manager.
398 * \returns The number of properties extracted from the property manager.
399 */
401{
402 return properties.describe(names);
403}
404
406{
407 return properties.describe(origin);
408}
409
411 NameList *names) const
412{
413 return properties.describe(origin, names);
414}
415
416/** \brief Get the number of properties defined in the property manager for this entity.
417 *
418 * \returns The number of properties.
419 */
420inline size_t Ioss::GroupingEntity::property_count() const { return properties.count(); }
421
422// ------------------------------------------------------------------------
423
424/** \brief Remove all fields of type `role` from the entity's field manager.
425 *
426 * \param[in] role Remove all fields (if any) of type `role`
427 */
429
430/** \brief Remove a field from the entity's field manager.
431 *
432 * Assumes that a field with the given name exists in the field manager.
433 *
434 * \param[in] field_name The name of the field to remove.
435 */
436inline void Ioss::GroupingEntity::field_erase(const std::string &field_name)
437{
438 fields.erase(field_name);
439}
440
441/** \brief Checks if a field with a given name exists in the entity's field manager.
442 *
443 * \param[in] field_name The name of the field to check for.
444 * \returns True if the field exists in the entity's field manager.
445 *
446 */
447inline bool Ioss::GroupingEntity::field_exists(const std::string &field_name) const
448{
449 return fields.exists(field_name);
450}
451
452/** \brief Get a field from the entity's field manager.
453 *
454 * \param[in] field_name The name of the field to get.
455 * \returns The field object.
456 *
457 */
458inline Ioss::Field Ioss::GroupingEntity::get_field(const std::string &field_name) const
459{
460 return fields.get(field_name);
461}
462
463/** \brief Get a reference to a field from the entity's field manager.
464 *
465 * \param[in] field_name The name of the field to get.
466 * \returns A reference to the field object.
467 *
468 */
469inline const Ioss::Field &Ioss::GroupingEntity::get_fieldref(const std::string &field_name) const
470{
471 return fields.getref(field_name);
472}
473
474/** \brief Get the names of all fields in the entity's field manager.
475 *
476 * \returns All field names in the entity's field manager.
477 *
478 */
479inline Ioss::NameList Ioss::GroupingEntity::field_describe() const { return fields.describe(); }
480
481/** \brief Get the names of all fields in the entity's field manager.
482 *
483 * \param[out] names All field names in the entity's field manager.
484 * \returns The number of fields extracted from the entity's field manager.
485 *
486 */
488{
489 return fields.describe(names);
490}
491
492/** \brief Get the names of all fields of a specified RoleType in the entity's field manager.
493 *
494 * \param[in] role The role type (MESH, ATTRIBUTE, TRANSIENT, REDUCTION, etc.)
495 * \returns All field names of the specified RoleType in the entity's field manager.
496 *
497 */
499{
500 return fields.describe(role);
501}
502
503/** \brief Get the names of all fields of a specified RoleType in the entity's field manager.
504 *
505 * \param[in] role The role type (MESH, ATTRIBUTE, TRANSIENT, REDUCTION, etc.)
506 * \param[out] names All field names of the specified RoleType in the entity's field manager.
507 * \returns The number of fields extracted from the entity's field manager.
508 *
509 */
511{
512 return fields.describe(role, names);
513}
514
515/** \brief Get the number of fields in the entity's field manager.
516 *
517 * \returns The number of fields in the entity's field manager.
518 */
519inline size_t Ioss::GroupingEntity::field_count() const { return fields.count(); }
520
521/** \brief Read type 'T' field data from the database file into memory using a std::vector.
522 *
523 * \param[in] field_name The name of the field to read.
524 * \param[out] data The data.
525 * \returns The number of values read.
526 *
527 */
528template <typename T>
529int64_t Ioss::GroupingEntity::get_field_data(const std::string &field_name,
530 std::vector<T> &data) const
531{
532 verify_field_exists(field_name, "input");
533
534 Ioss::Field field = get_field(field_name);
535 field.check_type(Ioss::Field::get_field_type(static_cast<T>(0)));
536
537 data.resize(field.raw_count() * field.raw_storage()->component_count());
538 size_t data_size = data.size() * sizeof(T);
539 auto retval = internal_get_field_data(field, Data(data), data_size);
540
541 // At this point, transform the field if specified...
542 if (retval >= 0) {
543 field.transform(Data(data));
544 }
545
546 return retval;
547}
548
549/** \brief Write type 'T' field data from memory into the database file using a std::vector.
550 *
551 * \param[in] field_name The name of the field to write.
552 * \param[in] data The data.
553 * \returns The number of values written.
554 *
555 */
556template <typename T>
557int64_t Ioss::GroupingEntity::put_field_data(const std::string &field_name,
558 const std::vector<T> &data) const
559{
560 verify_field_exists(field_name, "output");
561
562 Ioss::Field field = get_field(field_name);
564 size_t data_size = data.size() * sizeof(T);
565 if (field.has_transform()) {
566 // Need non-const data since the transform will change the users data.
567 std::vector<T> nc_data(data);
568 field.transform(Data(nc_data));
569 return internal_put_field_data(field, Data(nc_data), data_size);
570 }
571
572 T *my_data = const_cast<T *>(Data(data));
573 return internal_put_field_data(field, my_data, data_size);
574}
575
576template <typename T>
577int64_t Ioss::GroupingEntity::put_field_data(const std::string &field_name,
578 std::vector<T> &data) const
579{
580 verify_field_exists(field_name, "output");
581
582 Ioss::Field field = get_field(field_name);
583 field.check_type(Ioss::Field::get_field_type(static_cast<T>(0)));
584 size_t data_size = data.size() * sizeof(T);
585 T *my_data = const_cast<T *>(Data(data));
586 field.transform(my_data);
587 return internal_put_field_data(field, my_data, data_size);
588}
589
590#ifdef SEACAS_HAVE_KOKKOS
591
592/** \brief Read field data from the database file into memory using a 1-D Kokkos:::View.
593 *
594 * \tparam T The data type.
595 * \tparam Args The other template arguments for data.
596 * \param[in] field_name The name of the field to read.
597 * \param[out] data The data.
598 * \returns The number of values read.
599 *
600 */
601template <typename T, typename... Args>
602int64_t Ioss::GroupingEntity::get_field_data(const std::string &field_name,
603 Kokkos::View<T *, Args...> &data) const
604{
605 typedef Kokkos::View<T *, Args...> ViewType;
606
607 verify_field_exists(field_name, "input");
608
609 Ioss::Field field = get_field(field_name);
610
611 // Resize the view
612 auto new_view_size = field.raw_count() * field.raw_storage()->component_count();
613 Kokkos::resize(data, new_view_size);
614 size_t data_size = new_view_size * sizeof(T);
615
616 // Create a host mirror view. (No memory allocation if data is in HostSpace.)
617 typename ViewType::HostMirror host_data = Kokkos::create_mirror_view(data);
618
619 // Extract a pointer to the underlying allocated memory of the host view.
620 T *host_data_ptr = host_data.data();
621
622 // Extract the data from disk to the underlying memory pointed to by host_data_ptr.
623 auto retval = internal_get_field_data(field, host_data_ptr, data_size);
624
625 // At this point, transform the field if specified...
626 if (retval >= 0)
627 field.transform(host_data_ptr);
628
629 // Copy the data to the device. (No op if data is in HostSpace.)
630 Kokkos::deep_copy(data, host_data);
631
632 return retval;
633}
634
635/** \brief Read field data from the database file into memory using a 2-D Kokkos:::View.
636 *
637 * \tparam T The data type
638 * \tparam Args The other template arguments for data.
639 * \param[in] field_name The name of the field to read.
640 * \param[out] data The data.
641 * \returns The number of values read.
642 *
643 */
644template <typename T, typename... Args>
645int64_t Ioss::GroupingEntity::get_field_data(const std::string &field_name,
646 Kokkos::View<T **, Args...> &data) const
647{
648 typedef Kokkos::View<T **, Args...> ViewType;
649
650 verify_field_exists(field_name, "input");
651
652 Ioss::Field field = get_field(field_name);
653
654 // Resize the view
655 int new_view_size_left = field.raw_count();
656 int new_view_size_right = field.raw_storage()->component_count();
657 Kokkos::resize(data, new_view_size_left, new_view_size_right);
658 size_t data_size = new_view_size_left * new_view_size_right * sizeof(T);
659
660 // Create and allocate an array to hold the data temporarily.
661 // This is necessary to ensure the data is placed in the correct
662 // location in the 2-D array, avoiding incorrect placement due
663 // to Views with padded dimensions.
664 T *data_array = new T[data_size];
665
666 // Create a host mirror view. (No memory allocation if data is in HostSpace.)
667 typename ViewType::HostMirror host_data = Kokkos::create_mirror_view(data);
668
669 // Extract the data from disk to the underlying memory pointed to by host_data_ptr.
670 auto retval = internal_get_field_data(field, data_array, data_size);
671
672 // At this point, transform the field if specified...
673 if (retval >= 0)
674 field.transform(data_array);
675
676 // Copy the data to the host Mirror view.
677 // The host mirror view has the same layout as the device view.
678 // For CUDA, this will be LayoutLeft. In this case, the loop order
679 // chosen here will be slower than the reversed loop order.
680 // However, The time for this extra in-memory copy is small
681 // compared with the time to copy from disk into memory.
682 for (int i = 0; i < new_view_size_left; ++i) {
683 for (int j = 0; j < new_view_size_right; ++j) {
684 host_data(i, j) = data_array[new_view_size_right * i + j];
685 }
686 }
687
688 // Delete the temporary array
689 delete[] data_array;
690
691 // Copy the data to the device. (No op if data is in HostSpace.)
692 Kokkos::deep_copy(data, host_data);
693
694 return retval;
695}
696
697/** \brief Write field data from memory into the database file using a 1-D Kokkos::View.
698 *
699 * \tparam T The data type
700 * \tparam Args The other template arguments for data.
701 * \param[in] field_name The name of the field to write.
702 * \param[in] data The data.
703 * \returns The number of values written.
704 *
705 */
706template <typename T, typename... Args>
707int64_t Ioss::GroupingEntity::put_field_data(const std::string &field_name,
708 Kokkos::View<T *, Args...> &data) const
709{
710 typedef Kokkos::View<T *, Args...> ViewType;
711
712 verify_field_exists(field_name, "output");
713
714 Ioss::Field field = get_field(field_name);
715 size_t data_size = field.raw_count() * field.raw_storage()->component_count() * sizeof(T);
716
717 // Create a host mirror view. (No memory allocation if data is in HostSpace.)
718 typename ViewType::HostMirror host_data = Kokkos::create_mirror_view(data);
719
720 // Copy the data to the host. (No op if data is in HostSpace.)
721 Kokkos::deep_copy(host_data, data);
722
723 // Extract a pointer to the underlying allocated memory of the host view.
724 T *host_data_ptr = host_data.data();
725
726 // Transform the field
727 field.transform(host_data_ptr);
728
729 // Copy the data to disk from the underlying memory pointed to by host_data_ptr.
730 return internal_put_field_data(field, host_data_ptr, data_size);
731}
732
733/** \brief Write field data from memory into the database file using a 2-D Kokkos::View.
734 *
735 * \tparam T The data type
736 * \tparam Args The other template arguments for data.
737 * \param[in] field_name The name of the field to write.
738 * \param[in] data The data.
739 * \returns The number of values written.
740 *
741 */
742template <typename T, typename... Args>
743int64_t Ioss::GroupingEntity::put_field_data(const std::string &field_name,
744 Kokkos::View<T **, Args...> &data) const
745{
746 typedef Kokkos::View<T **, Args...> ViewType;
747
748 verify_field_exists(field_name, "output");
749
750 Ioss::Field field = get_field(field_name);
751
752 int view_size_left = data.extent(0);
753 int view_size_right = data.extent(1);
754 size_t data_size = field.raw_count() * field.raw_storage()->component_count() * sizeof(T);
755
756 if (view_size_left * view_size_right * sizeof(T) != data_size) {
757 std::ostringstream errmsg;
758 errmsg << "\nERROR: View dimensions are inconsistent with field raw count or raw storage "
759 "component count"
760 << "for field" << field_name << "\n\n";
761 IOSS_ERROR(errmsg);
762 }
763
764 // Create a host mirror view. (No memory allocation if data is in HostSpace.)
765 typename ViewType::HostMirror host_data = Kokkos::create_mirror_view(data);
766
767 // Copy the data to the host. (No op if data is in HostSpace.)
768 Kokkos::deep_copy(host_data, data);
769
770 // Create and allocate an array to hold the data temporarily.
771 // This is necessary to ensure the data is taken from the correct
772 // location in the 2-D array, avoiding incorrect location due
773 // to Views with padded dimensions.
774 T *data_array = new T[data_size];
775
776 // Copy the data from the host Mirror view.
777 // The host mirror view has the same layout as the device view.
778 // For CUDA, this will be LayoutLeft. In this case, the loop order
779 // chosen here will be slower than the reversed loop order.
780 // However, The time for this extra in-memory copy is small
781 // compared with the time to copy to disk from memory.
782 for (int i = 0; i < view_size_left; ++i) {
783 for (int j = 0; j < view_size_right; ++j) {
784 data_array[view_size_right * i + j] = host_data(i, j);
785 }
786 }
787
788 // Transform the field
789 field.transform(data_array);
790
791 // Copy the data to disk from the underlying memory pointed to by data_array.
792 auto retval = internal_put_field_data(field, data_array, data_size);
793
794 // Delete the temporary array
795 delete[] data_array;
796
797 return retval;
798}
799#endif
#define IOSS_NODISCARD
Definition Ioss_CodeTypes.h:56
IOSS_NODISCARD constexpr T * Data(std::vector< T > &vec)
Definition Ioss_Utils.h:58
void IOSS_ERROR(const std::ostringstream &errmsg)
Definition Ioss_Utils.h:38
void put_field_data(std::string field_name, int local_size, size_t component_count, Entity *e)
Definition Ut_ioad.C:276
An input or output Database.
Definition Ioss_DatabaseIO.h:63
A collection of Ioss::Field objects.
Definition Ioss_FieldManager.h:35
Holds metadata for bulk data associated with a GroupingEntity.
Definition Ioss_Field.h:28
IOSS_NODISCARD const VariableType * raw_storage() const
Definition Ioss_Field.h:171
IOSS_NODISCARD bool has_transform() const
Definition Ioss_Field.h:223
BasicType
The basic data type held in the field.
Definition Ioss_Field.h:32
@ INT64
Definition Ioss_Field.h:38
@ INT32
Definition Ioss_Field.h:37
IOSS_NODISCARD size_t raw_count() const
Definition Ioss_Field.h:174
RoleType
Definition Ioss_Field.h:72
bool transform(void *data)
Definition Ioss_Field.C:312
void check_type(BasicType the_type) const
Definition Ioss_Field.C:204
static IOSS_NODISCARD Ioss::Field::BasicType get_field_type(char)
Definition Ioss_Field.h:46
Base class for all 'grouping' entities. The following derived classes are typical:
Definition Ioss_GroupingEntity.h:67
virtual IOSS_NODISCARD std::string short_type_string() const =0
Get a short name of the particular type of entity.
IOSS_NODISCARD bool equal_(const GroupingEntity &rhs, bool quiet) const
Definition Ioss_GroupingEntity.C:391
void field_add(Field new_field)
Add a field to the entity's field manager.
Definition Ioss_GroupingEntity.C:216
virtual int64_t internal_get_field_data(const Field &field, void *data, size_t data_size=0) const =0
int64_t attributeCount
Definition Ioss_GroupingEntity.h:316
IOSS_NODISCARD Ioss::Field::BasicType field_int_type() const
Definition Ioss_GroupingEntity.h:249
virtual IOSS_NODISCARD EntityType type() const =0
Get the EntityType, which indicates the particular type of GroupingEntity this is.
FieldManager fields
Definition Ioss_GroupingEntity.h:292
virtual IOSS_NODISCARD std::string type_string() const =0
Get the name of the particular type of entity.
IOSS_NODISCARD int64_t get_optional_property(const std::string &property, int64_t optional_value) const
Definition Ioss_GroupingEntity.h:364
IOSS_NODISCARD DatabaseIO * get_database() const
Definition Ioss_GroupingEntity.C:95
GroupingEntity()=default
IOSS_NODISCARD NameList property_describe() const
Get the names of all properties in the property manager for this entity.
Definition Ioss_GroupingEntity.h:390
friend class Property
Definition Ioss_GroupingEntity.h:69
IOSS_NODISCARD Property get_property(const std::string &property_name) const
Get the Property from the property manager associated with the entity.
Definition Ioss_GroupingEntity.h:359
IOSS_NODISCARD int64_t entity_count() const
Definition Ioss_GroupingEntity.h:377
GroupingEntity & operator=(const GroupingEntity &rhs)=delete
int64_t get_field_data(const std::string &field_name, void *data, size_t data_size) const
Read field data from the database file into memory using a pointer.
Definition Ioss_GroupingEntity.C:256
IOSS_NODISCARD Field get_field(const std::string &field_name) const
Get a field from the entity's field manager.
Definition Ioss_GroupingEntity.h:458
IOSS_NODISCARD bool field_exists(const std::string &field_name) const
Checks if a field with a given name exists in the entity's field manager.
Definition Ioss_GroupingEntity.h:447
std::string entityName
Definition Ioss_GroupingEntity.h:311
int64_t reset_entity_count(int64_t new_entity_count) const
Definition Ioss_GroupingEntity.h:379
IOSS_NODISCARD unsigned int hash() const
Definition Ioss_GroupingEntity.h:258
void verify_field_exists(const std::string &field_name, const std::string &inout) const
Definition Ioss_GroupingEntity.C:349
void reset_database(DatabaseIO *io_database)
Definition Ioss_GroupingEntity.C:122
virtual void delete_database()
Definition Ioss_GroupingEntity.C:67
IOSS_NODISCARD State get_state() const
Get the current Ioss::State of the entity.
Definition Ioss_GroupingEntity.C:145
virtual int64_t internal_put_field_data(const Field &field, void *data, size_t data_size=0) const =0
void field_erase(const std::string &field_name)
Remove a field from the entity's field manager.
Definition Ioss_GroupingEntity.h:436
int field_describe(NameList *names) const
Get the names of all fields in the entity's field manager.
Definition Ioss_GroupingEntity.h:487
PropertyManager properties
Definition Ioss_GroupingEntity.h:291
int64_t put_field_data(const std::string &field_name, void *data, size_t data_size) const
Write field data from memory into the database file using a pointer.
Definition Ioss_GroupingEntity.C:304
IOSS_NODISCARD const Field & get_fieldref(const std::string &field_name) const
Get a reference to a field from the entity's field manager.
Definition Ioss_GroupingEntity.h:469
IOSS_NODISCARD const std::string & name() const
Get name of entity.
Definition Ioss_GroupingEntity.h:100
bool set_state(State new_state)
Definition Ioss_GroupingEntity.h:271
void property_update(const std::string &property, int64_t value) const
Definition Ioss_GroupingEntity.C:360
void property_add(const Property &new_prop)
Add a property to the entity's property manager.
Definition Ioss_GroupingEntity.h:326
IOSS_NODISCARD bool check_for_duplicate(const Ioss::Field &new_field) const
Definition Ioss_GroupingEntity.C:176
DatabaseIO * database_
Definition Ioss_GroupingEntity.h:313
void property_erase(const std::string &property_name)
Remove a property from the entity's property manager.
Definition Ioss_GroupingEntity.h:338
IOSS_NODISCARD size_t property_count() const
Get the number of properties defined in the property manager for this entity.
Definition Ioss_GroupingEntity.h:420
int64_t entityCount
Definition Ioss_GroupingEntity.h:315
unsigned int hash_
Definition Ioss_GroupingEntity.h:318
virtual void block_membership(Ioss::NameList &)
Get list of blocks that the entities in this GroupingEntity "touch".
Definition Ioss_GroupingEntity.h:131
IOSS_NODISCARD size_t field_count() const
Get the number of fields in the entity's field manager.
Definition Ioss_GroupingEntity.h:519
virtual IOSS_NODISCARD const GroupingEntity * contained_in() const
Definition Ioss_GroupingEntity.C:75
virtual IOSS_NODISCARD std::string contains_string() const =0
What does this entity contain.
void set_database(DatabaseIO *io_database)
Definition Ioss_GroupingEntity.C:115
State entityState
Definition Ioss_GroupingEntity.h:317
void set_name(const std::string &new_name)
Set the name of the entity.
Definition Ioss_GroupingEntity.h:106
IOSS_NODISCARD bool property_exists(const std::string &property_name) const
Checks if a property exists in the entity's property manager.
Definition Ioss_GroupingEntity.h:348
virtual int64_t internal_get_zc_field_data(const Field &field, void **data, size_t *data_size) const =0
IOSS_NODISCARD NameList field_describe() const
Get the names of all fields in the entity's field manager.
Definition Ioss_GroupingEntity.h:479
A collection of Ioss::Property objects.
Definition Ioss_PropertyManager.h:36
A named value that has a known type.
Definition Ioss_Property.h:27
Origin
Definition Ioss_Property.h:30
IOSS_NODISCARD int component_count() const
Definition Ioss_VariableType.h:154
size_t data_size(const Ioss::Field &f)
Definition Iofaodel_FieldSerialization.C:17
The main namespace for the Ioss library.
Definition Ioad_DatabaseIO.C:40
State
Access states for a database.
Definition Ioss_State.h:15
@ STATE_CLOSED
Definition Ioss_State.h:22
Ioss::NameList NameList
Definition Ioss_ChangeSetFactory.h:25
EntityType
The particular type of GroupingEntity.
Definition Ioss_EntityType.h:12
std::vector< char > data
Definition cth_pressure_map.C:46