 
 namespace chainerx {
 namespace cuda {
+namespace {
+
+template <typename T>
+cusolverStatus_t PotrfBuffersize(cusolverDnHandle_t /*handle*/, cublasFillMode_t /*uplo*/, int /*n*/, T* /*a*/, int /*lda*/, int* /*lwork*/) {
+    throw DtypeError{"Only Arrays of float or double type are supported by potrf (Cholesky)"};
+}
+
+template <typename T>
+cusolverStatus_t Potrf(cusolverDnHandle_t /*handle*/, cublasFillMode_t /*uplo*/, int /*n*/, T* /*a*/, int /*lda*/, T* /*workspace*/, int /*lwork*/, int* /*devinfo*/) {
+    throw DtypeError{"Only Arrays of float or double type are supported by potrf (Cholesky)"};
+}
+
+template <>
+cusolverStatus_t PotrfBuffersize<double>(cusolverDnHandle_t handle, cublasFillMode_t uplo, int n, double* a, int lda, int* lwork) {
+    return cusolverDnDpotrf_bufferSize(handle, uplo, n, a, lda, lwork);
+}
+
+template <>
+cusolverStatus_t PotrfBuffersize<float>(cusolverDnHandle_t handle, cublasFillMode_t uplo, int n, float* a, int lda, int* lwork) {
+    return cusolverDnSpotrf_bufferSize(handle, uplo, n, a, lda, lwork);
+}
+
+template <>
+cusolverStatus_t Potrf<double>(cusolverDnHandle_t handle, cublasFillMode_t uplo, int n, double* a, int lda, double* workspace, int lwork, int* devinfo) {
+    return cusolverDnDpotrf(handle, uplo, n, a, lda, workspace, lwork, devinfo);
+}
+
+template <>
+cusolverStatus_t Potrf<float>(cusolverDnHandle_t handle, cublasFillMode_t uplo, int n, float* a, int lda, float* workspace, int lwork, int* devinfo) {
+    return cusolverDnSpotrf(handle, uplo, n, a, lda, workspace, lwork, devinfo);
+}
+
+}  // namespace
 
 class CudaCholeskyKernel : public CholeskyKernel {
 public:


        Array out_contiguous = AsContiguous(out);

        auto cholesky_impl = [&](auto pt, auto bufsize_func, auto solver_func) {
            CHAINERX_ASSERT(a.dtype() == out_contiguous.dtype());

            using T = typename decltype(pt)::type;

                throw DtypeError{"Half-precision (float16) is not supported by Cholesky decomposition"};
                break;
            case Dtype::kFloat32:
                cholesky_impl(PrimitiveType<float>{});
                break;
            case Dtype::kFloat64:
                cholesky_impl(PrimitiveType<double>{});
                break;
            default:
                CHAINERX_NEVER_REACH();
