Bug Summary

File:nnc/cmd/causal_convolution/ccv_nnc_causal_convolution_cpu_ref.c
Warning:line 28, column 46
Division by zero

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_nnc_causal_convolution_cpu_ref.c -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 pic -pic-level 2 -pic-is-pie -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 -fdebug-compilation-dir=/home/liu/actions-runner/_work/ccv/ccv/lib/nnc/cmd -fcoverage-compilation-dir=/home/liu/actions-runner/_work/ccv/ccv/lib/nnc/cmd -resource-dir /usr/local/lib/clang/19 -I ../../ -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 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/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/liu/actions-runner/_work/ccv/ccv/_analyze/2026-11-05-170145-808375-1 -x c causal_convolution/ccv_nnc_causal_convolution_cpu_ref.c
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#include <math.h>
7
8static int _ccv_nnc_causal_convolution_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)
9{
10 assert(input_size == 3)((void) sizeof ((input_size == 3) ? 1 : 0), __extension__ ({ if
(input_size == 3) ; else __assert_fail ("input_size == 3", "causal_convolution/ccv_nnc_causal_convolution_cpu_ref.c"
, 10, __extension__ __PRETTY_FUNCTION__); }))
;
1
Assuming 'input_size' is equal to 3
2
Taking true branch
11 assert(output_size == 2)((void) sizeof ((output_size == 2) ? 1 : 0), __extension__ ({
if (output_size == 2) ; else __assert_fail ("output_size == 2"
, "causal_convolution/ccv_nnc_causal_convolution_cpu_ref.c", 11
, __extension__ __PRETTY_FUNCTION__); }))
;
3
Assuming 'output_size' is equal to 2
4
Taking true branch
12 const ccv_nnc_tensor_t* const x = inputs[0];
13 const ccv_nnc_tensor_t* const previous = inputs[1];
14 const ccv_nnc_tensor_t* const weight = inputs[2];
15 ccv_nnc_tensor_t* const y = outputs[0];
16 ccv_nnc_tensor_t* const next = outputs[1];
17 int i;
18 for (i = 0; i < 3; i++)
5
Loop condition is true. Entering loop body
10
Loop condition is true. Entering loop body
13
Loop condition is true. Entering loop body
16
Loop condition is false. Execution continues on line 20
19 assert(inputs[i]->info.datatype == CCV_32F && CCV_IS_TENSOR_CONTIGUOUS(inputs[i]))((void) sizeof ((inputs[i]->info.datatype == CCV_32F &&
(!((*(int*)(inputs[i])) & CCV_TENSOR_VIEW) || (((ccv_nnc_tensor_view_t
*)inputs[i])->contiguous == 1))) ? 1 : 0), __extension__ (
{ if (inputs[i]->info.datatype == CCV_32F && (!((*
(int*)(inputs[i])) & CCV_TENSOR_VIEW) || (((ccv_nnc_tensor_view_t
*)inputs[i])->contiguous == 1))) ; else __assert_fail ("inputs[i]->info.datatype == CCV_32F && CCV_IS_TENSOR_CONTIGUOUS(inputs[i])"
, "causal_convolution/ccv_nnc_causal_convolution_cpu_ref.c", 19
, __extension__ __PRETTY_FUNCTION__); }))
;
6
Assuming field 'datatype' is equal to CCV_32F
7
Assuming the condition is false
8
Assuming field 'contiguous' is equal to 1
9
Taking true branch
11
Assuming field 'datatype' is equal to CCV_32F
12
Assuming the condition is true
14
Assuming field 'datatype' is equal to CCV_32F
15
Assuming the condition is true
20 for (i = 0; i < 2; i++)
17
Loop condition is true. Entering loop body
22
Loop condition is true. Entering loop body
25
Loop condition is false. Execution continues on line 23
21 assert(outputs[i]->info.datatype == CCV_32F && CCV_IS_TENSOR_CONTIGUOUS(outputs[i]))((void) sizeof ((outputs[i]->info.datatype == CCV_32F &&
(!((*(int*)(outputs[i])) & CCV_TENSOR_VIEW) || (((ccv_nnc_tensor_view_t
*)outputs[i])->contiguous == 1))) ? 1 : 0), __extension__ (
{ if (outputs[i]->info.datatype == CCV_32F && (!((
*(int*)(outputs[i])) & CCV_TENSOR_VIEW) || (((ccv_nnc_tensor_view_t
*)outputs[i])->contiguous == 1))) ; else __assert_fail ("outputs[i]->info.datatype == CCV_32F && CCV_IS_TENSOR_CONTIGUOUS(outputs[i])"
, "causal_convolution/ccv_nnc_causal_convolution_cpu_ref.c", 21
, __extension__ __PRETTY_FUNCTION__); }))
;
18
Assuming field 'datatype' is equal to CCV_32F
19
Assuming the condition is false
20
Assuming field 'contiguous' is equal to 1
21
Taking true branch
23
Assuming field 'datatype' is equal to CCV_32F
24
Assuming the condition is true
22 // Shapes only matter through their counts: C is x's last axis and the previous rows hold B batches.
23 const int channels = x->info.dim[ccv_nnc_tensor_nd(x->info.dim) - 1];
24 const int kernel_size = ccv_nnc_tensor_count(weight->info) / channels;
25 // One tap has no previous rows to carry.
26 assert(kernel_size >= 2 && ccv_nnc_tensor_count(weight->info) == (size_t)kernel_size * channels)((void) sizeof ((kernel_size >= 2 && ccv_nnc_tensor_count
(weight->info) == (size_t)kernel_size * channels) ? 1 : 0)
, __extension__ ({ if (kernel_size >= 2 && ccv_nnc_tensor_count
(weight->info) == (size_t)kernel_size * channels) ; else __assert_fail
("kernel_size >= 2 && ccv_nnc_tensor_count(weight->info) == (size_t)kernel_size * channels"
, "causal_convolution/ccv_nnc_causal_convolution_cpu_ref.c", 26
, __extension__ __PRETTY_FUNCTION__); }))
;
26
Assuming 'kernel_size' is >= 2
27
Assuming the condition is true
28
Taking true branch
27 const int B = ccv_nnc_tensor_count(previous->info) / ((size_t)(kernel_size - 1) * channels);
29
'B' initialized to 0
28 const int T = ccv_nnc_tensor_count(x->info) / ((size_t)B * channels);
30
Division by zero
29 const int rows = ccv_nnc_tensor_count(next->info) / ((size_t)B * channels);
30 assert(ccv_nnc_tensor_count(y->info) == (size_t)B * T * channels)((void) sizeof ((ccv_nnc_tensor_count(y->info) == (size_t)
B * T * channels) ? 1 : 0), __extension__ ({ if (ccv_nnc_tensor_count
(y->info) == (size_t)B * T * channels) ; else __assert_fail
("ccv_nnc_tensor_count(y->info) == (size_t)B * T * channels"
, "causal_convolution/ccv_nnc_causal_convolution_cpu_ref.c", 30
, __extension__ __PRETTY_FUNCTION__); }))
;
31 assert(rows <= kernel_size - 1 + T)((void) sizeof ((rows <= kernel_size - 1 + T) ? 1 : 0), __extension__
({ if (rows <= kernel_size - 1 + T) ; else __assert_fail (
"rows <= kernel_size - 1 + T", "causal_convolution/ccv_nnc_causal_convolution_cpu_ref.c"
, 31, __extension__ __PRETTY_FUNCTION__); }))
;
32 const int history = kernel_size - 1;
33 // Context row r of batch b is previous row r, then x row r - history.
34#define CONTEXT(b, r, c) ((r) < history ? previous->data.f32[((size_t)(b) * history + (r)) * channels + (c)] : x->data.f32[((size_t)(b) * T + (r) - history) * channels + (c)])
35 const int silu = cmd.info.causal_convolution.silu;
36 int b, t, c, j;
37 for (b = 0; b < B; b++)
38 for (c = 0; c < channels; c++)
39 {
40 const float* const w = weight->data.f32 + (size_t)c * kernel_size;
41 for (t = 0; t < T; t++)
42 {
43 float sum = 0;
44 for (j = 0; j < kernel_size; j++)
45 sum += w[j] * CONTEXT(b, t + j, c);
46 y->data.f32[((size_t)b * T + t) * channels + c] = silu ? sum / (1 + expf(-sum)) : sum;
47 }
48 // The next rows are the context's last rows.
49 const int first = history + T - rows;
50 for (j = 0; j < rows; j++)
51 next->data.f32[((size_t)b * rows + j) * channels + c] = CONTEXT(b, first + j, c);
52 }
53#undef CONTEXT
54 return CCV_NNC_EXEC_SUCCESS;
55}
56
57static int _ccv_nnc_causal_convolution_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)
58{
59 return CCV_NNC_EXEC_INVALID;
60}
61
62REGISTER_COMMAND_BACKEND(CCV_NNC_CAUSAL_CONVOLUTION_FORWARD, CCV_NNC_BACKEND_CPU_REF)void _register_command_CCV_NNC_CAUSAL_CONVOLUTION_FORWARD_backend_CCV_NNC_BACKEND_CPU_REF(ccv_nnc_cmd_backend_registry_t* const registry)
63{
64 registry->tensor_formats = CCV_TENSOR_FORMAT_NHWC | CCV_TENSOR_FORMAT_NCHW | CCV_TENSOR_FORMAT_CHWN;
65 registry->tensor_datatypes = CCV_32F;
66 registry->tensor_memory = CCV_TENSOR_CPU_MEMORY;
67 registry->algorithms = 1;
68 registry->exec = _ccv_nnc_causal_convolution_forw;
69}
70
71REGISTER_COMMAND_BACKEND(CCV_NNC_CAUSAL_CONVOLUTION_BACKWARD, CCV_NNC_BACKEND_CPU_REF)void _register_command_CCV_NNC_CAUSAL_CONVOLUTION_BACKWARD_backend_CCV_NNC_BACKEND_CPU_REF(ccv_nnc_cmd_backend_registry_t* const registry)
72{
73 registry->tensor_formats = CCV_TENSOR_FORMAT_NHWC | CCV_TENSOR_FORMAT_NCHW | CCV_TENSOR_FORMAT_CHWN;
74 registry->tensor_datatypes = CCV_32F;
75 registry->tensor_memory = CCV_TENSOR_CPU_MEMORY;
76 registry->algorithms = 1;
77 registry->exec = _ccv_nnc_causal_convolution_back;
78}