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

Subversion Repositories steelcore

[/] [coremark/] [core_matrix.c] - Blame information for rev 11

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 11 rafaelcalc
/*
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
25
algorithms.
26
 
27
        The tight inner loop is the focus of many optimizations (compiler as
28
well as hardware based) and is thus relevant for embedded processing.
29
 
30
        The total available data space will be divided to 3 parts:
31
        NxN Matrix A - initialized with small values (upper 3/4 of the bits all
32
zero). NxN Matrix B - initialized with medium values (upper half of the bits all
33
zero). NxN Matrix C - used for the result.
34
 
35
        The actual values for A and B must be derived based on input that is not
36
available at compile time.
37
*/
38
ee_s16 matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val);
39
ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval);
40
void   matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val);
41
void   matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
42
void   matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
43
void   matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
44
void   matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val);
45
 
46
#define matrix_test_next(x)      (x + 1)
47
#define matrix_clip(x, y)        ((y) ? (x)&0x0ff : (x)&0x0ffff)
48
#define matrix_big(x)            (0xf000 | (x))
49
#define bit_extract(x, from, to) (((x) >> (from)) & (~(0xffffffff << (to))))
50
 
51
#if CORE_DEBUG
52
void
53
printmat(MATDAT *A, ee_u32 N, char *name)
54
{
55
    ee_u32 i, j;
56
    ee_printf("Matrix %s [%dx%d]:\n", name, N, N);
57
    for (i = 0; i < N; i++)
58
    {
59
        for (j = 0; j < N; j++)
60
        {
61
            if (j != 0)
62
                ee_printf(",");
63
            ee_printf("%d", A[i * N + j]);
64
        }
65
        ee_printf("\n");
66
    }
67
}
68
void
69
printmatC(MATRES *C, ee_u32 N, char *name)
70
{
71
    ee_u32 i, j;
72
    ee_printf("Matrix %s [%dx%d]:\n", name, N, N);
73
    for (i = 0; i < N; i++)
74
    {
75
        for (j = 0; j < N; j++)
76
        {
77
            if (j != 0)
78
                ee_printf(",");
79
            ee_printf("%d", C[i * N + j]);
80
        }
81
        ee_printf("\n");
82
    }
83
}
84
#endif
85
/* Function: core_bench_matrix
86
        Benchmark function
87
 
88
        Iterate <matrix_test> N times,
89
        changing the matrix values slightly by a constant amount each time.
90
*/
91
ee_u16
92
core_bench_matrix(mat_params *p, ee_s16 seed, ee_u16 crc)
93
{
94
    ee_u32  N   = p->N;
95
    MATRES *C   = p->C;
96
    MATDAT *A   = p->A;
97
    MATDAT *B   = p->B;
98
    MATDAT  val = (MATDAT)seed;
99
 
100
    crc = crc16(matrix_test(N, C, A, B, val), crc);
101
 
102
    return crc;
103
}
104
 
105
/* Function: matrix_test
106
        Perform matrix manipulation.
107
 
108
        Parameters:
109
        N - Dimensions of the matrix.
110
        C - memory for result matrix.
111
        A - input matrix
112
        B - operator matrix (not changed during operations)
113
 
114
        Returns:
115
        A CRC value that captures all results calculated in the function.
116
        In particular, crc of the value calculated on the result matrix
117
        after each step by <matrix_sum>.
118
 
119
        Operation:
120
 
121
        1 - Add a constant value to all elements of a matrix.
122
        2 - Multiply a matrix by a constant.
123
        3 - Multiply a matrix by a vector.
124
        4 - Multiply a matrix by a matrix.
125
        5 - Add a constant value to all elements of a matrix.
126
 
127
        After the last step, matrix A is back to original contents.
128
*/
129
ee_s16
130
matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val)
131
{
132
    ee_u16 crc     = 0;
133
    MATDAT clipval = matrix_big(val);
134
 
135
    matrix_add_const(N, A, val); /* make sure data changes  */
136
#if CORE_DEBUG
137
    printmat(A, N, "matrix_add_const");
138
#endif
139
    matrix_mul_const(N, C, A, val);
140
    crc = crc16(matrix_sum(N, C, clipval), crc);
141
#if CORE_DEBUG
142
    printmatC(C, N, "matrix_mul_const");
143
#endif
144
    matrix_mul_vect(N, C, A, B);
145
    crc = crc16(matrix_sum(N, C, clipval), crc);
146
#if CORE_DEBUG
147
    printmatC(C, N, "matrix_mul_vect");
148
#endif
149
    matrix_mul_matrix(N, C, A, B);
150
    crc = crc16(matrix_sum(N, C, clipval), crc);
151
#if CORE_DEBUG
152
    printmatC(C, N, "matrix_mul_matrix");
153
#endif
154
    matrix_mul_matrix_bitextract(N, C, A, B);
155
    crc = crc16(matrix_sum(N, C, clipval), crc);
156
#if CORE_DEBUG
157
    printmatC(C, N, "matrix_mul_matrix_bitextract");
158
#endif
159
 
160
    matrix_add_const(N, A, -val); /* return matrix to initial value */
161
    return crc;
162
}
163
 
164
/* Function : matrix_init
165
        Initialize the memory block for matrix benchmarking.
166
 
167
        Parameters:
168
        blksize - Size of memory to be initialized.
169
        memblk - Pointer to memory block.
170
        seed - Actual values chosen depend on the seed parameter.
171
        p - pointers to <mat_params> containing initialized matrixes.
172
 
173
        Returns:
174
        Matrix dimensions.
175
 
176
        Note:
177
        The seed parameter MUST be supplied from a source that cannot be
178
   determined at compile time
179
*/
180
ee_u32
181
core_init_matrix(ee_u32 blksize, void *memblk, ee_s32 seed, mat_params *p)
182
{
183
    ee_u32  N = 0;
184
    MATDAT *A;
185
    MATDAT *B;
186
    ee_s32  order = 1;
187
    MATDAT  val;
188
    ee_u32  i = 0, j = 0;
189
    if (seed == 0)
190
        seed = 1;
191
    while (j < blksize)
192
    {
193
        i++;
194
        j = i * i * 2 * 4;
195
    }
196
    N = i - 1;
197
    A = (MATDAT *)align_mem(memblk);
198
    B = A + N * N;
199
 
200
    for (i = 0; i < N; i++)
201
    {
202
        for (j = 0; j < N; j++)
203
        {
204
            seed         = ((order * seed) % 65536);
205
            val          = (seed + order);
206
            val          = matrix_clip(val, 0);
207
            B[i * N + j] = val;
208
            val          = (val + order);
209
            val          = matrix_clip(val, 1);
210
            A[i * N + j] = val;
211
            order++;
212
        }
213
    }
214
 
215
    p->A = A;
216
    p->B = B;
217
    p->C = (MATRES *)align_mem(B + N * N);
218
    p->N = N;
219
#if CORE_DEBUG
220
    printmat(A, N, "A");
221
    printmat(B, N, "B");
222
#endif
223
    return N;
224
}
225
 
226
/* Function: matrix_sum
227
        Calculate a function that depends on the values of elements in the
228
   matrix.
229
 
230
        For each element, accumulate into a temporary variable.
231
 
232
        As long as this value is under the parameter clipval,
233
        add 1 to the result if the element is bigger then the previous.
234
 
235
        Otherwise, reset the accumulator and add 10 to the result.
236
*/
237
ee_s16
238
matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval)
239
{
240
    MATRES tmp = 0, prev = 0, cur = 0;
241
    ee_s16 ret = 0;
242
    ee_u32 i, j;
243
    for (i = 0; i < N; i++)
244
    {
245
        for (j = 0; j < N; j++)
246
        {
247
            cur = C[i * N + j];
248
            tmp += cur;
249
            if (tmp > clipval)
250
            {
251
                ret += 10;
252
                tmp = 0;
253
            }
254
            else
255
            {
256
                ret += (cur > prev) ? 1 : 0;
257
            }
258
            prev = cur;
259
        }
260
    }
261
    return ret;
262
}
263
 
264
/* Function: matrix_mul_const
265
        Multiply a matrix by a constant.
266
        This could be used as a scaler for instance.
267
*/
268
void
269
matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val)
270
{
271
    ee_u32 i, j;
272
    for (i = 0; i < N; i++)
273
    {
274
        for (j = 0; j < N; j++)
275
        {
276
            C[i * N + j] = (MATRES)A[i * N + j] * (MATRES)val;
277
        }
278
    }
279
}
280
 
281
/* Function: matrix_add_const
282
        Add a constant value to all elements of a matrix.
283
*/
284
void
285
matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val)
286
{
287
    ee_u32 i, j;
288
    for (i = 0; i < N; i++)
289
    {
290
        for (j = 0; j < N; j++)
291
        {
292
            A[i * N + j] += val;
293
        }
294
    }
295
}
296
 
297
/* Function: matrix_mul_vect
298
        Multiply a matrix by a vector.
299
        This is common in many simple filters (e.g. fir where a vector of
300
   coefficients is applied to the matrix.)
301
*/
302
void
303
matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B)
304
{
305
    ee_u32 i, j;
306
    for (i = 0; i < N; i++)
307
    {
308
        C[i] = 0;
309
        for (j = 0; j < N; j++)
310
        {
311
            C[i] += (MATRES)A[i * N + j] * (MATRES)B[j];
312
        }
313
    }
314
}
315
 
316
/* Function: matrix_mul_matrix
317
        Multiply a matrix by a matrix.
318
        Basic code is used in many algorithms, mostly with minor changes such as
319
   scaling.
320
*/
321
void
322
matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B)
323
{
324
    ee_u32 i, j, k;
325
    for (i = 0; i < N; i++)
326
    {
327
        for (j = 0; j < N; j++)
328
        {
329
            C[i * N + j] = 0;
330
            for (k = 0; k < N; k++)
331
            {
332
                C[i * N + j] += (MATRES)A[i * N + k] * (MATRES)B[k * N + j];
333
            }
334
        }
335
    }
336
}
337
 
338
/* Function: matrix_mul_matrix_bitextract
339
        Multiply a matrix by a matrix, and extract some bits from the result.
340
        Basic code is used in many algorithms, mostly with minor changes such as
341
   scaling.
342
*/
343
void
344
matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B)
345
{
346
    ee_u32 i, j, k;
347
    for (i = 0; i < N; i++)
348
    {
349
        for (j = 0; j < N; j++)
350
        {
351
            C[i * N + j] = 0;
352
            for (k = 0; k < N; k++)
353
            {
354
                MATRES tmp = (MATRES)A[i * N + k] * (MATRES)B[k * N + j];
355
                C[i * N + j] += bit_extract(tmp, 2, 4) * bit_extract(tmp, 5, 7);
356
            }
357
        }
358
    }
359
}

powered by: WebSVN 2.1.0

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