| 2066 | } |
| 2067 | |
| 2068 | struct ggml_backend_graph_copy ggml_backend_graph_copy(ggml_backend_t backend, struct ggml_cgraph * graph) { |
| 2069 | GGML_ASSERT(graph); |
| 2070 | struct ggml_hash_set hash_set = ggml_hash_set_new(graph->visited_hash_set.size); |
| 2071 | struct ggml_tensor ** node_copies = (ggml_tensor **) calloc(hash_set.size, sizeof(node_copies[0])); // NOLINT |
| 2072 | bool * node_init = (bool *) calloc(hash_set.size, sizeof(node_init[0])); |
| 2073 | |
| 2074 | struct ggml_init_params params = { |
| 2075 | /* .mem_size = */ ggml_tensor_overhead()*hash_set.size + ggml_graph_overhead_custom(graph->size, false), |
| 2076 | /* .mem_buffer = */ NULL, |
| 2077 | /* .no_alloc = */ true |
| 2078 | }; |
| 2079 | |
| 2080 | struct ggml_context * ctx_allocated = ggml_init(params); |
| 2081 | struct ggml_context * ctx_unallocated = ggml_init(params); |
| 2082 | |
| 2083 | if (ctx_allocated == NULL || ctx_unallocated == NULL) { |
| 2084 | GGML_LOG_ERROR("%s: failed to allocate context for graph copy\n", __func__); |
| 2085 | ggml_hash_set_free(&hash_set); |
| 2086 | free(node_copies); |
| 2087 | free(node_init); |
| 2088 | ggml_free(ctx_allocated); |
| 2089 | ggml_free(ctx_unallocated); |
| 2090 | return { |
| 2091 | /* .buffer = */ NULL, |
| 2092 | /* .ctx_allocated = */ NULL, |
| 2093 | /* .ctx_unallocated = */ NULL, |
| 2094 | /* .graph = */ NULL, |
| 2095 | }; |
| 2096 | } |
| 2097 | |
| 2098 | // dup nodes |
| 2099 | for (int i = 0; i < graph->n_nodes; i++) { |
| 2100 | struct ggml_tensor * node = graph->nodes[i]; |
| 2101 | graph_copy_dup_tensor(hash_set, node_copies, ctx_allocated, ctx_unallocated, node); |
| 2102 | } |
| 2103 | |
| 2104 | // allocate nodes |
| 2105 | ggml_backend_buffer_t buffer = ggml_backend_alloc_ctx_tensors(ctx_allocated, backend); |
| 2106 | if (buffer == NULL) { |
| 2107 | GGML_LOG_ERROR("%s: failed to allocate buffer for graph copy\n", __func__); |
| 2108 | ggml_hash_set_free(&hash_set); |
| 2109 | free(node_copies); |
| 2110 | free(node_init); |
| 2111 | ggml_free(ctx_allocated); |
| 2112 | ggml_free(ctx_unallocated); |
| 2113 | return { |
| 2114 | /* .buffer = */ NULL, |
| 2115 | /* .ctx_allocated = */ NULL, |
| 2116 | /* .ctx_unallocated = */ NULL, |
| 2117 | /* .graph = */ NULL, |
| 2118 | }; |
| 2119 | } |
| 2120 | |
| 2121 | //printf("copy buffer size: %zu MB\n", ggml_backend_buffer_get_size(buffer) / 1024 / 1024); |
| 2122 | |
| 2123 | // copy data and init views |
| 2124 | for (int i = 0; i < graph->n_nodes; i++) { |
| 2125 | struct ggml_tensor * node = graph->nodes[i]; |
no test coverage detected