/home/liu/actions-runner/_work/ccv/ccv/test/unit/nnc/winograd.tests.c
Line | Count | Source |
1 | | #include "case.h" |
2 | | #include "ccv_case.h" |
3 | | #include "ccv_nnc_case.h" |
4 | | #include <ccv.h> |
5 | | #include <nnc/ccv_nnc.h> |
6 | | #include <nnc/ccv_nnc_easy.h> |
7 | | #include <3rdparty/dsfmt/dSFMT.h> |
8 | | |
9 | | TEST_SETUP() |
10 | | { |
11 | | ccv_nnc_init(); |
12 | | } |
13 | | |
14 | | TEST_CASE("convolutional network of 3x3 on 56x56 with non-uniform weights") |
15 | 1 | { |
16 | 1 | ccv_nnc_tensor_t* a = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 56, 56, 128), 0); |
17 | 1 | ccv_nnc_tensor_t* b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 56, 56, 128), 0); |
18 | 1 | ccv_nnc_cmd_t cmd = CMD_CONVOLUTION_FORWARD(1, 128, 3, 3, 128); |
19 | 1 | ccv_nnc_hint_t hint = ccv_nnc_hint_auto(cmd.info, a->info, b->info); |
20 | 1 | ccv_nnc_tensor_t* w = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 128, 3, 3, 128), 0); |
21 | 1 | ccv_nnc_tensor_t* bias = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 128), 0); |
22 | | // configure the inlets. |
23 | 1 | dsfmt_t dsfmt; |
24 | 1 | dsfmt_init_gen_rand(&dsfmt, 0); |
25 | 1 | int i; |
26 | 147k | for (i = 0; i < 128 * 3 * 3 * 128; i++147k ) |
27 | 147k | w->data.f32[i] = dsfmt_genrand_open_close(&dsfmt) / (3 * 3 * 128); |
28 | 401k | for (i = 0; i < 56 * 56 * 128; i++401k ) |
29 | 401k | a->data.f32[i] = dsfmt_genrand_open_close(&dsfmt); |
30 | 129 | for (i = 0; i < 128; i++128 ) |
31 | 128 | bias->data.f32[i] = (float)i / 128; |
32 | 1 | ccv_nnc_cmd_exec(cmd, hint, 0, TENSOR_LIST(a, w, bias), TENSOR_LIST(b), 0); |
33 | 1 | ccv_nnc_tensor_t* c = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 56, 56, 128), 0); |
34 | 1 | cmd.backend = CCV_NNC_BACKEND_CPU_OPT; |
35 | 1 | cmd.algorithm = 2; // CCV_NNC_CMD_OPT_CONV_ALGO_WINOGRAD |
36 | 1 | ccv_nnc_cmd_exec(cmd, hint, 0, TENSOR_LIST(a, w, bias), TENSOR_LIST(c), 0); |
37 | 1 | REQUIRE_TENSOR_EQ(b, c, "56x56 matrix should be exactly the same from reference implementation and winograd."); |
38 | 1 | ccv_nnc_tensor_free(c); |
39 | 1 | ccv_nnc_tensor_free(bias); |
40 | 1 | ccv_nnc_tensor_free(w); |
41 | 1 | ccv_nnc_tensor_free(b); |
42 | 1 | ccv_nnc_tensor_free(a); |
43 | 1 | } |
44 | | |
45 | | TEST_CASE("convolutional network of 3x3 on 55x55 with non-uniform weights") |
46 | 1 | { |
47 | 1 | ccv_nnc_tensor_t* a = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 55, 55, 128), 0); |
48 | 1 | ccv_nnc_tensor_t* b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 55, 55, 128), 0); |
49 | 1 | ccv_nnc_cmd_t cmd = CMD_CONVOLUTION_FORWARD(1, 128, 3, 3, 128); |
50 | 1 | ccv_nnc_hint_t hint = ccv_nnc_hint_auto(cmd.info, a->info, b->info); |
51 | 1 | ccv_nnc_tensor_t* w = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 128, 3, 3, 128), 0); |
52 | 1 | ccv_nnc_tensor_t* bias = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 128), 0); |
53 | | // configure the inlets. |
54 | 1 | dsfmt_t dsfmt; |
55 | 1 | dsfmt_init_gen_rand(&dsfmt, 0); |
56 | 1 | int i; |
57 | 147k | for (i = 0; i < 128 * 3 * 3 * 128; i++147k ) |
58 | 147k | w->data.f32[i] = dsfmt_genrand_open_close(&dsfmt) / (3 * 3 * 128); |
59 | 387k | for (i = 0; i < 55 * 55 * 128; i++387k ) |
60 | 387k | a->data.f32[i] = dsfmt_genrand_open_close(&dsfmt); |
61 | 129 | for (i = 0; i < 128; i++128 ) |
62 | 128 | bias->data.f32[i] = (float)i / 128; |
63 | 1 | ccv_nnc_cmd_exec(cmd, hint, 0, TENSOR_LIST(a, w, bias), TENSOR_LIST(b), 0); |
64 | 1 | ccv_nnc_tensor_t* c = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 55, 55, 128), 0); |
65 | 1 | cmd.backend = CCV_NNC_BACKEND_CPU_OPT; |
66 | 1 | cmd.algorithm = 2; // CCV_NNC_CMD_OPT_CONV_ALGO_WINOGRAD |
67 | 1 | ccv_nnc_cmd_exec(cmd, hint, 0, TENSOR_LIST(a, w, bias), TENSOR_LIST(c), 0); |
68 | 1 | REQUIRE_TENSOR_EQ(b, c, "55x55 matrix should be exactly the same from reference implementation and winograd."); |
69 | 1 | ccv_nnc_tensor_free(c); |
70 | 1 | ccv_nnc_tensor_free(bias); |
71 | 1 | ccv_nnc_tensor_free(w); |
72 | 1 | ccv_nnc_tensor_free(b); |
73 | 1 | ccv_nnc_tensor_free(a); |
74 | 1 | } |
75 | | |
76 | | TEST_CASE("convolutional network of 3x3 on 224x224 with non-uniform weights and RGB channels") |
77 | 1 | { |
78 | 1 | ccv_nnc_tensor_t* a = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 224, 224, 3), 0); |
79 | 1 | ccv_nnc_tensor_t* b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 224, 224, 128), 0); |
80 | 1 | ccv_nnc_cmd_t cmd = CMD_CONVOLUTION_FORWARD(1, 128, 3, 3, 3); |
81 | 1 | ccv_nnc_hint_t hint = ccv_nnc_hint_auto(cmd.info, a->info, b->info); |
82 | 1 | ccv_nnc_tensor_t* w = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 128, 3, 3, 3), 0); |
83 | 1 | ccv_nnc_tensor_t* bias = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 128), 0); |
84 | | // configure the inlets. |
85 | 1 | dsfmt_t dsfmt; |
86 | 1 | dsfmt_init_gen_rand(&dsfmt, 0); |
87 | 1 | int i; |
88 | 3.45k | for (i = 0; i < 3 * 3 * 3 * 128; i++3.45k ) |
89 | 3.45k | w->data.f32[i] = dsfmt_genrand_open_close(&dsfmt) / (3 * 3 * 3); |
90 | 150k | for (i = 0; i < 224 * 224 * 3; i++150k ) |
91 | 150k | a->data.f32[i] = dsfmt_genrand_open_close(&dsfmt); |
92 | 129 | for (i = 0; i < 128; i++128 ) |
93 | 128 | bias->data.f32[i] = (float)i / 128; |
94 | 1 | ccv_nnc_cmd_exec(cmd, hint, 0, TENSOR_LIST(a, w, bias), TENSOR_LIST(b), 0); |
95 | 1 | ccv_nnc_tensor_t* c = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 224, 224, 128), 0); |
96 | 1 | cmd.backend = CCV_NNC_BACKEND_CPU_OPT; |
97 | 1 | cmd.algorithm = 2; // CCV_NNC_CMD_OPT_CONV_ALGO_WINOGRAD |
98 | 1 | ccv_nnc_cmd_exec(cmd, hint, 0, TENSOR_LIST(a, w, bias), TENSOR_LIST(c), 0); |
99 | 1 | REQUIRE_TENSOR_EQ(b, c, "224x224 matrix should be exactly the same from reference implementation and winograd."); |
100 | 1 | ccv_nnc_tensor_free(c); |
101 | 1 | ccv_nnc_tensor_free(bias); |
102 | 1 | ccv_nnc_tensor_free(w); |
103 | 1 | ccv_nnc_tensor_free(b); |
104 | 1 | ccv_nnc_tensor_free(a); |
105 | 1 | } |
106 | | |
107 | | TEST_CASE("convolutional network of 3x3 on 56x56 with no bias") |
108 | 1 | { |
109 | 1 | ccv_nnc_tensor_t* a = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 56, 56, 128), 0); |
110 | 1 | ccv_nnc_tensor_t* b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 56, 56, 128), 0); |
111 | 1 | ccv_nnc_cmd_t cmd = CMD_CONVOLUTION_FORWARD(1, 128, 3, 3, 128); |
112 | 1 | ccv_nnc_hint_t hint = ccv_nnc_hint_auto(cmd.info, a->info, b->info); |
113 | 1 | ccv_nnc_tensor_t* w = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 128, 3, 3, 128), 0); |
114 | 1 | ccv_nnc_tensor_t* bias = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 128), 0); |
115 | | // configure the inlets. |
116 | 1 | dsfmt_t dsfmt; |
117 | 1 | dsfmt_init_gen_rand(&dsfmt, 0); |
118 | 1 | int i; |
119 | 147k | for (i = 0; i < 128 * 3 * 3 * 128; i++147k ) |
120 | 147k | w->data.f32[i] = dsfmt_genrand_open_close(&dsfmt) / (3 * 3 * 128); |
121 | 401k | for (i = 0; i < 56 * 56 * 128; i++401k ) |
122 | 401k | a->data.f32[i] = dsfmt_genrand_open_close(&dsfmt); |
123 | 129 | for (i = 0; i < 128; i++128 ) |
124 | 128 | bias->data.f32[i] = 0; |
125 | 1 | ccv_nnc_cmd_exec(cmd, hint, 0, TENSOR_LIST(a, w, bias), TENSOR_LIST(b), 0); |
126 | 1 | ccv_nnc_tensor_t* c = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 56, 56, 128), 0); |
127 | 1 | cmd.backend = CCV_NNC_BACKEND_CPU_OPT; |
128 | 1 | cmd.algorithm = 2; // CCV_NNC_CMD_OPT_CONV_ALGO_WINOGRAD |
129 | 1 | ccv_nnc_cmd_exec(cmd, hint, 0, TENSOR_LIST(a, w), TENSOR_LIST(c), 0); |
130 | 1 | REQUIRE_TENSOR_EQ(b, c, "56x56 matrix should be exactly the same from reference implementation and winograd."); |
131 | 1 | ccv_nnc_tensor_free(c); |
132 | 1 | ccv_nnc_tensor_free(bias); |
133 | 1 | ccv_nnc_tensor_free(w); |
134 | 1 | ccv_nnc_tensor_free(b); |
135 | 1 | ccv_nnc_tensor_free(a); |
136 | 1 | } |
137 | | |
138 | | #include "case_main.h" |