diff --git a/src/TNL/Algorithms/CudaReductionKernel.h b/src/TNL/Algorithms/CudaReductionKernel.h index e79410400c241e01e8a5d614438a186545d9cb67..c3d981fd57505f8b4c7f52757acb3904c2924324 100644 --- a/src/TNL/Algorithms/CudaReductionKernel.h +++ b/src/TNL/Algorithms/CudaReductionKernel.h @@ -54,7 +54,8 @@ auto CudaReductionFunctorWrapper( Reduction&& reduction, Arg1&& arg1, Arg2&& arg // let's suppress the aforementioned warning... #ifdef __NVCC__ #pragma push -#pragma diag_suppress 2979 +#pragma diag_suppress 2979 // error number for nvcc 10.2 +#pragma diag_suppress 3123 // error number for nvcc 11.1 #endif return std::forward(reduction)( std::forward(arg1), std::forward(arg2) ); #ifdef __NVCC__ diff --git a/src/TNL/Meshes/DistributedMeshes/DistributedMesh.h b/src/TNL/Meshes/DistributedMeshes/DistributedMesh.h index 2ea6d8539d285304320a0a72a718f84e2dcb7e10..9a79f823d1379fbf4d314c9bc4bb3641fd5e9a78 100644 --- a/src/TNL/Meshes/DistributedMeshes/DistributedMesh.h +++ b/src/TNL/Meshes/DistributedMeshes/DistributedMesh.h @@ -197,11 +197,14 @@ public: << "\tMesh dimension:\t" << getMeshDimension() << "\n" << "\tCell topology:\t" << getType( typename Cell::EntityTopology{} ) << "\n" << "\tCells count:\t" << cellsCount << "\n" + << "\tFaces count:\t" << localMesh.template getEntitiesCount< Mesh::getMeshDimension() - 1 >() << "\n" << "\tvertices count:\t" << verticesCount << "\n" << "\tGhost levels:\t" << getGhostLevels() << "\n" << "\tGhost cells count:\t" << localMesh.template getGhostEntitiesCount< Mesh::getMeshDimension() >() << "\n" + << "\tGhost faces count:\t" << localMesh.template getGhostEntitiesCount< Mesh::getMeshDimension() - 1 >() << "\n" << "\tGhost vertices count:\t" << localMesh.template getGhostEntitiesCount< 0 >() << "\n" << "\tBoundary cells count:\t" << localMesh.template getBoundaryIndices< Mesh::getMeshDimension() >().getSize() << "\n" + << "\tBoundary faces count:\t" << localMesh.template getBoundaryIndices< Mesh::getMeshDimension() - 1 >().getSize() << "\n" << "\tBoundary vertices count:\t" << localMesh.template getBoundaryIndices< 0 >().getSize() << "\n"; const GlobalIndexType globalPointIndices = getGlobalIndices< 0 >().getSize(); const GlobalIndexType globalCellIndices = getGlobalIndices< Mesh::getMeshDimension() >().getSize(); diff --git a/src/TNL/Meshes/DistributedMeshes/distributeSubentities.h b/src/TNL/Meshes/DistributedMeshes/distributeSubentities.h index 2135ffcee20369212ddcabfb0337cc4fd32af7f1..39663da99c8347b9f576b94410681c32cf31d413 100644 --- a/src/TNL/Meshes/DistributedMeshes/distributeSubentities.h +++ b/src/TNL/Meshes/DistributedMeshes/distributeSubentities.h @@ -12,21 +12,134 @@ #pragma once -#include // std::iota -#include - #include #include -#include - namespace TNL { namespace Meshes { namespace DistributedMeshes { +template< typename CommunicatorType, typename GlobalIndexType > +auto +exchangeGhostEntitySeeds( typename CommunicatorType::CommunicationGroup group, + const std::vector< std::vector< GlobalIndexType > >& seeds_vertex_indices, + const std::vector< std::vector< GlobalIndexType > >& seeds_entity_offsets ) +{ + const int rank = CommunicatorType::GetRank( group ); + const int nproc = CommunicatorType::GetSize( group ); + + // exchange sizes of the arrays + Containers::Array< GlobalIndexType, Devices::Host, int > sizes_vertex_indices( nproc ), sizes_entity_offsets( nproc ); + { + Containers::Array< GlobalIndexType, Devices::Host, int > sendbuf_indices( nproc ), sendbuf_offsets( nproc ); + for( int i = 0; i < nproc; i++ ) { + sendbuf_indices[ i ] = seeds_vertex_indices[ i ].size(); + sendbuf_offsets[ i ] = seeds_entity_offsets[ i ].size(); + } + CommunicatorType::Alltoall( sendbuf_indices.getData(), 1, + sizes_vertex_indices.getData(), 1, + group ); + CommunicatorType::Alltoall( sendbuf_offsets.getData(), 1, + sizes_entity_offsets.getData(), 1, + group ); + } + + // allocate arrays for the results + std::vector< std::vector< GlobalIndexType > > foreign_seeds_vertex_indices, foreign_seeds_entity_offsets; + foreign_seeds_vertex_indices.resize( nproc ); + foreign_seeds_entity_offsets.resize( nproc ); + for( int i = 0; i < nproc; i++ ) { + foreign_seeds_vertex_indices[ i ].resize( sizes_vertex_indices[ i ] ); + foreign_seeds_entity_offsets[ i ].resize( sizes_entity_offsets[ i ] ); + } + + // buffer for asynchronous communication requests + std::vector< typename CommunicatorType::Request > requests; + + // issue all async receive operations + for( int j = 0; j < nproc; j++ ) { + if( j == rank ) + continue; + requests.push_back( CommunicatorType::IRecv( + foreign_seeds_vertex_indices[ j ].data(), + foreign_seeds_vertex_indices[ j ].size(), + j, 0, group ) ); + requests.push_back( CommunicatorType::IRecv( + foreign_seeds_entity_offsets[ j ].data(), + foreign_seeds_entity_offsets[ j ].size(), + j, 1, group ) ); + } + + // issue all async send operations + for( int i = 0; i < nproc; i++ ) { + if( i == rank ) + continue; + requests.push_back( CommunicatorType::ISend( + seeds_vertex_indices[ i ].data(), + seeds_vertex_indices[ i ].size(), + i, 0, group ) ); + requests.push_back( CommunicatorType::ISend( + seeds_entity_offsets[ i ].data(), + seeds_entity_offsets[ i ].size(), + i, 1, group ) ); + } + + // wait for all communications to finish + CommunicatorType::WaitAll( requests.data(), requests.size() ); + + return std::make_tuple( foreign_seeds_vertex_indices, foreign_seeds_entity_offsets ); +} + +template< typename CommunicatorType, typename GlobalIndexType > +auto +exchangeGhostIndices( typename CommunicatorType::CommunicationGroup group, + const std::vector< std::vector< GlobalIndexType > >& foreign_ghost_indices, + const std::vector< std::vector< GlobalIndexType > >& seeds_local_indices ) +{ + const int rank = CommunicatorType::GetRank( group ); + const int nproc = CommunicatorType::GetSize( group ); + + // allocate arrays for the results + std::vector< std::vector< GlobalIndexType > > ghost_indices; + ghost_indices.resize( nproc ); + for( int i = 0; i < nproc; i++ ) + ghost_indices[ i ].resize( seeds_local_indices[ i ].size() ); + + // buffer for asynchronous communication requests + std::vector< typename CommunicatorType::Request > requests; + + // issue all async receive operations + for( int j = 0; j < nproc; j++ ) { + if( j == rank ) + continue; + requests.push_back( CommunicatorType::IRecv( + ghost_indices[ j ].data(), + ghost_indices[ j ].size(), + j, 0, group ) ); + } + + // issue all async send operations + for( int i = 0; i < nproc; i++ ) { + if( i == rank ) + continue; + requests.push_back( CommunicatorType::ISend( + foreign_ghost_indices[ i ].data(), + foreign_ghost_indices[ i ].size(), + i, 0, group ) ); + } + + // wait for all communications to finish + CommunicatorType::WaitAll( requests.data(), requests.size() ); + + return ghost_indices; +} + +// \param preferHighRanks When true, faces on the interface between two subdomains will be owned +// by the rank with the higher number. Otherwise, they will be owned by the +// rank with the lower number. template< int Dimension, typename DistributedMesh > void -distributeSubentities( DistributedMesh& mesh ) +distributeSubentities( DistributedMesh& mesh, bool preferHighRanks = true ) { using DeviceType = typename DistributedMesh::DeviceType; using GlobalIndexType = typename DistributedMesh::GlobalIndexType; @@ -44,64 +157,65 @@ distributeSubentities( DistributedMesh& mesh ) const int rank = CommunicatorType::GetRank( mesh.getCommunicationGroup() ); const int nproc = CommunicatorType::GetSize( mesh.getCommunicationGroup() ); - // 0. exchange vertex data to prepare getVertexOwner and later on synchronizeSparse - DistributedMeshSynchronizer< DistributedMesh, 0 > synchronizer; - synchronizer.initialize( mesh ); + // 0. exchange cell data to prepare getCellOwner for use in getEntityOwner + DistributedMeshSynchronizer< DistributedMesh, DistributedMesh::getMeshDimension() > cell_synchronizer; + cell_synchronizer.initialize( mesh ); - auto getVertexOwner = [&] ( GlobalIndexType local_idx ) -> int + auto getCellOwner = [&] ( GlobalIndexType local_idx ) -> int { - const GlobalIndexType global_idx = mesh.template getGlobalIndices< 0 >()[ local_idx ]; - return synchronizer.getEntityOwner( global_idx ); + const GlobalIndexType global_idx = mesh.template getGlobalIndices< DistributedMesh::getMeshDimension() >()[ local_idx ]; + return cell_synchronizer.getEntityOwner( global_idx ); }; - // find which rank owns all vertices of its local cells - int rankOwningAllLocalCellSubvertices = nproc; - { - std::atomic its_us( true ); - mesh.getLocalMesh().template forLocal< DistributedMesh::getMeshDimension() >( [&] ( GlobalIndexType i ) mutable { - for( LocalIndexType v = 0; v < mesh.getLocalMesh().template getSubentitiesCount< DistributedMesh::getMeshDimension(), 0 >( i ); v++ ) { - const GlobalIndexType gv = mesh.getLocalMesh().template getSubentityIndex< DistributedMesh::getMeshDimension(), 0 >( i, v ); - if( getVertexOwner( gv ) != rank ) - its_us = false; - } - }); - Containers::Array< bool, Devices::Host, int > recvbuf( nproc ), sendbuf( nproc ); - sendbuf.setValue( its_us ); - CommunicatorType::Alltoall( sendbuf.getData(), 1, - recvbuf.getData(), 1, - mesh.getCommunicationGroup() ); - for( int i = 0; i < nproc; i++ ) - if( recvbuf[ i ] ) { - rankOwningAllLocalCellSubvertices = i; - break; - } - } - if( rankOwningAllLocalCellSubvertices != 0 && rankOwningAllLocalCellSubvertices != nproc - 1 ) - throw std::runtime_error("Vertices are not distributed consistently. Shared vertices on the boundaries must be assigned " - "either to the highest or to the lowest rank. Thus, either the first or the last rank must " - "own all subvertices of its local cells."); - + // algorithm for getEntityOwner: + // 0. if all neighbor cells are local, we are the owner + // -> this is still necessary, e.g. for situations like this: + // __/\__ + // if the upper rank owns the vertices on the interface, it would get the face below the /\ cape + // (1.) all vertices internal -> local entity + // (this should be covered by 0.) + // (2.) some internal vertices, other vertices on the interface -> local entity + // (this should be covered by 0.) + // 3. all vertices on the interface (i.e. some neighbor cells are local, some are ghosts) + // -> faces: there are exactly 2 ranks which share the face on their interface, pick the one with min/max number + // -> other subentities: the face owner should own all subentities of the face + // 4. any number of ghost non-interface vertices (i.e. the entity has only ghost neighbor cells) + // -> the true owner cannot be determined, so we return just the owner of the first neighbor cell + // and let the iterative algorithm with padding indices to take care of the rest + // (the neighbor will return a padding index until it gets the global index from the true owner) + // TODO: implement getEntityOwner for other subentities + static_assert( Dimension == DistributedMesh::getMeshDimension() - 1, "the getEntityOwner function is implemented only for faces" ); auto getEntityOwner = [&] ( GlobalIndexType local_idx ) -> int { auto entity = mesh.getLocalMesh().template getEntity< Dimension >( local_idx ); - int owner = (rankOwningAllLocalCellSubvertices == 0) ? 0 : nproc; - if( rankOwningAllLocalCellSubvertices == 0 ) { - // this assumes that vertices at the boundaries were assigned to the subdomain with the lowest rank - // (this is used in DistributedMeshTest for simplicitty) - for( LocalIndexType v = 0; v < entity.template getSubentitiesCount< 0 >(); v++ ) { - const GlobalIndexType gv = entity.template getSubentityIndex< 0 >( v ); - owner = TNL::max( owner, getVertexOwner( gv ) ); - } + + int local_neighbor_cells_count = 0; + for( LocalIndexType k = 0; k < entity.template getSuperentitiesCount< DistributedMesh::getMeshDimension() >(); k++ ) { + const GlobalIndexType gk = entity.template getSuperentityIndex< DistributedMesh::getMeshDimension() >( k ); + if( ! mesh.getLocalMesh().template isGhostEntity< DistributedMesh::getMeshDimension() >( gk ) ) + local_neighbor_cells_count++; } - else { - // this assumes that vertices at the boundaries were assigned to the subdomain with the highest rank - // (this is what tnl-decompose-mesh does) - for( LocalIndexType v = 0; v < entity.template getSubentitiesCount< 0 >(); v++ ) { - const GlobalIndexType gv = entity.template getSubentityIndex< 0 >( v ); - owner = TNL::min( owner, getVertexOwner( gv ) ); + + // if all neighbor cells are local, we are the owner + if( local_neighbor_cells_count == 2 ) + return rank; + + // face is on the interface + if( local_neighbor_cells_count == 1 ) { + int owner = (preferHighRanks) ? 0 : nproc; + for( LocalIndexType k = 0; k < entity.template getSuperentitiesCount< DistributedMesh::getMeshDimension() >(); k++ ) { + const GlobalIndexType gk = entity.template getSuperentityIndex< DistributedMesh::getMeshDimension() >( k ); + if( preferHighRanks ) + owner = TNL::max( owner, getCellOwner( gk ) ); + else + owner = TNL::min( owner, getCellOwner( gk ) ); } + return owner; } - return owner; + + // only ghost cell neighbors - owner cannot be determined, return the first cell neighbor + const GlobalIndexType gk = entity.template getSuperentityIndex< DistributedMesh::getMeshDimension() >( 0 ); + return getCellOwner( gk ); }; // 1. identify local entities, set the GhostEntity tag on others @@ -111,107 +225,201 @@ distributeSubentities( DistributedMesh& mesh ) localMesh.template addEntityTag< Dimension >( i, EntityTags::GhostEntity ); }); - // 2. reorder the entities to make sure that all ghost entities are after local entities - // TODO: it would be nice if the mesh initializer could do this + // 2. exchange the counts of local entities between ranks, compute offsets for global indices + Containers::Vector< GlobalIndexType, Devices::Host, int > globalOffsets( nproc ); { - // count local entities GlobalIndexType localEntitiesCount = 0; for( GlobalIndexType i = 0; i < localMesh.template getEntitiesCount< Dimension >(); i++ ) if( ! localMesh.template isGhostEntity< Dimension >( i ) ) ++localEntitiesCount; - // create the permutation - typename LocalMesh::GlobalIndexArray perm, iperm; - perm.setSize( localMesh.template getEntitiesCount< Dimension >() ); - iperm.setSize( localMesh.template getEntitiesCount< Dimension >() ); - GlobalIndexType localsCount = 0; - GlobalIndexType ghostsCount = 0; - for( GlobalIndexType j = 0; j < iperm.getSize(); j++ ) { - if( localMesh.template isGhostEntity< Dimension >( j ) ) { - iperm[ j ] = localEntitiesCount + ghostsCount; - perm[ localEntitiesCount + ghostsCount ] = j; - ++ghostsCount; - } - else { - iperm[ j ] = localsCount; - perm[ localsCount ] = j; - ++localsCount; - } - } - - // reorder the local mesh - localMesh.template reorderEntities< Dimension >( perm, iperm ); - } - - // 3. update entity tags layer (this is actually done as part of the mesh reordering) - //localMesh.template updateEntityTagsLayer< Dimension >(); - - // 4. exchange the counts of local entities between ranks, compute offsets for global indices - Containers::Vector< GlobalIndexType, Devices::Host, int > globalOffsets( nproc ); - { Containers::Array< GlobalIndexType, Devices::Host, int > sendbuf( nproc ); - sendbuf.setValue( localMesh.template getGhostEntitiesOffset< Dimension >() ); + sendbuf.setValue( localEntitiesCount ); CommunicatorType::Alltoall( sendbuf.getData(), 1, globalOffsets.getData(), 1, mesh.getCommunicationGroup() ); } globalOffsets.template scan< Algorithms::ScanType::Exclusive >(); - // 5. assign global indices to the local entities + // 3. assign global indices to the local entities and a padding index to ghost entities + // (later we can check the padding index to know if an index was set or not) + const GlobalIndexType padding_index = (std::is_signed::value) ? -1 : std::numeric_limits::max(); mesh.template getGlobalIndices< Dimension >().setSize( localMesh.template getEntitiesCount< Dimension >() ); - localMesh.template forLocal< Dimension >( [&] ( GlobalIndexType i ) mutable { - mesh.template getGlobalIndices< Dimension >()[ i ] = globalOffsets[ rank ] + i; - }); + // also create mapping for ghost entities so that we can efficiently iterate over ghost entities + // while the entities were not sorted yet on the local mesh + std::vector< GlobalIndexType > localGhostIndices; + GlobalIndexType entityIndex = globalOffsets[ rank ]; + for( GlobalIndexType i = 0; i < localMesh.template getEntitiesCount< Dimension >(); i++ ) { + if( localMesh.template isGhostEntity< Dimension >( i ) ) { + mesh.template getGlobalIndices< Dimension >()[ i ] = padding_index; + localGhostIndices.push_back( i ); + } + else + mesh.template getGlobalIndices< Dimension >()[ i ] = entityIndex++; + } - // 6. exchange local indices for ghost entities - // We have to synchronize the vertex-entity superentity matrix, synchronization based - // on the cell-entity subentity matrix is not general. For example, two subdomains can - // have a common face, but no common cell, even when ghost_levels > 0. On the other - // hand, if two subdomains have a common face, they have common all its subvertices, - // so it is ensured that we send/receive indices for all ghost entities (with a rather - // great redundancy). - const auto sparseResult = synchronizer.synchronizeSparse( localMesh.template getSuperentitiesMatrix< 0, Dimension >() ); - const auto& rankOffsets = std::get< 0 >( sparseResult ); - const auto& rowPointers = std::get< 1 >( sparseResult ); - const auto& columnIndices = std::get< 2 >( sparseResult ); - - // 7. set the global indices of our ghost entities - localMesh.template forGhost< Dimension >( [&] ( GlobalIndexType entityIndex ) mutable { - const int owner = getEntityOwner( entityIndex ); - for( LocalIndexType v = 0; v < localMesh.template getSubentitiesCount< Dimension, 0 >( entityIndex ); v++ ) { - const GlobalIndexType vertex = localMesh.template getSubentityIndex< Dimension, 0 >( entityIndex, v ); - const int vertexOwner = getVertexOwner( vertex ); - if( vertexOwner == owner ) { - const GlobalIndexType ghostOffset = vertex - synchronizer.getGhostOffsets()[ vertexOwner ]; - // global index = owner's local index + owner's offset - const GlobalIndexType globalEntityIndex = columnIndices[ rowPointers[ rankOffsets[ vertexOwner ] + ghostOffset ] + v ] + globalOffsets[ owner ]; - mesh.template getGlobalIndices< Dimension >()[ entityIndex ] = globalEntityIndex; - break; - } + // Now for each ghost entity, we will take the global indices of its subvertices and + // send them to another rank (does not necessarily have to be the owner of the entity). + // The other rank will scan its vertex-entity superentity matrix, find the entity which + // has the received vertex indices and send the global entity index (which can be a + // padding index if it does not know it yet) back to the inquirer. The communication + // process is repeated until there are no padding indices. + // Note that we have to synchronize based on the vertex-entity superentity matrix, + // because synchronization based on the cell-entity subentity matrix would not be + // general. For example, two subdomains can have a common face, but no common cell, + // even when ghost_levels > 0. On the other hand, if two subdomains have a common face, + // they have common all its subvertices. + + // 4. build seeds for ghost entities + std::vector< std::vector< GlobalIndexType > > seeds_vertex_indices, seeds_entity_offsets, seeds_local_indices; + seeds_vertex_indices.resize( nproc ); + seeds_entity_offsets.resize( nproc ); + seeds_local_indices.resize( nproc ); + for( auto entity_index : localGhostIndices ) { + const int owner = getEntityOwner( entity_index ); + for( LocalIndexType v = 0; v < localMesh.template getSubentitiesCount< Dimension, 0 >( entity_index ); v++ ) { + const GlobalIndexType local_index = localMesh.template getSubentityIndex< Dimension, 0 >( entity_index, v ); + const GlobalIndexType global_index = mesh.template getGlobalIndices< 0 >()[ local_index ]; + seeds_vertex_indices[ owner ].push_back( global_index ); } - }); + seeds_entity_offsets[ owner ].push_back( seeds_vertex_indices[ owner ].size() ); + // record the corresponding local index for later use + seeds_local_indices[ owner ].push_back( entity_index ); + } + + // 5. exchange seeds for ghost entities + const auto foreign_seeds = exchangeGhostEntitySeeds< CommunicatorType >( mesh.getCommunicationGroup(), seeds_vertex_indices, seeds_entity_offsets ); + const auto& foreign_seeds_vertex_indices = std::get< 0 >( foreign_seeds ); + const auto& foreign_seeds_entity_offsets = std::get< 1 >( foreign_seeds ); + + std::vector< std::vector< GlobalIndexType > > foreign_ghost_indices; + foreign_ghost_indices.resize( nproc ); + for( int i = 0; i < nproc; i++ ) + foreign_ghost_indices[ i ].resize( foreign_seeds_entity_offsets[ i ].size() ); - // 8. reorder the entities to make sure that global indices are sorted + // 6. iterate until there are no padding indices + // (maybe 2 iterations are always enough, but we should be extra careful) + for( int iter = 0; iter < DistributedMesh::getMeshDimension(); iter++ ) { - // prepare vector with an identity permutation - std::vector< GlobalIndexType > permutation( localMesh.template getEntitiesCount< Dimension >() ); - std::iota( permutation.begin(), permutation.end(), (GlobalIndexType) 0 ); - - // sort the subarray corresponding to ghost entities by the global index - std::stable_sort( permutation.begin() + mesh.getLocalMesh().template getGhostEntitiesOffset< Dimension >(), - permutation.end(), - [&mesh](auto& left, auto& right) { - return mesh.template getGlobalIndices< Dimension >()[ left ] < mesh.template getGlobalIndices< Dimension >()[ right ]; + // 6a. determine global indices for the received seeds + Algorithms::ParallelFor< Devices::Host >::exec( 0, nproc, [&] ( int i ) { + GlobalIndexType vertexOffset = 0; + // loop over all foreign ghost entities + for( std::size_t entityIndex = 0; entityIndex < foreign_seeds_entity_offsets[ i ].size(); entityIndex++ ) { + // data structure for common indices + std::set< GlobalIndexType > common_indices; + + // global vertex index offset (for global-to-local index conversion) + const GlobalIndexType globalOffset = mesh.template getGlobalIndices< 0 >().getElement( 0 ); + + // loop over all subvertices of the entity + while( vertexOffset < foreign_seeds_entity_offsets[ i ][ entityIndex ] ) { + const GlobalIndexType vertex = foreign_seeds_vertex_indices[ i ][ vertexOffset++ ]; + GlobalIndexType localIndex = 0; + if( vertex >= globalOffset && vertex < globalOffset + localMesh.template getGhostEntitiesOffset< 0 >() ) + // subtract offset to get local index + localIndex = vertex - globalOffset; + else { + // we must go through the ghost vertices + for( GlobalIndexType g = localMesh.template getGhostEntitiesOffset< 0 >(); + g < localMesh.template getEntitiesCount< 0 >(); + g++ ) + if( vertex == mesh.template getGlobalIndices< 0 >()[ g ] ) { + localIndex = g; + break; + } + if( localIndex == 0 ) + throw std::runtime_error( "vertex with gid=" + std::to_string(vertex) + " received from rank " + + std::to_string(i) + " was not found on the local mesh for rank " + std::to_string(rank) + + " (global offset = " + std::to_string(globalOffset) + ")" ); + } + + // collect superentities of this vertex + std::set< GlobalIndexType > superentities; + for( LocalIndexType e = 0; e < localMesh.template getSuperentitiesCount< 0, Dimension >( localIndex ); e++ ) { + const GlobalIndexType entity = localMesh.template getSuperentityIndex< 0, Dimension >( localIndex, e ); + superentities.insert( entity ); + } + + // initialize or intersect + if( common_indices.empty() ) + common_indices = superentities; + else + // remove indices which are not in the current superentities set + for( auto it = common_indices.begin(); it != common_indices.end(); ) { + if( superentities.count( *it ) == 0 ) + it = common_indices.erase(it); + else + ++it; + } + } + + if( common_indices.size() != 1 ) { + std::stringstream msg; + msg << "expected exactly 1 common index, but the algorithm found these common indices: "; + for( auto i : common_indices ) + msg << i << " "; + msg << "\nDebug info: rank " << rank << ", entityIndex = " << entityIndex << ", received from rank " << i; + throw std::runtime_error( msg.str() ); + } + + // assign global index + // (note that we do not have to check if we are the actual owner of the entity, + // we can just forward global indices that we received from somebody else, or + // send the padding index if the global index was not received yet) + const GlobalIndexType local_index = *common_indices.begin(); + foreign_ghost_indices[ i ][ entityIndex ] = mesh.template getGlobalIndices< Dimension >()[ local_index ]; + } }); - // copy the permutation into TNL array and invert + // 6b. exchange global ghost indices + const auto ghost_indices = exchangeGhostIndices< CommunicatorType >( mesh.getCommunicationGroup(), foreign_ghost_indices, seeds_local_indices ); + + // 6c. set the global indices of our ghost entities + bool done = true; + for( int i = 0; i < nproc; i++ ) { + for( std::size_t g = 0; g < ghost_indices[ i ].size(); g++ ) { + mesh.template getGlobalIndices< Dimension >()[ seeds_local_indices[ i ][ g ] ] = ghost_indices[ i ][ g ]; + if( ghost_indices[ i ][ g ] == padding_index ) + done = false; + } + } + + // 6d. check if finished + bool all_done = false;; + CommunicatorType::Allreduce( &done, &all_done, 1, MPI_LAND, mesh.getCommunicationGroup() ); + if( all_done ) + break; + } + if( mesh.template getGlobalIndices< Dimension >().containsValue( padding_index ) ) + throw std::runtime_error( "some global indices were left unset" ); + + // 7. reorder the entities to make sure that global indices are sorted + { + // prepare arrays for the permutation and inverse permutation typename LocalMesh::GlobalIndexArray perm, iperm; perm.setSize( localMesh.template getEntitiesCount< Dimension >() ); iperm.setSize( localMesh.template getEntitiesCount< Dimension >() ); - for( GlobalIndexType i = 0; i < localMesh.template getEntitiesCount< Dimension >(); i++ ) { - perm[ i ] = permutation[ i ]; + + // create the permutation - sort the identity array by the global index, but put local entities first + localMesh.template forAll< Dimension >( [&] ( GlobalIndexType i ) mutable { perm[ i ] = i; }); + std::stable_sort( perm.getData(), // + mesh.getLocalMesh().template getGhostEntitiesOffset< Dimension >(), + perm.getData() + perm.getSize(), + [&mesh, &localMesh](auto& left, auto& right) { + auto is_local = [&](auto& i) { + return ! localMesh.template isGhostEntity< Dimension >( i ); + }; + if( is_local(left) && ! is_local(right) ) + return true; + if( ! is_local(left) && is_local(right) ) + return false; + return mesh.template getGlobalIndices< Dimension >()[ left ] < mesh.template getGlobalIndices< Dimension >()[ right ]; + }); + + // invert the permutation + localMesh.template forAll< Dimension >( [&] ( GlobalIndexType i ) mutable { iperm[ perm[ i ] ] = i; - } + }); // reorder the mesh mesh.template reorderEntities< Dimension >( perm, iperm ); diff --git a/src/Tools/CMakeLists.txt b/src/Tools/CMakeLists.txt index 34dfc5e3e28706dc13c601d59dd14b59d65cf736..7d85b9441feef5de90049a5acbef3da12ab7410c 100644 --- a/src/Tools/CMakeLists.txt +++ b/src/Tools/CMakeLists.txt @@ -7,6 +7,11 @@ ADD_EXECUTABLE(tnl-grid-setup tnl-grid-setup.cpp ) ADD_EXECUTABLE(tnl-grid-to-mesh tnl-grid-to-mesh.cpp ) ADD_EXECUTABLE(tnl-mesh-converter tnl-mesh-converter.cpp ) ADD_EXECUTABLE(tnl-game-of-life tnl-game-of-life.cpp ) +if( BUILD_CUDA ) + CUDA_ADD_EXECUTABLE(tnl-test-distributed-mesh tnl-test-distributed-mesh.cu ) +else() + ADD_EXECUTABLE(tnl-test-distributed-mesh tnl-test-distributed-mesh.cpp ) +endif() ADD_EXECUTABLE(tnl-init tnl-init.cpp ) ADD_EXECUTABLE(tnl-view tnl-view.cpp ) ADD_EXECUTABLE(tnl-diff tnl-diff.cpp ) @@ -27,26 +32,19 @@ endif() find_package( ZLIB ) if( ZLIB_FOUND ) - target_compile_definitions(tnl-view PUBLIC "-DHAVE_ZLIB") - target_include_directories(tnl-view PUBLIC ${ZLIB_INCLUDE_DIRS}) - target_link_libraries(tnl-view ${ZLIB_LIBRARIES}) - - target_compile_definitions(tnl-mesh-converter PUBLIC "-DHAVE_ZLIB") - target_include_directories(tnl-mesh-converter PUBLIC ${ZLIB_INCLUDE_DIRS}) - target_link_libraries(tnl-mesh-converter ${ZLIB_LIBRARIES}) - - target_compile_definitions(tnl-game-of-life PUBLIC "-DHAVE_ZLIB") - target_include_directories(tnl-game-of-life PUBLIC ${ZLIB_INCLUDE_DIRS}) - target_link_libraries(tnl-game-of-life ${ZLIB_LIBRARIES}) + foreach( target IN ITEMS tnl-view tnl-mesh-converter tnl-game-of-life tnl-test-distributed-mesh ) + target_compile_definitions(${target} PUBLIC "-DHAVE_ZLIB") + target_include_directories(${target} PUBLIC ${ZLIB_INCLUDE_DIRS}) + target_link_libraries(${target} ${ZLIB_LIBRARIES}) + endforeach() endif() find_package( tinyxml2 QUIET ) if( tinyxml2_FOUND ) - target_compile_definitions(tnl-mesh-converter PUBLIC "-DHAVE_TINYXML2") - target_link_libraries(tnl-mesh-converter tinyxml2::tinyxml2) - - target_compile_definitions(tnl-game-of-life PUBLIC "-DHAVE_TINYXML2") - target_link_libraries(tnl-game-of-life tinyxml2::tinyxml2) + foreach( target IN ITEMS tnl-mesh-converter tnl-game-of-life tnl-test-distributed-mesh ) + target_compile_definitions(${target} PUBLIC "-DHAVE_TINYXML2") + target_link_libraries(${target} tinyxml2::tinyxml2) + endforeach() endif() find_package( METIS QUIET ) @@ -80,6 +78,7 @@ INSTALL( TARGETS tnl-init tnl-grid-to-mesh tnl-mesh-converter tnl-game-of-life + tnl-test-distributed-mesh tnl-dicom-reader tnl-image-converter tnl-lattice-init diff --git a/src/Tools/tnl-decompose-mesh.cpp b/src/Tools/tnl-decompose-mesh.cpp index b1fb30d060cf834c31d205c61cde57cb1607b51c..5ebefe256de91b7fdcb1549380fe6d4c0606aa0e 100644 --- a/src/Tools/tnl-decompose-mesh.cpp +++ b/src/Tools/tnl-decompose-mesh.cpp @@ -14,9 +14,11 @@ #include #include #include +#include #include +#include // std::iota #include #include #include @@ -392,25 +394,32 @@ struct DecomposeMesh // set METIS options from parameters setMETISoptions(options, parameters); - if( options[METIS_OPTION_PTYPE] == METIS_PTYPE_KWAY ) { - std::cout << "Running METIS_PartGraphKway..." << std::endl; - status = METIS_PartGraphKway(&nvtxs, &ncon, xadj, adjncy, vwgt, vsize, adjwgt, &nparts, tpwgts, ubvec, options, &objval, part); + if( nparts == 1 ) { + // k-way partitioning from Metis fails for nparts == 1 (segfault), + // RB succeeds but produces nonsense + part_array.setValue( 0 ); } else { - std::cout << "Running METIS_PartGraphRecursive..." << std::endl; - status = METIS_PartGraphRecursive(&nvtxs, &ncon, xadj, adjncy, vwgt, vsize, adjwgt, &nparts, tpwgts, ubvec, options, &objval, part); - } + if( options[METIS_OPTION_PTYPE] == METIS_PTYPE_KWAY ) { + std::cout << "Running METIS_PartGraphKway..." << std::endl; + status = METIS_PartGraphKway(&nvtxs, &ncon, xadj, adjncy, vwgt, vsize, adjwgt, &nparts, tpwgts, ubvec, options, &objval, part); + } + else { + std::cout << "Running METIS_PartGraphRecursive..." << std::endl; + status = METIS_PartGraphRecursive(&nvtxs, &ncon, xadj, adjncy, vwgt, vsize, adjwgt, &nparts, tpwgts, ubvec, options, &objval, part); + } - switch( status ) - { - case METIS_OK: break; - case METIS_ERROR_INPUT: - throw std::runtime_error( "METIS_PartGraph failed due to an input error." ); - case METIS_ERROR_MEMORY: - throw std::runtime_error( "METIS_PartGraph failed due to a memory allocation error." ); - case METIS_ERROR: - default: - throw std::runtime_error( "METIS_PartGraph failed with an unspecified error." ); + switch( status ) + { + case METIS_OK: break; + case METIS_ERROR_INPUT: + throw std::runtime_error( "METIS_PartGraph failed due to an input error." ); + case METIS_ERROR_MEMORY: + throw std::runtime_error( "METIS_PartGraph failed due to a memory allocation error." ); + case METIS_ERROR: + default: + throw std::runtime_error( "METIS_PartGraph failed with an unspecified error." ); + } } // deallocate auxiliary vectors @@ -508,8 +517,8 @@ struct DecomposeMesh points_counts.setValue( 0 ); { // first assign points to subdomains - the subdomain with the highest number takes the point + // (go over local cells, set subvertex owner = cell owner, higher rank will overwrite) IndexArray point_to_subdomain( pointsCount ); - point_to_subdomain.setValue( 0 ); for( unsigned p = 0; p < nparts; p++ ) { for( Index local_idx = 0; local_idx < cells_counts[ p ]; local_idx++ ) { const Index global_idx = seed_to_cell_index[ cells_offsets[ p ] + local_idx ]; @@ -517,8 +526,7 @@ struct DecomposeMesh const Index subvertices = cell.template getSubentitiesCount< 0 >(); for( Index j = 0; j < subvertices; j++ ) { const Index v = cell.template getSubentityIndex< 0 >( j ); - if( (Index) p > point_to_subdomain[ v ] ) - point_to_subdomain[ v ] = p; + point_to_subdomain[ v ] = p; } } } @@ -623,7 +631,7 @@ struct DecomposeMesh } // collect seed indices of ghost cells - std::vector< Index > ghost_seed_indices; + std::set< Index > ghost_seed_indices; for( unsigned gl = 0; gl < ghost_levels; gl++ ) { std::vector< Index > new_ghosts; for( auto global_idx : ghost_neighbors ) { @@ -631,9 +639,15 @@ struct DecomposeMesh const Index neighbors_end = dual_xadj.get()[ global_idx + 1 ]; for( Index i = neighbors_start; i < neighbors_end; i++ ) { const Index neighbor_idx = dual_adjncy.get()[ i ]; - new_ghosts.push_back( neighbor_idx ); + // skip neighbors on the local subdomain + if( part[ neighbor_idx ] == (int) p ) + continue; const Index neighbor_seed_idx = cell_to_seed_index[ neighbor_idx ]; - ghost_seed_indices.push_back( neighbor_seed_idx ); + // skip neighbors whose seed was already added + if( ghost_seed_indices.count( neighbor_seed_idx ) == 0 ) { + new_ghosts.push_back( neighbor_idx ); + ghost_seed_indices.insert( neighbor_seed_idx ); + } } } std::swap( ghost_neighbors, new_ghosts ); @@ -641,10 +655,7 @@ struct DecomposeMesh ghost_neighbors.clear(); ghost_neighbors.shrink_to_fit(); - // sort ghosts by their seed index (i.g. global index on the decomposed mesh) - std::sort( ghost_seed_indices.begin(), ghost_seed_indices.end() ); - - // add ghost cells + // add ghost cells (the set is sorted by the seed index) for( auto idx : ghost_seed_indices ) { // the ghost_seed_indices array may contain duplicates and even local // cells, but add_cell takes care of uniqueness, so we don't have to @@ -653,7 +664,6 @@ struct DecomposeMesh add_cell( cell ); } ghost_seed_indices.clear(); - ghost_seed_indices.shrink_to_fit(); cell_global_indices.clear(); // set points needed for the subdomain @@ -685,14 +695,54 @@ struct DecomposeMesh for( Index i = cells_counts[ p ]; i < cellSeeds.getSize(); i++ ) cellGhosts[ i ] = (std::uint8_t) Meshes::VTK::CellGhostTypes::DUPLICATECELL; // point ghosts are more tricky because they were assigned to the subdomain with higher number + Index pointsGhostCount = 0; for( Index i = 0; i < points.getSize(); i++ ) { const Index global_idx = pointsGlobalIndices[ i ]; - if( global_idx < points_offsets[ p ] || global_idx >= points_offsets[ p ] + points_counts[ p ] ) + if( global_idx < points_offsets[ p ] || global_idx >= points_offsets[ p ] + points_counts[ p ] ) { pointGhosts[ i ] = (std::uint8_t) Meshes::VTK::PointGhostTypes::DUPLICATEPOINT; + pointsGhostCount++; + } else pointGhosts[ i ] = 0; } + // reorder ghost points to make sure that global indices are sorted + { + // prepare vector with an identity permutation + std::vector< Index > permutation( points.getSize() ); + std::iota( permutation.begin(), permutation.end(), (Index) 0 ); + + // sort the subarray corresponding to ghost entities by the global index + std::stable_sort( permutation.begin() + points.getSize() - pointsGhostCount, + permutation.end(), + [&pointsGlobalIndices](auto& left, auto& right) { + return pointsGlobalIndices[ left ] < pointsGlobalIndices[ right ]; + }); + + // copy the permutation into TNL array + typename Mesh::GlobalIndexArray perm( permutation ); + permutation.clear(); + permutation.shrink_to_fit(); + + // apply the permutation + using PermutationApplier = TNL::Meshes::IndexPermutationApplier< Mesh, 0 >; + // - pointGhosts + PermutationApplier::permuteArray( pointGhosts, perm ); + // - pointsGlobalIndices + PermutationApplier::permuteArray( pointsGlobalIndices, perm ); + // - points + PermutationApplier::permuteArray( points, perm ); + // - cellSeeds.setCornerID (inverse perm) + std::vector< Index > iperm( points.getSize() ); + for( Index i = 0; i < perm.getSize(); i++ ) + iperm[ perm[ i ] ] = i; + for( Index i = 0; i < cellSeeds.getSize(); i++ ) { + auto& cornerIds = cellSeeds[ i ].getCornerIds(); + for( Index v = 0; v < cornerIds.getSize(); v++ ) + cornerIds[ v ] = iperm[ cornerIds[ v ] ]; + } + } + // init mesh for the subdomain Mesh subdomain; subdomain.init( points, cellSeeds ); diff --git a/src/Tools/tnl-test-distributed-mesh.cpp b/src/Tools/tnl-test-distributed-mesh.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e194bd17f34f173aac1e5ed1b0ae4371c033975a --- /dev/null +++ b/src/Tools/tnl-test-distributed-mesh.cpp @@ -0,0 +1 @@ +#include "tnl-test-distributed-mesh.h" diff --git a/src/Tools/tnl-test-distributed-mesh.cu b/src/Tools/tnl-test-distributed-mesh.cu new file mode 100644 index 0000000000000000000000000000000000000000..e194bd17f34f173aac1e5ed1b0ae4371c033975a --- /dev/null +++ b/src/Tools/tnl-test-distributed-mesh.cu @@ -0,0 +1 @@ +#include "tnl-test-distributed-mesh.h" diff --git a/src/Tools/tnl-test-distributed-mesh.h b/src/Tools/tnl-test-distributed-mesh.h new file mode 100644 index 0000000000000000000000000000000000000000..1fc4c855ec8b3bf28187a9b50ac70439dff567c2 --- /dev/null +++ b/src/Tools/tnl-test-distributed-mesh.h @@ -0,0 +1,463 @@ +/*************************************************************************** + tnl-distributed-mesh-test.cpp - description + ------------------- + begin : Oct 18, 2020 + copyright : (C) 2020 by Tomas Oberhuber et al. + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace TNL; + +using CommunicatorType = Communicators::MpiCommunicator; + +struct MyConfigTag {}; + +namespace TNL { +namespace Meshes { +namespace BuildConfigTags { + +/**** + * Turn off support for float and long double. + */ +template<> struct GridRealTag< MyConfigTag, float > { enum { enabled = false }; }; +template<> struct GridRealTag< MyConfigTag, long double > { enum { enabled = false }; }; + +/**** + * Turn off support for short int and long int indexing. + */ +template<> struct GridIndexTag< MyConfigTag, short int >{ enum { enabled = false }; }; +template<> struct GridIndexTag< MyConfigTag, long int >{ enum { enabled = false }; }; + +/**** + * Unstructured meshes. + */ +//template<> struct MeshCellTopologyTag< MyConfigTag, Topologies::Edge > { enum { enabled = true }; }; +template<> struct MeshCellTopologyTag< MyConfigTag, Topologies::Triangle > { enum { enabled = true }; }; +//template<> struct MeshCellTopologyTag< MyConfigTag, Topologies::Quadrilateral > { enum { enabled = true }; }; +template<> struct MeshCellTopologyTag< MyConfigTag, Topologies::Tetrahedron > { enum { enabled = true }; }; +//template<> struct MeshCellTopologyTag< MyConfigTag, Topologies::Hexahedron > { enum { enabled = true }; }; + +// Meshes are enabled only for the world dimension equal to the cell dimension. +template< typename CellTopology, int WorldDimension > +struct MeshWorldDimensionTag< MyConfigTag, CellTopology, WorldDimension > +{ enum { enabled = ( WorldDimension == CellTopology::dimension ) }; }; + +// Meshes are enabled only for types explicitly listed below. +template<> struct MeshRealTag< MyConfigTag, float > { enum { enabled = false }; }; +template<> struct MeshRealTag< MyConfigTag, double > { enum { enabled = true }; }; +template<> struct MeshGlobalIndexTag< MyConfigTag, int > { enum { enabled = true }; }; +template<> struct MeshGlobalIndexTag< MyConfigTag, long int > { enum { enabled = false }; }; +template<> struct MeshLocalIndexTag< MyConfigTag, short int > { enum { enabled = true }; }; + +// Config tag specifying the MeshConfig template to use. +template<> +struct MeshConfigTemplateTag< MyConfigTag > +{ + template< typename Cell, + int WorldDimension = Cell::dimension, + typename Real = double, + typename GlobalIndex = int, + typename LocalIndex = GlobalIndex > + struct MeshConfig + { + using CellTopology = Cell; + using RealType = Real; + using GlobalIndexType = GlobalIndex; + using LocalIndexType = LocalIndex; + + static constexpr int worldDimension = WorldDimension; + static constexpr int meshDimension = Cell::dimension; + + template< typename EntityTopology > + static constexpr bool subentityStorage( EntityTopology, int SubentityDimension ) + { + return ( SubentityDimension == 0 && EntityTopology::dimension >= meshDimension - 1 ) + || SubentityDimension == meshDimension - 1; + } + + template< typename EntityTopology > + static constexpr bool subentityOrientationStorage( EntityTopology, int SubentityDimension ) + { + return false; + } + + template< typename EntityTopology > + static constexpr bool superentityStorage( EntityTopology, int SuperentityDimension ) + { +// return false; + return (EntityTopology::dimension == 0 || EntityTopology::dimension == meshDimension - 1) && SuperentityDimension >= meshDimension - 1; + } + + template< typename EntityTopology > + static constexpr bool entityTagsStorage( EntityTopology ) + { +// return false; + return EntityTopology::dimension == 0 || EntityTopology::dimension >= meshDimension - 1; + } + + static constexpr bool dualGraphStorage() + { + return true; + } + + static constexpr int dualGraphMinCommonVertices = meshDimension; + }; +}; + +} // namespace BuildConfigTags +} // namespace Meshes +} // namespace TNL + + +// TODO +// simple mesh function without SharedPointer for the mesh +template< typename Real, typename LocalMesh, int EntitiesDimension = LocalMesh::getMeshDimension() > +struct MyMeshFunction +{ + using MeshType = LocalMesh; + using RealType = Real; + using DeviceType = typename LocalMesh::DeviceType; + using IndexType = typename LocalMesh::GlobalIndexType; + using VectorType = Containers::Vector< RealType, DeviceType, IndexType >; + + static constexpr int getEntitiesDimension() { return EntitiesDimension; } + + static constexpr int getMeshDimension() { return LocalMesh::getMeshDimension(); } + + MyMeshFunction( const LocalMesh& localMesh ) + { + data.setSize( localMesh.template getEntitiesCount< getEntitiesDimension() >() ); + } + + const VectorType& getData() const + { + return data; + } + + VectorType& getData() + { + return data; + } + + private: + VectorType data; +}; + + +template< typename Mesh > +__cuda_callable__ +typename Mesh::LocalIndexType +getCellsForFace( const Mesh & mesh, const typename Mesh::GlobalIndexType E, typename Mesh::GlobalIndexType* cellIndexes ) +{ + using LocalIndexType = typename Mesh::LocalIndexType; + const LocalIndexType numCells = mesh.template getSuperentitiesCount< Mesh::getMeshDimension() - 1, Mesh::getMeshDimension() >( E ); + for( LocalIndexType i = 0; i < numCells; i++ ) + cellIndexes[ i ] = mesh.template getSuperentityIndex< Mesh::getMeshDimension() - 1, Mesh::getMeshDimension() >( E, i ); + return numCells; +} + + +// TODO: copy this to the DistributedMeshTest.h +// testing global indices is not enough - entity centers are needed to ensure that the transferred data really match the physical entities +template< typename Device, typename EntityType, typename MeshType > +void testSynchronizerOnDevice( const MeshType& mesh ) +{ + using LocalMesh = TNL::Meshes::Mesh< typename MeshType::Config, Device >; + using DeviceMesh = TNL::Meshes::DistributedMeshes::DistributedMesh< LocalMesh >; + using IndexType = typename MeshType::GlobalIndexType; + using PointType = typename MeshType::PointType; + using Array = TNL::Containers::Array< typename LocalMesh::RealType, typename LocalMesh::DeviceType, IndexType >; + using Synchronizer = TNL::Meshes::DistributedMeshes::DistributedMeshSynchronizer< DeviceMesh, EntityType::getEntityDimension() >; + + // initialize + DeviceMesh deviceMesh; + deviceMesh = mesh; + Array f( mesh.getLocalMesh().template getEntitiesCount< EntityType::getEntityDimension() >() * MeshType::getMeshDimension() ); + f.setValue( 0 ); + + // set center of each local entity + for( IndexType i = 0; i < mesh.getLocalMesh().template getEntitiesCount< EntityType >(); i++ ) + if( ! mesh.getLocalMesh().template isGhostEntity< EntityType::getEntityDimension() >( i ) ) { + const auto center = getEntityCenter( mesh.getLocalMesh(), mesh.getLocalMesh().template getEntity< EntityType >( i ) ); + for( int d = 0; d < MeshType::getMeshDimension(); d++ ) + f.setElement( d + MeshType::getMeshDimension() * i, center[ d ] ); + } + + // synchronize + Synchronizer sync; + sync.initialize( deviceMesh ); + sync.synchronizeArray( f, MeshType::getMeshDimension() ); + + // check all centers + IndexType errors = 0; + for( IndexType i = 0; i < mesh.getLocalMesh().template getEntitiesCount< EntityType >(); i++ ) + if( mesh.getLocalMesh().template isGhostEntity< EntityType::getEntityDimension() >( i ) ) { + const PointType center = getEntityCenter( mesh.getLocalMesh(), mesh.getLocalMesh().template getEntity< EntityType >( i ) ); + PointType received; + for( int d = 0; d < MeshType::getMeshDimension(); d++ ) + received[ d ] = f.getElement( d + MeshType::getMeshDimension() * i ); + if( received != center ) { + IndexType cellIndexes[ 2 ] = {0, 0}; + const int numCells = getCellsForFace( mesh.getLocalMesh(), i, cellIndexes ); + std::cerr << "rank " << CommunicatorType::GetRank() + << ": wrong result for entity " << i << " (gid " << mesh.template getGlobalIndices< EntityType::getEntityDimension() >()[i] << ")" + << " of dimension = " << EntityType::getEntityDimension() + << ": received " << received << ", expected = " << center + << ", neighbor cells " << cellIndexes[0] << " " << ((numCells>1) ? cellIndexes[1] : -1) + << std::endl; + errors++; + } + } + if( errors > 0 ) { + std::cerr << "rank " << CommunicatorType::GetRank() << ": " << errors << " errors in total." << std::endl; + TNL_ASSERT_TRUE( false, "test failed" ); + } +} + +template< typename Mesh > +void testSynchronizer( const Mesh& mesh ) +{ + testSynchronizerOnDevice< Devices::Host, typename Mesh::Vertex >( mesh ); + testSynchronizerOnDevice< Devices::Host, typename Mesh::Cell >( mesh ); + if( mesh.template getGlobalIndices< 1 >().getSize() > 0 ) + testSynchronizerOnDevice< Devices::Host, typename Mesh::Face >( mesh ); +#ifdef HAVE_CUDA + testSynchronizerOnDevice< Devices::Cuda, typename Mesh::Vertex >( mesh ); + testSynchronizerOnDevice< Devices::Cuda, typename Mesh::Cell >( mesh ); + if( mesh.template getGlobalIndices< 1 >().getSize() > 0 ) + testSynchronizerOnDevice< Devices::Cuda, typename Mesh::Face >( mesh ); +#endif +} + + +template< typename Mesh > +bool testPropagationOverFaces( const Mesh& mesh, int max_iterations ) +{ + using LocalMesh = typename Mesh::MeshType; + using Index = typename Mesh::GlobalIndexType; + + const LocalMesh& localMesh = mesh.getLocalMesh(); + + using CellSynchronizer = Meshes::DistributedMeshes::DistributedMeshSynchronizer< Mesh >; + using FaceSynchronizer = Meshes::DistributedMeshes::DistributedMeshSynchronizer< Mesh, Mesh::getMeshDimension() - 1 >; + CellSynchronizer cell_sync; + FaceSynchronizer face_sync; + cell_sync.initialize( mesh ); + face_sync.initialize( mesh ); + + using Real = int; + MyMeshFunction< Real, LocalMesh, Mesh::getMeshDimension() > f_K( localMesh ), f_K_test( localMesh ), f_K_test_aux( localMesh ); + MyMeshFunction< Real, LocalMesh, Mesh::getMeshDimension() - 1 > f_E( localMesh ); + f_K.getData().setValue( 0 ); + f_K_test.getData().setValue( 0 ); + f_K_test_aux.getData().setValue( 0 ); + f_E.getData().setValue( 0 ); + + auto make_snapshot = [&] ( Index iteration ) + { + // create a .pvtu file (only rank 0 actually writes to the file) + const std::string mainFilePath = "data_" + std::to_string(iteration) + ".pvtu"; + std::ofstream file; + if( CommunicatorType::GetRank() == 0 ) + file.open( mainFilePath ); + using PVTU = Meshes::Writers::PVTUWriter< LocalMesh >; + PVTU pvtu( file ); + pvtu.template writeEntities< Mesh::getMeshDimension() >( mesh ); + pvtu.writeMetadata( iteration, iteration ); + // the PointData and CellData from the individual files should be added here + if( mesh.getGhostLevels() > 0 ) + pvtu.template writePCellData< std::uint8_t >( Meshes::VTK::ghostArrayName() ); + pvtu.template writePCellData< Real >( "function values" ); + pvtu.template writePCellData< Real >( "test values" ); + const std::string subfilePath = pvtu.template addPiece< CommunicatorType >( mainFilePath, mesh.getCommunicationGroup() ); + + // create a .vtu file for local data + using Writer = Meshes::Writers::VTUWriter< LocalMesh >; + std::ofstream subfile( subfilePath ); + Writer writer( subfile ); + writer.writeMetadata( iteration, iteration ); + writer.template writeEntities< LocalMesh::getMeshDimension() >( localMesh ); + if( mesh.getGhostLevels() > 0 ) + writer.writeCellData( mesh.vtkCellGhostTypes(), Meshes::VTK::ghostArrayName() ); + writer.writeCellData( f_K.getData(), "function values" ); + writer.writeCellData( f_K_test.getData(), "test values" ); + }; + + // write initial state + make_snapshot( 0 ); + + // captures for the iteration kernel + auto f_K_view = f_K.getData().getView(); + auto f_K_test_view = f_K_test.getData().getView(); + auto f_K_test_aux_view = f_K_test_aux.getData().getView(); + auto f_E_view = f_E.getData().getView(); + Pointers::DevicePointer< const LocalMesh > localMeshDevicePointer( localMesh ); + const LocalMesh* localMeshPointer = &localMeshDevicePointer.template getData< typename LocalMesh::DeviceType >(); + + const Real boundary_value = 10; + + bool all_done = false; + int iteration = 0; + do { + iteration++; + if( CommunicatorType::GetRank() == 0 ) + std::cout << "Computing iteration " << iteration << "..." << std::endl; + + const Index prev_sum = sum( f_K.getData() ); + + f_K_test_aux_view = f_K_test_view; + + // iterate over all local cells + auto testKernel = [f_K_test_aux_view, f_K_test_view, localMeshPointer] __cuda_callable__ ( Index K ) mutable + { + Real max = f_K_test_aux_view[ K ]; + for( int e = 0; e < localMeshPointer->template getSubentitiesCount< LocalMesh::getMeshDimension(), LocalMesh::getMeshDimension() - 1 >( K ); e++ ) { + const Index E = localMeshPointer->template getSubentityIndex< LocalMesh::getMeshDimension(), LocalMesh::getMeshDimension() - 1 >( K, e ); + Index cellIndexes[ 2 ] = {0, 0}; + const int numCells = getCellsForFace( *localMeshPointer, E, cellIndexes ); + + Real edge_value; + if( numCells == 1 ) { + edge_value = boundary_value; + } + else { + edge_value = std::ceil( 0.5 * ( f_K_test_aux_view[ cellIndexes[ 0 ] ] + f_K_test_aux_view[ cellIndexes[ 1 ] ] ) ); +// edge_value = TNL::max( f_K_test_aux_view[ cellIndexes[ 0 ] ], f_K_test_aux_view[ cellIndexes[ 1 ] ] ); + } + if( edge_value > max ) { + max = edge_value; + } + } + f_K_test_view[ K ] = max; + }; + localMesh.template forLocal< LocalMesh::getMeshDimension() >( testKernel ); + + // synchronize f_K_test + cell_sync.synchronize( f_K_test ); + + // iterate over all local faces + auto faceAverageKernel = [f_K_view, f_E_view, localMeshPointer] __cuda_callable__ ( Index E ) mutable + { + TNL_ASSERT_FALSE( localMeshPointer->template isGhostEntity< LocalMesh::getMeshDimension() - 1 >( E ), + "iterator bug - got a ghost entity" ); + + Index cellIndexes[ 2 ] = {0, 0}; + const int numCells = getCellsForFace( *localMeshPointer, E, cellIndexes ); + + if( numCells == 1 ) { + TNL_ASSERT_FALSE( localMeshPointer->template isGhostEntity< LocalMesh::getMeshDimension() >( cellIndexes[0] ), + ("iterator bug - boundary face " + std::to_string(E) + " on a ghost cell " + + std::to_string(cellIndexes[0])).c_str() ); + f_E_view[ E ] = boundary_value; + } + else { + f_E_view[ E ] = std::ceil( 0.5 * ( f_K_view[ cellIndexes[ 0 ] ] + f_K_view[ cellIndexes[ 1 ] ] ) ); +// f_E_view[ E ] = TNL::max( f_K_view[ cellIndexes[ 0 ] ], f_K_view[ cellIndexes[ 1 ] ] ); + } + }; + localMesh.template forLocal< LocalMesh::getMeshDimension() - 1 >( faceAverageKernel ); + + // synchronize f_E + face_sync.synchronize( f_E ); + + // iterate over all local cells + auto kernel = [f_K_view, f_E_view, localMeshPointer] __cuda_callable__ ( Index K ) mutable + { + Real max = f_K_view[ K ]; + for( int e = 0; e < localMeshPointer->template getSubentitiesCount< LocalMesh::getMeshDimension(), LocalMesh::getMeshDimension() - 1 >( K ); e++ ) { + const Index E = localMeshPointer->template getSubentityIndex< LocalMesh::getMeshDimension(), LocalMesh::getMeshDimension() - 1 >( K, e ); + if( f_E_view[ E ] > max ) { + max = f_E_view[ E ]; + } + } + f_K_view[ K ] = max; + }; + localMesh.template forLocal< LocalMesh::getMeshDimension() >( kernel ); + + // synchronize f_K + cell_sync.synchronize( f_K ); + + // write output + make_snapshot( iteration ); + + // check correctness + if( f_K_view != f_K_test_view ) { + std::cerr << "ERROR: propatation over faces differs from the propagation over neighbor cells. Differing values are:\n"; + for( Index K = 0; K < f_K_view.getSize(); K++ ) + if( f_K_view[ K ] != f_K_test_view[ K ] ) + std::cerr << " rank = " << CommunicatorType::GetRank() << ", K = " << K << ": " << f_K_view[ K ] << " instead of " << f_K_test_view[ K ] << "\n"; + std::cerr.flush(); + TNL_ASSERT_TRUE( false, "test failed" ); + } + + // check if finished + const bool done = sum( f_K.getData() ) == prev_sum || iteration > max_iterations; + CommunicatorType::Allreduce( &done, &all_done, 1, MPI_LAND, mesh.getCommunicationGroup() ); + } + while( all_done == false ); + + return true; +} + +void configSetup( Config::ConfigDescription& config ) +{ + config.addDelimiter( "General settings:" ); + config.addRequiredEntry< String >( "input-file", "Input file with the mesh." ); + config.addEntry< String >( "input-file-format", "Input mesh file format.", "auto" ); + config.addEntry< int >( "max-iterations", "Maximum number of iterations to compute", 100 ); + config.addDelimiter( "MPI settings:" ); + CommunicatorType::configSetup( config ); +} + +int main( int argc, char* argv[] ) +{ + Config::ParameterContainer parameters; + Config::ConfigDescription conf_desc; + + configSetup( conf_desc ); + + Communicators::ScopedInitializer< CommunicatorType > scopedInit(argc, argv); + + if( ! parseCommandLine( argc, argv, conf_desc, parameters ) ) + return EXIT_FAILURE; + + if( ! CommunicatorType::setup( parameters ) ) + return EXIT_FAILURE; + + const String inputFileName = parameters.getParameter< String >( "input-file" ); + const String inputFileFormat = parameters.getParameter< String >( "input-file-format" ); + const int max_iterations = parameters.getParameter< int >( "max-iterations" ); + + auto wrapper = [&] ( auto& reader, auto&& mesh ) -> bool + { + using MeshType = std::decay_t< decltype(mesh) >; + + // print basic mesh info + mesh.printInfo( std::cout ); + + // distribute faces + TNL::Meshes::DistributedMeshes::distributeSubentities< MeshType::getMeshDimension() - 1 >( mesh ); + + // test synchronizer + testSynchronizer( mesh ); + + // test simple propagation algorithm + return testPropagationOverFaces( std::forward(mesh), max_iterations ); + }; + return ! Meshes::resolveAndLoadDistributedMesh< MyConfigTag, Devices::Host >( wrapper, inputFileName, inputFileFormat ); +} diff --git a/src/UnitTests/Algorithms/CMakeLists.txt b/src/UnitTests/Algorithms/CMakeLists.txt index 6870bc84e402f924e48f24f7e95fe8d52dac9434..1f6cdbc1e1420ded227fe2855311ba74bfcd6bd7 100644 --- a/src/UnitTests/Algorithms/CMakeLists.txt +++ b/src/UnitTests/Algorithms/CMakeLists.txt @@ -1,29 +1,28 @@ -IF( BUILD_CUDA ) - CUDA_ADD_EXECUTABLE( MemoryOperationsTest MemoryOperationsTest.cu - OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( MemoryOperationsTest ${GTEST_BOTH_LIBRARIES} ) +set( COMMON_TESTS + MemoryOperationsTest + MultireductionTest + ParallelForTest +) - CUDA_ADD_EXECUTABLE( MultireductionTest MultireductionTest.cu - OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( MultireductionTest ${GTEST_BOTH_LIBRARIES} ) +set( CPP_TESTS ) +set( CUDA_TESTS ) +if( BUILD_CUDA ) + set( CUDA_TESTS ${CUDA_TESTS} ${COMMON_TESTS} ) +else() + set( CPP_TESTS ${CPP_TESTS} ${COMMON_TESTS} ) +endif() - CUDA_ADD_EXECUTABLE( ParallelForTest ParallelForTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( ParallelForTest ${GTEST_BOTH_LIBRARIES} ) -ELSE( BUILD_CUDA ) - ADD_EXECUTABLE( MemoryOperationsTest MemoryOperationsTest.cpp ) - TARGET_COMPILE_OPTIONS( MemoryOperationsTest PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( MemoryOperationsTest ${GTEST_BOTH_LIBRARIES} ) +foreach( target IN ITEMS ${CPP_TESTS} ) + add_executable( ${target} ${target}.cpp ) + target_compile_options( ${target} PRIVATE ${CXX_TESTS_FLAGS} ) + target_link_libraries( ${target} ${GTEST_BOTH_LIBRARIES} ) + add_test( ${target} ${EXECUTABLE_OUTPUT_PATH}/${target}${CMAKE_EXECUTABLE_SUFFIX} ) +endforeach() - ADD_EXECUTABLE( MultireductionTest MultireductionTest.cpp ) - TARGET_COMPILE_OPTIONS( MultireductionTest PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( MultireductionTest ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( ParallelForTest ParallelForTest.cpp ) - TARGET_COMPILE_OPTIONS( ParallelForTest PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( ParallelForTest ${GTEST_BOTH_LIBRARIES} ) -ENDIF( BUILD_CUDA ) - - -ADD_TEST( MemoryOperationsTest ${EXECUTABLE_OUTPUT_PATH}/MemoryOperationsTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( MultireductionTest ${EXECUTABLE_OUTPUT_PATH}/MultireductionTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( ParallelForTest ${EXECUTABLE_OUTPUT_PATH}/ParallelForTest${CMAKE_EXECUTABLE_SUFFIX} ) +if( BUILD_CUDA ) + foreach( target IN ITEMS ${CUDA_TESTS} ) + cuda_add_executable( ${target} ${target}.cu OPTIONS ${CXX_TESTS_FLAGS} ) + target_link_libraries( ${target} ${GTEST_BOTH_LIBRARIES} ) + add_test( ${target} ${EXECUTABLE_OUTPUT_PATH}/${target}${CMAKE_EXECUTABLE_SUFFIX} ) + endforeach() +endif() diff --git a/src/UnitTests/CMakeLists.txt b/src/UnitTests/CMakeLists.txt index 15a6bf9f0d058f28366b76fa50436cd0579c541e..788667c9afe7f0559b8973a65732472bec710b58 100644 --- a/src/UnitTests/CMakeLists.txt +++ b/src/UnitTests/CMakeLists.txt @@ -5,60 +5,25 @@ ADD_SUBDIRECTORY( Functions ) ADD_SUBDIRECTORY( Meshes ) ADD_SUBDIRECTORY( Pointers ) -ADD_EXECUTABLE( AssertTest AssertTest.cpp ) -TARGET_COMPILE_OPTIONS( AssertTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( AssertTest ${GTEST_BOTH_LIBRARIES} ) - -if( BUILD_CUDA ) - CUDA_ADD_EXECUTABLE( AssertCudaTest AssertCudaTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( AssertCudaTest ${GTEST_BOTH_LIBRARIES} ) -endif() - -if( BUILD_CUDA ) - CUDA_ADD_EXECUTABLE( AllocatorsTest AllocatorsTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( AllocatorsTest ${GTEST_BOTH_LIBRARIES} ) -else() - ADD_EXECUTABLE( AllocatorsTest AllocatorsTest.cpp ) - TARGET_COMPILE_OPTIONS( AllocatorsTest PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( AllocatorsTest ${GTEST_BOTH_LIBRARIES} ) -endif() - +set( CPP_TESTS AssertTest FileNameTest StringTest ObjectTest TimerTest TypeInfoTest ) +set( CUDA_TESTS AssertCudaTest ) if( BUILD_CUDA ) - CUDA_ADD_EXECUTABLE( FileTest FileTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( FileTest ${GTEST_BOTH_LIBRARIES} ) + set( CUDA_TESTS ${CUDA_TESTS} AllocatorsTest FileTest ) else() - ADD_EXECUTABLE( FileTest FileTest.cpp ) - TARGET_COMPILE_OPTIONS( FileTest PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( FileTest ${GTEST_BOTH_LIBRARIES} ) + set( CPP_TESTS ${CPP_TESTS} AllocatorsTest FileTest ) endif() -ADD_EXECUTABLE( FileNameTest FileNameTest.cpp ) -TARGET_COMPILE_OPTIONS( FileNameTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( FileNameTest ${GTEST_BOTH_LIBRARIES} ) - -ADD_EXECUTABLE( StringTest StringTest.cpp ) -TARGET_COMPILE_OPTIONS( StringTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( StringTest ${GTEST_BOTH_LIBRARIES} ) - -ADD_EXECUTABLE( ObjectTest ObjectTest.cpp ) -TARGET_COMPILE_OPTIONS( ObjectTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( ObjectTest ${GTEST_BOTH_LIBRARIES} ) - -ADD_EXECUTABLE( TimerTest TimerTest.cpp ) -TARGET_COMPILE_OPTIONS( TimerTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( TimerTest ${GTEST_BOTH_LIBRARIES} ) - -ADD_EXECUTABLE( TypeInfoTest TypeInfoTest.cpp ) -TARGET_COMPILE_OPTIONS( TypeInfoTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( TypeInfoTest ${GTEST_BOTH_LIBRARIES} ) +foreach( target IN ITEMS ${CPP_TESTS} ) + add_executable( ${target} ${target}.cpp ) + target_compile_options( ${target} PRIVATE ${CXX_TESTS_FLAGS} ) + target_link_libraries( ${target} ${GTEST_BOTH_LIBRARIES} ) + add_test( ${target} ${EXECUTABLE_OUTPUT_PATH}/${target}${CMAKE_EXECUTABLE_SUFFIX} ) +endforeach() -ADD_TEST( AssertTest ${EXECUTABLE_OUTPUT_PATH}/AssertTest${CMAKE_EXECUTABLE_SUFFIX} ) if( BUILD_CUDA ) - ADD_TEST( AssertCudaTest ${EXECUTABLE_OUTPUT_PATH}/AssertCudaTest${CMAKE_EXECUTABLE_SUFFIX} ) + foreach( target IN ITEMS ${CUDA_TESTS} ) + cuda_add_executable( ${target} ${target}.cu OPTIONS ${CXX_TESTS_FLAGS} ) + target_link_libraries( ${target} ${GTEST_BOTH_LIBRARIES} ) + add_test( ${target} ${EXECUTABLE_OUTPUT_PATH}/${target}${CMAKE_EXECUTABLE_SUFFIX} ) + endforeach() endif() -ADD_TEST( AllocatorsTest ${EXECUTABLE_OUTPUT_PATH}/AllocatorsTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( FileTest ${EXECUTABLE_OUTPUT_PATH}/FileTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( StringTest ${EXECUTABLE_OUTPUT_PATH}/StringTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( ObjectTest ${EXECUTABLE_OUTPUT_PATH}/ObjectTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( TimerTest ${EXECUTABLE_OUTPUT_PATH}/TimerTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( TypeInfoTest ${EXECUTABLE_OUTPUT_PATH}/TypeInfoTest${CMAKE_EXECUTABLE_SUFFIX} ) diff --git a/src/UnitTests/Containers/ArrayTest.cu b/src/UnitTests/Containers/ArrayTestCuda.cu similarity index 100% rename from src/UnitTests/Containers/ArrayTest.cu rename to src/UnitTests/Containers/ArrayTestCuda.cu diff --git a/src/UnitTests/Containers/ArrayViewTest.cu b/src/UnitTests/Containers/ArrayViewTestCuda.cu similarity index 100% rename from src/UnitTests/Containers/ArrayViewTest.cu rename to src/UnitTests/Containers/ArrayViewTestCuda.cu diff --git a/src/UnitTests/Containers/CMakeLists.txt b/src/UnitTests/Containers/CMakeLists.txt index ae3c1b0e712acde15fcbc3deb15fc374cb118148..41518028331ee0f9148105b19997a58ec9b238db 100644 --- a/src/UnitTests/Containers/CMakeLists.txt +++ b/src/UnitTests/Containers/CMakeLists.txt @@ -1,119 +1,54 @@ +ADD_SUBDIRECTORY( ndarray ) ADD_SUBDIRECTORY( Segments ) -ADD_EXECUTABLE( ArrayTest ArrayTest.cpp ) -TARGET_COMPILE_OPTIONS( ArrayTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( ArrayTest ${GTEST_BOTH_LIBRARIES} ) - -ADD_EXECUTABLE( ArrayViewTest ArrayViewTest.cpp ) -TARGET_COMPILE_OPTIONS( ArrayViewTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( ArrayViewTest ${GTEST_BOTH_LIBRARIES} ) - -# NOTE: Vector = Array + VectorOperations, VectorView = ArrayView + VectorOperations, -# so we test Vector, VectorView and VectorOperations at the same time -ADD_EXECUTABLE( VectorTest VectorTest.cpp ) -ADD_EXECUTABLE( VectorPrefixSumTest VectorPrefixSumTest.cpp ) -ADD_EXECUTABLE( VectorEvaluateAndReduceTest VectorEvaluateAndReduceTest.cpp ) -TARGET_COMPILE_OPTIONS( VectorTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_COMPILE_OPTIONS( VectorPrefixSumTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_COMPILE_OPTIONS( VectorEvaluateAndReduceTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( VectorTest ${GTEST_BOTH_LIBRARIES} ) -TARGET_LINK_LIBRARIES( VectorPrefixSumTest ${GTEST_BOTH_LIBRARIES} ) -TARGET_LINK_LIBRARIES( VectorEvaluateAndReduceTest ${GTEST_BOTH_LIBRARIES} ) - -ADD_EXECUTABLE( VectorBinaryOperationsTest VectorBinaryOperationsTest.cpp ) -TARGET_COMPILE_OPTIONS( VectorBinaryOperationsTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( VectorBinaryOperationsTest ${GTEST_BOTH_LIBRARIES} ) - -ADD_EXECUTABLE( VectorUnaryOperationsTest VectorUnaryOperationsTest.cpp ) -TARGET_COMPILE_OPTIONS( VectorUnaryOperationsTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( VectorUnaryOperationsTest ${GTEST_BOTH_LIBRARIES} ) - -ADD_EXECUTABLE( VectorVerticalOperationsTest VectorVerticalOperationsTest.cpp ) -TARGET_COMPILE_OPTIONS( VectorVerticalOperationsTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( VectorVerticalOperationsTest ${GTEST_BOTH_LIBRARIES} ) - -ADD_EXECUTABLE( VectorOfStaticVectorsTest VectorOfStaticVectorsTest.cpp ) -TARGET_COMPILE_OPTIONS( VectorOfStaticVectorsTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( VectorOfStaticVectorsTest ${GTEST_BOTH_LIBRARIES} ) - -IF( BUILD_CUDA ) - CUDA_ADD_EXECUTABLE( ArrayTestCuda ArrayTest.cu - OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( ArrayTestCuda ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( ArrayViewTestCuda ArrayViewTest.cu - OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( ArrayViewTestCuda ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( VectorTestCuda VectorTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - CUDA_ADD_EXECUTABLE( VectorPrefixSumTestCuda VectorPrefixSumTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - CUDA_ADD_EXECUTABLE( VectorEvaluateAndReduceTestCuda VectorEvaluateAndReduceTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( VectorTestCuda ${GTEST_BOTH_LIBRARIES} ) - TARGET_LINK_LIBRARIES( VectorPrefixSumTestCuda ${GTEST_BOTH_LIBRARIES} ) - TARGET_LINK_LIBRARIES( VectorEvaluateAndReduceTestCuda ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( VectorBinaryOperationsTestCuda VectorBinaryOperationsTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( VectorBinaryOperationsTestCuda ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( VectorUnaryOperationsTestCuda VectorUnaryOperationsTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( VectorUnaryOperationsTestCuda ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( VectorVerticalOperationsTestCuda VectorVerticalOperationsTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( VectorVerticalOperationsTestCuda ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( VectorOfStaticVectorsTestCuda VectorOfStaticVectorsTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( VectorOfStaticVectorsTestCuda ${GTEST_BOTH_LIBRARIES} ) -ENDIF( BUILD_CUDA ) - -ADD_EXECUTABLE( StaticArrayTest StaticArrayTest.cpp ) -TARGET_COMPILE_OPTIONS( StaticArrayTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( StaticArrayTest ${GTEST_BOTH_LIBRARIES} ) - -ADD_EXECUTABLE( StaticVectorTest StaticVectorTest.cpp ) -TARGET_COMPILE_OPTIONS( StaticVectorTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( StaticVectorTest ${GTEST_BOTH_LIBRARIES} ) - -ADD_EXECUTABLE( StaticVectorOperationsTest StaticVectorOperationsTest.cpp ) -TARGET_COMPILE_OPTIONS( StaticVectorOperationsTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( StaticVectorOperationsTest ${GTEST_BOTH_LIBRARIES} ) - -ADD_EXECUTABLE( StaticVectorOfStaticVectorsTest StaticVectorOfStaticVectorsTest.cpp ) -TARGET_COMPILE_OPTIONS( StaticVectorOfStaticVectorsTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( StaticVectorOfStaticVectorsTest ${GTEST_BOTH_LIBRARIES} ) - - -ADD_TEST( ArrayTest ${EXECUTABLE_OUTPUT_PATH}/ArrayTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( ArrayViewTest ${EXECUTABLE_OUTPUT_PATH}/ArrayViewTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( VectorTest ${EXECUTABLE_OUTPUT_PATH}/VectorTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( VectorPrefixSumTest ${EXECUTABLE_OUTPUT_PATH}/VectorPrefixSumTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( VectorEvaluateAndReduceTest ${EXECUTABLE_OUTPUT_PATH}/VectorEvaluateAndReduceTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( VectorBinaryOperationsTest ${EXECUTABLE_OUTPUT_PATH}/VectorBinaryOperationsTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( VectorUnaryOperationsTest ${EXECUTABLE_OUTPUT_PATH}/VectorUnaryOperationsTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( VectorVerticalOperationsTest ${EXECUTABLE_OUTPUT_PATH}/VectorVerticalOperationsTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( VectorOfStaticVectorsTest ${EXECUTABLE_OUTPUT_PATH}/VectorOfStaticVectorsTest${CMAKE_EXECUTABLE_SUFFIX} ) -IF( BUILD_CUDA ) - ADD_TEST( ArrayTestCuda ${EXECUTABLE_OUTPUT_PATH}/ArrayTestCuda${CMAKE_EXECUTABLE_SUFFIX} ) - ADD_TEST( ArrayViewTestCuda ${EXECUTABLE_OUTPUT_PATH}/ArrayViewTestCuda${CMAKE_EXECUTABLE_SUFFIX} ) - ADD_TEST( VectorTestCuda ${EXECUTABLE_OUTPUT_PATH}/VectorTestCuda${CMAKE_EXECUTABLE_SUFFIX} ) - ADD_TEST( VectorPrefixSumTestCuda ${EXECUTABLE_OUTPUT_PATH}/VectorPrefixSumTestCuda${CMAKE_EXECUTABLE_SUFFIX} ) - ADD_TEST( VectorEvaluateAndReduceTestCuda ${EXECUTABLE_OUTPUT_PATH}/VectorEvaluateAndReduceTestCuda${CMAKE_EXECUTABLE_SUFFIX} ) - ADD_TEST( VectorBinaryOperationsTestCuda ${EXECUTABLE_OUTPUT_PATH}/VectorBinaryOperationsTestCuda${CMAKE_EXECUTABLE_SUFFIX} ) - ADD_TEST( VectorUnaryOperationsTestCuda ${EXECUTABLE_OUTPUT_PATH}/VectorUnaryOperationsTestCuda${CMAKE_EXECUTABLE_SUFFIX} ) - ADD_TEST( VectorVerticalOperationsTestCuda ${EXECUTABLE_OUTPUT_PATH}/VectorVerticalOperationsTestCuda${CMAKE_EXECUTABLE_SUFFIX} ) -# ADD_TEST( VectorOfStaticVectorsTestCuda ${EXECUTABLE_OUTPUT_PATH}/VectorOfStaticVectorsTestCuda${CMAKE_EXECUTABLE_SUFFIX} ) -ENDIF() -ADD_TEST( StaticArrayTest ${EXECUTABLE_OUTPUT_PATH}/StaticArrayTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( StaticVectorTest ${EXECUTABLE_OUTPUT_PATH}/StaticVectorTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( StaticVectorOperationsTest ${EXECUTABLE_OUTPUT_PATH}/StaticVectorOperationsTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( StaticVectorOfStaticVectorsTest ${EXECUTABLE_OUTPUT_PATH}/StaticVectorOfStaticVectorsTest${CMAKE_EXECUTABLE_SUFFIX} ) - - -ADD_SUBDIRECTORY( ndarray ) +set( CPP_TESTS + ArrayTest + ArrayViewTest + StaticArrayTest + StaticVectorTest + StaticVectorOperationsTest + StaticVectorOfStaticVectorsTest + VectorTest + VectorPrefixSumTest + VectorEvaluateAndReduceTest + VectorBinaryOperationsTest + VectorUnaryOperationsTest + VectorVerticalOperationsTest + VectorOfStaticVectorsTest +) +set( CUDA_TESTS + ArrayTestCuda + ArrayViewTestCuda + VectorTestCuda + VectorPrefixSumTestCuda + VectorEvaluateAndReduceTestCuda + VectorBinaryOperationsTestCuda + VectorUnaryOperationsTestCuda + VectorVerticalOperationsTestCuda + # FIXME: fails due to unspecified launch failure in the CUDA reduction kernel for scalar product, + # see https://mmg-gitlab.fjfi.cvut.cz/gitlab/tnl/tnl-dev/-/issues/82 + #VectorOfStaticVectorsTestCuda +) + +foreach( target IN ITEMS ${CPP_TESTS} ) + add_executable( ${target} ${target}.cpp ) + target_compile_options( ${target} PRIVATE ${CXX_TESTS_FLAGS} ) + target_link_libraries( ${target} ${GTEST_BOTH_LIBRARIES} ) + add_test( ${target} ${EXECUTABLE_OUTPUT_PATH}/${target}${CMAKE_EXECUTABLE_SUFFIX} ) +endforeach() + +if( BUILD_CUDA ) + foreach( target IN ITEMS ${CUDA_TESTS} ) + cuda_add_executable( ${target} ${target}.cu OPTIONS ${CXX_TESTS_FLAGS} ) + target_link_libraries( ${target} ${GTEST_BOTH_LIBRARIES} ) + add_test( ${target} ${EXECUTABLE_OUTPUT_PATH}/${target}${CMAKE_EXECUTABLE_SUFFIX} ) + endforeach() +endif() if( ${BUILD_MPI} ) if( BUILD_CUDA ) - CUDA_ADD_EXECUTABLE( DistributedArrayTest DistributedArrayTest.cu + CUDA_ADD_EXECUTABLE( DistributedArrayTest DistributedArrayTestCuda.cu OPTIONS ${CXX_TESTS_FLAGS} ) TARGET_LINK_LIBRARIES( DistributedArrayTest ${GTEST_BOTH_LIBRARIES} ) else() @@ -127,7 +62,7 @@ if( ${BUILD_MPI} ) TARGET_LINK_LIBRARIES( DistributedVectorTest ${GTEST_BOTH_LIBRARIES} ) if( BUILD_CUDA ) - CUDA_ADD_EXECUTABLE( DistributedVectorTestCuda DistributedVectorTest.cu + CUDA_ADD_EXECUTABLE( DistributedVectorTestCuda DistributedVectorTestCuda.cu OPTIONS ${CXX_TESTS_FLAGS} ) TARGET_LINK_LIBRARIES( DistributedVectorTestCuda ${GTEST_BOTH_LIBRARIES} ) endif() @@ -145,13 +80,13 @@ if( ${BUILD_MPI} ) TARGET_LINK_LIBRARIES( DistributedVectorVerticalOperationsTest ${GTEST_BOTH_LIBRARIES} ) if( BUILD_CUDA ) - CUDA_ADD_EXECUTABLE( DistributedVectorBinaryOperationsTestCuda DistributedVectorBinaryOperationsTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) + CUDA_ADD_EXECUTABLE( DistributedVectorBinaryOperationsTestCuda DistributedVectorBinaryOperationsTestCuda.cu OPTIONS ${CXX_TESTS_FLAGS} ) TARGET_LINK_LIBRARIES( DistributedVectorBinaryOperationsTestCuda ${GTEST_BOTH_LIBRARIES} ) - CUDA_ADD_EXECUTABLE( DistributedVectorUnaryOperationsTestCuda DistributedVectorUnaryOperationsTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) + CUDA_ADD_EXECUTABLE( DistributedVectorUnaryOperationsTestCuda DistributedVectorUnaryOperationsTestCuda.cu OPTIONS ${CXX_TESTS_FLAGS} ) TARGET_LINK_LIBRARIES( DistributedVectorUnaryOperationsTestCuda ${GTEST_BOTH_LIBRARIES} ) - CUDA_ADD_EXECUTABLE( DistributedVectorVerticalOperationsTestCuda DistributedVectorVerticalOperationsTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) + CUDA_ADD_EXECUTABLE( DistributedVectorVerticalOperationsTestCuda DistributedVectorVerticalOperationsTestCuda.cu OPTIONS ${CXX_TESTS_FLAGS} ) TARGET_LINK_LIBRARIES( DistributedVectorVerticalOperationsTestCuda ${GTEST_BOTH_LIBRARIES} ) endif( BUILD_CUDA ) diff --git a/src/UnitTests/Containers/DistributedArrayTest.cu b/src/UnitTests/Containers/DistributedArrayTestCuda.cu similarity index 100% rename from src/UnitTests/Containers/DistributedArrayTest.cu rename to src/UnitTests/Containers/DistributedArrayTestCuda.cu diff --git a/src/UnitTests/Containers/DistributedVectorBinaryOperationsTest.cu b/src/UnitTests/Containers/DistributedVectorBinaryOperationsTestCuda.cu similarity index 100% rename from src/UnitTests/Containers/DistributedVectorBinaryOperationsTest.cu rename to src/UnitTests/Containers/DistributedVectorBinaryOperationsTestCuda.cu diff --git a/src/UnitTests/Containers/DistributedVectorTest.cu b/src/UnitTests/Containers/DistributedVectorTestCuda.cu similarity index 100% rename from src/UnitTests/Containers/DistributedVectorTest.cu rename to src/UnitTests/Containers/DistributedVectorTestCuda.cu diff --git a/src/UnitTests/Containers/DistributedVectorUnaryOperationsTest.cu b/src/UnitTests/Containers/DistributedVectorUnaryOperationsTestCuda.cu similarity index 100% rename from src/UnitTests/Containers/DistributedVectorUnaryOperationsTest.cu rename to src/UnitTests/Containers/DistributedVectorUnaryOperationsTestCuda.cu diff --git a/src/UnitTests/Containers/DistributedVectorVerticalOperationsTest.cu b/src/UnitTests/Containers/DistributedVectorVerticalOperationsTestCuda.cu similarity index 100% rename from src/UnitTests/Containers/DistributedVectorVerticalOperationsTest.cu rename to src/UnitTests/Containers/DistributedVectorVerticalOperationsTestCuda.cu diff --git a/src/UnitTests/Containers/Segments/CMakeLists.txt b/src/UnitTests/Containers/Segments/CMakeLists.txt index 742fb69ef3060451f54bacafdb7fc1ca0d49a64d..3b4067c314d874dd86cca485b20bb1fe9b4bea86 100644 --- a/src/UnitTests/Containers/Segments/CMakeLists.txt +++ b/src/UnitTests/Containers/Segments/CMakeLists.txt @@ -1,52 +1,31 @@ -IF( BUILD_CUDA ) -# CUDA_ADD_EXECUTABLE( SegmentsTest_AdEllpack SegmentsTest_AdEllpack.cu OPTIONS ${CXX_TESTS_FLAGS} ) -# TARGET_LINK_LIBRARIES( SegmentsTest_AdEllpack ${GTEST_BOTH_LIBRARIES} ) - -# CUDA_ADD_EXECUTABLE( SegmentsTest_BiEllpack SegmentsTest_BiEllpack.cu OPTIONS ${CXX_TESTS_FLAGS} ) -# TARGET_LINK_LIBRARIES( SegmentsTest_BiEllpack ${GTEST_BOTH_LIBRARIES} ) - -# CUDA_ADD_EXECUTABLE( SegmentsTest_ChunkedEllpack SegmentsTest_ChunkedEllpack.cu OPTIONS ${CXX_TESTS_FLAGS} ) -# TARGET_LINK_LIBRARIES( SegmentsTest_ChunkedEllpack ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( SegmentsTest_CSR SegmentsTest_CSR.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SegmentsTest_CSR ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( SegmentsTest_Ellpack SegmentsTest_Ellpack.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SegmentsTest_Ellpack ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( SegmentsTest_SlicedEllpack SegmentsTest_SlicedEllpack.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SegmentsTest_SlicedEllpack ${GTEST_BOTH_LIBRARIES} ) - -ELSE( BUILD_CUDA ) -# ADD_EXECUTABLE( SegmentsTest_AdEllpack SegmentsTest_AdEllpack.cpp ) -# TARGET_COMPILE_OPTIONS( SegmentsTest_AdEllpack PRIVATE ${CXX_TESTS_FLAGS} ) -# TARGET_LINK_LIBRARIES( SegmentsTest_AdEllpack ${GTEST_BOTH_LIBRARIES} ) - -# ADD_EXECUTABLE( SegmentsTest_BiEllpack SegmentsTest_BiEllpack.cpp ) -# TARGET_COMPILE_OPTIONS( SegmentsTest_BiEllpack PRIVATE ${CXX_TESTS_FLAGS} ) -# TARGET_LINK_LIBRARIES( SegmentsTest_BiEllpack ${GTEST_BOTH_LIBRARIES} ) - -# ADD_EXECUTABLE( SegmentsTest_ChunkedEllpack SegmentsTest_ChunkedEllpack.cpp ) -# TARGET_COMPILE_OPTIONS( SegmentsTest_ChunkedEllpack PRIVATE ${CXX_TESTS_FLAGS} ) -# TARGET_LINK_LIBRARIES( SegmentsTest_ChunkedEllpack ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( SegmentsTest_CSR SegmentsTest_CSR.cpp ) - TARGET_COMPILE_OPTIONS( SegmentsTest_CSR PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SegmentsTest_CSR ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( SegmentsTest_Ellpack SegmentsTest_Ellpack.cpp ) - TARGET_COMPILE_OPTIONS( SegmentsTest_Ellpack PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SegmentsTest_Ellpack ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( SegmentsTest_SlicedEllpack SegmentsTest_SlicedEllpack.cpp ) - TARGET_COMPILE_OPTIONS( SegmentsTest_SlicedEllpack PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SegmentsTest_SlicedEllpack ${GTEST_BOTH_LIBRARIES} ) -ENDIF( BUILD_CUDA ) - - -#ADD_TEST( SegmentsTest_BiEllpack ${EXECUTABLE_OUTPUT_PATH}/SegmentsTest_BiEllpack${CMAKE_EXECUTABLE_SUFFIX} ) -#ADD_TEST( SegmentsTest_ChunkedEllpack ${EXECUTABLE_OUTPUT_PATH}/SegmentsTest_ChunkedEllpack${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( SegmentsTest_CSR ${EXECUTABLE_OUTPUT_PATH}/SegmentsTest_CSR${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( SegmentsTest_Ellpack ${EXECUTABLE_OUTPUT_PATH}/SegmentsTest_Ellpack${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( SegmentsTest_SlicedEllpack ${EXECUTABLE_OUTPUT_PATH}/SegmentsTest_SlicedEllpack${CMAKE_EXECUTABLE_SUFFIX} ) - +set( COMMON_TESTS + #SegmentsTest_AdEllpack + #SegmentsTest_BiEllpack + #SegmentsTest_ChunkedEllpack + SegmentsTest_CSR + SegmentsTest_Ellpack + SegmentsTest_SlicedEllpack +) + +set( CPP_TESTS ) +set( CUDA_TESTS ) +if( BUILD_CUDA ) + set( CUDA_TESTS ${CUDA_TESTS} ${COMMON_TESTS} ) +else() + set( CPP_TESTS ${CPP_TESTS} ${COMMON_TESTS} ) +endif() + +foreach( target IN ITEMS ${CPP_TESTS} ) + add_executable( ${target} ${target}.cpp ) + target_compile_options( ${target} PRIVATE ${CXX_TESTS_FLAGS} ) + target_link_libraries( ${target} ${GTEST_BOTH_LIBRARIES} ) + add_test( ${target} ${EXECUTABLE_OUTPUT_PATH}/${target}${CMAKE_EXECUTABLE_SUFFIX} ) +endforeach() + +if( BUILD_CUDA ) + foreach( target IN ITEMS ${CUDA_TESTS} ) + cuda_add_executable( ${target} ${target}.cu OPTIONS ${CXX_TESTS_FLAGS} ) + target_link_libraries( ${target} ${GTEST_BOTH_LIBRARIES} ) + add_test( ${target} ${EXECUTABLE_OUTPUT_PATH}/${target}${CMAKE_EXECUTABLE_SUFFIX} ) + endforeach() +endif() diff --git a/src/UnitTests/Containers/VectorBinaryOperationsTest.cu b/src/UnitTests/Containers/VectorBinaryOperationsTestCuda.cu similarity index 100% rename from src/UnitTests/Containers/VectorBinaryOperationsTest.cu rename to src/UnitTests/Containers/VectorBinaryOperationsTestCuda.cu diff --git a/src/UnitTests/Containers/VectorEvaluateAndReduceTest.cu b/src/UnitTests/Containers/VectorEvaluateAndReduceTestCuda.cu similarity index 100% rename from src/UnitTests/Containers/VectorEvaluateAndReduceTest.cu rename to src/UnitTests/Containers/VectorEvaluateAndReduceTestCuda.cu diff --git a/src/UnitTests/Containers/VectorOfStaticVectorsTest.cu b/src/UnitTests/Containers/VectorOfStaticVectorsTestCuda.cu similarity index 100% rename from src/UnitTests/Containers/VectorOfStaticVectorsTest.cu rename to src/UnitTests/Containers/VectorOfStaticVectorsTestCuda.cu diff --git a/src/UnitTests/Containers/VectorPrefixSumTest.cu b/src/UnitTests/Containers/VectorPrefixSumTestCuda.cu similarity index 100% rename from src/UnitTests/Containers/VectorPrefixSumTest.cu rename to src/UnitTests/Containers/VectorPrefixSumTestCuda.cu diff --git a/src/UnitTests/Containers/VectorTest.cu b/src/UnitTests/Containers/VectorTestCuda.cu similarity index 100% rename from src/UnitTests/Containers/VectorTest.cu rename to src/UnitTests/Containers/VectorTestCuda.cu diff --git a/src/UnitTests/Containers/VectorUnaryOperationsTest.cu b/src/UnitTests/Containers/VectorUnaryOperationsTestCuda.cu similarity index 100% rename from src/UnitTests/Containers/VectorUnaryOperationsTest.cu rename to src/UnitTests/Containers/VectorUnaryOperationsTestCuda.cu diff --git a/src/UnitTests/Containers/VectorVerticalOperationsTest.cu b/src/UnitTests/Containers/VectorVerticalOperationsTestCuda.cu similarity index 100% rename from src/UnitTests/Containers/VectorVerticalOperationsTest.cu rename to src/UnitTests/Containers/VectorVerticalOperationsTestCuda.cu diff --git a/src/UnitTests/Containers/ndarray/CMakeLists.txt b/src/UnitTests/Containers/ndarray/CMakeLists.txt index 2f87d64a9b79db1b29dad644660da0a94b56d9e4..edcf7986cb5d4da62fd032baf04c577e77e78197 100644 --- a/src/UnitTests/Containers/ndarray/CMakeLists.txt +++ b/src/UnitTests/Containers/ndarray/CMakeLists.txt @@ -1,35 +1,24 @@ +set( CPP_TESTS NDSubarrayTest SlicedNDArrayTest StaticNDArrayTest ) +set( CUDA_TESTS StaticNDArrayCudaTest ) if( BUILD_CUDA ) - cuda_add_executable( NDArrayTest NDArrayTest.cu - OPTIONS ${CXX_TESTS_FLAGS} ) - target_link_libraries( NDArrayTest ${GTEST_BOTH_LIBRARIES} ) - add_test( NDArrayTest ${EXECUTABLE_OUTPUT_PATH}/NDArrayTest${CMAKE_EXECUTABLE_SUFFIX} ) + set( CUDA_TESTS ${CUDA_TESTS} NDArrayTest ) else() - add_executable( NDArrayTest NDArrayTest.cpp ) - target_compile_options( NDArrayTest PRIVATE ${CXX_TESTS_FLAGS} ) - target_link_libraries( NDArrayTest ${GTEST_BOTH_LIBRARIES} ) - add_test( NDArrayTest ${EXECUTABLE_OUTPUT_PATH}/NDArrayTest${CMAKE_EXECUTABLE_SUFFIX} ) + set( CPP_TESTS ${CPP_TESTS} NDArrayTest ) endif() -add_executable( NDSubarrayTest NDSubarrayTest.cpp ) -target_compile_options( NDSubarrayTest PRIVATE ${CXX_TESTS_FLAGS} ) -target_link_libraries( NDSubarrayTest ${GTEST_BOTH_LIBRARIES} ) -add_test( NDSubarrayTest ${EXECUTABLE_OUTPUT_PATH}/NDSubarrayTest${CMAKE_EXECUTABLE_SUFFIX} ) - -add_executable( SlicedNDArrayTest SlicedNDArrayTest.cpp ) -target_compile_options( SlicedNDArrayTest PRIVATE ${CXX_TESTS_FLAGS} ) -target_link_libraries( SlicedNDArrayTest ${GTEST_BOTH_LIBRARIES} ) -add_test( SlicedNDArrayTest ${EXECUTABLE_OUTPUT_PATH}/SlicedNDArrayTest${CMAKE_EXECUTABLE_SUFFIX} ) - -add_executable( StaticNDArrayTest StaticNDArrayTest.cpp ) -target_compile_options( StaticNDArrayTest PRIVATE ${CXX_TESTS_FLAGS} ) -target_link_libraries( StaticNDArrayTest ${GTEST_BOTH_LIBRARIES} ) -add_test( StaticNDArrayTest ${EXECUTABLE_OUTPUT_PATH}/StaticNDArrayTest${CMAKE_EXECUTABLE_SUFFIX} ) +foreach( target IN ITEMS ${CPP_TESTS} ) + add_executable( ${target} ${target}.cpp ) + target_compile_options( ${target} PRIVATE ${CXX_TESTS_FLAGS} ) + target_link_libraries( ${target} ${GTEST_BOTH_LIBRARIES} ) + add_test( ${target} ${EXECUTABLE_OUTPUT_PATH}/${target}${CMAKE_EXECUTABLE_SUFFIX} ) +endforeach() if( BUILD_CUDA ) - cuda_add_executable( StaticNDArrayCudaTest StaticNDArrayCudaTest.cu - OPTIONS ${CXX_TESTS_FLAGS} ) - target_link_libraries( StaticNDArrayCudaTest ${GTEST_BOTH_LIBRARIES} ) - add_test( StaticNDArrayCudaTest ${EXECUTABLE_OUTPUT_PATH}/StaticNDArrayCudaTest${CMAKE_EXECUTABLE_SUFFIX} ) + foreach( target IN ITEMS ${CUDA_TESTS} ) + cuda_add_executable( ${target} ${target}.cu OPTIONS ${CXX_TESTS_FLAGS} ) + target_link_libraries( ${target} ${GTEST_BOTH_LIBRARIES} ) + add_test( ${target} ${EXECUTABLE_OUTPUT_PATH}/${target}${CMAKE_EXECUTABLE_SUFFIX} ) + endforeach() endif() if( ${BUILD_MPI} ) diff --git a/src/UnitTests/Functions/CMakeLists.txt b/src/UnitTests/Functions/CMakeLists.txt index c2ee3ac042a26e2de08d6a800beae6b92e7082fe..8c03c3cbafa0a25601cb5558a535a22b4a11f4fe 100644 --- a/src/UnitTests/Functions/CMakeLists.txt +++ b/src/UnitTests/Functions/CMakeLists.txt @@ -1,25 +1,22 @@ -IF( BUILD_CUDA ) - CUDA_ADD_EXECUTABLE( MeshFunctionTest MeshFunctionTest.h MeshFunctionTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_COMPILE_OPTIONS( MeshFunctionTest PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( MeshFunctionTest ${GTEST_BOTH_LIBRARIES} ) +set( CPP_TESTS SaveAndLoadMeshfunctionTest ) +set( CUDA_TESTS ) +if( BUILD_CUDA ) + set( CUDA_TESTS ${CUDA_TESTS} BoundaryMeshFunctionTest MeshFunctionTest ) +else() + set( CPP_TESTS ${CPP_TESTS} BoundaryMeshFunctionTest MeshFunctionTest ) +endif() - CUDA_ADD_EXECUTABLE( BoundaryMeshFunctionTest BoundaryMeshFunctionTest.h BoundaryMeshFunctionTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_COMPILE_OPTIONS( BoundaryMeshFunctionTest PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( BoundaryMeshFunctionTest ${GTEST_BOTH_LIBRARIES} ) -ELSE( BUILD_CUDA ) - ADD_EXECUTABLE( MeshFunctionTest MeshFunctionTest.h MeshFunctionTest.cpp ) - TARGET_COMPILE_OPTIONS( MeshFunctionTest PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( MeshFunctionTest ${GTEST_BOTH_LIBRARIES} ) +foreach( target IN ITEMS ${CPP_TESTS} ) + add_executable( ${target} ${target}.cpp ) + target_compile_options( ${target} PRIVATE ${CXX_TESTS_FLAGS} ) + target_link_libraries( ${target} ${GTEST_BOTH_LIBRARIES} ) + add_test( ${target} ${EXECUTABLE_OUTPUT_PATH}/${target}${CMAKE_EXECUTABLE_SUFFIX} ) +endforeach() - ADD_EXECUTABLE( BoundaryMeshFunctionTest BoundaryMeshFunctionTest.h BoundaryMeshFunctionTest.cpp ) - TARGET_COMPILE_OPTIONS( BoundaryMeshFunctionTest PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( BoundaryMeshFunctionTest ${GTEST_BOTH_LIBRARIES} ) -ENDIF( BUILD_CUDA ) - -ADD_EXECUTABLE( SaveAndLoadMeshfunctionTest SaveAndLoadMeshfunctionTest.cpp ) -TARGET_COMPILE_OPTIONS( SaveAndLoadMeshfunctionTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( SaveAndLoadMeshfunctionTest ${GTEST_BOTH_LIBRARIES} ) - -ADD_TEST( MeshFunctionTest ${EXECUTABLE_OUTPUT_PATH}/MeshFunctionTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( BoundaryMeshFunctionTest ${EXECUTABLE_OUTPUT_PATH}/BoundaryMeshFunctionTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( SaveAndLoadMeshfunctionTest ${EXECUTABLE_OUTPUT_PATH}/SaveAndLoadMeshfunctionTest${CMAKE_EXECUTABLE_SUFFIX} ) +if( BUILD_CUDA ) + foreach( target IN ITEMS ${CUDA_TESTS} ) + cuda_add_executable( ${target} ${target}.cu OPTIONS ${CXX_TESTS_FLAGS} ) + target_link_libraries( ${target} ${GTEST_BOTH_LIBRARIES} ) + add_test( ${target} ${EXECUTABLE_OUTPUT_PATH}/${target}${CMAKE_EXECUTABLE_SUFFIX} ) + endforeach() +endif() diff --git a/src/UnitTests/Matrices/CMakeLists.txt b/src/UnitTests/Matrices/CMakeLists.txt index 778ab29bd39d6d7e994218b493448cc10d7c9d3c..727b2bc0b1669e8a9ea6d357f23c437df85980ec 100644 --- a/src/UnitTests/Matrices/CMakeLists.txt +++ b/src/UnitTests/Matrices/CMakeLists.txt @@ -1,137 +1,47 @@ ADD_SUBDIRECTORY( Legacy ) -IF( BUILD_CUDA ) - CUDA_ADD_EXECUTABLE( DenseMatrixTest DenseMatrixTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( DenseMatrixTest ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( DenseMatrixCopyTest DenseMatrixCopyTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( DenseMatrixCopyTest ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( TridiagonalMatrixTest TridiagonalMatrixTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( TridiagonalMatrixTest ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( MultidiagonalMatrixTest MultidiagonalMatrixTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( MultidiagonalMatrixTest ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( SparseMatrixTest_CSR SparseMatrixTest_CSR.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SparseMatrixTest_CSR ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( SparseMatrixTest_Ellpack SparseMatrixTest_Ellpack.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SparseMatrixTest_Ellpack ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( SparseMatrixTest_SlicedEllpack SparseMatrixTest_SlicedEllpack.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SparseMatrixTest_SlicedEllpack ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( SparseMatrixTest_ChunkedEllpack SparseMatrixTest_ChunkedEllpack.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SparseMatrixTest_ChunkedEllpack ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( SparseMatrixTest_BiEllpack SparseMatrixTest_BiEllpack.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SparseMatrixTest_BiEllpack ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( SparseMatrixCopyTest SparseMatrixCopyTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SparseMatrixCopyTest ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( BinarySparseMatrixTest_CSR BinarySparseMatrixTest_CSR.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( BinarySparseMatrixTest_CSR ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( BinarySparseMatrixTest_Ellpack BinarySparseMatrixTest_Ellpack.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( BinarySparseMatrixTest_Ellpack ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( BinarySparseMatrixTest_SlicedEllpack BinarySparseMatrixTest_SlicedEllpack.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( BinarySparseMatrixTest_SlicedEllpack ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( BinarySparseMatrixCopyTest BinarySparseMatrixCopyTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( BinarySparseMatrixCopyTest ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( SymmetricSparseMatrixTest_CSR SymmetricSparseMatrixTest_CSR.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SymmetricSparseMatrixTest_CSR ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( LambdaMatrixTest LambdaMatrixTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( LambdaMatrixTest ${GTEST_BOTH_LIBRARIES} ) - -ELSE( BUILD_CUDA ) - ADD_EXECUTABLE( DenseMatrixTest DenseMatrixTest.cpp ) - TARGET_COMPILE_OPTIONS( DenseMatrixTest PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( DenseMatrixTest ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( DenseMatrixCopyTest DenseMatrixCopyTest.cpp ) - TARGET_COMPILE_OPTIONS( DenseMatrixCopyTest PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( DenseMatrixCopyTest ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( TridiagonalMatrixTest TridiagonalMatrixTest.cpp ) - TARGET_COMPILE_OPTIONS( TridiagonalMatrixTest PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( TridiagonalMatrixTest ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( MultidiagonalMatrixTest MultidiagonalMatrixTest.cpp ) - TARGET_COMPILE_OPTIONS( MultidiagonalMatrixTest PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( MultidiagonalMatrixTest ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( SparseMatrixTest_CSR SparseMatrixTest_CSR.cpp ) - TARGET_COMPILE_OPTIONS( SparseMatrixTest_CSR PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SparseMatrixTest_CSR ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( SparseMatrixTest_Ellpack SparseMatrixTest_Ellpack.cpp ) - TARGET_COMPILE_OPTIONS( SparseMatrixTest_Ellpack PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SparseMatrixTest_Ellpack ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( SparseMatrixTest_SlicedEllpack SparseMatrixTest_SlicedEllpack.cpp ) - TARGET_COMPILE_OPTIONS( SparseMatrixTest_SlicedEllpack PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SparseMatrixTest_SlicedEllpack ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( SparseMatrixTest_ChunkedEllpack SparseMatrixTest_ChunkedEllpack.cpp ) - TARGET_COMPILE_OPTIONS( SparseMatrixTest_ChunkedEllpack PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SparseMatrixTest_ChunkedEllpack ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( SparseMatrixTest_BiEllpack SparseMatrixTest_BiEllpack.cpp ) - TARGET_COMPILE_OPTIONS( SparseMatrixTest_BiEllpack PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SparseMatrixTest_BiEllpack ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( SparseMatrixCopyTest SparseMatrixCopyTest.cpp ) - TARGET_COMPILE_OPTIONS( SparseMatrixCopyTest PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SparseMatrixCopyTest ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( BinarySparseMatrixTest_CSR BinarySparseMatrixTest_CSR.cpp ) - TARGET_COMPILE_OPTIONS( BinarySparseMatrixTest_CSR PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( BinarySparseMatrixTest_CSR ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( BinarySparseMatrixTest_Ellpack BinarySparseMatrixTest_Ellpack.cpp ) - TARGET_COMPILE_OPTIONS( BinarySparseMatrixTest_Ellpack PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( BinarySparseMatrixTest_Ellpack ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( BinarySparseMatrixTest_SlicedEllpack BinarySparseMatrixTest_SlicedEllpack.cpp ) - TARGET_COMPILE_OPTIONS( BinarySparseMatrixTest_SlicedEllpack PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( BinarySparseMatrixTest_SlicedEllpack ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( BinarySparseMatrixCopyTest BinarySparseMatrixCopyTest.cpp ) - TARGET_COMPILE_OPTIONS( BinarySparseMatrixCopyTest PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( BinarySparseMatrixCopyTest ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( SymmetricSparseMatrixTest_CSR SymmetricSparseMatrixTest_CSR.cpp ) - TARGET_COMPILE_OPTIONS( SymmetricSparseMatrixTest_CSR PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SymmetricSparseMatrixTest_CSR ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( LambdaMatrixTest LambdaMatrixTest.cpp ) - TARGET_COMPILE_OPTIONS( LambdaMatrixTest PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( LambdaMatrixTest ${GTEST_BOTH_LIBRARIES} ) - -ENDIF( BUILD_CUDA ) - -ADD_TEST( DenseMatrixTest ${EXECUTABLE_OUTPUT_PATH}/DenseMatrixTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( TridiagonalMatrixTest ${EXECUTABLE_OUTPUT_PATH}/TridiagonalMatrixTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( MultidiagonalMatrixTest ${EXECUTABLE_OUTPUT_PATH}/MultidiagonalMatrixTest${CMAKE_EXECUTABLE_SUFFIX} ) +set( COMMON_TESTS + DenseMatrixTest + DenseMatrixCopyTest + TridiagonalMatrixTest + MultidiagonalMatrixTest + + SparseMatrixTest_CSR + SparseMatrixTest_Ellpack + SparseMatrixTest_SlicedEllpack + SparseMatrixTest_ChunkedEllpack + SparseMatrixTest_BiEllpack + SparseMatrixCopyTest + BinarySparseMatrixTest_CSR + BinarySparseMatrixTest_Ellpack + BinarySparseMatrixTest_SlicedEllpack + BinarySparseMatrixCopyTest + SymmetricSparseMatrixTest_CSR + LambdaMatrixTest +) + +set( CPP_TESTS ) +set( CUDA_TESTS ) +if( BUILD_CUDA ) + set( CUDA_TESTS ${CUDA_TESTS} ${COMMON_TESTS} ) +else() + set( CPP_TESTS ${CPP_TESTS} ${COMMON_TESTS} ) +endif() -ADD_TEST( SparseMatrixTest_CSR ${EXECUTABLE_OUTPUT_PATH}/SparseMatrixTest_CSR${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( SparseMatrixTest_Ellpack ${EXECUTABLE_OUTPUT_PATH}/SparseMatrixTest_Ellpack${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( SparseMatrixTest_SlicedEllpack ${EXECUTABLE_OUTPUT_PATH}/SparseMatrixTest_SlicedEllpack${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( SparseMatrixTest_ChunkedEllpack ${EXECUTABLE_OUTPUT_PATH}/SparseMatrixTest_ChunkedEllpack${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( SparseMatrixTest_BiEllpack ${EXECUTABLE_OUTPUT_PATH}/SparseMatrixTest_BiEllpack${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( SparseMatrixCopyTest ${EXECUTABLE_OUTPUT_PATH}/SparseMatrixCopyTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( BinarySparseMatrixTest_CSR ${EXECUTABLE_OUTPUT_PATH}/BinarySparseMatrixTest_CSR${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( BinarySparseMatrixTest_Ellpack ${EXECUTABLE_OUTPUT_PATH}/BinarySparseMatrixTest_Ellpack${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( BinarySparseMatrixTest_SlicedEllpack ${EXECUTABLE_OUTPUT_PATH}/BinarySparseMatrixTest_SlicedEllpack${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( BinarySparseMatrixCopyTest ${EXECUTABLE_OUTPUT_PATH}/BinarySparseMatrixCopyTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( SymmetricSparseMatrixTest_CSR ${EXECUTABLE_OUTPUT_PATH}/SymmetricSparseMatrixTest_CSR${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( LambdaMatrixTest ${EXECUTABLE_OUTPUT_PATH}/LambdaMatrixTest${CMAKE_EXECUTABLE_SUFFIX} ) +foreach( target IN ITEMS ${CPP_TESTS} ) + add_executable( ${target} ${target}.cpp ) + target_compile_options( ${target} PRIVATE ${CXX_TESTS_FLAGS} ) + target_link_libraries( ${target} ${GTEST_BOTH_LIBRARIES} ) + add_test( ${target} ${EXECUTABLE_OUTPUT_PATH}/${target}${CMAKE_EXECUTABLE_SUFFIX} ) +endforeach() + +if( BUILD_CUDA ) + foreach( target IN ITEMS ${CUDA_TESTS} ) + cuda_add_executable( ${target} ${target}.cu OPTIONS ${CXX_TESTS_FLAGS} ) + target_link_libraries( ${target} ${GTEST_BOTH_LIBRARIES} ) + add_test( ${target} ${EXECUTABLE_OUTPUT_PATH}/${target}${CMAKE_EXECUTABLE_SUFFIX} ) + endforeach() +endif() if( ${BUILD_MPI} ) if( BUILD_CUDA ) diff --git a/src/UnitTests/Matrices/Legacy/CMakeLists.txt b/src/UnitTests/Matrices/Legacy/CMakeLists.txt index 2e7297cceb0f73d197be8b5e2bf80f5c69b4d06b..cb73ad5af0f798a2904490ef24ec41c15233488f 100644 --- a/src/UnitTests/Matrices/Legacy/CMakeLists.txt +++ b/src/UnitTests/Matrices/Legacy/CMakeLists.txt @@ -1,72 +1,34 @@ -IF( BUILD_CUDA ) - #CUDA_ADD_EXECUTABLE( Legacy_SparseMatrixCopyTest SparseMatrixCopyTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - #TARGET_LINK_LIBRARIES( Legacy_SparseMatrixCopyTest ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( Legacy_SparseMatrixTest SparseMatrixTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( Legacy_SparseMatrixTest ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( Legacy_SparseMatrixTest_AdEllpack SparseMatrixTest_AdEllpack.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( Legacy_SparseMatrixTest_AdEllpack ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( Legacy_SparseMatrixTest_BiEllpack SparseMatrixTest_BiEllpack.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( Legacy_SparseMatrixTest_BiEllpack ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( Legacy_SparseMatrixTest_ChunkedEllpack SparseMatrixTest_ChunkedEllpack.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( Legacy_SparseMatrixTest_ChunkedEllpack ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( Legacy_SparseMatrixTest_CSR SparseMatrixTest_CSR.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( Legacy_SparseMatrixTest_CSR ${GTEST_BOTH_LIBRARIES} ${CUDA_cudadevrt_LIBRARY} ) - - CUDA_ADD_EXECUTABLE( Legacy_SparseMatrixTest_Ellpack SparseMatrixTest_Ellpack.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( Legacy_SparseMatrixTest_Ellpack ${GTEST_BOTH_LIBRARIES} ) - - CUDA_ADD_EXECUTABLE( Legacy_SparseMatrixTest_SlicedEllpack SparseMatrixTest_SlicedEllpack.cu OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( Legacy_SparseMatrixTest_SlicedEllpack ${GTEST_BOTH_LIBRARIES} ) - -ELSE( BUILD_CUDA ) - #ADD_EXECUTABLE( Legacy_SparseMatrixCopyTest SparseMatrixCopyTest.cpp ) - #TARGET_COMPILE_OPTIONS( Legacy_SparseMatrixCopyTest PRIVATE ${CXX_TESTS_FLAGS} ) - #TARGET_LINK_LIBRARIES( Legacy_SparseMatrixCopyTest ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( Legacy_SparseMatrixTest SparseMatrixTest.cpp ) - TARGET_COMPILE_OPTIONS( Legacy_SparseMatrixTest PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( Legacy_SparseMatrixTest ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( Legacy_SparseMatrixTest_AdEllpack SparseMatrixTest_AdEllpack.cpp ) - TARGET_COMPILE_OPTIONS( Legacy_SparseMatrixTest_AdEllpack PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( Legacy_SparseMatrixTest_AdEllpack ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( Legacy_SparseMatrixTest_BiEllpack SparseMatrixTest_BiEllpack.cpp ) - TARGET_COMPILE_OPTIONS( Legacy_SparseMatrixTest_BiEllpack PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( Legacy_SparseMatrixTest_BiEllpack ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( Legacy_SparseMatrixTest_ChunkedEllpack SparseMatrixTest_ChunkedEllpack.cpp ) - TARGET_COMPILE_OPTIONS( Legacy_SparseMatrixTest_ChunkedEllpack PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( Legacy_SparseMatrixTest_ChunkedEllpack ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( Legacy_SparseMatrixTest_CSR SparseMatrixTest_CSR.cpp ) - TARGET_COMPILE_OPTIONS( Legacy_SparseMatrixTest_CSR PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( Legacy_SparseMatrixTest_CSR ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( Legacy_SparseMatrixTest_Ellpack SparseMatrixTest_Ellpack.cpp ) - TARGET_COMPILE_OPTIONS( Legacy_SparseMatrixTest_Ellpack PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( Legacy_SparseMatrixTest_Ellpack ${GTEST_BOTH_LIBRARIES} ) - - ADD_EXECUTABLE( Legacy_SparseMatrixTest_SlicedEllpack SparseMatrixTest_SlicedEllpack.cpp ) - TARGET_COMPILE_OPTIONS( Legacy_SparseMatrixTest_SlicedEllpack PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( Legacy_SparseMatrixTest_SlicedEllpack ${GTEST_BOTH_LIBRARIES} ) - -ENDIF( BUILD_CUDA ) - - -#ADD_TEST( Legacy_SparseMatrixCopyTest ${EXECUTABLE_OUTPUT_PATH}/Legacy_SparseMatrixCopyTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( Legacy_SparseMatrixTest ${EXECUTABLE_OUTPUT_PATH}/Legacy_SparseMatrixTest${CMAKE_EXECUTABLE_SUFFIX} ) -# TODO: Uncomment the following when AdEllpack works -#ADD_TEST( SparseMatrixTest_AdEllpack ${EXECUTABLE_OUTPUT_PATH}/SparseMatrixTest_AdEllpack${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( Legacy_SparseMatrixTest_BiEllpack ${EXECUTABLE_OUTPUT_PATH}/Legacy_SparseMatrixTest_BiEllpack${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( Legacy_SparseMatrixTest_ChunkedEllpack ${EXECUTABLE_OUTPUT_PATH}/Legacy_SparseMatrixTest_ChunkedEllpack${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( Legacy_SparseMatrixTest_CSR ${EXECUTABLE_OUTPUT_PATH}/Legacy_SparseMatrixTest_CSR${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( Legacy_SparseMatrixTest_Ellpack ${EXECUTABLE_OUTPUT_PATH}/Legacy_SparseMatrixTest_Ellpack${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( Legacy_SparseMatrixTest_SlicedEllpack ${EXECUTABLE_OUTPUT_PATH}/Legacy_SparseMatrixTest_SlicedEllpack${CMAKE_EXECUTABLE_SUFFIX} ) -# TODO: DenseMatrixTest is not finished -#ADD_TEST( DenseMatrixTest ${EXECUTABLE_OUTPUT_PATH}/DenseMatrixTest${CMAKE_EXECUTABLE_SUFFIX} ) +set( COMMON_TESTS + #Legacy_SparseMatrixCopyTest + Legacy_SparseMatrixTest + # TODO: Uncomment the following when AdEllpack works + #SparseMatrixTest_AdEllpack + Legacy_SparseMatrixTest_BiEllpack + Legacy_SparseMatrixTest_ChunkedEllpack + Legacy_SparseMatrixTest_CSR + Legacy_SparseMatrixTest_Ellpack + Legacy_SparseMatrixTest_SlicedEllpack +) + +set( CPP_TESTS ) +set( CUDA_TESTS ) +if( BUILD_CUDA ) + set( CUDA_TESTS ${CUDA_TESTS} ${COMMON_TESTS} ) +else() + set( CPP_TESTS ${CPP_TESTS} ${COMMON_TESTS} ) +endif() + +foreach( target IN ITEMS ${CPP_TESTS} ) + add_executable( ${target} ${target}.cpp ) + target_compile_options( ${target} PRIVATE ${CXX_TESTS_FLAGS} ) + target_link_libraries( ${target} ${GTEST_BOTH_LIBRARIES} ) + add_test( ${target} ${EXECUTABLE_OUTPUT_PATH}/${target}${CMAKE_EXECUTABLE_SUFFIX} ) +endforeach() + +if( BUILD_CUDA ) + foreach( target IN ITEMS ${CUDA_TESTS} ) + cuda_add_executable( ${target} ${target}.cu OPTIONS ${CXX_TESTS_FLAGS} ) + target_link_libraries( ${target} ${GTEST_BOTH_LIBRARIES} ) + add_test( ${target} ${EXECUTABLE_OUTPUT_PATH}/${target}${CMAKE_EXECUTABLE_SUFFIX} ) + endforeach() +endif() diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixCopyTest.cpp b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixCopyTest.cpp similarity index 92% rename from src/UnitTests/Matrices/Legacy/SparseMatrixCopyTest.cpp rename to src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixCopyTest.cpp index 30b8f64ecfdbf228856d272a71d3de08980f3987..61c5201afc1b98a0f54525aecc989a8f81a88b85 100644 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixCopyTest.cpp +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixCopyTest.cpp @@ -8,4 +8,4 @@ /* See Copyright Notice in tnl/Copyright */ -#include "SparseMatrixCopyTest.h" +#include "Legacy_SparseMatrixCopyTest.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixCopyTest.cu b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixCopyTest.cu similarity index 92% rename from src/UnitTests/Matrices/Legacy/SparseMatrixCopyTest.cu rename to src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixCopyTest.cu index 431fe481c2db1d5b18cfa849e882c0ed836463c1..9e46803d1fa9ff2b1fdd57e640582190c3ad689f 100644 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixCopyTest.cu +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixCopyTest.cu @@ -8,4 +8,4 @@ /* See Copyright Notice in tnl/Copyright */ -#include "SparseMatrixCopyTest.h" +#include "Legacy_SparseMatrixCopyTest.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixCopyTest.h b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixCopyTest.h similarity index 100% rename from src/UnitTests/Matrices/Legacy/SparseMatrixCopyTest.h rename to src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixCopyTest.h diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest.cpp b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest.cpp similarity index 92% rename from src/UnitTests/Matrices/Legacy/SparseMatrixTest.cpp rename to src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest.cpp index 46f6b9bd3531652feb15f10d60e5736ddfb627fa..7d9843ba2b147524c6cbe60664fd90ffbd64bfed 100644 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest.cpp +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest.cpp @@ -8,4 +8,4 @@ /* See Copyright Notice in tnl/Copyright */ -#include "SparseMatrixTest.h" \ No newline at end of file +#include "Legacy_SparseMatrixTest.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest.cu b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest.cu similarity index 92% rename from src/UnitTests/Matrices/Legacy/SparseMatrixTest.cu rename to src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest.cu index 01c23c1937b6ea39c2c99647207d74297ea588c9..cfffec8451d5192dc06b2703081325d9d60eb16e 100644 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest.cu +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest.cu @@ -8,4 +8,4 @@ /* See Copyright Notice in tnl/Copyright */ -#include "SparseMatrixTest.h" \ No newline at end of file +#include "Legacy_SparseMatrixTest.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest.h b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest.h similarity index 96% rename from src/UnitTests/Matrices/Legacy/SparseMatrixTest.h rename to src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest.h index f7ee41411f33826c0b4fd01d82d17267bf75bd11..db79594387b88fc67a3db7e2fec212577537d1f8 100644 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest.h +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest.h @@ -10,7 +10,7 @@ #include -#include "SparseMatrixTest.hpp" +#include "Legacy_SparseMatrixTest.hpp" #include #ifdef HAVE_GTEST diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest.hpp b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest.hpp similarity index 100% rename from src/UnitTests/Matrices/Legacy/SparseMatrixTest.hpp rename to src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest.hpp diff --git a/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_AdEllpack.cpp b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_AdEllpack.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f5baa1c809793ed4a2cac86c039b1963b80dab0e --- /dev/null +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_AdEllpack.cpp @@ -0,0 +1 @@ +#include "Legacy_SparseMatrixTest_AdEllpack.h" diff --git a/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_AdEllpack.cu b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_AdEllpack.cu new file mode 100644 index 0000000000000000000000000000000000000000..f5baa1c809793ed4a2cac86c039b1963b80dab0e --- /dev/null +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_AdEllpack.cu @@ -0,0 +1 @@ +#include "Legacy_SparseMatrixTest_AdEllpack.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_AdEllpack.h b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_AdEllpack.h similarity index 99% rename from src/UnitTests/Matrices/Legacy/SparseMatrixTest_AdEllpack.h rename to src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_AdEllpack.h index ca2b0b9724907b5576699e7b6f4598c825b52099..1b63ab8433c0e64608a702ea4ac78ccf76906015 100644 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_AdEllpack.h +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_AdEllpack.h @@ -10,7 +10,7 @@ #include -#include "SparseMatrixTest.hpp" +#include "Legacy_SparseMatrixTest.hpp" #include #ifdef HAVE_GTEST diff --git a/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_BiEllpack.cpp b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_BiEllpack.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9d9a9ce8c403d059e375686a5a1b4bee220103c6 --- /dev/null +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_BiEllpack.cpp @@ -0,0 +1 @@ +#include "Legacy_SparseMatrixTest_BiEllpack.h" diff --git a/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_BiEllpack.cu b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_BiEllpack.cu new file mode 100644 index 0000000000000000000000000000000000000000..9d9a9ce8c403d059e375686a5a1b4bee220103c6 --- /dev/null +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_BiEllpack.cu @@ -0,0 +1 @@ +#include "Legacy_SparseMatrixTest_BiEllpack.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_BiEllpack.h b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_BiEllpack.h similarity index 99% rename from src/UnitTests/Matrices/Legacy/SparseMatrixTest_BiEllpack.h rename to src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_BiEllpack.h index d0277e27cbedd269e17bd6517fbf5027da112cde..e443a61783e4d3a9b0811b6e5e3f1975750342a0 100644 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_BiEllpack.h +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_BiEllpack.h @@ -10,7 +10,7 @@ #include -#include "SparseMatrixTest.hpp" +#include "Legacy_SparseMatrixTest.hpp" #include #ifdef HAVE_GTEST diff --git a/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_CSR.cpp b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_CSR.cpp new file mode 100644 index 0000000000000000000000000000000000000000..981914b3be40fe69e64533480f356a416e46873f --- /dev/null +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_CSR.cpp @@ -0,0 +1 @@ +#include "Legacy_SparseMatrixTest_CSR.h" diff --git a/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_CSR.cu b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_CSR.cu new file mode 100644 index 0000000000000000000000000000000000000000..981914b3be40fe69e64533480f356a416e46873f --- /dev/null +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_CSR.cu @@ -0,0 +1 @@ +#include "Legacy_SparseMatrixTest_CSR.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_CSR.h b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_CSR.h similarity index 99% rename from src/UnitTests/Matrices/Legacy/SparseMatrixTest_CSR.h rename to src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_CSR.h index 4b9325e06269e98d9d9f5b9b1e3556c6efed325a..c43185c141c250f975a2a3a0237d214df5e1e874 100644 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_CSR.h +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_CSR.h @@ -10,7 +10,7 @@ #include -#include "SparseMatrixTest.hpp" +#include "Legacy_SparseMatrixTest.hpp" #include #ifdef HAVE_GTEST diff --git a/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_ChunkedEllpack.cpp b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_ChunkedEllpack.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3a913069806e57aec7674da67768e605e956da46 --- /dev/null +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_ChunkedEllpack.cpp @@ -0,0 +1 @@ +#include "Legacy_SparseMatrixTest_ChunkedEllpack.h" diff --git a/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_ChunkedEllpack.cu b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_ChunkedEllpack.cu new file mode 100644 index 0000000000000000000000000000000000000000..3a913069806e57aec7674da67768e605e956da46 --- /dev/null +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_ChunkedEllpack.cu @@ -0,0 +1 @@ +#include "Legacy_SparseMatrixTest_ChunkedEllpack.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_ChunkedEllpack.h b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_ChunkedEllpack.h similarity index 99% rename from src/UnitTests/Matrices/Legacy/SparseMatrixTest_ChunkedEllpack.h rename to src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_ChunkedEllpack.h index f0ee7c079b66320fd5404e92ec7ee65eb7f4f9f5..84d0151887b5e8f2c08afe5c6f2811539d0b9935 100644 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_ChunkedEllpack.h +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_ChunkedEllpack.h @@ -10,7 +10,7 @@ #include -#include "SparseMatrixTest.hpp" +#include "Legacy_SparseMatrixTest.hpp" #include #ifdef HAVE_GTEST diff --git a/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_Ellpack.cpp b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_Ellpack.cpp new file mode 100644 index 0000000000000000000000000000000000000000..839235aaf712038f39feca62316ec50e8305b302 --- /dev/null +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_Ellpack.cpp @@ -0,0 +1 @@ +#include "Legacy_SparseMatrixTest_Ellpack.h" diff --git a/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_Ellpack.cu b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_Ellpack.cu new file mode 100644 index 0000000000000000000000000000000000000000..839235aaf712038f39feca62316ec50e8305b302 --- /dev/null +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_Ellpack.cu @@ -0,0 +1 @@ +#include "Legacy_SparseMatrixTest_Ellpack.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_Ellpack.h b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_Ellpack.h similarity index 99% rename from src/UnitTests/Matrices/Legacy/SparseMatrixTest_Ellpack.h rename to src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_Ellpack.h index 8376654cdda95d723e5e68613117c6718e030270..307e5728a9114ccbf37c68182f33f55dc1158a1a 100644 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_Ellpack.h +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_Ellpack.h @@ -10,7 +10,7 @@ #include -#include "SparseMatrixTest.hpp" +#include "Legacy_SparseMatrixTest.hpp" #include #ifdef HAVE_GTEST diff --git a/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_SlicedEllpack.cpp b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_SlicedEllpack.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ef75cbcfa77df24dbe6f8d1628112509758e8817 --- /dev/null +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_SlicedEllpack.cpp @@ -0,0 +1 @@ +#include "Legacy_SparseMatrixTest_SlicedEllpack.h" diff --git a/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_SlicedEllpack.cu b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_SlicedEllpack.cu new file mode 100644 index 0000000000000000000000000000000000000000..ef75cbcfa77df24dbe6f8d1628112509758e8817 --- /dev/null +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_SlicedEllpack.cu @@ -0,0 +1 @@ +#include "Legacy_SparseMatrixTest_SlicedEllpack.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_SlicedEllpack.h b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_SlicedEllpack.h similarity index 99% rename from src/UnitTests/Matrices/Legacy/SparseMatrixTest_SlicedEllpack.h rename to src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_SlicedEllpack.h index 9ffba75041066790ba0b6439b23e5f19e1c0bd80..b975c9c602248232de799e0e7dc09b0c9ce35e00 100644 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_SlicedEllpack.h +++ b/src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_SlicedEllpack.h @@ -11,7 +11,7 @@ #include -#include "SparseMatrixTest.hpp" +#include "Legacy_SparseMatrixTest.hpp" #include #ifdef HAVE_GTEST diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_AdEllpack.cpp b/src/UnitTests/Matrices/Legacy/SparseMatrixTest_AdEllpack.cpp deleted file mode 100644 index 563a3dc2686b30d8d73dda8a37d2187508139b16..0000000000000000000000000000000000000000 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_AdEllpack.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "SparseMatrixTest_AdEllpack.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_AdEllpack.cu b/src/UnitTests/Matrices/Legacy/SparseMatrixTest_AdEllpack.cu deleted file mode 100644 index 563a3dc2686b30d8d73dda8a37d2187508139b16..0000000000000000000000000000000000000000 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_AdEllpack.cu +++ /dev/null @@ -1 +0,0 @@ -#include "SparseMatrixTest_AdEllpack.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_BiEllpack.cpp b/src/UnitTests/Matrices/Legacy/SparseMatrixTest_BiEllpack.cpp deleted file mode 100644 index ccb62e4a87cb3abada95e807bca652106fb92538..0000000000000000000000000000000000000000 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_BiEllpack.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "SparseMatrixTest_BiEllpack.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_BiEllpack.cu b/src/UnitTests/Matrices/Legacy/SparseMatrixTest_BiEllpack.cu deleted file mode 100644 index ccb62e4a87cb3abada95e807bca652106fb92538..0000000000000000000000000000000000000000 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_BiEllpack.cu +++ /dev/null @@ -1 +0,0 @@ -#include "SparseMatrixTest_BiEllpack.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_CSR.cpp b/src/UnitTests/Matrices/Legacy/SparseMatrixTest_CSR.cpp deleted file mode 100644 index 258ad2c53831010111eeec9dc240368ae5dffb35..0000000000000000000000000000000000000000 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_CSR.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "SparseMatrixTest_CSR.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_CSR.cu b/src/UnitTests/Matrices/Legacy/SparseMatrixTest_CSR.cu deleted file mode 100644 index 258ad2c53831010111eeec9dc240368ae5dffb35..0000000000000000000000000000000000000000 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_CSR.cu +++ /dev/null @@ -1 +0,0 @@ -#include "SparseMatrixTest_CSR.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_ChunkedEllpack.cpp b/src/UnitTests/Matrices/Legacy/SparseMatrixTest_ChunkedEllpack.cpp deleted file mode 100644 index c09609ae6c664298693799efe3751ca082e2d129..0000000000000000000000000000000000000000 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_ChunkedEllpack.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "SparseMatrixTest_ChunkedEllpack.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_ChunkedEllpack.cu b/src/UnitTests/Matrices/Legacy/SparseMatrixTest_ChunkedEllpack.cu deleted file mode 100644 index c09609ae6c664298693799efe3751ca082e2d129..0000000000000000000000000000000000000000 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_ChunkedEllpack.cu +++ /dev/null @@ -1 +0,0 @@ -#include "SparseMatrixTest_ChunkedEllpack.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_Ellpack.cpp b/src/UnitTests/Matrices/Legacy/SparseMatrixTest_Ellpack.cpp deleted file mode 100644 index c454706f0b1d437b798f2d7a1e93ccf4c0291d3f..0000000000000000000000000000000000000000 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_Ellpack.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "SparseMatrixTest_Ellpack.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_Ellpack.cu b/src/UnitTests/Matrices/Legacy/SparseMatrixTest_Ellpack.cu deleted file mode 100644 index c454706f0b1d437b798f2d7a1e93ccf4c0291d3f..0000000000000000000000000000000000000000 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_Ellpack.cu +++ /dev/null @@ -1 +0,0 @@ -#include "SparseMatrixTest_Ellpack.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_SlicedEllpack.cpp b/src/UnitTests/Matrices/Legacy/SparseMatrixTest_SlicedEllpack.cpp deleted file mode 100644 index 40e2e94b81ca64051ddceee82f46dd2d20e66e42..0000000000000000000000000000000000000000 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_SlicedEllpack.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "SparseMatrixTest_SlicedEllpack.h" diff --git a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_SlicedEllpack.cu b/src/UnitTests/Matrices/Legacy/SparseMatrixTest_SlicedEllpack.cu deleted file mode 100644 index 40e2e94b81ca64051ddceee82f46dd2d20e66e42..0000000000000000000000000000000000000000 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_SlicedEllpack.cu +++ /dev/null @@ -1 +0,0 @@ -#include "SparseMatrixTest_SlicedEllpack.h" diff --git a/src/UnitTests/Meshes/DistributedMeshes/DistributedMeshTest.h b/src/UnitTests/Meshes/DistributedMeshes/DistributedMeshTest.h index 641d3af39d580e943b975329c2216738f0aa3873..3b3e162bf57a5dc74dc8972c3db8857947e6aece 100644 --- a/src/UnitTests/Meshes/DistributedMeshes/DistributedMeshTest.h +++ b/src/UnitTests/Meshes/DistributedMeshes/DistributedMeshTest.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -267,7 +268,7 @@ struct GridDistributor< TNL::Meshes::Grid< 2, Real, Device, Index > > if( overlap > 0 ) { // distribute faces - distributeSubentities< 1 >( mesh ); + distributeSubentities< 1 >( mesh, /* preferHighRanks = */ false ); } } @@ -578,7 +579,7 @@ void testTraverser( const Mesh& mesh ) } template< typename Device, typename EntityType, typename MeshType > -void testSynchronizerOnDevice( const MeshType& mesh ) +void testSynchronizerOnDevice_global_indices( const MeshType& mesh ) { using LocalMesh = Mesh< typename MeshType::Config, Device >; using DeviceMesh = DistributedMesh< LocalMesh >; @@ -608,6 +609,79 @@ void testSynchronizerOnDevice( const MeshType& mesh ) EXPECT_EQ( f.getData(), mesh.template getGlobalIndices< EntityType::getEntityDimension() >() ); } +template< typename Mesh > +__cuda_callable__ +typename Mesh::LocalIndexType +getCellsForFace( const Mesh & mesh, const typename Mesh::GlobalIndexType E, typename Mesh::GlobalIndexType* cellIndexes ) +{ + using LocalIndexType = typename Mesh::LocalIndexType; + const LocalIndexType numCells = mesh.template getSuperentitiesCount< Mesh::getMeshDimension() - 1, Mesh::getMeshDimension() >( E ); + for( LocalIndexType i = 0; i < numCells; i++ ) + cellIndexes[ i ] = mesh.template getSuperentityIndex< Mesh::getMeshDimension() - 1, Mesh::getMeshDimension() >( E, i ); + return numCells; +} + +// testing global indices is not enough - entity centers are needed to ensure that the transferred data really match the physical entities +template< typename Device, typename EntityType, typename MeshType > +void testSynchronizerOnDevice_entity_centers( const MeshType& mesh ) +{ + using LocalMesh = TNL::Meshes::Mesh< typename MeshType::Config, Device >; + using DeviceMesh = TNL::Meshes::DistributedMeshes::DistributedMesh< LocalMesh >; + using IndexType = typename MeshType::GlobalIndexType; + using PointType = typename MeshType::PointType; + using Array = TNL::Containers::Array< typename LocalMesh::RealType, typename LocalMesh::DeviceType, IndexType >; + using Synchronizer = TNL::Meshes::DistributedMeshes::DistributedMeshSynchronizer< DeviceMesh, EntityType::getEntityDimension() >; + + // initialize + DeviceMesh deviceMesh; + deviceMesh = mesh; + Array f( mesh.getLocalMesh().template getEntitiesCount< EntityType::getEntityDimension() >() * MeshType::getMeshDimension() ); + f.setValue( 0 ); + + // set center of each local entity + for( IndexType i = 0; i < mesh.getLocalMesh().template getEntitiesCount< EntityType >(); i++ ) + if( ! mesh.getLocalMesh().template isGhostEntity< EntityType::getEntityDimension() >( i ) ) { + const auto center = getEntityCenter( mesh.getLocalMesh(), mesh.getLocalMesh().template getEntity< EntityType >( i ) ); + for( int d = 0; d < MeshType::getMeshDimension(); d++ ) + f.setElement( d + MeshType::getMeshDimension() * i, center[ d ] ); + } + + // synchronize + Synchronizer sync; + sync.initialize( deviceMesh ); + sync.synchronizeArray( f, MeshType::getMeshDimension() ); + + // check all centers + IndexType errors = 0; + for( IndexType i = 0; i < mesh.getLocalMesh().template getEntitiesCount< EntityType >(); i++ ) + if( mesh.getLocalMesh().template isGhostEntity< EntityType::getEntityDimension() >( i ) ) { + const PointType center = getEntityCenter( mesh.getLocalMesh(), mesh.getLocalMesh().template getEntity< EntityType >( i ) ); + PointType received; + for( int d = 0; d < MeshType::getMeshDimension(); d++ ) + received[ d ] = f.getElement( d + MeshType::getMeshDimension() * i ); + if( received != center ) { + IndexType cellIndexes[ 2 ] = {0, 0}; + const int numCells = getCellsForFace( mesh.getLocalMesh(), i, cellIndexes ); + std::cerr << "rank " << CommunicatorType::GetRank() + << ": wrong result for entity " << i << " (gid " << mesh.template getGlobalIndices< EntityType::getEntityDimension() >()[i] << ")" + << " of dimension = " << EntityType::getEntityDimension() + << ": received " << received << ", expected = " << center + << ", neighbor cells " << cellIndexes[0] << " " << ((numCells>1) ? cellIndexes[1] : -1) + << std::endl; + errors++; + } + } + if( errors > 0 ) + FAIL() << "rank " << CommunicatorType::GetRank() << ": " << errors << " errors in total." << std::endl; +} + +template< typename Device, typename EntityType, typename MeshType > +void testSynchronizerOnDevice( const MeshType& mesh ) +{ + testSynchronizerOnDevice_global_indices< Device, EntityType >( mesh ); + testSynchronizerOnDevice_entity_centers< Device, EntityType >( mesh ); +} + template< typename Mesh > void testSynchronizer( const Mesh& mesh ) { @@ -733,7 +807,7 @@ TEST( DistributedMeshTest, PVTUWriterReader ) reader.loadMesh( loadedMesh ); // decomposition of faces is not stored in the VTK files if( mesh.getGhostLevels() > 0 ) { - distributeSubentities< 1 >( loadedMesh ); + distributeSubentities< 1 >( loadedMesh, /* preferHighRanks = */ false ); } EXPECT_EQ( loadedMesh, mesh ); diff --git a/src/UnitTests/Pointers/CMakeLists.txt b/src/UnitTests/Pointers/CMakeLists.txt index 8845cdfbdffd7c0723698d97b9f0d68715ea71df..1b11483921d80a18ba1616d907f33a253ed9c309 100644 --- a/src/UnitTests/Pointers/CMakeLists.txt +++ b/src/UnitTests/Pointers/CMakeLists.txt @@ -1,21 +1,20 @@ -ADD_EXECUTABLE( UniquePointerTest UniquePointerTest.cpp ) -TARGET_COMPILE_OPTIONS( UniquePointerTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( UniquePointerTest ${GTEST_BOTH_LIBRARIES} ) -ADD_TEST( UniquePointerTest ${EXECUTABLE_OUTPUT_PATH}/UniquePointerTest${CMAKE_EXECUTABLE_SUFFIX} ) - +set( CPP_TESTS UniquePointerTest SharedPointerHostTest ) +set( CUDA_TESTS ) +if( BUILD_CUDA ) + set( CUDA_TESTS ${CUDA_TESTS} SharedPointerCudaTest DevicePointerCudaTest ) +endif() -ADD_EXECUTABLE( SharedPointerHostTest SharedPointerHostTest.cpp ) -TARGET_COMPILE_OPTIONS( SharedPointerHostTest PRIVATE ${CXX_TESTS_FLAGS} ) -TARGET_LINK_LIBRARIES( SharedPointerHostTest ${GTEST_BOTH_LIBRARIES} ) -ADD_TEST( SharedPointerHostTest ${EXECUTABLE_OUTPUT_PATH}/SharedPointerHostTest${CMAKE_EXECUTABLE_SUFFIX} ) +foreach( target IN ITEMS ${CPP_TESTS} ) + add_executable( ${target} ${target}.cpp ) + target_compile_options( ${target} PRIVATE ${CXX_TESTS_FLAGS} ) + target_link_libraries( ${target} ${GTEST_BOTH_LIBRARIES} ) + add_test( ${target} ${EXECUTABLE_OUTPUT_PATH}/${target}${CMAKE_EXECUTABLE_SUFFIX} ) +endforeach() if( BUILD_CUDA ) - CUDA_ADD_EXECUTABLE( SharedPointerCudaTest SharedPointerCudaTest.cu - OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( SharedPointerCudaTest ${GTEST_BOTH_LIBRARIES} ) - ADD_TEST( SharedPointerCudaTest ${EXECUTABLE_OUTPUT_PATH}/SharedPointerCudaTest${CMAKE_EXECUTABLE_SUFFIX} ) - CUDA_ADD_EXECUTABLE( DevicePointerCudaTest DevicePointerCudaTest.cu - OPTIONS ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( DevicePointerCudaTest ${GTEST_BOTH_LIBRARIES} ) - ADD_TEST( DevicePointerCudaTest ${EXECUTABLE_OUTPUT_PATH}/DevicePointerCudaTest${CMAKE_EXECUTABLE_SUFFIX} ) -endif( BUILD_CUDA ) + foreach( target IN ITEMS ${CUDA_TESTS} ) + cuda_add_executable( ${target} ${target}.cu OPTIONS ${CXX_TESTS_FLAGS} ) + target_link_libraries( ${target} ${GTEST_BOTH_LIBRARIES} ) + add_test( ${target} ${EXECUTABLE_OUTPUT_PATH}/${target}${CMAKE_EXECUTABLE_SUFFIX} ) + endforeach() +endif()