Haha, thanks both! I ended up going down a very similar line to what you’ve just described, so here’s my entry to the competition:
class _AssignInAVerySafeManner(torch.autograd.Function):
    @staticmethod
    def forward(ctx, scratch, value, index):
        ctx.index = index
        scratch.data[index] = value
        return scratch

    @staticmethod
    def backward(ctx, grad_scratch):
        return grad_scratch, grad_scratch[ctx.index], None


a = torch.rand(1, requires_grad=True)
b = torch.rand(2, requires_grad=True)
c = torch.rand(3, requires_grad=True)
x = torch.rand((), requires_grad=True)
y = torch.empty(4)

y = _AssignInAVerySafeManner.apply(y, x, 0)
for i, letter in zip((1, 2, 3), (a, b, c)):
    y_ = y[:i].dot(letter)
    y = _AssignInAVerySafeManner.apply(y, y_, i)
y.sum().backward()

This does use the to-be-deprecated .data. though. Do you have any idea roughly when that’s likely to disappear?