Bug Summary

File:nnc/ccv_cnnp_model_addons.c
Warning:line 236, column 2
Declared variable-length array (VLA) has negative size

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ccv_cnnp_model_addons.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -target-feature +sse2 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/liu/buildslave/linux-x64-runtests/build/lib/nnc -resource-dir /usr/local/lib/clang/14.0.0 -I ../ -I /usr/local/cuda/include -D HAVE_CBLAS -D HAVE_LIBPNG -D HAVE_LIBJPEG -D HAVE_FFTW3 -D HAVE_PTHREAD -D HAVE_LIBLINEAR -D HAVE_TESSERACT -D HAVE_AVCODEC -D HAVE_AVFORMAT -D HAVE_AVUTIL -D HAVE_SWSCALE -D USE_DISPATCH -D HAVE_SSE2 -D HAVE_GSL -D HAVE_CUDA -D HAVE_CUDNN -D HAVE_NCCL -D USE_SYSTEM_CUB -I /usr/local/include -internal-isystem /usr/local/lib/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/9/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -fdebug-compilation-dir=/home/liu/buildslave/linux-x64-runtests/build/lib/nnc -ferror-limit 19 -fblocks -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/liu/buildslave/public_html/analyze/2022-06-22-151334-490440-1 -x c ccv_cnnp_model_addons.c
1#include "ccv_nnc.h"
2#include "ccv_nnc_easy.h"
3#include "ccv_nnc_internal.h"
4#include "ccv_internal.h"
5#include "_ccv_cnnp_model.h"
6
7// MARK - Add-on Functions
8
9static int _ccv_cnnp_model_clip_grad_norm_reduce_norm2(const ccv_nnc_cmd_t cmd, const ccv_nnc_hint_t hint, const int flags, ccv_nnc_tensor_t* const* const inputs, const int input_size, ccv_nnc_tensor_t* const* const outputs, const int output_size, ccv_nnc_stream_context_t* const stream_context)
10{
11 const int device_id = CCV_TENSOR_GET_DEVICE_ID(inputs[0]->info.type)(((inputs[0]->info.type) & 0xfff00) >> 8);
12 ccv_nnc_tensor_t* const old_norm2 = outputs[1 + device_id * 2];
13 ccv_nnc_tensor_t* const norm2 = outputs[1 + device_id * 2 + 1];
14 const int tensor_count = ccv_nnc_tensor_count(inputs[0]->info);
15 if (tensor_count == 1)
16 ccv_nnc_cmd_exec(CMD_MUL_FORWARD(1)ccv_nnc_cmd(CCV_NNC_MUL_FORWARD, 0, (ccv_nnc_cmd_param_t){.size
={.dim={1,1,1}},.blas={.a={1,}}}, 0)
, hint, flags, TENSOR_LIST(inputs[0], inputs[0])(ccv_nnc_tensor_t* []){inputs[0], inputs[0]}, (1 +1 +1 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_LIST(norm2)(ccv_nnc_tensor_t* []){norm2}, (1 +1 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, stream_context);
17 else {
18 ccv_nnc_cmd_exec(CMD_REDUCE_NORM2_FORWARD()ccv_nnc_cmd(CCV_NNC_REDUCE_NORM2_FORWARD, 0, ((ccv_nnc_cmd_param_t
){.size={.dim={1,1,1}},.reduce={.count=(1 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1),.axis={}}}
), 0)
, hint, flags, TENSOR_LIST(inputs[0])(ccv_nnc_tensor_t* []){inputs[0]}, (1 +1 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_LIST(norm2)(ccv_nnc_tensor_t* []){norm2}, (1 +1 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, stream_context);
19 ccv_nnc_cmd_exec(CMD_MUL_FORWARD(1)ccv_nnc_cmd(CCV_NNC_MUL_FORWARD, 0, (ccv_nnc_cmd_param_t){.size
={.dim={1,1,1}},.blas={.a={1,}}}, 0)
, hint, flags, TENSOR_LIST(norm2, norm2)(ccv_nnc_tensor_t* []){norm2, norm2}, (1 +1 +1 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_LIST(norm2)(ccv_nnc_tensor_t* []){norm2}, (1 +1 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, stream_context);
20 }
21 ccv_nnc_cmd_exec(CMD_ADD_FORWARD(1, 1)ccv_nnc_cmd(CCV_NNC_ADD_FORWARD, 0, (ccv_nnc_cmd_param_t){.size
={.dim={1,1,1}},.blas={.a={1, 1}}}, 0)
, hint, flags, TENSOR_LIST(old_norm2, norm2)(ccv_nnc_tensor_t* []){old_norm2, norm2}, (1 +1 +1 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_LIST(old_norm2)(ccv_nnc_tensor_t* []){old_norm2}, (1 +1 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, stream_context);
22 return CCV_NNC_EXEC_SUCCESS;
23}
24
25static ccv_nnc_cmd_vtab_t clip_grad_norm_reduce_norm2_vtab = {
26 .exec = _ccv_cnnp_model_clip_grad_norm_reduce_norm2
27};
28
29static int _ccv_cnnp_model_clip_grad_norm_scatter_norm2(const ccv_nnc_cmd_t cmd, const ccv_nnc_hint_t hint, const int flags, ccv_nnc_tensor_t* const* const inputs, const int input_size, ccv_nnc_tensor_t* const* const outputs, const int output_size, ccv_nnc_stream_context_t* const stream_context)
30{
31 const int device_id = CCV_TENSOR_GET_DEVICE_ID(inputs[0]->info.type)(((inputs[0]->info.type) & 0xfff00) >> 8);
32 ccv_nnc_tensor_t* const norm2 = inputs[1 + device_id * 2];
33 ccv_nnc_cmd_exec(CMD_MUL_FORWARD(1)ccv_nnc_cmd(CCV_NNC_MUL_FORWARD, 0, (ccv_nnc_cmd_param_t){.size
={.dim={1,1,1}},.blas={.a={1,}}}, 0)
, hint, flags, TENSOR_LIST(inputs[0], norm2)(ccv_nnc_tensor_t* []){inputs[0], norm2}, (1 +1 +1 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_LIST(outputs[0])(ccv_nnc_tensor_t* []){outputs[0]}, (1 +1 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, stream_context);
34 return CCV_NNC_EXEC_SUCCESS;
35}
36
37static ccv_nnc_cmd_vtab_t clip_grad_norm_scatter_norm2_vtab = {
38 .exec = _ccv_cnnp_model_clip_grad_norm_scatter_norm2
39};
40
41void ccv_cnnp_model_parameters_clip_grad_norm(ccv_cnnp_model_t* const model, const ccv_cnnp_model_io_t parameters, int norm_type, float max_norm, ccv_nnc_stream_context_t* const stream_context)
42{
43 assert(norm_type == 2)((void) sizeof ((norm_type == 2) ? 1 : 0), __extension__ ({ if
(norm_type == 2) ; else __assert_fail ("norm_type == 2", "ccv_cnnp_model_addons.c"
, 43, __extension__ __PRETTY_FUNCTION__); }))
;
44 ccv_cnnp_compiled_data_t* const compiled_data = model->compiled_data;
45 assert(compiled_data)((void) sizeof ((compiled_data) ? 1 : 0), __extension__ ({ if
(compiled_data) ; else __assert_fail ("compiled_data", "ccv_cnnp_model_addons.c"
, 45, __extension__ __PRETTY_FUNCTION__); }))
;
46 const int parallel_count = ccv_max(model->parallel_count, 1)({ typeof (model->parallel_count) _a = (model->parallel_count
); typeof (1) _b = (1); (_a > _b) ? _a : _b; })
;
47 ccv_nnc_tensor_t* norm2[parallel_count * 2];
48 ccv_nnc_tensor_t* max_normt[parallel_count];
49 const int stream_type = model->compiled_data->stream_type;
50 int i;
51 if (stream_type == CCV_STREAM_CONTEXT_GPU)
52 {
53 for (i = 0; i < parallel_count; i++)
54 {
55 ccv_nnc_tensor_param_t info = {
56 .type = CCV_TENSOR_GPU_MEMORY,
57 .format = CCV_TENSOR_FORMAT_NHWC,
58 .datatype = CCV_32F,
59 .dim = {1},
60 };
61 CCV_TENSOR_SET_DEVICE_ID(info.type, i)(info.type) = (((info.type) & ~0xfff00) | (((i) & 0xfff
) << 8))
;
62 norm2[i * 2] = ccv_nnc_tensor_new(ccv_nnc_xpu_alloc(&compiled_data->xpu_alloc, i, stream_context, ccv_nnc_tensor_data_size(info)), info, 0);
63 norm2[i * 2 + 1] = ccv_nnc_tensor_new(ccv_nnc_xpu_alloc(&compiled_data->xpu_alloc, i, stream_context, ccv_nnc_tensor_data_size(info)), info, 0);
64 max_normt[i] = ccv_nnc_tensor_new(ccv_nnc_xpu_alloc(&compiled_data->xpu_alloc, i, stream_context, ccv_nnc_tensor_data_size(info)), info, 0);
65 }
66 } else {
67 for (i = 0; i < parallel_count; i++)
68 {
69 ccv_nnc_tensor_param_t info = {
70 .type = CCV_TENSOR_CPU_MEMORY,
71 .format = CCV_TENSOR_FORMAT_NHWC,
72 .datatype = CCV_32F,
73 .dim = {1},
74 };
75 norm2[i * 2] = ccv_nnc_tensor_new(0, info, 0);
76 norm2[i * 2 + 1] = ccv_nnc_tensor_new(0, info, 0);
77 max_normt[i] = ccv_nnc_tensor_new(0, info, 0);
78 }
79 }
80 // zero out old norm2.
81 if (parallel_count > 1)
82 {
83 ccv_nnc_stream_context_t* streams[parallel_count];
84 ccv_nnc_stream_signal_t* signal;
85 if (stream_context)
86 signal = ccv_nnc_stream_context_emit_signal_new(stream_context);
87 for (i = 0; i < parallel_count; i++)
88 {
89 const int stream_type = CCV_TENSOR_GET_MEMORY(norm2[i * 2]->info.type)((norm2[i * 2]->info.type) & 0x3) == CCV_TENSOR_GPU_MEMORY ? CCV_STREAM_CONTEXT_GPU : CCV_STREAM_CONTEXT_CPU;
90 const int device_id = CCV_TENSOR_GET_DEVICE_ID(norm2[i * 2]->info.type)(((norm2[i * 2]->info.type) & 0xfff00) >> 8);
91 int type = stream_type;
92 CCV_STREAM_SET_DEVICE_ID(type, device_id)(type) = (((type) & ~0xfff00) | (((device_id) & 0xfff
) << 8))
;
93 ccv_nnc_stream_context_t* const stream_0 = ccv_cnnp_compiled_data_get_stream(compiled_data, type);
94 // Wait signal to finish.
95 if (stream_context)
96 ccv_nnc_stream_context_wait_signal(stream_0, signal);
97 ccv_nnc_cmd_exec(CMD_SET_FORWARD(0)ccv_nnc_cmd(CCV_NNC_SET_FORWARD, 0, (ccv_nnc_cmd_param_t){.size
={.dim={1,1,1}},.blas={.a={0,}}}, 0)
, ccv_nnc_no_hint, 0, 0, 0, TENSOR_LIST(norm2[i * 2])(ccv_nnc_tensor_t* []){norm2[i * 2]}, (1 +1 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, stream_0);
98 if (stream_context)
99 {
100 ccv_nnc_stream_signal_t* const signal = ccv_nnc_stream_context_emit_signal_new(stream_0);
101 ccv_nnc_stream_context_wait_signal(stream_context, signal);
102 }
103 streams[i] = stream_0;
104 }
105 // If this should be blocking, blocking it.
106 if (!stream_context)
107 for (i = 0; i < parallel_count; i++)
108 if (streams[i])
109 ccv_nnc_stream_context_wait(streams[i]);
110 } else {
111 ccv_nnc_cmd_exec(CMD_SET_FORWARD(0)ccv_nnc_cmd(CCV_NNC_SET_FORWARD, 0, (ccv_nnc_cmd_param_t){.size
={.dim={1,1,1}},.blas={.a={0,}}}, 0)
, ccv_nnc_no_hint, 0, 0, 0, TENSOR_LIST(norm2[0])(ccv_nnc_tensor_t* []){norm2[0]}, (1 +1 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, stream_context);
112 }
113 // Gather norm2.
114 ccv_nnc_cmd_t reduce_cmd = {
115 .cmd = CCV_NNC_CUSTOM_FORWARD,
116 .isa = &clip_grad_norm_reduce_norm2_vtab,
117 };
118 ccv_cnnp_model_parameter_gradients_map(model, parameters, reduce_cmd, ccv_nnc_no_hint, 0, 0, 0, norm2, parallel_count * 2, stream_context);
119 // Now compute max(max_norm / norm2, 1.0).
120 if (parallel_count > 1)
121 {
122 ccv_nnc_stream_context_t* streams[parallel_count];
123 ccv_nnc_stream_signal_t* signal;
124 if (stream_context)
125 signal = ccv_nnc_stream_context_emit_signal_new(stream_context);
126 for (i = 0; i < parallel_count; i++)
127 {
128 const int stream_type = CCV_TENSOR_GET_MEMORY(norm2[i * 2]->info.type)((norm2[i * 2]->info.type) & 0x3) == CCV_TENSOR_GPU_MEMORY ? CCV_STREAM_CONTEXT_GPU : CCV_STREAM_CONTEXT_CPU;
129 const int device_id = CCV_TENSOR_GET_DEVICE_ID(norm2[i * 2]->info.type)(((norm2[i * 2]->info.type) & 0xfff00) >> 8);
130 int type = stream_type;
131 CCV_STREAM_SET_DEVICE_ID(type, device_id)(type) = (((type) & ~0xfff00) | (((device_id) & 0xfff
) << 8))
;
132 ccv_nnc_stream_context_t* const stream_0 = ccv_cnnp_compiled_data_get_stream(compiled_data, type);
133 // Wait signal to finish.
134 if (stream_context)
135 ccv_nnc_stream_context_wait_signal(stream_0, signal);
136 ccv_nnc_cmd_exec(CMD_EWSQRT_FORWARD()ccv_nnc_cmd(CCV_NNC_EWSQRT_FORWARD, 0, ccv_nnc_cmd_auto, 0), ccv_nnc_no_hint, 0, TENSOR_LIST(norm2[i * 2])(ccv_nnc_tensor_t* []){norm2[i * 2]}, (1 +1 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_LIST(norm2[i * 2])(ccv_nnc_tensor_t* []){norm2[i * 2]}, (1 +1 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, stream_0);
137 ccv_nnc_cmd_exec(CMD_SET_FORWARD(max_norm)ccv_nnc_cmd(CCV_NNC_SET_FORWARD, 0, (ccv_nnc_cmd_param_t){.size
={.dim={1,1,1}},.blas={.a={max_norm,}}}, 0)
, ccv_nnc_no_hint, 0, 0, 0, TENSOR_LIST(max_normt[i])(ccv_nnc_tensor_t* []){max_normt[i]}, (1 +1 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, stream_0);
138 ccv_nnc_cmd_exec(CMD_EWDIV_FORWARD()ccv_nnc_cmd(CCV_NNC_EWDIV_FORWARD, 0, ccv_nnc_cmd_auto, 0), ccv_nnc_no_hint, 0, TENSOR_LIST(max_normt[i], norm2[i * 2])(ccv_nnc_tensor_t* []){max_normt[i], norm2[i * 2]}, (1 +1 +1 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1
)
, TENSOR_LIST(norm2[i * 2])(ccv_nnc_tensor_t* []){norm2[i * 2]}, (1 +1 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, stream_0);
139 ccv_nnc_cmd_exec(CMD_CLAMP_FORWARD(NAN, 1)ccv_nnc_cmd(CCV_NNC_CLAMP_FORWARD, 0, (ccv_nnc_cmd_param_t){.
size={.dim={1,1,1}},.clamp={.min=(__builtin_nanf ("")),.max=1
}}, 0)
, ccv_nnc_no_hint, 0, TENSOR_LIST(norm2[i * 2])(ccv_nnc_tensor_t* []){norm2[i * 2]}, (1 +1 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_LIST(norm2[i * 2])(ccv_nnc_tensor_t* []){norm2[i * 2]}, (1 +1 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, stream_0);
140 if (stream_context)
141 {
142 ccv_nnc_stream_signal_t* const signal = ccv_nnc_stream_context_emit_signal_new(stream_0);
143 ccv_nnc_stream_context_wait_signal(stream_context, signal);
144 }
145 streams[i] = stream_0;
146 }
147 // If this should be blocking, blocking it.
148 if (!stream_context)
149 for (i = 0; i < parallel_count; i++)
150 if (streams[i])
151 ccv_nnc_stream_context_wait(streams[i]);
152 } else {
153 ccv_nnc_cmd_exec(CMD_EWSQRT_FORWARD()ccv_nnc_cmd(CCV_NNC_EWSQRT_FORWARD, 0, ccv_nnc_cmd_auto, 0), ccv_nnc_no_hint, 0, TENSOR_LIST(norm2[0])(ccv_nnc_tensor_t* []){norm2[0]}, (1 +1 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_LIST(norm2[0])(ccv_nnc_tensor_t* []){norm2[0]}, (1 +1 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, stream_context);
154 ccv_nnc_cmd_exec(CMD_SET_FORWARD(max_norm)ccv_nnc_cmd(CCV_NNC_SET_FORWARD, 0, (ccv_nnc_cmd_param_t){.size
={.dim={1,1,1}},.blas={.a={max_norm,}}}, 0)
, ccv_nnc_no_hint, 0, 0, 0, TENSOR_LIST(max_normt[0])(ccv_nnc_tensor_t* []){max_normt[0]}, (1 +1 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, stream_context);
155 ccv_nnc_cmd_exec(CMD_EWDIV_FORWARD()ccv_nnc_cmd(CCV_NNC_EWDIV_FORWARD, 0, ccv_nnc_cmd_auto, 0), ccv_nnc_no_hint, 0, TENSOR_LIST(max_normt[0], norm2[0])(ccv_nnc_tensor_t* []){max_normt[0], norm2[0]}, (1 +1 +1 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_LIST(norm2[0])(ccv_nnc_tensor_t* []){norm2[0]}, (1 +1 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, stream_context);
156 ccv_nnc_cmd_exec(CMD_CLAMP_FORWARD(NAN, 1)ccv_nnc_cmd(CCV_NNC_CLAMP_FORWARD, 0, (ccv_nnc_cmd_param_t){.
size={.dim={1,1,1}},.clamp={.min=(__builtin_nanf ("")),.max=1
}}, 0)
, ccv_nnc_no_hint, 0, TENSOR_LIST(norm2[0])(ccv_nnc_tensor_t* []){norm2[0]}, (1 +1 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_LIST(norm2[0])(ccv_nnc_tensor_t* []){norm2[0]}, (1 +1 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, stream_context);
157 }
158 ccv_nnc_cmd_t scatter_cmd = {
159 .cmd = CCV_NNC_CUSTOM_FORWARD,
160 .isa = &clip_grad_norm_scatter_norm2_vtab,
161 };
162 ccv_cnnp_model_parameter_gradients_map(model, parameters, scatter_cmd, ccv_nnc_no_hint, 0, norm2, parallel_count * 2, 0, 0, stream_context);
163 for (i = 0; i < parallel_count; i++)
164 {
165 ccv_nnc_tensor_free(norm2[i * 2]);
166 ccv_nnc_tensor_free(norm2[i * 2 + 1]);
167 ccv_nnc_tensor_free(max_normt[i]);
168 }
169}
170
171// MARK - Core Layers
172
173static void _ccv_cnnp_sum_build(ccv_cnnp_model_t* const self, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
174{
175 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 175, __extension__ __PRETTY_FUNCTION__
); }))
;
176 outputs[0] = ccv_nnc_tensor_symbol_new(graph, ccv_nnc_tensor_symbol_params(graph, inputs[0]), 0);
177 ccv_nnc_graph_exec_symbol_new(graph, CMD_EWSUM_FORWARD()ccv_nnc_cmd(CCV_NNC_EWSUM_FORWARD, 0, ccv_nnc_cmd_auto, 0), inputs, input_size, outputs, output_size, 0);
178}
179
180static ccv_cnnp_model_t* _ccv_cnnp_sum_copy(const ccv_cnnp_model_t* const self, void* const context);
181
182static const ccv_cnnp_model_vtab_t ccv_cnnp_sum_isa = {
183 .build = _ccv_cnnp_sum_build,
184 .copy = _ccv_cnnp_sum_copy,
185};
186
187typedef struct {
188 ccv_cnnp_model_t super;
189 ccv_nnc_tensor_symbol_t output;
190} ccv_cnnp_model_sum_t;
191
192ccv_cnnp_model_t* ccv_cnnp_sum(const char* const name)
193{
194 ccv_cnnp_model_sum_t* const model_sum = (ccv_cnnp_model_sum_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_sum_t));
195 model_sum->super.isa = &ccv_cnnp_sum_isa;
196 model_sum->super.input_size = 0;
197 model_sum->super.outputs = &model_sum->output;
198 model_sum->super.output_size = 1;
199 ccv_cnnp_model_copy_name(&model_sum->super, name);
200 return (ccv_cnnp_model_t*)model_sum;
201}
202
203static ccv_cnnp_model_t* _ccv_cnnp_sum_copy(const ccv_cnnp_model_t* const self, void* const context)
204{
205 return ccv_cnnp_sum(self->name);
206}
207
208typedef struct {
209 ccv_cnnp_model_t super;
210 int axis;
211 ccv_nnc_tensor_symbol_t output;
212} ccv_cnnp_model_concat_t;
213
214static void _ccv_cnnp_concat_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
215{
216 const ccv_cnnp_model_concat_t* const self = (const ccv_cnnp_model_concat_t*)super;
217 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 217, __extension__ __PRETTY_FUNCTION__
); }))
;
1
Assuming 'output_size' is equal to 1
2
Taking true branch
218 ccv_nnc_tensor_param_t output_params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
219 const int nd = ccv_nnc_tensor_nd(output_params.dim);
220 const int axis = self->axis;
221 assert(axis < nd)((void) sizeof ((axis < nd) ? 1 : 0), __extension__ ({ if (
axis < nd) ; else __assert_fail ("axis < nd", "ccv_cnnp_model_addons.c"
, 221, __extension__ __PRETTY_FUNCTION__); }))
;
3
Assuming 'axis' is < 'nd'
4
Taking true branch
222 output_params.dim[axis] = 0;
223 int i, j;
224 for (i = 0; i < input_size; i++)
5
Assuming 'i' is >= 'input_size'
6
Loop condition is false. Execution continues on line 234
225 {
226 const ccv_nnc_tensor_param_t input_params = ccv_nnc_tensor_symbol_params(graph, inputs[i]);
227 const int input_nd = ccv_nnc_tensor_nd(input_params.dim);
228 assert(input_nd == nd)((void) sizeof ((input_nd == nd) ? 1 : 0), __extension__ ({ if
(input_nd == nd) ; else __assert_fail ("input_nd == nd", "ccv_cnnp_model_addons.c"
, 228, __extension__ __PRETTY_FUNCTION__); }))
;
229 for (j = 0; j < nd; j++)
230 if (j != axis)
231 { assert(input_params.dim[j] == output_params.dim[j])((void) sizeof ((input_params.dim[j] == output_params.dim[j])
? 1 : 0), __extension__ ({ if (input_params.dim[j] == output_params
.dim[j]) ; else __assert_fail ("input_params.dim[j] == output_params.dim[j]"
, "ccv_cnnp_model_addons.c", 231, __extension__ __PRETTY_FUNCTION__
); }))
; }
232 output_params.dim[axis] += input_params.dim[axis];
233 }
234 outputs[0] = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
235 int ofs[CCV_NNC_MAX_DIM_ALLOC(12)] = {};
236 ccv_nnc_tensor_symbol_t aliases[input_size];
7
Declared variable-length array (VLA) has negative size
237 for (i = 0; i < input_size; i++)
238 {
239 const ccv_nnc_tensor_param_t input_params = ccv_nnc_tensor_symbol_params(graph, inputs[i]);
240 aliases[i] = ccv_nnc_tensor_symbol_alias_new(graph, outputs[0], ofs, output_params.dim, input_params, 0);
241 ofs[axis] += input_params.dim[axis];
242 }
243 // Format transform is more flexible.
244 ccv_nnc_graph_exec_symbol_new(graph, CMD_FORMAT_TRANSFORM_FORWARD()ccv_nnc_cmd(CCV_NNC_FORMAT_TRANSFORM_FORWARD, 0, ccv_nnc_cmd_auto
, 0)
, inputs, input_size, aliases, input_size, 0);
245}
246
247static ccv_cnnp_model_t* _ccv_cnnp_concat_copy(const ccv_cnnp_model_t* const self, void* const context);
248
249static const ccv_cnnp_model_vtab_t ccv_cnnp_concat_isa = {
250 .build = _ccv_cnnp_concat_build,
251 .copy = _ccv_cnnp_concat_copy,
252};
253
254ccv_cnnp_model_t* ccv_cnnp_concat(const int axis, const char* const name)
255{
256 ccv_cnnp_model_concat_t* const model_concat = (ccv_cnnp_model_concat_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_concat_t));
257 model_concat->super.isa = &ccv_cnnp_concat_isa;
258 model_concat->super.input_size = 0;
259 model_concat->super.outputs = &model_concat->output;
260 model_concat->super.output_size = 1;
261 model_concat->axis = axis;
262 ccv_cnnp_model_copy_name(&model_concat->super, name);
263 return (ccv_cnnp_model_t*)model_concat;
264}
265
266static ccv_cnnp_model_t* _ccv_cnnp_concat_copy(const ccv_cnnp_model_t* const super, void* const context)
267{
268 const ccv_cnnp_model_concat_t* const self = (const ccv_cnnp_model_concat_t*)super;
269 return ccv_cnnp_concat(self->axis, self->super.name);
270}
271
272typedef struct {
273 ccv_cnnp_model_t super;
274 ccv_nnc_tensor_symbol_t output;
275 int dim[CCV_NNC_MAX_DIM_ALLOC(12)];
276 int ofs[CCV_NNC_MAX_DIM_ALLOC(12)];
277 int inc[CCV_NNC_MAX_DIM_ALLOC(12)];
278} ccv_cnnp_model_reshape_t;
279
280static void _ccv_cnnp_reshape_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
281{
282 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 282, __extension__ __PRETTY_FUNCTION__); }))
;
283 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 283, __extension__ __PRETTY_FUNCTION__
); }))
;
284 ccv_cnnp_model_reshape_t* const self = (ccv_cnnp_model_reshape_t*)super;
285 ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
286 assert(ccv_nnc_dimension_count(self->dim) <= ccv_nnc_tensor_count(params))((void) sizeof ((ccv_nnc_dimension_count(self->dim) <= ccv_nnc_tensor_count
(params)) ? 1 : 0), __extension__ ({ if (ccv_nnc_dimension_count
(self->dim) <= ccv_nnc_tensor_count(params)) ; else __assert_fail
("ccv_nnc_dimension_count(self->dim) <= ccv_nnc_tensor_count(params)"
, "ccv_cnnp_model_addons.c", 286, __extension__ __PRETTY_FUNCTION__
); }))
;
287 memcpy(params.dim, self->dim, sizeof(params.dim));
288 outputs[0] = ccv_nnc_tensor_symbol_alias_new(graph, inputs[0], self->ofs, self->inc, params, 0);
289}
290
291static ccv_cnnp_model_t* _ccv_cnnp_reshape_copy(const ccv_cnnp_model_t* const super, void* const context);
292
293static const ccv_cnnp_model_vtab_t ccv_cnnp_reshape_isa = {
294 .build = _ccv_cnnp_reshape_build,
295 .copy = _ccv_cnnp_reshape_copy,
296};
297
298ccv_cnnp_model_t* ccv_cnnp_reshape(const int dim[CCV_NNC_MAX_DIM_ALLOC(12)], const int ofs[CCV_NNC_MAX_DIM_ALLOC(12)], const int inc[CCV_NNC_MAX_DIM_ALLOC(12)], const char* const name)
299{
300 ccv_cnnp_model_reshape_t* const model_reshape = (ccv_cnnp_model_reshape_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_reshape_t));
301 model_reshape->super.isa = &ccv_cnnp_reshape_isa;
302 model_reshape->super.input_size = 1;
303 model_reshape->super.outputs = &model_reshape->output;
304 model_reshape->super.output_size = 1;
305 ccv_cnnp_model_copy_name(&model_reshape->super, name);
306 memcpy(model_reshape->dim, dim, sizeof(model_reshape->dim));
307 memcpy(model_reshape->ofs, ofs, sizeof(model_reshape->ofs));
308 int i, flag = 0;
309 for (i = 0; !flag && i < CCV_NNC_MAX_DIM_ALLOC(12); i++)
310 flag = (inc[i] != 0);
311 memcpy(model_reshape->inc, flag ? inc : dim, sizeof(model_reshape->inc));
312 return (ccv_cnnp_model_t*)model_reshape;
313}
314
315static ccv_cnnp_model_t* _ccv_cnnp_reshape_copy(const ccv_cnnp_model_t* const super, void* const context)
316{
317 const ccv_cnnp_model_reshape_t* const self = (const ccv_cnnp_model_reshape_t*)super;
318 return ccv_cnnp_reshape(self->dim, self->ofs, self->inc, self->super.name);
319}
320
321typedef struct {
322 ccv_cnnp_model_t super;
323 ccv_nnc_tensor_symbol_t output;
324} ccv_cnnp_model_flatten_t;
325
326static void _ccv_cnnp_flatten_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
327{
328 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 328, __extension__ __PRETTY_FUNCTION__); }))
;
329 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 329, __extension__ __PRETTY_FUNCTION__
); }))
;
330 const ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
331 ccv_nnc_tensor_param_t output_params = params;
332 memset(output_params.dim, 0, sizeof(output_params.dim));
333 output_params.dim[0] = ccv_nnc_tensor_get_n(params);
334 assert(output_params.dim[0] > 0)((void) sizeof ((output_params.dim[0] > 0) ? 1 : 0), __extension__
({ if (output_params.dim[0] > 0) ; else __assert_fail ("output_params.dim[0] > 0"
, "ccv_cnnp_model_addons.c", 334, __extension__ __PRETTY_FUNCTION__
); }))
;
335 output_params.dim[1] = ccv_nnc_tensor_count(params) / output_params.dim[0];
336 outputs[0] = ccv_nnc_tensor_symbol_alias_new(graph, inputs[0], DIM_ALLOC()(int [(12)]){}, output_params.dim, output_params, 0);
337}
338
339static ccv_cnnp_model_t* _ccv_cnnp_flatten_copy(const ccv_cnnp_model_t* const self, void* const context);
340
341static const ccv_cnnp_model_vtab_t ccv_cnnp_flatten_isa = {
342 .build = _ccv_cnnp_flatten_build,
343 .copy = _ccv_cnnp_flatten_copy,
344};
345
346ccv_cnnp_model_t* ccv_cnnp_flatten(const char* const name)
347{
348 ccv_cnnp_model_flatten_t* const model_flatten = (ccv_cnnp_model_flatten_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_flatten_t));
349 model_flatten->super.isa = &ccv_cnnp_flatten_isa;
350 model_flatten->super.input_size = 1;
351 model_flatten->super.outputs = &model_flatten->output;
352 model_flatten->super.output_size = 1;
353 ccv_cnnp_model_copy_name(&model_flatten->super, name);
354 return (ccv_cnnp_model_t*)model_flatten;
355}
356
357static ccv_cnnp_model_t* _ccv_cnnp_flatten_copy(const ccv_cnnp_model_t* const self, void* const context)
358{
359 return ccv_cnnp_flatten(self->name);
360}
361
362// MARK - Batch Norm Layer
363
364typedef struct {
365 ccv_cnnp_model_t super;
366 ccv_nnc_tensor_symbol_t output;
367 ccv_nnc_tensor_symbol_t bias;
368 ccv_nnc_tensor_symbol_t scale;
369 ccv_nnc_graph_exec_symbol_t batch_norm;
370 ccv_nnc_cmd_param_t params;
371 ccv_array_t* zero_inits;
372 ccv_array_t* retainables;
373} ccv_cnnp_model_batch_norm_t;
374
375static void _ccv_cnnp_batch_norm_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
376{
377 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 377, __extension__ __PRETTY_FUNCTION__); }))
;
378 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 378, __extension__ __PRETTY_FUNCTION__
); }))
;
379 ccv_cnnp_model_batch_norm_t* const self = (ccv_cnnp_model_batch_norm_t*)super;
380 const ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
381 const int nd = ccv_nnc_tensor_nd(params.dim);
382 ccv_nnc_tensor_param_t bias_params = params;
383 memset(bias_params.dim, 0, sizeof(bias_params.dim));
384 // If the accuracy is not enough, bump it to 32-bit floating point.
385 if (bias_params.datatype != CCV_32F && bias_params.datatype != CCV_64F)
386 bias_params.datatype = CCV_32F;
387 bias_params.dim[0] = nd > 1 ? ccv_nnc_tensor_get_c(params) : params.dim[0];
388 const ccv_nnc_tensor_symbol_t output = ccv_nnc_tensor_symbol_new(graph, params, 0);
389 // Both scale and bias are shared between if this model is reused.
390 if (!self->scale.graph)
391 self->scale = ccv_nnc_tensor_symbol_new(graph, bias_params, 0);
392 if (!self->bias.graph)
393 self->bias = ccv_nnc_tensor_symbol_new(graph, bias_params, 0);
394 const ccv_nnc_tensor_symbol_t mean = ccv_nnc_tensor_symbol_new(graph, bias_params, 0);
395 const ccv_nnc_tensor_symbol_t var = ccv_nnc_tensor_symbol_new(graph, bias_params, 0);
396 // Otherwise, notice mean, var, saved_mean, saved_inv_std are not reused.
397 if (!self->zero_inits)
398 self->zero_inits = ccv_array_new(sizeof(ccv_nnc_tensor_symbol_t), 0, 0);
399 ccv_array_push(self->zero_inits, &mean);
400 ccv_array_push(self->zero_inits, &var);
401 const ccv_nnc_tensor_symbol_t out_mean = ccv_nnc_tensor_symbol_new(graph, bias_params, 0);
402 const ccv_nnc_tensor_symbol_t out_var = ccv_nnc_tensor_symbol_new(graph, bias_params, 0);
403 if (!self->retainables)
404 self->retainables = ccv_array_new(sizeof(ccv_nnc_tensor_symbol_t), 0, 0);
405 ccv_array_push(self->retainables, &out_mean);
406 ccv_array_push(self->retainables, &out_var);
407 const ccv_nnc_tensor_symbol_t saved_mean = ccv_nnc_tensor_symbol_new(graph, bias_params, 0);
408 const ccv_nnc_tensor_symbol_t saved_inv_std = ccv_nnc_tensor_symbol_new(graph, bias_params, 0);
409 const int hw = ccv_nnc_tensor_hw(params, ccv_nnc_tensor_nd(params.dim));
410 ccv_nnc_cmd_param_t batch_norm = self->params;
411 batch_norm.bnorm.count = hw >= 0 ? CCV_NNC_MAX_DIM(2) + 1 : 1;
412 int i;
413 batch_norm.bnorm.axis[0] = (params.format == CCV_TENSOR_FORMAT_CHWN) ? 3 : 0;
414 if (hw >= 0)
415 for (i = 0; i < CCV_NNC_MAX_DIM(2); i++)
416 batch_norm.bnorm.axis[i + 1] = i + hw;
417 self->params = batch_norm;
418 self->batch_norm = ccv_nnc_graph_exec_symbol_new(graph, ccv_nnc_cmd(CCV_NNC_BATCH_NORM_FORWARD, 0, batch_norm, 0), TENSOR_SYMBOL_LIST(inputs[0], self->scale, self->bias, mean, var)(const ccv_nnc_tensor_symbol_t []){inputs[0], self->scale,
self->bias, mean, var}, (1 +1 +1 +1 +1 +1 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_SYMBOL_LIST(output, out_mean, out_var, saved_mean, saved_inv_std)(const ccv_nnc_tensor_symbol_t []){output, out_mean, out_var,
saved_mean, saved_inv_std}, (1 +1 +1 +1 +1 +1 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, 0);
419 outputs[0] = output;
420}
421
422static void _ccv_cnnp_batch_norm_init_states(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_cnnp_state_initializer_f initializer, void* const context)
423{
424 ccv_cnnp_model_batch_norm_t* const self = (ccv_cnnp_model_batch_norm_t*)super;
425 if (self->bias.graph)
426 initializer(context, CMD_SET_FORWARD(0)ccv_nnc_cmd(CCV_NNC_SET_FORWARD, 0, (ccv_nnc_cmd_param_t){.size
={.dim={1,1,1}},.blas={.a={0,}}}, 0)
, ccv_nnc_no_hint, 0, 0, self->bias);
427 if (self->scale.graph)
428 initializer(context, CMD_RANDOM_UNIFORM_FORWARD(0, 1)ccv_nnc_cmd(CCV_NNC_RANDOM_UNIFORM_FORWARD, 0, (ccv_nnc_cmd_param_t
){.size={.dim={1,1,1}},.blas={.a={0, 1}}}, 0)
, ccv_nnc_no_hint, 0, 0, self->scale);
429 int i;
430 if (self->zero_inits)
431 for (i = 0; i < self->zero_inits->rnum; i++)
432 initializer(context, CMD_SET_FORWARD(0)ccv_nnc_cmd(CCV_NNC_SET_FORWARD, 0, (ccv_nnc_cmd_param_t){.size
={.dim={1,1,1}},.blas={.a={0,}}}, 0)
, ccv_nnc_no_hint, 0, 0, *(ccv_nnc_tensor_symbol_t*)ccv_array_get(self->zero_inits, i)((void*)(((char*)((self->zero_inits)->data)) + (size_t)
(self->zero_inits)->rsize * (size_t)(i)))
);
433}
434
435static void _ccv_cnnp_batch_norm_add_to_parameter(ccv_cnnp_model_t* const super, const ccv_cnnp_add_to_array_f add_to_array, void* const parameters)
436{
437 ccv_cnnp_model_batch_norm_t* const self = (ccv_cnnp_model_batch_norm_t*)super;
438 if (self->bias.graph)
439 add_to_array(parameters, self->bias);
440 if (self->scale.graph)
441 add_to_array(parameters, self->scale);
442}
443
444static void _ccv_cnnp_batch_norm_add_to_output(ccv_cnnp_model_t* const super, const ccv_cnnp_add_to_array_f add_to_array, void* const outputs)
445{
446 ccv_cnnp_model_batch_norm_t* const self = (ccv_cnnp_model_batch_norm_t*)super;
447 int i;
448 if (self->retainables)
449 for (i = 0; i < self->retainables->rnum; i++)
450 {
451 const ccv_nnc_tensor_symbol_t symbol = *(ccv_nnc_tensor_symbol_t*)ccv_array_get(self->retainables, i)((void*)(((char*)((self->retainables)->data)) + (size_t
)(self->retainables)->rsize * (size_t)(i)))
;
452 add_to_array(outputs, symbol);
453 }
454}
455
456static void _ccv_cnnp_batch_norm_set_is_test(ccv_cnnp_model_t* const super, const int is_test, const ccv_cnnp_cmd_updater_f updater, void* const context)
457{
458 ccv_cnnp_model_batch_norm_t* const self = (ccv_cnnp_model_batch_norm_t*)super;
459 if (self->batch_norm.graph)
460 {
461 self->params.bnorm.is_test = is_test;
462 updater(context, self->batch_norm, ccv_nnc_cmd(CCV_NNC_BATCH_NORM_FORWARD, 0, self->params, 0), ccv_nnc_no_hint);
463 }
464}
465
466static void _ccv_cnnp_batch_norm_deinit(ccv_cnnp_model_t* const super)
467{
468 ccv_cnnp_model_batch_norm_t* const self = (ccv_cnnp_model_batch_norm_t*)super;
469 if (self->zero_inits)
470 ccv_array_free(self->zero_inits);
471 if (self->retainables)
472 ccv_array_free(self->retainables);
473}
474
475static ccv_cnnp_model_t* _ccv_cnnp_batch_norm_copy(const ccv_cnnp_model_t* const super, void* const context);
476
477static const ccv_cnnp_model_vtab_t ccv_cnnp_batch_norm_isa = {
478 .build = _ccv_cnnp_batch_norm_build,
479 .init_states = _ccv_cnnp_batch_norm_init_states,
480 .add_to_parameter = _ccv_cnnp_batch_norm_add_to_parameter,
481 .add_to_output = _ccv_cnnp_batch_norm_add_to_output,
482 .copy = _ccv_cnnp_batch_norm_copy,
483 .set_is_test = _ccv_cnnp_batch_norm_set_is_test,
484 .deinit = _ccv_cnnp_batch_norm_deinit,
485};
486
487ccv_cnnp_model_t* ccv_cnnp_batch_norm(const float momentum, const float epsilon, const char* const name)
488{
489 ccv_cnnp_model_batch_norm_t* const model_batch_norm = (ccv_cnnp_model_batch_norm_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_batch_norm_t));
490 model_batch_norm->super.isa = &ccv_cnnp_batch_norm_isa;
491 model_batch_norm->super.input_size = 1;
492 model_batch_norm->super.outputs = &model_batch_norm->output;
493 model_batch_norm->super.output_size = 1;
494 ccv_cnnp_model_copy_name(&model_batch_norm->super, name);
495 model_batch_norm->scale.d = CCV_NNC_NO_TENSOR_SYMBOL;
496 model_batch_norm->scale.graph = 0;
497 model_batch_norm->bias.d = CCV_NNC_NO_TENSOR_SYMBOL;
498 model_batch_norm->bias.graph = 0;
499 model_batch_norm->params.bnorm.momentum = momentum;
500 model_batch_norm->params.bnorm.epsilon = epsilon;
501 return (ccv_cnnp_model_t*)model_batch_norm;
502}
503
504static ccv_cnnp_model_t* _ccv_cnnp_batch_norm_copy(const ccv_cnnp_model_t* const super, void* const context)
505{
506 const ccv_cnnp_model_batch_norm_t* const self = (const ccv_cnnp_model_batch_norm_t*)super;
507 return ccv_cnnp_batch_norm(self->params.bnorm.momentum, self->params.bnorm.epsilon, self->super.name);
508}
509
510// MARK - Convolution Layer
511
512typedef struct {
513 ccv_cnnp_model_t super;
514 ccv_nnc_tensor_symbol_t output;
515 ccv_nnc_tensor_symbol_t weights;
516 ccv_nnc_tensor_symbol_t bias;
517 int groups;
518 int filters;
519 int kdim[CCV_NNC_MAX_DIM_ALLOC(12)];
520 int no_bias;
521 ccv_nnc_hint_t hint;
522} ccv_cnnp_model_convolution_t;
523
524static void _ccv_cnnp_convolution_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
525{
526 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 526, __extension__ __PRETTY_FUNCTION__); }))
;
527 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 527, __extension__ __PRETTY_FUNCTION__
); }))
;
528 ccv_cnnp_model_convolution_t* const self = (ccv_cnnp_model_convolution_t*)super;
529 const ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
530 int i;
531 const int nd = CCV_NNC_MAX_DIM(2) + 2;
532 ccv_nnc_tensor_param_t weights_params = params;
533 ccv_nnc_tensor_set_n(&weights_params, self->filters);
534 assert(ccv_nnc_tensor_get_c(params) % self->groups == 0)((void) sizeof ((ccv_nnc_tensor_get_c(params) % self->groups
== 0) ? 1 : 0), __extension__ ({ if (ccv_nnc_tensor_get_c(params
) % self->groups == 0) ; else __assert_fail ("ccv_nnc_tensor_get_c(params) % self->groups == 0"
, "ccv_cnnp_model_addons.c", 534, __extension__ __PRETTY_FUNCTION__
); }))
;
535 ccv_nnc_tensor_set_c(&weights_params, nd, ccv_nnc_tensor_get_c(params) / self->groups);
536 const int hw = ccv_nnc_tensor_hw(weights_params, nd);
537 assert(hw >= 0)((void) sizeof ((hw >= 0) ? 1 : 0), __extension__ ({ if (hw
>= 0) ; else __assert_fail ("hw >= 0", "ccv_cnnp_model_addons.c"
, 537, __extension__ __PRETTY_FUNCTION__); }))
;
538 for (i = 0; i < CCV_NNC_MAX_DIM(2); i++)
539 weights_params.dim[i + hw] = self->kdim[i];
540 if (!self->weights.graph)
541 self->weights = ccv_nnc_tensor_symbol_new(graph, weights_params, 0);
542 assert(self->weights.graph == graph)((void) sizeof ((self->weights.graph == graph) ? 1 : 0), __extension__
({ if (self->weights.graph == graph) ; else __assert_fail
("self->weights.graph == graph", "ccv_cnnp_model_addons.c"
, 542, __extension__ __PRETTY_FUNCTION__); }))
;
543 ccv_nnc_tensor_param_t bias_params = params;
544 memset(bias_params.dim, 0, sizeof(bias_params.dim));
545 bias_params.dim[0] = self->filters;
546 ccv_nnc_cmd_t cmd = CMD_CONVOLUTION_FORWARD(self->groups, self->filters)ccv_nnc_cmd(CCV_NNC_CONVOLUTION_FORWARD, 0, ((ccv_nnc_cmd_param_t
){.size={.dim={}},.convolution={.count=self->filters,.groups
=self->groups}}), 0)
;
547 for (i = 0; i < CCV_NNC_MAX_DIM(2); i++)
548 cmd.info.size.dim[i] = self->kdim[i];
549 ccv_nnc_tensor_param_t output_params;
550 ccv_nnc_hint_tensor_auto(cmd, (ccv_nnc_tensor_param_t []){
551 params,
552 weights_params,
553 bias_params,
554 }, 3, self->hint, &output_params, 1);
555 const ccv_nnc_tensor_symbol_t output = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
556 ccv_nnc_graph_exec_symbol_t convolution;
557 if (self->no_bias)
558 convolution = ccv_nnc_graph_exec_symbol_new(graph, cmd, TENSOR_SYMBOL_LIST(inputs[0], self->weights)(const ccv_nnc_tensor_symbol_t []){inputs[0], self->weights
}, (1 +1 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 -1)
, TENSOR_SYMBOL_LIST(output)(const ccv_nnc_tensor_symbol_t []){output}, (1 +1 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, 0);
559 else {
560 if (!self->bias.graph)
561 self->bias = ccv_nnc_tensor_symbol_new(graph, bias_params, 0);
562 convolution = ccv_nnc_graph_exec_symbol_new(graph, cmd, TENSOR_SYMBOL_LIST(inputs[0], self->weights, self->bias)(const ccv_nnc_tensor_symbol_t []){inputs[0], self->weights
, self->bias}, (1 +1 +1 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_SYMBOL_LIST(output)(const ccv_nnc_tensor_symbol_t []){output}, (1 +1 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, 0);
563 }
564 ccv_nnc_graph_exec_symbol_set_hint(graph, convolution, self->hint);
565 outputs[0] = output;
566}
567
568static void _ccv_cnnp_convolution_init_states(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_cnnp_state_initializer_f initializer, void* const context)
569{
570 ccv_cnnp_model_convolution_t* const self = (ccv_cnnp_model_convolution_t*)super;
571 const ccv_nnc_tensor_param_t weight_params = ccv_nnc_tensor_symbol_params(graph, self->weights);
572 const int n = ccv_max(ccv_nnc_tensor_get_n(weight_params), 1)({ typeof (ccv_nnc_tensor_get_n(weight_params)) _a = (ccv_nnc_tensor_get_n
(weight_params)); typeof (1) _b = (1); (_a > _b) ? _a : _b
; })
;
573 const int count = ccv_nnc_tensor_count(weight_params);
574 const float std = sqrtf(2) / sqrtf(count / n);
575 const float bound = sqrtf(3) * std;
576 initializer(context, CMD_RANDOM_UNIFORM_FORWARD(-bound, bound)ccv_nnc_cmd(CCV_NNC_RANDOM_UNIFORM_FORWARD, 0, (ccv_nnc_cmd_param_t
){.size={.dim={1,1,1}},.blas={.a={-bound, bound}}}, 0)
, ccv_nnc_no_hint, 0, 0, self->weights);
577 if (self->bias.graph)
578 initializer(context, CMD_SET_FORWARD(0)ccv_nnc_cmd(CCV_NNC_SET_FORWARD, 0, (ccv_nnc_cmd_param_t){.size
={.dim={1,1,1}},.blas={.a={0,}}}, 0)
, ccv_nnc_no_hint, 0, 0, self->bias);
579}
580
581static void _ccv_cnnp_convolution_add_to_parameter(ccv_cnnp_model_t* const super, const ccv_cnnp_add_to_array_f add_to_array, void* const parameters)
582{
583 ccv_cnnp_model_convolution_t* const self = (ccv_cnnp_model_convolution_t*)super;
584 add_to_array(parameters, self->weights);
585 if (self->bias.graph)
586 add_to_array(parameters, self->bias);
587}
588
589static ccv_cnnp_model_t* _ccv_cnnp_convolution_copy(const ccv_cnnp_model_t* const super, void* const context);
590
591static const ccv_cnnp_model_vtab_t ccv_cnnp_convolution_isa = {
592 .build = _ccv_cnnp_convolution_build,
593 .init_states = _ccv_cnnp_convolution_init_states,
594 .add_to_parameter = _ccv_cnnp_convolution_add_to_parameter,
595 .copy = _ccv_cnnp_convolution_copy,
596};
597
598ccv_cnnp_model_t* ccv_cnnp_convolution(const int groups, const int filters, const int kdim[CCV_NNC_MAX_DIM_ALLOC(12)], const int no_bias, ccv_nnc_hint_t hint, const char* const name)
599{
600 ccv_cnnp_model_convolution_t* const model_convolution = (ccv_cnnp_model_convolution_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_convolution_t));
601 model_convolution->super.isa = &ccv_cnnp_convolution_isa;
602 model_convolution->super.input_size = 1;
603 model_convolution->super.outputs = &model_convolution->output;
604 model_convolution->super.output_size = 1;
605 ccv_cnnp_model_copy_name(&model_convolution->super, name);
606 model_convolution->weights.d = CCV_NNC_NO_TENSOR_SYMBOL;
607 model_convolution->weights.graph = 0;
608 model_convolution->bias.d = CCV_NNC_NO_TENSOR_SYMBOL;
609 model_convolution->bias.graph = 0;
610 model_convolution->groups = groups;
611 model_convolution->filters = filters;
612 memcpy(model_convolution->kdim, kdim, sizeof(model_convolution->kdim));
613 model_convolution->no_bias = no_bias;
614 model_convolution->hint = hint;
615 return (ccv_cnnp_model_t*)model_convolution;
616}
617
618static ccv_cnnp_model_t* _ccv_cnnp_convolution_copy(const ccv_cnnp_model_t* const super, void* const context)
619{
620 ccv_cnnp_model_convolution_t* const self = (ccv_cnnp_model_convolution_t*)super;
621 return ccv_cnnp_convolution(self->groups, self->filters, self->kdim, self->no_bias, self->hint, self->super.name);
622}
623
624// MARK - Dense Layer
625
626typedef struct {
627 ccv_cnnp_model_t super;
628 ccv_nnc_tensor_symbol_t output;
629 ccv_nnc_tensor_symbol_t weights;
630 ccv_nnc_tensor_symbol_t bias;
631 int count;
632 int no_bias;
633} ccv_cnnp_model_dense_t;
634
635static void _ccv_cnnp_dense_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
636{
637 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 637, __extension__ __PRETTY_FUNCTION__); }))
;
638 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 638, __extension__ __PRETTY_FUNCTION__
); }))
;
639 ccv_cnnp_model_dense_t* const self = (ccv_cnnp_model_dense_t*)super;
640 const ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
641 ccv_nnc_tensor_param_t weights_params = params;
642 memset(weights_params.dim, 0, sizeof(weights_params.dim));
643 weights_params.dim[0] = self->count;
644 weights_params.dim[1] = params.dim[ccv_nnc_tensor_nd(params.dim) - 1];
645 if (!self->weights.graph)
646 self->weights = ccv_nnc_tensor_symbol_new(graph, weights_params, 0);
647 assert(self->weights.graph == graph)((void) sizeof ((self->weights.graph == graph) ? 1 : 0), __extension__
({ if (self->weights.graph == graph) ; else __assert_fail
("self->weights.graph == graph", "ccv_cnnp_model_addons.c"
, 647, __extension__ __PRETTY_FUNCTION__); }))
;
648 ccv_nnc_tensor_param_t bias_params = params;
649 memset(bias_params.dim, 0, sizeof(bias_params.dim));
650 bias_params.dim[0] = self->count;
651 const ccv_nnc_cmd_t cmd = CMD_GEMM_FORWARD(NO_TRANSPOSE, TRANSPOSE(0, 1))ccv_nnc_cmd(CCV_NNC_GEMM_FORWARD, 0, ((ccv_nnc_cmd_param_t){.
size={.dim={1,1,1}},.blas={.a={1,1},.transpose_a={((int[]){(0
),(0)})[0],((int[]){(0),(0)})[1]},.transpose_b={((int[]){(0),
(1)})[0],((int[]){(0),(1)})[1]},}}), 0)
;
652 ccv_nnc_tensor_param_t output_params;
653 ccv_nnc_hint_tensor_auto(cmd, (ccv_nnc_tensor_param_t []){
654 params,
655 weights_params,
656 bias_params,
657 }, 3, ccv_nnc_no_hint, &output_params, 1);
658 const ccv_nnc_tensor_symbol_t output = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
659 if (self->no_bias)
660 ccv_nnc_graph_exec_symbol_new(graph, cmd, TENSOR_SYMBOL_LIST(inputs[0], self->weights)(const ccv_nnc_tensor_symbol_t []){inputs[0], self->weights
}, (1 +1 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 -1)
, TENSOR_SYMBOL_LIST(output)(const ccv_nnc_tensor_symbol_t []){output}, (1 +1 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, 0);
661 else {
662 if (!self->bias.graph)
663 self->bias = ccv_nnc_tensor_symbol_new(graph, bias_params, 0);
664 ccv_nnc_graph_exec_symbol_new(graph, cmd, TENSOR_SYMBOL_LIST(inputs[0], self->weights, self->bias)(const ccv_nnc_tensor_symbol_t []){inputs[0], self->weights
, self->bias}, (1 +1 +1 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_SYMBOL_LIST(output)(const ccv_nnc_tensor_symbol_t []){output}, (1 +1 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, 0);
665 }
666 outputs[0] = output;
667}
668
669static void _ccv_cnnp_dense_init_states(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_cnnp_state_initializer_f initializer, void* const context)
670{
671 ccv_cnnp_model_dense_t* const self = (ccv_cnnp_model_dense_t*)super;
672 const ccv_nnc_tensor_param_t weight_params = ccv_nnc_tensor_symbol_params(graph, self->weights);
673 const int c = weight_params.dim[1];
674 const float std = sqrtf(2) / sqrtf(c);
675 const float bound = sqrtf(3) * std;
676 initializer(context, CMD_RANDOM_UNIFORM_FORWARD(-bound, bound)ccv_nnc_cmd(CCV_NNC_RANDOM_UNIFORM_FORWARD, 0, (ccv_nnc_cmd_param_t
){.size={.dim={1,1,1}},.blas={.a={-bound, bound}}}, 0)
, ccv_nnc_no_hint, 0, 0, self->weights);
677 if (self->bias.graph)
678 initializer(context, CMD_SET_FORWARD(0)ccv_nnc_cmd(CCV_NNC_SET_FORWARD, 0, (ccv_nnc_cmd_param_t){.size
={.dim={1,1,1}},.blas={.a={0,}}}, 0)
, ccv_nnc_no_hint, 0, 0, self->bias);
679}
680
681static void _ccv_cnnp_dense_add_to_parameter(ccv_cnnp_model_t* const super, const ccv_cnnp_add_to_array_f add_to_array, void* const parameters)
682{
683 ccv_cnnp_model_dense_t* const self = (ccv_cnnp_model_dense_t*)super;
684 add_to_array(parameters, self->weights);
685 if (self->bias.graph)
686 add_to_array(parameters, self->bias);
687}
688
689static ccv_cnnp_model_t* _ccv_cnnp_dense_copy(const ccv_cnnp_model_t* const super, void* const context);
690
691static const ccv_cnnp_model_vtab_t ccv_cnnp_dense_isa = {
692 .build = _ccv_cnnp_dense_build,
693 .init_states = _ccv_cnnp_dense_init_states,
694 .add_to_parameter = _ccv_cnnp_dense_add_to_parameter,
695 .copy = _ccv_cnnp_dense_copy,
696};
697
698ccv_cnnp_model_t* ccv_cnnp_dense(const int count, const int no_bias, const char* const name)
699{
700 ccv_cnnp_model_dense_t* const model_dense = (ccv_cnnp_model_dense_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_dense_t));
701 model_dense->super.isa = &ccv_cnnp_dense_isa;
702 model_dense->super.input_size = 1;
703 model_dense->super.outputs = &model_dense->output;
704 model_dense->super.output_size = 1;
705 ccv_cnnp_model_copy_name(&model_dense->super, name);
706 model_dense->weights.d = CCV_NNC_NO_TENSOR_SYMBOL;
707 model_dense->weights.graph = 0;
708 model_dense->bias.d = CCV_NNC_NO_TENSOR_SYMBOL;
709 model_dense->bias.graph = 0;
710 model_dense->count = count;
711 model_dense->no_bias = no_bias;
712 return (ccv_cnnp_model_t*)model_dense;
713}
714
715static ccv_cnnp_model_t* _ccv_cnnp_dense_copy(const ccv_cnnp_model_t* const super, void* const context)
716{
717 const ccv_cnnp_model_dense_t* const self = (const ccv_cnnp_model_dense_t*)super;
718 return ccv_cnnp_dense(self->count, self->no_bias, self->super.name);
719}
720
721// MARK - Pool Layers
722
723typedef struct {
724 ccv_cnnp_model_t super;
725 ccv_nnc_tensor_symbol_t output;
726 int kdim[CCV_NNC_MAX_DIM_ALLOC(12)];
727 ccv_nnc_hint_t hint;
728} ccv_cnnp_model_pool_t;
729
730static void _ccv_cnnp_max_pool_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
731{
732 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 732, __extension__ __PRETTY_FUNCTION__); }))
;
733 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 733, __extension__ __PRETTY_FUNCTION__
); }))
;
734 ccv_cnnp_model_pool_t* const self = (ccv_cnnp_model_pool_t*)super;
735 const ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
736 const int hw = ccv_nnc_tensor_hw(params, ccv_nnc_tensor_nd(params.dim));
737 ccv_nnc_cmd_t cmd;
738 if (hw >= 0 && self->kdim[0] == 0 && self->kdim[1] == 0)
739 cmd = CMD_MAX_POOL_FORWARD(params.dim[hw], params.dim[hw + 1])ccv_nnc_cmd(CCV_NNC_MAX_POOL_FORWARD, 0, ((ccv_nnc_cmd_param_t
){.size={.dim={params.dim[hw], params.dim[hw + 1],1}}}), 0)
;
740 else
741 cmd = CMD_MAX_POOL_FORWARD(self->kdim[0], self->kdim[1])ccv_nnc_cmd(CCV_NNC_MAX_POOL_FORWARD, 0, ((ccv_nnc_cmd_param_t
){.size={.dim={self->kdim[0], self->kdim[1],1}}}), 0)
;
742 ccv_nnc_tensor_param_t output_params;
743 ccv_nnc_hint_tensor_auto(cmd, &params, 1, self->hint, &output_params, 1);
744 const ccv_nnc_tensor_symbol_t pool_output = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
745 const ccv_nnc_graph_exec_symbol_t exec = ccv_nnc_graph_exec_symbol_new(graph, cmd, TENSOR_SYMBOL_LIST(inputs[0])(const ccv_nnc_tensor_symbol_t []){inputs[0]}, (1 +1 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_SYMBOL_LIST(pool_output)(const ccv_nnc_tensor_symbol_t []){pool_output}, (1 +1 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, 0);
746 ccv_nnc_graph_exec_symbol_set_hint(graph, exec, self->hint);
747 outputs[0] = pool_output;
748}
749
750static ccv_cnnp_model_t* _ccv_cnnp_max_pool_copy(const ccv_cnnp_model_t* const super, void* const context);
751
752static const ccv_cnnp_model_vtab_t ccv_cnnp_max_pool_isa = {
753 .build = _ccv_cnnp_max_pool_build,
754 .copy = _ccv_cnnp_max_pool_copy,
755};
756
757ccv_cnnp_model_t* ccv_cnnp_max_pool(const int kdim[CCV_NNC_MAX_DIM_ALLOC(12)], const ccv_nnc_hint_t hint, const char* const name)
758{
759 ccv_cnnp_model_pool_t* const model_pool = (ccv_cnnp_model_pool_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_pool_t));
760 model_pool->super.isa = &ccv_cnnp_max_pool_isa;
761 model_pool->super.input_size = 1;
762 model_pool->super.outputs = &model_pool->output;
763 model_pool->super.output_size = 1;
764 ccv_cnnp_model_copy_name(&model_pool->super, name);
765 memcpy(model_pool->kdim, kdim, sizeof(model_pool->kdim));
766 model_pool->hint = hint;
767 return (ccv_cnnp_model_t*)model_pool;
768}
769
770static ccv_cnnp_model_t* _ccv_cnnp_max_pool_copy(const ccv_cnnp_model_t* const super, void* const context)
771{
772 const ccv_cnnp_model_pool_t* const self = (const ccv_cnnp_model_pool_t*)super;
773 return ccv_cnnp_max_pool(self->kdim, self->hint, self->super.name);
774}
775
776static void _ccv_cnnp_average_pool_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
777{
778 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 778, __extension__ __PRETTY_FUNCTION__); }))
;
779 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 779, __extension__ __PRETTY_FUNCTION__
); }))
;
780 ccv_cnnp_model_pool_t* const self = (ccv_cnnp_model_pool_t*)super;
781 const ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
782 const int hw = ccv_nnc_tensor_hw(params, ccv_nnc_tensor_nd(params.dim));
783 ccv_nnc_cmd_t cmd;
784 if (hw >= 0 && self->kdim[0] == 0 && self->kdim[1] == 0)
785 cmd = CMD_AVERAGE_POOL_FORWARD(params.dim[hw], params.dim[hw + 1])ccv_nnc_cmd(CCV_NNC_AVERAGE_POOL_FORWARD, 0, ((ccv_nnc_cmd_param_t
){.size={.dim={params.dim[hw], params.dim[hw + 1],1}}}), 0)
;
786 else
787 cmd = CMD_AVERAGE_POOL_FORWARD(self->kdim[0], self->kdim[1])ccv_nnc_cmd(CCV_NNC_AVERAGE_POOL_FORWARD, 0, ((ccv_nnc_cmd_param_t
){.size={.dim={self->kdim[0], self->kdim[1],1}}}), 0)
;
788 ccv_nnc_tensor_param_t output_params;
789 ccv_nnc_hint_tensor_auto(cmd, &params, 1, self->hint, &output_params, 1);
790 const ccv_nnc_tensor_symbol_t pool_output = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
791 const ccv_nnc_graph_exec_symbol_t exec = ccv_nnc_graph_exec_symbol_new(graph, cmd, TENSOR_SYMBOL_LIST(inputs[0])(const ccv_nnc_tensor_symbol_t []){inputs[0]}, (1 +1 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_SYMBOL_LIST(pool_output)(const ccv_nnc_tensor_symbol_t []){pool_output}, (1 +1 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, 0);
792 ccv_nnc_graph_exec_symbol_set_hint(graph, exec, self->hint);
793 outputs[0] = pool_output;
794}
795
796static ccv_cnnp_model_t* _ccv_cnnp_average_pool_copy(const ccv_cnnp_model_t* const super, void* const context);
797
798static const ccv_cnnp_model_vtab_t ccv_cnnp_average_pool_isa = {
799 .build = _ccv_cnnp_average_pool_build,
800 .copy = _ccv_cnnp_average_pool_copy,
801};
802
803ccv_cnnp_model_t* ccv_cnnp_average_pool(const int kdim[CCV_NNC_MAX_DIM_ALLOC(12)], const ccv_nnc_hint_t hint, const char* const name)
804{
805 ccv_cnnp_model_pool_t* const model_pool = (ccv_cnnp_model_pool_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_pool_t));
806 model_pool->super.isa = &ccv_cnnp_average_pool_isa;
807 model_pool->super.input_size = 1;
808 model_pool->super.outputs = &model_pool->output;
809 model_pool->super.output_size = 1;
810 ccv_cnnp_model_copy_name(&model_pool->super, name);
811 memcpy(model_pool->kdim, kdim, sizeof(model_pool->kdim));
812 model_pool->hint = hint;
813 return (ccv_cnnp_model_t*)model_pool;
814}
815
816static ccv_cnnp_model_t* _ccv_cnnp_average_pool_copy(const ccv_cnnp_model_t* const super, void* const context)
817{
818 const ccv_cnnp_model_pool_t* const self = (const ccv_cnnp_model_pool_t*)super;
819 return ccv_cnnp_average_pool(self->kdim, self->hint, self->super.name);
820}
821
822// MARK - RELU Layer
823
824typedef struct {
825 ccv_cnnp_model_t super;
826 ccv_nnc_tensor_symbol_t output;
827} ccv_cnnp_model_relu_t;
828
829static void _ccv_cnnp_relu_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
830{
831 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 831, __extension__ __PRETTY_FUNCTION__); }))
;
832 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 832, __extension__ __PRETTY_FUNCTION__
); }))
;
833 ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
834 ccv_nnc_tensor_param_t output_params;
835 const ccv_nnc_cmd_t relu = CMD_RELU_FORWARD()ccv_nnc_cmd(CCV_NNC_RELU_FORWARD, 0, ccv_nnc_cmd_auto, 0);
836 ccv_nnc_hint_tensor_auto(relu, (ccv_nnc_tensor_param_t []){
837 params,
838 }, 1, ccv_nnc_no_hint, &output_params, 1);
839 const ccv_nnc_tensor_symbol_t relu_output = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
840 ccv_nnc_graph_exec_symbol_new(graph, relu, TENSOR_SYMBOL_LIST(inputs[0])(const ccv_nnc_tensor_symbol_t []){inputs[0]}, (1 +1 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_SYMBOL_LIST(relu_output)(const ccv_nnc_tensor_symbol_t []){relu_output}, (1 +1 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, 0);
841 outputs[0] = relu_output;
842}
843
844static ccv_cnnp_model_t* _ccv_cnnp_relu_copy(const ccv_cnnp_model_t* const self, void* const context);
845
846static const ccv_cnnp_model_vtab_t ccv_cnnp_relu_isa = {
847 .build = _ccv_cnnp_relu_build,
848 .copy = _ccv_cnnp_relu_copy,
849};
850
851ccv_cnnp_model_t* ccv_cnnp_relu(const char* const name)
852{
853 ccv_cnnp_model_relu_t* const model_relu = (ccv_cnnp_model_relu_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_relu_t));
854 model_relu->super.isa = &ccv_cnnp_relu_isa;
855 model_relu->super.input_size = 1;
856 model_relu->super.outputs = &model_relu->output;
857 model_relu->super.output_size = 1;
858 ccv_cnnp_model_copy_name(&model_relu->super, name);
859 return (ccv_cnnp_model_t*)model_relu;
860}
861
862static ccv_cnnp_model_t* _ccv_cnnp_relu_copy(const ccv_cnnp_model_t* const self, void* const context)
863{
864 return ccv_cnnp_relu(self->name);
865}
866
867// MARK - Sigmoid Layer
868
869typedef struct {
870 ccv_cnnp_model_t super;
871 ccv_nnc_tensor_symbol_t output;
872} ccv_cnnp_model_sigmoid_t;
873
874static void _ccv_cnnp_sigmoid_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
875{
876 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 876, __extension__ __PRETTY_FUNCTION__); }))
;
877 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 877, __extension__ __PRETTY_FUNCTION__
); }))
;
878 ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
879 ccv_nnc_tensor_param_t output_params;
880 const ccv_nnc_cmd_t sigmoid = CMD_SIGMOID_FORWARD()ccv_nnc_cmd(CCV_NNC_SIGMOID_FORWARD, 0, ccv_nnc_cmd_auto, 0);
881 ccv_nnc_hint_tensor_auto(sigmoid, (ccv_nnc_tensor_param_t []){
882 params,
883 }, 1, ccv_nnc_no_hint, &output_params, 1);
884 const ccv_nnc_tensor_symbol_t sigmoid_output = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
885 ccv_nnc_graph_exec_symbol_new(graph, sigmoid, TENSOR_SYMBOL_LIST(inputs[0])(const ccv_nnc_tensor_symbol_t []){inputs[0]}, (1 +1 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_SYMBOL_LIST(sigmoid_output)(const ccv_nnc_tensor_symbol_t []){sigmoid_output}, (1 +1 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1
)
, 0);
886 outputs[0] = sigmoid_output;
887}
888
889static ccv_cnnp_model_t* _ccv_cnnp_sigmoid_copy(const ccv_cnnp_model_t* const self, void* const context);
890
891static const ccv_cnnp_model_vtab_t ccv_cnnp_sigmoid_isa = {
892 .build = _ccv_cnnp_sigmoid_build,
893 .copy = _ccv_cnnp_sigmoid_copy,
894};
895
896ccv_cnnp_model_t* ccv_cnnp_sigmoid(const char* const name)
897{
898 ccv_cnnp_model_sigmoid_t* const model_sigmoid = (ccv_cnnp_model_sigmoid_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_sigmoid_t));
899 model_sigmoid->super.isa = &ccv_cnnp_sigmoid_isa;
900 model_sigmoid->super.input_size = 1;
901 model_sigmoid->super.outputs = &model_sigmoid->output;
902 model_sigmoid->super.output_size = 1;
903 ccv_cnnp_model_copy_name(&model_sigmoid->super, name);
904 return (ccv_cnnp_model_t*)model_sigmoid;
905}
906
907static ccv_cnnp_model_t* _ccv_cnnp_sigmoid_copy(const ccv_cnnp_model_t* const self, void* const context)
908{
909 return ccv_cnnp_sigmoid(self->name);
910}
911
912// MARK - Tanh Layer
913
914typedef struct {
915 ccv_cnnp_model_t super;
916 ccv_nnc_tensor_symbol_t output;
917} ccv_cnnp_model_tanh_t;
918
919static void _ccv_cnnp_tanh_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
920{
921 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 921, __extension__ __PRETTY_FUNCTION__); }))
;
922 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 922, __extension__ __PRETTY_FUNCTION__
); }))
;
923 ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
924 ccv_nnc_tensor_param_t output_params;
925 const ccv_nnc_cmd_t tanh = CMD_TANH_FORWARD()ccv_nnc_cmd(CCV_NNC_TANH_FORWARD, 0, ccv_nnc_cmd_auto, 0);
926 ccv_nnc_hint_tensor_auto(tanh, (ccv_nnc_tensor_param_t []){
927 params,
928 }, 1, ccv_nnc_no_hint, &output_params, 1);
929 const ccv_nnc_tensor_symbol_t tanh_output = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
930 ccv_nnc_graph_exec_symbol_new(graph, tanh, TENSOR_SYMBOL_LIST(inputs[0])(const ccv_nnc_tensor_symbol_t []){inputs[0]}, (1 +1 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_SYMBOL_LIST(tanh_output)(const ccv_nnc_tensor_symbol_t []){tanh_output}, (1 +1 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, 0);
931 outputs[0] = tanh_output;
932}
933
934static ccv_cnnp_model_t* _ccv_cnnp_tanh_copy(const ccv_cnnp_model_t* const self, void* const context);
935
936static const ccv_cnnp_model_vtab_t ccv_cnnp_tanh_isa = {
937 .build = _ccv_cnnp_tanh_build,
938 .copy = _ccv_cnnp_tanh_copy,
939};
940
941ccv_cnnp_model_t* ccv_cnnp_tanh(const char* const name)
942{
943 ccv_cnnp_model_tanh_t* const model_tanh = (ccv_cnnp_model_tanh_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_tanh_t));
944 model_tanh->super.isa = &ccv_cnnp_tanh_isa;
945 model_tanh->super.input_size = 1;
946 model_tanh->super.outputs = &model_tanh->output;
947 model_tanh->super.output_size = 1;
948 ccv_cnnp_model_copy_name(&model_tanh->super, name);
949 return (ccv_cnnp_model_t*)model_tanh;
950}
951
952static ccv_cnnp_model_t* _ccv_cnnp_tanh_copy(const ccv_cnnp_model_t* const self, void* const context)
953{
954 return ccv_cnnp_tanh(self->name);
955}
956
957// MARK - Swish Layer
958
959typedef struct {
960 ccv_cnnp_model_t super;
961 ccv_nnc_tensor_symbol_t output;
962} ccv_cnnp_model_swish_t;
963
964static void _ccv_cnnp_swish_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
965{
966 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 966, __extension__ __PRETTY_FUNCTION__); }))
;
967 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 967, __extension__ __PRETTY_FUNCTION__
); }))
;
968 ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
969 ccv_nnc_tensor_param_t output_params;
970 const ccv_nnc_cmd_t swish = CMD_SWISH_FORWARD()ccv_nnc_cmd(CCV_NNC_SWISH_FORWARD, 0, ccv_nnc_cmd_auto, 0);
971 ccv_nnc_hint_tensor_auto(swish, (ccv_nnc_tensor_param_t []){
972 params,
973 }, 1, ccv_nnc_no_hint, &output_params, 1);
974 const ccv_nnc_tensor_symbol_t swish_output = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
975 ccv_nnc_graph_exec_symbol_new(graph, swish, TENSOR_SYMBOL_LIST(inputs[0])(const ccv_nnc_tensor_symbol_t []){inputs[0]}, (1 +1 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_SYMBOL_LIST(swish_output)(const ccv_nnc_tensor_symbol_t []){swish_output}, (1 +1 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, 0);
976 outputs[0] = swish_output;
977}
978
979static ccv_cnnp_model_t* _ccv_cnnp_swish_copy(const ccv_cnnp_model_t* const self, void* const context);
980
981static const ccv_cnnp_model_vtab_t ccv_cnnp_swish_isa = {
982 .build = _ccv_cnnp_swish_build,
983 .copy = _ccv_cnnp_swish_copy,
984};
985
986ccv_cnnp_model_t* ccv_cnnp_swish(const char* const name)
987{
988 ccv_cnnp_model_swish_t* const model_swish = (ccv_cnnp_model_swish_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_swish_t));
989 model_swish->super.isa = &ccv_cnnp_swish_isa;
990 model_swish->super.input_size = 1;
991 model_swish->super.outputs = &model_swish->output;
992 model_swish->super.output_size = 1;
993 ccv_cnnp_model_copy_name(&model_swish->super, name);
994 return (ccv_cnnp_model_t*)model_swish;
995}
996
997static ccv_cnnp_model_t* _ccv_cnnp_swish_copy(const ccv_cnnp_model_t* const self, void* const context)
998{
999 return ccv_cnnp_swish(self->name);
1000}
1001
1002// MARK - Softmax Layer
1003
1004typedef struct {
1005 ccv_cnnp_model_t super;
1006 ccv_nnc_tensor_symbol_t output;
1007} ccv_cnnp_model_softmax_t;
1008
1009static void _ccv_cnnp_softmax_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
1010{
1011 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 1011, __extension__ __PRETTY_FUNCTION__); }))
;
1012 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 1012, __extension__ __PRETTY_FUNCTION__
); }))
;
1013 ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
1014 ccv_nnc_tensor_param_t output_params;
1015 const ccv_nnc_cmd_t softmax = CMD_SOFTMAX_FORWARD()ccv_nnc_cmd(CCV_NNC_SOFTMAX_FORWARD, 0, ccv_nnc_cmd_auto, 0);
1016 ccv_nnc_hint_tensor_auto(softmax, (ccv_nnc_tensor_param_t []){
1017 params,
1018 }, 1, ccv_nnc_no_hint, &output_params, 1);
1019 const ccv_nnc_tensor_symbol_t softmax_output = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
1020 ccv_nnc_graph_exec_symbol_new(graph, softmax, TENSOR_SYMBOL_LIST(inputs[0])(const ccv_nnc_tensor_symbol_t []){inputs[0]}, (1 +1 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_SYMBOL_LIST(softmax_output)(const ccv_nnc_tensor_symbol_t []){softmax_output}, (1 +1 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1
)
, 0);
1021 outputs[0] = softmax_output;
1022}
1023
1024static ccv_cnnp_model_t* _ccv_cnnp_softmax_copy(const ccv_cnnp_model_t* const self, void* const context);
1025
1026static const ccv_cnnp_model_vtab_t ccv_cnnp_softmax_isa = {
1027 .build = _ccv_cnnp_softmax_build,
1028 .copy = _ccv_cnnp_softmax_copy,
1029};
1030
1031ccv_cnnp_model_t* ccv_cnnp_softmax(const char* const name)
1032{
1033 ccv_cnnp_model_softmax_t* const model_softmax = (ccv_cnnp_model_softmax_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_softmax_t));
1034 model_softmax->super.isa = &ccv_cnnp_softmax_isa;
1035 model_softmax->super.input_size = 1;
1036 model_softmax->super.outputs = &model_softmax->output;
1037 model_softmax->super.output_size = 1;
1038 ccv_cnnp_model_copy_name(&model_softmax->super, name);
1039 return (ccv_cnnp_model_t*)model_softmax;
1040}
1041
1042static ccv_cnnp_model_t* _ccv_cnnp_softmax_copy(const ccv_cnnp_model_t* const self, void* const context)
1043{
1044 return ccv_cnnp_softmax(self->name);
1045}
1046
1047// MARK - Add Layer
1048
1049typedef struct {
1050 ccv_cnnp_model_t super;
1051 float p;
1052 float q;
1053 ccv_nnc_tensor_symbol_t output;
1054} ccv_cnnp_model_add_t;
1055
1056static void _ccv_cnnp_add_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
1057{
1058 const ccv_cnnp_model_add_t* const self = (const ccv_cnnp_model_add_t*)super;
1059 assert(input_size == 2)((void) sizeof ((input_size == 2) ? 1 : 0), __extension__ ({ if
(input_size == 2) ; else __assert_fail ("input_size == 2", "ccv_cnnp_model_addons.c"
, 1059, __extension__ __PRETTY_FUNCTION__); }))
;
1060 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 1060, __extension__ __PRETTY_FUNCTION__
); }))
;
1061 ccv_nnc_tensor_param_t input_params[2];
1062 int i;
1063 for (i = 0; i < 2; i++)
1064 input_params[i] = ccv_nnc_tensor_symbol_params(graph, inputs[i]);
1065 ccv_nnc_tensor_param_t output_params;
1066 const ccv_nnc_cmd_t add = CMD_ADD_FORWARD(self->p, self->q)ccv_nnc_cmd(CCV_NNC_ADD_FORWARD, 0, (ccv_nnc_cmd_param_t){.size
={.dim={1,1,1}},.blas={.a={self->p, self->q}}}, 0)
;
1067 ccv_nnc_hint_tensor_auto(add, input_params, 2, ccv_nnc_no_hint, &output_params, 1);
1068 outputs[0] = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
1069 ccv_nnc_graph_exec_symbol_new(graph, add, inputs, input_size, outputs, output_size, 0);
1070}
1071
1072static ccv_cnnp_model_t* _ccv_cnnp_add_copy(const ccv_cnnp_model_t* const self, void* const context);
1073
1074static const ccv_cnnp_model_vtab_t ccv_cnnp_add_isa = {
1075 .build = _ccv_cnnp_add_build,
1076 .copy = _ccv_cnnp_add_copy,
1077};
1078
1079ccv_cnnp_model_t* ccv_cnnp_add(const float p, const float q, const char* const name)
1080{
1081 ccv_cnnp_model_add_t* const model_add = (ccv_cnnp_model_add_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_add_t));
1082 model_add->super.isa = &ccv_cnnp_add_isa;
1083 model_add->super.input_size = 2;
1084 model_add->super.outputs = &model_add->output;
1085 model_add->super.output_size = 1;
1086 model_add->p = p;
1087 model_add->q = q;
1088 ccv_cnnp_model_copy_name(&model_add->super, name);
1089 return (ccv_cnnp_model_t*)model_add;
1090}
1091
1092static ccv_cnnp_model_t* _ccv_cnnp_add_copy(const ccv_cnnp_model_t* const super, void* const context)
1093{
1094 const ccv_cnnp_model_add_t* const self = (const ccv_cnnp_model_add_t*)super;
1095 return ccv_cnnp_add(self->p, self->q, self->super.name);
1096}
1097
1098// MARK - Mul Layer
1099
1100typedef struct {
1101 ccv_cnnp_model_t super;
1102 ccv_nnc_tensor_symbol_t output;
1103 float p;
1104} ccv_cnnp_model_mul_t;
1105
1106static void _ccv_cnnp_mul_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
1107{
1108 const ccv_cnnp_model_mul_t* const self = (const ccv_cnnp_model_mul_t*)super;
1109 assert(input_size == 2)((void) sizeof ((input_size == 2) ? 1 : 0), __extension__ ({ if
(input_size == 2) ; else __assert_fail ("input_size == 2", "ccv_cnnp_model_addons.c"
, 1109, __extension__ __PRETTY_FUNCTION__); }))
;
1110 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 1110, __extension__ __PRETTY_FUNCTION__
); }))
;
1111 ccv_nnc_tensor_param_t input_params[2];
1112 int i;
1113 for (i = 0; i < 2; i++)
1114 input_params[i] = ccv_nnc_tensor_symbol_params(graph, inputs[i]);
1115 ccv_nnc_tensor_param_t output_params;
1116 const ccv_nnc_cmd_t mul = CMD_MUL_FORWARD(self->p)ccv_nnc_cmd(CCV_NNC_MUL_FORWARD, 0, (ccv_nnc_cmd_param_t){.size
={.dim={1,1,1}},.blas={.a={self->p,}}}, 0)
;
1117 ccv_nnc_hint_tensor_auto(mul, input_params, 2, ccv_nnc_no_hint, &output_params, 1);
1118 outputs[0] = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
1119 ccv_nnc_graph_exec_symbol_new(graph, mul, inputs, input_size, outputs, output_size, 0);
1120}
1121
1122static ccv_cnnp_model_t* _ccv_cnnp_mul_copy(const ccv_cnnp_model_t* const self, void* const context);
1123
1124static const ccv_cnnp_model_vtab_t ccv_cnnp_mul_isa = {
1125 .build = _ccv_cnnp_mul_build,
1126 .copy = _ccv_cnnp_mul_copy,
1127};
1128
1129ccv_cnnp_model_t* ccv_cnnp_mul(const float p, const char* const name)
1130{
1131 ccv_cnnp_model_mul_t* const model_mul = (ccv_cnnp_model_mul_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_mul_t));
1132 model_mul->super.isa = &ccv_cnnp_mul_isa;
1133 model_mul->super.input_size = 2;
1134 model_mul->super.outputs = &model_mul->output;
1135 model_mul->super.output_size = 1;
1136 model_mul->p = p;
1137 ccv_cnnp_model_copy_name(&model_mul->super, name);
1138 return (ccv_cnnp_model_t*)model_mul;
1139}
1140
1141static ccv_cnnp_model_t* _ccv_cnnp_mul_copy(const ccv_cnnp_model_t* const super, void* const context)
1142{
1143 const ccv_cnnp_model_mul_t* const self = (const ccv_cnnp_model_mul_t*)super;
1144 return ccv_cnnp_mul(self->p, self->super.name);
1145}
1146
1147// MARK - Scalar Mul Layer
1148
1149typedef struct {
1150 ccv_cnnp_model_t super;
1151 ccv_nnc_tensor_symbol_t output;
1152 float a;
1153} ccv_cnnp_model_scalar_mul_t;
1154
1155static void _ccv_cnnp_scalar_mul_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
1156{
1157 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 1157, __extension__ __PRETTY_FUNCTION__); }))
;
1158 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 1158, __extension__ __PRETTY_FUNCTION__
); }))
;
1159 ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
1160 ccv_nnc_tensor_param_t output_params;
1161 ccv_cnnp_model_scalar_mul_t* const self = (ccv_cnnp_model_scalar_mul_t*)super;
1162 const ccv_nnc_cmd_t scalar_mul = CMD_SCALAR_MUL_FORWARD(self->a)ccv_nnc_cmd(CCV_NNC_SCALAR_MUL_FORWARD, 0, (ccv_nnc_cmd_param_t
){.size={.dim={1,1,1}},.blas={.a={self->a,}}}, 0)
;
1163 ccv_nnc_hint_tensor_auto(scalar_mul, (ccv_nnc_tensor_param_t []){
1164 params,
1165 }, 1, ccv_nnc_no_hint, &output_params, 1);
1166 const ccv_nnc_tensor_symbol_t scalar_mul_output = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
1167 ccv_nnc_graph_exec_symbol_new(graph, scalar_mul, TENSOR_SYMBOL_LIST(inputs[0])(const ccv_nnc_tensor_symbol_t []){inputs[0]}, (1 +1 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_SYMBOL_LIST(scalar_mul_output)(const ccv_nnc_tensor_symbol_t []){scalar_mul_output}, (1 +1 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
-1)
, 0);
1168 outputs[0] = scalar_mul_output;
1169}
1170
1171static ccv_cnnp_model_t* _ccv_cnnp_scalar_mul_copy(const ccv_cnnp_model_t* const super, void* const context);
1172
1173static const ccv_cnnp_model_vtab_t ccv_cnnp_scalar_mul_isa = {
1174 .build = _ccv_cnnp_scalar_mul_build,
1175 .copy = _ccv_cnnp_scalar_mul_copy,
1176};
1177
1178ccv_cnnp_model_t* ccv_cnnp_scalar_mul(const float a, const char* const name)
1179{
1180 ccv_cnnp_model_scalar_mul_t* const model_scalar_mul = (ccv_cnnp_model_scalar_mul_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_scalar_mul_t));
1181 model_scalar_mul->super.isa = &ccv_cnnp_scalar_mul_isa;
1182 model_scalar_mul->super.input_size = 1;
1183 model_scalar_mul->super.outputs = &model_scalar_mul->output;
1184 model_scalar_mul->super.output_size = 1;
1185 model_scalar_mul->a = a;
1186 ccv_cnnp_model_copy_name(&model_scalar_mul->super, name);
1187 return (ccv_cnnp_model_t*)model_scalar_mul;
1188}
1189
1190static ccv_cnnp_model_t* _ccv_cnnp_scalar_mul_copy(const ccv_cnnp_model_t* const super, void* const context)
1191{
1192 const ccv_cnnp_model_scalar_mul_t* const self = (const ccv_cnnp_model_scalar_mul_t*)super;
1193 return ccv_cnnp_scalar_mul(self->a, self->super.name);
1194}
1195
1196// MARK - Transpose Layer
1197
1198typedef struct {
1199 ccv_cnnp_model_t super;
1200 ccv_nnc_tensor_symbol_t output;
1201 int transpose[2];
1202} ccv_cnnp_model_transpose_t;
1203
1204static void _ccv_cnnp_transpose_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
1205{
1206 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 1206, __extension__ __PRETTY_FUNCTION__); }))
;
1207 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 1207, __extension__ __PRETTY_FUNCTION__
); }))
;
1208 ccv_cnnp_model_transpose_t* const self = (ccv_cnnp_model_transpose_t*)super;
1209 if (self->transpose[0] == self->transpose[1])
1210 {
1211 outputs[0] = inputs[0];
1212 return;
1213 }
1214 ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
1215 ccv_nnc_tensor_param_t output_params;
1216 const ccv_nnc_cmd_t transpose = CMD_TRANSPOSE_FORWARD(self->transpose[0], self->transpose[1])ccv_nnc_cmd(CCV_NNC_TRANSPOSE_FORWARD, 0, ((ccv_nnc_cmd_param_t
){.size={.dim={1,1,1}},.transpose={.axis={self->transpose[
0], self->transpose[1]}}}), 0)
;
1217 ccv_nnc_hint_tensor_auto(transpose, (ccv_nnc_tensor_param_t []){
1218 params,
1219 }, 1, ccv_nnc_no_hint, &output_params, 1);
1220 const ccv_nnc_tensor_symbol_t transpose_output = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
1221 ccv_nnc_graph_exec_symbol_new(graph, transpose, TENSOR_SYMBOL_LIST(inputs[0])(const ccv_nnc_tensor_symbol_t []){inputs[0]}, (1 +1 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_SYMBOL_LIST(transpose_output)(const ccv_nnc_tensor_symbol_t []){transpose_output}, (1 +1 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
-1)
, 0);
1222 outputs[0] = transpose_output;
1223}
1224
1225static ccv_cnnp_model_t* _ccv_cnnp_transpose_copy(const ccv_cnnp_model_t* const super, void* const context);
1226
1227static const ccv_cnnp_model_vtab_t ccv_cnnp_transpose_isa = {
1228 .build = _ccv_cnnp_transpose_build,
1229 .copy = _ccv_cnnp_transpose_copy,
1230};
1231
1232ccv_cnnp_model_t* ccv_cnnp_transpose(const int axis_a, const int axis_b, const char* const name)
1233{
1234 ccv_cnnp_model_transpose_t* const model_transpose = (ccv_cnnp_model_transpose_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_transpose_t));
1235 model_transpose->super.isa = &ccv_cnnp_transpose_isa;
1236 model_transpose->super.input_size = 1;
1237 model_transpose->super.outputs = &model_transpose->output;
1238 model_transpose->super.output_size = 1;
1239 model_transpose->transpose[0] = axis_a;
1240 model_transpose->transpose[1] = axis_b;
1241 ccv_cnnp_model_copy_name(&model_transpose->super, name);
1242 return (ccv_cnnp_model_t*)model_transpose;
1243}
1244
1245static ccv_cnnp_model_t* _ccv_cnnp_transpose_copy(const ccv_cnnp_model_t* const super, void* const context)
1246{
1247 const ccv_cnnp_model_transpose_t* const self = (const ccv_cnnp_model_transpose_t*)super;
1248 return ccv_cnnp_transpose(self->transpose[0], self->transpose[1], self->super.name);
1249}
1250
1251// MARK - Layer Norm Layer
1252
1253typedef struct {
1254 ccv_cnnp_model_t super;
1255 ccv_nnc_tensor_symbol_t output;
1256 ccv_nnc_tensor_symbol_t bias;
1257 ccv_nnc_tensor_symbol_t scale;
1258 ccv_nnc_cmd_param_t params;
1259} ccv_cnnp_model_layer_norm_t;
1260
1261static void _ccv_cnnp_layer_norm_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
1262{
1263 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 1263, __extension__ __PRETTY_FUNCTION__); }))
;
1264 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 1264, __extension__ __PRETTY_FUNCTION__
); }))
;
1265 ccv_cnnp_model_layer_norm_t* const self = (ccv_cnnp_model_layer_norm_t*)super;
1266 const ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
1267 ccv_nnc_tensor_param_t bias_params = params;
1268 // If the accuracy is not enough, bump it to 32-bit floating point.
1269 if (bias_params.datatype != CCV_32F && bias_params.datatype != CCV_64F)
1270 bias_params.datatype = CCV_32F;
1271 const int nd = ccv_nnc_tensor_nd(params.dim);
1272 int i;
1273 for (i = 0; i < nd; i++)
1274 bias_params.dim[i] = 1;
1275 for (i = 0; i < self->params.lnorm.count; i++)
1276 bias_params.dim[self->params.lnorm.axis[i]] = params.dim[self->params.lnorm.axis[i]];
1277 // Both scale and bias are shared between if this model is reused.
1278 if (!self->scale.graph)
1279 self->scale = ccv_nnc_tensor_symbol_new(graph, bias_params, 0);
1280 if (!self->bias.graph)
1281 self->bias = ccv_nnc_tensor_symbol_new(graph, bias_params, 0);
1282 const ccv_nnc_cmd_t layer_norm = ccv_nnc_cmd(CCV_NNC_LAYER_NORM_FORWARD, 0, self->params, 0);
1283 ccv_nnc_tensor_param_t output_params[3];
1284 ccv_nnc_hint_tensor_auto(layer_norm, (ccv_nnc_tensor_param_t []){
1285 params,
1286 bias_params,
1287 bias_params,
1288 }, 3, ccv_nnc_no_hint, output_params, 3);
1289 const ccv_nnc_tensor_symbol_t output = ccv_nnc_tensor_symbol_new(graph, output_params[0], 0);
1290 const ccv_nnc_tensor_symbol_t saved_mean = ccv_nnc_tensor_symbol_new(graph, output_params[1], 0);
1291 const ccv_nnc_tensor_symbol_t saved_inv_std = ccv_nnc_tensor_symbol_new(graph, output_params[2], 0);
1292 ccv_nnc_graph_exec_symbol_new(graph, layer_norm, TENSOR_SYMBOL_LIST(inputs[0], self->scale, self->bias)(const ccv_nnc_tensor_symbol_t []){inputs[0], self->scale,
self->bias}, (1 +1 +1 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_SYMBOL_LIST(output, saved_mean, saved_inv_std)(const ccv_nnc_tensor_symbol_t []){output, saved_mean, saved_inv_std
}, (1 +1 +1 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 -1)
, 0);
1293 outputs[0] = output;
1294}
1295
1296static void _ccv_cnnp_layer_norm_init_states(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_cnnp_state_initializer_f initializer, void* const context)
1297{
1298 ccv_cnnp_model_layer_norm_t* const self = (ccv_cnnp_model_layer_norm_t*)super;
1299 if (self->bias.graph)
1300 initializer(context, CMD_SET_FORWARD(0)ccv_nnc_cmd(CCV_NNC_SET_FORWARD, 0, (ccv_nnc_cmd_param_t){.size
={.dim={1,1,1}},.blas={.a={0,}}}, 0)
, ccv_nnc_no_hint, 0, 0, self->bias);
1301 if (self->scale.graph)
1302 initializer(context, CMD_RANDOM_UNIFORM_FORWARD(0, 1)ccv_nnc_cmd(CCV_NNC_RANDOM_UNIFORM_FORWARD, 0, (ccv_nnc_cmd_param_t
){.size={.dim={1,1,1}},.blas={.a={0, 1}}}, 0)
, ccv_nnc_no_hint, 0, 0, self->scale);
1303}
1304
1305static void _ccv_cnnp_layer_norm_add_to_parameter(ccv_cnnp_model_t* const super, const ccv_cnnp_add_to_array_f add_to_array, void* const parameters)
1306{
1307 ccv_cnnp_model_layer_norm_t* const self = (ccv_cnnp_model_layer_norm_t*)super;
1308 if (self->bias.graph)
1309 add_to_array(parameters, self->bias);
1310 if (self->scale.graph)
1311 add_to_array(parameters, self->scale);
1312}
1313
1314static ccv_cnnp_model_t* _ccv_cnnp_layer_norm_copy(const ccv_cnnp_model_t* const super, void* const context);
1315
1316static const ccv_cnnp_model_vtab_t ccv_cnnp_layer_norm_isa = {
1317 .build = _ccv_cnnp_layer_norm_build,
1318 .init_states = _ccv_cnnp_layer_norm_init_states,
1319 .add_to_parameter = _ccv_cnnp_layer_norm_add_to_parameter,
1320 .copy = _ccv_cnnp_layer_norm_copy,
1321};
1322
1323ccv_cnnp_model_t* ccv_cnnp_layer_norm(const float epsilon, const int axis[CCV_NNC_MAX_DIM_ALLOC(12)], const int axis_count, const char* const name)
1324{
1325 ccv_cnnp_model_layer_norm_t* const model_layer_norm = (ccv_cnnp_model_layer_norm_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_layer_norm_t));
1326 model_layer_norm->super.isa = &ccv_cnnp_layer_norm_isa;
1327 model_layer_norm->super.input_size = 1;
1328 model_layer_norm->super.outputs = &model_layer_norm->output;
1329 model_layer_norm->super.output_size = 1;
1330 ccv_cnnp_model_copy_name(&model_layer_norm->super, name);
1331 model_layer_norm->scale.d = CCV_NNC_NO_TENSOR_SYMBOL;
1332 model_layer_norm->scale.graph = 0;
1333 model_layer_norm->bias.d = CCV_NNC_NO_TENSOR_SYMBOL;
1334 model_layer_norm->bias.graph = 0;
1335 model_layer_norm->params.lnorm.epsilon = epsilon;
1336 model_layer_norm->params.lnorm.count = axis_count;
1337 memcpy(model_layer_norm->params.lnorm.axis, axis, sizeof(model_layer_norm->params.lnorm.axis));
1338 return (ccv_cnnp_model_t*)model_layer_norm;
1339}
1340
1341static ccv_cnnp_model_t* _ccv_cnnp_layer_norm_copy(const ccv_cnnp_model_t* const super, void* const context)
1342{
1343 const ccv_cnnp_model_layer_norm_t* const self = (const ccv_cnnp_model_layer_norm_t*)super;
1344 return ccv_cnnp_layer_norm(self->params.lnorm.epsilon, self->params.lnorm.axis, self->params.lnorm.count, self->super.name);
1345}
1346
1347// MARK - Batched Matrix Mul Layer
1348
1349typedef struct {
1350 ccv_cnnp_model_t super;
1351 ccv_nnc_tensor_symbol_t output;
1352 int transpose_a[2];
1353 int transpose_b[2];
1354} ccv_cnnp_model_matmul_t;
1355
1356static void _ccv_cnnp_matmul_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
1357{
1358 assert(input_size == 2)((void) sizeof ((input_size == 2) ? 1 : 0), __extension__ ({ if
(input_size == 2) ; else __assert_fail ("input_size == 2", "ccv_cnnp_model_addons.c"
, 1358, __extension__ __PRETTY_FUNCTION__); }))
;
1359 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 1359, __extension__ __PRETTY_FUNCTION__
); }))
;
1360 ccv_cnnp_model_matmul_t* const self = (ccv_cnnp_model_matmul_t*)super;
1361 ccv_nnc_tensor_param_t a_params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
1362 ccv_nnc_tensor_param_t b_params = ccv_nnc_tensor_symbol_params(graph, inputs[1]);
1363 ccv_nnc_tensor_param_t output_params;
1364 const ccv_nnc_cmd_t matmul = CMD_GEMM_FORWARD(self->transpose_a, self->transpose_b)ccv_nnc_cmd(CCV_NNC_GEMM_FORWARD, 0, ((ccv_nnc_cmd_param_t){.
size={.dim={1,1,1}},.blas={.a={1,1},.transpose_a={self->transpose_a
[0],self->transpose_a[1]},.transpose_b={self->transpose_b
[0],self->transpose_b[1]},}}), 0)
;
1365 ccv_nnc_hint_tensor_auto(matmul, (ccv_nnc_tensor_param_t []){
1366 a_params,
1367 b_params,
1368 }, 2, ccv_nnc_no_hint, &output_params, 1);
1369 const ccv_nnc_tensor_symbol_t matmul_output = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
1370 ccv_nnc_graph_exec_symbol_new(graph, matmul, inputs, input_size, TENSOR_SYMBOL_LIST(matmul_output)(const ccv_nnc_tensor_symbol_t []){matmul_output}, (1 +1 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1
)
, 0);
1371 outputs[0] = matmul_output;
1372}
1373
1374static ccv_cnnp_model_t* _ccv_cnnp_matmul_copy(const ccv_cnnp_model_t* const super, void* const context);
1375
1376static const ccv_cnnp_model_vtab_t ccv_cnnp_matmul_isa = {
1377 .build = _ccv_cnnp_matmul_build,
1378 .copy = _ccv_cnnp_matmul_copy,
1379};
1380
1381ccv_cnnp_model_t* ccv_cnnp_matmul(const int transpose_a[2], const int transpose_b[2], const char* const name)
1382{
1383 ccv_cnnp_model_matmul_t* const model_matmul = (ccv_cnnp_model_matmul_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_matmul_t));
1384 model_matmul->super.isa = &ccv_cnnp_matmul_isa;
1385 model_matmul->super.input_size = 2;
1386 model_matmul->super.outputs = &model_matmul->output;
1387 model_matmul->super.output_size = 1;
1388 model_matmul->transpose_a[0] = transpose_a[0];
1389 model_matmul->transpose_a[1] = transpose_a[1];
1390 model_matmul->transpose_b[0] = transpose_b[0];
1391 model_matmul->transpose_b[1] = transpose_b[1];
1392 ccv_cnnp_model_copy_name(&model_matmul->super, name);
1393 return (ccv_cnnp_model_t*)model_matmul;
1394}
1395
1396static ccv_cnnp_model_t* _ccv_cnnp_matmul_copy(const ccv_cnnp_model_t* const super, void* const context)
1397{
1398 const ccv_cnnp_model_matmul_t* const self = (const ccv_cnnp_model_matmul_t*)super;
1399 return ccv_cnnp_matmul(self->transpose_a, self->transpose_b, self->super.name);
1400}
1401
1402// MARK - Dropout Layer
1403
1404typedef struct {
1405 ccv_cnnp_model_t super;
1406 ccv_nnc_tensor_symbol_t output;
1407 ccv_nnc_graph_exec_symbol_t dropout;
1408 float p;
1409 int entirety;
1410} ccv_cnnp_model_dropout_t;
1411
1412static void _ccv_cnnp_dropout_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
1413{
1414 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 1414, __extension__ __PRETTY_FUNCTION__); }))
;
1415 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 1415, __extension__ __PRETTY_FUNCTION__
); }))
;
1416 ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
1417 ccv_nnc_tensor_param_t output_params[2];
1418 ccv_cnnp_model_dropout_t* const self = (ccv_cnnp_model_dropout_t*)super;
1419 const ccv_nnc_cmd_t dropout = CMD_DROPOUT_FORWARD(self->p, self->entirety)ccv_nnc_cmd(CCV_NNC_DROPOUT_FORWARD, 0, ((ccv_nnc_cmd_param_t
){.size={.dim={1,1,1}},.dropout={.p=self->p,.entirety=self
->entirety}}), 0)
;
1420 ccv_nnc_hint_tensor_auto(dropout, (ccv_nnc_tensor_param_t []){
1421 params,
1422 }, 1, ccv_nnc_no_hint, output_params, 2);
1423 const ccv_nnc_tensor_symbol_t dropout_output = ccv_nnc_tensor_symbol_new(graph, output_params[0], 0);
1424 const ccv_nnc_tensor_symbol_t mask = ccv_nnc_tensor_symbol_new(graph, output_params[1], 0);
1425 self->dropout = ccv_nnc_graph_exec_symbol_new(graph, dropout, TENSOR_SYMBOL_LIST(inputs[0])(const ccv_nnc_tensor_symbol_t []){inputs[0]}, (1 +1 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_SYMBOL_LIST(dropout_output, mask)(const ccv_nnc_tensor_symbol_t []){dropout_output, mask}, (1 +
1 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 -1)
, 0);
1426 outputs[0] = dropout_output;
1427}
1428
1429static void _ccv_cnnp_dropout_set_is_test(ccv_cnnp_model_t* const super, const int is_test, const ccv_cnnp_cmd_updater_f updater, void* const context)
1430{
1431 ccv_cnnp_model_dropout_t* const self = (ccv_cnnp_model_dropout_t*)super;
1432 if (self->dropout.graph)
1433 {
1434 if (is_test)
1435 // During test, the dropout is not applied. Data transfer is perfect because if these are the same tensor, it will skip.
1436 updater(context, self->dropout, CMD_DATA_TRANSFER_FORWARD()ccv_nnc_cmd(CCV_NNC_DATA_TRANSFER_FORWARD, 0, ccv_nnc_cmd_auto
, 0)
, ccv_nnc_no_hint);
1437 else
1438 updater(context, self->dropout, CMD_DROPOUT_FORWARD(self->p, self->entirety)ccv_nnc_cmd(CCV_NNC_DROPOUT_FORWARD, 0, ((ccv_nnc_cmd_param_t
){.size={.dim={1,1,1}},.dropout={.p=self->p,.entirety=self
->entirety}}), 0)
, ccv_nnc_no_hint);
1439 }
1440}
1441
1442static ccv_cnnp_model_t* _ccv_cnnp_dropout_copy(const ccv_cnnp_model_t* const super, void* const context);
1443
1444static const ccv_cnnp_model_vtab_t ccv_cnnp_dropout_isa = {
1445 .build = _ccv_cnnp_dropout_build,
1446 .set_is_test = _ccv_cnnp_dropout_set_is_test,
1447 .copy = _ccv_cnnp_dropout_copy,
1448};
1449
1450ccv_cnnp_model_t* ccv_cnnp_dropout(const float p, const int entirety, const char* const name)
1451{
1452 ccv_cnnp_model_dropout_t* const model_dropout = (ccv_cnnp_model_dropout_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_dropout_t));
1453 model_dropout->super.isa = &ccv_cnnp_dropout_isa;
1454 model_dropout->super.input_size = 1;
1455 model_dropout->super.outputs = &model_dropout->output;
1456 model_dropout->super.output_size = 1;
1457 model_dropout->p = p;
1458 model_dropout->entirety = entirety;
1459 ccv_cnnp_model_copy_name(&model_dropout->super, name);
1460 return (ccv_cnnp_model_t*)model_dropout;
1461}
1462
1463static ccv_cnnp_model_t* _ccv_cnnp_dropout_copy(const ccv_cnnp_model_t* const super, void* const context)
1464{
1465 const ccv_cnnp_model_dropout_t* const self = (const ccv_cnnp_model_dropout_t*)super;
1466 return ccv_cnnp_dropout(self->p, self->entirety, self->super.name);
1467}
1468
1469// MARK - Masked Fill Layer
1470
1471typedef struct {
1472 ccv_cnnp_model_t super;
1473 ccv_nnc_tensor_symbol_t output;
1474 float eq;
1475 float fill;
1476} ccv_cnnp_model_masked_fill_t;
1477
1478static void _ccv_cnnp_masked_fill_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
1479{
1480 assert(input_size == 2)((void) sizeof ((input_size == 2) ? 1 : 0), __extension__ ({ if
(input_size == 2) ; else __assert_fail ("input_size == 2", "ccv_cnnp_model_addons.c"
, 1480, __extension__ __PRETTY_FUNCTION__); }))
;
1481 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 1481, __extension__ __PRETTY_FUNCTION__
); }))
;
1482 ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
1483 ccv_cnnp_model_masked_fill_t* const self = (ccv_cnnp_model_masked_fill_t*)super;
1484 const ccv_nnc_tensor_symbol_t masked_fill_output = ccv_nnc_tensor_symbol_new(graph, params, 0);
1485 ccv_nnc_graph_exec_symbol_new(graph, CMD_MASKED_FILL_FORWARD(self->eq, self->fill)ccv_nnc_cmd(CCV_NNC_MASKED_FILL_FORWARD, 0, (ccv_nnc_cmd_param_t
){.size={.dim={1,1,1}},.blas={.a={self->eq, self->fill}
}}, 0)
, TENSOR_SYMBOL_LIST(inputs[0], inputs[1])(const ccv_nnc_tensor_symbol_t []){inputs[0], inputs[1]}, (1 +
1 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 -1)
, TENSOR_SYMBOL_LIST(masked_fill_output)(const ccv_nnc_tensor_symbol_t []){masked_fill_output}, (1 +1
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 -1)
, 0);
1486 outputs[0] = masked_fill_output;
1487}
1488
1489static ccv_cnnp_model_t* _ccv_cnnp_masked_fill_copy(const ccv_cnnp_model_t* const super, void* const context);
1490
1491static const ccv_cnnp_model_vtab_t ccv_cnnp_masked_fill_isa = {
1492 .build = _ccv_cnnp_masked_fill_build,
1493 .copy = _ccv_cnnp_masked_fill_copy,
1494};
1495
1496ccv_cnnp_model_t* ccv_cnnp_masked_fill(const float eq, const float fill, const char* const name)
1497{
1498 ccv_cnnp_model_masked_fill_t* const model_masked_fill = (ccv_cnnp_model_masked_fill_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_masked_fill_t));
1499 model_masked_fill->super.isa = &ccv_cnnp_masked_fill_isa;
1500 model_masked_fill->super.input_size = 2;
1501 model_masked_fill->super.outputs = &model_masked_fill->output;
1502 model_masked_fill->super.output_size = 1;
1503 model_masked_fill->eq = eq;
1504 model_masked_fill->fill = fill;
1505 ccv_cnnp_model_copy_name(&model_masked_fill->super, name);
1506 return (ccv_cnnp_model_t*)model_masked_fill;
1507}
1508
1509static ccv_cnnp_model_t* _ccv_cnnp_masked_fill_copy(const ccv_cnnp_model_t* const super, void* const context)
1510{
1511 const ccv_cnnp_model_masked_fill_t* const self = (const ccv_cnnp_model_masked_fill_t*)super;
1512 return ccv_cnnp_masked_fill(self->eq, self->fill, self->super.name);
1513}
1514
1515// MARK - Index Select Layer
1516
1517typedef struct {
1518 ccv_cnnp_model_t super;
1519 ccv_nnc_tensor_symbol_t output;
1520} ccv_cnnp_model_index_select_t;
1521
1522static void _ccv_cnnp_index_select_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
1523{
1524 assert(input_size == 2)((void) sizeof ((input_size == 2) ? 1 : 0), __extension__ ({ if
(input_size == 2) ; else __assert_fail ("input_size == 2", "ccv_cnnp_model_addons.c"
, 1524, __extension__ __PRETTY_FUNCTION__); }))
;
1525 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 1525, __extension__ __PRETTY_FUNCTION__
); }))
;
1526 const ccv_nnc_tensor_param_t vocab_params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
1527 const ccv_nnc_tensor_param_t index_params = ccv_nnc_tensor_symbol_params(graph, inputs[1]);
1528 ccv_nnc_tensor_param_t output_params;
1529 const ccv_nnc_cmd_t index_select = CMD_INDEX_SELECT_FORWARD()ccv_nnc_cmd(CCV_NNC_INDEX_SELECT_FORWARD, 0, ccv_nnc_cmd_auto
, 0)
;
1530 ccv_nnc_hint_tensor_auto(index_select, (ccv_nnc_tensor_param_t []){
1531 vocab_params,
1532 index_params,
1533 }, 2, ccv_nnc_no_hint, &output_params, 1);
1534 const ccv_nnc_tensor_symbol_t output = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
1535 ccv_nnc_graph_exec_symbol_new(graph, index_select, TENSOR_SYMBOL_LIST(inputs[0], inputs[1])(const ccv_nnc_tensor_symbol_t []){inputs[0], inputs[1]}, (1 +
1 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 -1)
, TENSOR_SYMBOL_LIST(output)(const ccv_nnc_tensor_symbol_t []){output}, (1 +1 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, 0);
1536 outputs[0] = output;
1537}
1538
1539static ccv_cnnp_model_t* _ccv_cnnp_index_select_copy(const ccv_cnnp_model_t* const super, void* const context);
1540
1541static const ccv_cnnp_model_vtab_t ccv_cnnp_index_select_isa = {
1542 .build = _ccv_cnnp_index_select_build,
1543 .copy = _ccv_cnnp_index_select_copy,
1544};
1545
1546ccv_cnnp_model_t* ccv_cnnp_index_select(const char* const name)
1547{
1548 ccv_cnnp_model_index_select_t* const model_index_select = (ccv_cnnp_model_index_select_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_index_select_t));
1549 model_index_select->super.isa = &ccv_cnnp_index_select_isa;
1550 model_index_select->super.input_size = 2;
1551 model_index_select->super.outputs = &model_index_select->output;
1552 model_index_select->super.output_size = 1;
1553 ccv_cnnp_model_copy_name(&model_index_select->super, name);
1554 return (ccv_cnnp_model_t*)model_index_select;
1555}
1556
1557static ccv_cnnp_model_t* _ccv_cnnp_index_select_copy(const ccv_cnnp_model_t* const super, void* const context)
1558{
1559 ccv_cnnp_model_index_select_t* const self = (ccv_cnnp_model_index_select_t*)super;
1560 return ccv_cnnp_index_select(self->super.name);
1561}
1562
1563// MARK - Embedding Layer
1564
1565typedef struct {
1566 ccv_cnnp_model_t super;
1567 ccv_nnc_tensor_symbol_t output;
1568 ccv_nnc_tensor_symbol_t vocab;
1569 int datatype;
1570 int vocab_size;
1571 int embed_size;
1572} ccv_cnnp_model_embedding_t;
1573
1574static void _ccv_cnnp_embedding_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
1575{
1576 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 1576, __extension__ __PRETTY_FUNCTION__); }))
;
1577 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 1577, __extension__ __PRETTY_FUNCTION__
); }))
;
1578 ccv_cnnp_model_embedding_t* const self = (ccv_cnnp_model_embedding_t*)super;
1579 const ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
1580 ccv_nnc_tensor_param_t vocab_params = params;
1581 memset(vocab_params.dim, 0, sizeof(vocab_params.dim));
1582 vocab_params.datatype = self->datatype;
1583 vocab_params.dim[0] = self->vocab_size;
1584 vocab_params.dim[1] = self->embed_size;
1585 if (!self->vocab.graph)
1586 self->vocab = ccv_nnc_tensor_symbol_new(graph, vocab_params, 0);
1587 assert(self->vocab.graph == graph)((void) sizeof ((self->vocab.graph == graph) ? 1 : 0), __extension__
({ if (self->vocab.graph == graph) ; else __assert_fail (
"self->vocab.graph == graph", "ccv_cnnp_model_addons.c", 1587
, __extension__ __PRETTY_FUNCTION__); }))
;
1588 ccv_nnc_tensor_param_t output_params;
1589 const ccv_nnc_cmd_t embedding = CMD_INDEX_SELECT_FORWARD()ccv_nnc_cmd(CCV_NNC_INDEX_SELECT_FORWARD, 0, ccv_nnc_cmd_auto
, 0)
;
1590 ccv_nnc_hint_tensor_auto(embedding, (ccv_nnc_tensor_param_t []){
1591 vocab_params,
1592 params,
1593 }, 2, ccv_nnc_no_hint, &output_params, 1);
1594 const ccv_nnc_tensor_symbol_t output = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
1595 ccv_nnc_graph_exec_symbol_new(graph, embedding, TENSOR_SYMBOL_LIST(self->vocab, inputs[0])(const ccv_nnc_tensor_symbol_t []){self->vocab, inputs[0]}
, (1 +1 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 -1)
, TENSOR_SYMBOL_LIST(output)(const ccv_nnc_tensor_symbol_t []){output}, (1 +1 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, 0);
1596 outputs[0] = output;
1597}
1598
1599static void _ccv_cnnp_embedding_init_states(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_cnnp_state_initializer_f initializer, void* const context)
1600{
1601 ccv_cnnp_model_embedding_t* const self = (ccv_cnnp_model_embedding_t*)super;
1602 const float std = sqrtf(2) / sqrtf(self->vocab_size + self->embed_size);
1603 const float bound = sqrtf(3) * std;
1604 initializer(context, CMD_RANDOM_UNIFORM_FORWARD(-bound, bound)ccv_nnc_cmd(CCV_NNC_RANDOM_UNIFORM_FORWARD, 0, (ccv_nnc_cmd_param_t
){.size={.dim={1,1,1}},.blas={.a={-bound, bound}}}, 0)
, ccv_nnc_no_hint, 0, 0, self->vocab);
1605}
1606
1607static void _ccv_cnnp_embedding_add_to_parameter(ccv_cnnp_model_t* const super, const ccv_cnnp_add_to_array_f add_to_array, void* const parameters)
1608{
1609 ccv_cnnp_model_embedding_t* const self = (ccv_cnnp_model_embedding_t*)super;
1610 add_to_array(parameters, self->vocab);
1611}
1612
1613static ccv_cnnp_model_t* _ccv_cnnp_embedding_copy(const ccv_cnnp_model_t* const super, void* const context);
1614
1615static const ccv_cnnp_model_vtab_t ccv_cnnp_embedding_isa = {
1616 .build = _ccv_cnnp_embedding_build,
1617 .init_states = _ccv_cnnp_embedding_init_states,
1618 .add_to_parameter = _ccv_cnnp_embedding_add_to_parameter,
1619 .copy = _ccv_cnnp_embedding_copy,
1620};
1621
1622ccv_cnnp_model_t* ccv_cnnp_embedding(const int datatype, const int vocab_size, const int embed_size, const char* const name)
1623{
1624 ccv_cnnp_model_embedding_t* const model_embedding = (ccv_cnnp_model_embedding_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_embedding_t));
1625 model_embedding->super.isa = &ccv_cnnp_embedding_isa;
1626 model_embedding->super.input_size = 1;
1627 model_embedding->super.outputs = &model_embedding->output;
1628 model_embedding->super.output_size = 1;
1629 ccv_cnnp_model_copy_name(&model_embedding->super, name);
1630 model_embedding->vocab.d = CCV_NNC_NO_TENSOR_SYMBOL;
1631 model_embedding->vocab.graph = 0;
1632 assert(datatype == CCV_32F || datatype == CCV_16F)((void) sizeof ((datatype == CCV_32F || datatype == CCV_16F) ?
1 : 0), __extension__ ({ if (datatype == CCV_32F || datatype
== CCV_16F) ; else __assert_fail ("datatype == CCV_32F || datatype == CCV_16F"
, "ccv_cnnp_model_addons.c", 1632, __extension__ __PRETTY_FUNCTION__
); }))
;
1633 model_embedding->datatype = datatype;
1634 assert(vocab_size > 0)((void) sizeof ((vocab_size > 0) ? 1 : 0), __extension__ (
{ if (vocab_size > 0) ; else __assert_fail ("vocab_size > 0"
, "ccv_cnnp_model_addons.c", 1634, __extension__ __PRETTY_FUNCTION__
); }))
;
1635 model_embedding->vocab_size = vocab_size;
1636 assert(embed_size > 0)((void) sizeof ((embed_size > 0) ? 1 : 0), __extension__ (
{ if (embed_size > 0) ; else __assert_fail ("embed_size > 0"
, "ccv_cnnp_model_addons.c", 1636, __extension__ __PRETTY_FUNCTION__
); }))
;
1637 model_embedding->embed_size = embed_size;
1638 return (ccv_cnnp_model_t*)model_embedding;
1639}
1640
1641static ccv_cnnp_model_t* _ccv_cnnp_embedding_copy(const ccv_cnnp_model_t* const super, void* const context)
1642{
1643 ccv_cnnp_model_embedding_t* const self = (ccv_cnnp_model_embedding_t*)super;
1644 return ccv_cnnp_embedding(self->datatype, self->vocab_size, self->embed_size, self->super.name);
1645}
1646
1647// MARK - Pool Layers
1648
1649typedef struct {
1650 ccv_cnnp_model_t super;
1651 ccv_nnc_tensor_symbol_t output;
1652 float width_scale;
1653 float height_scale;
1654} ccv_cnnp_model_upsample_t;
1655
1656static void _ccv_cnnp_upsample_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
1657{
1658 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 1658, __extension__ __PRETTY_FUNCTION__); }))
;
1659 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 1659, __extension__ __PRETTY_FUNCTION__
); }))
;
1660 ccv_cnnp_model_upsample_t* const self = (ccv_cnnp_model_upsample_t*)super;
1661 const ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
1662 ccv_nnc_cmd_t cmd = CMD_UPSAMPLE_BILINEAR_FORWARD(self->width_scale, self->height_scale)ccv_nnc_cmd(CCV_NNC_UPSAMPLE_BILINEAR_FORWARD, 0, ((ccv_nnc_cmd_param_t
){.size={.dim={1,1,1}},.upsample={.width_scale=self->width_scale
,.height_scale=self->height_scale}}), 0)
;
1663 ccv_nnc_tensor_param_t output_params;
1664 ccv_nnc_hint_tensor_auto(cmd, &params, 1, ccv_nnc_no_hint, &output_params, 1);
1665 const ccv_nnc_tensor_symbol_t output = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
1666 ccv_nnc_graph_exec_symbol_new(graph, cmd, TENSOR_SYMBOL_LIST(inputs[0])(const ccv_nnc_tensor_symbol_t []){inputs[0]}, (1 +1 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, TENSOR_SYMBOL_LIST(output)(const ccv_nnc_tensor_symbol_t []){output}, (1 +1 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1)
, 0);
1667 outputs[0] = output;
1668}
1669
1670static ccv_cnnp_model_t* _ccv_cnnp_upsample_copy(const ccv_cnnp_model_t* const super, void* const context);
1671
1672static const ccv_cnnp_model_vtab_t ccv_cnnp_upsample_isa = {
1673 .build = _ccv_cnnp_upsample_build,
1674 .copy = _ccv_cnnp_upsample_copy,
1675};
1676
1677ccv_cnnp_model_t* ccv_cnnp_upsample(const float width_scale, const float height_scale, const char* const name)
1678{
1679 ccv_cnnp_model_upsample_t* const model_upsample = (ccv_cnnp_model_upsample_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_upsample_t));
1680 model_upsample->super.isa = &ccv_cnnp_upsample_isa;
1681 model_upsample->super.input_size = 1;
1682 model_upsample->super.outputs = &model_upsample->output;
1683 model_upsample->super.output_size = 1;
1684 ccv_cnnp_model_copy_name(&model_upsample->super, name);
1685 model_upsample->width_scale = width_scale;
1686 model_upsample->height_scale = height_scale;
1687 return (ccv_cnnp_model_t*)model_upsample;
1688}
1689
1690static ccv_cnnp_model_t* _ccv_cnnp_upsample_copy(const ccv_cnnp_model_t* const super, void* const context)
1691{
1692 const ccv_cnnp_model_upsample_t* const self = (const ccv_cnnp_model_upsample_t*)super;
1693 return ccv_cnnp_upsample(self->width_scale, self->height_scale, self->super.name);
1694}
1695
1696// MARK - Reduce Sum Layer
1697
1698typedef struct {
1699 ccv_cnnp_model_t super;
1700 int axis[CCV_NNC_MAX_DIM_ALLOC(12)];
1701 int count;
1702 ccv_nnc_tensor_symbol_t output;
1703} ccv_cnnp_model_reduce_sum_t;
1704
1705static void _ccv_cnnp_reduce_sum_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
1706{
1707 const ccv_cnnp_model_reduce_sum_t* const self = (const ccv_cnnp_model_reduce_sum_t*)super;
1708 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 1708, __extension__ __PRETTY_FUNCTION__); }))
;
1709 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 1709, __extension__ __PRETTY_FUNCTION__
); }))
;
1710 ccv_nnc_tensor_param_t input_params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
1711 ccv_nnc_tensor_param_t output_params;
1712 ccv_nnc_cmd_t reduce_sum = CMD_REDUCE_SUM_FORWARD()ccv_nnc_cmd(CCV_NNC_REDUCE_SUM_FORWARD, 0, ((ccv_nnc_cmd_param_t
){.size={.dim={1,1,1}},.reduce={.count=(1 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1),.axis={}}}
), 0)
;
1713 int i;
1714 for (i = 0; i < self->count; i++)
1715 reduce_sum.info.reduce.axis[i] = self->axis[i];
1716 reduce_sum.info.reduce.count = self->count;
1717 ccv_nnc_hint_tensor_auto(reduce_sum, &input_params, 1, ccv_nnc_no_hint, &output_params, 1);
1718 outputs[0] = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
1719 ccv_nnc_graph_exec_symbol_new(graph, reduce_sum, inputs, input_size, outputs, output_size, 0);
1720}
1721
1722static ccv_cnnp_model_t* _ccv_cnnp_reduce_sum_copy(const ccv_cnnp_model_t* const self, void* const context);
1723
1724static const ccv_cnnp_model_vtab_t ccv_cnnp_reduce_sum_isa = {
1725 .build = _ccv_cnnp_reduce_sum_build,
1726 .copy = _ccv_cnnp_reduce_sum_copy,
1727};
1728
1729ccv_cnnp_model_t* ccv_cnnp_reduce_sum(const int* const axis, const int axis_count, const char* const name)
1730{
1731 ccv_cnnp_model_reduce_sum_t* const model_reduce_sum = (ccv_cnnp_model_reduce_sum_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_reduce_sum_t));
1732 model_reduce_sum->super.isa = &ccv_cnnp_reduce_sum_isa;
1733 model_reduce_sum->super.input_size = 1;
1734 model_reduce_sum->super.outputs = &model_reduce_sum->output;
1735 model_reduce_sum->super.output_size = 1;
1736 ccv_cnnp_model_copy_name(&model_reduce_sum->super, name);
1737 assert(axis_count <= CCV_NNC_MAX_DIM_ALLOC)((void) sizeof ((axis_count <= (12)) ? 1 : 0), __extension__
({ if (axis_count <= (12)) ; else __assert_fail ("axis_count <= CCV_NNC_MAX_DIM_ALLOC"
, "ccv_cnnp_model_addons.c", 1737, __extension__ __PRETTY_FUNCTION__
); }))
;
1738 int i;
1739 for (i = 0; i < axis_count; i++)
1740 model_reduce_sum->axis[i] = axis[i];
1741 model_reduce_sum->count = axis_count;
1742 return (ccv_cnnp_model_t*)model_reduce_sum;
1743}
1744
1745static ccv_cnnp_model_t* _ccv_cnnp_reduce_sum_copy(const ccv_cnnp_model_t* const super, void* const context)
1746{
1747 const ccv_cnnp_model_reduce_sum_t* const self = (const ccv_cnnp_model_reduce_sum_t*)super;
1748 return ccv_cnnp_reduce_sum(self->axis, self->count, self->super.name);
1749}
1750
1751// MARK - Reduce Max Layer
1752
1753typedef struct {
1754 ccv_cnnp_model_t super;
1755 int axis[CCV_NNC_MAX_DIM_ALLOC(12)];
1756 int count;
1757 ccv_nnc_tensor_symbol_t output;
1758} ccv_cnnp_model_reduce_max_t;
1759
1760static void _ccv_cnnp_reduce_max_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
1761{
1762 const ccv_cnnp_model_reduce_max_t* const self = (const ccv_cnnp_model_reduce_max_t*)super;
1763 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 1763, __extension__ __PRETTY_FUNCTION__); }))
;
1764 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 1764, __extension__ __PRETTY_FUNCTION__
); }))
;
1765 ccv_nnc_tensor_param_t input_params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
1766 ccv_nnc_tensor_param_t output_params;
1767 ccv_nnc_cmd_t reduce_max = CMD_REDUCE_MAX_FORWARD()ccv_nnc_cmd(CCV_NNC_REDUCE_MAX_FORWARD, 0, ((ccv_nnc_cmd_param_t
){.size={.dim={1,1,1}},.reduce={.count=(1 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1),.axis={}}}
), 0)
;
1768 int i;
1769 for (i = 0; i < self->count; i++)
1770 reduce_max.info.reduce.axis[i] = self->axis[i];
1771 reduce_max.info.reduce.count = self->count;
1772 ccv_nnc_hint_tensor_auto(reduce_max, &input_params, 1, ccv_nnc_no_hint, &output_params, 1);
1773 outputs[0] = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
1774 ccv_nnc_graph_exec_symbol_new(graph, reduce_max, inputs, input_size, outputs, output_size, 0);
1775}
1776
1777static ccv_cnnp_model_t* _ccv_cnnp_reduce_max_copy(const ccv_cnnp_model_t* const self, void* const context);
1778
1779static const ccv_cnnp_model_vtab_t ccv_cnnp_reduce_max_isa = {
1780 .build = _ccv_cnnp_reduce_max_build,
1781 .copy = _ccv_cnnp_reduce_max_copy,
1782};
1783
1784ccv_cnnp_model_t* ccv_cnnp_reduce_max(const int* const axis, const int axis_count, const char* const name)
1785{
1786 ccv_cnnp_model_reduce_max_t* const model_reduce_max = (ccv_cnnp_model_reduce_max_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_reduce_max_t));
1787 model_reduce_max->super.isa = &ccv_cnnp_reduce_max_isa;
1788 model_reduce_max->super.input_size = 1;
1789 model_reduce_max->super.outputs = &model_reduce_max->output;
1790 model_reduce_max->super.output_size = 1;
1791 ccv_cnnp_model_copy_name(&model_reduce_max->super, name);
1792 assert(axis_count <= CCV_NNC_MAX_DIM_ALLOC)((void) sizeof ((axis_count <= (12)) ? 1 : 0), __extension__
({ if (axis_count <= (12)) ; else __assert_fail ("axis_count <= CCV_NNC_MAX_DIM_ALLOC"
, "ccv_cnnp_model_addons.c", 1792, __extension__ __PRETTY_FUNCTION__
); }))
;
1793 int i;
1794 for (i = 0; i < axis_count; i++)
1795 model_reduce_max->axis[i] = axis[i];
1796 model_reduce_max->count = axis_count;
1797 return (ccv_cnnp_model_t*)model_reduce_max;
1798}
1799
1800static ccv_cnnp_model_t* _ccv_cnnp_reduce_max_copy(const ccv_cnnp_model_t* const super, void* const context)
1801{
1802 const ccv_cnnp_model_reduce_max_t* const self = (const ccv_cnnp_model_reduce_max_t*)super;
1803 return ccv_cnnp_reduce_max(self->axis, self->count, self->super.name);
1804}
1805
1806// MARK - Reduce Norm2 Layer
1807
1808typedef struct {
1809 ccv_cnnp_model_t super;
1810 int axis[CCV_NNC_MAX_DIM_ALLOC(12)];
1811 int count;
1812 ccv_nnc_tensor_symbol_t output;
1813} ccv_cnnp_model_reduce_norm2_t;
1814
1815static void _ccv_cnnp_reduce_norm2_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
1816{
1817 const ccv_cnnp_model_reduce_norm2_t* const self = (const ccv_cnnp_model_reduce_norm2_t*)super;
1818 assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if
(input_size == 1) ; else __assert_fail ("input_size == 1", "ccv_cnnp_model_addons.c"
, 1818, __extension__ __PRETTY_FUNCTION__); }))
;
1819 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 1819, __extension__ __PRETTY_FUNCTION__
); }))
;
1820 ccv_nnc_tensor_param_t input_params = ccv_nnc_tensor_symbol_params(graph, inputs[0]);
1821 ccv_nnc_tensor_param_t output_params;
1822 ccv_nnc_cmd_t reduce_norm2 = CMD_REDUCE_NORM2_FORWARD()ccv_nnc_cmd(CCV_NNC_REDUCE_NORM2_FORWARD, 0, ((ccv_nnc_cmd_param_t
){.size={.dim={1,1,1}},.reduce={.count=(1 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -1),.axis={}}}
), 0)
;
1823 int i;
1824 for (i = 0; i < self->count; i++)
1825 reduce_norm2.info.reduce.axis[i] = self->axis[i];
1826 reduce_norm2.info.reduce.count = self->count;
1827 ccv_nnc_hint_tensor_auto(reduce_norm2, &input_params, 1, ccv_nnc_no_hint, &output_params, 1);
1828 outputs[0] = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
1829 ccv_nnc_graph_exec_symbol_new(graph, reduce_norm2, inputs, input_size, outputs, output_size, 0);
1830}
1831
1832static ccv_cnnp_model_t* _ccv_cnnp_reduce_norm2_copy(const ccv_cnnp_model_t* const self, void* const context);
1833
1834static const ccv_cnnp_model_vtab_t ccv_cnnp_reduce_norm2_isa = {
1835 .build = _ccv_cnnp_reduce_norm2_build,
1836 .copy = _ccv_cnnp_reduce_norm2_copy,
1837};
1838
1839ccv_cnnp_model_t* ccv_cnnp_reduce_norm2(const int* const axis, const int axis_count, const char* const name)
1840{
1841 ccv_cnnp_model_reduce_norm2_t* const model_reduce_norm2 = (ccv_cnnp_model_reduce_norm2_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_reduce_norm2_t));
1842 model_reduce_norm2->super.isa = &ccv_cnnp_reduce_norm2_isa;
1843 model_reduce_norm2->super.input_size = 1;
1844 model_reduce_norm2->super.outputs = &model_reduce_norm2->output;
1845 model_reduce_norm2->super.output_size = 1;
1846 ccv_cnnp_model_copy_name(&model_reduce_norm2->super, name);
1847 assert(axis_count <= CCV_NNC_MAX_DIM_ALLOC)((void) sizeof ((axis_count <= (12)) ? 1 : 0), __extension__
({ if (axis_count <= (12)) ; else __assert_fail ("axis_count <= CCV_NNC_MAX_DIM_ALLOC"
, "ccv_cnnp_model_addons.c", 1847, __extension__ __PRETTY_FUNCTION__
); }))
;
1848 int i;
1849 for (i = 0; i < axis_count; i++)
1850 model_reduce_norm2->axis[i] = axis[i];
1851 model_reduce_norm2->count = axis_count;
1852 return (ccv_cnnp_model_t*)model_reduce_norm2;
1853}
1854
1855static ccv_cnnp_model_t* _ccv_cnnp_reduce_norm2_copy(const ccv_cnnp_model_t* const super, void* const context)
1856{
1857 const ccv_cnnp_model_reduce_norm2_t* const self = (const ccv_cnnp_model_reduce_norm2_t*)super;
1858 return ccv_cnnp_reduce_norm2(self->axis, self->count, self->super.name);
1859}
1860
1861// MARK - Min Layer
1862
1863typedef struct {
1864 ccv_cnnp_model_t super;
1865 ccv_nnc_tensor_symbol_t output;
1866} ccv_cnnp_model_min_t;
1867
1868static void _ccv_cnnp_min_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
1869{
1870 assert(input_size == 2)((void) sizeof ((input_size == 2) ? 1 : 0), __extension__ ({ if
(input_size == 2) ; else __assert_fail ("input_size == 2", "ccv_cnnp_model_addons.c"
, 1870, __extension__ __PRETTY_FUNCTION__); }))
;
1871 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 1871, __extension__ __PRETTY_FUNCTION__
); }))
;
1872 ccv_nnc_tensor_param_t input_params[2];
1873 int i;
1874 for (i = 0; i < 2; i++)
1875 input_params[i] = ccv_nnc_tensor_symbol_params(graph, inputs[i]);
1876 ccv_nnc_tensor_param_t output_params;
1877 const ccv_nnc_cmd_t min = CMD_MIN_FORWARD()ccv_nnc_cmd(CCV_NNC_MIN_FORWARD, 0, (ccv_nnc_cmd_param_t){.size
={.dim={1,1,1}}}, 0)
;
1878 ccv_nnc_hint_tensor_auto(min, input_params, 2, ccv_nnc_no_hint, &output_params, 1);
1879 outputs[0] = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
1880 ccv_nnc_graph_exec_symbol_new(graph, min, inputs, input_size, outputs, output_size, 0);
1881}
1882
1883static ccv_cnnp_model_t* _ccv_cnnp_min_copy(const ccv_cnnp_model_t* const self, void* const context);
1884
1885static const ccv_cnnp_model_vtab_t ccv_cnnp_min_isa = {
1886 .build = _ccv_cnnp_min_build,
1887 .copy = _ccv_cnnp_min_copy,
1888};
1889
1890ccv_cnnp_model_t* ccv_cnnp_min(const char* const name)
1891{
1892 ccv_cnnp_model_min_t* const model_min = (ccv_cnnp_model_min_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_min_t));
1893 model_min->super.isa = &ccv_cnnp_min_isa;
1894 model_min->super.input_size = 2;
1895 model_min->super.outputs = &model_min->output;
1896 model_min->super.output_size = 1;
1897 ccv_cnnp_model_copy_name(&model_min->super, name);
1898 return (ccv_cnnp_model_t*)model_min;
1899}
1900
1901static ccv_cnnp_model_t* _ccv_cnnp_min_copy(const ccv_cnnp_model_t* const super, void* const context)
1902{
1903 const ccv_cnnp_model_min_t* const self = (const ccv_cnnp_model_min_t*)super;
1904 return ccv_cnnp_min(self->super.name);
1905}
1906
1907// MARK - Max Layer
1908
1909typedef struct {
1910 ccv_cnnp_model_t super;
1911 ccv_nnc_tensor_symbol_t output;
1912} ccv_cnnp_model_max_t;
1913
1914static void _ccv_cnnp_max_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
1915{
1916 assert(input_size == 2)((void) sizeof ((input_size == 2) ? 1 : 0), __extension__ ({ if
(input_size == 2) ; else __assert_fail ("input_size == 2", "ccv_cnnp_model_addons.c"
, 1916, __extension__ __PRETTY_FUNCTION__); }))
;
1917 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 1917, __extension__ __PRETTY_FUNCTION__
); }))
;
1918 ccv_nnc_tensor_param_t input_params[2];
1919 int i;
1920 for (i = 0; i < 2; i++)
1921 input_params[i] = ccv_nnc_tensor_symbol_params(graph, inputs[i]);
1922 ccv_nnc_tensor_param_t output_params;
1923 const ccv_nnc_cmd_t max = CMD_MAX_FORWARD()ccv_nnc_cmd(CCV_NNC_MAX_FORWARD, 0, (ccv_nnc_cmd_param_t){.size
={.dim={1,1,1}}}, 0)
;
1924 ccv_nnc_hint_tensor_auto(max, input_params, 2, ccv_nnc_no_hint, &output_params, 1);
1925 outputs[0] = ccv_nnc_tensor_symbol_new(graph, output_params, 0);
1926 ccv_nnc_graph_exec_symbol_new(graph, max, inputs, input_size, outputs, output_size, 0);
1927}
1928
1929static ccv_cnnp_model_t* _ccv_cnnp_max_copy(const ccv_cnnp_model_t* const self, void* const context);
1930
1931static const ccv_cnnp_model_vtab_t ccv_cnnp_max_isa = {
1932 .build = _ccv_cnnp_max_build,
1933 .copy = _ccv_cnnp_max_copy,
1934};
1935
1936ccv_cnnp_model_t* ccv_cnnp_max(const char* const name)
1937{
1938 ccv_cnnp_model_max_t* const model_max = (ccv_cnnp_model_max_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_max_t));
1939 model_max->super.isa = &ccv_cnnp_max_isa;
1940 model_max->super.input_size = 2;
1941 model_max->super.outputs = &model_max->output;
1942 model_max->super.output_size = 1;
1943 ccv_cnnp_model_copy_name(&model_max->super, name);
1944 return (ccv_cnnp_model_t*)model_max;
1945}
1946
1947static ccv_cnnp_model_t* _ccv_cnnp_max_copy(const ccv_cnnp_model_t* const super, void* const context)
1948{
1949 const ccv_cnnp_model_max_t* const self = (const ccv_cnnp_model_max_t*)super;
1950 return ccv_cnnp_max(self->super.name);
1951}
1952
1953// MARK - LSTM Layer
1954
1955typedef struct {
1956 ccv_cnnp_model_t super;
1957 int masked;
1958 ccv_nnc_tensor_symbol_t output;
1959 ccv_nnc_tensor_symbol_t weights;
1960 ccv_nnc_tensor_symbol_t reserves;
1961 ccv_nnc_cmd_param_t params;
1962 ccv_nnc_graph_exec_symbol_t lstm;
1963} ccv_cnnp_model_lstm_t;
1964
1965static int _ccv_cnnp_lstm_weight_dim(int bidirectional, int num_layers, int input_size, int hidden_size, int proj_size, int bias)
1966{
1967 const int D = !!bidirectional + 1;
1968 if (hidden_size == proj_size)
1969 return (num_layers * (bias ? 8 : 0) + (num_layers - 1) * (hidden_size * 4 * D + hidden_size * 4) + input_size * 4 + hidden_size * 4) * D;
1970 else
1971 return (num_layers * (bias ? 8 : 0) + (num_layers - 1) * (proj_size * 4 * D + proj_size * 4) + (proj_size * 4 + input_size * 4) + num_layers * proj_size) * D;
1972}
1973
1974static void _ccv_cnnp_lstm_build(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, ccv_nnc_tensor_symbol_t* const outputs, const int output_size)
1975{
1976 ccv_cnnp_model_lstm_t* const self = (ccv_cnnp_model_lstm_t*)super;
1977 assert(input_size == self->super.input_size)((void) sizeof ((input_size == self->super.input_size) ? 1
: 0), __extension__ ({ if (input_size == self->super.input_size
) ; else __assert_fail ("input_size == self->super.input_size"
, "ccv_cnnp_model_addons.c", 1977, __extension__ __PRETTY_FUNCTION__
); }))
;
1978 assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({
if (output_size == 1) ; else __assert_fail ("output_size == 1"
, "ccv_cnnp_model_addons.c", 1978, __extension__ __PRETTY_FUNCTION__
); }))
;
1979 const int proj_size = self->params.rnn.proj_size == 0 ? self->params.rnn.hidden_size : self->params.rnn.proj_size;
1980 ccv_nnc_tensor_param_t input_params[5];
1981 input_params[0]= ccv_nnc_tensor_symbol_params(graph, inputs[0]);
1982 if (input_size == 2)
1983 input_params[1] = ccv_nnc_tensor_symbol_params(graph, inputs[1]);
1984 input_params[4] = input_params[0];
1985 memset(input_params[4].dim, 0, sizeof(input_params[4].dim));
1986 const int x_nd = ccv_nnc_tensor_nd(input_params[0].dim);
1987 const int feature_count = input_params[0].dim[x_nd - 1];
1988 input_params[4].dim[0] = _ccv_cnnp_lstm_weight_dim(self->params.rnn.bidirectional, self->params.rnn.num_layers, feature_count, self->params.rnn.hidden_size, proj_size, self->params.rnn.bias);
1989 input_params[4].dim[1] = self->params.rnn.hidden_size;
1990 const ccv_nnc_cmd_t lstm = ccv_nnc_cmd(CCV_NNC_LSTM_FORWARD, 0, self->params, 0);
1991 ccv_nnc_tensor_param_t output_params[4];
1992 ccv_nnc_hint_tensor_auto(lstm, input_params, 5, ccv_nnc_no_hint, output_params, 4);
1993 outputs[0] = ccv_nnc_tensor_symbol_new(graph, output_params[0], 0);
1994 self->weights = ccv_nnc_tensor_symbol_new(graph, input_params[4], 0);
1995 self->reserves = ccv_nnc_tensor_symbol_new(graph, output_params[3], 0);
1996 const ccv_nnc_tensor_symbol_t mask = input_size == 2 ? inputs[1] : NO_TENSOR_SYMBOL(const ccv_nnc_tensor_symbol_t){.d = CCV_NNC_NO_TENSOR_SYMBOL
}
;
1997 self->lstm = ccv_nnc_graph_exec_symbol_new(graph, lstm, TENSOR_SYMBOL_LIST(inputs[0], mask, NO_TENSOR_SYMBOL, NO_TENSOR_SYMBOL, self->weights)(const ccv_nnc_tensor_symbol_t []){inputs[0], mask, (const ccv_nnc_tensor_symbol_t
){.d = CCV_NNC_NO_TENSOR_SYMBOL}, (const ccv_nnc_tensor_symbol_t
){.d = CCV_NNC_NO_TENSOR_SYMBOL}, self->weights}, (1 +1 +1
+1 +1 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 -
1)
, TENSOR_SYMBOL_LIST(outputs[0], NO_TENSOR_SYMBOL, NO_TENSOR_SYMBOL, self->reserves)(const ccv_nnc_tensor_symbol_t []){outputs[0], (const ccv_nnc_tensor_symbol_t
){.d = CCV_NNC_NO_TENSOR_SYMBOL}, (const ccv_nnc_tensor_symbol_t
){.d = CCV_NNC_NO_TENSOR_SYMBOL}, self->reserves}, (1 +1 +
1 +1 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
+0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +
0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0
-1)
, 0);
1998}
1999
2000static void _ccv_cnnp_lstm_init_states(ccv_cnnp_model_t* const super, ccv_nnc_symbolic_graph_t* const graph, const ccv_cnnp_state_initializer_f initializer, void* const context)
2001{
2002 ccv_cnnp_model_lstm_t* const self = (ccv_cnnp_model_lstm_t*)super;
2003 if (self->weights.graph)
2004 {
2005 const float stdv = 1.0 / sqrt(self->params.rnn.hidden_size);
2006 initializer(context, CMD_RANDOM_UNIFORM_FORWARD(-stdv, stdv)ccv_nnc_cmd(CCV_NNC_RANDOM_UNIFORM_FORWARD, 0, (ccv_nnc_cmd_param_t
){.size={.dim={1,1,1}},.blas={.a={-stdv, stdv}}}, 0)
, ccv_nnc_no_hint, 0, 0, self->weights);
2007 }
2008}
2009
2010static void _ccv_cnnp_lstm_add_to_parameter(ccv_cnnp_model_t* const super, const ccv_cnnp_add_to_array_f add_to_array, void* const parameters)
2011{
2012 ccv_cnnp_model_lstm_t* const self = (ccv_cnnp_model_lstm_t*)super;
2013 if (self->weights.graph)
2014 add_to_array(parameters, self->weights);
2015}
2016
2017static void _ccv_cnnp_lstm_set_is_test(ccv_cnnp_model_t* const super, const int is_test, const ccv_cnnp_cmd_updater_f updater, void* const context)
2018{
2019 ccv_cnnp_model_lstm_t* const self = (ccv_cnnp_model_lstm_t*)super;
2020 if (self->lstm.graph)
2021 {
2022 self->params.rnn.is_test = is_test;
2023 updater(context, self->lstm, ccv_nnc_cmd(CCV_NNC_LSTM_FORWARD, 0, self->params, 0), ccv_nnc_no_hint);
2024 }
2025}
2026
2027static ccv_cnnp_model_t* _ccv_cnnp_lstm_copy(const ccv_cnnp_model_t* const self, void* const context);
2028
2029static const ccv_cnnp_model_vtab_t ccv_cnnp_lstm_isa = {
2030 .build = _ccv_cnnp_lstm_build,
2031 .init_states = _ccv_cnnp_lstm_init_states,
2032 .add_to_parameter = _ccv_cnnp_lstm_add_to_parameter,
2033 .copy = _ccv_cnnp_lstm_copy,
2034 .set_is_test = _ccv_cnnp_lstm_set_is_test,
2035};
2036
2037ccv_cnnp_model_t* ccv_cnnp_lstm(const int masked, const int hidden_size, const int proj_size, const int num_layers, const int bias, const int batch_first, const int bidirectional, const float dropout, const char* const name)
2038{
2039 ccv_cnnp_model_lstm_t* const model_lstm = (ccv_cnnp_model_lstm_t*)cccalloccalloc(1, sizeof(ccv_cnnp_model_lstm_t));
2040 model_lstm->super.isa = &ccv_cnnp_lstm_isa;
2041 model_lstm->super.input_size = masked ? 2 : 1;
2042 model_lstm->super.outputs = &model_lstm->output;
2043 model_lstm->super.output_size = 1;
2044 ccv_cnnp_model_copy_name(&model_lstm->super, name);
2045 model_lstm->masked = masked;
2046 model_lstm->weights.d = CCV_NNC_NO_TENSOR_SYMBOL;
2047 model_lstm->weights.graph = 0;
2048 model_lstm->params.rnn.hidden_size = hidden_size;
2049 model_lstm->params.rnn.proj_size = proj_size;
2050 model_lstm->params.rnn.num_layers = num_layers;
2051 model_lstm->params.rnn.bias = bias;
2052 model_lstm->params.rnn.batch_first = batch_first;
2053 model_lstm->params.rnn.bidirectional = bidirectional;
2054 model_lstm->params.rnn.dropout = dropout;
2055 return (ccv_cnnp_model_t*)model_lstm;
2056}
2057
2058static ccv_cnnp_model_t* _ccv_cnnp_lstm_copy(const ccv_cnnp_model_t* const super, void* const context)
2059{
2060 const ccv_cnnp_model_lstm_t* const self = (const ccv_cnnp_model_lstm_t*)super;
2061 return ccv_cnnp_lstm(self->masked, self->params.rnn.hidden_size, self->params.rnn.proj_size, self->params.rnn.num_layers, self->params.rnn.bias, self->params.rnn.batch_first, self->params.rnn.bidirectional, self->params.rnn.dropout, self->super.name);
2062}