Bug Summary

File:nnc/ccv_nnc_tensor_io.c
Warning:line 172, column 14
Value stored to 'payload' during its initialization is never read

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_tensor_io.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 -fcoverage-compilation-dir=/home/liu/actions-runner/_work/ccv/ccv/lib/nnc -resource-dir /usr/local/lib/clang/19 -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-05-01-233500-1493103-1 -x c ccv_nnc_tensor_io.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_nnc_symbolic_graph.h"
6#include "3rdparty/sqlite3/sqlite3.h"
7#include <limits.h>
8#include <stdint.h>
9#ifdef HAVE_CUDA1
10#include "gpu/ccv_nnc_compat.h"
11#elif HAVE_MPS
12#include "mps/ccv_nnc_mps.h"
13#endif
14
15#ifdef NDEBUG
16#define SQLITE_ENFORCE(stmt)((void) sizeof ((stmt) ? 1 : 0), __extension__ ({ if (stmt) ;
else __assert_fail ("stmt", "ccv_nnc_tensor_io.c", 16, __extension__
__PRETTY_FUNCTION__); }))
(void)(stmt)
17#else
18#define SQLITE_ENFORCEassert assert
19#endif
20
21// SQLite INTEGER is 64-bit. Tensor IO already packs side metadata into the
22// high 32 bits of type / datatype. Tensor formats are low 32-bit int enum
23// values (NCHW/NHWC/CHWN), so bit 32 can mark that tensors.data is the head
24// chunk. Always mask this out before assigning to ccv_nnc_tensor_param_t.format.
25#define CCV_NNC_TENSOR_IO_SPLIT_FORMAT(((sqlite_int64)1) << 32) (((sqlite_int64)1) << 32)
26#define CCV_NNC_TENSOR_IO_FORMAT_MASK0xffffffffll 0xffffffffll
27#define CCV_NNC_TENSOR_IO_SPLIT_HEADROOM1024 1024
28
29static int _ccv_nnc_tensor_io_blob_chunk_size(sqlite3* const conn)
30{
31 const int limit = sqlite3_limit(conn, SQLITE_LIMIT_LENGTH0, -1);
32 if (limit <= 0)
33 return INT_MAX2147483647;
34 if (limit > CCV_NNC_TENSOR_IO_SPLIT_HEADROOM1024 * 2)
35 return limit - CCV_NNC_TENSOR_IO_SPLIT_HEADROOM1024;
36 return limit > 1 ? limit / 2 : 1;
37}
38
39static int _ccv_nnc_tensor_io_delete_splits(sqlite3* const conn, const char* const name)
40{
41 const char tensor_split_delete_qs[] = "DELETE FROM tensor_splits WHERE name=$name";
42 sqlite3_stmt* tensor_split_delete_stmt = 0;
43 int rc = sqlite3_prepare_v2(conn, tensor_split_delete_qs, sizeof(tensor_split_delete_qs), &tensor_split_delete_stmt, 0);
44 if (rc != SQLITE_OK0)
45 return rc;
46 sqlite3_bind_text(tensor_split_delete_stmt, 1, name, -1, SQLITE_STATIC((sqlite3_destructor_type)0));
47 rc = sqlite3_step(tensor_split_delete_stmt);
48 sqlite3_finalize(tensor_split_delete_stmt);
49 return rc == SQLITE_DONE101 ? SQLITE_OK0 : rc;
50}
51
52static int _ccv_nnc_tensor_io_write_splits(sqlite3* const conn, const char* const name, const unsigned char* const data, const size_t data_size, const size_t offset, const int chunk_size)
53{
54 const char tensor_split_insert_qs[] =
55 "REPLACE INTO tensor_splits "
56 "(name, part, data) VALUES ($name, $part, $data)";
57 sqlite3_stmt* tensor_split_insert_stmt = 0;
58 int rc = sqlite3_prepare_v2(conn, tensor_split_insert_qs, sizeof(tensor_split_insert_qs), &tensor_split_insert_stmt, 0);
59 if (rc != SQLITE_OK0)
60 return rc;
61 size_t pos = offset;
62 int part = 0;
63 while (pos < data_size)
64 {
65 const size_t tail_size = data_size - pos;
66 const int write_size = (int)ccv_min(tail_size, (size_t)chunk_size)({ typeof (tail_size) _a = (tail_size); typeof ((size_t)chunk_size
) _b = ((size_t)chunk_size); (_a < _b) ? _a : _b; })
;
67 sqlite3_bind_text(tensor_split_insert_stmt, 1, name, -1, SQLITE_STATIC((sqlite3_destructor_type)0));
68 sqlite3_bind_int(tensor_split_insert_stmt, 2, part++);
69 rc = sqlite3_bind_blob(tensor_split_insert_stmt, 3, data + pos, write_size, SQLITE_STATIC((sqlite3_destructor_type)0));
70 if (rc != SQLITE_OK0)
71 break;
72 rc = sqlite3_step(tensor_split_insert_stmt);
73 if (rc != SQLITE_DONE101)
74 break;
75 sqlite3_reset(tensor_split_insert_stmt);
76 sqlite3_clear_bindings(tensor_split_insert_stmt);
77 pos += write_size;
78 }
79 sqlite3_finalize(tensor_split_insert_stmt);
80 return rc == SQLITE_DONE101 ? SQLITE_OK0 : rc;
81}
82
83static int _ccv_nnc_tensor_io_read_split_data(sqlite3* const conn, const char* const name, const void* const first_data, const size_t first_size, const void** const data_out, size_t* const data_size_out, unsigned char** const workspace_out)
84{
85 const char tensor_split_size_qs[] = "SELECT COUNT(*), SUM(length(data)) FROM tensor_splits WHERE name=$name";
86 sqlite3_stmt* tensor_split_size_stmt = 0;
87 int rc = sqlite3_prepare_v2(conn, tensor_split_size_qs, sizeof(tensor_split_size_qs), &tensor_split_size_stmt, 0);
88 if (rc != SQLITE_OK0)
89 return rc;
90 sqlite3_bind_text(tensor_split_size_stmt, 1, name, -1, SQLITE_STATIC((sqlite3_destructor_type)0));
91 rc = sqlite3_step(tensor_split_size_stmt);
92 if (rc != SQLITE_ROW100)
93 {
94 sqlite3_finalize(tensor_split_size_stmt);
95 return rc;
96 }
97 const sqlite_int64 split_count = sqlite3_column_int64(tensor_split_size_stmt, 0);
98 const sqlite_int64 tail_size = sqlite3_column_int64(tensor_split_size_stmt, 1);
99 sqlite3_finalize(tensor_split_size_stmt);
100 if (split_count <= 0 || tail_size < 0 || (size_t)tail_size > SIZE_MAX(18446744073709551615UL) - first_size)
101 return SQLITE_CORRUPT11;
102 const size_t total_size = first_size + (size_t)tail_size;
103 unsigned char* const workspace = (unsigned char*)ccmallocmalloc(total_size);
104 if (first_size > 0)
105 memcpy(workspace, first_data, first_size);
106 const char tensor_split_select_qs[] = "SELECT part, data FROM tensor_splits WHERE name=$name ORDER BY part";
107 sqlite3_stmt* tensor_split_select_stmt = 0;
108 rc = sqlite3_prepare_v2(conn, tensor_split_select_qs, sizeof(tensor_split_select_qs), &tensor_split_select_stmt, 0);
109 if (rc != SQLITE_OK0)
110 {
111 ccfreefree(workspace);
112 return rc;
113 }
114 sqlite3_bind_text(tensor_split_select_stmt, 1, name, -1, SQLITE_STATIC((sqlite3_destructor_type)0));
115 size_t offset = first_size;
116 int expected_part = 0;
117 while ((rc = sqlite3_step(tensor_split_select_stmt)) == SQLITE_ROW100)
118 {
119 if (sqlite3_column_int(tensor_split_select_stmt, 0) != expected_part++)
120 {
121 sqlite3_finalize(tensor_split_select_stmt);
122 ccfreefree(workspace);
123 return SQLITE_CORRUPT11;
124 }
125 const int split_size = sqlite3_column_bytes(tensor_split_select_stmt, 1);
126 if (split_size < 0 || (size_t)split_size > total_size - offset)
127 {
128 sqlite3_finalize(tensor_split_select_stmt);
129 ccfreefree(workspace);
130 return SQLITE_CORRUPT11;
131 }
132 const void* const split_data = sqlite3_column_blob(tensor_split_select_stmt, 1);
133 if (split_size > 0)
134 memcpy(workspace + offset, split_data, split_size);
135 offset += split_size;
136 }
137 sqlite3_finalize(tensor_split_select_stmt);
138 if (rc != SQLITE_DONE101 || offset != total_size)
139 {
140 ccfreefree(workspace);
141 return rc == SQLITE_DONE101 ? SQLITE_CORRUPT11 : rc;
142 }
143 *data_out = workspace;
144 *data_size_out = total_size;
145 *workspace_out = workspace;
146 return SQLITE_OK0;
147}
148
149// MARK - Level-1 API
150
151int ccv_nnc_tensor_write(const ccv_nnc_tensor_t* const tensor, void* const handle, const char* const name, const ccv_nnc_tensor_io_option_t* const options)
152{
153 assert(CCV_IS_TENSOR_CONTIGUOUS(tensor))((void) sizeof (((!((*(int*)(tensor)) & CCV_TENSOR_VIEW) ||
(((ccv_nnc_tensor_view_t*)tensor)->contiguous == 1))) ? 1
: 0), __extension__ ({ if ((!((*(int*)(tensor)) & CCV_TENSOR_VIEW
) || (((ccv_nnc_tensor_view_t*)tensor)->contiguous == 1)))
; else __assert_fail ("CCV_IS_TENSOR_CONTIGUOUS(tensor)", "ccv_nnc_tensor_io.c"
, 153, __extension__ __PRETTY_FUNCTION__); }))
;
154 assert(name)((void) sizeof ((name) ? 1 : 0), __extension__ ({ if (name) ;
else __assert_fail ("name", "ccv_nnc_tensor_io.c", 154, __extension__
__PRETTY_FUNCTION__); }))
;
155 sqlite3* conn = (sqlite3*)handle;
156 if (!conn)
157 return CCV_IO_ERROR;
158 const char tensor_create_table_qs[] = "CREATE TABLE IF NOT EXISTS tensors "
159 "(name TEXT, type INTEGER, format INTEGER, datatype INTEGER, "
160 "dim BLOB, data BLOB, PRIMARY KEY (name))";
161 SQLITE_ENFORCE(SQLITE_OK == sqlite3_exec(conn, tensor_create_table_qs, 0, 0, 0))((void) sizeof ((0 == sqlite3_exec(conn, tensor_create_table_qs
, 0, 0, 0)) ? 1 : 0), __extension__ ({ if (0 == sqlite3_exec(
conn, tensor_create_table_qs, 0, 0, 0)) ; else __assert_fail (
"SQLITE_OK == sqlite3_exec(conn, tensor_create_table_qs, 0, 0, 0)"
, "ccv_nnc_tensor_io.c", 161, __extension__ __PRETTY_FUNCTION__
); }))
;
162 const char tensor_insert_qs[] =
163 "REPLACE INTO tensors "
164 "(name, type, format, datatype, dim, data) VALUES ("
165 "$name, $type, $format, $datatype, $dim, $data)";
166 sqlite3_stmt* tensor_insert_stmt = 0;
167 SQLITE_ENFORCE(SQLITE_OK == sqlite3_prepare_v2(conn, tensor_insert_qs, sizeof(tensor_insert_qs), &tensor_insert_stmt, 0))((void) sizeof ((0 == sqlite3_prepare_v2(conn, tensor_insert_qs
, sizeof(tensor_insert_qs), &tensor_insert_stmt, 0)) ? 1 :
0), __extension__ ({ if (0 == sqlite3_prepare_v2(conn, tensor_insert_qs
, sizeof(tensor_insert_qs), &tensor_insert_stmt, 0)) ; else
__assert_fail ("SQLITE_OK == sqlite3_prepare_v2(conn, tensor_insert_qs, sizeof(tensor_insert_qs), &tensor_insert_stmt, 0)"
, "ccv_nnc_tensor_io.c", 167, __extension__ __PRETTY_FUNCTION__
); }))
;
168 sqlite3_bind_text(tensor_insert_stmt, 1, name, -1, 0);
169 ccv_nnc_tensor_param_t params = tensor->info;
170 const size_t data_size = ccv_nnc_tensor_data_size_without_padding(tensor->info);
171 unsigned char* workspace = 0;
172 const void* payload = tensor->data.u8;
Value stored to 'payload' during its initialization is never read
173 size_t payload_size = data_size;
174 unsigned int identifier = 0;
175#ifdef HAVE_CUDA1
176 if (CCV_TENSOR_GET_MEMORY(tensor->info.type)((tensor->info.type) & 0x3) == CCV_TENSOR_GPU_MEMORY)
177 {
178 if (!options || !options->encode)
179 {
180 workspace = ccmallocmalloc(data_size);
181 cumemcpy(workspace, CCV_TENSOR_CPU_MEMORY, tensor->data.u8, tensor->info.type, data_size);
182 payload = workspace;
183 } else {
184 workspace = ccmallocmalloc(data_size * 2 + 4);
185 cumemcpy(workspace, CCV_TENSOR_CPU_MEMORY, tensor->data.u8, tensor->info.type, data_size);
186 size_t encoded_size = data_size + 4;
187 if (options->encode(workspace, data_size, tensor->info.datatype, tensor->info.dim, ccv_nnc_tensor_nd(tensor->info.dim), options->context, workspace + data_size, &encoded_size, &params, &identifier))
188 {
189 payload = workspace + data_size;
190 payload_size = encoded_size;
191 }
192 else
193 payload = workspace;
194 }
195 } else {
196 if (!options || !options->encode)
197 payload = tensor->data.u8;
198 else {
199 workspace = ccmallocmalloc(data_size + 4);
200 size_t encoded_size = data_size + 4;
201 if (options->encode(tensor->data.u8, data_size, tensor->info.datatype, tensor->info.dim, ccv_nnc_tensor_nd(tensor->info.dim), options->context, workspace, &encoded_size, &params, &identifier))
202 {
203 payload = workspace;
204 payload_size = encoded_size;
205 }
206 else
207 payload = tensor->data.u8;
208 }
209 }
210#elif defined(HAVE_MPS)
211 if (CCV_TENSOR_GET_MEMORY(tensor->info.type)((tensor->info.type) & 0x3) == CCV_TENSOR_GPU_MEMORY)
212 {
213 if (!options || !options->encode)
214 {
215 workspace = ccmallocmalloc(data_size);
216 mpmemcpy(workspace, 0, CCV_TENSOR_CPU_MEMORY, tensor->data.u8, tensor->dataof, tensor->info.type, data_size);
217 payload = workspace;
218 } else {
219 workspace = ccmallocmalloc(data_size * 2 + 4);
220 mpmemcpy(workspace, 0, CCV_TENSOR_CPU_MEMORY, tensor->data.u8, tensor->dataof, tensor->info.type, data_size);
221 size_t encoded_size = data_size + 4;
222 if (options->encode(workspace, data_size, tensor->info.datatype, tensor->info.dim, ccv_nnc_tensor_nd(tensor->info.dim), options->context, workspace + data_size, &encoded_size, &params, &identifier))
223 {
224 payload = workspace + data_size;
225 payload_size = encoded_size;
226 }
227 else
228 payload = workspace;
229 }
230 } else {
231 if (!options || !options->encode)
232 payload = tensor->data.u8;
233 else {
234 workspace = ccmallocmalloc(data_size + 4); // Allocate extra 4 bytes in case we need to copy the QX tensor out.
235 size_t encoded_size = data_size + 4;
236 if (options->encode(tensor->data.u8, data_size, tensor->info.datatype, tensor->info.dim, ccv_nnc_tensor_nd(tensor->info.dim), options->context, workspace, &encoded_size, &params, &identifier))
237 {
238 payload = workspace;
239 payload_size = encoded_size;
240 }
241 else
242 payload = tensor->data.u8;
243 }
244 }
245#else
246 if (!options || !options->encode)
247 payload = tensor->data.u8;
248 else {
249 workspace = ccmallocmalloc(data_size + 4);
250 size_t encoded_size = data_size + 4;
251 if (options->encode(tensor->data.u8, data_size, tensor->info.datatype, tensor->info.dim, ccv_nnc_tensor_nd(tensor->info.dim), options->context, workspace, &encoded_size, &params, &identifier))
252 {
253 payload = workspace;
254 payload_size = encoded_size;
255 }
256 else
257 payload = tensor->data.u8;
258 }
259#endif
260 int result = SQLITE_TOOBIG18;
261 int bind_result = payload_size <= INT_MAX2147483647 ? sqlite3_bind_blob(tensor_insert_stmt, 6, payload, (int)payload_size, 0) : SQLITE_TOOBIG18;
262 if (bind_result == SQLITE_OK0)
263 {
264 sqlite3_bind_int64(tensor_insert_stmt, 2, ((sqlite_int64)identifier << 32) | params.type);
265 sqlite3_bind_int(tensor_insert_stmt, 3, params.format);
266 sqlite3_bind_int64(tensor_insert_stmt, 4, ((sqlite_int64)params.reserved << 32) | params.datatype);
267 sqlite3_bind_blob(tensor_insert_stmt, 5, params.dim, sizeof(params.dim), 0);
268 result = sqlite3_step(tensor_insert_stmt);
269 if (result == SQLITE_DONE101)
270 {
271 sqlite3_reset(tensor_insert_stmt);
272 sqlite3_clear_bindings(tensor_insert_stmt);
273 sqlite3_finalize(tensor_insert_stmt);
274 if (workspace)
275 free(workspace);
276 return CCV_IO_FINAL;
277 }
278 sqlite3_reset(tensor_insert_stmt);
279 sqlite3_clear_bindings(tensor_insert_stmt);
280 if (result != SQLITE_TOOBIG18)
281 {
282 sqlite3_finalize(tensor_insert_stmt);
283 if (workspace)
284 free(workspace);
285 return CCV_IO_ERROR;
286 }
287 } else {
288 sqlite3_reset(tensor_insert_stmt);
289 sqlite3_clear_bindings(tensor_insert_stmt);
290 if (bind_result != SQLITE_TOOBIG18)
291 {
292 sqlite3_finalize(tensor_insert_stmt);
293 if (workspace)
294 free(workspace);
295 return CCV_IO_ERROR;
296 }
297 }
298 if (sqlite3_exec(conn, "SAVEPOINT ccv_nnc_tensor_write", 0, 0, 0) != SQLITE_OK0)
299 {
300 sqlite3_finalize(tensor_insert_stmt);
301 if (workspace)
302 free(workspace);
303 return CCV_IO_ERROR;
304 }
305 const char tensor_split_create_table_qs[] = "CREATE TABLE IF NOT EXISTS tensor_splits "
306 "(name TEXT, part INTEGER, data BLOB, PRIMARY KEY (name, part))";
307 if (sqlite3_exec(conn, tensor_split_create_table_qs, 0, 0, 0) != SQLITE_OK0)
308 {
309 sqlite3_finalize(tensor_insert_stmt);
310 sqlite3_exec(conn, "ROLLBACK TO ccv_nnc_tensor_write", 0, 0, 0);
311 sqlite3_exec(conn, "RELEASE ccv_nnc_tensor_write", 0, 0, 0);
312 if (workspace)
313 free(workspace);
314 return CCV_IO_ERROR;
315 }
316 sqlite3_bind_text(tensor_insert_stmt, 1, name, -1, 0);
317 const int chunk_size = _ccv_nnc_tensor_io_blob_chunk_size(conn);
318 assert(chunk_size > 0)((void) sizeof ((chunk_size > 0) ? 1 : 0), __extension__ (
{ if (chunk_size > 0) ; else __assert_fail ("chunk_size > 0"
, "ccv_nnc_tensor_io.c", 318, __extension__ __PRETTY_FUNCTION__
); }))
;
319 const size_t first_size = ccv_min(payload_size, (size_t)chunk_size)({ typeof (payload_size) _a = (payload_size); typeof ((size_t
)chunk_size) _b = ((size_t)chunk_size); (_a < _b) ? _a : _b
; })
;
320 bind_result = first_size < payload_size ? sqlite3_bind_blob(tensor_insert_stmt, 6, payload, (int)first_size, SQLITE_STATIC((sqlite3_destructor_type)0)) : SQLITE_TOOBIG18;
321 if (bind_result == SQLITE_OK0)
322 bind_result = _ccv_nnc_tensor_io_delete_splits(conn, name);
323 if (bind_result == SQLITE_OK0)
324 bind_result = _ccv_nnc_tensor_io_write_splits(conn, name, (const unsigned char*)payload, payload_size, first_size, chunk_size);
325 if (bind_result != SQLITE_OK0)
326 {
327 sqlite3_finalize(tensor_insert_stmt);
328 sqlite3_exec(conn, "ROLLBACK TO ccv_nnc_tensor_write", 0, 0, 0);
329 sqlite3_exec(conn, "RELEASE ccv_nnc_tensor_write", 0, 0, 0);
330 if (workspace)
331 free(workspace);
332 return CCV_IO_ERROR;
333 }
334 sqlite3_bind_int64(tensor_insert_stmt, 2, ((sqlite_int64)identifier << 32) | params.type);
335 sqlite3_bind_int64(tensor_insert_stmt, 3, ((sqlite_int64)params.format & CCV_NNC_TENSOR_IO_FORMAT_MASK0xffffffffll) | CCV_NNC_TENSOR_IO_SPLIT_FORMAT(((sqlite_int64)1) << 32));
336 sqlite3_bind_int64(tensor_insert_stmt, 4, ((sqlite_int64)params.reserved << 32) | params.datatype);
337 sqlite3_bind_blob(tensor_insert_stmt, 5, params.dim, sizeof(params.dim), 0);
338 result = sqlite3_step(tensor_insert_stmt);
339 sqlite3_reset(tensor_insert_stmt);
340 sqlite3_clear_bindings(tensor_insert_stmt);
341 sqlite3_finalize(tensor_insert_stmt);
342 if (result == SQLITE_DONE101)
343 {
344 if (sqlite3_exec(conn, "RELEASE ccv_nnc_tensor_write", 0, 0, 0) != SQLITE_OK0)
345 {
346 if (workspace)
347 free(workspace);
348 return CCV_IO_ERROR;
349 }
350 } else {
351 sqlite3_exec(conn, "ROLLBACK TO ccv_nnc_tensor_write", 0, 0, 0);
352 sqlite3_exec(conn, "RELEASE ccv_nnc_tensor_write", 0, 0, 0);
353 }
354 if (workspace)
355 free(workspace);
356 return result == SQLITE_DONE101 ? CCV_IO_FINAL : CCV_IO_ERROR;
357}
358
359int ccv_nnc_tensor_read(void* const handle, const char* const name, const ccv_nnc_tensor_io_option_t* const options, const int flags, const ccv_nnc_tensor_param_t* const tensor_params_optional, ccv_nnc_tensor_t** const tensor_out)
360{
361 assert(name)((void) sizeof ((name) ? 1 : 0), __extension__ ({ if (name) ;
else __assert_fail ("name", "ccv_nnc_tensor_io.c", 361, __extension__
__PRETTY_FUNCTION__); }))
;
362 sqlite3* conn = (sqlite3*)handle;
363 if (!conn)
364 return CCV_IO_ERROR;
365 const char tensor_select_qs[] =
366 "SELECT data, type, format, datatype, dim FROM tensors WHERE name=$name";
367 sqlite3_stmt* tensor_select_stmt = 0;
368 if (SQLITE_OK0 != sqlite3_prepare_v2(conn, tensor_select_qs, sizeof(tensor_select_qs), &tensor_select_stmt, 0))
369 return CCV_IO_ERROR;
370 sqlite3_bind_text(tensor_select_stmt, 1, name, -1, 0);
371 if (SQLITE_ROW100 != sqlite3_step(tensor_select_stmt))
372 {
373 sqlite3_finalize(tensor_select_stmt);
374 return CCV_IO_ERROR;
375 }
376 ccv_nnc_tensor_t* tensor = *tensor_out;
377 ccv_nnc_tensor_param_t tensor_params;
378 int datatype = 0;
379 unsigned int identifier = 0;
380 const sqlite_int64 format_mix = sqlite3_column_int64(tensor_select_stmt, 2);
381 const int has_splits = !!(format_mix & CCV_NNC_TENSOR_IO_SPLIT_FORMAT(((sqlite_int64)1) << 32));
382 if (!tensor) // If the tensor is not provided, we need to create one.
383 {
384 if (tensor_params_optional)
385 {
386 identifier = (sqlite3_column_int64(tensor_select_stmt, 1) >> 32) & 0xffffffff;
387 datatype = sqlite3_column_int64(tensor_select_stmt, 3) & 0xffffffff;
388 tensor_params = *tensor_params_optional;
389 assert(!(flags & CCV_NNC_TENSOR_READ_METADATA_ONLY))((void) sizeof ((!(flags & CCV_NNC_TENSOR_READ_METADATA_ONLY
)) ? 1 : 0), __extension__ ({ if (!(flags & CCV_NNC_TENSOR_READ_METADATA_ONLY
)) ; else __assert_fail ("!(flags & CCV_NNC_TENSOR_READ_METADATA_ONLY)"
, "ccv_nnc_tensor_io.c", 389, __extension__ __PRETTY_FUNCTION__
); }))
;
390 } else {
391 const sqlite_int64 type = sqlite3_column_int64(tensor_select_stmt, 1);
392 identifier = (type >> 32) & 0xffffffff;
393 tensor_params.type = (type & 0xffffffff);
394 tensor_params.format = (int)(format_mix & CCV_NNC_TENSOR_IO_FORMAT_MASK0xffffffffll);
395 const sqlite_int64 datatype_mix = sqlite3_column_int64(tensor_select_stmt, 3);
396 datatype = tensor_params.datatype = (datatype_mix & 0xffffffff);
397 tensor_params.reserved = (datatype_mix >> 32) & 0xffffffff;
398 const void* const dim = sqlite3_column_blob(tensor_select_stmt, 4);
399 memcpy(tensor_params.dim, dim, ccv_min(sizeof(tensor_params.dim), sqlite3_column_bytes(tensor_select_stmt, 4))({ typeof (sizeof(tensor_params.dim)) _a = (sizeof(tensor_params
.dim)); typeof (sqlite3_column_bytes(tensor_select_stmt, 4)) _b
= (sqlite3_column_bytes(tensor_select_stmt, 4)); (_a < _b
) ? _a : _b; })
);
400 }
401 if (flags & CCV_NNC_TENSOR_READ_CPU_MEMORY) // Reset type to CPU memory.
402 tensor_params.type = (tensor_params.type & 0xfff00000) | CCV_TENSOR_CPU_MEMORY;
403 if (!options || !options->decode)
404 {
405 if (flags & CCV_NNC_TENSOR_READ_METADATA_ONLY)
406 {
407 *tensor_out = tensor = ccv_nnc_tensor_new(0, tensor_params, CCV_NO_DATA_ALLOC); // Set the data point to 1 so it is allocated without data.
408 assert(tensor->data.u8 == 0)((void) sizeof ((tensor->data.u8 == 0) ? 1 : 0), __extension__
({ if (tensor->data.u8 == 0) ; else __assert_fail ("tensor->data.u8 == 0"
, "ccv_nnc_tensor_io.c", 408, __extension__ __PRETTY_FUNCTION__
); }))
; // Set it back to 0.
409 // Already done loading metadata, return.
410 sqlite3_reset(tensor_select_stmt);
411 sqlite3_clear_bindings(tensor_select_stmt);
412 sqlite3_finalize(tensor_select_stmt);
413 return CCV_IO_FINAL;
414 } else
415 *tensor_out = tensor = ccv_nnc_tensor_new(0, tensor_params, 0);
416 } else {
417 assert(!(flags & CCV_NNC_TENSOR_READ_METADATA_ONLY))((void) sizeof ((!(flags & CCV_NNC_TENSOR_READ_METADATA_ONLY
)) ? 1 : 0), __extension__ ({ if (!(flags & CCV_NNC_TENSOR_READ_METADATA_ONLY
)) ; else __assert_fail ("!(flags & CCV_NNC_TENSOR_READ_METADATA_ONLY)"
, "ccv_nnc_tensor_io.c", 417, __extension__ __PRETTY_FUNCTION__
); }))
;
418 }
419 } else {
420 identifier = (sqlite3_column_int64(tensor_select_stmt, 1) >> 32) & 0xffffffff;
421 datatype = sqlite3_column_int64(tensor_select_stmt, 3) & 0xffffffff;
422 tensor_params = tensor->info;
423 assert(!(flags & CCV_NNC_TENSOR_READ_METADATA_ONLY))((void) sizeof ((!(flags & CCV_NNC_TENSOR_READ_METADATA_ONLY
)) ? 1 : 0), __extension__ ({ if (!(flags & CCV_NNC_TENSOR_READ_METADATA_ONLY
)) ; else __assert_fail ("!(flags & CCV_NNC_TENSOR_READ_METADATA_ONLY)"
, "ccv_nnc_tensor_io.c", 423, __extension__ __PRETTY_FUNCTION__
); }))
;
424 }
425 const void* data = sqlite3_column_blob(tensor_select_stmt, 0);
426 size_t data_bytes = sqlite3_column_bytes(tensor_select_stmt, 0);
427 unsigned char* split_workspace = 0;
428 if (has_splits)
429 {
430 const int split_result = _ccv_nnc_tensor_io_read_split_data(conn, name, data, data_bytes, &data, &data_bytes, &split_workspace);
431 if (split_result != SQLITE_OK0)
432 {
433 sqlite3_reset(tensor_select_stmt);
434 sqlite3_clear_bindings(tensor_select_stmt);
435 sqlite3_finalize(tensor_select_stmt);
436 return CCV_IO_ERROR;
437 }
438 }
439 int dim[CCV_NNC_MAX_DIM_ALLOC(12)];
440 memcpy(dim, sqlite3_column_blob(tensor_select_stmt, 4), ccv_min(sizeof(dim), sqlite3_column_bytes(tensor_select_stmt, 4))({ typeof (sizeof(dim)) _a = (sizeof(dim)); typeof (sqlite3_column_bytes
(tensor_select_stmt, 4)) _b = (sqlite3_column_bytes(tensor_select_stmt
, 4)); (_a < _b) ? _a : _b; })
);
441 const int nd = ccv_nnc_tensor_nd(dim);
442 if (datatype != tensor_params.datatype && CCV_GET_DATA_TYPE(tensor_params.datatype)((tensor_params.datatype) & 0xFF000) != CCV_QX)
443 {
444 // Only ever works for 16F to 32F or 32F to 16F transparently.
445 assert((datatype == CCV_16F && tensor_params.datatype == CCV_32F) || (datatype == CCV_32F && tensor_params.datatype == CCV_16F))((void) sizeof (((datatype == CCV_16F && tensor_params
.datatype == CCV_32F) || (datatype == CCV_32F && tensor_params
.datatype == CCV_16F)) ? 1 : 0), __extension__ ({ if ((datatype
== CCV_16F && tensor_params.datatype == CCV_32F) || (
datatype == CCV_32F && tensor_params.datatype == CCV_16F
)) ; else __assert_fail ("(datatype == CCV_16F && tensor_params.datatype == CCV_32F) || (datatype == CCV_32F && tensor_params.datatype == CCV_16F)"
, "ccv_nnc_tensor_io.c", 445, __extension__ __PRETTY_FUNCTION__
); }))
;
446 const size_t tensor_count = ccv_nnc_tensor_count(tensor_params);
447 ccv_nnc_tensor_param_t params = tensor_params;
448 params.datatype = datatype;
449 const size_t source_data_size = ccv_nnc_tensor_data_size(params);
450#ifdef HAVE_CUDA1
451 if (CCV_TENSOR_GET_MEMORY(tensor_params.type)((tensor_params.type) & 0x3) == CCV_TENSOR_GPU_MEMORY)
452 {
453 const size_t data_size = ccv_nnc_tensor_data_size(tensor_params);
454 unsigned char* workspace;
455 unsigned char* copying;
456 size_t decoded_size = data_size;
457 if (!options || !options->decode)
458 {
459 copying = workspace = ccmallocmalloc(data_size);
460 if (datatype == CCV_16F && tensor_params.datatype == CCV_32F)
461 ccv_half_precision_to_float((uint16_t*)data, (float*)workspace, ccv_min(tensor_count, data_bytes / sizeof(uint16_t))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(uint16_t)) _b = (data_bytes / sizeof(uint16_t)); (_a
< _b) ? _a : _b; })
);
462 else if (datatype == CCV_32F && tensor_params.datatype == CCV_16F)
463 ccv_float_to_half_precision((float*)data, (uint16_t*)workspace, ccv_min(tensor_count, data_bytes / sizeof(float))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(float)) _b = (data_bytes / sizeof(float)); (_a <
_b) ? _a : _b; })
);
464 else
465 { assert(0)((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail
("0", "ccv_nnc_tensor_io.c", 465, __extension__ __PRETTY_FUNCTION__
); }))
; }
466 } else {
467 copying = workspace = ccmallocmalloc(data_size + source_data_size);
468 if (datatype == CCV_16F && tensor_params.datatype == CCV_32F)
469 {
470 decoded_size = source_data_size;
471 if (options->decode(data, data_bytes, datatype, dim, nd, identifier, options->context, tensor_params, tensor_out, workspace + data_size, &decoded_size))
472 {
473 // If we loaded quantized tensor, don't do the conversion.
474 if (CCV_GET_DATA_TYPE(tensor_out[0]->info.datatype)((tensor_out[0]->info.datatype) & 0xFF000) == CCV_QX)
475 copying = workspace + data_size;
476 else {
477 ccv_half_precision_to_float((uint16_t*)(workspace + data_size), (float*)workspace, ccv_min(tensor_count, ccv_min(source_data_size, decoded_size) / sizeof(uint16_t))({ typeof (tensor_count) _a = (tensor_count); typeof (({ typeof
(source_data_size) _a = (source_data_size); typeof (decoded_size
) _b = (decoded_size); (_a < _b) ? _a : _b; }) / sizeof(uint16_t
)) _b = (({ typeof (source_data_size) _a = (source_data_size)
; typeof (decoded_size) _b = (decoded_size); (_a < _b) ? _a
: _b; }) / sizeof(uint16_t)); (_a < _b) ? _a : _b; })
);
478 decoded_size = data_size;
479 }
480 } else {
481 if (!tensor)
482 *tensor_out = tensor = ccv_nnc_tensor_new(0, tensor_params, 0);
483 ccv_half_precision_to_float((uint16_t*)data, (float*)workspace, ccv_min(tensor_count, data_bytes / sizeof(uint16_t))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(uint16_t)) _b = (data_bytes / sizeof(uint16_t)); (_a
< _b) ? _a : _b; })
);
484 decoded_size = data_size;
485 }
486 } else if (datatype == CCV_32F && tensor_params.datatype == CCV_16F) {
487 decoded_size = source_data_size;
488 if (options->decode(data, data_bytes, datatype, dim, nd, identifier, options->context, tensor_params, tensor_out, workspace + data_size, &decoded_size))
489 {
490 if (CCV_GET_DATA_TYPE(tensor_out[0]->info.datatype)((tensor_out[0]->info.datatype) & 0xFF000) == CCV_QX)
491 copying = workspace + data_size;
492 else {
493 ccv_float_to_half_precision((float*)(workspace + data_size), (uint16_t*)workspace, ccv_min(tensor_count, ccv_min(source_data_size, decoded_size) / sizeof(float))({ typeof (tensor_count) _a = (tensor_count); typeof (({ typeof
(source_data_size) _a = (source_data_size); typeof (decoded_size
) _b = (decoded_size); (_a < _b) ? _a : _b; }) / sizeof(float
)) _b = (({ typeof (source_data_size) _a = (source_data_size)
; typeof (decoded_size) _b = (decoded_size); (_a < _b) ? _a
: _b; }) / sizeof(float)); (_a < _b) ? _a : _b; })
);
494 decoded_size = data_size;
495 }
496 } else {
497 if (!tensor)
498 *tensor_out = tensor = ccv_nnc_tensor_new(0, tensor_params, 0);
499 ccv_float_to_half_precision((float*)data, (uint16_t*)workspace, ccv_min(tensor_count, data_bytes / sizeof(float))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(float)) _b = (data_bytes / sizeof(float)); (_a <
_b) ? _a : _b; })
);
500 decoded_size = data_size;
501 }
502 } else
503 { assert(0)((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail
("0", "ccv_nnc_tensor_io.c", 503, __extension__ __PRETTY_FUNCTION__
); }))
; }
504 }
505 cumemcpy(tensor_out[0]->data.u8, tensor_out[0]->info.type, copying, CCV_TENSOR_CPU_MEMORY, decoded_size);
506 ccfreefree(workspace);
507 } else {
508 if (!options || !options->decode)
509 {
510 if (datatype == CCV_16F && tensor_params.datatype == CCV_32F)
511 ccv_half_precision_to_float((uint16_t*)data, tensor->data.f32, ccv_min(tensor_count, data_bytes / sizeof(uint16_t))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(uint16_t)) _b = (data_bytes / sizeof(uint16_t)); (_a
< _b) ? _a : _b; })
);
512 else if (datatype == CCV_32F && tensor_params.datatype == CCV_16F)
513 ccv_float_to_half_precision((float*)data, (uint16_t*)tensor->data.f16, ccv_min(tensor_count, data_bytes / sizeof(float))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(float)) _b = (data_bytes / sizeof(float)); (_a <
_b) ? _a : _b; })
);
514 else
515 { assert(0)((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail
("0", "ccv_nnc_tensor_io.c", 515, __extension__ __PRETTY_FUNCTION__
); }))
; }
516 } else {
517 void* const workspace = ccmallocmalloc(source_data_size);
518 if (datatype == CCV_16F && tensor_params.datatype == CCV_32F)
519 {
520 size_t decoded_size = source_data_size;
521 if (options->decode(data, data_bytes, datatype, dim, nd, identifier, options->context, tensor_params, tensor_out, workspace, &decoded_size))
522 {
523 if (CCV_GET_DATA_TYPE(tensor_out[0]->info.datatype)((tensor_out[0]->info.datatype) & 0xFF000) == CCV_QX)
524 {
525 if (decoded_size > 0)
526 memcpy(tensor_out[0]->data.f32, workspace, ccv_min(source_data_size, decoded_size)({ typeof (source_data_size) _a = (source_data_size); typeof (
decoded_size) _b = (decoded_size); (_a < _b) ? _a : _b; })
);
527 } else
528 ccv_half_precision_to_float((uint16_t*)workspace, tensor_out[0]->data.f32, ccv_min(tensor_count, ccv_min(source_data_size, decoded_size) / sizeof(uint16_t))({ typeof (tensor_count) _a = (tensor_count); typeof (({ typeof
(source_data_size) _a = (source_data_size); typeof (decoded_size
) _b = (decoded_size); (_a < _b) ? _a : _b; }) / sizeof(uint16_t
)) _b = (({ typeof (source_data_size) _a = (source_data_size)
; typeof (decoded_size) _b = (decoded_size); (_a < _b) ? _a
: _b; }) / sizeof(uint16_t)); (_a < _b) ? _a : _b; })
);
529 } else {
530 if (!tensor)
531 *tensor_out = tensor = ccv_nnc_tensor_new(0, tensor_params, 0);
532 ccv_half_precision_to_float((uint16_t*)data, tensor->data.f32, ccv_min(tensor_count, data_bytes / sizeof(uint16_t))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(uint16_t)) _b = (data_bytes / sizeof(uint16_t)); (_a
< _b) ? _a : _b; })
);
533 }
534 } else if (datatype == CCV_32F && tensor_params.datatype == CCV_16F) {
535 size_t decoded_size = source_data_size;
536 if (options->decode(data, data_bytes, datatype, dim, nd, identifier, options->context, tensor_params, tensor_out, workspace, &decoded_size))
537 {
538 if (CCV_GET_DATA_TYPE(tensor_out[0]->info.datatype)((tensor_out[0]->info.datatype) & 0xFF000) == CCV_QX)
539 {
540 if (decoded_size > 0)
541 memcpy(tensor_out[0]->data.f16, workspace, ccv_min(source_data_size, decoded_size)({ typeof (source_data_size) _a = (source_data_size); typeof (
decoded_size) _b = (decoded_size); (_a < _b) ? _a : _b; })
);
542 } else
543 ccv_float_to_half_precision((float*)workspace, (uint16_t*)tensor_out[0]->data.f16, ccv_min(tensor_count, ccv_min(source_data_size, decoded_size) / sizeof(float))({ typeof (tensor_count) _a = (tensor_count); typeof (({ typeof
(source_data_size) _a = (source_data_size); typeof (decoded_size
) _b = (decoded_size); (_a < _b) ? _a : _b; }) / sizeof(float
)) _b = (({ typeof (source_data_size) _a = (source_data_size)
; typeof (decoded_size) _b = (decoded_size); (_a < _b) ? _a
: _b; }) / sizeof(float)); (_a < _b) ? _a : _b; })
);
544 } else {
545 if (!tensor)
546 *tensor_out = tensor = ccv_nnc_tensor_new(0, tensor_params, 0);
547 ccv_float_to_half_precision((float*)data, (uint16_t*)tensor->data.f16, ccv_min(tensor_count, data_bytes / sizeof(float))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(float)) _b = (data_bytes / sizeof(float)); (_a <
_b) ? _a : _b; })
);
548 }
549 } else
550 { assert(0)((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail
("0", "ccv_nnc_tensor_io.c", 550, __extension__ __PRETTY_FUNCTION__
); }))
; }
551 ccfreefree(workspace);
552 }
553 }
554#elif defined(HAVE_MPS)
555 if (CCV_TENSOR_GET_MEMORY(tensor_params.type)((tensor_params.type) & 0x3) == CCV_TENSOR_GPU_MEMORY)
556 {
557 const size_t data_size = ccv_nnc_tensor_data_size(tensor_params);
558 unsigned char* workspace;
559 unsigned char* copying;
560 size_t decoded_size = data_size;
561 if (!options || !options->decode)
562 {
563 copying = workspace = ccmallocmalloc(data_size);
564 if (datatype == CCV_16F && tensor_params.datatype == CCV_32F)
565 ccv_half_precision_to_float((uint16_t*)data, (float*)workspace, ccv_min(tensor_count, data_bytes / sizeof(uint16_t))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(uint16_t)) _b = (data_bytes / sizeof(uint16_t)); (_a
< _b) ? _a : _b; })
);
566 else if (datatype == CCV_32F && tensor_params.datatype == CCV_16F)
567 ccv_float_to_half_precision((float*)data, (uint16_t*)workspace, ccv_min(tensor_count, data_bytes / sizeof(float))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(float)) _b = (data_bytes / sizeof(float)); (_a <
_b) ? _a : _b; })
);
568 else
569 { assert(0)((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail
("0", "ccv_nnc_tensor_io.c", 569, __extension__ __PRETTY_FUNCTION__
); }))
; }
570 } else {
571 copying = workspace = ccmallocmalloc(data_size + source_data_size);
572 if (datatype == CCV_16F && tensor_params.datatype == CCV_32F)
573 {
574 decoded_size = source_data_size;
575 if (options->decode(data, data_bytes, datatype, dim, nd, identifier, options->context, tensor_params, tensor_out, workspace + data_size, &decoded_size))
576 {
577 if (CCV_GET_DATA_TYPE(tensor_out[0]->info.datatype)((tensor_out[0]->info.datatype) & 0xFF000) == CCV_QX)
578 copying = workspace + data_size;
579 else {
580 ccv_half_precision_to_float((uint16_t*)(workspace + data_size), (float*)workspace, ccv_min(tensor_count, ccv_min(source_data_size, decoded_size) / sizeof(uint16_t))({ typeof (tensor_count) _a = (tensor_count); typeof (({ typeof
(source_data_size) _a = (source_data_size); typeof (decoded_size
) _b = (decoded_size); (_a < _b) ? _a : _b; }) / sizeof(uint16_t
)) _b = (({ typeof (source_data_size) _a = (source_data_size)
; typeof (decoded_size) _b = (decoded_size); (_a < _b) ? _a
: _b; }) / sizeof(uint16_t)); (_a < _b) ? _a : _b; })
);
581 decoded_size = data_size;
582 }
583 } else {
584 if (!tensor)
585 *tensor_out = tensor = ccv_nnc_tensor_new(0, tensor_params, 0);
586 ccv_half_precision_to_float((uint16_t*)data, (float*)workspace, ccv_min(tensor_count, data_bytes / sizeof(uint16_t))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(uint16_t)) _b = (data_bytes / sizeof(uint16_t)); (_a
< _b) ? _a : _b; })
);
587 decoded_size = data_size;
588 }
589 } else if (datatype == CCV_32F && tensor_params.datatype == CCV_16F) {
590 decoded_size = source_data_size;
591 if (options->decode(data, data_bytes, datatype, dim, nd, identifier, options->context, tensor_params, tensor_out, workspace + data_size, &decoded_size))
592 {
593 if (CCV_GET_DATA_TYPE(tensor_out[0]->info.datatype)((tensor_out[0]->info.datatype) & 0xFF000) == CCV_QX)
594 copying = workspace + data_size;
595 else {
596 ccv_float_to_half_precision((float*)(workspace + data_size), (uint16_t*)workspace, ccv_min(tensor_count, ccv_min(source_data_size, decoded_size) / sizeof(float))({ typeof (tensor_count) _a = (tensor_count); typeof (({ typeof
(source_data_size) _a = (source_data_size); typeof (decoded_size
) _b = (decoded_size); (_a < _b) ? _a : _b; }) / sizeof(float
)) _b = (({ typeof (source_data_size) _a = (source_data_size)
; typeof (decoded_size) _b = (decoded_size); (_a < _b) ? _a
: _b; }) / sizeof(float)); (_a < _b) ? _a : _b; })
);
597 decoded_size = data_size;
598 }
599 } else {
600 if (!tensor)
601 *tensor_out = tensor = ccv_nnc_tensor_new(0, tensor_params, 0);
602 ccv_float_to_half_precision((float*)data, (uint16_t*)workspace, ccv_min(tensor_count, data_bytes / sizeof(float))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(float)) _b = (data_bytes / sizeof(float)); (_a <
_b) ? _a : _b; })
);
603 decoded_size = data_size;
604 }
605 } else
606 { assert(0)((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail
("0", "ccv_nnc_tensor_io.c", 606, __extension__ __PRETTY_FUNCTION__
); }))
; }
607 }
608 assert(tensor_out[0]->dataof == 0)((void) sizeof ((tensor_out[0]->dataof == 0) ? 1 : 0), __extension__
({ if (tensor_out[0]->dataof == 0) ; else __assert_fail (
"tensor_out[0]->dataof == 0", "ccv_nnc_tensor_io.c", 608, __extension__
__PRETTY_FUNCTION__); }))
;
609 mpmemcpy(tensor_out[0]->data.u8, tensor_out[0]->dataof, tensor_out[0]->info.type, copying, 0, CCV_TENSOR_CPU_MEMORY, decoded_size);
610 ccfreefree(workspace);
611 } else {
612 if (!options || !options->decode)
613 {
614 if (datatype == CCV_16F && tensor_params.datatype == CCV_32F)
615 ccv_half_precision_to_float((uint16_t*)data, tensor->data.f32, ccv_min(tensor_count, data_bytes / sizeof(uint16_t))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(uint16_t)) _b = (data_bytes / sizeof(uint16_t)); (_a
< _b) ? _a : _b; })
);
616 else if (datatype == CCV_32F && tensor_params.datatype == CCV_16F)
617 ccv_float_to_half_precision((float*)data, (uint16_t*)tensor->data.f16, ccv_min(tensor_count, data_bytes / sizeof(float))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(float)) _b = (data_bytes / sizeof(float)); (_a <
_b) ? _a : _b; })
);
618 else
619 { assert(0)((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail
("0", "ccv_nnc_tensor_io.c", 619, __extension__ __PRETTY_FUNCTION__
); }))
; }
620 } else {
621 void* const workspace = ccmallocmalloc(source_data_size);
622 if (datatype == CCV_16F && tensor_params.datatype == CCV_32F)
623 {
624 size_t decoded_size = source_data_size;
625 if (options->decode(data, data_bytes, datatype, dim, nd, identifier, options->context, tensor_params, tensor_out, workspace, &decoded_size))
626 {
627 if (CCV_GET_DATA_TYPE(tensor_out[0]->info.datatype)((tensor_out[0]->info.datatype) & 0xFF000) == CCV_QX)
628 {
629 if (decoded_size > 0)
630 memcpy(tensor_out[0]->data.f32, workspace, ccv_min(source_data_size, decoded_size)({ typeof (source_data_size) _a = (source_data_size); typeof (
decoded_size) _b = (decoded_size); (_a < _b) ? _a : _b; })
);
631 } else
632 ccv_half_precision_to_float((uint16_t*)workspace, tensor_out[0]->data.f32, ccv_min(tensor_count, ccv_min(source_data_size, decoded_size) / sizeof(uint16_t))({ typeof (tensor_count) _a = (tensor_count); typeof (({ typeof
(source_data_size) _a = (source_data_size); typeof (decoded_size
) _b = (decoded_size); (_a < _b) ? _a : _b; }) / sizeof(uint16_t
)) _b = (({ typeof (source_data_size) _a = (source_data_size)
; typeof (decoded_size) _b = (decoded_size); (_a < _b) ? _a
: _b; }) / sizeof(uint16_t)); (_a < _b) ? _a : _b; })
);
633 } else {
634 if (!tensor)
635 *tensor_out = tensor = ccv_nnc_tensor_new(0, tensor_params, 0);
636 ccv_half_precision_to_float((uint16_t*)data, tensor->data.f32, ccv_min(tensor_count, data_bytes / sizeof(uint16_t))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(uint16_t)) _b = (data_bytes / sizeof(uint16_t)); (_a
< _b) ? _a : _b; })
);
637 }
638 } else if (datatype == CCV_32F && tensor_params.datatype == CCV_16F) {
639 size_t decoded_size = source_data_size;
640 if (options->decode(data, data_bytes, datatype, dim, nd, identifier, options->context, tensor_params, tensor_out, workspace, &decoded_size))
641 {
642 if (CCV_GET_DATA_TYPE(tensor_out[0]->info.datatype)((tensor_out[0]->info.datatype) & 0xFF000) == CCV_QX)
643 {
644 if (decoded_size > 0)
645 memcpy(tensor_out[0]->data.f16, workspace, ccv_min(source_data_size, decoded_size)({ typeof (source_data_size) _a = (source_data_size); typeof (
decoded_size) _b = (decoded_size); (_a < _b) ? _a : _b; })
);
646 } else
647 ccv_float_to_half_precision((float*)workspace, (uint16_t*)tensor_out[0]->data.f16, ccv_min(tensor_count, ccv_min(source_data_size, decoded_size) / sizeof(float))({ typeof (tensor_count) _a = (tensor_count); typeof (({ typeof
(source_data_size) _a = (source_data_size); typeof (decoded_size
) _b = (decoded_size); (_a < _b) ? _a : _b; }) / sizeof(float
)) _b = (({ typeof (source_data_size) _a = (source_data_size)
; typeof (decoded_size) _b = (decoded_size); (_a < _b) ? _a
: _b; }) / sizeof(float)); (_a < _b) ? _a : _b; })
);
648 } else {
649 if (!tensor)
650 *tensor_out = tensor = ccv_nnc_tensor_new(0, tensor_params, 0);
651 ccv_float_to_half_precision((float*)data, (uint16_t*)tensor->data.f16, ccv_min(tensor_count, data_bytes / sizeof(float))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(float)) _b = (data_bytes / sizeof(float)); (_a <
_b) ? _a : _b; })
);
652 }
653 } else
654 { assert(0)((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail
("0", "ccv_nnc_tensor_io.c", 654, __extension__ __PRETTY_FUNCTION__
); }))
; }
655 ccfreefree(workspace);
656 }
657 }
658#else
659 if (!options || !options->decode)
660 {
661 if (datatype == CCV_16F && tensor_params.datatype == CCV_32F)
662 ccv_half_precision_to_float((uint16_t*)data, tensor->data.f32, ccv_min(tensor_count, data_bytes / sizeof(uint16_t))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(uint16_t)) _b = (data_bytes / sizeof(uint16_t)); (_a
< _b) ? _a : _b; })
);
663 else if (datatype == CCV_32F && tensor_params.datatype == CCV_16F)
664 ccv_float_to_half_precision((float*)data, (uint16_t*)tensor->data.f16, ccv_min(tensor_count, data_bytes / sizeof(float))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(float)) _b = (data_bytes / sizeof(float)); (_a <
_b) ? _a : _b; })
);
665 else
666 { assert(0)((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail
("0", "ccv_nnc_tensor_io.c", 666, __extension__ __PRETTY_FUNCTION__
); }))
; }
667 } else {
668 void* const workspace = ccmallocmalloc(source_data_size);
669 if (datatype == CCV_16F && tensor_params.datatype == CCV_32F)
670 {
671 size_t decoded_size = source_data_size;
672 if (options->decode(data, data_bytes, datatype, dim, nd, identifier, options->context, tensor_params, tensor_out, workspace, &decoded_size))
673 {
674 if (CCV_GET_DATA_TYPE(tensor_out[0]->info.datatype)((tensor_out[0]->info.datatype) & 0xFF000) == CCV_QX)
675 {
676 if (decoded_size > 0)
677 memcpy(tensor_out[0]->data.f32, workspace, ccv_min(source_data_size, decoded_size)({ typeof (source_data_size) _a = (source_data_size); typeof (
decoded_size) _b = (decoded_size); (_a < _b) ? _a : _b; })
);
678 } else
679 ccv_half_precision_to_float((uint16_t*)workspace, tensor_out[0]->data.f32, ccv_min(tensor_count, ccv_min(source_data_size, decoded_size) / sizeof(uint16_t))({ typeof (tensor_count) _a = (tensor_count); typeof (({ typeof
(source_data_size) _a = (source_data_size); typeof (decoded_size
) _b = (decoded_size); (_a < _b) ? _a : _b; }) / sizeof(uint16_t
)) _b = (({ typeof (source_data_size) _a = (source_data_size)
; typeof (decoded_size) _b = (decoded_size); (_a < _b) ? _a
: _b; }) / sizeof(uint16_t)); (_a < _b) ? _a : _b; })
);
680 } else {
681 if (!tensor)
682 *tensor_out = tensor = ccv_nnc_tensor_new(0, tensor_params, 0);
683 ccv_half_precision_to_float((uint16_t*)data, tensor->data.f32, ccv_min(tensor_count, data_bytes / sizeof(uint16_t))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(uint16_t)) _b = (data_bytes / sizeof(uint16_t)); (_a
< _b) ? _a : _b; })
);
684 }
685 } else if (datatype == CCV_32F && tensor_params.datatype == CCV_16F) {
686 size_t decoded_size = source_data_size;
687 if (options->decode(data, data_bytes, datatype, dim, nd, identifier, options->context, tensor_params, tensor_out, workspace, &decoded_size))
688 {
689 if (CCV_GET_DATA_TYPE(tensor_out[0]->info.datatype)((tensor_out[0]->info.datatype) & 0xFF000) == CCV_QX)
690 {
691 if (decoded_size > 0)
692 memcpy(tensor_out[0]->data.f16, workspace, ccv_min(source_data_size, decoded_size)({ typeof (source_data_size) _a = (source_data_size); typeof (
decoded_size) _b = (decoded_size); (_a < _b) ? _a : _b; })
);
693 } else
694 ccv_float_to_half_precision((float*)workspace, (uint16_t*)tensor_out[0]->data.f16, ccv_min(tensor_count, ccv_min(source_data_size, decoded_size) / sizeof(float))({ typeof (tensor_count) _a = (tensor_count); typeof (({ typeof
(source_data_size) _a = (source_data_size); typeof (decoded_size
) _b = (decoded_size); (_a < _b) ? _a : _b; }) / sizeof(float
)) _b = (({ typeof (source_data_size) _a = (source_data_size)
; typeof (decoded_size) _b = (decoded_size); (_a < _b) ? _a
: _b; }) / sizeof(float)); (_a < _b) ? _a : _b; })
);
695 } else {
696 if (!tensor)
697 *tensor_out = tensor = ccv_nnc_tensor_new(0, tensor_params, 0);
698 ccv_float_to_half_precision((float*)data, (uint16_t*)tensor->data.f16, ccv_min(tensor_count, data_bytes / sizeof(float))({ typeof (tensor_count) _a = (tensor_count); typeof (data_bytes
/ sizeof(float)) _b = (data_bytes / sizeof(float)); (_a <
_b) ? _a : _b; })
);
699 }
700 } else
701 { assert(0)((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail
("0", "ccv_nnc_tensor_io.c", 701, __extension__ __PRETTY_FUNCTION__
); }))
; }
702 ccfreefree(workspace);
703 }
704#endif
705 } else {
706 // If it is QX, we need to have a custom decoder to decode properly.
707 if (datatype != tensor_params.datatype)
708 { assert(options && options->decode)((void) sizeof ((options && options->decode) ? 1 :
0), __extension__ ({ if (options && options->decode
) ; else __assert_fail ("options && options->decode"
, "ccv_nnc_tensor_io.c", 708, __extension__ __PRETTY_FUNCTION__
); }))
; }
709 size_t data_size = ccv_nnc_tensor_data_size(tensor_params);
710#ifdef HAVE_CUDA1
711 if (!options || !options->decode)
712 {
713 if (CCV_TENSOR_GET_MEMORY(tensor_params.type)((tensor_params.type) & 0x3) == CCV_TENSOR_GPU_MEMORY)
714 cumemcpy(tensor->data.u8, tensor->info.type, data, CCV_TENSOR_CPU_MEMORY, ccv_min(data_size, data_bytes)({ typeof (data_size) _a = (data_size); typeof (data_bytes) _b
= (data_bytes); (_a < _b) ? _a : _b; })
);
715 else
716 memcpy(tensor->data.u8, data, ccv_min(data_size, data_bytes)({ typeof (data_size) _a = (data_size); typeof (data_bytes) _b
= (data_bytes); (_a < _b) ? _a : _b; })
);
717 } else {
718 if (CCV_TENSOR_GET_MEMORY(tensor_params.type)((tensor_params.type) & 0x3) == CCV_TENSOR_GPU_MEMORY)
719 {
720 void* const workspace = ccmallocmalloc(data_size);
721 size_t decoded_size = data_size;
722 if (options->decode(data, data_bytes, datatype, dim, nd, identifier, options->context, tensor_params, tensor_out, workspace, &decoded_size))
723 cumemcpy(tensor_out[0]->data.u8, tensor_out[0]->info.type, workspace, CCV_TENSOR_CPU_MEMORY, ccv_min(data_size, decoded_size)({ typeof (data_size) _a = (data_size); typeof (decoded_size)
_b = (decoded_size); (_a < _b) ? _a : _b; })
);
724 else {
725 if (!tensor)
726 *tensor_out = tensor = ccv_nnc_tensor_new(0, tensor_params, 0);
727 cumemcpy(tensor->data.u8, tensor->info.type, data, CCV_TENSOR_CPU_MEMORY, ccv_min(data_size, data_bytes)({ typeof (data_size) _a = (data_size); typeof (data_bytes) _b
= (data_bytes); (_a < _b) ? _a : _b; })
);
728 }
729 ccfreefree(workspace);
730 } else {
731 size_t decoded_size = data_size;
732 if (!options->decode(data, data_bytes, datatype, dim, nd, identifier, options->context, tensor_params, tensor_out, tensor ? tensor->data.u8 : 0, &decoded_size))
733 {
734 if (!tensor)
735 *tensor_out = tensor = ccv_nnc_tensor_new(0, tensor_params, 0);
736 memcpy(tensor->data.u8, data, ccv_min(data_size, data_bytes)({ typeof (data_size) _a = (data_size); typeof (data_bytes) _b
= (data_bytes); (_a < _b) ? _a : _b; })
);
737 }
738 }
739 }
740#elif defined(HAVE_MPS)
741 if (!options || !options->decode)
742 {
743 if (CCV_TENSOR_GET_MEMORY(tensor_params.type)((tensor_params.type) & 0x3) == CCV_TENSOR_GPU_MEMORY)
744 {
745 assert(tensor->dataof == 0)((void) sizeof ((tensor->dataof == 0) ? 1 : 0), __extension__
({ if (tensor->dataof == 0) ; else __assert_fail ("tensor->dataof == 0"
, "ccv_nnc_tensor_io.c", 745, __extension__ __PRETTY_FUNCTION__
); }))
;
746 mpmemcpy(tensor->data.u8, tensor->dataof, tensor->info.type, data, 0, CCV_TENSOR_CPU_MEMORY, ccv_min(data_size, data_bytes)({ typeof (data_size) _a = (data_size); typeof (data_bytes) _b
= (data_bytes); (_a < _b) ? _a : _b; })
);
747 } else
748 memcpy(tensor->data.u8, data, ccv_min(data_size, data_bytes)({ typeof (data_size) _a = (data_size); typeof (data_bytes) _b
= (data_bytes); (_a < _b) ? _a : _b; })
);
749 } else {
750 if (CCV_TENSOR_GET_MEMORY(tensor_params.type)((tensor_params.type) & 0x3) == CCV_TENSOR_GPU_MEMORY)
751 {
752 if (tensor)
753 { assert(tensor->dataof == 0)((void) sizeof ((tensor->dataof == 0) ? 1 : 0), __extension__
({ if (tensor->dataof == 0) ; else __assert_fail ("tensor->dataof == 0"
, "ccv_nnc_tensor_io.c", 753, __extension__ __PRETTY_FUNCTION__
); }))
; }
754 void* const workspace = ccmallocmalloc(data_size);
755 size_t decoded_size = data_size;
756 if (options->decode(data, data_bytes, datatype, dim, nd, identifier, options->context, tensor_params, tensor_out, workspace, &decoded_size)) {
757 mpmemcpy(tensor_out[0]->data.u8, tensor_out[0]->dataof, tensor_out[0]->info.type, workspace, 0, CCV_TENSOR_CPU_MEMORY, ccv_min(data_size, decoded_size)({ typeof (data_size) _a = (data_size); typeof (decoded_size)
_b = (decoded_size); (_a < _b) ? _a : _b; })
);
758 } else {
759 if (!tensor)
760 *tensor_out = tensor = ccv_nnc_tensor_new(0, tensor_params, 0);
761 mpmemcpy(tensor->data.u8, tensor->dataof, tensor->info.type, data, 0, CCV_TENSOR_CPU_MEMORY, ccv_min(data_size, data_bytes)({ typeof (data_size) _a = (data_size); typeof (data_bytes) _b
= (data_bytes); (_a < _b) ? _a : _b; })
);
762 }
763 ccfreefree(workspace);
764 } else {
765 size_t decoded_size = data_size;
766 if (!options->decode(data, data_bytes, datatype, dim, nd, identifier, options->context, tensor_params, tensor_out, tensor ? tensor->data.u8 : 0, &decoded_size))
767 {
768 if (!tensor)
769 *tensor_out = tensor = ccv_nnc_tensor_new(0, tensor_params, 0);
770 memcpy(tensor->data.u8, data, ccv_min(data_size, data_bytes)({ typeof (data_size) _a = (data_size); typeof (data_bytes) _b
= (data_bytes); (_a < _b) ? _a : _b; })
);
771 }
772 }
773 }
774#else
775 if (!options || !options->decode)
776 memcpy(tensor->data.u8, data, ccv_min(data_size, data_bytes)({ typeof (data_size) _a = (data_size); typeof (data_bytes) _b
= (data_bytes); (_a < _b) ? _a : _b; })
);
777 else {
778 size_t decoded_size = data_size;
779 if (!options->decode(data, data_bytes, datatype, dim, nd, identifier, options->context, tensor_params, tensor_out, tensor ? tensor->data.u8 : 0, &decoded_size))
780 {
781 if (!tensor)
782 *tensor_out = tensor = ccv_nnc_tensor_new(0, tensor_params, 0);
783 memcpy(tensor->data.u8, data, ccv_min(data_size, data_bytes)({ typeof (data_size) _a = (data_size); typeof (data_bytes) _b
= (data_bytes); (_a < _b) ? _a : _b; })
);
784 }
785 }
786#endif
787 }
788 tensor_out[0]->type &= ~CCV_GARBAGE; // If it is marked as garbage, remove that mark now.
789 sqlite3_reset(tensor_select_stmt);
790 sqlite3_clear_bindings(tensor_select_stmt);
791 sqlite3_finalize(tensor_select_stmt);
792 if (split_workspace)
793 ccfreefree(split_workspace);
794 return CCV_IO_FINAL;
795}