Commit 7f8033a2 authored by adelmann's avatar adelmann 🎗
Browse files

cleanup

parent d287a9ba
......@@ -5,25 +5,6 @@
/LICENSE -text
/README -text
cmake/IPPLConfig.cmake.in -text
doc/BRICK/BinaryBalancer.cpp -text
doc/BRICK/BinaryBalancer.h -text
doc/BRICK/CenteredFieldLayout.cpp -text
doc/BRICK/CenteredFieldLayout.h -text
doc/BRICK/ConejoBalancer.cpp -text
doc/BRICK/ConejoBalancer.h -text
doc/BRICK/ConejoBalancer_inst.cpp -text
doc/BRICK/FieldLayout.cpp -text
doc/BRICK/FieldLayout.h -text
doc/BRICK/FieldLayoutUser.cpp -text
doc/BRICK/FieldLayoutUser.h -text
doc/BRICK/MultiBalancer.cpp -text
doc/BRICK/MultiBalancer.h -text
doc/BRICK/MultiBalancer.t.cpp -text
doc/BRICK/VRB.cpp -text
doc/BRICK/VRB.h -text
doc/BRICK/Vnode.h -text
doc/BRICK/VnodeMultiBalancer.cpp -text
doc/BRICK/VnodeMultiBalancer.h -text
doc/DiscField/DiscFieldDoc.doc -text
doc/DiscField/DiscFieldDoc.htm -text
doc/DiscField/DiscFieldDoc.pdf -text
......
This diff is collapsed.
// -*- C++ -*-
/***************************************************************************
*
* The IPPL Framework
*
*
* Visit http://people.web.psi.ch/adelmann/ for more details
*
***************************************************************************/
#ifndef BINARY_BALANCER_H
#define BINARY_BALANCER_H
//////////////////////////////////////////////////////////////////////
/*
A fairly simple load balancer inspired by Dan Quinlan's MLB.
It does recursive binary subdivision of a FieldLayout domain,
restricting the cuts to coordinate directions, so as to balance the
workload. The "workload" is given by a Field of weights passed in.
It decides on the cut axis by cutting the longest axis of a brick,
and the location of that cut by balancing the weights on each side
of the cut. The resulting distribution has one vnode per processor.
This is restricted to a processor number that is a power of two.
It performs log(P) parallel reductions.
It does nothing fancy when deciding on the splits to try to make the
new paritioning close to the previous. The same set of weights will
always give the same repartitioning, but similar sets of weights
could result in quite different partitionings.
There are two functions defined here:
NDIndex<Dim>
CalcBinaryRepartion(FieldLayout<Dim>&, BareField<double,Dim>&);
Given a FieldLayout and a Field of weights, find the domain for this
processor. This does not repartition the FieldLayout, it just
calculates the domain. If you want to further subdivide these
domains, just cut up what this function returns.
void
BinaryRepartition(FieldLayout<Dim>&, BareField<double,Dim>&);
Just call the above function and then repartition the FieldLayout
(and all the Fields defined on it).
*/
//////////////////////////////////////////////////////////////////////
// forward declarations
template<unsigned Dim> class FieldLayout;
template<class T, unsigned Dim> class BareField;
// Calculate the local domain for a binary repartition.
template<unsigned Dim>
NDIndex<Dim>
CalcBinaryRepartition(FieldLayout<Dim>&, BareField<double,Dim>&);
// Calculate and apply a local domain for a binary repartition.
template<unsigned Dim>
void
BinaryRepartition(FieldLayout<Dim>& layout, BareField<double,Dim>& weights)
{
layout.Repartition( CalcBinaryRepartition(layout,weights) );
}
//////////////////////////////////////////////////////////////////////
#include "FieldLayout/BinaryBalancer.cpp"
#endif // BINARY_BALANCER_H
/***************************************************************************
* $RCSfile: BinaryBalancer.h,v $ $Author: adelmann $
* $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:27 $
* IPPL_VERSION_ID: $Id: BinaryBalancer.h,v 1.1.1.1 2003/01/23 07:40:27 adelmann Exp $
***************************************************************************/
This diff is collapsed.
// -*- C++ -*-
/***************************************************************************
*
* The IPPL Framework
*
*
* Visit http://people.web.psi.ch/adelmann/ for more details
*
***************************************************************************/
#ifndef CENTERED_FIELD_LAYOUT_H
#define CENTERED_FIELD_LAYOUT_H
// include files
#include "FieldLayout/FieldLayout.h"
template<unsigned Dim, class Mesh, class Centering>
class CenteredFieldLayout : public FieldLayout<Dim>
{
public:
//---------------------------------------------------------------------------
// Constructors from a mesh object only and parallel/serial specifiers.
// If not doing this, user should be just using simple FieldLayout object,
// though no harm would be done in constructiong a CenteredFieldLayout with
// Index/NDIndex arguments via the inherited constructors from FieldLayout.
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// These specify only a total number of vnodes, allowing the constructor
// complete control on how to do the vnode partitioning of the index space:
// Constructor for arbitrary dimension with parallel/serial specifier array:
// This one also works if nothing except mesh is specified:
CenteredFieldLayout(Mesh& mesh,
e_dim_tag *p=0,
int vnodes=-1);
// Special constructor which uses a existing partition
// particular from expde
// ada: BrickInfo CenteredFieldLayout(BrickInfo *bi,Mesh& mesh,e_dim_tag *p=0,int vnodes=-1);
// Constructors for 1 ... 6 dimensions with parallel/serial specifiers:
CenteredFieldLayout(Mesh& mesh,
e_dim_tag p1,
int vnodes=-1);
CenteredFieldLayout(Mesh& mesh,
e_dim_tag p1, e_dim_tag p2,
int vnodes=-1);
CenteredFieldLayout(Mesh& mesh,
e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
int vnodes=-1);
CenteredFieldLayout(Mesh& mesh,
e_dim_tag p1, e_dim_tag p2, e_dim_tag p3, e_dim_tag p4,
int vnodes=-1);
CenteredFieldLayout(Mesh& mesh,
e_dim_tag p1, e_dim_tag p2, e_dim_tag p3, e_dim_tag p4,
e_dim_tag p5,
int vnodes=-1);
CenteredFieldLayout(Mesh& mesh,
e_dim_tag p1, e_dim_tag p2, e_dim_tag p3, e_dim_tag p4,
e_dim_tag p5, e_dim_tag p6,
int vnodes=-1);
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// These specify both the total number of vnodes and the numbers of vnodes
// along each dimension for the partitioning of the index space. Obviously
// this restricts the number of vnodes to be a product of the numbers along
// each dimension (the constructor implementation checks this):
// Constructor for arbitrary dimension with parallel/serial specifier array:
CenteredFieldLayout(Mesh& mesh, e_dim_tag *p,
unsigned* vnodesAlongDirection,
bool recurse=false,
int vnodes=-1);
// Constructors for 1 ... 6 dimensions with parallel/serial specifiers:
CenteredFieldLayout(Mesh& mesh,
e_dim_tag p1,
unsigned vnodes1,
bool recurse=false,
int vnodes=-1);
CenteredFieldLayout(Mesh& mesh,
e_dim_tag p1, e_dim_tag p2,
unsigned vnodes1, unsigned vnodes2,
bool recurse=false,
int vnodes=-1);
CenteredFieldLayout(Mesh& mesh,
e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
unsigned vnodes1, unsigned vnodes2, unsigned vnodes3,
bool recurse=false,
int vnodes=-1);
CenteredFieldLayout(Mesh& mesh,
e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
e_dim_tag p4,
unsigned vnodes1, unsigned vnodes2, unsigned vnodes3,
unsigned vnodes4,
bool recurse=false,
int vnodes=-1);
CenteredFieldLayout(Mesh& mesh,
e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
e_dim_tag p4, e_dim_tag p5,
unsigned vnodes1, unsigned vnodes2, unsigned vnodes3,
unsigned vnodes4, unsigned vnodes5,
bool recurse=false,
int vnodes=-1);
CenteredFieldLayout(Mesh& mesh,
e_dim_tag p1, e_dim_tag p2, e_dim_tag p3,
e_dim_tag p4, e_dim_tag p5, e_dim_tag p6,
unsigned vnodes1, unsigned vnodes2, unsigned vnodes3,
unsigned vnodes4, unsigned vnodes5, unsigned vnodes6,
bool recurse=false,
int vnodes=-1);
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// A constructor a a completely user-specified partitioning of the
// mesh space.
CenteredFieldLayout(Mesh& mesh,
const NDIndex<Dim> *dombegin,
const NDIndex<Dim> *domend,
const int *nbegin,
const int *nend);
};
#include "FieldLayout/CenteredFieldLayout.cpp"
#endif // CENTERED_FIELD_LAYOUT_H
/***************************************************************************
* $RCSfile: CenteredFieldLayout.h,v $ $Author: adelmann $
* $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:27 $
* IPPL_VERSION_ID: $Id: CenteredFieldLayout.h,v 1.1.1.1 2003/01/23 07:40:27 adelmann Exp $
***************************************************************************/
// -*- C++ -*-
/***************************************************************************
*
* The IPPL Framework
*
* This program was prepared by PSI.
* All rights in the program are reserved by PSI.
* Neither PSI nor the author(s)
* makes any warranty, express or implied, or assumes any liability or
* responsibility for the use of this software
*
* Visit http://www.acl.lanl.gov/POOMS for more details
*
***************************************************************************/
// -*- C++ -*-
/***************************************************************************
*
* The IPPL Framework
*
*
* Visit http://people.web.psi.ch/adelmann/ for more details
*
***************************************************************************/
// include files
#include "FieldLayout/ConejoBalancer.h"
#include "FieldLayout/MultiBalancer.h"
#include "Utility/IplInfo.h"
//////////////////////////////////////////////////////////////////////
//
// reduceLocalWeights
//
// Input:
// BareField<T,D> with weights
// bool dropCompressed, which is true if compressed vnodes in weights
// should have the weight of a single element instead of multiplied
// by the number of elements.
// Outout: a container of doubles.
//
// Given a BareField and a container,
// loop over each vnode, finding the maximum weight
// on each vnode.
// Put those reduced weights in the container.
//
// This is a bare function, since it does not depend on anything
// in the class ConejoBalancer.
// This is an inline function so it does not generate an additional
// prelink step.
//
template<class T, unsigned int D>
inline void
reduceLocalWeights(BareField<T,D>& weights,
vector<double>& vnodeWeights,
bool dropCompressed)
{
// Get an iterator and loop over the LFields of the BareField.
typename BareField<T,D>::iterator_if lf = weights.begin_if();
for ( ; lf != weights.end_if() ; ++lf )
{
// Get an iterator and loop over the contents of this LField.
typename LField<T,D>::iterator lp = (*lf).second->begin();
// A place to record the total weight.
// Start with just the first element.
double x = *lp;
// If the LField is compressed and and dropCompressed is true,
// then the weight from this vnode comes from just the one element.
if ( !(dropCompressed && (*lf).second->IsCompressed()) )
{
// Add up all the values in the vnode.
for ( ++lp ; lp != (*lf).second->end() ; ++lp )
x += *lp;
}
// Append the largest value to the container.
vnodeWeights.push_back( x );
}
}
//////////////////////////////////////////////////////////////////////
//
// PRIVATE member functions
//
//////////////////////////////////////////////////////////////////////
//mwerks Moved into class definition (.h file).
/***************************************************************************
* $RCSfile: ConejoBalancer.cpp,v $ $Author: adelmann $
* $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:27 $
* IPPL_VERSION_ID: $Id: ConejoBalancer.cpp,v 1.1.1.1 2003/01/23 07:40:27 adelmann Exp $
***************************************************************************/
// -*- C++ -*-
/***************************************************************************
*
* The IPPL Framework
*
*
* Visit http://people.web.psi.ch/adelmann/ for more details
*
***************************************************************************/
//////////////////////////////////////////////////////////////////////
// Class ConejoBalancer
//////////////////////////////////////////////////////////////////////
#ifndef CONEJO_BALANCER_H
#define CONEJO_BALANCER_H
//////////////////////////////////////////////////////////////////////
//
// Description:
// A load balancer designed for the Conejo code.
// It distributes the vnodes so that each of the materials is
// simultaneously load balanced.
//
//////////////////////////////////////////////////////////////////////
// include files
#include "Field/BareField.h"
#ifdef IPPL_STDSTL
#include <vector>
using std::vector;
#else
#include <vector.h>
#endif
// forward declarations
class MultiBalancer;
template<unsigned int D> class FieldLayout;
template<unsigned int D> class NDIndex;
/*
ConejoBalancer is an interface class for MultiBalancer.
**************************************************
GENERAL DESCRIPTION
**************************************************
ConejoBalancer does the following things:
1. Inputs a series of BareFields with weights for each
grid location for each material.
2. Sum the weights to a single value per vnode.
3. Uses MultiBalancer to find the new distribution of vnodes.
4. Rebalances one or more FieldLayouts for that new distribution.
*/
class ConejoBalancer
{
public:
// Construct the ConejoBalancer.
// This needs no arguments since it gets its information
// from member functions below.
ConejoBalancer();
// Destroy the balancer.
~ConejoBalancer();
// Add a new set of weights for a new material.
// if dropCompressed is true, complressed vnodes in weights
// are considered to have weight of just one element.
//mwerks template<class T, unsigned int D>
//mwerks void addMaterial(BareField<T,D>& weights, bool dropCompressed=false);
//////////////////////////////////////////////////////////////////////
//
// ConejoBalancer::addMaterial
//
// Input:
// BareField with weights for this material.
// bool dropCompressed, which is true if compressed vnodes in weights
// should have the weight of a single element instead of multiplied
// by the number of elements.
// Output: The state of the ConejoBalancer includes the new weights.
//
// Extracting the weights goes through several phases:
// 1. If this is the first time this has been called,
// initialize the MultiBalancer.
// 2. Calculate the weights for the local part of the BareField.
// 3a. If this is not processor zero, send those weights to processor zero.
// 3b. If it is processor zero, collect the weights.
//
template<class T, unsigned int D>
void addMaterial(BareField<T,D>& weights, bool dropCompressed)
{
// Initialize (or check consistency).
setupVnodes(weights.size_if(), weights.getLayout().size_rdv());
// A container to hold the reduced weights for the local vnodes.
vector<double> vnodeWeights;
vnodeWeights.reserve(m_localVnodes);
// Get the local weights.
reduceLocalWeights(weights,vnodeWeights,dropCompressed);
// Get a message tag.
int tag = Ipl::Comm->next_tag(F_CONEJO_BALANCER_TAG, F_TAG_CYCLE);
// Everybody sends their data to processor zero.
sendWeights(vnodeWeights,tag);
// If we are processor zero, process messages.
if ( m_myProc == 0 )
receiveWeights(vnodeWeights,tag);
}
// Redistribute a FieldLayout using the stored weights.
//mwerks template<unsigned int D>
//mwerks void redistribute(FieldLayout<D>& layout);
//////////////////////////////////////////////////////////////////////
//
// ConejoBalancer::redistribute
//
// Redistribute a FieldLayout using the stored weights.
//
template<unsigned int D>
void redistribute(FieldLayout<D>& layout)
{
// Get message tags.
int bcasttag = Ipl::Comm->next_tag(F_CB_BCAST_TAG, F_TAG_CYCLE);
int domaintag = Ipl::Comm->next_tag(F_CB_DOMAIN_TAG, F_TAG_CYCLE);
// On proc 0, figure things out and send them.
if ( m_myProc == 0 )
{
// Tell the MultiBalancer to figure out the new distribution.
m_balancer->distribute();
// Broadcast the vnode ids that each processor will have to send.
broadcastVnodesToSend(bcasttag);
}
// Everywhere receives the id's of the vnodes it will send.
vector<int> vnodeDestinations;
receiveVnodesToSend(vnodeDestinations,bcasttag);
// Send the domains for the vnodes to their new homes.
sendVnodeDomains(vnodeDestinations,layout,domaintag);
// Receive the domains for the vnodes that will live here.
vector< NDIndex<D> > vnodeDomains;
receiveVnodeDomains(vnodeDomains,domaintag);
// Redistribute the FieldLayout using the new local domains.
NDIndex<D> *p = &*(vnodeDomains.begin());
layout.Repartition( p , p + vnodeDomains.size() );
}
private:
// Keep a pointer to the object that encapsulates the algorithm.
MultiBalancer *m_balancer;
// Remember the number of local vnodes.
int m_localVnodes;
// Remember the total number of vnodes.
int m_totalVnodes;
// Remember the number of processors.
int m_procs;
// Remember my processor.
int m_myProc;
// Record the number of vnodes on each processor.
vector<int> m_vnodeCounts;
// Support functions for internal use.
void sendWeights(vector<double>& vnodeWeights, int tag);
void receiveWeights(vector<double>& vnodeWeights, int tag);
void setupVnodes(int localVnodes, int remoteVnodes);
void recordVnodeCount(int count, int proc);
void broadcastVnodesToSend(int tag);
void receiveVnodesToSend(vector<int>& vnodeDestinations,int tag);
//mwerks template<unsigned int D>
//mwerks void sendVnodeDomains(vector<int>& vnodeDests,
//mwerks FieldLayout<D>& layout,
//mwerks int tag);
//
// ConejoBalancer::sendVnodeDomains
//
// Send to all the other processors the domains for the vnodes
// that will be sent.
// Here just the NDIndexes are being sent.
// The contents of the Fields on those domains will be sent later.
//
template<unsigned int D>
void sendVnodeDomains(vector<int>& vnodeDests,
FieldLayout<D>& layout,
int tag)
{
// A buffer for writing down the domains to be sent.
vector< NDIndex<D> > send;
// Loop over processors, sending a message to each.
for ( int proc = 0; proc < m_procs; ++proc )
{
// Loop over the local vnodes, figuring out where each should go.
vector<int>::iterator vp = vnodeDests.begin();
typename FieldLayout<D>::iterator_iv fp = layout.begin_iv();
for ( ; vp!=vnodeDests.end(); ++vp, ++fp)
{
// If this vnode is going to processor proc
if ( *vp == proc )
// Record the domain for sending.
send.push_back( (*fp).second->getDomain() );
}
// Build the message to be sent.
Message *msg = new Message;
// Add the domains to the message.
NDIndex<D> *p = &*(send.begin());
msg->put(send.size());
putMessage(*msg, p , p + send.size() );
// Send the message.
Ipl::Comm->send(msg,proc,tag);
// Clear the send container.
send.clear();
}
}
//mwerks template<unsigned int D>
//mwerks void receiveVnodeDomains(vector< NDIndex<D> >& vnodeDomains, int tag);
//////////////////////////////////////////////////////////////////////
//
// ConejoBalancer::receiveVnodeDomains
//
// Each processor receives from all the other processors
// the domains it will have after the redistribution.
//
template<unsigned int D>
void receiveVnodeDomains(vector< NDIndex<D> >& vnodeDomains,
int tag)
{
// Loop over all the processors, receiving a message from each.
for (int proc=0; proc < m_procs; ++proc)
{
// Receive a message from any processor.
int any_proc = -1;
Message *msg = Ipl::Comm->receive_block(any_proc,tag);
// Get the number of NDIndexes in this message.
long int s;
msg->get(s);
// Make sure the size isn't negative.
PAssert(s>=0);
// If there are any there, unpack them.
if ( s != 0 )