| 2423 | } |
| 2424 | |
| 2425 | static struct ggml_tensor * ggml_new_tensor_impl( |
| 2426 | struct ggml_context * ctx, |
| 2427 | enum ggml_type type, |
| 2428 | int n_dims, |
| 2429 | const int64_t * ne, |
| 2430 | struct ggml_tensor * view_src, |
| 2431 | size_t view_offs) { |
| 2432 | |
| 2433 | assert(n_dims >= 1 && n_dims <= GGML_MAX_DIMS); |
| 2434 | |
| 2435 | // find the base tensor and absolute offset |
| 2436 | if (view_src != NULL && view_src->view_src != NULL) { |
| 2437 | view_offs += view_src->view_offs; |
| 2438 | view_src = view_src->view_src; |
| 2439 | } |
| 2440 | |
| 2441 | size_t data_size = ggml_type_size(type)*(ne[0]/ggml_blck_size(type)); |
| 2442 | for (int i = 1; i < n_dims; i++) { |
| 2443 | data_size *= ne[i]; |
| 2444 | } |
| 2445 | |
| 2446 | GGML_ASSERT(view_src == NULL || data_size + view_offs <= ggml_nbytes(view_src)); |
| 2447 | |
| 2448 | void * data = view_src != NULL ? view_src->data : NULL; |
| 2449 | if (data != NULL) { |
| 2450 | data = (char *) data + view_offs; |
| 2451 | } |
| 2452 | |
| 2453 | size_t obj_alloc_size = 0; |
| 2454 | |
| 2455 | if (view_src == NULL && !ctx->no_alloc) { |
| 2456 | if (ctx->scratch.data != NULL) { |
| 2457 | // allocate tensor data in the scratch buffer |
| 2458 | if (ctx->scratch.offs + data_size > ctx->scratch.size) { |
| 2459 | GGML_PRINT("%s: not enough space in the scratch memory pool (needed %zu, available %zu)\n", |
| 2460 | __func__, ctx->scratch.offs + data_size, ctx->scratch.size); |
| 2461 | assert(false); |
| 2462 | return NULL; |
| 2463 | } |
| 2464 | |
| 2465 | data = (char * const) ctx->scratch.data + ctx->scratch.offs; |
| 2466 | |
| 2467 | ctx->scratch.offs += data_size; |
| 2468 | } else { |
| 2469 | // allocate tensor data in the context's memory pool |
| 2470 | obj_alloc_size = data_size; |
| 2471 | } |
| 2472 | } |
| 2473 | |
| 2474 | struct ggml_object * const obj_new = ggml_new_object(ctx, GGML_OBJECT_TENSOR, GGML_TENSOR_SIZE + obj_alloc_size); |
| 2475 | |
| 2476 | // TODO: for recoverable errors, we would need to free the data allocated from the scratch buffer here |
| 2477 | |
| 2478 | struct ggml_tensor * const result = (struct ggml_tensor *)((char *)ctx->mem_buffer + obj_new->offs); |
| 2479 | |
| 2480 | *result = (struct ggml_tensor) { |
| 2481 | /*.type =*/ type, |
| 2482 | /*.backend =*/ GGML_BACKEND_CPU, |
no test coverage detected