Skip to content

Commit

Permalink
Merge Pull Request #6706 from jvo1012/Trilinos/stk-2020-01-29
Browse files Browse the repository at this point in the history
Automatically Merged using Trilinos Pull Request AutoTester
PR Title: stk snapshot as of 2020-01-29
PR Author: jvo1012
  • Loading branch information
trilinos-autotester authored Feb 3, 2020
2 parents 0689f7f + 14a00f7 commit a0f0127
Show file tree
Hide file tree
Showing 122 changed files with 18,461 additions and 404 deletions.
16 changes: 14 additions & 2 deletions packages/stk/stk_balance/stk_balance/balance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "internal/balanceCoincidentElements.hpp"
#include "internal/balanceCommandLine.hpp"
#include "internal/privateDeclarations.hpp" // for callZoltan1, etc
#include "internal/NodeBalancer.hpp"
#include "stk_io/StkIoUtils.hpp"
#include "stk_mesh/base/BulkData.hpp" // for BulkData
#include "stk_mesh/base/Comm.hpp"
Expand Down Expand Up @@ -261,16 +262,27 @@ bool balanceStkMesh(const BalanceSettings& balanceSettings, stk::mesh::BulkData&

bool balanceStkMesh(const BalanceSettings& balanceSettings, stk::mesh::BulkData& stkMeshBulkData, const std::vector<stk::mesh::Selector>& selectors)
{
if( balanceSettings.getGraphOption() == BalanceSettings::LOAD_BALANCE )
if (balanceSettings.getGraphOption() == BalanceSettings::LOAD_BALANCE)
{
return loadBalance(balanceSettings, stkMeshBulkData, stkMeshBulkData.parallel_size(), selectors);
}
return false;
}

bool balanceStkMeshNodes(const BalanceSettings& balanceSettings, stk::mesh::BulkData& stkMeshBulkData)
{
if ((balanceSettings.getGraphOption() == BalanceSettings::LOAD_BALANCE) && balanceSettings.useNodeBalancer())
{
internal::NodeBalancer nodeBalancer(stkMeshBulkData);
return nodeBalancer.balance_node_entities(balanceSettings.getNodeBalancerTargetLoadBalance(),
balanceSettings.getNodeBalancerMaxIterations());
}
return false;
}

bool colorStkMesh(const BalanceSettings& colorSettings, stk::mesh::BulkData& stkMeshBulkData)
{
if(colorSettings.getGraphOption() == BalanceSettings::COLOR_MESH )
if (colorSettings.getGraphOption() == BalanceSettings::COLOR_MESH )
{
return colorMesh(colorSettings, stkMeshBulkData, {&(stkMeshBulkData.mesh_meta_data().locally_owned_part())});
}
Expand Down
1 change: 1 addition & 0 deletions packages/stk/stk_balance/stk_balance/balance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class StkBalanceSettings : public GraphCreationSettings

bool balanceStkMesh(const BalanceSettings& balanceSettings, stk::mesh::BulkData& stkMeshBulkData);
bool balanceStkMesh(const BalanceSettings& balanceSettings, stk::mesh::BulkData& stkMeshBulkData, const std::vector<stk::mesh::Selector>& selectors);
bool balanceStkMeshNodes(const BalanceSettings& balanceSettings, stk::mesh::BulkData& stkMeshBulkData);
bool colorStkMesh(const BalanceSettings& colorSettings, stk::mesh::BulkData& stkMeshBulkData);
void run_stk_rebalance(const ParsedOptions& options, MPI_Comm comm);
void run_stk_balance_with_settings(const std::string& outputDirectory, const std::string& exodusFilename, MPI_Comm comm, stk::balance::BalanceSettings& graphOptions);
Expand Down
52 changes: 52 additions & 0 deletions packages/stk/stk_balance/stk_balance/balanceUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,22 @@ bool BalanceSettings::useLocalIds() const
getGraphOption() == stk::balance::BalanceSettings::COLOR_MESH_AND_OUTPUT_COLOR_FIELDS;
}


bool BalanceSettings::useNodeBalancer() const
{
return false;
}

double BalanceSettings::getNodeBalancerTargetLoadBalance() const
{
return 1.0;
}

unsigned BalanceSettings::getNodeBalancerMaxIterations() const
{
return 5;
}

//////////////////////////////////////

size_t GraphCreationSettings::getNumNodesRequiredForConnection(stk::topology element1Topology, stk::topology element2Topology) const
Expand Down Expand Up @@ -264,6 +280,8 @@ int GraphCreationSettings::getGraphVertexWeight(stk::topology type) const
case stk::topology::LINE_2:
case stk::topology::BEAM_2:
case stk::topology::BEAM_3:
case stk::topology::SPRING_2:
case stk::topology::SPRING_3:
return 1;
case stk::topology::SHELL_TRIANGLE_3:
return 3;
Expand Down Expand Up @@ -393,6 +411,8 @@ int GraphCreationSettings::getConnectionTableIndex(stk::topology elementTopology
case stk::topology::BEAM_3:
case stk::topology::SHELL_LINE_2:
case stk::topology::SHELL_LINE_3:
case stk::topology::SPRING_2:
case stk::topology::SPRING_3:
tableIndex = 1;
break;
case stk::topology::TRI_3_2D:
Expand Down Expand Up @@ -457,6 +477,8 @@ int GraphCreationSettings::getEdgeWeightTableIndex(stk::topology elementTopology
case stk::topology::BEAM_3:
case stk::topology::SHELL_LINE_2:
case stk::topology::SHELL_LINE_3:
case stk::topology::SPRING_2:
case stk::topology::SPRING_3:
tableIndex = 1;
break;
case stk::topology::TRI_3_2D:
Expand Down Expand Up @@ -534,6 +556,36 @@ const stk::mesh::Field<int> * GraphCreationSettings::getSpiderConnectivityCountF
return m_spiderConnectivityCountField;
}

void GraphCreationSettings::setUseNodeBalancer(bool useBalancer)
{
m_useNodeBalancer = useBalancer;
}

void GraphCreationSettings::setNodeBalancerTargetLoadBalance(double targetLoadBalance)
{
m_nodeBalancerTargetLoadBalance = targetLoadBalance;
}

void GraphCreationSettings::setNodeBalancerMaxIterations(unsigned maxIterations)
{
m_nodeBalancerMaxIterations = maxIterations;
}

bool GraphCreationSettings::useNodeBalancer() const
{
return m_useNodeBalancer;
}

double GraphCreationSettings::getNodeBalancerTargetLoadBalance() const
{
return m_nodeBalancerTargetLoadBalance;
}

unsigned GraphCreationSettings::getNodeBalancerMaxIterations() const
{
return m_nodeBalancerMaxIterations;
}

const std::string& get_coloring_part_base_name()
{
static std::string coloringPartBaseName = "STK_INTERNAL_COLORING_PART";
Expand Down
37 changes: 28 additions & 9 deletions packages/stk/stk_balance/stk_balance/balanceUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ class BalanceSettings
virtual std::string getSpiderConnectivityCountFieldName() const;
virtual const stk::mesh::Field<int> * getSpiderConnectivityCountField(const stk::mesh::BulkData & stkMeshBulkData) const;
virtual bool useLocalIds() const;

virtual bool useNodeBalancer() const;
virtual double getNodeBalancerTargetLoadBalance() const;
virtual unsigned getNodeBalancerMaxIterations() const;

};

class BasicGeometricSettings : public BalanceSettings
Expand All @@ -160,15 +165,18 @@ class GraphCreationSettings : public BalanceSettings
{}

GraphCreationSettings(double faceSearchTol, double particleSearchTol, double edgeWeightSearch, const std::string& decompMethod, double multiplierVWSearch)
: mToleranceForFaceSearch(faceSearchTol),
mToleranceForParticleSearch(particleSearchTol),
edgeWeightForSearch (edgeWeightSearch),
method(decompMethod),
vertexWeightMultiplierForVertexInSearch(multiplierVWSearch),
m_UseConstantToleranceForFaceSearch(true),
m_shouldFixSpiders(false),
m_spiderConnectivityCountField(nullptr),
m_includeSearchResultInGraph(true)
: mToleranceForFaceSearch(faceSearchTol),
mToleranceForParticleSearch(particleSearchTol),
edgeWeightForSearch (edgeWeightSearch),
method(decompMethod),
vertexWeightMultiplierForVertexInSearch(multiplierVWSearch),
m_UseConstantToleranceForFaceSearch(true),
m_shouldFixSpiders(false),
m_spiderConnectivityCountField(nullptr),
m_includeSearchResultInGraph(true),
m_useNodeBalancer(false),
m_nodeBalancerTargetLoadBalance(1.0),
m_nodeBalancerMaxIterations(5)
{}

virtual ~GraphCreationSettings() = default;
Expand Down Expand Up @@ -210,6 +218,14 @@ class GraphCreationSettings : public BalanceSettings
virtual bool shouldFixSpiders() const override;
virtual const stk::mesh::Field<int> * getSpiderConnectivityCountField(const stk::mesh::BulkData & stkMeshBulkData) const override;

virtual void setUseNodeBalancer(bool useBalancer);
virtual void setNodeBalancerTargetLoadBalance(double targetLoadBalance);
virtual void setNodeBalancerMaxIterations(unsigned maxIterations);

virtual bool useNodeBalancer() const override;
virtual double getNodeBalancerTargetLoadBalance() const override;
virtual unsigned getNodeBalancerMaxIterations() const override;

protected:
int getConnectionTableIndex(stk::topology elementTopology) const;
int getEdgeWeightTableIndex(stk::topology elementTopology) const;
Expand All @@ -223,6 +239,9 @@ class GraphCreationSettings : public BalanceSettings
mutable const stk::mesh::Field<int> * m_spiderConnectivityCountField;
std::shared_ptr<stk::balance::FaceSearchTolerance> m_faceSearchToleranceFunction;
bool m_includeSearchResultInGraph;
bool m_useNodeBalancer;
double m_nodeBalancerTargetLoadBalance;
unsigned m_nodeBalancerMaxIterations;
};

class GraphCreationSettingsWithCustomTolerances : public GraphCreationSettings
Expand Down
184 changes: 184 additions & 0 deletions packages/stk/stk_balance/stk_balance/internal/NodeBalancer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#include "NodeBalancer.hpp"
#include <stk_mesh/base/Bucket.hpp>
#include <stk_mesh/base/BulkData.hpp>
#include <stk_mesh/base/Entity.hpp>
#include <stk_mesh/base/EntityKey.hpp>
#include <stk_mesh/base/MetaData.hpp>
#include <stk_mesh/base/Selector.hpp>
#include <stk_topology/topology.hpp>
#include <stk_util/environment/Env.hpp>
#include <stk_util/parallel/ParallelReduce.hpp>
#include <stk_util/parallel/ParallelVectorConcat.hpp>
#include "stk_balance/internal/privateDeclarations.hpp"

namespace stk {
namespace balance {
namespace internal {

NodeBalancer::NodeBalancer(stk::mesh::BulkData& bulk)
: m_bulkData(bulk),
m_metaData(bulk.mesh_meta_data())
{}

bool
NodeBalancer::balance_node_entities(const double targetLoadBalance,
const unsigned maxIterations)
{
bool changedNodeOwnership = false;
if (m_bulkData.parallel_size() == 1) return changedNodeOwnership;

for (unsigned bal = 0; bal < maxIterations; ++bal) {
int numLocallyOwnedNodes = 0;
double loadFactor = 0;

getGlobalLoadImbalance(loadFactor, numLocallyOwnedNodes);

const bool converged = (loadFactor <= targetLoadBalance);
if (converged) break;

std::set<int> neighborProcessors;
std::map<stk::mesh::Entity, std::vector<int>> interfaceNodesAndProcessors;

getInterfaceDescription(neighborProcessors,
interfaceNodesAndProcessors);

std::map<int, int> numLocallyOwnedByRank;
exchangeLocalSizes(neighborProcessors, numLocallyOwnedNodes, numLocallyOwnedByRank);

changedNodeOwnership = true;
changeOwnersOfNodes(interfaceNodesAndProcessors, numLocallyOwnedByRank, numLocallyOwnedNodes);
}
return changedNodeOwnership;
}

void
NodeBalancer::getInterfaceDescription(std::set<int>& neighborProcessors,
std::map<stk::mesh::Entity,
std::vector<int> >& interfaceNodesAndProcessors)
{
stk::mesh::Selector sharedSelector(m_metaData.globally_shared_part());
const stk::mesh::BucketVector& buckets = m_bulkData.get_buckets(stk::topology::NODE_RANK, sharedSelector);

int numInterfaceNodesOwned = 0;

for (auto ib = buckets.begin(); ib != buckets.end(); ++ib) {

const stk::mesh::Bucket& b = **ib;
const size_t nnodes = b.size();
const bool isOwned = b.owned();
for (size_t n = 0; n < nnodes; ++n) {
stk::mesh::Entity node = b[n];
std::vector<int> shared_procs;

m_bulkData.comm_shared_procs(m_bulkData.entity_key(node), shared_procs);
neighborProcessors.insert(shared_procs.begin(), shared_procs.end());
std::pair<stk::mesh::Entity, std::vector<int>> item(node, shared_procs);
interfaceNodesAndProcessors.insert(item);
if (isOwned) {
numInterfaceNodesOwned++;
}
}
}
}

void
NodeBalancer::getGlobalLoadImbalance(double &loadFactor, int& numLocallyOwnedNodes)
{
stk::mesh::Selector localSelector = m_metaData.locally_owned_part();
stk::mesh::EntityVector ownedNodes;
m_bulkData.get_entities(stk::topology::NODE_RANK, localSelector, ownedNodes);

numLocallyOwnedNodes = ownedNodes.size();
int maxLocallyOwned = 0;
int minLocallyOwned = 0;
stk::all_reduce_max(m_bulkData.parallel(), &numLocallyOwnedNodes, &maxLocallyOwned, 1);
stk::all_reduce_min(m_bulkData.parallel(), &numLocallyOwnedNodes, &minLocallyOwned, 1);
loadFactor = double(maxLocallyOwned) / double(minLocallyOwned);

internal::logMessage(m_bulkData.parallel(),
"Balancing locally-owned nodes: min = " + std::to_string(minLocallyOwned) +
", max = " + std::to_string(maxLocallyOwned) +
" (loadFactor = " + std::to_string(loadFactor) + ")");
}

void
NodeBalancer::exchangeLocalSizes(const std::set<int>& neighborProcessors,
int& numLocallyOwnedNodes,
std::map<int, int> &numLocallyOwnedByRank)
{
size_t numCommunications = neighborProcessors.size();
std::vector<int> recvBuffer(numCommunications);
std::vector<MPI_Request> receiveRequests(numCommunications);
std::vector<MPI_Request> sendRequests(numCommunications);

int bufferCounter = 0;
for (int p : neighborProcessors) {
MPI_Irecv(&recvBuffer[bufferCounter], 1, MPI_INT, p,
MPI_ANY_TAG, m_bulkData.parallel(), &receiveRequests[bufferCounter]);
++bufferCounter;
}

bufferCounter = 0;
for (int p : neighborProcessors) {
MPI_Isend(&numLocallyOwnedNodes, 1, MPI_INT, p, 0, m_bulkData.parallel(), &sendRequests[bufferCounter]);
++bufferCounter;
}

std::vector<MPI_Status> receiveStati(receiveRequests.size());
MPI_Waitall(receiveRequests.size(), &receiveRequests[0], &receiveStati[0]);

std::vector<MPI_Status> sendStati(sendRequests.size());
MPI_Waitall(sendRequests.size(), &sendRequests[0], &sendStati[0]);

int i = 0;
for (int p : neighborProcessors) {
int n = recvBuffer[i];
numLocallyOwnedByRank.insert(std::pair<int, int>(p, n));
++i;
}
}

void
NodeBalancer::changeOwnersOfNodes(const std::map<stk::mesh::Entity, std::vector<int> >& interfaceNodesAndProcessors,
std::map<int, int>& numLocallyOwnedByRank,
int numLocallyOwnedNodes)
{
int myRank = m_bulkData.parallel_rank();

stk::mesh::EntityProcVec nodesToMove;

for (const auto & nodeProcs : interfaceNodesAndProcessors) {
stk::mesh::Entity node = nodeProcs.first;
const bool isOwned = m_bulkData.bucket(node).owned();

if (!isOwned) continue;

const auto & procs = nodeProcs.second;
double maxLoad = 1;
int destination = myRank;

for (auto p : procs) {
double numOwnedByP = numLocallyOwnedByRank[p];
double load = double(numLocallyOwnedNodes) / numOwnedByP;
if (load > maxLoad) { //could test for max rank
maxLoad = load;
destination = p;
}
}

if (destination != myRank) {
std::pair<stk::mesh::Entity, int> item(node, destination);
nodesToMove.push_back(item);
numLocallyOwnedNodes--;
numLocallyOwnedByRank[destination] += 1;
}

}

m_bulkData.change_entity_owner(nodesToMove);
}


}
}
}
Loading

0 comments on commit a0f0127

Please sign in to comment.