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
9This 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
11namespace 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
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:68
Level level() const
Definition key.h:161
hashT hash() const
Definition key.h:150
Key parent(int generation=1) const
Returns the key of the parent.
Definition key.h:245
const Vector< Translation, NDIM > & translation() const
Definition key.h:166
Procmap implemented using Tree of TreeCoords.
Definition mypmap.h:15
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< D > & operator=(const MyPmap< D > &other)
Definition mypmap.h:111
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
A tensor is a multidimensional array.
Definition tensor.h:317
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:330
char * p(char *buf, const char *name, int k, int initial_level, double thresh, int order)
Definition derivatives.cc:72
static double function(const coord_3d &r)
Normalized gaussian.
Definition functionio.cc:100
static const double v
Definition hatom_sf_dirac.cc:20
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
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