| 291 | } |
| 292 | |
| 293 | static ggml_cgraph * dup_graph(ggml_context * ctx, ggml_cgraph * src) { |
| 294 | std::map<ggml_tensor *, ggml_tensor *> tensor_map; |
| 295 | |
| 296 | ggml_cgraph * dst = ggml_new_graph_custom(ctx, src->size, /*grads =*/ true); |
| 297 | |
| 298 | for (int i = 0; i < src->n_leafs; i++) { |
| 299 | ggml_build_forward_expand(dst, map_tensor(tensor_map, ctx, src->leafs[i])); |
| 300 | } |
| 301 | GGML_ASSERT(dst->n_leafs == src->n_leafs); |
| 302 | for (int i = 0; i < src->n_nodes; i++) { |
| 303 | ggml_build_forward_expand(dst, map_tensor(tensor_map, ctx, src->nodes[i])); |
| 304 | } |
| 305 | GGML_ASSERT(dst->n_nodes == src->n_nodes); |
| 306 | for (int i = 0; i < src->n_nodes; ++i) { |
| 307 | const size_t igrad_src = ggml_hash_find(&src->visited_hash_set, src->nodes[i]); |
| 308 | const size_t igrad_dst = ggml_hash_find(&dst->visited_hash_set, dst->nodes[i]); |
| 309 | |
| 310 | GGML_ASSERT(igrad_src != GGML_HASHSET_FULL); |
| 311 | GGML_ASSERT(ggml_bitset_get(src->visited_hash_set.used, igrad_src)); |
| 312 | GGML_ASSERT(igrad_dst != GGML_HASHSET_FULL); |
| 313 | GGML_ASSERT(ggml_bitset_get(dst->visited_hash_set.used, igrad_dst)); |
| 314 | |
| 315 | dst->grads[igrad_dst] = src->grads[igrad_src]; |
| 316 | dst->grad_accs[igrad_dst] = src->grad_accs[igrad_src]; |
| 317 | } |
| 318 | |
| 319 | return dst; |
| 320 | } |
| 321 | |
| 322 | static void ggml_opt_build(ggml_opt_context_t opt_ctx) { |
| 323 | GGML_ASSERT(opt_ctx->ctx_compute && "no compute context set, either use static graphs or set one with ggml_opt_prepare_alloc"); |
no test coverage detected