ae2f_docs
Conv.c
Go to the documentation of this file.
1#include <ae2f/Ann/Conv.h>
2#include <stdio.h>
3#include <memory.h>
4
6
7/** @brief SUPER SMALL NUMBER that I would not care when comparing */
8#define EPSILON 0.000001
9
10size_t i, j, a, el;
11ae2f_err_t e[1] = {0};
12
13size_t test_mMMapFieldIdx(const ae2f_mMMap *const mmap, const size_t dim, const size_t *const idxs)
14{
15 size_t ret;
16 ae2f_mMMapFieldIdx(mmap, dim, idxs, &ret);
17 return ret;
18}
19
20uint64_t Conv1dTestNoPad() {
21 uint64_t r = 0;
22
23 ae2f_mMMap
24 * input
25 , * kernel
26 , * output;
27
28 size_t inputsz = 10, kernelsz = 3, outsz = 8, stride = 1, padding = 0;
29
30 ae2f_mMMapMk(1, &inputsz, e, &input);
31 ae2f_mMMapMk(1, &kernelsz, e, &kernel);
32 ae2f_mMMapMk(1, &outsz, e, &output);
33
34 assert(!(*e));
35
36 for(i = 0; i < inputsz; i++) {
37 ae2f_mMMapField(input)[i] = i + 1;
38 }
39
40 ae2f_mMMapField(kernel)[0] = 0.5;
41 ae2f_mMMapField(kernel)[1] = 0.3;
42 ae2f_mMMapField(kernel)[2] = 0.2;
43
46 , inputsz
47 , ae2f_mMMapField(kernel)
48 , kernelsz
49 , ae2f_mMMapField(output)
50 , NULL, stride
51 , padding
52 );
53
55 matchbuff = 0
56 , targets[] = {
57 1.7,
58 2.7,
59 3.7,
60 4.7,
61 5.7,
62 6.7,
63 7.7,
64 8.7
65 };
66 for(i = 0; i < outsz; i++)
67 {
68 (matchbuff = ae2f_mMMapField(
69 output
70 , const
71 )[i]);
72
73 printf(
74 "Match: %f %f\n"
75 , matchbuff
76
77 , targets[i]
78 );
79
80 if (
81 (targets[i] - matchbuff)
82 * (targets[i] - matchbuff)
83
84 > EPSILON) {
85 puts("Match none");
86 r = 1;
87 }
88 }
89
90 ae2f_mMMapDel(kernel);
91 ae2f_mMMapDel(output);
92 ae2f_mMMapDel(input);
93
94 return r;
95}
96
97uint64_t Conv1dTestWithPad() {
98 uint64_t r = 0;
99
100 ae2f_mMMap
101 * input
102 , * kernel
103 , * output;
104
105 size_t inputsz = 6, kernelsz = 3, outsz = 8, stride = 1, padding = 2;
106
107 ae2f_mMMapMk(1, &inputsz, e, &input);
108 ae2f_mMMapMk(1, &kernelsz, e, &kernel);
109 ae2f_mMMapMk(1, &outsz, e, &output);
110
111 assert(!(*e));
112
113 for(i = 0; i < inputsz; i++) {
114 ae2f_mMMapField(input)[i] = i + 1;
115 }
116
117 ae2f_mMMapField(kernel)[0] = 0.5;
118 ae2f_mMMapField(kernel)[1] = 0.3;
119 ae2f_mMMapField(kernel)[2] = 0.2;
120
121 // 0, 0, 1, 2, 3, 4, 5, 6, 0, 0
123 ae2f_mMMapField(input)
124 , inputsz
125
126 , ae2f_mMMapField(kernel)
127 , kernelsz
128 , ae2f_mMMapField(output)
129 , NULL, stride, padding
130 );
131
133 matchbuff = 0
134 , targets[] = {
135 0.2, 0.7, 1.7, 2.7, 3.7, 4.7, 4.3, 3
136 };
137 for(i = 0; i < outsz; i++)
138 {
139 printf(
140 "Match: %f %f\n"
141 , (matchbuff = ae2f_mMMapField(
142 output
143 , const
144 )[i])
145 , targets[i]
146 );
147
148 if (
149 (targets[i] - matchbuff)
150 * (targets[i] - matchbuff)
151
152 > EPSILON) {
153 puts("Match none");
154 r = 2;
155 }
156 }
157
158 ae2f_mMMapDel(kernel);
159 ae2f_mMMapDel(output);
160 ae2f_mMMapDel(input);
161
162 return r;
163}
164
165uint64_t Conv2DTest() {
166 puts("Conv2DTest start");
167
168 ae2f_mMMap
169 * input
170 , * kernel
171 , * output;
172
173 size_t
174 inputsz[2] = {4, 4},
175 kernelsz[2] = {3, 3},
176 outsz[2] = {2, 2},
177 stride[2] = { 1, 1 };
178
179 size_t idxbuff[2] = {0, 0};
180 ae2f_float_t kernelelbuff[3] = { 0, };
181
182 ae2f_mMMapMk(2, inputsz, e, &input);
183 ae2f_mMMapMk(2, kernelsz, e, &kernel);
184 ae2f_mMMapMk(2, outsz, e, &output);
185 assert(!(*e));
186
187 puts("obj has made");
188
189 for(i = 0, el = 1; i < 4; i++)
190 for(j = 0; j < 4; j++) {
191 idxbuff[1] = i;
192 idxbuff[0] = j;
193
194 ae2f_mMMapField(input)[test_mMMapFieldIdx(input, 2, idxbuff)]
195 = el++;
196 }
197
198 puts("field");
199
200 kernelelbuff[0] = 1;
201 kernelelbuff[1] = 0;
202 kernelelbuff[2] = -1;
203
204 idxbuff[0] = 0;
205 idxbuff[1] = 2;
206
207
208 puts("buff has made");
209
210 memcpy(
211 ae2f_mMMapField(kernel)
212 , kernelelbuff
213 , sizeof(ae2f_float_t) * 3
214 );
215
216 memcpy(
217 ae2f_mMMapField(kernel) + test_mMMapFieldIdx(kernel, 2, idxbuff)
218 , kernelelbuff
219 , sizeof(ae2f_float_t) * 3
220 );
221
222 idxbuff[1] = 1;
223 kernelelbuff[0] = 2;
224 kernelelbuff[1] = 0;
225 kernelelbuff[2] = -2;
226
227 memcpy(
228 ae2f_mMMapField(kernel) + test_mMMapFieldIdx(kernel, 2, idxbuff)
229 , kernelelbuff
230 , sizeof(ae2f_float_t) * 3
231 );
232
233
234 for(i = 0, el = 1; i < 3; i++) {
235 for(j = 0; j < 3; j++) {
236 idxbuff[1] = i;
237 idxbuff[0] = j;
238
239
240 printf("%lu "
241 , test_mMMapFieldIdx(
242 kernel,
243 2,
244 idxbuff
245 )
246 );
247 printf(
248 "%f "
249 , ae2f_mMMapField(kernel)[test_mMMapFieldIdx(
250 kernel,
251 2,
252 idxbuff
253 )]
254 );
255 }
256 printf("\n");
257 }
258
259
260 puts("__ae2f_AnnConv");
262 2
265 , ae2f_mMMapField(output), 0, 0
266 , stride, 0
267 );
268
269 ae2f_float_t target[2][2] = {
270 {-8., -8.}
271 , {-8., -8.}
272 };
273
274 for(a = 0; a < sizeof(target) / sizeof(**target); a++) {
275 printf("Check: %f %f\n", ae2f_mMMapField(output)[a], target[0][a]);
276 if(
277 ((ae2f_mMMapField(output)[a] - target[0][a])
278 * (ae2f_mMMapField(output)[a] - target[0][a]))
279 > EPSILON
280 )
281 { puts("Match None"); assert("Match None"); }
282 }
283
284 ae2f_mMMapDel(input);
285 ae2f_mMMapDel(kernel);
286 ae2f_mMMapDel(output);
287
288 return 0;
289}
290
291
292uint64_t Pool1dTest()
293{
294 puts("Pool1dTest");
295 ae2f_err_t e = 0;
296
297 /* Define input vector and parameters */
298 ae2f_float_t inv[5] = {1.0, 2.0, 3.0, 4.0, 5.0};
299 size_t inc = 5;
300 size_t window = 2;
301 size_t stride = 2;
303 outv[2] = {0, 0}, /* Output vector */
304 outv_expected[4][2] = {
305 {2, 4}, /* MAX */
306 {1, 3}, /* MIN */
307 {3, 7}, /* ADD */
308 {1.5, 3.5} /* AVG */
309 };
310
311 size_t outc; /* Output size */
312
313 /* Array of pooling types and their names for iteration */
314 ae2f_eAnnCnnPool types[] = {
319 };
320 const char* type_names[] = {
321 "MAX", "MIN", "ADD", "AVG", "MIDDLE"
322 };
323 int num_types = sizeof(types) / sizeof(types[0]);
324
325 /* Test each pooling type */
326 for (i = 0; i < num_types; i++) {
327 /* Reset output vector to zeros */
328 outv[0] = 0.0;
329 outv[1] = 0.0;
330
331 /* Call the function */
332 e = ae2f_AnnCnnPool1d(inv, inc, outv, &outc, window, stride, types[i]);
333
334
335 /* Check and print results */
336 if (e == 0) {
337 printf("%s Pooling: outc = %zu, outv = [%f, %f]\n",
338 type_names[i], outc, outv[0], outv[1]);
339
340 if(
341 ((outv[0] - outv_expected[i][0])
342 * (outv[0] - outv_expected[i][0])
343 > EPSILON)
344
345 || ((outv[1] - outv_expected[i][1])
346 * (outv[1] - outv_expected[i][1])
347 > EPSILON)
348
349 ) {
350 printf("Mismatch: Expected value: %f, %f\n"
351 , outv_expected[i][0]
352 , outv_expected[i][1]
353 );
354 return 8;
355 }
356 } else {
357 printf("%s Pooling: Error occurred: %d\n", type_names[i], e);
358 return 8;
359 }
360 }
361
362 return 0;
363}
364
365uint64_t Pool2dTest() {
366 puts("Pool2dTest START");
367
368 /* Input 4x4 grid, flattened in row-major order */
369 ae2f_float_t inv[16] = {
370 1, 2, 3, 4,
371 5, 6, 7, 8,
372 9, 10, 11, 12,
373 13, 14, 15, 16
374 };
375
376 /* Input dimensions: 4x4 */
377 size_t inc[2] = {4, 4};
378
379 /* Window size: 2x2 */
380 size_t window_opt[2] = {2, 2};
381
382 /* Stride: 2x2 */
383 size_t stride_opt[2] = {2, 2};
384
385 /* Output array (allocate for 2x2 = 4 elements) */
386 ae2f_float_t outv[4] = {0, 0, 0, 0};
387
388 /* Variable to store computed output size */
389 size_t outc = 0;
390
391 /* Error code */
392 ae2f_err_t err = 0;
393
394 /* Test MAX pooling */
395 err = ae2f_AnnCnnPool(2, inv, inc, 0, outv, 0, 0, window_opt, 0, stride_opt, ae2f_eAnnCnnPool_MAX);
396 if (err == 0) {
397 printf("MAX Pooling: outc = %zu, outv = [%f, %f, %f, %f]\n",
398 outc, outv[0], outv[1], outv[2], outv[3]);
399
400
401 ae2f_float_t tar[] = {6., 8., 14., 16.};
402 for(i = 0; i < sizeof(tar)/ sizeof(tar[0]);i++)
403 {
404 printf("Match test %lu\n", i);
405 if((tar[i] - outv[i]) * (tar[i] - outv[i]) > EPSILON)
406 {
407 printf("Mismatch: %f, %f\n", tar[i], outv[i]);
408 return 16;
409 }
410 }
411
412 } else {
413 printf("MAX Pooling Error: %d\n", err);
414 return 16;
415 }
416
417 outv[0] = outv[1] = outv[2] = outv[3] = 0;
418
419 /* Test AVG pooling */
420 err = ae2f_AnnCnnPool(2, inv, inc, 0, outv, 0, 0, window_opt, 0, stride_opt, ae2f_eAnnCnnPool_AVG);
421 if (err == 0) {
422 printf("AVG Pooling: outc = %zu, outv = [%f, %f, %f, %f]\n",
423 outc, outv[0], outv[1], outv[2], outv[3]);
424
425
426 ae2f_float_t tar[] = {3.5, 5.5, 11.5, 13.5};
427 for(i = 0; i < sizeof(tar)/ sizeof(tar[0]);i++)
428 {
429 if((tar[i] - outv[i]) * (tar[i] - outv[i]) > EPSILON)
430 {
431 printf("Mismatch: %f, %f\n", tar[i], outv[i]);
432 return 16;
433 }
434 }
435
436 } else {
437 printf("AVG Pooling Error: %d\n", err);
438 return 16;
439 }
440
441 return 0;
442}
443
444int main() {
445 uint64_t
446 a =
447 Conv1dTestNoPad()
448 | Conv1dTestWithPad()
449 | Conv2DTest()
450 | Pool1dTest()
451 | Pool2dTest()
452 | 0
453 ;
454
455 printf("Check 0: %lu\n", a);
456
457 return a;
458}
459
460#else
461
462int main() { return 0; }
463
464#endif
@ ae2f_eAnnCnnPool_MAX
Max.
Definition Conv.h:51
@ ae2f_eAnnCnnPool_MIN
Min.
Definition Conv.h:54
@ ae2f_eAnnCnnPool_ADD
Add.
Definition Conv.h:57
@ ae2f_eAnnCnnPool_AVG
Average.
Definition Conv.h:60
ae2f_extern ae2f_SHAREDEXPORT ae2f_err_t ae2f_AnnCnnPool1d(const ae2f_float_t *inv, const size_t inc, ae2f_float_t *outv, size_t *opt_outc, const size_t window, const size_t stride, ae2f_eAnnCnnPool type) noexcept
Definition Conv.imp.c:124
ae2f_extern ae2f_SHAREDEXPORT ae2f_err_t ae2f_AnnCnnPool(size_t dim, const ae2f_float_t *inv, const size_t *inc, size_t incc, ae2f_float_t *outv, size_t *opt_outc, size_t outcc, const size_t *window_opt, size_t windowcc, const size_t *stride_opt, ae2f_eAnnCnnPool type)
Definition Conv.imp.c:350
ae2f_SHAREDEXPORT ae2f_err_t ae2f_AnnCnnConv1d(const ae2f_float_t *infv, size_t infc, const ae2f_float_t *ingv, size_t ingc, ae2f_float_t *outv, size_t *opt_outc, size_t stride, size_t pad)
all vectors are suggested initiated as 0.
Definition Conv.imp.c:69
ae2f_SHAREDEXPORT ae2f_err_t ae2f_AnnCnnConv(size_t dim, const ae2f_float_t *infv, const size_t *infc, size_t infcc, const ae2f_float_t *ingv, const size_t *ingc, size_t ingcc, ae2f_float_t *outv, size_t *outc_opt, size_t outcc, const size_t *stride_opt, const size_t *pad_opt)
dim must be the dimension of mmaps, lengths of lists. This function is meant to be recursive....
Definition Conv.imp.c:210
ae2f_float ae2f_float_t
Definition Float.h:38
#define ae2f_MAC_BUILD
Definition Util.h:4
#define ae2f_mMMapDimLen(mmap,...)
Length vector for every dimension index.
Definition MMap.auto.h:104
#define ae2f_mMMapField(mmap,...)
Definition MMap.auto.h:108
ae2f_extern ae2f_SHAREDCALL void ae2f_mMMapMk(const size_t dim, const size_t *const lens, ae2f_err_t *const opt_ret_err, ae2f_FREE(free, ae2f_mMMapDel) ae2f_mMMap **const ret_mmap) noexcept
ae2f_extern ae2f_SHAREDCALL void ae2f_mMMapDel(ae2f_mMMap *mmap)
Definition MMap.imp.c:46
ae2f_extern ae2f_SHAREDCALL void ae2f_mMMapFieldIdx(const ae2f_mMMap *const mmap, const size_t dim, const size_t *const idxs, size_t *const ret)
Definition MMap.imp.c:14
ae2f_addrel_t el
Definition WaitWake.c:6
uint8_t ae2f_err_t
Informs that this number represents the error.
Definition errGlob.h:19