forked from LLNL/mitos
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathapi_openmp_matmul.cpp
138 lines (110 loc) · 3.91 KB
/
api_openmp_matmul.cpp
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <iostream>
#include <fstream>
#include <vector>
#include <cstdlib>
#include <unistd.h>
#include "../src/Mitos.h"
#include "src/virtual_address_writer.h"
thread_local static mitos_output mout;
thread_local static char* virt_address;
static long ts_output_prefix_omp;
#include <omp.h>
void sample_handler(perf_event_sample *sample, void *args)
{
//fprintf(stderr, "SAMP: cpu=%d, tid=%d\n", sample->cpu, sample->tid);
Mitos_write_sample(sample, &mout);
}
#define ROW_MAJOR(x,y,width) y*width+x
void init_matrices(int N, double **a, double **b, double **c)
{
int i,j,k;
*a = new double[N*N];
*b = new double[N*N];
*c = new double[N*N];
size_t dims[2];
dims[0] = N; //static_cast<size_t>(N);
dims[1] = N; //static_cast<size_t>(N);
Mitos_add_symbol("a",*a,sizeof(double),dims,2);
Mitos_add_symbol("b",*b,sizeof(double),dims,2);
Mitos_add_symbol("c",*c,sizeof(double),dims,2);
for(i=0; i<N; ++i)
{
for(j=0; j<N; ++j)
{
(*a)[ROW_MAJOR(i,j,N)] = (double)rand();
(*b)[ROW_MAJOR(i,j,N)] = (double)rand();
(*c)[ROW_MAJOR(i,j,N)] = 0;
}
}
}
void matmul(int N, double *a, double *b, double *c)
{
ts_output_prefix_omp = time(NULL);
#pragma omp parallel
{
// Sampling MUST be done inside the parallel region.
printf("Hello from thread %i of %i!\n", omp_get_thread_num(),
omp_get_num_threads());
/* Setting up mitos for every thread*/
pid_t tid = gettid();
// This function takes saved timestamp and tid to save a unique directory name for every thread.
Mitos_create_output(&mout, ts_output_prefix_omp, tid);
// The virtual offset is saved in this file
std::string virt_address = "/tmp/" + std::to_string(ts_output_prefix_omp) + "_virt_address.txt";
Mitos_save_virtual_address_offset(virt_address);
Mitos_pre_process(&mout);
Mitos_set_pid(tid);
Mitos_set_handler_fn(&sample_handler,NULL);
Mitos_set_sample_latency_threshold(10);
Mitos_set_sample_event_period(4000);
std::cout << "[Mitos] Beginning sampler: " << omp_get_thread_num() <<"\n";
Mitos_begin_sampler();
/* Main computation*/
#pragma omp for
for(int i=0; i<N; ++i)
{
for(int j=0; j<N; ++j)
{
for(int k=0; k<N; ++k)
{
c[ROW_MAJOR(i,j,N)] += a[ROW_MAJOR(i,k,N)]*b[ROW_MAJOR(k,j,N)];
}
}
}
/*End the thread-specific sampler and flush the raw samples*/
Mitos_end_sampler();
Mitos_add_offsets(virt_address.c_str(), &mout);
}
int randx = N*((float)rand() / (float)RAND_MAX+1);
int randy = N*((float)rand() / (float)RAND_MAX+1);
std::cout << c[ROW_MAJOR(randx,randy,N)] << std::endl;
std::cout << "[Mitos] End sampler\n";
}
int main(int argc, char **argv)
{
int N = (argc == 2) ? atoi(argv[1]) : 1024;
double *a,*b,*c;
init_matrices(N,&a,&b,&c);
// Sampling done inside this function
matmul(N,a,b,c);
/* Post-processing of raw samples (to be done by the primary thread)*/
/* Merge and copy the thread-local raw samples into results directory*/
// Merges all the raw samples into a single raw_samples.csv file
std::string result_dir;
Mitos_merge_files(ts_output_prefix_omp, result_dir);
// Store result information
mitos_output result_mout;
Mitos_set_result_mout(&result_mout, result_dir);
// Read the binary for symbols
if(Mitos_process_binary(argv[0], &result_mout))
{
std::cerr << "Error opening binary file!" << std::endl;
return 1;
}
// Finalize post-processing
if(Mitos_post_process(argv[0], &result_mout, result_dir)){
std::cerr << "Error post processing!" << std::endl;
return 1;
}
return 0;
}