Torch::cholesky ignoring exception

I’m having for some matrices on my batch exception due singular matrices.

cholesky_cpu: For batch 51100: U(22,22) is zero, singular U

I would like to ignore the exception for those and further set as Nan is it possible somehow?

Actually if I catch the exception and use continue still it doesn’t finish the calculations of the other matrices.

Could you post the code you are using to catch the exception?

Thanks @ptrblck here is the code

        th::Tensor L;
        try {
            L = th::cholesky(Xt.bmm(Xbtc));
        }
        catch (const std::exception & ex) {
            std::cout << "c++ exception: " << std::endl;
        }
        std::cout << L << std::endl;
        auto Gi = th::cholesky_solve(th::eye(p + 3, dtype_option.device(deviceifGPU)), L); // (X ^ T.X) ^ -1

It prints:

c++ exception:
[ Tensor (undefined) ]

Thanks for the code.
It seems you want to ignore this single sample in the calculation.
I’m not sure, but I would assume that removing this sample from the batch and call cholesky again on the cleaned batch of matrices might work.

Thank you!
Unfortunantly I would loose my peformance gain if I had to analyse which samples fail and remove those specifically. There might be more than one.

I am running this here

I really would like to run the cholesky ignoring those and dealing with nans or infs after.
Is it possible somehow?

I guess there is no way then. I think I will try tensorflow then… But thanks @ptrblck

Sure! Feel free to let us know, how you solved your use case in the end. :slight_smile:

1 Like

Just to let everybody know that’s how I solved.

The solution, unfortunately, was to implement my own simple batched cholesky ( th.cholesky(..., upper=False) ) and then deal with Nan values using th.isnan .

import torch as th

# nograd cholesky
def cholesky(A):
    L = th.zeros_like(A)

    for i in range(A.shape[-1]):
        for j in range(i+1):
            s = 0.0
            for k in range(j):
                s = s + L[...,i,k] * L[...,j,k]

            L[...,i,j] = th.sqrt(A[...,i,i] - s) if (i == j) else \
                      (1.0 / L[...,j,j] * (A[...,i,j] - s))
    return L

Using this code on here I also implemented this on C++ Libtorch and worked flawless.