Blas 和 Lapack 库是否有原生 C++(不是 C)接口?
Are there native C++ (not C) interfaces for Blas and Lapack libraries?
目前有:
但是,这些是 C 接口。
显然,您可以在 C++ 代码中使用它们,但如果这些接口是为 C++ 设计的,您将无法获得所有好处。所以我的问题是:
原生 C++ 中是否存在此类接口?
田纳西大学最近发布了这两个接口:
使用这些本机 C++ 实现有一些直接的好处。
让我们考虑一个基本的泛型编程示例:
假设您想缩放一个矢量:v = alpha*v
多亏了 cblas_?scal 函数。
使用 cblas,如果您想要某种东西 "generic",因为它对所有支持的标量类型(float
、double
、complex<float>
、complex<double>
、...),所有 C 函数都必须被包装:
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> ...
原因是在 C 中,如果两个函数具有不同的名称,则它们是不同的:cblas_sscal
、cblas_dscal
...
在 C++ 中,您可以使用相同的名称 scal,这是编译器根据其参数分派到正确函数的工作,此处为 float
、double
.. .
现在的情况。 有了提到的 https://bitbucket.org/icl/blaspp C++ 本地接口,这个样板代码已经写完了。例如,如果您查看 scal.hh 头文件,您有:
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 ) { ... }
甚至是通用实现:
template<typename T>
void scal(int64_t n, T alpha, T *x, int64_t incx ) { ... }
因此有了这个 C++ 接口,很容易为您喜欢的 vector/matrix 类型定义一个通用接口。例如,使用 std::vector<T>
,您只需编写(独立于实际的 T 类型):
template<typename T>
void scal(T alpha, std::vector<T>& v) {
scal(v.size(),alpha,v.data(),1);
}
不再有样板代码!
这是想法,但请注意:
- 尚未为所有子例程实现通用实现,例如:
.
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
}
- 前面的例子用的是blas,但是lapack更有意思,有几百个wrapped subroutines
这不是您想要的,但建议 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 列出了 BLAS and LAPACK 个支持的函数。
我自己并没有使用它,但是 benchmarks 表明这个库性能非常好。开发社区非常友好,欢迎讨论。
目前有:
但是,这些是 C 接口。
显然,您可以在 C++ 代码中使用它们,但如果这些接口是为 C++ 设计的,您将无法获得所有好处。所以我的问题是: 原生 C++ 中是否存在此类接口?
田纳西大学最近发布了这两个接口:
使用这些本机 C++ 实现有一些直接的好处。
让我们考虑一个基本的泛型编程示例:
假设您想缩放一个矢量:v = alpha*v
多亏了 cblas_?scal 函数。
使用 cblas,如果您想要某种东西 "generic",因为它对所有支持的标量类型(float
、double
、complex<float>
、complex<double>
、...),所有 C 函数都必须被包装:
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> ...
原因是在 C 中,如果两个函数具有不同的名称,则它们是不同的:cblas_sscal
、cblas_dscal
...
在 C++ 中,您可以使用相同的名称 scal,这是编译器根据其参数分派到正确函数的工作,此处为 float
、double
.. .
现在的情况。 有了提到的 https://bitbucket.org/icl/blaspp C++ 本地接口,这个样板代码已经写完了。例如,如果您查看 scal.hh 头文件,您有:
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 ) { ... }
甚至是通用实现:
template<typename T>
void scal(int64_t n, T alpha, T *x, int64_t incx ) { ... }
因此有了这个 C++ 接口,很容易为您喜欢的 vector/matrix 类型定义一个通用接口。例如,使用 std::vector<T>
,您只需编写(独立于实际的 T 类型):
template<typename T>
void scal(T alpha, std::vector<T>& v) {
scal(v.size(),alpha,v.data(),1);
}
不再有样板代码!
这是想法,但请注意:
- 尚未为所有子例程实现通用实现,例如:
.
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
}
- 前面的例子用的是blas,但是lapack更有意思,有几百个wrapped subroutines
这不是您想要的,但建议 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 列出了 BLAS and LAPACK 个支持的函数。
我自己并没有使用它,但是 benchmarks 表明这个库性能非常好。开发社区非常友好,欢迎讨论。