aboutsummaryrefslogtreecommitdiffstats
path: root/bin/rt_matrix.c
diff options
context:
space:
mode:
Diffstat (limited to 'bin/rt_matrix.c')
-rw-r--r--bin/rt_matrix.c851
1 files changed, 0 insertions, 851 deletions
diff --git a/bin/rt_matrix.c b/bin/rt_matrix.c
deleted file mode 100644
index d3fa62c..0000000
--- a/bin/rt_matrix.c
+++ /dev/null
@@ -1,851 +0,0 @@
1#include <sys/time.h>
2#include <sys/mman.h>
3
4#include <stdio.h>
5#include <stdlib.h>
6#include <unistd.h>
7#include <time.h>
8#include <string.h>
9#include <assert.h>
10#include <limits.h>
11
12
13#include "litmus.h"
14#include "common.h"
15#include "DISstressmarkRNG.h"
16
17#define MIN_SEED -2147483647
18#define MAX_SEED -1
19#define MIN_DIM 1
20#define MAX_DIM 32768
21#define MAX_ITERATIONS 65536
22#define MIN_TOLERANCE 0.000007
23#define MAX_TOLERANCE 0.5
24#define MIN_NUMBER -3.4e10/dim
25#define MAX_NUMBER 3.4e10/dim
26#define EPSI 1.0e-10
27#define MIN_DIG_NUMBER 1.0e-10
28#define MAX_DIG_NUMBER 3.4e10
29
30static char* progname;
31int loops = 1;
32struct timeval t1, t2;
33
34/*
35 * External variable, dimension
36 */
37
38int max_dim;
39double *vectorP, *vectorR, *nextVectorR;
40double *matrixA = NULL;
41double *vectorB = NULL;
42double *vectorX = NULL;
43double *value = NULL;
44int *col_ind = NULL;
45int *row_start = NULL;
46double *tmpVector1, *tmpVector2, *tmpVector3;
47
48/*
49 * matrix * vector
50 */
51
52void matrixMulvector(double *value,
53 int *col_ind,
54 int *row_start,
55 double *vector,
56 double *out,
57 int dim)
58{
59 int l, ll;
60 int tmp_rs, tmp_re;
61
62 for (l=0; l<dim; l++){
63 *(out + l) = 0;
64 tmp_rs = row_start[l];
65
66 if (tmp_rs != -1){
67 tmp_re = row_start[l+1]; /*
68 *get the start and ending elements of
69 * each row
70 */
71 for (ll=tmp_rs; ll<tmp_re; ll++){
72 *(out + l) += value[ll]*vector[col_ind[ll]];
73 }
74 }
75 }
76 return;
77}
78
79
80/*
81 * vector1 - vector2
82 */
83
84void vectorSub(double *vector1, double *vector2, double *vector, int dim){
85
86 int l;
87
88 for (l=0; l<dim; l++){
89 *(vector + l) = *(vector1 + l) - *(vector2 + l);
90 }
91 return;
92}
93
94
95/*
96 * vector1 + vector2
97 */
98
99void vectorAdd(double *vector1, double *vector2, double *vector, int dim){
100
101 int l;
102
103 for (l=0; l<dim; l++){
104 *(vector + l) = *(vector1 + l) + *(vector2 + l);
105 }
106 return;
107}
108
109/*
110 * vector1 * vector2
111 */
112
113double vectorMul(double *vector1, double *vector2, int dim){
114
115 int l;
116 double product;
117
118 product = 0;
119
120 for (l=0; l<dim; l++){
121 product += (*(vector1 + l))*(*(vector2 + l));
122
123 }
124 return product;
125}
126
127/*
128 * /vector/
129 */
130
131double vectorValue(double *vector, int dim){
132
133 double value;
134 int l;
135
136 value = 0;
137
138 for (l=0; l<dim; l++){
139 value += (*(vector + l)) * (*(vector + l));
140 }
141
142 return (sqrt(value));
143}
144
145/*
146 * transpose(vector)
147 * In fact, we return the original vector here
148 */
149
150void transpose(double *vector, double *vect){
151
152 int l;
153
154 for (l=0; l<max_dim; l++){
155 *(vect+l) = *(vector+l);
156 }
157 return;
158}
159
160/*
161 * value * <vector>
162 */
163void valueMulvector(double value, double *vector, double *vect){
164
165 int l;
166
167 for (l=0; l<max_dim; l++){
168 *(vect + l) = *(vector + l) * value;
169 }
170 return;
171}
172
173/*
174 * generate the data distributed sparsely in matrix
175 */
176
177void initMatrix(double *matrix, int dim, int numberNonzero){
178
179 int k, l, ll;
180 int i, j;
181
182 int lll;
183 double sum;
184
185 for (k=0; k< dim*dim; k++){
186 *(matrix + k) = 0;
187 }
188
189 for (l=0; l<numberNonzero/2; l++){
190
191 i = randomUInt(1, dim-1);
192 j = randomUInt(0, i-1);
193
194 while (*(matrix + i*dim + j) != 0){
195
196 i++;
197 if (i == dim){
198 j++;
199 if (j == dim-1){
200 j = 0;
201 i = 1;
202 }
203 else{
204 i = j+1;
205 }
206 }
207 }
208
209 if (*(matrix + i*dim + j) == 0){
210 *(matrix + i*dim + j) = (double )randomNonZeroFloat(MIN_NUMBER,
211 MAX_NUMBER,
212 EPSI);
213 *(matrix + j*dim + i) = *(matrix + i*dim + j);
214 }
215 }
216
217 for (ll=0; ll<dim; ll++){
218
219
220
221 *(matrix + ll*dim + ll) = (double )randomNonZeroFloat(-MAX_DIG_NUMBER,
222 MAX_DIG_NUMBER,
223 MIN_DIG_NUMBER);
224
225 sum = 0;
226
227 for (lll=0; lll<dim; lll++){
228 if (lll != ll){
229 sum += *(matrix + lll*dim + ll);
230 }
231 }
232
233 if (*(matrix + ll*dim + ll) < sum ){
234 *(matrix + ll*dim + ll) += sum;
235 }
236 }
237
238 return;
239}
240
241/*
242 * generate the data value in the vectors
243 */
244
245void initVector(double *vector, int dim){
246
247 int l;
248
249 for (l=0; l<dim; l++){
250 *(vector + l) = (double )randomFloat (MIN_NUMBER, MAX_NUMBER);
251 }
252
253 return;
254}
255
256/*
257 * make a vector contains value of zero
258 */
259
260void zeroVector(double *vector, int dim){
261 int l;
262
263 for (l=0; l<dim; l++){
264 *(vector + l) = 0;
265 }
266 return;
267}
268
269/*
270 * return a vector which is the copy of the vect
271 */
272
273void equalVector(double *vect, double *vect1){
274
275 int l;
276
277 for (l=0; l<max_dim; l++){
278 *(vect1+l) = *(vect+l);
279 }
280 return;
281}
282
283
284
285void biConjugateGradient(double *value,
286 int *col_ind,
287 int *row_start,
288 double *vectorB,
289 double *vectorX,
290 double errorTolerance,
291 int maxIterations,
292 double *actualError,
293 int *actualIteration,
294 int dim)
295 /*
296 * in the code, we use a lot of temparary vectors and variables
297 * this is just for simple and clear
298 * you can optimize these temporary variables and vectors
299 * based on your need
300 *
301 */
302{
303 double error;
304 int iteration;
305 double alpha, beta;
306
307 double tmpValue1, tmpValue2;
308 int l;
309 int ll;
310
311 alpha = 0;
312 beta = 0;
313
314 /*
315 * vectorR = vectorB - matrixA*vectorX
316 */
317 matrixMulvector(value,col_ind, row_start, vectorX, tmpVector1, dim);
318
319 vectorSub(vectorB, tmpVector1, vectorR, dim);
320
321 /*
322 * vectorP = vectorR
323 */
324
325 equalVector(vectorR, vectorP);
326
327 /*
328 * error = |matrixA * vectorX - vectorB| / |vectorB|
329 */
330 vectorSub(tmpVector1, vectorB, tmpVector1, dim);
331
332 error = vectorValue(tmpVector1,dim)/vectorValue(vectorB,dim);
333
334 iteration = 0;
335
336 while ((iteration < maxIterations) && (error > errorTolerance)){
337
338 /*
339 * alpha = (transpose(vectorR) * vectorR) /
340 * (transpose(vectorP) * (matrixA * vectorP)
341 */
342
343 matrixMulvector(value, col_ind, row_start, vectorP, tmpVector1, dim);
344 transpose(vectorR, tmpVector2);
345 transpose(vectorP, tmpVector3);
346 tmpValue1 = vectorMul(tmpVector3, tmpVector1, dim);
347 tmpValue2 = vectorMul(tmpVector2, vectorR, dim);
348 alpha = tmpValue2/tmpValue1;
349
350 /*
351 * nextVectorR = vectorR - alpha*(matrixA * vectorP)
352 */
353
354 valueMulvector(alpha, tmpVector1, tmpVector2);
355 vectorSub(vectorR, tmpVector2, tmpVector1, dim);
356 equalVector(tmpVector1, nextVectorR);
357
358 /*
359 * beta = (transpose(nextVectorR) * nextVectorR) /
360 * (transpose(vectorR) * vectorR)
361 */
362
363 transpose(nextVectorR, tmpVector3);
364 tmpValue1 = vectorMul(tmpVector3, nextVectorR, dim);
365 transpose(vectorR, tmpVector2);
366 tmpValue2 = vectorMul(tmpVector2, vectorR, dim);
367 beta = tmpValue1/tmpValue2;
368
369 /*
370 * vectorX = vectorX + alpha * vectorP
371 */
372 valueMulvector(alpha, vectorP, tmpVector1);
373 vectorAdd(vectorX,tmpVector1, vectorX, dim);
374
375 /*
376 *vectorP = nextVectorR + beta*vectorP
377 */
378 valueMulvector(beta, vectorP, tmpVector1);
379 vectorAdd(nextVectorR, tmpVector1, tmpVector1, dim);
380
381 for (ll=0; ll<dim; ll++){
382 *(vectorP + ll) = *(tmpVector1 + ll);
383 }
384
385 /*
386 * vectorR = nextVectorR
387 */
388
389 for (l=0; l<dim; l++){
390 *(vectorR+l) = *(nextVectorR+l);
391 }
392
393 /*
394 * error = |matrixA * vectorX - vectorB| / |vectorB|
395 */
396 matrixMulvector(value, col_ind,row_start, vectorX, tmpVector1, dim);
397 vectorSub(tmpVector1,vectorB,tmpVector1,dim);
398 error = vectorValue(tmpVector1,dim)/vectorValue(vectorB,dim);
399
400 iteration++;
401 }
402
403 *actualError = error;
404 *actualIteration = iteration;
405
406
407 return;
408}
409
410/*
411 * This is the function to transfer the data from the matrix of dense storage
412 * to Compact Row Storage
413 */
414void create_CRS(double *matrixA,
415 double *value,
416 int *col_ind,
417 int *row_start,
418 int dim,
419 int numberNonzero)
420{
421
422 int i, j, k;
423 int cnt;
424 double tmp;
425
426 /*
427 *initialize the row_start
428 */
429
430 for(k=0; k<dim; k++){
431 row_start[k] = -1;
432 }
433
434 /*
435 * make the end of the last row to be numberNonzero + dim.
436 */
437
438 row_start[dim] = numberNonzero+dim;
439
440 /*
441 * initialize the col_ind
442 */
443
444 for (k=0; k<numberNonzero+dim; k++){
445 col_ind[k] = -1;
446 }
447
448
449 cnt = 0;
450
451 for (i=0; (cnt<numberNonzero+dim)&&(i<dim); i++){
452 for (j=0; (cnt<numberNonzero+dim)&&(j<dim); j++){
453
454 tmp = *(matrixA + i*dim + j);
455
456 if (tmp!=0){
457
458 value[cnt] = tmp;
459 col_ind[cnt] = j;
460
461 if (row_start[i] == -1)
462 row_start[i] = cnt;
463
464 cnt += 1;
465 }
466 }
467 }
468 row_start[i] = cnt;
469
470 return;
471}
472
473 int seed;
474 int max_numberNonzero;
475 int maxIterations;
476 float errorTolerance;
477 int k;
478
479 //fscanf(stdin, "%d %d %d %d %f",
480// &seed, &dim, &numberNonzero,&maxIterations,&errorTolerance);
481int init_job() {
482 //seed = -2;
483 //randInit(seed);
484
485 max_dim = 300;
486 //max_dim = 100;
487 max_numberNonzero = max_dim*max_dim/2+1;
488
489//maxIterations = 65535;
490
491 //dim = randInt(100, 500);
492 //numberNonzero = randInt(dim+1, dim*dim/2);
493 //maxIterations = randInt(10240, 32768);
494
495 errorTolerance = 0.02734;
496
497 //printf("%d %d %d\n",dim,numberNonzero,maxIterations);
498 //assert((seed > MIN_SEED) && (seed < MAX_SEED));
499 assert((max_dim > MIN_DIM) && (max_dim < MAX_DIM));
500 assert((max_numberNonzero > max_dim) && (max_numberNonzero < max_dim*max_dim));
501 //assert((maxIterations > 0) && (maxIterations < MAX_ITERATIONS));
502 assert((errorTolerance > MIN_TOLERANCE) && (errorTolerance < MAX_TOLERANCE));
503
504 matrixA = (double *)malloc(max_dim*max_dim*sizeof(double ));
505 vectorB = (double *)malloc(max_dim*sizeof(double));
506 vectorX = (double *)malloc(max_dim*sizeof(double));
507
508 value = (double *)malloc((max_numberNonzero+max_dim)*sizeof(double));
509 col_ind = (int *)malloc((max_numberNonzero+max_dim)*sizeof(int));
510 row_start = (int *)malloc((max_dim+1)*sizeof(int));
511
512
513 //initMatrix(matrixA, dim, numberNonzero);
514
515 //create_CRS(matrixA, value, col_ind, row_start, dim, numberNonzero);
516
517 //initVector(vectorB, dim);
518 //zeroVector(vectorX, dim);
519
520 vectorP = (double *)malloc(max_dim*sizeof(double));
521 vectorR = (double *)malloc(max_dim*sizeof(double));
522 nextVectorR = (double *)malloc(max_dim*sizeof(double));
523
524 tmpVector1 = (double *)malloc(max_dim*sizeof(double));
525 tmpVector2 = (double *)malloc(max_dim*sizeof(double));
526 tmpVector3 = (double *)malloc(max_dim*sizeof(double));
527
528 return 0;
529}
530
531int main_job() {
532 int sum, dim, numberNonzero;
533 double actualError;
534 int actualIteration;
535
536 /* for online */
537/* dim = randInt(100, max_dim);
538 numberNonzero = randInt(dim+1, dim*dim/2);
539 maxIterations = randInt(1024, 8192);
540*/
541
542 /* for case */
543 dim = randInt(4, 50);
544 numberNonzero = randInt(dim+1, dim*dim/2);
545 maxIterations = randInt(1, 10); //randInt(32, 512);
546
547
548 initMatrix(matrixA, dim, numberNonzero);
549 create_CRS(matrixA, value, col_ind, row_start, dim, numberNonzero);
550
551 initVector(vectorB, dim);
552 zeroVector(vectorX, dim);
553
554 actualError = 0;
555 actualIteration = 0;
556
557 biConjugateGradient(value, col_ind, row_start, vectorB, vectorX, errorTolerance,
558 maxIterations,
559 &actualError, &actualIteration, dim);
560
561 sum = 0;
562 for (k=1; k<dim; k++){
563 sum += sum + *(vectorX + k);
564 }
565
566 //fprintf(stdout, "sum = %d, actualError = %e, actualIteration = %d\n", sum, actualError, actualIteration);
567 //fprintf(stdout, "total time = %u sec. \n", (unsigned int)endTime);
568
569 return(0);
570}
571
572int post_job() {
573 if (matrixA) {
574 free(matrixA);
575 matrixA = NULL;
576 }
577 if (vectorB) {
578 free(vectorB);
579 vectorB = NULL;
580 }
581 if (vectorX) {
582 free(vectorX);
583 vectorX = NULL;
584 }
585 if (value) {
586 free(value);
587 value = NULL;
588 }
589 if (col_ind) {
590 free(col_ind);
591 col_ind = NULL;
592 }
593 if (row_start) {
594 free(row_start);
595 row_start = NULL;
596 }
597 if (vectorP) {
598 free(vectorP);
599 vectorP = NULL;
600 }
601 if (vectorR) {
602 free(vectorR);
603 vectorR = NULL;
604 }
605 if (nextVectorR) {
606 free(nextVectorR);
607 nextVectorR = NULL;
608 }
609 if (tmpVector1) {
610 free(tmpVector1);
611 tmpVector1 = NULL;
612 }
613 if (tmpVector2) {
614 free(tmpVector2);
615 tmpVector2 = NULL;
616 }
617 if (tmpVector3) {
618 free(tmpVector3);
619 tmpVector3 = NULL;
620 }
621
622 return 0;
623}
624
625static void usage(char *error) {
626 fprintf(stderr, "Error: %s\n", error);
627 fprintf(stderr,
628 "Usage:\n"
629 " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n"
630 " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n"
631 " rt_spin -l\n"
632 "\n"
633 "COMMON-OPTS = [-w] [-s SCALE]\n"
634 " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n"
635 "\n"
636 "WCET and PERIOD are microseconds, DURATION is seconds.\n");
637 exit(EXIT_FAILURE);
638}
639
640inline unsigned long get_cyclecount (void)
641{
642 unsigned long value;
643 // Read CCNT Register
644 asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));
645 return value;
646}
647
648static int job(double exec_time, double program_end)
649{
650 if (wctime() > program_end)
651 return 0;
652 else {
653 //register int iter = 0;
654 //register unsigned long t;
655 //t = get_cyclecount();
656 //gettimeofday(&t1, NULL);
657 //while (iter++ < loops) {
658 main_job();
659 //}
660 //t = get_cyclecount() - t;
661 //printf("%ld cycles\n", t);
662 //gettimeofday(&t2, NULL);
663 //printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec)));
664 sleep_next_period();
665 return 1;
666 }
667}
668
669#define OPTSTR "p:wves:l:m:i:b:"
670int main(int argc, char** argv)
671{
672 int ret;
673 lt_t wcet;
674 lt_t period;
675 lt_t budget;
676 double wcet_ms, period_ms, budget_ms;
677 unsigned int priority = LITMUS_NO_PRIORITY;
678 int migrate = 0;
679 int cluster = 0;
680 int opt;
681 int wait = 0;
682 int want_enforcement = 0;
683 double duration = 0, start = 0;
684 double scale = 1.0;
685 task_class_t class = RT_CLASS_HARD;
686 struct rt_task param;
687 struct mc2_task mc2_param;
688 struct reservation_config config;
689 int res_type = PERIODIC_POLLING;
690
691 progname = argv[0];
692
693 /* default for reservation */
694 config.id = 0;
695 config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */
696 config.cpu = -1;
697
698 mc2_param.crit = CRIT_LEVEL_C;
699
700 budget_ms = 10;
701
702 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
703 switch (opt) {
704 case 'w':
705 wait = 1;
706 break;
707 case 'p':
708 cluster = atoi(optarg);
709 migrate = 1;
710 config.cpu = cluster;
711 break;
712 case 'e':
713 want_enforcement = 1;
714 break;
715 case 's':
716 scale = atof(optarg);
717 break;
718 case 'l':
719 loops = atoi(optarg);
720 break;
721 case 'm':
722 mc2_param.crit = atoi(optarg);
723 if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) {
724 usage("Invalid criticality level.");
725 }
726 res_type = PERIODIC_POLLING;
727 break;
728 case 'b':
729 budget_ms = atof(optarg);
730 break;
731 case 'i':
732 config.priority = atoi(optarg);
733 break;
734 case ':':
735 usage("Argument missing.");
736 break;
737 case '?':
738 default:
739 usage("Bad argument.");
740 break;
741 }
742 }
743
744 if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY)
745 usage("Bad criticailty level or priority");
746
747 if (argc - optind < 3)
748 usage("Arguments missing.");
749
750 wcet_ms = atof(argv[optind + 0]);
751 period_ms = atof(argv[optind + 1]);
752
753 wcet = ms2ns(wcet_ms);
754 period = ms2ns(period_ms);
755 budget = ms2ns(budget_ms);
756
757 if (wcet <= 0)
758 usage("The worst-case execution time must be a "
759 "positive number.");
760 if (period <= 0)
761 usage("The period must be a positive number.");
762 if (wcet > period) {
763 usage("The worst-case execution time must not "
764 "exceed the period.");
765 }
766
767 duration = atof(argv[optind + 2]);
768
769 if (migrate) {
770 ret = be_migrate_to_domain(cluster);
771 if (ret < 0)
772 bail_out("could not migrate to target partition or cluster.");
773 }
774
775 /* reservation config */
776 config.id = gettid();
777
778 config.polling_params.budget = budget;
779 config.polling_params.period = period;
780 config.polling_params.offset = 0;
781 config.polling_params.relative_deadline = 0;
782 if (config.polling_params.budget > config.polling_params.period) {
783 usage("The budget must not exceed the period.");
784 }
785
786 /* create a reservation */
787 ret = reservation_create(res_type, &config);
788 if (ret < 0) {
789 bail_out("failed to create reservation.");
790 }
791 //srand (time(NULL));
792
793 seed = -2;
794 randInit(seed);
795
796 init_job();
797
798 init_rt_task_param(&param);
799 param.exec_cost = wcet;
800 param.period = period;
801 param.priority = priority;
802 param.cls = class;
803 param.release_policy = TASK_PERIODIC;
804 param.budget_policy = (want_enforcement) ?
805 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
806 if (migrate) {
807 param.cpu = gettid();
808 }
809 ret = set_rt_task_param(gettid(), &param);
810
811 if (ret < 0)
812 bail_out("could not setup rt task params");
813
814 mc2_param.res_id = gettid();
815 ret = set_mc2_task_param(gettid(), &mc2_param);
816
817 if (ret < 0)
818 bail_out("could not setup mc2 task params");
819
820 init_litmus();
821
822 if (mc2_param.crit == CRIT_LEVEL_C)
823 set_page_color(-1);
824 else if (mc2_param.crit < CRIT_LEVEL_C)
825 set_page_color(config.cpu);
826
827 start = wctime();
828 ret = task_mode(LITMUS_RT_TASK);
829
830 if (ret != 0)
831 bail_out("could not become RT task");
832
833
834 if (wait) {
835 ret = wait_for_ts_release();
836 if (ret != 0)
837 bail_out("wait_for_ts_release()");
838 start = wctime();
839 }
840
841 while (job(wcet_ms * 0.001 * scale, start + duration)) {};
842
843 ret = task_mode(BACKGROUND_TASK);
844 if (ret != 0)
845 bail_out("could not become regular task (huh?)");
846
847 reservation_destroy(gettid(), config.cpu);
848 post_job();
849 printf("%s/%d finished.\n",progname, gettid());
850 return 0;
851}