我在Linux上使用商业模拟软件进行密集的矩阵操作。该软件默认使用英特尔MKL,但它允许我用自定义BLAS / LAPACK库替换它。此库必须是共享对象(.so)库,并且必须导出BLAS和LAPACK标准例程。该软件需要所有这些软件的标准Fortran接口。
为了验证我可以使用自定义库,我编译了ATLAS并将LAPACK(来自netlib)链接到其中。该软件能够毫无问题地使用我编译的ATLAS版本。
现在,我想让软件使用cuBLAS以提高模拟速度。我遇到的问题是cuBLAS没有导出标准的BLAS函数名称(它们有cublas
前缀)。此外,库cuBLAS库不包括LAPACK例程。
我使用readelf -a
来检查导出的函数。
另一方面,我尝试使用MAGMA来解决这个问题。我成功地编译并链接到所有ATLAS,LAPACK和cuBLAS。但它仍然不会导出正确的函数,也不会在最终的共享对象中包含LAPACK。我不确定这是应该的样子,还是我在构建过程中做错了什么。
我也找到CULA,但我不确定这是否能解决问题。
是否有人试图将cuBLAS / LAPACK(或正确的包装器)链接到单个(.so)中,并使用正确的函数名称导出标准Fortran接口?我相信它在概念上是可行的,但我不知道该怎么做!
答案 0 :(得分:2)
如@talonmies所示,CUDA提供了一个fortran thunking包装器接口。
http://docs.nvidia.com/cuda/cublas/index.html#appendix-b-cublas-fortran-bindings
您应该能够使用它运行您的应用程序。但是由于下面描述的内存分配/复制问题,您可能无法获得任何性能提升。
这可能并不容易。 CUBLAS和其他CUDA库接口假设所有数据都已存储在设备内存中,但在您的情况下,所有数据在调用之前仍在CPU RAM中。
您可能需要编写自己的包装器来处理它,如
void dgemm(...) {
copy_data_from_cpu_ram_to_gpu_mem();
cublas_dgemm(...);
copy_data_from_gpu_mem_to_cpu_ram();
}
另一方面,您可能已经注意到每个BLAS调用都需要2个数据副本。这可能会带来巨大的开销并降低整体性能,除非您的大多数调用都是BLAS 3操作。