///|
impl BackwardOp for AddBackward with fn backward(_self, grad, out_shape, inputs) {
  [
    { slot: 0, data: reduce_to_shape(grad, out_shape, inputs[0].shape) },
    { slot: 1, data: reduce_to_shape(grad, out_shape, inputs[1].shape) },
  ]
}

///|
impl BackwardOp for SubBackward with fn backward(_self, grad, out_shape, inputs) {
  [
    { slot: 0, data: reduce_to_shape(grad, out_shape, inputs[0].shape) },
    {
      slot: 1,
      data: reduce_to_shape(grad, out_shape, inputs[1].shape).map(x => -x),
    },
  ]
}

///|
impl BackwardOp for MulBackward with fn backward(self, grad, out_shape, inputs) {
  let lhs_shape = inputs[0].shape
  let rhs_shape = inputs[1].shape
  let lhs_grad = Array::make(shape_size(out_shape), 0.0)
  let rhs_grad = Array::make(shape_size(out_shape), 0.0)
  for i in 0.. -x), out_shape, inputs[0].shape),
    },
  ]
}

///|
impl BackwardOp for ExpBackward with fn backward(self, grad, out_shape, inputs) {
  let g = Array::make(grad.length(), 0.0)
  for i in 0.. 0.0 { grad[i] } else { 0.0 }
  }
  [{ slot: 0, data: reduce_to_shape(g, out_shape, inputs[0].shape) }]
}

///|
impl BackwardOp for GeluBackward with fn backward(self, grad, out_shape, inputs) {
  let g = Array::make(grad.length(), 0.0)
  for i in 0..