在 Debian 10 上,我有 2 个带有 NVlink 硬件组件的 GPU 卡 RTX A6000,我希望受益于这两张卡的潜在组合功能。
目前,我有以下由 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
当我执行我的代码时,我有内存错误,因为在这段代码中,我尝试逆矩阵 size 120k x 120k
。
如果我们仔细观察,120k x 120k 矩阵需要双精度:120k x 120k x 8 字节,因此差不多 108GB。
隐含的函数不能接受单精度。
不幸的是,我有 2 个 48GB 的 NVIDIA GPU 卡:
问题 :
从计算的角度或从编码的角度来看,有没有办法合并 2 个 GPU 卡的 2 个内存(将提供 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
}
}
如果这不可能直接使用两个 GPU 卡之间的 NVlink 硬件组件来实现,我们可以找到哪种解决方法来允许这种矩阵反转?
编辑 :
@user2357112supportsMonica
. 感谢您的快速答复。是的,如您所见,我意识到我没有足够的内存来存储 120k x 120k。但我们的目标是以 60k x 60k 矩阵为例,大概是 54GB:在这种情况下,我怎样才能合并两个 48GB GPU 卡的能力,以便能够反转这个 54GB 矩阵?我正在使用岩浆。
如果我可以将 GPU 内存与 2 张卡合并,也许第三张 48GB 的 GPU 卡可以让我反转 120k x 120k:你怎么看?