35#ifdef MAIA_EXTRA_DEBUG
36#define GRIDTREE_SANITY_CHECKS_ACCESSORS
40#ifdef GRIDTREE_SANITY_CHECKS_ACCESSORS
41#define ENSURE_VALID_ID_ACCESSOR(id) \
43 MAIA_CONTAINER_ENSURE_VALID_ID(id); \
45#define ENSURE_VALID_CHILD_POSITION_ACCESSOR(pos) \
47 MAIA_CONTAINER_ENSURE(pos >= 0 && pos < noChildrenPerNode(), \
48 "child position = " + std::to_string(pos) + " out-of-bounds [0, " \
49 + std::to_string(noChildrenPerNode()) + ")", \
52#define ENSURE_VALID_NEIGHBOR_DIR_ACCESSOR(dir) \
54 MAIA_CONTAINER_ENSURE(dir >= 0 && dir < noNeighborsPerNode(), \
55 "neighbor direction = " + std::to_string(dir) + " out-of-bounds [0, " \
56 + std::to_string(noNeighborsPerNode()) + ")", \
59#define ENSURE_VALID_COORDINATE_DIR_ACCESSOR(dir) \
61 MAIA_CONTAINER_ENSURE( \
62 dir >= 0 && dir < nDim, \
63 "coordinate direction " + std::to_string(dir) + " out-of-bounds [0, " + std::to_string(nDim) + ")", AT_); \
65#define ENSURE_VALID_PROPERTY_ACCESSOR(p) \
67 MAIA_CONTAINER_ENSURE(p != Cell::NumProperties, "Invalid property", AT_); \
69#define ENSURE_VALID_SOLVER_ID_ACCESSOR(id) \
71 MAIA_CONTAINER_ENSURE(id >= 0 && id < noSolvers(), "Invalid solver id", AT_); \
74#define ENSURE_VALID_ID_ACCESSOR(id) \
77#define ENSURE_VALID_CHILD_POSITION_ACCESSOR(pos) \
80#define ENSURE_VALID_NEIGHBOR_DIR_ACCESSOR(dir) \
83#define ENSURE_VALID_COORDINATE_DIR_ACCESSOR(dir) \
86#define ENSURE_VALID_PROPERTY_ACCESSOR(dir) \
89#define ENSURE_VALID_SOLVER_ID_ACCESSOR(id) \
108static constexpr MInt MAIA_MULTISOLVER_MAX_NO_SOLVERS = 8;
120 static constexpr MInt value() {
return std::numeric_limits<MInt>::min(); }
125 static constexpr MLong value() {
return std::numeric_limits<MLong>::min(); }
131 static constexpr MInt value() {
return std::numeric_limits<MChar>::min(); }
137 static constexpr MInt value() {
return std::numeric_limits<MUchar>::min(); }
144#ifdef MAIA_PGI_COMPILER
145 return std::numeric_limits<MFloat>::quiet_NaN();
147 return std::numeric_limits<MFloat>::signaling_NaN();
211 MLong child(const MInt id, const MInt pos) const;
234 SolverBitsetType::reference
solver(const MInt id, const MInt solverId);
235 MBool solver(const MInt id, const MInt solverId) const;
243 SolverBitsetType::reference
isLeafCell(const MInt id, const MInt solverId);
248 PropertyBitsetType::reference
hasProperty(const MInt id, const Cell p);
293 template <
class Functor,
class T>
320 resetStorage(1, m_parentIds);
321 resetStorage(noChildrenPerNode(), m_childIds);
322 resetStorage(noNeighborsPerNode(), m_neighborIds);
323 resetStorage(1, m_levels);
324 resetStorage(1, m_globalIds);
325 resetStorage(nDim, m_coordinates);
326 resetStorage(1, m_weight);
327 resetStorage(1, m_solver);
328 resetStorage(1, m_isLeafCell);
329 resetStorage(1, m_properties);
330 resetStorage(1, m_noOffsprings);
331 resetStorage(1, m_workload);
338 ENSURE_VALID_ID_ACCESSOR(
id);
339 return m_parentIds[
id];
344 ENSURE_VALID_ID_ACCESSOR(
id);
345 return m_parentIds[
id];
352 ENSURE_VALID_ID_ACCESSOR(
id);
353 return m_parentIds[
id] > -1;
361#ifdef GRIDTREE_SOA_MEMORY_LAYOUT
362#error Missing implementation for structure-of-arrays memory layout.
364 ENSURE_VALID_ID_ACCESSOR(
id);
365 ENSURE_VALID_CHILD_POSITION_ACCESSOR(pos);
366 return m_childIds[
id * noChildrenPerNode() + pos];
372#ifdef GRIDTREE_SOA_MEMORY_LAYOUT
373#error Missing implementation for structure-of-arrays memory layout.
375 ENSURE_VALID_ID_ACCESSOR(
id);
376 ENSURE_VALID_CHILD_POSITION_ACCESSOR(pos);
377 return m_childIds[
id * noChildrenPerNode() + pos];
385#ifdef GRIDTREE_SOA_MEMORY_LAYOUT
386#error Missing implementation for structure-of-arrays memory layout.
388 ENSURE_VALID_ID_ACCESSOR(
id);
389 ENSURE_VALID_CHILD_POSITION_ACCESSOR(pos);
390 return m_childIds[
id * noChildrenPerNode() + pos] > -1;
397 ENSURE_VALID_ID_ACCESSOR(
id);
398 return noChildren(
id) > 0;
404 ENSURE_VALID_ID_ACCESSOR(
id);
405 return std::any_of(&m_childIds[
id * noChildrenPerNode()], &m_childIds[
id * noChildrenPerNode() + noChildrenPerNode()],
406 [&](
MLong c) {
return c > -1 && solver(c, solverId); });
413#ifdef GRIDTREE_SOA_MEMORY_LAYOUT
414#error Missing implementation for structure-of-arrays memory layout.
416 ENSURE_VALID_ID_ACCESSOR(
id);
417 return std::count_if(&m_childIds[
id * noChildrenPerNode() + 0],
418 &m_childIds[
id * noChildrenPerNode() + noChildrenPerNode()],
419 [](
const ParallelIo::size_type childId) {
return childId > -1; });
427#ifdef GRIDTREE_SOA_MEMORY_LAYOUT
428#error Missing implementation for structure-of-arrays memory layout.
430 ENSURE_VALID_ID_ACCESSOR(
id);
431 ENSURE_VALID_NEIGHBOR_DIR_ACCESSOR(dir);
432 return m_neighborIds[
id * noNeighborsPerNode() + dir];
438#ifdef GRIDTREE_SOA_MEMORY_LAYOUT
439#error Missing implementation for structure-of-arrays memory layout.
441 ENSURE_VALID_ID_ACCESSOR(
id);
442 ENSURE_VALID_NEIGHBOR_DIR_ACCESSOR(dir);
443 return m_neighborIds[
id * noNeighborsPerNode() + dir];
451#ifdef GRIDTREE_SOA_MEMORY_LAYOUT
452#error Missing implementation for structure-of-arrays memory layout.
454 ENSURE_VALID_ID_ACCESSOR(
id);
455 ENSURE_VALID_NEIGHBOR_DIR_ACCESSOR(dir);
456 return m_neighborIds[
id * noNeighborsPerNode() + dir] > -1;
461 ENSURE_VALID_ID_ACCESSOR(
id);
462 ENSURE_VALID_NEIGHBOR_DIR_ACCESSOR(dir);
463 return hasNeighbor(
id, dir) || (hasParent(
id) && hasNeighbor(parent(
id), dir));
470 ENSURE_VALID_ID_ACCESSOR(
id);
471 return m_globalIds[
id];
476 ENSURE_VALID_ID_ACCESSOR(
id);
477 return m_globalIds[
id];
484 ENSURE_VALID_ID_ACCESSOR(
id);
490 ENSURE_VALID_ID_ACCESSOR(
id);
499#ifdef GRIDTREE_SOA_MEMORY_LAYOUT
500#error Missing implementation for structure-of-arrays memory layout.
502 ENSURE_VALID_ID_ACCESSOR(
id);
503 ENSURE_VALID_COORDINATE_DIR_ACCESSOR(dir);
504 return m_coordinates[
id * nDim + dir];
510#ifdef GRIDTREE_SOA_MEMORY_LAYOUT
511#error Missing implementation for structure-of-arrays memory layout.
513 ENSURE_VALID_ID_ACCESSOR(
id);
514 ENSURE_VALID_COORDINATE_DIR_ACCESSOR(dir);
515 return m_coordinates[
id * nDim + dir];
521#ifdef GRIDTREE_SOA_MEMORY_LAYOUT
522#error Missing implementation for structure-of-arrays memory layout.
524 ENSURE_VALID_ID_ACCESSOR(
id);
525 return &m_coordinates[
id * nDim];
532 ENSURE_VALID_ID_ACCESSOR(
id);
538 ENSURE_VALID_ID_ACCESSOR(
id);
546 ENSURE_VALID_ID_ACCESSOR(
id);
547 return m_noOffsprings[
id];
552 ENSURE_VALID_ID_ACCESSOR(
id);
553 return m_noOffsprings[
id];
560 ENSURE_VALID_ID_ACCESSOR(
id);
561 return m_workload[
id];
566 ENSURE_VALID_ID_ACCESSOR(
id);
567 return m_workload[
id];
574 ENSURE_VALID_ID_ACCESSOR(
id);
575 ENSURE_VALID_SOLVER_ID_ACCESSOR(solverId);
576 return m_solver[
id][solverId];
581 ENSURE_VALID_ID_ACCESSOR(
id);
582 ENSURE_VALID_SOLVER_ID_ACCESSOR(solverId);
583 return m_solver[
id][solverId];
588 ENSURE_VALID_ID_ACCESSOR(
id);
589 m_solver[
id].reset();
594 ENSURE_VALID_ID_ACCESSOR(
id);
595 return m_solver[
id].to_ulong();
600 ENSURE_VALID_ID_ACCESSOR(
id);
606 return m_solver[cellId][solverId];
611 ENSURE_VALID_ID_ACCESSOR(
id);
619 ENSURE_VALID_ID_ACCESSOR(
id);
620 return (m_isLeafCell[
id].any() && m_isLeafCell[
id] == m_solver[
id]);
625 ENSURE_VALID_ID_ACCESSOR(
id);
626 ENSURE_VALID_SOLVER_ID_ACCESSOR(solverId);
628 return m_isLeafCell[
id][solverId];
633 ENSURE_VALID_ID_ACCESSOR(
id);
634 ENSURE_VALID_SOLVER_ID_ACCESSOR(solverId);
636 return m_isLeafCell[
id][solverId];
641 ENSURE_VALID_ID_ACCESSOR(
id);
642 m_isLeafCell[
id].reset();
647 ENSURE_VALID_ID_ACCESSOR(
id);
648 return m_isLeafCell[
id];
654 ENSURE_VALID_ID_ACCESSOR(
id);
655 ENSURE_VALID_PROPERTY_ACCESSOR(p);
661 ENSURE_VALID_ID_ACCESSOR(
id);
662 ENSURE_VALID_PROPERTY_ACCESSOR(p);
668 ENSURE_VALID_ID_ACCESSOR(
id);
669 m_properties[
id].reset();
674 ENSURE_VALID_ID_ACCESSOR(
id);
675 return m_properties[
id].to_ulong();
680 ENSURE_VALID_ID_ACCESSOR(
id);
686 ENSURE_VALID_ID_ACCESSOR(
id);
687 return m_properties[
id].to_string();
692 ENSURE_VALID_ID_ACCESSOR(
id);
693 return m_properties[
id];
700 MAIA_CONTAINER_ENSURE(count > 0,
"Number of solvers must be greater than zero.", AT_);
701 MAIA_CONTAINER_ENSURE(count <= maxNoSolvers(),
702 "Number of solvers out-of-bounds [0, " + std::to_string(maxNoSolvers()) +
"].", AT_);
710 MAIA_CONTAINER_ENSURE(solverId >= 0 && solverId <
noSolvers(),
711 "solver id = " + std::to_string(solverId) +
" out-of-bounds [0, " + std::to_string(
noSolvers())
717 for(
MInt id = 0;
id < this->size();
id++) {
718 noNodes += solver(
id, solverId);
728 MAIA_CONTAINER_ENSURE(solverId >= 0 && solverId <
noSolvers(),
729 "solver id = " + std::to_string(solverId) +
" out-of-bounds [0, " + std::to_string(
noSolvers())
732 MAIA_CONTAINER_ENSURE(ids !=
nullptr,
"Data pointer must not be null", AT_);
736 for(
MInt id = 0;
id < this->size();
id++) {
738 if(!solver(
id, solverId)) {
755#ifdef GRIDTREE_SOA_MEMORY_LAYOUT
756#error Missing implementation for structure-of-arrays memory layout.
760 fill_invalid(m_parentIds, begin, end);
763 fill_invalid(m_childIds, begin, end, noChildrenPerNode());
766 fill_invalid(m_neighborIds, begin, end, noNeighborsPerNode());
769 fill_invalid(m_globalIds, begin, end);
772 fill_invalid(m_levels, begin, end);
775 fill_invalid(m_coordinates, begin, end, nDim);
778 fill_invalid(m_solver, begin, end);
781 fill_invalid(m_isLeafCell, begin, end);
784 fill_invalid(m_weight, begin, end);
787 fill_invalid(m_properties, begin, end);
790 fill_invalid(m_noOffsprings, begin, end);
793 fill_invalid(m_workload, begin, end);
799template <
class Functor,
class T>
801 const MInt destination) {
803#ifdef GRIDTREE_SOA_MEMORY_LAYOUT
804#error Missing implementation for structure-of-arrays memory layout.
807 copyData(source.m_parentIds, m_parentIds, c, begin, end, destination);
810 copyData(source.m_childIds, m_childIds, c, begin, end, destination, noChildrenPerNode());
813 copyData(source.m_neighborIds, m_neighborIds, c, begin, end, destination, noNeighborsPerNode());
816 copyData(source.m_globalIds, m_globalIds, c, begin, end, destination);
819 copyData(source.m_levels, m_levels, c, begin, end, destination);
822 copyData(source.m_coordinates, m_coordinates, c, begin, end, destination, nDim);
825 copyData(source.m_solver, m_solver, c, begin, end, destination);
828 copyData(source.m_isLeafCell, m_isLeafCell, c, begin, end, destination);
831 copyData(source.m_weight, m_weight, c, begin, end, destination);
834 copyData(source.m_properties, m_properties, c, begin, end, destination);
837 copyData(source.m_noOffsprings, m_noOffsprings, c, begin, end, destination);
840 copyData(source.m_workload, m_workload, c, begin, end, destination);
847 for(
MInt i = begin; i < end; i++) {
850 const MInt p = parent(i);
851 for(
MInt j = 0; j < noChildrenPerNode(); j++) {
852 if(child(p, j) == i) {
859 for(
MInt j = 0; j < noChildrenPerNode(); j++) {
861 parent(child(i, j)) = -1;
866 for(
MInt j = 0; j < noNeighborsPerNode(); j++) {
867 if(hasNeighbor(i, j)) {
868 neighbor(neighbor(i, j), oppositeNeighborDir(j)) = -1;
879 auto inMovedRange = [begin, end](
const MInt id) {
return (
id >= begin &&
id < end); };
885 for(
MInt from = begin; from < end; from++) {
886 const MInt distance = to - begin;
887 const MInt destination = from + distance;
890 if(hasParent(destination)) {
891 const MInt p = parent(destination);
892 if(inMovedRange(p)) {
893 parent(destination) += distance;
895 for(
MInt j = 0; j < noChildrenPerNode(); j++) {
896 if(child(p, j) == from) {
897 child(p, j) = destination;
904 for(
MInt j = 0; j < noChildrenPerNode(); j++) {
905 if(hasChild(destination, j)) {
906 const MInt c = child(destination, j);
907 if(inMovedRange(c)) {
908 child(destination, j) += distance;
910 parent(c) = destination;
916 for(
MInt j = 0; j < noNeighborsPerNode(); j++) {
917 if(hasNeighbor(destination, j)) {
918 const MInt n = neighbor(destination, j);
919 if(inMovedRange(n)) {
920 neighbor(destination, j) += distance;
922 neighbor(n, oppositeNeighborDir(j)) = destination;
935#undef GRIDTREE_SANITY_CHECKS_ACCESSORS
936#undef ENSURE_VALID_ID_ACCESSOR
937#undef ENSURE_VALID_CHILD_POSITION_ACCESSOR
938#undef ENSURE_VALID_NEIGHBOR_DIR_ACCESSOR
939#undef ENSURE_VALID_COORDINATE_DIR_ACCESSOR
940#undef ENSURE_VALID_PROPERTY_ACCESSOR
GridCell
Grid cell Property Labels.
void copyData(const Container_ &source, Container_ &target, Functor &&f, const MInt begin, const MInt end, const MInt dest, const MInt solverSize=1)
Copy [begin, end) range with given solver size from source to dest position of target.
void fill_invalid(Container_ &c, const MInt begin, const MInt end, const MInt solverSize=1, const T value=maia::grid::tree::Invalid< T >::value())
void resetStorage(const MInt n, Storage< T > &c)
Create new container with given size and replace original one.
void reset(const MInt capacity)
Reset tree, re-create data structures with given capacity, and set size to zero.
Class that represents grid tree and contains all relevant per-node data.
MBool hasChild(const MInt id, const MInt pos) const
Return whether node has child at given position.
MInt noChildren(const MInt id) const
Return number of children of given node.
static constexpr MInt maxNoSolvers()
Return maximum number of supported solvers.
void moveConnectivity(const MInt begin, const MInt end, const MInt to)
Update parent/children/neighbors after nodes have moved.
SolverBitsetType::reference solver(const MInt id, const MInt solverId)
Accessor for solver usage.
MFloat & weight(const MInt id)
Accessor for weight.
void propertiesFromBits(const MInt id, const MUlong bits)
Convert properties from bits.
MUlong propertiesToBits(const MInt id) const
Convert properties to bits.
maia::grid::tree::PropertyBitsetType PropertyBitsetType
MBool hasAnyNeighbor(const MInt id, const MInt dir) const
Return whether node or its parent has neighbor in given direction.
static constexpr MInt oppositeNeighborDir(const MInt dir)
Return opposite direction for given neighbor direction.
MString propertiesToString(const MInt id) const
Convert properties to string.
MBool hasParent(const MInt id) const
Return whether node has parent.
MInt & noOffsprings(const MInt id)
Accessor for noOffsprings.
void rawCopyGeneric(Functor &&c, const T &source, const MInt begin, const MInt end, const MInt destination)
Helper function for rawCopy(). Destination may refer to beginning or end of target range.
MLong & globalId(const MInt id)
Accessor for global id.
MLong & neighbor(const MInt id, const MInt dir)
Accessor for neighbor node.
PropertyBitsetType & properties(const MInt id)
Accessor for properties.
static constexpr MInt noChildrenPerNode()
Return maximum number of children per node.
maia::grid::tree::SolverBitsetType SolverBitsetType
typename Base::template Storage< T > Storage
MInt nodesBySolver(const MInt solverId, MInt *const ids) const
Generate list of node ids that are used by a given solver and return number of used nodes.
MInt noNodesBySolver(const MInt solverId) const
Return number of nodes for a given solver.
void invalidate(const MInt begin, const MInt end)
Erase range of nodes such that they contain no sensible values anymore.
MLong & parent(const MInt id)
Accessor for parent node.
MInt m_noSolvers
Number of solvers that are actively using this tree.
void resetSolver(const MInt id)
Reset all solver use.
MBool hasNeighbor(const MInt id, const MInt dir) const
Return whether node has same-level neighbor in given direction.
Storage< MFloat > m_coordinates
MFloat & workload(const MInt id)
Accessor for workload.
Storage< MLong > m_childIds
typename maia::grid::tree::Invalid< T > Invalid
MUlong solverToBits(const MInt id) const
Convert solver usage to bits.
void deleteConnectivity(const MInt begin, const MInt end)
Update parent/children/neighbors before nodes are erased.
Storage< MFloat > m_weight
Storage< SolverBitsetType > m_isLeafCell
MInt & level(const MInt id)
Accessor for level.
constexpr MInt noSolvers() const
Return currently set number of solvers.
MBool isLeafCell(const MInt id) const
Accessor for isLeafCell usage (const version).
SolverBitsetType & leafCellBits(const MInt id)
Accessor for properties.
SolverBitsetType & solverBits(const MInt id)
Accessor for properties.
Storage< MLong > m_globalIds
PropertyBitsetType::reference hasProperty(const MInt id, const Cell p)
Accessor for properties.
MLong & child(const MInt id, const MInt pos)
Accessor for child node.
void setNoSolvers(const MInt count)
Set number of solvers.
Storage< MInt > m_noOffsprings
void solverFromBits(const MInt id, const MUlong bits)
Convert solver usage from bits.
Storage< MLong > m_neighborIds
void resetIsLeafCell(const MInt id)
Reset all isLeafCell.
static constexpr MInt noNeighborsPerNode()
Return maximum number of same-level neighbors per node.
void reset()
Reset tree, re-create data structures with given capacity, and set size to zero.
MBool cellHasSolver(const MInt cellId, const MInt solverId)
Check if solver is contained for cell.
void resetProperties(const MInt id)
Reset all properties.
static constexpr MInt noProperties()
Return number of properties defined for each node.
Storage< MFloat > m_workload
MFloat & coordinate(const MInt id, const MInt dim)
Accessor for coordinates.
Storage< PropertyBitsetType > m_properties
MBool hasChildren(const MInt id) const
Return whether node has any children.
Storage< MLong > m_parentIds
Storage< SolverBitsetType > m_solver
std::basic_string< char > MString
constexpr std::underlying_type< GridCell >::type p(const GridCell property)
Converts property name to underlying integer value.
std::bitset< p(GridCell::NumProperties)> BitsetType
maia::grid::cell::BitsetType PropertyBitsetType
Underlying bitset type for property storage.
std::bitset< MAIA_MULTISOLVER_MAX_NO_SOLVERS > SolverBitsetType
Underlying bitset type for solver use storage (Note: If there are more solvers, change size here)
Namespace for auxiliary functions/classes.
static constexpr MInt value()
static constexpr MFloat value()
static constexpr MInt value()
static constexpr MLong value()
static constexpr MInt value()
static constexpr PropertyBitsetType value()