forked from taskflow/taskflow
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathomp.cpp
More file actions
111 lines (94 loc) · 3.1 KB
/
omp.cpp
File metadata and controls
111 lines (94 loc) · 3.1 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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include "dnn.hpp"
#include <omp.h>
void omp_dnn(MNIST_DNN& D, const unsigned num_iteration) {
const int num_layers = D.num_layers();
auto dep_f = new int [num_iteration];
auto dep_b = new int [num_iteration*num_layers];
auto dep_u = new int [num_iteration*num_layers];
#pragma omp parallel
{
#pragma omp single
{
for(auto i=0u; i<num_iteration; i++) {
// Forward Task
if(i == 0) {
#pragma omp task depend (out: dep_f[i]) shared(D, IMAGES, LABELS)
{
forward_task(D, IMAGES, LABELS);
}
}
else {
switch(num_layers) {
case 3:
#pragma omp task depend (in: dep_u[(i-1)*num_layers], dep_u[(i-1)*num_layers+1], dep_u[(i-1)*num_layers+2]) depend (out: dep_f[i]) shared(D, IMAGES, LABELS)
{
forward_task(D, IMAGES, LABELS);
}
break;
case 5:
#pragma omp task depend (in: dep_u[(i-1)*num_layers], dep_u[(i-1)*num_layers+1], dep_u[(i-1)*num_layers+2], dep_u[(i-1)*num_layers+3], dep_u[(i-1)*num_layers+4]) depend (out: dep_f[i]) shared(D, IMAGES, LABELS)
{
forward_task(D, IMAGES, LABELS);
}
break;
default: assert(false); break;
}
} // End of Forward Task
// Backward tasks
for(int j=num_layers-1; j>=0; j--) {
if(j == num_layers-1) {
#pragma omp task depend (in: dep_f[i]) depend (out: dep_b[i*num_layers + j]) firstprivate(j) shared(D, IMAGES)
{
backward_task(D, j, IMAGES);
}
}
else {
#pragma omp task depend (in: dep_b[i*num_layers + j + 1]) depend (out: dep_b[i*num_layers + j]) firstprivate(j) shared(D, IMAGES)
{
backward_task(D, j, IMAGES);
}
}
}
// Update tasks
for(int j=num_layers-1; j>=0; j--) {
#pragma omp task depend (in: dep_b[i*num_layers + j]) depend (out: dep_u[i*num_layers + j]) firstprivate(j) shared(D)
{
D.update(j);
}
}
} // End of one iteration
}
} // End of omp parallel
delete [] dep_f;
delete [] dep_b;
delete [] dep_u;
}
void run_omp(const unsigned num_epochs, const unsigned num_threads) {
auto dnns = std::make_unique<MNIST_DNN[]>(NUM_DNNS);
for(auto i=0u; i<NUM_DNNS; i++) {
init_dnn(dnns[i], rand_rate());
}
omp_set_num_threads(num_threads);
//auto t1 = std::chrono::high_resolution_clock::now();
#pragma omp parallel
{
#pragma omp single
{
for(auto i=0u; i<num_epochs; i++) {
for(auto j=0u; j<NUM_DNNS; j++) {
#pragma omp task firstprivate(j) shared(dnns)
{
omp_dnn(dnns[j], NUM_ITERATIONS);
}
}
#pragma omp taskwait
for(auto j=0u; j<NUM_DNNS; j++) {
//std::cout << "Validate " << j << "th NN: ";
dnns[j].validate(TEST_IMAGES, TEST_LABELS);
}
shuffle(IMAGES, LABELS);
//report_runtime(t1);
}
}
}
}