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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [bootloaders/] [orpmon/] [coremark/] [core_matrix.c] - Blame information for rev 406

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 355 julius
/*
2
Author : Shay Gal-On, EEMBC
3
 
4
This file is part of  EEMBC(R) and CoreMark(TM), which are Copyright (C) 2009
5
All rights reserved.
6
 
7
EEMBC CoreMark Software is a product of EEMBC and is provided under the terms of the
8
CoreMark License that is distributed with the official EEMBC COREMARK Software release.
9
If you received this EEMBC CoreMark Software without the accompanying CoreMark License,
10
you must discontinue use and download the official release from www.coremark.org.
11
 
12
Also, if you are publicly displaying scores generated from the EEMBC CoreMark software,
13
make sure that you are in compliance with Run and Reporting rules specified in the accompanying readme.txt file.
14
 
15
EEMBC
16
4354 Town Center Blvd. Suite 114-200
17
El Dorado Hills, CA, 95762
18 406 julius
*/
19 355 julius
#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 406 julius
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 355 julius
 
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 406 julius
void printmat(MATDAT * A, ee_u32 N, char *name)
51
{
52
        ee_u32 i, j;
53
        ee_printf("Matrix %s [%dx%d]:\n", name, N, N);
54
        for (i = 0; i < N; i++) {
55
                for (j = 0; j < N; j++) {
56
                        if (j != 0)
57 355 julius
                                ee_printf(",");
58 406 julius
                        ee_printf("%d", A[i * N + j]);
59 355 julius
                }
60
                ee_printf("\n");
61
        }
62
}
63 406 julius
 
64
void printmatC(MATRES * C, ee_u32 N, char *name)
65
{
66
        ee_u32 i, j;
67
        ee_printf("Matrix %s [%dx%d]:\n", name, N, N);
68
        for (i = 0; i < N; i++) {
69
                for (j = 0; j < N; j++) {
70
                        if (j != 0)
71 355 julius
                                ee_printf(",");
72 406 julius
                        ee_printf("%d", C[i * N + j]);
73 355 julius
                }
74
                ee_printf("\n");
75
        }
76
}
77
#endif
78
/* Function: core_bench_matrix
79
        Benchmark function
80
 
81
        Iterate <matrix_test> N times,
82
        changing the matrix values slightly by a constant amount each time.
83
*/
84 406 julius
ee_u16 core_bench_matrix(mat_params * p, ee_s16 seed, ee_u16 crc)
85
{
86
        ee_u32 N = p->N;
87
        MATRES *C = p->C;
88
        MATDAT *A = p->A;
89
        MATDAT *B = p->B;
90
        MATDAT val = (MATDAT) seed;
91 355 julius
 
92 406 julius
        crc = crc16(matrix_test(N, C, A, B, val), crc);
93 355 julius
 
94
        return crc;
95
}
96
 
97
/* Function: matrix_test
98
        Perform matrix manipulation.
99
 
100
        Parameters:
101
        N - Dimensions of the matrix.
102
        C - memory for result matrix.
103
        A - input matrix
104
        B - operator matrix (not changed during operations)
105
 
106
        Returns:
107
        A CRC value that captures all results calculated in the function.
108
        In particular, crc of the value calculated on the result matrix
109
        after each step by <matrix_sum>.
110
 
111
        Operation:
112
 
113
        1 - Add a constant value to all elements of a matrix.
114
        2 - Multiply a matrix by a constant.
115
        3 - Multiply a matrix by a vector.
116
        4 - Multiply a matrix by a matrix.
117
        5 - Add a constant value to all elements of a matrix.
118
 
119
        After the last step, matrix A is back to original contents.
120
*/
121 406 julius
ee_s16 matrix_test(ee_u32 N, MATRES * C, MATDAT * A, MATDAT * B, MATDAT val)
122
{
123
        ee_u16 crc = 0;
124
        MATDAT clipval = matrix_big(val);
125 355 julius
 
126 406 julius
        matrix_add_const(N, A, val);    /* make sure data changes  */
127 355 julius
#if CORE_DEBUG
128 406 julius
        printmat(A, N, "matrix_add_const");
129 355 julius
#endif
130 406 julius
        matrix_mul_const(N, C, A, val);
131
        crc = crc16(matrix_sum(N, C, clipval), crc);
132 355 julius
#if CORE_DEBUG
133 406 julius
        printmatC(C, N, "matrix_mul_const");
134 355 julius
#endif
135 406 julius
        matrix_mul_vect(N, C, A, B);
136
        crc = crc16(matrix_sum(N, C, clipval), crc);
137 355 julius
#if CORE_DEBUG
138 406 julius
        printmatC(C, N, "matrix_mul_vect");
139 355 julius
#endif
140 406 julius
        matrix_mul_matrix(N, C, A, B);
141
        crc = crc16(matrix_sum(N, C, clipval), crc);
142 355 julius
#if CORE_DEBUG
143 406 julius
        printmatC(C, N, "matrix_mul_matrix");
144 355 julius
#endif
145 406 julius
        matrix_mul_matrix_bitextract(N, C, A, B);
146
        crc = crc16(matrix_sum(N, C, clipval), crc);
147 355 julius
#if CORE_DEBUG
148 406 julius
        printmatC(C, N, "matrix_mul_matrix_bitextract");
149 355 julius
#endif
150 406 julius
 
151
        matrix_add_const(N, A, -val);   /* return matrix to initial value */
152 355 julius
        return crc;
153
}
154
 
155
/* Function : matrix_init
156
        Initialize the memory block for matrix benchmarking.
157
 
158
        Parameters:
159
        blksize - Size of memory to be initialized.
160
        memblk - Pointer to memory block.
161
        seed - Actual values chosen depend on the seed parameter.
162
        p - pointers to <mat_params> containing initialized matrixes.
163
 
164
        Returns:
165
        Matrix dimensions.
166
 
167
        Note:
168
        The seed parameter MUST be supplied from a source that cannot be determined at compile time
169
*/
170 406 julius
ee_u32 core_init_matrix(ee_u32 blksize, void *memblk, ee_s32 seed,
171
                        mat_params * p)
172
{
173
        ee_u32 N = 0;
174 355 julius
        MATDAT *A;
175
        MATDAT *B;
176 406 julius
        ee_s32 order = 1;
177 355 julius
        MATDAT val;
178 406 julius
        ee_u32 i = 0, j = 0;
179
        if (seed == 0)
180
                seed = 1;
181
        while (j < blksize) {
182 355 julius
                i++;
183 406 julius
                j = i * i * 2 * 4;
184 355 julius
        }
185 406 julius
        N = i - 1;
186
        A = (MATDAT *) align_mem(memblk);
187
        B = A + N * N;
188 355 julius
 
189 406 julius
        for (i = 0; i < N; i++) {
190
                for (j = 0; j < N; j++) {
191
                        seed = ((order * seed) % 65536);
192 355 julius
                        val = (seed + order);
193 406 julius
                        val = matrix_clip(val, 0);
194
                        B[i * N + j] = val;
195
                        val = (val + order);
196
                        val = matrix_clip(val, 1);
197
                        A[i * N + j] = val;
198 355 julius
                        order++;
199
                }
200
        }
201
 
202 406 julius
        p->A = A;
203
        p->B = B;
204
        p->C = (MATRES *) align_mem(B + N * N);
205
        p->N = N;
206 355 julius
#if CORE_DEBUG
207 406 julius
        printmat(A, N, "A");
208
        printmat(B, N, "B");
209 355 julius
#endif
210
        return N;
211
}
212
 
213
/* Function: matrix_sum
214
        Calculate a function that depends on the values of elements in the matrix.
215
 
216
        For each element, accumulate into a temporary variable.
217
 
218
        As long as this value is under the parameter clipval,
219
        add 1 to the result if the element is bigger then the previous.
220
 
221
        Otherwise, reset the accumulator and add 10 to the result.
222
*/
223 406 julius
ee_s16 matrix_sum(ee_u32 N, MATRES * C, MATDAT clipval)
224
{
225
        MATRES tmp = 0, prev = 0, cur = 0;
226
        ee_s16 ret = 0;
227
        ee_u32 i, j;
228
        for (i = 0; i < N; i++) {
229
                for (j = 0; j < N; j++) {
230
                        cur = C[i * N + j];
231
                        tmp += cur;
232
                        if (tmp > clipval) {
233
                                ret += 10;
234
                                tmp = 0;
235 355 julius
                        } else {
236 406 julius
                                ret += (cur > prev) ? 1 : 0;
237 355 julius
                        }
238 406 julius
                        prev = cur;
239 355 julius
                }
240
        }
241
        return ret;
242
}
243
 
244
/* Function: matrix_mul_const
245
        Multiply a matrix by a constant.
246
        This could be used as a scaler for instance.
247
*/
248 406 julius
void matrix_mul_const(ee_u32 N, MATRES * C, MATDAT * A, MATDAT val)
249
{
250
        ee_u32 i, j;
251
        for (i = 0; i < N; i++) {
252
                for (j = 0; j < N; j++) {
253
                        C[i * N + j] = (MATRES) A[i * N + j] * (MATRES) val;
254 355 julius
                }
255
        }
256
}
257
 
258
/* Function: matrix_add_const
259
        Add a constant value to all elements of a matrix.
260
*/
261 406 julius
void matrix_add_const(ee_u32 N, MATDAT * A, MATDAT val)
262
{
263
        ee_u32 i, j;
264
        for (i = 0; i < N; i++) {
265
                for (j = 0; j < N; j++) {
266
                        A[i * N + j] += val;
267 355 julius
                }
268
        }
269
}
270
 
271
/* Function: matrix_mul_vect
272
        Multiply a matrix by a vector.
273
        This is common in many simple filters (e.g. fir where a vector of coefficients is applied to the matrix.)
274
*/
275 406 julius
void matrix_mul_vect(ee_u32 N, MATRES * C, MATDAT * A, MATDAT * B)
276
{
277
        ee_u32 i, j;
278
        for (i = 0; i < N; i++) {
279
                C[i] = 0;
280
                for (j = 0; j < N; j++) {
281
                        C[i] += (MATRES) A[i * N + j] * (MATRES) B[j];
282 355 julius
                }
283
        }
284
}
285
 
286
/* Function: matrix_mul_matrix
287
        Multiply a matrix by a matrix.
288
        Basic code is used in many algorithms, mostly with minor changes such as scaling.
289
*/
290 406 julius
void matrix_mul_matrix(ee_u32 N, MATRES * C, MATDAT * A, MATDAT * B)
291
{
292
        ee_u32 i, j, k;
293
        for (i = 0; i < N; i++) {
294
                for (j = 0; j < N; j++) {
295
                        C[i * N + j] = 0;
296
                        for (k = 0; k < N; k++) {
297
                                C[i * N + j] +=
298
                                    (MATRES) A[i * N + k] * (MATRES) B[k * N +
299
                                                                       j];
300 355 julius
                        }
301
                }
302
        }
303
}
304
 
305
/* Function: matrix_mul_matrix_bitextract
306
        Multiply a matrix by a matrix, and extract some bits from the result.
307
        Basic code is used in many algorithms, mostly with minor changes such as scaling.
308
*/
309 406 julius
void matrix_mul_matrix_bitextract(ee_u32 N, MATRES * C, MATDAT * A, MATDAT * B)
310
{
311
        ee_u32 i, j, k;
312
        for (i = 0; i < N; i++) {
313
                for (j = 0; j < N; j++) {
314
                        C[i * N + j] = 0;
315
                        for (k = 0; k < N; k++) {
316
                                MATRES tmp =
317
                                    (MATRES) A[i * N + k] * (MATRES) B[k * N +
318
                                                                       j];
319
                                C[i * N + j] +=
320
                                    bit_extract(tmp, 2, 4) * bit_extract(tmp, 5,
321
                                                                         7);
322 355 julius
                        }
323
                }
324
        }
325
}

powered by: WebSVN 2.1.0

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