在工作中,在Debian 10上,我有2个GPU卡,RTX A6000,带有1TB内存的NVlink harware组件,我想从两者结合的潜力中获益。
目前,Makefile调用了以下magma.make:
CXX = nvcc -std=c++17 -O3
LAPACK = /opt/intel/oneapi/mkl/latest
LAPACK_ANOTHER=/opt/intel/mkl/lib/intel64
MAGMA = /usr/local/magma
INCLUDE_CUDA=/usr/local/cuda/include
LIBCUDA=/usr/local/cuda/lib64
SEARCH_DIRS_INCL=-I${MAGMA}/include -I${INCLUDE_CUDA} -I${LAPACK}/include
SEARCH_DIRS_LINK=-L${LAPACK}/lib/intel64 -L${LAPACK_ANOTHER} -L${LIBCUDA} -L${MAGMA}/lib
CXXFLAGS = -c -DMAGMA_ILP64 -DMKL_ILP64 -m64 ${SEARCH_DIRS_INCL}
LDFLAGS = ${SEARCH_DIRS_LINK} -lmkl_intel_lp64 -lmkl_gnu_thread -lmkl_core -lgomp -lcuda -lcudart -lcublas -lmagma -lpthread -lm -ldl
SOURCES = main_magma.cpp XSAF_C_magma.cpp
EXECUTABLE = main_magma.exe当我执行我的代码时,我会出现内存错误,因为在这段代码中,我试图反演大小为120k x 120k的矩阵。
如果我们看得更近,120 k x 120 k矩阵需要双精度:120 k x 120 k x 8字节,所以几乎是108 so。
所隐含的函数不能接受单一精度。
不幸的是,我有两个NVIDIA GPU卡,每一个48 GPU:
问题:
从计算的角度来看,还是从编码的角度来看,是否有一种方法来合并两个GPU卡的两个内存(这将给出96GB),以反演这些大矩阵?
我正在使用MAGMA进行编译,并用于如下所示的反转例程:
// ROUTINE MAGMA IMPLEMENTED
void matrix_inverse_magma(vector<vector<double>> const &F_matrix, vector<vector<double>> &F_output) {
// Index for loop and arrays
int i, j, ip, idx;
// Start magma part
magma_int_t m = F_matrix.size();
if (m) {
magma_init (); // initialize Magma
magma_queue_t queue=NULL;
magma_int_t dev=0;
magma_queue_create(dev ,&queue );
double gpu_time , *dwork; // dwork - workspace
magma_int_t ldwork; // size of dwork
magma_int_t *piv, info; // piv - array of indices of inter -
magma_int_t mm=m*m; // size of a, r, c
double *a; // a- mxm matrix on the host
double *d_a; // d_a - mxm matrix a on the device
double *d_c; // d_c - mxm matrix c on the device
magma_int_t ione = 1;
magma_int_t ISEED [4] = { 0,0,0,1 }; // seed
magma_int_t err;
const double alpha = 1.0; // alpha =1
const double beta = 0.0; // beta=0
ldwork = m * magma_get_dgetri_nb( m ); // optimal block size
// allocate matrices
err = magma_dmalloc_cpu( &a , mm ); // host memory for a
for (i = 0; i<m; i++){
for (j = 0; j<m; j++){
idx = i*m + j;
a[idx] = F_matrix[i][j];
//cout << "a[" << idx << "]" << a[idx] << endl;
}
}
err = magma_dmalloc( &d_a , mm ); // device memory for a
err = magma_dmalloc( &dwork , ldwork );// dev. mem. for ldwork
piv=( magma_int_t *) malloc(m*sizeof(magma_int_t ));// host mem.
magma_dsetmatrix( m, m, a, m, d_a, m, queue); // copy a -> d_a
magma_dgetrf_gpu( m, m, d_a, m, piv, &info);
magma_dgetri_gpu(m, d_a, m, piv, dwork, ldwork, &info);
magma_dgetmatrix( m, m, d_a , m, a, m, queue); // copy d_a ->a
for (i = 0; i<m; i++){
for (j = 0; j<m; j++){
idx = i*m + j;
F_output[i][j] = a[idx];
}
}
// SAVE ORIGINAL
free(a); // free host memory
free(piv); // free host memory
magma_free(d_a); // free device memory
magma_queue_destroy(queue); // destroy queue
magma_finalize ();
// End magma part
}
}如果这是不可能直接与NVlink硬件组件之间的两个GPU卡,我们能找到什么解决办法,允许这个矩阵反演?
编辑:
一位高性能工程师告诉我:
“最简单的方法将是使用Makefiles,直到我们弄清楚cmake如何支持它。如果你这样做,你只需要用LAPACKE_dgetrf代替magma_dgetrf。MAGMA将在内部使用一个内存不足的算法来填充矩阵,即使它很大,而且不会进入GPU的内存中。”
这是否意味着我必须找到Makefile的适当标志才能使用magma_dgetrf而不是LAPACKE_dgetrf?
至于第二句,据说
岩浆将在内部使用一个GPU,并采用内存不足的算法来填充矩阵
这是否意味着,如果我的矩阵大于48 my,那么岩浆将能够将其余的填充到第二个GPU A6000或内存中,并执行整个矩阵的反演?
请让我知道,在我的情况下,使用哪些标志来正确地构建岩浆。
最近,我做了:
$ mkdir build && cd build
$ cmake -DUSE_FORTRAN=ON \
-DGPU_TARGET=Ampere \
-DLAPACK_LIBRARIES="/opt/intel/oneapi/intelpython/latest/lib/liblapack.so" \
-DMAGMA_ENABLE_CUDA=ON ..
$ cmake --build . --config Release发布于 2022-01-04 14:58:01
我不是GP/GPU计算方面的专家,但是如果你能将两个计算设备组合成一个设备,我会非常惊讶。至少我认为使用标准库是不可能的。如果你想一想,它一开始就挫败了使用GPU的目的。
然而,我想说的是,一旦你使用了非常大的矩阵,你就会遇到很多问题,这使得教科书的反运算在数值上不稳定。相反,通常的方法是根本不存储逆矩阵。通常,您只需要一个逆矩阵就可以求解。
Ax =b(解x) Ax -b=0(同质形式)
可以不用逆-A来求解。
我建议你从读C/C++中的数值循环的逆矩阵一章开始。这是一个标准文本,有示例代码,并且可以从亚马逊等广泛使用。这些文本假设CPU实现,但是.
一旦您了解了这些算法,您可能(或者可能不会)发现,能够发出两个并行的非逆矩阵操作对您是有用的。然而,在这个(和其他文本)中描述的算法比任何蛮力操作都快一个数量级。
https://stackoverflow.com/questions/70493020
复制相似问题