我正在尝试将MKL Sparse BLAS用于CSR矩阵,其行数/列数量为100M。当我将其增加到100M时,我的源代码似乎在10M行/列上工作正常失败。
我将问题分离到以下代码段:
void TestSegfault1() {
float values[1] = { 1.0f };
int col_indx[1] = { 0 };
int rows_start[1] = { 0 };
int rows_end[1] = { 1 };
// Step 1. Create 1 x 100M matrix
// with single non-zero value at (0,0)
sparse_matrix_t A;
mkl_sparse_s_create_csr(
&A, SPARSE_INDEX_BASE_ZERO, 1, 100000000,
rows_start, rows_end, col_indx, values);
// Step 2. Transpose it to get 100M x 1 matrix
sparse_matrix_t B;
mkl_sparse_convert_csr(A, SPARSE_OPERATION_TRANSPOSE, &B);
}
此函数在mkl_sparse_convert_csr中使用backtrace进行段错误
#0 0x00000000004c0d03 in mkl_sparse_s_convert_csr_i4_avx ()
#1 0x0000000000434061 in TestSegfault1 ()
对于略有不同的代码(但基本相同),它有更多细节:
#0 0x00000000008fc09b in mkl_serv_free ()
#1 0x000000000099949e in mkl_sparse_s_export_csr_data_i4_avx ()
#2 0x0000000000999ee4 in mkl_sparse_s_convert_csr_i4_avx ()
显然内存分配有些不好。它确实看起来像是从外部溢出的某种整数。 MKL的构建我使用MKL_INT = int = int32。
确实是这种情况,并且我在稀疏BLAS CSR矩阵中可以拥有的行数限制是< 100M(看起来更像是〜65M)?或者我做错了吗?
编辑1: MKL版本字符串是“用于英特尔(R)64架构应用程序的英特尔(R)数学核心库版本11.3.1产品构建20151021”。
编辑2:想出来。在为内部每线程缓冲区分配内存时,确实存在一种微妙的整数溢出。在mkl_sparse_s_export_csr_data_i4_avx内部的某个点上,它尝试分配(omp_get_max_threads()+ 1)* num_rows * 4个字节;该数字不适合32位有符号整数。对mkl_serv_malloc的后续调用会导致内存损坏并最终导致段错误。一种可能的解决方案是通过omp_set_num_threads调用来改变OpenMP线程的数量。
答案 0 :(得分:0)
你能检查一下MKL最新版本的例子吗?我在MKL 11.3.2上运行它并正确传递100M矩阵。但是它可能取决于您机器上的线程数(矩阵多个线程的大小必须小于max int)。为防止此类问题,我强烈建议您使用ilp64版本的MKL库 谢谢, 亚历
答案 1 :(得分:0)
检查此示例如何与最新的mkl 2019 u4配合使用。 用ILP64模式编译示例,如下所示:
icc -I/opt/intel/compilers_and_libraries_2019/linux/mkl/include test_csr.cpp \
-L/opt/intel/compilers_and_libraries_2019/linux/mkl/lib/intel64 -lmkl_core -lmkl_intel_ilp64 -lmkl_intel_thread -liomp5 -lpthread -lm -ldl
./ a.out mkl_sparse_convert_csr通过了