33 #ifndef MADNESS_MRA_IBDEUX_H__INCLUDED
34 #define MADNESS_MRA_IBDEUX_H__INCLUDED
51 template<
typename T, std::
size_t NDIM>
54 template<
typename T, std::
size_t NDIM>
57 template <std::
size_t NDIM>
60 typedef std::pair<keyT,ProcessID> pairT;
61 typedef std::map<keyT,ProcessID> mapT;
63 typedef typename mapT::const_iterator iteratorT;
67 for (
unsigned int i=0; i<v.size(); ++i) {
75 while (key.
level() >= 0) {
76 iteratorT it = map.find(key);
77 if (it == map.end()) {
85 throw "LBDeuxPmap: lookup failed";
95 template <std::
size_t NDIM>
97 static const int nchild = (1<<
NDIM);
101 volatile double child_cost[nchild];
102 volatile double my_cost;
103 volatile double total_cost;
104 volatile bool gotkids;
108 int index(
const keyT& key) {
110 for (std::size_t d=0; d<
NDIM; ++d) ind += ((key.
translation()[d])&0x1) << d;
116 : my_cost(0.0), total_cost(0.0), gotkids(false) {
118 for (
int i=0; i<nchild; ++i)
123 my_cost(other.my_cost), total_cost(other.total_cost), gotkids(other.gotkids)
125 nsummed = other.nsummed;
126 for (
int i=0; i<nchild; ++i)
127 child_cost[i] = other.child_cost[i];
131 for (
int i=0; i<nchild; ++i)
132 child_cost[i] = other.child_cost[i];
133 my_cost = other.my_cost;
134 total_cost = other.total_cost;
135 gotkids = other.gotkids;
136 nsummed = other.nsummed;
151 total_cost = (my_cost += cost);
152 gotkids = gotkids || got_kids;
157 Void sum(
const treeT& tree,
const keyT& child,
double value) {
158 child_cost[index(child)] = value;
160 if (nsummed == nchild) {
161 for (
int i=0; i<nchild; ++i) total_cost += child_cost[i];
162 if (child.
level() > 1) {
163 keyT key = child.
parent();
164 keyT parent = key.
parent();
165 const_cast<treeT&
>(tree).task(parent, &
nodeT::sum, tree, key,
double(total_cost));
177 total_cost = my_cost = -1.0;
180 const keyT child = kit.key();
181 const_cast<treeT&
>(tree).task(child, &
nodeT::deleter, tree, child);
194 const keyT child = kit.key();
195 int ind = index(child);
197 vals[ind] = child_cost[ind];
199 for (
int i=0; i<nchild; ++i) {
200 for (
int j=i+1; j<nchild; ++j) {
201 if (vals[i] < vals[j]) {
209 for (
int i=0; i<nchild; ++i) {
210 if (total_cost <= avg) {
211 const_cast<treeT&
>(tree).task(keys[i], &
nodeT::deleter, tree, keys[i]);
214 total_cost -= vals[i];
215 const_cast<treeT&
>(tree).task(keys[i], &
nodeT::partition, tree, keys[i], avg);
222 template <
typename Archive>
229 template <std::
size_t NDIM>
240 template <
typename T,
typename costT>
244 add_op(
LoadBalanceDeux* lb,
const costT& costfn) : lb(lb), costfn(costfn) {}
253 const_iteratorT end = tree.
end();
254 for (const_iteratorT it=tree.
begin(); it!=end; ++it) {
255 const keyT& key = it->first;
256 const nodeT& node = it->second;
265 total = tree.
find(key0).get()->second.get_total_cost();
274 static bool compare(
const std::pair<keyT,double>&
a,
const std::pair<keyT,double>&
b) {
275 return a.second < b.second;
287 template <
typename T,
typename costT>
289 const_cast<Function<T,NDIM>&
>(
f).unaryop_node(add_op<T,costT>(
this,costfn), fence);
295 iteratorT it = futit.
get();
296 if (it != tree.
end()) {
297 for (
int i=0; i<key.level(); ++i) std::cout <<
" ";
298 print(key, it->second.get_total_cost());
300 if (it->second.has_children()) {
314 return cost > other.
cost;
322 double avg = sum()/(world.
size()*fac);
334 std::vector< std::pair<keyT,double> > results;
335 const_iteratorT end = tree.
end();
336 for (const_iteratorT it=tree.
begin(); it!=end; ++it) {
337 if (it->second.get_total_cost() >= 0) {
338 results.push_back(std::make_pair(it->first,it->second.get_total_cost()));
341 results = world.
gop.
concat0(results, 128*1024*1024);
344 std::vector< std::pair<keyT,ProcessID> > map;
346 if (world.
rank() == 0) {
348 std::sort(results.begin(), results.end(), compare);
350 print(
"THESE ARE THE INITIAL SUBTREES");
351 for (
unsigned int i=0; i<results.size(); ++i)
print(i,results[i]);
355 map.reserve(results.size());
358 unsigned int nproc = world.
size();
359 std::priority_queue<CostPerProc> costs;
360 for (
unsigned int p=0; p<nproc && !results.empty(); ++p) {
361 const std::pair<keyT,double>&
f = results.back();
363 map.push_back(std::make_pair(f.first,p));
368 while (!results.empty()) {
369 const std::pair<keyT,double>&
f = results.back();
372 top.
cost += f.second;
374 map.push_back(std::make_pair(f.first,top.
proc));
378 print(
"THIS IS THE MAP");
380 print(
"THESE ARE THE COSTS PER PROCESSOR");
381 while (!costs.empty()) {
382 print(costs.top().proc,costs.top().cost);
400 #endif // MADNESS_MRA_IBDEUX_H__INCLUDED
WorldGopInterface & gop
Global operations.
Definition: worldfwd.h:462
Definition: shared_ptr_bits.h:38
FunctionDefaults holds default paramaters as static class members.
Definition: funcdefaults.h:175
bool find(accessor &acc, const keyT &key)
Write access to LOCAL value by key. Returns true if found, false otherwise (always false for remote)...
Definition: worlddc.h:740
void print_tree(const keyT &key=keyT(0))
Printing for the curious.
Definition: lbdeux.h:293
bool has_children() const
Returns true if this node has children.
Definition: funcimpl.h:196
const Vector< Translation, NDIM > & translation() const
Definition: key.h:225
LBNodeDeux< NDIM > & operator=(const LBNodeDeux< NDIM > &other)
Definition: lbdeux.h:130
const int NDIM
Definition: tdse1.cc:44
std::shared_ptr< WorldDCPmapInterface< keyT > > load_balance(double fac=1.0, bool printstuff=false)
Actually does the partitioning of the tree.
Definition: lbdeux.h:319
Iterator for distributed container wraps the local iterator.
Definition: worlddc.h:159
double get_total_cost() const
Definition: lbdeux.h:145
Void partition(const treeT &tree, const keyT &key, double avg)
Descends tree deleting all except internal nodes and sub-tree parents.
Definition: lbdeux.h:188
ProcessID owner(const keyT &key) const
Maps key to processor.
Definition: lbdeux.h:74
LoadBalanceDeux(World &world)
Definition: lbdeux.h:280
NDIM & f
Definition: mra.h:2179
iterator end()
Returns an iterator past the end of the local data (no communication)
Definition: worlddc.h:835
ProcessID size() const
Returns the number of processes in this world (same as MPI_Comm_size())
Definition: worldfwd.h:533
Provides FunctionDefaults and utilities for coordinate transformation.
iterator begin()
Returns an iterator to the beginning of the local data (no communication)
Definition: worlddc.h:822
LBDeuxPmap(const std::vector< pairT > &v)
Definition: lbdeux.h:66
Void add(double cost, bool got_kids)
Accumulates cost into this node.
Definition: lbdeux.h:150
bool operator<(const CostPerProc &other) const
Definition: lbdeux.h:313
Void deleter(const treeT &tree, const keyT &key)
Logically deletes this node by setting cost to -1.
Definition: lbdeux.h:176
CostPerProc(double cost, int proc)
Definition: lbdeux.h:312
CostPerProc()
Definition: lbdeux.h:311
void broadcast_serializable(objT &obj, ProcessID root)
Broadcast a serializable object.
Definition: worldgop.h:707
T & get()
Gets the value, waiting if necessary (error if not a local future)
Definition: worldfut.h:513
Key parent(int generation=1) const
Returns the key of the parent.
Definition: key.h:248
bool has_children() const
Definition: lbdeux.h:141
FLOAT a(int j, FLOAT z)
Definition: y1.cc:86
Level level() const
Definition: key.h:220
LBNodeDeux()
Definition: lbdeux.h:115
Void sum(const treeT &tree, const keyT &child, double value)
Accumulates cost up the tree from children.
Definition: lbdeux.h:157
An integer with atomic set, get, read+inc, read+dec, dec+test operations.
Definition: atomicint.h:73
A parallel world with full functionality wrapping an MPI communicator.
Definition: worldfwd.h:416
void fence()
Synchronizes all processes in communicator AND globally ensures no pending AM or tasks.
Definition: worldgop.cc:52
int proc
Definition: lbdeux.h:310
A multiresolution adaptive numerical function.
Definition: derivative.h:61
int ProcessID
Used to clearly identify process number/rank.
Definition: worldtypes.h:37
Future< MEMFUN_RETURNT(memfunT) > send(const keyT &key, memfunT memfun)
Sends message "resultT memfun()" to item (non-blocking comm if remote)
Definition: worlddc.h:919
FunctionNode holds the coefficients, etc., at each node of the 2^NDIM-tree.
Definition: derivative.h:58
ProcessID rank() const
Returns the process rank in this world (same as MPI_Comm_rank()))
Definition: worldfwd.h:526
archive_array< unsigned char > wrap_opaque(const T *, unsigned int)
Factory function to wrap pointer to contiguous data as opaque (uchar) archive_array.
Definition: archive.h:827
ProcessID owner(const keyT &key) const
Returns processor that logically owns key (no communication)
Definition: worlddc.h:786
std::vector< T > concat0(const std::vector< T > &v, size_t bufsz=1024 *1024)
Concatenate an STL vector of serializable stuff onto node 0.
Definition: worldgop.h:846
void serialize(Archive &ar)
Definition: lbdeux.h:223
double cost
Definition: lbdeux.h:309
LBNodeDeux(const LBNodeDeux< NDIM > &other)
Definition: lbdeux.h:122
void broadcast(void *buf, size_t nbyte, ProcessID root, bool dowork=true)
Broadcasts bytes from process root while still processing AM & tasks.
Definition: worldgop.cc:145
Implements WorldContainer.
void print() const
Definition: lbdeux.h:88
A future is a possibly yet unevaluated value.
Definition: ref.h:210
A type you can return when you want to return void ... use "return None".
Definition: typestuff.h:154
Interface to be provided by any process map.
Definition: worlddc.h:64
Future< REMFUTURE(MEMFUN_RETURNT(memfunT)) > task(const keyT &key, memfunT memfun, const TaskAttributes &attr=TaskAttributes())
Adds task "resultT memfun()" in process owning item (non-blocking comm if remote) ...
Definition: worlddc.h:1148
void print(const A &a)
Print a single item to std::cout terminating with new line.
Definition: print.h:122
Multidimension Key for MRA tree and associated iterators.
Holds machinery to set up Functions/FuncImpls using various Factories and Interfaces.
Definition: chem/atomutil.cc:45
FLOAT b(int j, FLOAT z)
Definition: y1.cc:79
void add_tree(const Function< T, NDIM > &f, const costT &costfn, bool fence=false)
Accumulates cost from a function.
Definition: lbdeux.h:288
void swap(mpfr::mpreal &x, mpfr::mpreal &y)
Definition: mpreal.h:3069
Key is the index for a node of the 2^NDIM-tree.
Definition: key.h:69
Iterates in lexical order thru all children of a key.
Definition: key.h:61