Commit 2afe51bb authored by Ján Bobot's avatar Ján Bobot
Browse files

Refactoring for mesh initialization and unit tests

- refactored a few for cycles in EntityInitializer to use ParallelFor
- modified function findEntitySeedIndex in Initializer to use find instead of insert
- modified FPMAReaderTest to use slightly bigger mesh for testing
- added a few explanatory comments
- deleted unused methods from SubentitySeedsCreator
- created specialization of Formatter in Assert.h for std::pair to avoid compilation error caused by calling inplaceExclusiveScan on array of pairs
parent cd4da1f1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -62,7 +62,7 @@ struct MeshBenchmarks
         // {"mesh-file", meshFile},
         {"config", Mesh::Config::getConfigType()},
         //{"topology", removeNamespaces( getType< typename Mesh::Config::CellTopology >() ) },
         {"world dim", std::to_string( Mesh::Config::worldDimension )},
         //{"world dim", std::to_string( Mesh::Config::worldDimension )},
         //{"real", getType< typename Mesh::RealType >()},
         //{"gid_t", getType< typename Mesh::GlobalIndexType >()},
         //{"lid_t", getType< typename Mesh::LocalIndexType >()}
+12 −7
Original line number Diff line number Diff line
@@ -217,13 +217,6 @@ fatalFailure()
#endif
}

template< typename T >
::std::stringstream& operator<<( ::std::stringstream& ss, const std::pair< T, T >& pair )
{
   ss << '(' << pair.first << ',' <<  pair.second << ')';
   return ss;
}

template< typename T >
struct Formatter
{
@@ -247,6 +240,18 @@ struct Formatter< bool >
   }
};

template< typename T, typename U >
struct Formatter< std::pair< T, U > >
{
   static std::string
   printToString( const std::pair< T, U >& pair )
   {
      ::std::stringstream ss;
      ss << '(' << pair.first << ',' <<  pair.second << ')';
      return ss.str();
   }
};

template< typename T1, typename T2 >
__cuda_callable__ void
cmpHelperOpFailure( const char* assertion,
+1 −1
Original line number Diff line number Diff line
@@ -84,7 +84,7 @@ UnorderedIndexedSet< Key, Index, Hash, KeyEqual, Allocator >::find( const Key& k
   auto iter = map.find( Key( key ) );
   if( iter == map.end() )
      return false;
   index = iter->second.index;
   index = iter->second;
   return true;
}

+48 −20
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@

#include <TNL/Meshes/MeshDetails/initializer/EntitySeed.h>
#include <TNL/Meshes/MeshDetails/initializer/SubentitySeedsCreator.h>
#include <TNL/Atomic.h>
#include <TNL/Algorithms/AtomicOperations.h>

namespace TNL {
namespace Meshes {
@@ -157,8 +159,10 @@ public:
      {
         NeighborCountsArray capacities( superentitiesCount );

         for( GlobalIndexType superentityIndex = 0; superentityIndex < capacities.getSize(); superentityIndex++ )
         Algorithms::ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, superentitiesCount, [&] ( GlobalIndexType superentityIndex ) 
         {
            capacities[ superentityIndex ] = SubentitySeedsCreatorType::getSubentitiesCount( meshInitializer, mesh, superentityIndex );
         });

         meshInitializer.template initSubentityMatrix< SuperdimensionTag::value, SubdimensionTag::value >( capacities, subentitiesCount );
      }
@@ -168,15 +172,19 @@ public:
      superentitiesCounts.setSize( subentitiesCount );
      superentitiesCounts.setValue( 0 );

      for( GlobalIndexType superentityIndex = 0; superentityIndex < superentitiesCount; superentityIndex++ )
      Algorithms::ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, superentitiesCount, [&] ( GlobalIndexType superentityIndex ) 
      {
         LocalIndexType i = 0;
         SubentitySeedsCreatorType::iterate( meshInitializer, mesh, superentityIndex, [&] ( SeedType& seed ) {
            const GlobalIndexType subentityIndex = meshInitializer.findEntitySeedIndex( seed );
            
            // SubentityIndeces for SubdimensionTag::value == 0 of non-polyhedral meshes were already set up from seeds
            if( SubdimensionTag::value > 0 || std::is_same< SuperentityTopology, Topologies::Polyhedron >::value ) 
               meshInitializer.template setSubentityIndex< SuperdimensionTag::value, SubdimensionTag::value >( superentityIndex, i++, subentityIndex );
            superentitiesCounts[ subentityIndex ]++;

            Algorithms::AtomicOperations< Devices::Host >::add( superentitiesCounts[ subentityIndex ], LocalIndexType{ 1 } );
         });
      });
      }
      
      // allocate superentities storage
      SuperentityMatrixType& matrix = meshInitializer.template getSuperentitiesMatrix< SubdimensionTag::value, SuperdimensionTag::value >();
@@ -184,7 +192,6 @@ public:
      matrix.setRowCapacities( superentitiesCounts );
      superentitiesCounts.setValue( 0 );

      // initialize superentities storage
      for( GlobalIndexType superentityIndex = 0; superentityIndex < superentitiesCount; superentityIndex++ )
      {
         for( LocalIndexType i = 0;
@@ -338,19 +345,22 @@ public:
      {
         NeighborCountsArray capacities( superentitiesCount );

         for( GlobalIndexType superentityIndex = 0; superentityIndex < capacities.getSize(); superentityIndex++ )
         Algorithms::ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, superentitiesCount, [&] ( GlobalIndexType superentityIndex ) 
         {
            capacities[ superentityIndex ] = SubentitySeedsCreatorType::getSubentitiesCount( meshInitializer, mesh, superentityIndex );
         });

         meshInitializer.template initSubentityMatrix< SuperdimensionTag::value, SubdimensionTag::value >( capacities, subentitiesCount );
      }

      for( GlobalIndexType superentityIndex = 0; superentityIndex < superentitiesCount; superentityIndex++ )
         Algorithms::ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, superentitiesCount, [&] ( GlobalIndexType superentityIndex ) 
         {
            LocalIndexType i = 0;
         SubentitySeedsCreatorType::iterate( meshInitializer, mesh, superentityIndex, [&] ( SeedType& seed ) {
            SubentitySeedsCreatorType::iterate( meshInitializer, mesh, superentityIndex, [&] ( SeedType& seed )
            {
               const GlobalIndexType subentityIndex = meshInitializer.findEntitySeedIndex( seed );
               meshInitializer.template setSubentityIndex< SuperdimensionTag::value, SubdimensionTag::value >( superentityIndex, i++, subentityIndex );
            });
         });
      }
         
      BaseType::initSuperentities( meshInitializer, mesh );
@@ -456,13 +466,13 @@ public:
      superentitiesCounts.setSize( subentitiesCount );
      superentitiesCounts.setValue( 0 );

      for( GlobalIndexType superentityIndex = 0; superentityIndex < superentitiesCount; superentityIndex++ )
      Algorithms::ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, superentitiesCount, [&] ( GlobalIndexType superentityIndex ) 
      {
         SubentitySeedsCreatorType::iterate( meshInitializer, mesh, superentityIndex, [&] ( SeedType& seed ) {
            const GlobalIndexType subentityIndex = meshInitializer.findEntitySeedIndex( seed );
            superentitiesCounts[ subentityIndex ]++;
            Algorithms::AtomicOperations< Devices::Host >::add( superentitiesCounts[ subentityIndex ], LocalIndexType{ 1 } );
         });
      });
      }

      // allocate superentities storage
      SuperentityMatrixType& matrix = meshInitializer.template getSuperentitiesMatrix< SubdimensionTag::value, SuperdimensionTag::value >();
@@ -480,6 +490,24 @@ public:
         });
      }

      // Here is an attempt of parallelization of previous for cycle, that seemingly causes some kind of race condition
      /*Algorithms::ParallelFor< Devices::Host >::exec( GlobalIndexType{ 0 }, superentitiesCount, [&] ( GlobalIndexType superentityIndex ) 
      {
         SubentitySeedsCreatorType::iterate( meshInitializer, mesh, superentityIndex, [&] ( SeedType& seed ) {
            const GlobalIndexType subentityIndex = meshInitializer.findEntitySeedIndex( seed );
            auto row = matrix.getRow( subentityIndex );

            LocalIndexType superentityCount;
            #pragma omp atomic capture
            {
               superentityCount = superentitiesCounts[ subentityIndex ];
               superentitiesCounts[ subentityIndex ]++;
            }
         
            row.setElement( superentityCount, superentityIndex, true );
         });
      });*/

      BaseType::initSuperentities( meshInitializer, mesh );
   }
};
+6 −2
Original line number Diff line number Diff line
@@ -271,9 +271,11 @@ protected:
      }

      using BaseType::findEntitySeedIndex;
      GlobalIndexType findEntitySeedIndex( const SeedType& seed )
      GlobalIndexType findEntitySeedIndex( const SeedType& seed ) const
      {
         return this->seedsIndexedSet.insert( seed );
         GlobalIndexType index = -1;
         this->seedsIndexedSet.find( seed, index );
         return index;
      }

      void initEntities( InitializerType& initializer, MeshType& mesh )
@@ -309,6 +311,8 @@ protected:
         BaseType::initEntities( initializer, mesh );
      }

      // This overload of initEntities is only called when face seeds are required for initialization.
      // Currently only polyhedral meshes use this function.
      void initEntities( InitializerType& initializer, SeedMatrixType& seeds, MeshType& mesh )
      {
         //std::cout << " Initiating entities with dimension " << DimensionTag::value << " ... " << std::endl;
Loading