OpenCores
URL https://opencores.org/ocsvn/neo430/neo430/trunk

Subversion Repositories neo430

[/] [neo430/] [trunk/] [neo430/] [sw/] [example/] [coremark/] [core_matrix.c] - Blame information for rev 198

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 198 zero_gravi
/*
2
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
3
 
4
Licensed under the Apache License, Version 2.0 (the "License");
5
you may not use this file except in compliance with the License.
6
You may obtain a copy of the License at
7
 
8
    http://www.apache.org/licenses/LICENSE-2.0
9
 
10
Unless required by applicable law or agreed to in writing, software
11
distributed under the License is distributed on an "AS IS" BASIS,
12
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
See the License for the specific language governing permissions and
14
limitations under the License.
15
 
16
Original Author: Shay Gal-on
17
*/
18
 
19
#include "coremark.h"
20
/*
21
Topic: Description
22
        Matrix manipulation benchmark
23
 
24
        This very simple algorithm forms the basis of many more complex algorithms.
25
 
26
        The tight inner loop is the focus of many optimizations (compiler as well as hardware based)
27
        and is thus relevant for embedded processing.
28
 
29
        The total available data space will be divided to 3 parts:
30
        NxN Matrix A - initialized with small values (upper 3/4 of the bits all zero).
31
        NxN Matrix B - initialized with medium values (upper half of the bits all zero).
32
        NxN Matrix C - used for the result.
33
 
34
        The actual values for A and B must be derived based on input that is not available at compile time.
35
*/
36
ee_s16 matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val);
37
ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval);
38
void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val);
39
void matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
40
void matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
41
void matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
42
void matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val);
43
 
44
#define matrix_test_next(x) (x+1)
45
#define matrix_clip(x,y) ((y) ? (x) & 0x0ff : (x) & 0x0ffff)
46
#define matrix_big(x) (0xf000 | (x))
47
#define bit_extract(x,from,to) (((x)>>(from)) & (~(0xffffffff << (to))))
48
 
49
#if CORE_DEBUG
50
void printmat(MATDAT *A, ee_u32 N, char *name) {
51
        ee_u32 i,j;
52
        ee_printf("Matrix %s [%dx%d]:\n",name,N,N);
53
        for (i=0; i<N; i++) {
54
                for (j=0; j<N; j++) {
55
                        if (j!=0)
56
                                ee_printf(",");
57
                        ee_printf("%d",A[i*N+j]);
58
                }
59
                ee_printf("\n");
60
        }
61
}
62
void printmatC(MATRES *C, ee_u32 N, char *name) {
63
        ee_u32 i,j;
64
        ee_printf("Matrix %s [%dx%d]:\n",name,N,N);
65
        for (i=0; i<N; i++) {
66
                for (j=0; j<N; j++) {
67
                        if (j!=0)
68
                                ee_printf(",");
69
                        ee_printf("%d",C[i*N+j]);
70
                }
71
                ee_printf("\n");
72
        }
73
}
74
#endif
75
/* Function: core_bench_matrix
76
        Benchmark function
77
 
78
        Iterate <matrix_test> N times,
79
        changing the matrix values slightly by a constant amount each time.
80
*/
81
ee_u16 core_bench_matrix(mat_params *p, ee_s16 seed, ee_u16 crc) {
82
        ee_u32 N=p->N;
83
        MATRES *C=p->C;
84
        MATDAT *A=p->A;
85
        MATDAT *B=p->B;
86
        MATDAT val=(MATDAT)seed;
87
 
88
        crc=crc16(matrix_test(N,C,A,B,val),crc);
89
 
90
        return crc;
91
}
92
 
93
/* Function: matrix_test
94
        Perform matrix manipulation.
95
 
96
        Parameters:
97
        N - Dimensions of the matrix.
98
        C - memory for result matrix.
99
        A - input matrix
100
        B - operator matrix (not changed during operations)
101
 
102
        Returns:
103
        A CRC value that captures all results calculated in the function.
104
        In particular, crc of the value calculated on the result matrix
105
        after each step by <matrix_sum>.
106
 
107
        Operation:
108
 
109
        1 - Add a constant value to all elements of a matrix.
110
        2 - Multiply a matrix by a constant.
111
        3 - Multiply a matrix by a vector.
112
        4 - Multiply a matrix by a matrix.
113
        5 - Add a constant value to all elements of a matrix.
114
 
115
        After the last step, matrix A is back to original contents.
116
*/
117
ee_s16 matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val) {
118
        ee_u16 crc=0;
119
        MATDAT clipval=matrix_big(val);
120
 
121
        matrix_add_const(N,A,val); /* make sure data changes  */
122
#if CORE_DEBUG
123
        printmat(A,N,"matrix_add_const");
124
#endif
125
        matrix_mul_const(N,C,A,val);
126
        crc=crc16(matrix_sum(N,C,clipval),crc);
127
#if CORE_DEBUG
128
        printmatC(C,N,"matrix_mul_const");
129
#endif
130
        matrix_mul_vect(N,C,A,B);
131
        crc=crc16(matrix_sum(N,C,clipval),crc);
132
#if CORE_DEBUG
133
        printmatC(C,N,"matrix_mul_vect");
134
#endif
135
        matrix_mul_matrix(N,C,A,B);
136
        crc=crc16(matrix_sum(N,C,clipval),crc);
137
#if CORE_DEBUG
138
        printmatC(C,N,"matrix_mul_matrix");
139
#endif
140
        matrix_mul_matrix_bitextract(N,C,A,B);
141
        crc=crc16(matrix_sum(N,C,clipval),crc);
142
#if CORE_DEBUG
143
        printmatC(C,N,"matrix_mul_matrix_bitextract");
144
#endif
145
 
146
        matrix_add_const(N,A,-val); /* return matrix to initial value */
147
        return crc;
148
}
149
 
150
/* Function : matrix_init
151
        Initialize the memory block for matrix benchmarking.
152
 
153
        Parameters:
154
        blksize - Size of memory to be initialized.
155
        memblk - Pointer to memory block.
156
        seed - Actual values chosen depend on the seed parameter.
157
        p - pointers to <mat_params> containing initialized matrixes.
158
 
159
        Returns:
160
        Matrix dimensions.
161
 
162
        Note:
163
        The seed parameter MUST be supplied from a source that cannot be determined at compile time
164
*/
165
ee_u32 core_init_matrix(ee_u32 blksize, void *memblk, ee_s32 seed, mat_params *p) {
166
        ee_u32 N=0;
167
        MATDAT *A;
168
        MATDAT *B;
169
        ee_s32 order=1;
170
        MATDAT val;
171
        ee_u32 i=0,j=0;
172
        if (seed==0)
173
                seed=1;
174
        while (j<blksize) {
175
                i++;
176
                j=i*i*2*4;
177
        }
178
        N=i-1;
179
        A=(MATDAT *)align_mem(memblk);
180
        B=A+N*N;
181
 
182
        for (i=0; i<N; i++) {
183
                for (j=0; j<N; j++) {
184
                        seed = ( ( order * seed ) % 65536 );
185
                        val = (seed + order);
186
                        val=matrix_clip(val,0);
187
                        B[i*N+j] = val;
188
                        val =  (val + order);
189
                        val=matrix_clip(val,1);
190
                        A[i*N+j] = val;
191
                        order++;
192
                }
193
        }
194
 
195
        p->A=A;
196
        p->B=B;
197
        p->C=(MATRES *)align_mem(B+N*N);
198
        p->N=N;
199
#if CORE_DEBUG
200
        printmat(A,N,"A");
201
        printmat(B,N,"B");
202
#endif
203
        return N;
204
}
205
 
206
/* Function: matrix_sum
207
        Calculate a function that depends on the values of elements in the matrix.
208
 
209
        For each element, accumulate into a temporary variable.
210
 
211
        As long as this value is under the parameter clipval,
212
        add 1 to the result if the element is bigger then the previous.
213
 
214
        Otherwise, reset the accumulator and add 10 to the result.
215
*/
216
ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval) {
217
        MATRES tmp=0,prev=0,cur=0;
218
        ee_s16 ret=0;
219
        ee_u32 i,j;
220
        for (i=0; i<N; i++) {
221
                for (j=0; j<N; j++) {
222
                        cur=C[i*N+j];
223
                        tmp+=cur;
224
                        if (tmp>clipval) {
225
                                ret+=10;
226
                                tmp=0;
227
                        } else {
228
                                ret += (cur>prev) ? 1 : 0;
229
                        }
230
                        prev=cur;
231
                }
232
        }
233
        return ret;
234
}
235
 
236
/* Function: matrix_mul_const
237
        Multiply a matrix by a constant.
238
        This could be used as a scaler for instance.
239
*/
240
void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val) {
241
        ee_u32 i,j;
242
        for (i=0; i<N; i++) {
243
                for (j=0; j<N; j++) {
244
                        C[i*N+j]=(MATRES)A[i*N+j] * (MATRES)val;
245
                }
246
        }
247
}
248
 
249
/* Function: matrix_add_const
250
        Add a constant value to all elements of a matrix.
251
*/
252
void matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val) {
253
        ee_u32 i,j;
254
        for (i=0; i<N; i++) {
255
                for (j=0; j<N; j++) {
256
                        A[i*N+j] += val;
257
                }
258
        }
259
}
260
 
261
/* Function: matrix_mul_vect
262
        Multiply a matrix by a vector.
263
        This is common in many simple filters (e.g. fir where a vector of coefficients is applied to the matrix.)
264
*/
265
void matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) {
266
        ee_u32 i,j;
267
        for (i=0; i<N; i++) {
268
                C[i]=0;
269
                for (j=0; j<N; j++) {
270
                        C[i]+=(MATRES)A[i*N+j] * (MATRES)B[j];
271
                }
272
        }
273
}
274
 
275
/* Function: matrix_mul_matrix
276
        Multiply a matrix by a matrix.
277
        Basic code is used in many algorithms, mostly with minor changes such as scaling.
278
*/
279
void matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) {
280
        ee_u32 i,j,k;
281
        for (i=0; i<N; i++) {
282
                for (j=0; j<N; j++) {
283
                        C[i*N+j]=0;
284
                        for(k=0;k<N;k++)
285
                        {
286
                                C[i*N+j]+=(MATRES)A[i*N+k] * (MATRES)B[k*N+j];
287
                        }
288
                }
289
        }
290
}
291
 
292
/* Function: matrix_mul_matrix_bitextract
293
        Multiply a matrix by a matrix, and extract some bits from the result.
294
        Basic code is used in many algorithms, mostly with minor changes such as scaling.
295
*/
296
void matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) {
297
        ee_u32 i,j,k;
298
        for (i=0; i<N; i++) {
299
                for (j=0; j<N; j++) {
300
                        C[i*N+j]=0;
301
                        for(k=0;k<N;k++)
302
                        {
303
                                MATRES tmp=(MATRES)A[i*N+k] * (MATRES)B[k*N+j];
304
                                C[i*N+j]+=bit_extract(tmp,2,4)*bit_extract(tmp,5,7);
305
                        }
306
                }
307
        }
308
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.