forked from hxmhuang/OpenArray_Dev
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPartitionPool.hpp
More file actions
91 lines (77 loc) · 3.01 KB
/
Copy pathPartitionPool.hpp
File metadata and controls
91 lines (77 loc) · 3.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
* PartitionPool.hpp
* if two array have the same partition, they share the same partition pointer
* each partition has it's own hash value
*
=======================================================*/
#ifndef __PARTITIONPOOL_HPP__
#define __PARTITIONPOOL_HPP__
#include <vector>
#include "Partition.hpp"
#include <unordered_map>
using namespace std;
typedef unordered_map<size_t, PartitionPtr> PartitionPoolMap;
class PartitionPool {
private:
// use [comm, procs_size, (gx, gy, gz), stencil_width] as identicial key
PartitionPoolMap m_pool;
// use [comm, lx, ly, lz, stencil_width] as identical key
PartitionPoolMap m_pool_xyz;
int global_count = 0; // the total number of different partition
public:
// get a PartitionPtr from m_pool based on hash created by key:
// [comm, process_size, (gx, gy, gz), stencil_width]
PartitionPtr get(MPI_Comm comm, int size, const Shape& gs,
int stencil_width = 1, size_t par_hash = 0) {
PartitionPtr par_ptr;
// par_hash == 0: should generate hash
// par_hash != 0: means arraypool has already gen hash, just use it
if (par_hash == 0)
par_hash = Partition::gen_hash(comm, gs, stencil_width);
PartitionPoolMap::iterator it = m_pool.find(par_hash);
if (it == m_pool.end()) { // create new partition in pool
par_ptr = PartitionPtr(new Partition(comm, size, gs, stencil_width));
add_count();
if (g_debug) cout<<"PartitionPool.size() = "<<count()<<endl;
par_ptr->set_hash(par_hash);
m_pool[par_hash] = par_ptr;
} else { // get partition from pool
par_ptr = it->second;
}
return par_ptr;
}
// get a PartitionPtr from m_pool_xyz based on hash created by key:
// [comm, lx, ly, lz, stencil_width]
PartitionPtr get(MPI_Comm comm, const vector<int> &x, const vector<int> &y,
const vector<int> &z, int stencil_width = 1, size_t par_hash = 0) {
PartitionPtr par_ptr;
// par_hash == 0: should gen hash
// par_hash != 0: means arraypool has already gen hash, just use it
if (par_hash == 0) par_hash = Partition::gen_hash(comm, x, y, z, stencil_width);
PartitionPoolMap::iterator it = m_pool_xyz.find(par_hash);
if (it == m_pool_xyz.end()) { // create new partition in pool
par_ptr = PartitionPtr(new Partition(comm, x, y, z, stencil_width));
add_count();
if (g_debug) cout<<"PartitionPool.size() = "<<count()<<endl;
par_ptr->set_hash(par_hash);
m_pool_xyz[par_hash] = par_ptr;
} else { // get partition from pool
par_ptr = it->second;
}
return par_ptr;
}
// only need one Partition Pool in each process, so make it static
static PartitionPool* global() {
static PartitionPool par_pool;
return &par_pool;
}
// return the total number of different partition
int count() {
return global_count;
}
// add the number of different partition
void add_count() {
global_count += 1;
}
};
#endif