MADNESS  version 0.9
mypmap.h
Go to the documentation of this file.
1 // #include <madness/world/world.h>
2 // #include <madness/misc/misc.h>
3 // #include <madness/tensor/tensor.h>
4 // #include <madness/misc/ran.h>
5 // #include <madness/mra/key.h>
6 // #include <madness/mra/funcimpl.h>
7 
8 
9 This is not presently in use but is left here since it is actually useful. It provides a process map that can use a cost function for partitioning subtrees. Originally written by Rebecca Hartman-Baker.
10 
11 namespace madness {
13 
14  template <int D>
15  class MyPmap : public WorldDCPmapInterface< Key<D> > {
16  private:
17  unsigned int map_type; // 0 = simple map, 1 = gaussian distributed map, 2 = treecoords list
18  const int nproc;
19  const int n;
20  std::shared_ptr< ProcMapImpl<D> > tree_map; // for map_type 2
21  Tensor<ProcessID> simple_key_map; // map of keys at level n, for map_type 1
22  typedef Key<D> KeyD;
23 
25  void build_tree_map(std::vector< TreeCoords<D> > v) {
26  tree_map = std::shared_ptr< ProcMapImpl<D> > (new ProcMapImpl<D>(v));
27  }
28 
29  ProcessID simple_hash(const KeyD& key) const {
30  if (key.level() == 0) return 0;
31  KeyD parent = (key.level() > n) ? key.parent(key.level()-n) : key;
32  return (parent.hash()%nproc);
33  }
34  ProcessID not_so_simple_hash(const KeyD& key) const {
35  KeyD parent = (key.level() > n) ? key.parent(key.level()-n) : key;
36  return simple_key_map((const long *) &(parent.translation()[0]));
37  }
38 
39  void prepare_not_so_simple_map(World& world) {
40  std::vector<long> vdim(D);
41  for (int i=0; i<D; ++i) vdim[i] = 1L<<n;
42  simple_key_map = Tensor<ProcessID>(vdim);
43 
44  std::list< std::pair<KeyD,double> > costmap;
46  long cent = (1L<<n) / 2;
47  for (TensorIterator<ProcessID> iter=simple_key_map.unary_iterator(0,false,false); iter._p0; ++iter) {
48  double dist = 0.01;
49  for (int i=0; i<D; ++i) {
50  l[i] = iter.ind[i];
51  dist += (l[i] - cent)*(l[i] - cent);
52  }
53  double cost = 1.0/dist; // actually dist squared
54  cost *= (1.0 + 0.001*RandomValue<double>()); // To shuffle (nearly) equal values
55  costmap.push_back(std::pair<KeyD,double>(KeyD(n,l),cost));
56  }
57  costmap.sort(costmapcmp);
58 // if (world.rank() == 0) {
59 // for (typename std::list< std::pair<KeyD,double> >::iterator it=costmap.begin(); it!=costmap.end(); ++it) {
60 // madness::print("costmap", it->first, it->second);
61 // }
62 // }
63  ProcessID p = 0;
64  for (typename std::list< std::pair<KeyD,double> >::iterator it=costmap.begin(); it!=costmap.end(); ++it) {
65  const long *l = (const long *) &(it->first.translation()[0]);
66  simple_key_map(l) = p;
67  ++p;
68  if (p == world.size()) p = 0;
69  }
70 // if (world.rank() == 0) {
71 // madness::print("SIMPLE MAP", D,"\n", simple_key_map);
72 // }
73  }
74 
75  public:
76  MyPmap() : map_type(2) {};
77 
78  static bool costmapcmp(const std::pair<KeyD,double>& a, const std::pair<KeyD,double>& b) {
79  return a.second > b.second;
80  }
81  MyPmap(World& world)
82  : map_type(1)
83  , nproc(world.nproc())
84  , n(int((std::log((double)world.size())/std::log(2.0)+3)/D) + 2) { // 16*nproc = 2^(nD)
85  // We set n to have about 16 tasks per processor and we try to
86  // give each process a mix of large, medium, and small
87  // tasks. Currently estimate cost as inversely
88  // proportional to distance from center but we could
89  // enable the user to provide a function.
90 
91  //if (world.rank() == 0) madness::print("DIM",D,"N IN MAP IS",n);
92  prepare_not_so_simple_map(world);
93  }
94 
95  MyPmap(World& world, unsigned int map_type, int n=100)
96  : map_type(map_type)
97  , nproc(world.nproc())
98  , n(n) {
99  if (map_type==1) {
100  n =int((std::log((double)world.size())/std::log(2.0)+3)/D) + 2; // 16*nproc = 2^(nD)
101  prepare_not_so_simple_map(world);
102  }
103  }
104 
105  MyPmap(World& world, std::vector<TreeCoords<D> > v) : map_type(2), nproc(world.nproc()), n(0) {
106  build_tree_map(v);
107  }
108 
109  MyPmap(const MyPmap<D>& other) : map_type(other.map_type), nproc(other.nproc), n(other.n), tree_map(other.tree_map) {};
110 
111  MyPmap<D>& operator=(const MyPmap<D>& other) {
112  if (this != &other) {
113  map_type = other.map_type;
114  simple_key_map = other.simple_key_map; // shallow copy
115  nproc = other.nproc;
116  n = other.n;
117  tree_map = other.tree_map;
118  }
119  return *this;
120  }
121 
122  void print() const {
123  if (map_type == 2) {
124  tree_map->print();
125  } else if (map_type == 1) {
126  madness::print("MyPmap: gaussian distributed map with n =", n);
127  } else {
128  madness::print("MyPmap: simple map with n =", n);
129  }
130  }
131 
133  ProcessID owner(const KeyD& key) const {
134  if (map_type == 0) {
135  return simple_hash(key);
136  } else if (map_type == 1) {
137  return not_so_simple_hash(key);
138  } else {
139  return tree_map->find_owner(key);
140  }
141  }
142  };
143 }
Definition: shared_ptr_bits.h:38
ProcessID owner(const KeyD &key) const
Find the owner of a given key.
Definition: mypmap.h:133
const mpreal log(const mpreal &v, mp_rnd_t rnd_mode)
Definition: mpreal.h:2213
const Vector< Translation, NDIM > & translation() const
Definition: key.h:225
A simple, fixed dimension Coordinate.
Definition: array.h:99
const double L
Definition: 3dharmonic.cc:123
MyPmap< D > & operator=(const MyPmap< D > &other)
Definition: mypmap.h:111
Definition: mpreal.h:3066
ProcessID size() const
Returns the number of processes in this world (same as MPI_Comm_size())
Definition: worldfwd.h:533
void print() const
Definition: mypmap.h:122
MyPmap(World &world, std::vector< TreeCoords< D > > v)
Definition: mypmap.h:105
MyPmap(World &world)
Definition: mypmap.h:81
Key parent(int generation=1) const
Returns the key of the parent.
Definition: key.h:248
Procmap implemented using Tree of TreeCoords.
Definition: mypmap.h:15
MyPmap(World &world, unsigned int map_type, int n=100)
Definition: mypmap.h:95
FLOAT a(int j, FLOAT z)
Definition: y1.cc:86
Level level() const
Definition: key.h:220
MyPmap()
Definition: mypmap.h:76
double RandomValue< double >()
Random double.
Definition: ran.cc:234
A parallel world with full functionality wrapping an MPI communicator.
Definition: worldfwd.h:416
int ProcessID
Used to clearly identify process number/rank.
Definition: worldtypes.h:37
MyPmap(const MyPmap< D > &other)
Definition: mypmap.h:109
hashT hash() const
Definition: key.h:209
Interface to be provided by any process map.
Definition: worlddc.h:64
Definition: tensoriter.h:61
void print(const A &a)
Print a single item to std::cout terminating with new line.
Definition: print.h:122
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
Key is the index for a node of the 2^NDIM-tree.
Definition: key.h:69
static bool costmapcmp(const std::pair< KeyD, double > &a, const std::pair< KeyD, double > &b)
Definition: mypmap.h:78