GSoC ChainerX: six weeks progress

Me and my mentor Vincent have a face-to-face meeting every Wednesday over videochat. Last week our weekly meeting was in person. I’ve visited Preferred Networks office (that’s the company behind Chainer) and met a few developers there and we had lunch together. They even have a little space with Tatami (japanese mat) in the common area! Unfortunately, I forgot to take pictures.

For the past days I was mostly focused on polishing existing PRs according to the code review. It was decided to wrap calls to the cuSOLVER and LAPACK with templated functions making the code easier to maintain in the future. Here is an example based on potrf (Cholesky) routine. First make Fortran subroutines available in C++ with

extern "C" {
// potrf
void dpotrf_(char* uplo, int* n, double* a, int* lda, int* info);
void spotrf_(char* uplo, int* n, float* a, int* lda, int* info);
}

Then we define the base template function as

template <typename T>
void Potrf(char /*uplo*/, int /*n*/, T* /*a*/, int /*lda*/, int* /*info*/) {
    throw DtypeError{"Only Arrays of float or double type are supported by potrf (Cholesky)"};
}

It raises an error for all non implemented dtypes. Next we define our specialized wrappers as

template <>
void Potrf<double>(char uplo, int n, double* a, int lda, int* info) {
    dpotrf_(&uplo, &n, a, &lda, info);
}

template <>
void Potrf<float>(char uplo, int n, float* a, int lda, int* info) {
    spotrf_(&uplo, &n, a, &lda, info);
}

Finally, implemented functions are dispatched based on input dtype

...
auto cholesky_impl = [&](auto pt) {
    using T = typename decltype(pt)::type;
    T* a_matrix_ptr = static_cast<T*>(internal::GetRawOffsetData(a_matrix));
    int N = a.shape()[0];
    int info;
    Potrf<T>(uplo, N, a_matrix_ptr, N, &info);
};
VisitFloatingPointDtype(a.dtype(), cholesky_impl);  // Dispatch based on dtype happens here

As for other news, solve, inv, pinv, qr routines are now differentiable.