Merge branch 'master' of github.com:ucb-bar/riscv-tests
[riscv-tests.git] / benchmarks / vec-vvadd / vec_vvadd_main.c
1 //**************************************************************************
2 // Vector-Thread Vector-vector add benchmark
3 //--------------------------------------------------------------------------
4 //
5 // This benchmark uses adds to vectors and writes the results to a third
6 // vector. The input data (and reference data) should be generated using the
7 // vvadd_gendata.pl perl script and dumped to a file named dataset.h.
8
9 // Choose which implementation you wish to test... but leave only one on!
10 // (only the first one will be executed).
11 //#define SCALAR_C
12 //#define SCALAR_ASM
13 #define VT_ASM
14
15 //--------------------------------------------------------------------------
16 // Input/Reference Data
17
18 //#include "dataset_test.h"
19 #include "dataset.h"
20
21 //--------------------------------------------------------------------------
22 // Helper functions
23
24 int verify( int n, float test[], float correct[] )
25 {
26 int i;
27 for ( i = 0; i < n; i++ ) {
28 // if ( test[i] != correct[i] ) {
29 if ( test[i] > 1.02*correct[i]
30 || test[i] < 0.98*correct[i]) {
31 #if HOST_DEBUG
32 printf(" test[%d] : %3.2f\n", i, test[i]);
33 printf(" corr[%d] : %3.2f\n", i, correct[i]);
34 #endif
35 // tell us which index fails + 2
36 // (so that if i==0,i==1 fails, we don't
37 // think it was a 'not-finished yet' or pass)
38 // return i+10;
39 return 2;
40 }
41 }
42 return 1;
43 }
44
45 void finishTest( int correct, long long num_cycles, long long num_retired )
46 {
47 int toHostValue = correct;
48 #if HOST_DEBUG
49 if ( toHostValue == 1 )
50 printf( "*** PASSED ***\n" );
51 else
52 printf( "*** FAILED *** (tohost = %d)\n", toHostValue );
53 exit(0);
54 #else
55 // we no longer run in -testrun mode, which means we can't use
56 // the tohost register to communicate "test is done" and "test results"
57 // so instead we will communicate through print* functions!
58 if ( correct == 1 )
59 {
60 printstr( "*** PASSED *** (num_cycles = 0x" );
61 printhex(num_cycles);
62 printstr( ", num_inst_retired = 0x");
63 printhex(num_retired);
64 printstr( ")\n" );
65 }
66 else
67 {
68 printstr( "*** FAILED *** (num_cycles = 0x");
69 printhex(num_cycles);
70 printstr( ", num_inst_retired = 0x");
71 printhex(num_retired);
72 printstr( ")\n" );
73 }
74 exit();
75 #endif
76 }
77
78
79 // deprecated - cr10/stats-enable register no longer exists
80 void setStats( int enable )
81 {
82 #if ( !HOST_DEBUG && SET_STATS )
83 asm( "mtpcr %0, cr10" : : "r" (enable) );
84 #endif
85 }
86
87 long long getCycles()
88 {
89 long long cycles = 1337;
90 #if ( !HOST_DEBUG && SET_STATS )
91 __asm__ __volatile__( "rdcycle %0" : "=r" (cycles) );
92 #endif
93 return cycles;
94 }
95
96 long long getInstRetired()
97 {
98 long long inst_retired = 1338;
99 #if ( !HOST_DEBUG && SET_STATS )
100 __asm__ __volatile__( "rdinstret %0" : "=r" (inst_retired) );
101 #endif
102 return inst_retired;
103 }
104
105 //--------------------------------------------------------------------------
106 // vvadd function
107
108 // scalar C implementation
109 void vvadd( int n, float a[], float b[], float c[] )
110 {
111 int i;
112 for ( i = 0; i < n; i++ )
113 c[i] = a[i] + b[i];
114 }
115
116 // assembly implementations can be found in *_asm.S
117
118 //--------------------------------------------------------------------------
119 // Main
120
121 int main( int argc, char* argv[] )
122 {
123 float results_data[DATA_SIZE];
124 long long start_cycles = 0;
125 long long stop_cycles = 0;
126 long long num_cycles;
127 long long start_retired = 0;
128 long long stop_retired = 0;
129 long long num_retired;
130
131 // Output the input array
132
133 #if HOST_DEBUG
134 printArray( "input1", DATA_SIZE, input1_data );
135 printArray( "input2", DATA_SIZE, input2_data );
136 printArray( "verify", DATA_SIZE, verify_data );
137 #endif
138
139 // --------------------------------------------------
140 // If needed we preallocate everything in the caches
141
142 #if PREALLOCATE
143
144 #ifdef SCALAR_C
145 vvadd( DATA_SIZE, input1_data, input2_data, results_data );
146 #else
147 #ifdef SCALAR_ASM
148 scalar_vvadd_asm( DATA_SIZE, input1_data, input2_data, results_data );
149 #else
150 #ifdef VT_ASM
151 vt_vvadd_asm( DATA_SIZE, input1_data, input2_data, results_data );
152 #endif
153 #endif
154 #endif
155
156 #endif
157
158 // --------------------------------------------------
159 // Do the vvadd
160 start_cycles = getCycles();
161 start_retired = getInstRetired();
162
163 #ifdef SCALAR_C
164 vvadd( DATA_SIZE, input1_data, input2_data, results_data );
165 #else
166 #ifdef SCALAR_ASM
167 #if HOST_DEBUG==0
168 scalar_vvadd_asm( DATA_SIZE, input1_data, input2_data, results_data );
169 #endif
170 #else
171 #ifdef VT_ASM
172 #if HOST_DEBUG==0
173 vt_vvadd_asm( DATA_SIZE, input1_data, input2_data, results_data );
174 #endif
175 #endif
176 #endif
177 #endif
178
179 stop_cycles = getCycles();
180 stop_retired = getInstRetired();
181 num_cycles = stop_cycles - start_cycles;
182 num_retired = stop_retired - start_retired;
183
184 // printstr("stop_cycles: "); printhex(stop_cycles); printstr("\n");
185 // printstr("star_cycles: "); printhex(start_cycles); printstr("\n");
186
187 // --------------------------------------------------
188 // Print out the results
189
190 #if HOST_DEBUG
191 printArray( "results", DATA_SIZE, results_data );
192 #endif
193
194 // --------------------------------------------------
195 // Check the results
196 int correct = verify( DATA_SIZE, results_data, verify_data );
197 finishTest(correct, num_cycles, num_retired);
198 }