I just encountered the same problem and wanted to share my approach.
def fun3(N, c, device):
    exponents = torch.triu(torch.ones(N, N, device=device), 1).cumsum(-1)
    power = torch.float_power(c, exponents)
    power_mask = torch.tril(torch.ones(N, N, dtype=torch.bool, device=device), diagonal=-1)
    result = power.masked_fill(power_mask, 0)
    return result

Avoiding the for-loops seems to be a little bit more performant (tested with GPU):

If anyone wants to replicate my results, you’ll have to adjust the correctness check a little:
assert torch.isclose(fun2(N, c, device).double(), fun3(N, c, device)).all()