MADNESS  0.10.1
mypmap.h
Go to the documentation of this file.
1 // #include <madness/world/MADworld.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 {
12  /// Procmap implemented using Tree of TreeCoords
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 
24  /// private method that builds the Tree underlying the procmap
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 
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 
132  /// Find the owner of a given key
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 }
Key is the index for a node of the 2^NDIM-tree.
Definition: key.h:66
Level level() const
Definition: key.h:159
const Vector< Translation, NDIM > & translation() const
Definition: key.h:164
hashT hash() const
Definition: key.h:148
Key parent(int generation=1) const
Returns the key of the parent.
Definition: key.h:187
Procmap implemented using Tree of TreeCoords.
Definition: mypmap.h:15
MyPmap< D > & operator=(const MyPmap< D > &other)
Definition: mypmap.h:111
void build_tree_map(std::vector< TreeCoords< D > > v)
private method that builds the Tree underlying the procmap
Definition: mypmap.h:25
MyPmap(World &world, std::vector< TreeCoords< D > > v)
Definition: mypmap.h:105
Tensor< ProcessID > simple_key_map
Definition: mypmap.h:21
unsigned int map_type
Definition: mypmap.h:17
Key< D > KeyD
Definition: mypmap.h:22
ProcessID not_so_simple_hash(const KeyD &key) const
Definition: mypmap.h:34
ProcessID simple_hash(const KeyD &key) const
Definition: mypmap.h:29
const int nproc
Definition: mypmap.h:18
void prepare_not_so_simple_map(World &world)
Definition: mypmap.h:39
std::shared_ptr< ProcMapImpl< D > > tree_map
Definition: mypmap.h:20
MyPmap(const MyPmap< D > &other)
Definition: mypmap.h:109
ProcessID owner(const KeyD &key) const
Find the owner of a given key.
Definition: mypmap.h:133
MyPmap()
Definition: mypmap.h:76
MyPmap(World &world)
Definition: mypmap.h:81
const int n
Definition: mypmap.h:19
MyPmap(World &world, unsigned int map_type, int n=100)
Definition: mypmap.h:95
void print() const
Definition: mypmap.h:122
static bool costmapcmp(const std::pair< KeyD, double > &a, const std::pair< KeyD, double > &b)
Definition: mypmap.h:78
Definition: tensoriter.h:61
TensorIterator< T > unary_iterator(long iterlevel=0, bool optimize=true, bool fusedim=true, long jdim=default_jdim) const
Return iterator over single tensor.
Definition: tensor.h:1844
A simple, fixed dimension vector.
Definition: vector.h:64
Interface to be provided by any process map.
Definition: worlddc.h:82
A parallel world class.
Definition: world.h:132
ProcessID size() const
Returns the number of processes in this World (same as MPI_Comm_size()).
Definition: world.h:328
char * p(char *buf, const char *name, int k, int initial_level, double thresh, int order)
Definition: derivatives.cc:72
static const double v
Definition: hatom_sf_dirac.cc:20
File holds all helper structures necessary for the CC_Operator and CC2 class.
Definition: DFParameters.h:10
double RandomValue< double >()
Random double.
Definition: ran.cc:234
void print(const T &t, const Ts &... ts)
Print items to std::cout (items separated by spaces) and terminate with a new line.
Definition: print.h:225
Definition: mraimpl.h:50
static const double b
Definition: nonlinschro.cc:119
static const double a
Definition: nonlinschro.cc:118
Definition: test_ar.cc:204
double dist(const Vector< double, 3 > v1, const Vector< double, 3 > v2)
distance between v1 and v2
Definition: test_localizer.cc:38
int ProcessID
Used to clearly identify process number/rank.
Definition: worldtypes.h:43