Hi again 
Is this what you suggest?
def func1(x,E,L):
    F = torch.multiply(torch.sigmoid(E[:,0]),L)
    return torch.matmul(x[:,:,:,0], F)

def func2(x,E,L):
    return torch.einsum('btrc,ri,ic->btic',x,L,torch.sigmoid(E))

torch.autograd.gradcheck(func1,(x0,E,L))

torch.autograd.gradcheck(func2,(x0,E,L))

I have changed the precisions to double for everything, and it seems that at least according to the standard settings, both versions have the correct gradients. I have also tried to change atol and rtol, but can not seem to find values where one fails but not the other.
This is a bit annoying. both because I adore the idea of einsum (my background is in physics), and because it gives a very nice way of generalizing my code beyond nChan=1.
it seems that for now, I should just stay away from einsum?