5

Currently, there are:

  • cblas which is shipped with blas,
  • lapacke which is shipped with lapack,

however, these are C interfaces.

Obviously, you can use them in a C++ code, but you do not get all the benefits you would get if these interfaces were designed for C++. So my question is: are such interfaces exist in native C++?

Picaud Vincent
  • 10,518
  • 5
  • 31
  • 70

2 Answers2

3

Recently these two interfaces, from University of Tennessee, has been released:

There are some immediate benefits of using these native C++ implementations.

Let's consider a basic generic programming example:

Imagine that you want to scale a vector: v = alpha*v thanks to the cblas_?scal functions.

With cblas, if you wanted something "generic" in the sense that it has the same interface for all supported scalar types (float, double, complex<float>, complex<double>,...), all the C functions had to be wrapped:

void scal(cblas_int n,float alpha, float *x, cblas_int inc) {
    ...
    cblas_sscal(n,alpha,x,inc);  <- s for float
}

void scal(cblas_int n,double alpha, double *x, cblas_int inc) {
    ...
    cblas_dscal(n,alpha,x,inc);  <- d for double
}

// do the same for complex<float>, complex<double> ...

The reason is that in C, two functions are differents if they have different names: cblas_sscal, cblas_dscal... In C++ you can have the same name scal and this is the compiler job to dispatch to the right function according to its arguments, here float, double...

The situation now. With the mentioned https://bitbucket.org/icl/blaspp C++ native interface this boilerplate code has already been written once for all. For instance if you look scal.hh header file you have:

void scal(int64_t n, float alpha, float *x, int64_t incx ) { ... }
void scal(int64_t n, double alpha, double *x, int64_t incx ) { ... }
void scal(int64_t n, std:complex<float> alpha, std:complex<float> *x, int64_t incx ) { ... }
void scal(int64_t n, std:complex<double> alpha, std:complex<double> *x, int64_t incx ) { ... }

and even a generic implementation:

template<typename T>
void scal(int64_t n, T alpha, T *x, int64_t incx ) { ... }

Hence with this C++ interface, it is easy to define a generic interface for your favorit vector/matrix type. As example, with std::vector<T>, you only have to write (independently of the actual T type):

template<typename T>
void scal(T alpha, std::vector<T>& v) {
   scal(v.size(),alpha,v.data(),1);
}

No more boilerplate code!


This is the idea, however note that:

  • generic implementation are not yet implemented for all subroutines, for instance:

.

template< typename TA, typename TX >
void trmm(
    blas::Layout layout,
    blas::Side side,
    blas::Uplo uplo,
    blas::Op trans,
    blas::Diag diag,
    int64_t m,
    int64_t n,
    typename blas::traits2<TA, TX>::scalar_t alpha,
    TA const *A, int64_t lda,
    TX       *B, int64_t ldb )
{
    throw std::exception();  // not yet implemented
}
  • The previous example used blas, however, it is even more interesting for lapack which has several hundreds of wrapped subroutines.
Picaud Vincent
  • 10,518
  • 5
  • 31
  • 70
  • 1
    I had a mini heart-attack when I saw that someone wrote this big answer to a question that was asked 1 minute ago. – Yashas Dec 14 '17 at 13:53
  • @Yashas I write some notes for myself here, however, maybe they can be useful for others, this is the idea :-). – Picaud Vincent Dec 14 '17 at 13:55
2

It is not exactly what you seek, but would suggest Blaze C++ library:

Blaze is an open-source, high-performance C++ math library for dense and sparse arithmetic. With its state-of-the-art Smart Expression Template implementation Blaze combines the elegance and ease of use of a domain-specific language with HPC-grade performance, making it one of the most intuitive and fastest C++ math libraries available.

The Blaze library offers ...

  • ... high performance through the integration of BLAS libraries and manually tuned HPC math kernels
  • ... vectorization by SSE, SSE2, SSE3, SSSE3, SSE4, AVX, AVX2, AVX-512, FMA, and SVML
  • ... parallel execution by OpenMP, C++11 threads and Boost threads
  • ... the intuitive and easy to use API of a domain specific language
  • ... unified arithmetic with dense and sparse vectors and matrices
  • ... thoroughly tested matrix and vector arithmetic
  • ... completely portable, high quality C++ source code

Wiki has lists of BLAS and LAPACK functions supported.

I did not use it myself, but benchmarks show, that this library performs very well. The development community is very friendly and is open for discussion.

  • yes, I am aware of Blaze, Eigen, Armadillo,... libraries. However, sometimes I prefer a flat interface, without the [Expression Template Mechanism](http://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=06266939). Reason: simpler code and reduced compilation time :). Thanks for completing my answer anyway :) – Picaud Vincent Dec 14 '17 at 14:29