| 7318 | } |
| 7319 | GGML_ASSERT(node->src[j]->type == GGML_TYPE_F32 || node->src[j]->type == GGML_TYPE_F16); |
| 7320 | node_needs_grad = true; |
| 7321 | break; |
| 7322 | } |
| 7323 | if (!node_needs_grad) { |
| 7324 | continue; |
| 7325 | } |
| 7326 | |
| 7327 | // inplace operations are currently not supported |
| 7328 | GGML_ASSERT(!node->view_src || node->op == GGML_OP_CPY || node->op == GGML_OP_VIEW || |
| 7329 | node->op == GGML_OP_RESHAPE || node->op == GGML_OP_PERMUTE || node->op == GGML_OP_TRANSPOSE); |
| 7330 | |
| 7331 | const size_t ihash = ggml_hash_find(&cgraph->visited_hash_set, node); |
| 7332 | GGML_ASSERT(ihash != GGML_HASHSET_FULL); |
| 7333 | GGML_ASSERT(ggml_bitset_get(cgraph->visited_hash_set.used, ihash)); |
| 7334 | if (grad_accs && grad_accs[i]) { |
| 7335 | cgraph->grad_accs[ihash] = grad_accs[i]; |
| 7336 | cgraph->grads[ihash] = cgraph->grad_accs[ihash]; |
| 7337 | } else if (node->flags & GGML_TENSOR_FLAG_LOSS) { |
| 7338 | // loss tensors always need a gradient accumulator |
| 7339 | cgraph->grad_accs[ihash] = ggml_new_tensor(ctx, GGML_TYPE_F32, GGML_MAX_DIMS, node->ne); |
| 7340 | cgraph->grads[ihash] = cgraph->grad_accs[ihash]; |
| 7341 | } |
| 7342 | grads_needed[ihash] = true; |
| 7343 | } |
| 7344 | |
| 7345 | for (int i = n_nodes_f - 1; i >= 0; --i) { |
| 7346 | // inplace operations to add gradients are not created by ggml_compute_backward except for gradient accumulation |
| 7347 | // use allocator to automatically make inplace operations |
| 7348 | ggml_compute_backward(ctx, cgraph, i, grads_needed); |
| 7349 | } |
| 7350 | |
| 7351 | free(grads_needed); |
| 7352 | } |
| 7353 | |
| 7354 | static void * incr_ptr_aligned(void ** p, size_t size, size_t align) { |
| 7355 | void * ptr = *p; |
| 7356 | ptr = (void *) GGML_PAD((uintptr_t) ptr, align); |
| 7357 | *p = (void *) ((char *) ptr + size); |
| 7358 | return ptr; |
| 7359 | } |
| 7360 | |
| 7361 | static size_t ggml_graph_nbytes(size_t size, bool grads) { |
| 7362 | size_t hash_size = ggml_hash_size(size * 2); |
| 7363 | void * p = 0; |
| 7364 | incr_ptr_aligned(&p, sizeof(struct ggml_cgraph), 1); |
| 7365 | incr_ptr_aligned(&p, size * sizeof(struct ggml_tensor *), sizeof(struct ggml_tensor *)); // nodes |
| 7366 | incr_ptr_aligned(&p, size * sizeof(struct ggml_tensor *), sizeof(struct ggml_tensor *)); // leafs |
| 7367 | incr_ptr_aligned(&p, hash_size * sizeof(int32_t), sizeof(int32_t)); // use_counts |
| 7368 | incr_ptr_aligned(&p, hash_size * sizeof(struct ggml_tensor *), sizeof(struct ggml_tensor *)); // hash keys |