| File: | nnc/cmd/reduce/ccv_nnc_reduce_logsumexp_cpu_ref.c |
| Warning: | line 53, column 18 Use of memory allocated with size zero |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | #include "ccv.h" | |||
| 2 | #include "ccv_internal.h" | |||
| 3 | #include "nnc/ccv_nnc.h" | |||
| 4 | #include "nnc/ccv_nnc_easy.h" | |||
| 5 | #include "nnc/ccv_nnc_internal.h" | |||
| 6 | ||||
| 7 | // Shared methods. | |||
| 8 | #include "../_ccv_nnc_cpu_ref.h" | |||
| 9 | ||||
| 10 | static int _ccv_nnc_reduce_logsumexp_forw(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) | |||
| 11 | { | |||
| 12 | assert(input_size == 1)((void) sizeof ((input_size == 1) ? 1 : 0), __extension__ ({ if (input_size == 1) ; else __assert_fail ("input_size == 1", "reduce/ccv_nnc_reduce_logsumexp_cpu_ref.c" , 12, __extension__ __PRETTY_FUNCTION__); })); | |||
| ||||
| 13 | assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({ if (output_size == 1) ; else __assert_fail ("output_size == 1" , "reduce/ccv_nnc_reduce_logsumexp_cpu_ref.c", 13, __extension__ __PRETTY_FUNCTION__); })); | |||
| 14 | ccv_nnc_tensor_view_t* const a = (ccv_nnc_tensor_view_t*)inputs[0]; | |||
| 15 | ccv_nnc_tensor_view_t* const b = (ccv_nnc_tensor_view_t*)outputs[0]; | |||
| 16 | assert(ccv_nnc_tensor_nd(a->info.dim) <= CCV_NNC_MAX_DIM + 2)((void) sizeof ((ccv_nnc_tensor_nd(a->info.dim) <= (2) + 2) ? 1 : 0), __extension__ ({ if (ccv_nnc_tensor_nd(a->info .dim) <= (2) + 2) ; else __assert_fail ("ccv_nnc_tensor_nd(a->info.dim) <= CCV_NNC_MAX_DIM + 2" , "reduce/ccv_nnc_reduce_logsumexp_cpu_ref.c", 16, __extension__ __PRETTY_FUNCTION__); })); | |||
| 17 | assert(ccv_nnc_tensor_nd(b->info.dim) <= CCV_NNC_MAX_DIM + 2)((void) sizeof ((ccv_nnc_tensor_nd(b->info.dim) <= (2) + 2) ? 1 : 0), __extension__ ({ if (ccv_nnc_tensor_nd(b->info .dim) <= (2) + 2) ; else __assert_fail ("ccv_nnc_tensor_nd(b->info.dim) <= CCV_NNC_MAX_DIM + 2" , "reduce/ccv_nnc_reduce_logsumexp_cpu_ref.c", 17, __extension__ __PRETTY_FUNCTION__); })); | |||
| 18 | int adim[CCV_NNC_MAX_DIM_ALLOC(12)]; | |||
| 19 | int bdim[CCV_NNC_MAX_DIM_ALLOC(12)]; | |||
| 20 | ccv_nnc_tensor_view_get_dim(a, adim); | |||
| 21 | ccv_nnc_tensor_view_get_dim(b, bdim); | |||
| 22 | assert(ccv_nnc_tensor_view_check_broadcast_dim(b, adim))((void) sizeof ((ccv_nnc_tensor_view_check_broadcast_dim(b, adim )) ? 1 : 0), __extension__ ({ if (ccv_nnc_tensor_view_check_broadcast_dim (b, adim)) ; else __assert_fail ("ccv_nnc_tensor_view_check_broadcast_dim(b, adim)" , "reduce/ccv_nnc_reduce_logsumexp_cpu_ref.c", 22, __extension__ __PRETTY_FUNCTION__); })); | |||
| 23 | int astride[CCV_NNC_MAX_DIM_ALLOC(12)]; | |||
| 24 | int bstride[CCV_NNC_MAX_DIM_ALLOC(12)]; | |||
| 25 | assert(CCV_NNC_MAX_DIM == 2)((void) sizeof (((2) == 2) ? 1 : 0), __extension__ ({ if ((2) == 2) ; else __assert_fail ("CCV_NNC_MAX_DIM == 2", "reduce/ccv_nnc_reduce_logsumexp_cpu_ref.c" , 25, __extension__ __PRETTY_FUNCTION__); })); // Need to change this logic for CCV_NNC_MAX_DIM == other number. | |||
| 26 | ccv_nnc_tensor_view_get_stride(a, astride); | |||
| 27 | ccv_nnc_tensor_view_get_stride(b, bstride); | |||
| 28 | const float scale = cmd.info.reduce.scale; | |||
| 29 | const size_t b_count = ccv_nnc_tensor_count(b->info); | |||
| 30 | float* const maxp = (float*)ccmallocmalloc(sizeof(float) * b_count); | |||
| 31 | size_t j; | |||
| 32 | for (j = 0; j < b_count; j++) | |||
| 33 | maxp[j] = -INFINITY(__builtin_inff ()); | |||
| 34 | const float* const ap = a->data.f32; | |||
| 35 | int i[CCV_NNC_MAX_DIM(2) + 2]; | |||
| 36 | int x; | |||
| 37 | for (i[0] = 0; i[0] < adim[0]; i[0]++) | |||
| 38 | { | |||
| 39 | const float* const ap0 = ap + i[0] * astride[0]; | |||
| 40 | const size_t bi0 = bdim[0] == 1 ? 0 : i[0]; | |||
| 41 | for (i[1] = 0; i[1] < adim[1]; i[1]++) | |||
| 42 | { | |||
| 43 | const float* ap1 = ap0 + i[1] * astride[1]; | |||
| 44 | const size_t bi1 = bdim[1] == 1 ? 0 : i[1]; | |||
| 45 | for (i[2] = 0; i[2] < adim[2]; i[2]++) | |||
| 46 | { | |||
| 47 | const size_t bi2 = bdim[2] == 1 ? 0 : i[2]; | |||
| 48 | for (x = 0; x < adim[3]; x++) | |||
| 49 | { | |||
| 50 | const size_t bi3 = bdim[3] == 1 ? 0 : x; | |||
| 51 | const size_t b_idx = ((bi0 * bdim[1] + bi1) * bdim[2] + bi2) * bdim[3] + bi3; | |||
| 52 | const float value = scale * ap1[x]; | |||
| 53 | if (value > maxp[b_idx] || isnan(value)__builtin_isnan (value)) | |||
| ||||
| 54 | maxp[b_idx] = value; | |||
| 55 | } | |||
| 56 | ap1 += astride[2]; | |||
| 57 | } | |||
| 58 | } | |||
| 59 | } | |||
| 60 | ccv_nnc_tensor_zero(b); | |||
| 61 | float* const bp = b->data.f32; | |||
| 62 | for (i[0] = 0; i[0] < adim[0]; i[0]++) | |||
| 63 | { | |||
| 64 | const float* const ap0 = ap + i[0] * astride[0]; | |||
| 65 | float* const bp0 = bdim[0] == 1 ? bp : bp + i[0] * bstride[0]; | |||
| 66 | const size_t bi0 = bdim[0] == 1 ? 0 : i[0]; | |||
| 67 | for (i[1] = 0; i[1] < adim[1]; i[1]++) | |||
| 68 | { | |||
| 69 | const float* ap1 = ap0 + i[1] * astride[1]; | |||
| 70 | float* const bp1 = bdim[1] == 1 ? bp0 : bp0 + i[1] * bstride[1]; | |||
| 71 | const size_t bi1 = bdim[1] == 1 ? 0 : i[1]; | |||
| 72 | for (i[2] = 0; i[2] < adim[2]; i[2]++) | |||
| 73 | { | |||
| 74 | float* const bp2 = bdim[2] == 1 ? bp1 : bp1 + i[2] * bstride[2]; | |||
| 75 | const size_t bi2 = bdim[2] == 1 ? 0 : i[2]; | |||
| 76 | for (x = 0; x < adim[3]; x++) | |||
| 77 | { | |||
| 78 | const int bx = bdim[3] == 1 ? 0 : x; | |||
| 79 | const size_t b_idx = ((bi0 * bdim[1] + bi1) * bdim[2] + bi2) * bdim[3] + bx; | |||
| 80 | if (isfinite(maxp[b_idx])__builtin_isfinite (maxp[b_idx])) | |||
| 81 | bp2[bx] += expf(scale * ap1[x] - maxp[b_idx]); | |||
| 82 | } | |||
| 83 | ap1 += astride[2]; | |||
| 84 | } | |||
| 85 | } | |||
| 86 | } | |||
| 87 | j = 0; | |||
| 88 | for (i[0] = 0; i[0] < bdim[0]; i[0]++) | |||
| 89 | { | |||
| 90 | float* const bp0 = bp + i[0] * bstride[0]; | |||
| 91 | for (i[1] = 0; i[1] < bdim[1]; i[1]++) | |||
| 92 | { | |||
| 93 | float* bp1 = bp0 + i[1] * bstride[1]; | |||
| 94 | for (i[2] = 0; i[2] < bdim[2]; i[2]++) | |||
| 95 | { | |||
| 96 | for (x = 0; x < bdim[3]; x++, j++) | |||
| 97 | bp1[x] = isfinite(maxp[j])__builtin_isfinite (maxp[j]) ? logf(bp1[x]) + maxp[j] : maxp[j]; | |||
| 98 | bp1 += bstride[2]; | |||
| 99 | } | |||
| 100 | } | |||
| 101 | } | |||
| 102 | ccfreefree(maxp); | |||
| 103 | return CCV_NNC_EXEC_SUCCESS; | |||
| 104 | } | |||
| 105 | ||||
| 106 | static int _ccv_nnc_reduce_logsumexp_back(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) | |||
| 107 | { | |||
| 108 | assert(input_size >= 3)((void) sizeof ((input_size >= 3) ? 1 : 0), __extension__ ( { if (input_size >= 3) ; else __assert_fail ("input_size >= 3" , "reduce/ccv_nnc_reduce_logsumexp_cpu_ref.c", 108, __extension__ __PRETTY_FUNCTION__); })); | |||
| 109 | assert(output_size == 1)((void) sizeof ((output_size == 1) ? 1 : 0), __extension__ ({ if (output_size == 1) ; else __assert_fail ("output_size == 1" , "reduce/ccv_nnc_reduce_logsumexp_cpu_ref.c", 109, __extension__ __PRETTY_FUNCTION__); })); | |||
| 110 | ccv_nnc_tensor_view_t* const a = (ccv_nnc_tensor_view_t*)inputs[1]; | |||
| 111 | ccv_nnc_tensor_view_t* const b = (ccv_nnc_tensor_view_t*)inputs[2]; | |||
| 112 | ccv_nnc_tensor_view_t* const h = (ccv_nnc_tensor_view_t*)outputs[0]; | |||
| 113 | assert(ccv_nnc_tensor_nd(a->info.dim) <= CCV_NNC_MAX_DIM + 2)((void) sizeof ((ccv_nnc_tensor_nd(a->info.dim) <= (2) + 2) ? 1 : 0), __extension__ ({ if (ccv_nnc_tensor_nd(a->info .dim) <= (2) + 2) ; else __assert_fail ("ccv_nnc_tensor_nd(a->info.dim) <= CCV_NNC_MAX_DIM + 2" , "reduce/ccv_nnc_reduce_logsumexp_cpu_ref.c", 113, __extension__ __PRETTY_FUNCTION__); })); | |||
| 114 | assert(ccv_nnc_tensor_nd(b->info.dim) <= CCV_NNC_MAX_DIM + 2)((void) sizeof ((ccv_nnc_tensor_nd(b->info.dim) <= (2) + 2) ? 1 : 0), __extension__ ({ if (ccv_nnc_tensor_nd(b->info .dim) <= (2) + 2) ; else __assert_fail ("ccv_nnc_tensor_nd(b->info.dim) <= CCV_NNC_MAX_DIM + 2" , "reduce/ccv_nnc_reduce_logsumexp_cpu_ref.c", 114, __extension__ __PRETTY_FUNCTION__); })); | |||
| 115 | assert(ccv_nnc_tensor_nd(h->info.dim) <= CCV_NNC_MAX_DIM + 2)((void) sizeof ((ccv_nnc_tensor_nd(h->info.dim) <= (2) + 2) ? 1 : 0), __extension__ ({ if (ccv_nnc_tensor_nd(h->info .dim) <= (2) + 2) ; else __assert_fail ("ccv_nnc_tensor_nd(h->info.dim) <= CCV_NNC_MAX_DIM + 2" , "reduce/ccv_nnc_reduce_logsumexp_cpu_ref.c", 115, __extension__ __PRETTY_FUNCTION__); })); | |||
| 116 | int adim[CCV_NNC_MAX_DIM_ALLOC(12)]; | |||
| 117 | int bdim[CCV_NNC_MAX_DIM_ALLOC(12)]; | |||
| 118 | int hdim[CCV_NNC_MAX_DIM_ALLOC(12)]; | |||
| 119 | ccv_nnc_tensor_view_get_dim(a, adim); | |||
| 120 | ccv_nnc_tensor_view_get_dim(b, bdim); | |||
| 121 | ccv_nnc_tensor_view_get_dim(h, hdim); | |||
| 122 | assert(ccv_nnc_tensor_view_check_dim(a, hdim))((void) sizeof ((ccv_nnc_tensor_view_check_dim(a, hdim)) ? 1 : 0), __extension__ ({ if (ccv_nnc_tensor_view_check_dim(a, hdim )) ; else __assert_fail ("ccv_nnc_tensor_view_check_dim(a, hdim)" , "reduce/ccv_nnc_reduce_logsumexp_cpu_ref.c", 122, __extension__ __PRETTY_FUNCTION__); })); | |||
| 123 | assert(ccv_nnc_tensor_view_check_broadcast_dim(b, hdim))((void) sizeof ((ccv_nnc_tensor_view_check_broadcast_dim(b, hdim )) ? 1 : 0), __extension__ ({ if (ccv_nnc_tensor_view_check_broadcast_dim (b, hdim)) ; else __assert_fail ("ccv_nnc_tensor_view_check_broadcast_dim(b, hdim)" , "reduce/ccv_nnc_reduce_logsumexp_cpu_ref.c", 123, __extension__ __PRETTY_FUNCTION__); })); | |||
| 124 | int astride[CCV_NNC_MAX_DIM_ALLOC(12)]; | |||
| 125 | int bstride[CCV_NNC_MAX_DIM_ALLOC(12)]; | |||
| 126 | int hstride[CCV_NNC_MAX_DIM_ALLOC(12)]; | |||
| 127 | assert(CCV_NNC_MAX_DIM == 2)((void) sizeof (((2) == 2) ? 1 : 0), __extension__ ({ if ((2) == 2) ; else __assert_fail ("CCV_NNC_MAX_DIM == 2", "reduce/ccv_nnc_reduce_logsumexp_cpu_ref.c" , 127, __extension__ __PRETTY_FUNCTION__); })); // Need to change this logic for CCV_NNC_MAX_DIM == other number. | |||
| 128 | ccv_nnc_tensor_view_get_stride(a, astride); | |||
| 129 | ccv_nnc_tensor_view_get_stride(b, bstride); | |||
| 130 | ccv_nnc_tensor_view_get_stride(h, hstride); | |||
| 131 | ccv_nnc_tensor_view_t* const g = inputs[0] ? (ccv_nnc_tensor_view_t*)inputs[0] : 0; | |||
| 132 | int gdim[CCV_NNC_MAX_DIM_ALLOC(12)]; | |||
| 133 | int gstride[CCV_NNC_MAX_DIM_ALLOC(12)]; | |||
| 134 | if (g) | |||
| 135 | { | |||
| 136 | assert(ccv_nnc_tensor_nd(g->info.dim) <= CCV_NNC_MAX_DIM + 2)((void) sizeof ((ccv_nnc_tensor_nd(g->info.dim) <= (2) + 2) ? 1 : 0), __extension__ ({ if (ccv_nnc_tensor_nd(g->info .dim) <= (2) + 2) ; else __assert_fail ("ccv_nnc_tensor_nd(g->info.dim) <= CCV_NNC_MAX_DIM + 2" , "reduce/ccv_nnc_reduce_logsumexp_cpu_ref.c", 136, __extension__ __PRETTY_FUNCTION__); })); | |||
| 137 | ccv_nnc_tensor_view_get_dim(g, gdim); | |||
| 138 | assert(ccv_nnc_tensor_view_check_broadcast_dim(g, hdim))((void) sizeof ((ccv_nnc_tensor_view_check_broadcast_dim(g, hdim )) ? 1 : 0), __extension__ ({ if (ccv_nnc_tensor_view_check_broadcast_dim (g, hdim)) ; else __assert_fail ("ccv_nnc_tensor_view_check_broadcast_dim(g, hdim)" , "reduce/ccv_nnc_reduce_logsumexp_cpu_ref.c", 138, __extension__ __PRETTY_FUNCTION__); })); | |||
| 139 | ccv_nnc_tensor_view_get_stride(g, gstride); | |||
| 140 | } | |||
| 141 | const float* const ap = a->data.f32; | |||
| 142 | const float* const bp = b->data.f32; | |||
| 143 | const float* const gp = g ? g->data.f32 : 0; | |||
| 144 | float* const hp = h->data.f32; | |||
| 145 | const float scale = cmd.info.reduce.scale; | |||
| 146 | int i[CCV_NNC_MAX_DIM(2) + 2]; | |||
| 147 | int x; | |||
| 148 | for (i[0] = 0; i[0] < hdim[0]; i[0]++) | |||
| 149 | { | |||
| 150 | const float* const ap0 = ap + i[0] * astride[0]; | |||
| 151 | const float* const bp0 = bdim[0] == 1 ? bp : bp + i[0] * bstride[0]; | |||
| 152 | const float* const gp0 = !g || gdim[0] == 1 ? gp : gp + i[0] * gstride[0]; | |||
| 153 | float* const hp0 = hp + i[0] * hstride[0]; | |||
| 154 | for (i[1] = 0; i[1] < hdim[1]; i[1]++) | |||
| 155 | { | |||
| 156 | const float* ap1 = ap0 + i[1] * astride[1]; | |||
| 157 | const float* const bp1 = bdim[1] == 1 ? bp0 : bp0 + i[1] * bstride[1]; | |||
| 158 | const float* const gp1 = !g || gdim[1] == 1 ? gp0 : gp0 + i[1] * gstride[1]; | |||
| 159 | float* hp1 = hp0 + i[1] * hstride[1]; | |||
| 160 | for (i[2] = 0; i[2] < hdim[2]; i[2]++) | |||
| 161 | { | |||
| 162 | const float* const bp2 = bdim[2] == 1 ? bp1 : bp1 + i[2] * bstride[2]; | |||
| 163 | const float* const gp2 = !g || gdim[2] == 1 ? gp1 : gp1 + i[2] * gstride[2]; | |||
| 164 | for (x = 0; x < hdim[3]; x++) | |||
| 165 | { | |||
| 166 | const float gradient = g ? gp2[gdim[3] == 1 ? 0 : x] : 1; | |||
| 167 | hp1[x] = gradient * scale * expf(scale * ap1[x] - bp2[bdim[3] == 1 ? 0 : x]); | |||
| 168 | } | |||
| 169 | ap1 += astride[2]; | |||
| 170 | hp1 += hstride[2]; | |||
| 171 | } | |||
| 172 | } | |||
| 173 | } | |||
| 174 | return CCV_NNC_EXEC_SUCCESS; | |||
| 175 | } | |||
| 176 | ||||
| 177 | REGISTER_COMMAND_BACKEND(CCV_NNC_REDUCE_LOGSUMEXP_FORWARD, CCV_NNC_BACKEND_CPU_REF)void _register_command_CCV_NNC_REDUCE_LOGSUMEXP_FORWARD_backend_CCV_NNC_BACKEND_CPU_REF(ccv_nnc_cmd_backend_registry_t* const registry) | |||
| 178 | { | |||
| 179 | registry->tensor_formats = CCV_TENSOR_FORMAT_NHWC | CCV_TENSOR_FORMAT_NCHW | CCV_TENSOR_FORMAT_CHWN; | |||
| 180 | registry->tensor_datatypes = CCV_32F; | |||
| 181 | registry->tensor_memory = CCV_TENSOR_CPU_MEMORY; | |||
| 182 | registry->algorithms = 1; | |||
| 183 | registry->exec = _ccv_nnc_reduce_logsumexp_forw; | |||
| 184 | } | |||
| 185 | ||||
| 186 | REGISTER_COMMAND_BACKEND(CCV_NNC_REDUCE_LOGSUMEXP_BACKWARD, CCV_NNC_BACKEND_CPU_REF)void _register_command_CCV_NNC_REDUCE_LOGSUMEXP_BACKWARD_backend_CCV_NNC_BACKEND_CPU_REF(ccv_nnc_cmd_backend_registry_t* const registry) | |||
| 187 | { | |||
| 188 | registry->tensor_formats = CCV_TENSOR_FORMAT_NHWC | CCV_TENSOR_FORMAT_NCHW | CCV_TENSOR_FORMAT_CHWN; | |||
| 189 | registry->tensor_datatypes = CCV_32F; | |||
| 190 | registry->tensor_memory = CCV_TENSOR_CPU_MEMORY; | |||
| 191 | registry->algorithms = 1; | |||
| 192 | registry->exec = _ccv_nnc_reduce_logsumexp_back; | |||
| 193 | } |