source: soft/giet_vm/applications/coremark/core_matrix.c @ 753

Last change on this file since 753 was 753, checked in by cfuguet, 8 years ago

Introducing the coremark benchmark

File size: 7.9 KB
Line 
1/*
2Author : Shay Gal-On, EEMBC
3
4This file is part of  EEMBC(R) and CoreMark(TM), which are Copyright (C) 2009
5All rights reserved.                           
6
7EEMBC CoreMark Software is a product of EEMBC and is provided under the terms of the
8CoreMark License that is distributed with the official EEMBC COREMARK Software release.
9If you received this EEMBC CoreMark Software without the accompanying CoreMark License,
10you must discontinue use and download the official release from www.coremark.org. 
11
12Also, if you are publicly displaying scores generated from the EEMBC CoreMark software,
13make sure that you are in compliance with Run and Reporting rules specified in the accompanying readme.txt file.
14
15EEMBC
164354 Town Center Blvd. Suite 114-200
17El Dorado Hills, CA, 95762
18*/ 
19#include "coremark.h"
20/*
21Topic: 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*/
36ee_s16 matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val);
37ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval);
38void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val);
39void matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
40void matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
41void matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
42void 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
50void 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}
62void 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*/
81ee_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*/
117ee_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*/
165ee_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*/
216ee_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*/
240void 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*/
252void 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*/
265void 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*/
279void 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*/
296void 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}
Note: See TracBrowser for help on using the repository browser.