summaryrefslogtreecommitdiffstats
path: root/dis/original/Matrix/ver2/matrix.c
diff options
context:
space:
mode:
authorJoshua Bakita <bakitajoshua@gmail.com>2019-10-19 10:50:11 -0400
committerJoshua Bakita <bakitajoshua@gmail.com>2019-10-19 10:50:11 -0400
commit7e6ceb16b53fdbdb2a27cf3ade15d32177ff811f (patch)
treed6cf9044570b8b9707e89260d7267bcd69e163e7 /dis/original/Matrix/ver2/matrix.c
parent386b7d3366f1359a265da207a9cafa3edf553b64 (diff)
Add DIS benchmarks
Diffstat (limited to 'dis/original/Matrix/ver2/matrix.c')
-rwxr-xr-xdis/original/Matrix/ver2/matrix.c586
1 files changed, 586 insertions, 0 deletions
diff --git a/dis/original/Matrix/ver2/matrix.c b/dis/original/Matrix/ver2/matrix.c
new file mode 100755
index 0000000..56245a6
--- /dev/null
+++ b/dis/original/Matrix/ver2/matrix.c
@@ -0,0 +1,586 @@
1/* Please note:
2 * This code is the optimized version of the first version of Matrix
3 * Stressmark. It uses less temporary vectors and vsariables, thus reduce
4 * memory allocation/deallocation overhead. the simulation is faster
5 */
6/*
7 * Sample code for the DIS Matrix Stressmark
8 *
9 * This source code is the completely correct source code based on
10 * the example codes provided by Atlantic Aerospace Division, Titan
11 * Systems Corporation, 2000.
12 *
13 * If you just compile and generate the executables from this source
14 * code, this code would be enough. However, if you wish to get a complete
15 * understanding of this stressmark, it is strongly suggested that you
16 * read the Benchmark Analysis and Specifications Document Version 1.0
17 * before going on since the detailed comments are given in this documents.
18 * the comments are not repeated here.
19 */
20
21/*
22 * The Sparse Matrix Storage is implemented by Compact Row Storage Scheme
23 * In the code, the data is first generated by randomNonzeroFloat()
24 * the data is first stored in a full-space matrix with size of dim*dim
25 * then the data is transfered to the Compact Row Matrix,
26 * the data value is kept in *value,
27 * the columns corresponding to the value are stored in *col_ind,
28 * the start element of each row is stored in *row_start.
29 */
30
31/*
32 * Please note:
33 * the total number of data is numberNonzero +dim
34 * among which, NumberNonzero because this is symmetric matrix
35 * dim because the diagonal elements
36 */
37
38#include <stdio.h>
39#include <math.h>
40#include <stdlib.h>
41#include <time.h>
42#include <assert.h>
43#include "DISstressmarkRNG.h"
44
45#define MIN_SEED -2147483647
46#define MAX_SEED -1
47#define MIN_DIM 1
48#define MAX_DIM 32768
49#define MAX_ITERATIONS 65536
50#define MIN_TOLERANCE 0.000007
51#define MAX_TOLERANCE 0.5
52#define MIN_NUMBER -3.4e10/dim
53#define MAX_NUMBER 3.4e10/dim
54#define EPSI 1.0e-10
55#define MIN_DIG_NUMBER 1.0e-10
56#define MAX_DIG_NUMBER 3.4e10
57
58/*
59 * External variable, dimension
60 */
61
62static int dim;
63
64/*
65 * matrix * vector
66 */
67
68void matrixMulvector(double *value,
69 int *col_ind,
70 int *row_start,
71 double *vector,
72 double *out)
73{
74 int l, ll;
75 double sum;
76 int tmp_rs, tmp_re;
77
78 for (l=0; l<dim; l++){
79 *(out + l) = 0;
80 tmp_rs = row_start[l];
81
82 if (tmp_rs != -1){
83 tmp_re = row_start[l+1]; /*
84 *get the start and ending elements of
85 * each row
86 */
87 for (ll=tmp_rs; ll<tmp_re; ll++){
88 *(out + l) += value[ll]*vector[col_ind[ll]];
89 }
90 }
91 }
92 return;
93}
94
95
96/*
97 * vector1 - vector2
98 */
99
100void vectorSub(double *vector1, double *vector2, double *vector){
101
102 int l;
103
104 for (l=0; l<dim; l++){
105 *(vector + l) = *(vector1 + l) - *(vector2 + l);
106 }
107 return;
108}
109
110
111/*
112 * vector1 + vector2
113 */
114
115void vectorAdd(double *vector1, double *vector2, double *vector){
116
117 int l;
118
119 for (l=0; l<dim; l++){
120 *(vector + l) = *(vector1 + l) + *(vector2 + l);
121 }
122 return;
123}
124
125/*
126 * vector1 * vector2
127 */
128
129double vectorMul(double *vector1, double *vector2){
130
131 int l;
132 double product;
133
134 product = 0;
135
136 for (l=0; l<dim; l++){
137 product += (*(vector1 + l))*(*(vector2 + l));
138
139 }
140 return product;
141}
142
143/*
144 * /vector/
145 */
146
147double vectorValue(double *vector){
148
149 double value;
150 int l;
151
152 value = 0;
153
154 for (l=0; l<dim; l++){
155 value += (*(vector + l)) * (*(vector + l));
156 }
157
158 return (sqrt(value));
159}
160
161/*
162 * transpose(vector)
163 * In fact, we return the original vector here
164 */
165
166void transpose(double *vector, double *vect){
167
168 int l;
169
170 for (l=0; l<dim; l++){
171 *(vect+l) = *(vector+l);
172 }
173 return;
174}
175
176/*
177 * value * <vector>
178 */
179void valueMulvector(double value, double *vector, double *vect){
180
181 int l;
182 int lll, i;
183 double tmp;
184
185 for (l=0; l<dim; l++){
186 *(vect + l) = *(vector + l) * value;
187 }
188 return;
189}
190
191/*
192 * generate the data distributed sparsely in matrix
193 */
194
195void initMatrix(double *matrix, int dim, int numberNonzero){
196
197 int k, l, ll;
198 int i, j;
199
200 int lll;
201 double sum;
202
203 for (k=0; k< dim*dim; k++){
204 *(matrix + k) = 0;
205 }
206
207 for (l=0; l<numberNonzero/2; l++){
208
209 i = randomUInt(1, dim-1);
210 j = randomUInt(0, i-1);
211
212 while (*(matrix + i*dim + j) != 0){
213
214 i++;
215 if (i == dim){
216 j++;
217 if (j == dim-1){
218 j = 0;
219 i = 1;
220 }
221 else{
222 i = j+1;
223 }
224 }
225 }
226
227 if (*(matrix + i*dim + j) == 0){
228 *(matrix + i*dim + j) = (double )randomNonZeroFloat(MIN_NUMBER,
229 MAX_NUMBER,
230 EPSI);
231 *(matrix + j*dim + i) = *(matrix + i*dim + j);
232 }
233 }
234
235 for (ll=0; ll<dim; ll++){
236
237
238
239 *(matrix + ll*dim + ll) = (double )randomNonZeroFloat(-MAX_DIG_NUMBER,
240 MAX_DIG_NUMBER,
241 MIN_DIG_NUMBER);
242
243 sum = 0;
244
245 for (lll=0; lll<dim; lll++){
246 if (lll != ll){
247 sum += *(matrix + lll*dim + ll);
248 }
249 }
250
251 if (*(matrix + ll*dim + ll) < sum ){
252 *(matrix + ll*dim + ll) += sum;
253 }
254 }
255
256 return;
257}
258
259/*
260 * generate the data value in the vectors
261 */
262
263void initVector(double *vector, int dim){
264
265 int l;
266
267 for (l=0; l<dim; l++){
268 *(vector + l) = (double )randomFloat (MIN_NUMBER, MAX_NUMBER);
269 }
270
271 return;
272}
273
274/*
275 * make a vector contains value of zero
276 */
277
278void zeroVector(double *vector, int dim){
279 int l;
280
281 for (l=0; l<dim; l++){
282 *(vector + l) = 0;
283 }
284 return;
285}
286
287/*
288 * return a vector which is the copy of the vect
289 */
290
291void equalVector(double *vect, double *vect1){
292
293 int l;
294
295 for (l=0; l<dim; l++){
296 *(vect1+l) = *(vect+l);
297 }
298 return;
299}
300
301
302
303void biConjugateGradient(double *value,
304 int *col_ind,
305 int *row_start,
306 double *vectorB,
307 double *vectorX,
308 double errorTolerance,
309 int maxIterations,
310 double *actualError,
311 int *actualIteration,
312 int dim)
313 /*
314 * in the code, we use a lot of temparary vectors and variables
315 * this is just for simple and clear
316 * you can optimize these temporary variables and vectors
317 * based on your need
318 *
319 */
320{
321 double *vectorR;
322 double *vectorP, *matrixAvectorP, *nextVectorR;
323 double error;
324 int iteration;
325 double alpha, beta;
326
327 double *tmpVector1, *tmpVector2, *tmpVector3;
328 double tmpValue1, tmpValue2;
329 int i;
330 int l;
331 int ll;
332
333 alpha = 0;
334 beta = 0;
335
336 vectorP = (double *)malloc(dim*sizeof(double));
337 vectorR = (double *)malloc(dim*sizeof(double));
338 nextVectorR = (double *)malloc(dim*sizeof(double));
339 vectorX = (double *)malloc(dim*sizeof(double));
340
341 tmpVector1 = (double *)malloc(dim*sizeof(double));
342 tmpVector2 = (double *)malloc(dim*sizeof(double));
343 tmpVector3 = (double *)malloc(dim*sizeof(double));
344
345 /*
346 * vectorR = vectorB - matrixA*vectorX
347 */
348 matrixMulvector(value,col_ind, row_start, vectorX, tmpVector1);
349
350 vectorSub(vectorB, tmpVector1, vectorR);
351
352 /*
353 * vectorP = vectorR
354 */
355
356 equalVector(vectorR, vectorP);
357
358 /*
359 * error = |matrixA * vectorX - vectorB| / |vectorB|
360 */
361 vectorSub(tmpVector1, vectorB, tmpVector1);
362
363 error = vectorValue(tmpVector1)/vectorValue(vectorB);
364
365 iteration = 0;
366
367 while ((iteration < maxIterations) && (error > errorTolerance)){
368
369 /*
370 * alpha = (transpose(vectorR) * vectorR) /
371 * (transpose(vectorP) * (matrixA * vectorP)
372 */
373
374 matrixMulvector(value, col_ind, row_start, vectorP, tmpVector1);
375 transpose(vectorR, tmpVector2);
376 transpose(vectorP, tmpVector3);
377 tmpValue1 = vectorMul(tmpVector3, tmpVector1);
378 tmpValue2 = vectorMul(tmpVector2, vectorR);
379 alpha = tmpValue2/tmpValue1;
380
381 /*
382 * nextVectorR = vectorR - alpha*(matrixA * vectorP)
383 */
384
385 valueMulvector(alpha, tmpVector1, tmpVector2);
386 vectorSub(vectorR, tmpVector2, tmpVector1);
387 equalVector(tmpVector1, nextVectorR);
388
389 /*
390 * beta = (transpose(nextVectorR) * nextVectorR) /
391 * (transpose(vectorR) * vectorR)
392 */
393
394 transpose(nextVectorR, tmpVector3);
395 tmpValue1 = vectorMul(tmpVector3, nextVectorR);
396 transpose(vectorR, tmpVector2);
397 tmpValue2 = vectorMul(tmpVector2, vectorR);
398 beta = tmpValue1/tmpValue2;
399
400 /*
401 * vectorX = vectorX + alpha * vectorP
402 */
403 valueMulvector(alpha, vectorP, tmpVector1);
404 vectorAdd(vectorX,tmpVector1, vectorX);
405
406 /*
407 *vectorP = nextVectorR + beta*vectorP
408 */
409 valueMulvector(beta, vectorP, tmpVector1);
410 vectorAdd(nextVectorR, tmpVector1, tmpVector1);
411
412 for (ll=0; ll<dim; ll++){
413 *(vectorP + ll) = *(tmpVector1 + ll);
414 }
415
416 /*
417 * vectorR = nextVectorR
418 */
419
420 for (l=0; l<dim; l++){
421 *(vectorR+l) = *(nextVectorR+l);
422 }
423
424 /*
425 * error = |matrixA * vectorX - vectorB| / |vectorB|
426 */
427 matrixMulvector(value, col_ind,row_start, vectorX, tmpVector1);
428 vectorSub(tmpVector1,vectorB,tmpVector1);
429 error = vectorValue(tmpVector1)/vectorValue(vectorB);
430
431 iteration++;
432 }
433
434 *actualError = error;
435 *actualIteration = iteration;
436
437 free(tmpVector1);
438 free(tmpVector2);
439 free(tmpVector3);
440
441 free(vectorR);
442 free(vectorP);
443
444 return;
445}
446
447/*
448 * This is the function to transfer the data from the matrix of dense storage
449 * to Compact Row Storage
450 */
451void create_CRS(double *matrixA,
452 double *value,
453 int *col_ind,
454 int *row_start,
455 int dim,
456 int numberNonzero)
457{
458
459 int i, j, k;
460 int cnt;
461 double tmp;
462
463 /*
464 *initialize the row_start
465 */
466
467 for(k=0; k<dim; k++){
468 row_start[k] = -1;
469 }
470
471 /*
472 * make the end of the last row to be numberNonzero + dim.
473 */
474
475 row_start[dim] = numberNonzero+dim;
476
477 /*
478 * initialize the col_ind
479 */
480
481 for (k=0; k<numberNonzero+dim; k++){
482 col_ind[k] = -1;
483 }
484
485
486 cnt = 0;
487
488 for (i=0; (cnt<numberNonzero+dim)&&(i<dim); i++){
489 for (j=0; (cnt<numberNonzero+dim)&&(j<dim); j++){
490
491 tmp = *(matrixA + i*dim + j);
492
493 if (tmp!=0){
494
495 value[cnt] = tmp;
496 col_ind[cnt] = j;
497
498 if (row_start[i] == -1)
499 row_start[i] = cnt;
500
501 cnt += 1;
502 }
503 }
504 }
505 row_start[i] = cnt;
506
507 return;
508}
509
510
511
512int main()
513{
514 int seed;
515 int numberNonzero;
516 int maxIterations;
517 float errorTolerance;
518 double actualError;
519 int actualIteration;
520
521 time_t beginTime;
522 time_t endTime;
523
524 double *matrixA;
525 double *vectorB;
526 double *vectorX;
527
528 double *value;
529 int *col_ind;
530 int *row_start;
531 int sum;
532 int k;
533
534 fscanf(stdin, "%d %d %d %d %f",
535 &seed, &dim, &numberNonzero,&maxIterations,&errorTolerance);
536 assert((seed > MIN_SEED) && (seed < MAX_SEED));
537 assert((dim > MIN_DIM) && (dim < MAX_DIM));
538 assert((numberNonzero > dim) && (numberNonzero < dim*dim));
539 assert((maxIterations > 0) && (maxIterations < MAX_ITERATIONS));
540 assert((errorTolerance > MIN_TOLERANCE) && (errorTolerance < MAX_TOLERANCE));
541
542 matrixA = (double *)malloc(dim*dim*sizeof(double ));
543 vectorB = (double *)malloc(dim*sizeof(double));
544 vectorX = (double *)malloc(dim*sizeof(double));
545
546 value = (double *)malloc((numberNonzero+dim)*sizeof(double));
547 col_ind = (int *)malloc((numberNonzero+dim)*sizeof(int));
548 row_start = (int *)malloc((dim+1)*sizeof(int));
549
550 randInit(seed);
551
552 initMatrix(matrixA, dim, numberNonzero);
553
554 create_CRS(matrixA, value, col_ind, row_start, dim, numberNonzero);
555
556 initVector(vectorB, dim);
557 zeroVector(vectorX, dim);
558 printf(" after init\n");
559
560 beginTime = time(NULL);
561
562 actualError = 0;
563 actualIteration = 0;
564
565 biConjugateGradient(value, col_ind, row_start, vectorB, vectorX, errorTolerance,
566 maxIterations,
567 &actualError, &actualIteration, dim);
568
569
570
571 endTime = time(NULL) - beginTime;
572
573
574
575 sum = 0;
576 for (k=1; k<dim; k++){
577 sum += sum + *(vectorX + k);
578 }
579
580 fprintf(stdout, "sum = %d, actualError = %e, actualIteration = %d\n", sum, actualError, actualIteration);
581 fprintf(stdout, "total time = %u sec. \n", (unsigned int)endTime);
582
583 return(0);
584 }
585
586