From a2f3fe3d732b853686903718d2eb0e45c0b3f726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Sat, 31 Oct 2020 12:21:10 +0100 Subject: [PATCH 01/11] CudaReductionKernel: suppress renumbered warning in CUDA 11 --- src/TNL/Algorithms/CudaReductionKernel.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/TNL/Algorithms/CudaReductionKernel.h b/src/TNL/Algorithms/CudaReductionKernel.h index e79410400..c3d981fd5 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__ -- GitLab From 5a89f28b8cb3858f7324bdba982e0fdbc7e9c666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Sun, 18 Oct 2020 09:26:52 +0200 Subject: [PATCH 02/11] tnl-decompose-mesh: handle the case when nparts == 1 --- src/Tools/tnl-decompose-mesh.cpp | 39 +++++++++++++++++++------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/Tools/tnl-decompose-mesh.cpp b/src/Tools/tnl-decompose-mesh.cpp index b1fb30d06..f64e22113 100644 --- a/src/Tools/tnl-decompose-mesh.cpp +++ b/src/Tools/tnl-decompose-mesh.cpp @@ -392,25 +392,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 -- GitLab From 2954c50b81553e4681857f0c22b279dff7cc2be6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Sun, 25 Oct 2020 18:43:07 +0100 Subject: [PATCH 03/11] Print basic info about faces in the distributed mesh --- src/TNL/Meshes/DistributedMeshes/DistributedMesh.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/TNL/Meshes/DistributedMeshes/DistributedMesh.h b/src/TNL/Meshes/DistributedMeshes/DistributedMesh.h index 2ea6d8539..9a79f823d 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(); -- GitLab From 6580a5e8259e4955a3b356efccd7c0d84447cee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Sun, 25 Oct 2020 19:23:11 +0100 Subject: [PATCH 04/11] distributeSubentities: fix for decompositions where multiple ranks own all subvertices of their local cells --- .../DistributedMeshes/distributeSubentities.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/TNL/Meshes/DistributedMeshes/distributeSubentities.h b/src/TNL/Meshes/DistributedMeshes/distributeSubentities.h index 2135ffcee..aa0887f4f 100644 --- a/src/TNL/Meshes/DistributedMeshes/distributeSubentities.h +++ b/src/TNL/Meshes/DistributedMeshes/distributeSubentities.h @@ -55,6 +55,8 @@ distributeSubentities( DistributedMesh& mesh ) }; // find which rank owns all vertices of its local cells + // (this is not unique, there might be more such subdomains (which are not connected), + // so we assume it's either 0 or nproc-1) int rankOwningAllLocalCellSubvertices = nproc; { std::atomic its_us( true ); @@ -70,16 +72,15 @@ distributeSubentities( DistributedMesh& mesh ) CommunicatorType::Alltoall( sendbuf.getData(), 1, recvbuf.getData(), 1, mesh.getCommunicationGroup() ); - for( int i = 0; i < nproc; i++ ) - if( recvbuf[ i ] ) { - rankOwningAllLocalCellSubvertices = i; - break; - } + if( recvbuf[ 0 ] ) + rankOwningAllLocalCellSubvertices = 0; + else if( recvbuf[ nproc - 1 ] ) + rankOwningAllLocalCellSubvertices = nproc - 1; + else + 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."); } - 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."); auto getEntityOwner = [&] ( GlobalIndexType local_idx ) -> int { -- GitLab From 6fea752e826da7d8c81dca20c5ece9e6b873298c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Sun, 25 Oct 2020 20:09:40 +0100 Subject: [PATCH 05/11] tnl-decompose-mesh: reorder ghost points to make sure that global indices are sorted --- src/Tools/tnl-decompose-mesh.cpp | 49 +++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/src/Tools/tnl-decompose-mesh.cpp b/src/Tools/tnl-decompose-mesh.cpp index f64e22113..213190778 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 @@ -515,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 ]; @@ -524,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; } } } @@ -692,14 +693,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 ); -- GitLab From 149b1764984cda08bb0a890529eeb490cbe5d02b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Thu, 29 Oct 2020 21:41:26 +0100 Subject: [PATCH 06/11] distributeSubentities: fix the algorithm for assigning global IDs Previously we matched the local subvertex ID with the neighbor's local superentity ID (entities sharing the same vertex), which does not make sense. The result cannot use the synchronizeSparse function, so it looks more complicated. Note that it still does not work in all corner cases - see the FIXME notes. --- .../DistributedMeshes/distributeSubentities.h | 329 +++++++++++++++--- 1 file changed, 288 insertions(+), 41 deletions(-) diff --git a/src/TNL/Meshes/DistributedMeshes/distributeSubentities.h b/src/TNL/Meshes/DistributedMeshes/distributeSubentities.h index aa0887f4f..923007479 100644 --- a/src/TNL/Meshes/DistributedMeshes/distributeSubentities.h +++ b/src/TNL/Meshes/DistributedMeshes/distributeSubentities.h @@ -18,12 +18,135 @@ #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; +} + +// FIXME: This algorithm works only when min-common-vertices == 1, i.e. we have +// the full information about neighbors of ghosts on the overlap. Otherwise, +// depending on how the mesh was decomposed, we might end up with errors like +// vertex with gid=XXX received from rank X was not found on the local mesh for rank Y (global offset = YYY) +// The problem is with the getEntityOwner function, which assumes that it knows +// everything about the neighbors of the entity based on its subvertices. +// +// FIXME: This algorithm may distribute entities in such a way that some rank +// owns an entity on the interface between two (other) subdomains, but the +// neighbor cell of the entity is a ghost. template< int Dimension, typename DistributedMesh > void distributeSubentities( DistributedMesh& mesh ) @@ -44,7 +167,7 @@ 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 + // 0. exchange vertex data to prepare getVertexOwner for use in getEntityOwner DistributedMeshSynchronizer< DistributedMesh, 0 > synchronizer; synchronizer.initialize( mesh ); @@ -85,22 +208,30 @@ distributeSubentities( DistributedMesh& mesh ) 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 ) ); + + // if all neighbor cells are local, we are the owner + bool all_neighbor_cells_local = true; + 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 ) ) { + all_neighbor_cells_local = false; + break; } } - 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 ); + if( all_neighbor_cells_local ) + return rank; + + int owner = (rankOwningAllLocalCellSubvertices == 0) ? 0 : nproc; + for( LocalIndexType v = 0; v < entity.template getSubentitiesCount< 0 >(); v++ ) { + const GlobalIndexType gv = entity.template getSubentityIndex< 0 >( v ); + 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) + owner = TNL::max( owner, getVertexOwner( gv ) ); + else + // this assumes that vertices at the boundaries were assigned to the subdomain with the highest rank + // (this is what tnl-decompose-mesh does) owner = TNL::min( owner, getVertexOwner( gv ) ); - } } return owner; }; @@ -164,35 +295,151 @@ distributeSubentities( DistributedMesh& mesh ) mesh.template getGlobalIndices< Dimension >()[ i ] = globalOffsets[ rank ] + i; }); - // 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 the owner of the entity. The owner will scan its vertex-entity + // superentity matrix, find the entity which has the received vertex indices and send + // the global entity index back to the inquirer. + // 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. + + // 6. 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( GlobalIndexType entity_index = localMesh.template getGhostEntitiesOffset< Dimension >(); + entity_index < localMesh.template getEntitiesCount< Dimension >(); + entity_index++ ) + { + 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 ); + } + + // 7. 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::stringstream msg; +// msg << "rank " << rank << ":\n"; +// for( int i = 0; i < nproc; i++ ) { +// msg << "- from rank " << i << ":\n"; +// msg << "\tindices: "; +// for( auto j : foreign_seeds_vertex_indices[i] ) +// msg << j << " "; +// msg << "\n\toffsets: "; +// for( auto j : foreign_seeds_entity_offsets[i] ) +// msg << j << " "; +// msg << "\n"; +// } +// std::cout << msg.str(); + + // 8. determine global indices for the received 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() ); + 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; + + // 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 >= synchronizer.getGlobalOffsets()[ rank ] + && vertex < synchronizer.getGlobalOffsets()[ rank ] + localMesh.template getGhostEntitiesOffset< 0 >() ) + { + // subtract offset to get local index + localIndex = vertex - synchronizer.getGlobalOffsets()[ rank ]; + } + else { + // we must go through the ghost entities + 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(synchronizer.getGlobalOffsets()[ rank ]) + ")" ); + } + + // 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() ); } + + const GlobalIndexType local_index = *common_indices.begin(); + if( getEntityOwner( local_index ) != rank ) + throw std::runtime_error( "rank " + std::to_string(rank) + " does not own the entity which was left common: " + std::to_string(local_index) ); + + // assign global index + foreign_ghost_indices[ i ][ entityIndex ] = mesh.template getGlobalIndices< Dimension >()[ local_index ]; } }); - // 8. reorder the entities to make sure that global indices are sorted + // 9. exchange global ghost indices + const auto ghost_indices = exchangeGhostIndices< CommunicatorType >( mesh.getCommunicationGroup(), foreign_ghost_indices, seeds_local_indices ); + +// std::stringstream msg; +// msg << "rank " << rank << ":\n"; +// for( int i = 0; i < nproc; i++ ) { +// msg << "- from rank " << i << ":\n"; +// msg << "\tghost indices: "; +// for( auto j : ghost_indices[i] ) +// msg << j << " "; +// msg << "\n"; +// } +// std::cout << msg.str(); + + // 10. set the global indices of our ghost entities + 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 ]; + } + + // 11. reorder the entities to make sure that global indices are sorted { // prepare vector with an identity permutation std::vector< GlobalIndexType > permutation( localMesh.template getEntitiesCount< Dimension >() ); -- GitLab From a1530c8ac371018372aaf2acd1479d793a4b4cba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Fri, 30 Oct 2020 22:27:30 +0100 Subject: [PATCH 07/11] Fixed the behaviour of distributeSubentities in the final corner cases - iterative way of communicating the global indices for ghost entities - only one reordering at the end - a lot of code cleanup --- .../DistributedMeshes/distributeSubentities.h | 404 ++++++++---------- .../DistributedMeshes/DistributedMeshTest.h | 4 +- 2 files changed, 184 insertions(+), 224 deletions(-) diff --git a/src/TNL/Meshes/DistributedMeshes/distributeSubentities.h b/src/TNL/Meshes/DistributedMeshes/distributeSubentities.h index 923007479..39663da99 100644 --- a/src/TNL/Meshes/DistributedMeshes/distributeSubentities.h +++ b/src/TNL/Meshes/DistributedMeshes/distributeSubentities.h @@ -12,9 +12,6 @@ #pragma once -#include // std::iota -#include - #include #include @@ -137,19 +134,12 @@ exchangeGhostIndices( typename CommunicatorType::CommunicationGroup group, return ghost_indices; } -// FIXME: This algorithm works only when min-common-vertices == 1, i.e. we have -// the full information about neighbors of ghosts on the overlap. Otherwise, -// depending on how the mesh was decomposed, we might end up with errors like -// vertex with gid=XXX received from rank X was not found on the local mesh for rank Y (global offset = YYY) -// The problem is with the getEntityOwner function, which assumes that it knows -// everything about the neighbors of the entity based on its subvertices. -// -// FIXME: This algorithm may distribute entities in such a way that some rank -// owns an entity on the interface between two (other) subdomains, but the -// neighbor cell of the entity is a ghost. +// \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; @@ -167,73 +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 for use in getEntityOwner - 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 - // (this is not unique, there might be more such subdomains (which are not connected), - // so we assume it's either 0 or nproc-1) - 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() ); - if( recvbuf[ 0 ] ) - rankOwningAllLocalCellSubvertices = 0; - else if( recvbuf[ nproc - 1 ] ) - rankOwningAllLocalCellSubvertices = nproc - 1; - else - 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 ); - // if all neighbor cells are local, we are the owner - bool all_neighbor_cells_local = true; + 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 ) ) { - all_neighbor_cells_local = false; - break; - } + if( ! mesh.getLocalMesh().template isGhostEntity< DistributedMesh::getMeshDimension() >( gk ) ) + local_neighbor_cells_count++; } - if( all_neighbor_cells_local ) + + // if all neighbor cells are local, we are the owner + if( local_neighbor_cells_count == 2 ) return rank; - int owner = (rankOwningAllLocalCellSubvertices == 0) ? 0 : nproc; - for( LocalIndexType v = 0; v < entity.template getSubentitiesCount< 0 >(); v++ ) { - const GlobalIndexType gv = entity.template getSubentityIndex< 0 >( v ); - 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) - owner = TNL::max( owner, getVertexOwner( gv ) ); - else - // this assumes that vertices at the boundaries were assigned to the subdomain with the highest rank - // (this is what tnl-decompose-mesh does) - owner = TNL::min( owner, getVertexOwner( gv ) ); + // 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 @@ -243,77 +225,57 @@ 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++; + } // Now for each ghost entity, we will take the global indices of its subvertices and - // send them to the owner of the entity. The owner will scan its vertex-entity - // superentity matrix, find the entity which has the received vertex indices and send - // the global entity index back to the inquirer. + // 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. - // 6. build seeds for ghost entities + // 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( GlobalIndexType entity_index = localMesh.template getGhostEntitiesOffset< Dimension >(); - entity_index < localMesh.template getEntitiesCount< Dimension >(); - entity_index++ ) - { + 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 ); @@ -325,141 +287,139 @@ distributeSubentities( DistributedMesh& mesh ) seeds_local_indices[ owner ].push_back( entity_index ); } - // 7. exchange seeds for ghost entities + // 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::stringstream msg; -// msg << "rank " << rank << ":\n"; -// for( int i = 0; i < nproc; i++ ) { -// msg << "- from rank " << i << ":\n"; -// msg << "\tindices: "; -// for( auto j : foreign_seeds_vertex_indices[i] ) -// msg << j << " "; -// msg << "\n\toffsets: "; -// for( auto j : foreign_seeds_entity_offsets[i] ) -// msg << j << " "; -// msg << "\n"; -// } -// std::cout << msg.str(); - - // 8. determine global indices for the received 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() ); - 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; - - // 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 >= synchronizer.getGlobalOffsets()[ rank ] - && vertex < synchronizer.getGlobalOffsets()[ rank ] + localMesh.template getGhostEntitiesOffset< 0 >() ) - { - // subtract offset to get local index - localIndex = vertex - synchronizer.getGlobalOffsets()[ rank ]; - } - else { - // we must go through the ghost entities - for( GlobalIndexType g = localMesh.template getGhostEntitiesOffset< 0 >(); - g < localMesh.template getEntitiesCount< 0 >(); - g++ ) - if( vertex == mesh.template getGlobalIndices< 0 >()[ g ] ) { - localIndex = g; - break; + + // 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++ ) + { + // 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( 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(synchronizer.getGlobalOffsets()[ rank ]) + ")" ); } - // 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 ); + 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() ); } - // 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 ]; } + }); - const GlobalIndexType local_index = *common_indices.begin(); - if( getEntityOwner( local_index ) != rank ) - throw std::runtime_error( "rank " + std::to_string(rank) + " does not own the entity which was left common: " + std::to_string(local_index) ); + // 6b. exchange global ghost indices + const auto ghost_indices = exchangeGhostIndices< CommunicatorType >( mesh.getCommunicationGroup(), foreign_ghost_indices, seeds_local_indices ); - // assign global index - foreign_ghost_indices[ i ][ entityIndex ] = mesh.template getGlobalIndices< Dimension >()[ local_index ]; + // 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; + } } - }); - // 9. exchange global ghost indices - const auto ghost_indices = exchangeGhostIndices< CommunicatorType >( mesh.getCommunicationGroup(), foreign_ghost_indices, seeds_local_indices ); - -// std::stringstream msg; -// msg << "rank " << rank << ":\n"; -// for( int i = 0; i < nproc; i++ ) { -// msg << "- from rank " << i << ":\n"; -// msg << "\tghost indices: "; -// for( auto j : ghost_indices[i] ) -// msg << j << " "; -// msg << "\n"; -// } -// std::cout << msg.str(); - - // 10. set the global indices of our ghost entities - 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 ]; + // 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" ); - // 11. reorder the entities to make sure that global indices are sorted + // 7. reorder the entities to make sure that global indices are sorted { - // 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 ]; - }); - - // copy the permutation into TNL array and invert + // 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/UnitTests/Meshes/DistributedMeshes/DistributedMeshTest.h b/src/UnitTests/Meshes/DistributedMeshes/DistributedMeshTest.h index 641d3af39..a9cac3912 100644 --- a/src/UnitTests/Meshes/DistributedMeshes/DistributedMeshTest.h +++ b/src/UnitTests/Meshes/DistributedMeshes/DistributedMeshTest.h @@ -267,7 +267,7 @@ struct GridDistributor< TNL::Meshes::Grid< 2, Real, Device, Index > > if( overlap > 0 ) { // distribute faces - distributeSubentities< 1 >( mesh ); + distributeSubentities< 1 >( mesh, /* preferHighRanks = */ false ); } } @@ -733,7 +733,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 ); -- GitLab From 039eb80110d6a6037d8da0f48bb7c0a7f24662dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Sat, 31 Oct 2020 00:31:26 +0100 Subject: [PATCH 08/11] tnl-decompose-mesh: optimize the creation of ghost levels --- src/Tools/tnl-decompose-mesh.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Tools/tnl-decompose-mesh.cpp b/src/Tools/tnl-decompose-mesh.cpp index 213190778..5ebefe256 100644 --- a/src/Tools/tnl-decompose-mesh.cpp +++ b/src/Tools/tnl-decompose-mesh.cpp @@ -631,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 ) { @@ -639,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 ); @@ -649,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 @@ -661,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 -- GitLab From fa1e1334c753b210585217fddca55b65992a5274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Sat, 31 Oct 2020 10:03:20 +0100 Subject: [PATCH 09/11] tnl-test-distributed-mesh: additional tool for testing distributed mesh It depends on input data files, so it is not a unit test. --- src/Tools/CMakeLists.txt | 13 + src/Tools/tnl-test-distributed-mesh.cpp | 1 + src/Tools/tnl-test-distributed-mesh.cu | 1 + src/Tools/tnl-test-distributed-mesh.h | 463 ++++++++++++++++++++++++ 4 files changed, 478 insertions(+) create mode 100644 src/Tools/tnl-test-distributed-mesh.cpp create mode 100644 src/Tools/tnl-test-distributed-mesh.cu create mode 100644 src/Tools/tnl-test-distributed-mesh.h diff --git a/src/Tools/CMakeLists.txt b/src/Tools/CMakeLists.txt index 34dfc5e3e..a7d0cc91f 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 ) @@ -38,6 +43,10 @@ if( ZLIB_FOUND ) 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}) + + target_compile_definitions(tnl-test-distributed-mesh PUBLIC "-DHAVE_ZLIB") + target_include_directories(tnl-test-distributed-mesh PUBLIC ${ZLIB_INCLUDE_DIRS}) + target_link_libraries(tnl-test-distributed-mesh ${ZLIB_LIBRARIES}) endif() find_package( tinyxml2 QUIET ) @@ -47,6 +56,9 @@ if( tinyxml2_FOUND ) target_compile_definitions(tnl-game-of-life PUBLIC "-DHAVE_TINYXML2") target_link_libraries(tnl-game-of-life tinyxml2::tinyxml2) + + target_compile_definitions(tnl-test-distributed-mesh PUBLIC "-DHAVE_TINYXML2") + target_link_libraries(tnl-test-distributed-mesh tinyxml2::tinyxml2) endif() find_package( METIS QUIET ) @@ -80,6 +92,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-test-distributed-mesh.cpp b/src/Tools/tnl-test-distributed-mesh.cpp new file mode 100644 index 000000000..e194bd17f --- /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 000000000..e194bd17f --- /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 000000000..1fc4c855e --- /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 ); +} -- GitLab From 11f01ea7e1afc3cc20d1192ae5c2e46ea12ab7d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Sat, 31 Oct 2020 10:05:07 +0100 Subject: [PATCH 10/11] DistributedMeshTest: add test with entity centers to ensure that the transferred data really match the physical entities --- .../DistributedMeshes/DistributedMeshTest.h | 76 ++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/src/UnitTests/Meshes/DistributedMeshes/DistributedMeshTest.h b/src/UnitTests/Meshes/DistributedMeshes/DistributedMeshTest.h index a9cac3912..3b3e162bf 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 @@ -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 ) { -- GitLab From 9c64790bc81449706cac3e851390640b07485da1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Sat, 31 Oct 2020 12:18:44 +0100 Subject: [PATCH 11/11] Refactoring CMakeLists.txt: use foreach to avoid repetition --- src/Tools/CMakeLists.txt | 32 +--- src/UnitTests/Algorithms/CMakeLists.txt | 51 +++--- src/UnitTests/CMakeLists.txt | 65 ++----- .../{ArrayTest.cu => ArrayTestCuda.cu} | 0 ...{ArrayViewTest.cu => ArrayViewTestCuda.cu} | 0 src/UnitTests/Containers/CMakeLists.txt | 163 +++++------------ ...rayTest.cu => DistributedArrayTestCuda.cu} | 0 ...tributedVectorBinaryOperationsTestCuda.cu} | 0 ...orTest.cu => DistributedVectorTestCuda.cu} | 0 ...stributedVectorUnaryOperationsTestCuda.cu} | 0 ...ibutedVectorVerticalOperationsTestCuda.cu} | 0 .../Containers/Segments/CMakeLists.txt | 83 ++++----- ...t.cu => VectorBinaryOperationsTestCuda.cu} | 0 ....cu => VectorEvaluateAndReduceTestCuda.cu} | 0 ...st.cu => VectorOfStaticVectorsTestCuda.cu} | 0 ...xSumTest.cu => VectorPrefixSumTestCuda.cu} | 0 .../{VectorTest.cu => VectorTestCuda.cu} | 0 ...st.cu => VectorUnaryOperationsTestCuda.cu} | 0 ...cu => VectorVerticalOperationsTestCuda.cu} | 0 .../Containers/ndarray/CMakeLists.txt | 41 ++--- src/UnitTests/Functions/CMakeLists.txt | 43 ++--- src/UnitTests/Matrices/CMakeLists.txt | 172 +++++------------- src/UnitTests/Matrices/Legacy/CMakeLists.txt | 106 ++++------- ...st.cpp => Legacy_SparseMatrixCopyTest.cpp} | 2 +- ...Test.cu => Legacy_SparseMatrixCopyTest.cu} | 2 +- ...pyTest.h => Legacy_SparseMatrixCopyTest.h} | 0 ...ixTest.cpp => Legacy_SparseMatrixTest.cpp} | 2 +- ...trixTest.cu => Legacy_SparseMatrixTest.cu} | 2 +- ...MatrixTest.h => Legacy_SparseMatrixTest.h} | 2 +- ...ixTest.hpp => Legacy_SparseMatrixTest.hpp} | 0 .../Legacy_SparseMatrixTest_AdEllpack.cpp | 1 + .../Legacy_SparseMatrixTest_AdEllpack.cu | 1 + ....h => Legacy_SparseMatrixTest_AdEllpack.h} | 2 +- .../Legacy_SparseMatrixTest_BiEllpack.cpp | 1 + .../Legacy_SparseMatrixTest_BiEllpack.cu | 1 + ....h => Legacy_SparseMatrixTest_BiEllpack.h} | 2 +- .../Legacy/Legacy_SparseMatrixTest_CSR.cpp | 1 + .../Legacy/Legacy_SparseMatrixTest_CSR.cu | 1 + ...st_CSR.h => Legacy_SparseMatrixTest_CSR.h} | 2 +- ...Legacy_SparseMatrixTest_ChunkedEllpack.cpp | 1 + .../Legacy_SparseMatrixTest_ChunkedEllpack.cu | 1 + ... Legacy_SparseMatrixTest_ChunkedEllpack.h} | 2 +- .../Legacy_SparseMatrixTest_Ellpack.cpp | 1 + .../Legacy/Legacy_SparseMatrixTest_Ellpack.cu | 1 + ...ck.h => Legacy_SparseMatrixTest_Ellpack.h} | 2 +- .../Legacy_SparseMatrixTest_SlicedEllpack.cpp | 1 + .../Legacy_SparseMatrixTest_SlicedEllpack.cu | 1 + ...> Legacy_SparseMatrixTest_SlicedEllpack.h} | 2 +- .../Legacy/SparseMatrixTest_AdEllpack.cpp | 1 - .../Legacy/SparseMatrixTest_AdEllpack.cu | 1 - .../Legacy/SparseMatrixTest_BiEllpack.cpp | 1 - .../Legacy/SparseMatrixTest_BiEllpack.cu | 1 - .../Matrices/Legacy/SparseMatrixTest_CSR.cpp | 1 - .../Matrices/Legacy/SparseMatrixTest_CSR.cu | 1 - .../SparseMatrixTest_ChunkedEllpack.cpp | 1 - .../Legacy/SparseMatrixTest_ChunkedEllpack.cu | 1 - .../Legacy/SparseMatrixTest_Ellpack.cpp | 1 - .../Legacy/SparseMatrixTest_Ellpack.cu | 1 - .../Legacy/SparseMatrixTest_SlicedEllpack.cpp | 1 - .../Legacy/SparseMatrixTest_SlicedEllpack.cu | 1 - src/UnitTests/Pointers/CMakeLists.txt | 35 ++-- 61 files changed, 279 insertions(+), 558 deletions(-) rename src/UnitTests/Containers/{ArrayTest.cu => ArrayTestCuda.cu} (100%) rename src/UnitTests/Containers/{ArrayViewTest.cu => ArrayViewTestCuda.cu} (100%) rename src/UnitTests/Containers/{DistributedArrayTest.cu => DistributedArrayTestCuda.cu} (100%) rename src/UnitTests/Containers/{DistributedVectorBinaryOperationsTest.cu => DistributedVectorBinaryOperationsTestCuda.cu} (100%) rename src/UnitTests/Containers/{DistributedVectorTest.cu => DistributedVectorTestCuda.cu} (100%) rename src/UnitTests/Containers/{DistributedVectorUnaryOperationsTest.cu => DistributedVectorUnaryOperationsTestCuda.cu} (100%) rename src/UnitTests/Containers/{DistributedVectorVerticalOperationsTest.cu => DistributedVectorVerticalOperationsTestCuda.cu} (100%) rename src/UnitTests/Containers/{VectorBinaryOperationsTest.cu => VectorBinaryOperationsTestCuda.cu} (100%) rename src/UnitTests/Containers/{VectorEvaluateAndReduceTest.cu => VectorEvaluateAndReduceTestCuda.cu} (100%) rename src/UnitTests/Containers/{VectorOfStaticVectorsTest.cu => VectorOfStaticVectorsTestCuda.cu} (100%) rename src/UnitTests/Containers/{VectorPrefixSumTest.cu => VectorPrefixSumTestCuda.cu} (100%) rename src/UnitTests/Containers/{VectorTest.cu => VectorTestCuda.cu} (100%) rename src/UnitTests/Containers/{VectorUnaryOperationsTest.cu => VectorUnaryOperationsTestCuda.cu} (100%) rename src/UnitTests/Containers/{VectorVerticalOperationsTest.cu => VectorVerticalOperationsTestCuda.cu} (100%) rename src/UnitTests/Matrices/Legacy/{SparseMatrixCopyTest.cpp => Legacy_SparseMatrixCopyTest.cpp} (92%) rename src/UnitTests/Matrices/Legacy/{SparseMatrixCopyTest.cu => Legacy_SparseMatrixCopyTest.cu} (92%) rename src/UnitTests/Matrices/Legacy/{SparseMatrixCopyTest.h => Legacy_SparseMatrixCopyTest.h} (100%) rename src/UnitTests/Matrices/Legacy/{SparseMatrixTest.cpp => Legacy_SparseMatrixTest.cpp} (92%) rename src/UnitTests/Matrices/Legacy/{SparseMatrixTest.cu => Legacy_SparseMatrixTest.cu} (92%) rename src/UnitTests/Matrices/Legacy/{SparseMatrixTest.h => Legacy_SparseMatrixTest.h} (96%) rename src/UnitTests/Matrices/Legacy/{SparseMatrixTest.hpp => Legacy_SparseMatrixTest.hpp} (100%) create mode 100644 src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_AdEllpack.cpp create mode 100644 src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_AdEllpack.cu rename src/UnitTests/Matrices/Legacy/{SparseMatrixTest_AdEllpack.h => Legacy_SparseMatrixTest_AdEllpack.h} (99%) create mode 100644 src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_BiEllpack.cpp create mode 100644 src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_BiEllpack.cu rename src/UnitTests/Matrices/Legacy/{SparseMatrixTest_BiEllpack.h => Legacy_SparseMatrixTest_BiEllpack.h} (99%) create mode 100644 src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_CSR.cpp create mode 100644 src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_CSR.cu rename src/UnitTests/Matrices/Legacy/{SparseMatrixTest_CSR.h => Legacy_SparseMatrixTest_CSR.h} (99%) create mode 100644 src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_ChunkedEllpack.cpp create mode 100644 src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_ChunkedEllpack.cu rename src/UnitTests/Matrices/Legacy/{SparseMatrixTest_ChunkedEllpack.h => Legacy_SparseMatrixTest_ChunkedEllpack.h} (99%) create mode 100644 src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_Ellpack.cpp create mode 100644 src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_Ellpack.cu rename src/UnitTests/Matrices/Legacy/{SparseMatrixTest_Ellpack.h => Legacy_SparseMatrixTest_Ellpack.h} (99%) create mode 100644 src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_SlicedEllpack.cpp create mode 100644 src/UnitTests/Matrices/Legacy/Legacy_SparseMatrixTest_SlicedEllpack.cu rename src/UnitTests/Matrices/Legacy/{SparseMatrixTest_SlicedEllpack.h => Legacy_SparseMatrixTest_SlicedEllpack.h} (99%) delete mode 100644 src/UnitTests/Matrices/Legacy/SparseMatrixTest_AdEllpack.cpp delete mode 100644 src/UnitTests/Matrices/Legacy/SparseMatrixTest_AdEllpack.cu delete mode 100644 src/UnitTests/Matrices/Legacy/SparseMatrixTest_BiEllpack.cpp delete mode 100644 src/UnitTests/Matrices/Legacy/SparseMatrixTest_BiEllpack.cu delete mode 100644 src/UnitTests/Matrices/Legacy/SparseMatrixTest_CSR.cpp delete mode 100644 src/UnitTests/Matrices/Legacy/SparseMatrixTest_CSR.cu delete mode 100644 src/UnitTests/Matrices/Legacy/SparseMatrixTest_ChunkedEllpack.cpp delete mode 100644 src/UnitTests/Matrices/Legacy/SparseMatrixTest_ChunkedEllpack.cu delete mode 100644 src/UnitTests/Matrices/Legacy/SparseMatrixTest_Ellpack.cpp delete mode 100644 src/UnitTests/Matrices/Legacy/SparseMatrixTest_Ellpack.cu delete mode 100644 src/UnitTests/Matrices/Legacy/SparseMatrixTest_SlicedEllpack.cpp delete mode 100644 src/UnitTests/Matrices/Legacy/SparseMatrixTest_SlicedEllpack.cu diff --git a/src/Tools/CMakeLists.txt b/src/Tools/CMakeLists.txt index a7d0cc91f..7d85b9441 100644 --- a/src/Tools/CMakeLists.txt +++ b/src/Tools/CMakeLists.txt @@ -32,33 +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}) - - target_compile_definitions(tnl-test-distributed-mesh PUBLIC "-DHAVE_ZLIB") - target_include_directories(tnl-test-distributed-mesh PUBLIC ${ZLIB_INCLUDE_DIRS}) - target_link_libraries(tnl-test-distributed-mesh ${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) - - target_compile_definitions(tnl-test-distributed-mesh PUBLIC "-DHAVE_TINYXML2") - target_link_libraries(tnl-test-distributed-mesh 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 ) diff --git a/src/UnitTests/Algorithms/CMakeLists.txt b/src/UnitTests/Algorithms/CMakeLists.txt index 6870bc84e..1f6cdbc1e 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 15a6bf9f0..788667c9a 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 ae3c1b0e7..415180283 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 742fb69ef..3b4067c31 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 2f87d64a9..edcf7986c 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 c2ee3ac04..8c03c3cba 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 778ab29bd..727b2bc0b 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 2e7297cce..cb73ad5af 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 30b8f64ec..61c5201af 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 431fe481c..9e46803d1 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 46f6b9bd3..7d9843ba2 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 01c23c193..cfffec845 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 f7ee41411..db7959438 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 000000000..f5baa1c80 --- /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 000000000..f5baa1c80 --- /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 ca2b0b972..1b63ab843 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 000000000..9d9a9ce8c --- /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 000000000..9d9a9ce8c --- /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 d0277e27c..e443a6178 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 000000000..981914b3b --- /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 000000000..981914b3b --- /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 4b9325e06..c43185c14 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 000000000..3a9130698 --- /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 000000000..3a9130698 --- /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 f0ee7c079..84d015188 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 000000000..839235aaf --- /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 000000000..839235aaf --- /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 8376654cd..307e5728a 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 000000000..ef75cbcfa --- /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 000000000..ef75cbcfa --- /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 9ffba7504..b975c9c60 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 563a3dc26..000000000 --- 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 563a3dc26..000000000 --- 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 ccb62e4a8..000000000 --- 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 ccb62e4a8..000000000 --- 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 258ad2c53..000000000 --- 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 258ad2c53..000000000 --- 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 c09609ae6..000000000 --- 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 c09609ae6..000000000 --- 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 c454706f0..000000000 --- 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 c454706f0..000000000 --- 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 40e2e94b8..000000000 --- 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 40e2e94b8..000000000 --- a/src/UnitTests/Matrices/Legacy/SparseMatrixTest_SlicedEllpack.cu +++ /dev/null @@ -1 +0,0 @@ -#include "SparseMatrixTest_SlicedEllpack.h" diff --git a/src/UnitTests/Pointers/CMakeLists.txt b/src/UnitTests/Pointers/CMakeLists.txt index 8845cdfbd..1b1148392 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() -- GitLab