-
Notifications
You must be signed in to change notification settings - Fork 53
/
paralleldo.h
100 lines (86 loc) · 2.39 KB
/
paralleldo.h
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
92
93
94
95
96
97
98
99
100
#pragma once
#include <future>
#include "util.h"
//Represents a range of integers, enumerating
//the training data handled by a given thread
struct Bound
{
size_t n = 0;
size_t begin = 0;
size_t end = 0;
Bound() { }
Bound(size_t nn, size_t b, size_t e) : n(nn),begin(b), end(e) { }
size_t
size() const { return end-begin; }
};
//Function object for doing parallel tasks
class ParallelDo
{
vector<Bound> bounds_;
public:
ParallelDo() { }
ParallelDo(vector<Bound> const& bs)
: bounds_(bs)
{ }
ParallelDo(int Nthread, int Ntask)
: bounds_(Nthread)
{
auto th_size = Ntask/Nthread;
auto bcount = 0;
for(auto n : range(Nthread))
{
bounds_.at(n) = Bound(n,bcount,bcount+th_size);
bcount += th_size;
}
bounds_.back().end = Ntask;
}
size_t
Nthread() const { return bounds_.size(); }
vector<Bound> const&
bounds() const { return bounds_; }
template<typename Task>
void
operator()(Task&& T) const
{
const auto Nf = 16ul;
if(bounds_.size() > Nf) Error("Need to increase size of futs");
auto futs = std::array<std::future<void>,Nf>{};
auto task = std::move(T);
for(auto& b : bounds_)
{
futs.at(b.n) = std::async(std::launch::async,task,b);
}
for(auto& b : bounds_)
{
futs.at(b.n).wait();
}
}
};
void inline
setOneThread()
{
setenv("VECLIB_NUM_THREADS","1",1);
auto vnt = getenv("VECLIB_NUM_THREADS");
if(vnt != NULL)
println("pdmrg: VECLIB_NUM_THREADS = ",vnt);
else
println("pdmrg: OMP_NUM_THREADS not defined");
setenv("OMP_NUM_THREADS","1",1);
auto ont = getenv("OMP_NUM_THREADS");
if(ont != NULL)
println("pdmrg: OMP_NUM_THREADS = ",ont);
else
println("pdmrg: OMP_NUM_THREADS not defined");
setenv("MKL_NUM_THREADS","1",1);
auto mnt = getenv("MKL_NUM_THREADS");
if(mnt != NULL)
println("pdmrg: MKL_NUM_THREADS = ",mnt);
else
println("pdmrg: MKL_NUM_THREADS not defined");
setenv("GOTO_NUM_THREADS","1",1);
auto gnt = getenv("GOTO_NUM_THREADS");
if(gnt != NULL)
println("pdmrg: GOTO_NUM_THREADS = ",gnt);
else
println("pdmrg: GOTO_NUM_THREADS not defined");
}