forked from wence-/ccs-l3-coursework-2018
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsparsemm.c
197 lines (174 loc) · 4.79 KB
/
sparsemm.c
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "utils.h"
#ifdef LIKWID_PERFMON
#include <likwid.h>
#else
#define LIKWID_MARKER_INIT
#define LIKWID_MARKER_THREADINIT
#define LIKWID_MARKER_SWITCH
#define LIKWID_MARKER_REGISTER(regionTag)
#define LIKWID_MARKER_START(regionTag)
#define LIKWID_MARKER_STOP(regionTag)
#define LIKWID_MARKER_CLOSE
#define LIKWID_MARKER_GET(regionTag, nevents, events, time, count)
#endif
void basic_sparsemm(const COO, const COO, COO*);
void basic_sparsemm_sum(const COO, const COO, const COO,
const COO, const COO, const COO,
COO *);
void optimised_sparsemm(const COO, const COO, COO*);
void optimised_sparsemm_sum(const COO, const COO, const COO,
const COO, const COO, const COO,
COO *);
int col_sort(const void *a, const void *b);
int row_sort(const void *a, const void *b);
void sort_coo(const COO A, COO* S, int compare(const void *, const void *));
static int check_sparsemm()
{
//create 4 COO pointers
COO A, B, Cbasic, Copt;
double *basic, *opt;
int i, j, m, n, k;
int pass = 0;
m = 20;
k = 30;
n = 15;
// printf("A:\n");
random_matrix(m, k, 0.1, &A); //creates random m x k matrix
// printf("B:\n");
random_matrix(k, n, 0.2, &B); //creates random k x n matrix
basic_sparsemm(A, B, &Cbasic); //basic matrix matrix multiplication
optimised_sparsemm(A, B, &Copt);
convert_sparse_to_dense(Cbasic, &basic);
convert_sparse_to_dense(Copt, &opt);
for (j = 0; j < n; j++) {
for (i = 0; i < m; i++) {
double diff = fabs(opt[j*m + i] - basic[j*m + i]);
if (diff != diff || diff > 1e-3) {
fprintf(stderr, "MM Failed check at entry (%d, %d), basic value %g, opt value %g\n", i, j, basic[j*m + i], opt[j*m + i]);
//printf("m: %d, k: %d, n: %d\n", m, n, k);
pass = 1;
}
}
}
free(basic);
free(opt);
free_sparse(&A);
free_sparse(&B);
free_sparse(&Cbasic);
free_sparse(&Copt);
return pass;
}
static int check_sparsemm_sum()
{
COO A, B, C, D, E, F, Obasic, Oopt;
double *basic, *opt;
int i, j, m, n, k;
int pass = 0;
m = 78;
k = 81;
n = 45;
//printf("A\n");
random_matrix(m, k, 0.1, &A);
//printf("\nB\n");
random_matrix(m, k, 0.4, &B);
//printf("\nC\n");
random_matrix(m, k, 0.01, &C);
//printf("\nD\n");
random_matrix(k, n, 0.2, &D);
//printf("\nE\n");
random_matrix(k, n, 0.3, &E);
//printf("\nF\n");
random_matrix(k, n, 0.15, &F);
basic_sparsemm_sum(A, B, C, D, E, F, &Obasic);
optimised_sparsemm_sum(A, B, C, D, E, F, &Oopt);
convert_sparse_to_dense(Obasic, &basic);
convert_sparse_to_dense(Oopt, &opt);
for (j = 0; j < n; j++) {
for (i = 0; i < m; i++) {
double diff = fabs(opt[j*m + i] - basic[j*m + i]);
if (diff != diff || diff > 1e-3) {
fprintf(stderr, "MM-SUM Failed check at entry (%d, %d), basic value %g, opt value %g\n", i, j, basic[j*m + i], opt[j*m + i]);
pass = 1;
}
}
}
free(basic);
free(opt);
free_sparse(&A);
free_sparse(&B);
free_sparse(&C);
free_sparse(&D);
free_sparse(&E);
free_sparse(&F);
free_sparse(&Obasic);
free_sparse(&Oopt);
return pass;
}
int main(int argc, char **argv)
{
LIKWID_MARKER_INIT;
LIKWID_MARKER_THREADINIT;
COO O;
FILE *f;
if (!(argc == 2 || argc == 4 || argc == 8)) {
fprintf(stderr, "Invalid arguments.\n");
fprintf(stderr, "Usage: %s CHECK\n", argv[0]);
fprintf(stderr, " Check the implemented routines using randomly generated matrices.\n");
fprintf(stderr, "Alternate usage: %s O A B\n", argv[0]);
fprintf(stderr, " Computes O = A B\n");
fprintf(stderr, " Where A and B are filenames of matrices to read.\n");
fprintf(stderr, " O is the filename of the matrix to be written.\n\n");
fprintf(stderr, "Alternate usage: %s O A B C D E F\n", argv[0]);
fprintf(stderr, " Computes O = (A + B + C) (D + E + F)\n");
fprintf(stderr, " Where A-F are the files names of matrices to read.\n");
fprintf(stderr, " O is the filename of the matrix to be written.\n\n");
return 1;
}
if (argc == 2) {
int pass = 0;
if (strcmp(argv[1], "CHECK")) {
fprintf(stderr, "Invalid mode, expecting CHECK, got %s\n", argv[1]);
return 1;
}
pass |= check_sparsemm();
pass |= check_sparsemm_sum();
if(pass == 0){
printf("Passed");
}else{
printf("Failed");
}
return pass;
} else if (argc == 4) {
COO A, B;
read_sparse(argv[2], &A);
read_sparse(argv[3], &B);
optimised_sparsemm(A, B, &O);
free_sparse(&A);
free_sparse(&B);
} else {
COO A, B, C, D, E, F;
read_sparse(argv[2], &A);
read_sparse(argv[3], &B);
read_sparse(argv[4], &C);
read_sparse(argv[5], &D);
read_sparse(argv[6], &E);
read_sparse(argv[7], &F);
optimised_sparsemm_sum(A, B, C, D, E, F, &O);
free_sparse(&A);
free_sparse(&B);
free_sparse(&C);
free_sparse(&D);
free_sparse(&E);
free_sparse(&F);
}
LIKWID_MARKER_CLOSE;
f = fopen(argv[1], "w");
write_sparse(f, O);
free_sparse(&O);
fclose(f);
return 0;
}