///|
fn backward_node(ctx : AutogradContext, id : Int, grad : Array[Double]) -> Unit {
let node = ctx.state.val.tape[id]
let input_grads = node.op.backward(grad, node.shape, node.inputs)
for input_grad in input_grads {
if input_grad.slot < 0 || input_grad.slot >= node.inputs.length() {
abort("backward op returned an invalid input slot")
}
let input = node.inputs[input_grad.slot]
if input_grad.data.length() != shape_size(input.shape) {
abort("backward op returned a gradient with the wrong shape")
}
match input.target {
Some(target) => ctx.add_grad(target, input_grad.data)
None => ()
}
}
}