Commit d6faaab4 authored by Marcel Koch's avatar Marcel Koch
Browse files

reduce complexity of neighbor setup in migratePrimitives

before this was O(#neighbour_id * (#local_id + log(#neighbor_id)), now it should be O(#local_id + #neighbor_id)
parent ce853620
...@@ -41,6 +41,23 @@ ...@@ -41,6 +41,23 @@
#include "hyteg/primitivestorage/SetupPrimitiveStorage.hpp" #include "hyteg/primitivestorage/SetupPrimitiveStorage.hpp"
#include "hyteg/primitivestorage/loadbalancing/SimpleBalancer.hpp" #include "hyteg/primitivestorage/loadbalancing/SimpleBalancer.hpp"
namespace std{
template<> struct hash<hyteg::PrimitiveID>{
size_t operator()(const hyteg::PrimitiveID &pid) const{
return std::hash<hyteg::PrimitiveID::IDType>{}(pid.getID());
}
};
template<> struct equal_to<hyteg::PrimitiveID>{
bool operator()( const hyteg::PrimitiveID& lhs, const hyteg::PrimitiveID& rhs ) const
{
return lhs.getID() == rhs.getID();
}
};
}
namespace hyteg { namespace hyteg {
using walberla::uint_t; using walberla::uint_t;
...@@ -1136,67 +1153,69 @@ void PrimitiveStorage::migratePrimitives( const MigrationInfo& migrationInfo ) ...@@ -1136,67 +1153,69 @@ void PrimitiveStorage::migratePrimitives( const MigrationInfo& migrationInfo )
std::vector< PrimitiveID > localPrimitiveIDs; std::vector< PrimitiveID > localPrimitiveIDs;
getPrimitiveIDs( localPrimitiveIDs ); getPrimitiveIDs( localPrimitiveIDs );
for ( const auto& localID : localPrimitiveIDs )
if(localPrimitiveIDs.empty())
{ {
if ( vertexExistsInNeighborhood( localID ) ) neighborVertices_ = VertexMap{};
neighborVertices_.erase( localID.getID() ); neighborEdges_ = EdgeMap{};
if ( edgeExistsInNeighborhood( localID ) ) neighborFaces_ = FaceMap{};
neighborEdges_.erase( localID.getID() ); neighborCells_ = CellMap{};
if ( faceExistsInNeighborhood( localID ) )
neighborFaces_.erase( localID.getID() );
if ( cellExistsInNeighborhood( localID ) )
neighborCells_.erase( localID.getID() );
} }
else {
for ( const auto& localID : localPrimitiveIDs )
{
if ( vertexExistsInNeighborhood( localID ) )
neighborVertices_.erase( localID.getID() );
if ( edgeExistsInNeighborhood( localID ) )
neighborEdges_.erase( localID.getID() );
if ( faceExistsInNeighborhood( localID ) )
neighborFaces_.erase( localID.getID() );
if ( cellExistsInNeighborhood( localID ) )
neighborCells_.erase( localID.getID() );
}
///////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////
// Erasing all neighbors that are not referenced by local primitives from neighborhood // // Erasing all neighbors that are not referenced by local primitives from neighborhood //
///////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////
// enjoy worst possible complexity...
std::vector< PrimitiveID > neighborhoodIDs; // enjoy worst possible complexity...
for ( const auto& it : neighborVertices_ ) std::vector< PrimitiveID > neighborhoodIDs;
neighborhoodIDs.push_back( it.first ); neighborhoodIDs.reserve( neighborVertices_.size() + neighborEdges_.size() + neighborFaces_.size() + neighborCells_.size() );
for ( const auto& it : neighborEdges_ ) for ( const auto& it : neighborVertices_ )
neighborhoodIDs.push_back( it.first ); neighborhoodIDs.emplace_back( it.first );
for ( const auto& it : neighborFaces_ ) for ( const auto& it : neighborEdges_ )
neighborhoodIDs.push_back( it.first ); neighborhoodIDs.emplace_back( it.first );
for ( const auto& it : neighborCells_ ) for ( const auto& it : neighborFaces_ )
neighborhoodIDs.push_back( it.first ); neighborhoodIDs.emplace_back( it.first );
for ( const auto& it : neighborCells_ )
for ( const auto& neighborhoodID : neighborhoodIDs ) neighborhoodIDs.emplace_back( it.first );
{
bool referenced = false; std::unordered_set<PrimitiveID> neighborhood_from_local_primitives;
std::vector< PrimitiveID > neighborIDs;
auto work = std::make_shared<std::vector< PrimitiveID >>();
for ( const auto& localID : localPrimitiveIDs ) for ( const auto& localID : localPrimitiveIDs )
{ {
if ( referenced )
break;
Primitive* primitive = getPrimitive( localID ); Primitive* primitive = getPrimitive( localID );
std::vector< PrimitiveID > neighborIDs; neighborIDs.clear();
primitive->getNeighborPrimitives( neighborIDs ); primitive->getNeighborPrimitives(neighborIDs, work);
for ( const auto& neighborOfLocalID : neighborIDs ) neighborhood_from_local_primitives.insert(neighborIDs.begin(), neighborIDs.end());
{
if ( neighborOfLocalID == neighborhoodID )
{
referenced = true;
break;
}
}
} }
if ( !referenced ) for ( const auto& neighborhoodID : neighborhoodIDs )
{ {
if ( vertexExistsInNeighborhood( neighborhoodID ) ) if ( neighborhood_from_local_primitives.find(neighborhoodID) == neighborhood_from_local_primitives.end())
neighborVertices_.erase( neighborhoodID.getID() ); {
if ( edgeExistsInNeighborhood( neighborhoodID ) ) if ( vertexExistsInNeighborhood( neighborhoodID ) )
neighborEdges_.erase( neighborhoodID.getID() ); neighborVertices_.erase( neighborhoodID.getID() );
if ( faceExistsInNeighborhood( neighborhoodID ) ) if ( edgeExistsInNeighborhood( neighborhoodID ) )
neighborFaces_.erase( neighborhoodID.getID() ); neighborEdges_.erase( neighborhoodID.getID() );
if ( cellExistsInNeighborhood( neighborhoodID ) ) if ( faceExistsInNeighborhood( neighborhoodID ) )
neighborCells_.erase( neighborhoodID.getID() ); neighborFaces_.erase( neighborhoodID.getID() );
if ( cellExistsInNeighborhood( neighborhoodID ) )
neighborCells_.erase( neighborhoodID.getID() );
}
} }
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment