J'essaie d'utiliser MKL Sparse BLAS pour les matrices CSR avec le nombre de lignes/colonnes de l'ordre de 100M. Mon code source qui semble fonctionner correctement pour 10M lignes/colonnes échoue avec segfault quand je l'augmente à 100M.MKL Sparse BLAS segfault lors de la transposition CSR avec 100M lignes
J'isolé le problème à l'extrait de code suivant:
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);
}
Cette fonction segfaults à mkl_sparse_convert_csr avec backtrace
#0 0x00000000004c0d03 in mkl_sparse_s_convert_csr_i4_avx()
#1 0x0000000000434061 in TestSegfault1()
Pour un code légèrement différent (mais essentiellement le même), il a un peu plus détail:
#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()
Apparemment, quelque chose va mal en m allocation d'émory. Et cela ressemble à une sorte de débordement d'entier de l'extérieur. La construction de MKL utilise MKL_INT = int = int32.
Est-ce bien le cas et la limite sur le nombre de lignes que je peux avoir dans la matrice RSE Sparse BLAS est < 100M (ressemble plus à ~ 65M)? Ou est-ce que je le fais mal?
EDIT 1: La chaîne de version MKL est «Bibliothèque de noyaux Intel (R) Math version 11.3.1 Produit Build 20151021 pour les applications d'architecture Intel (R) 64».
EDIT 2: Compris. Il y a en effet un type subtil de débordement d'entier lors de l'allocation de mémoire pour les tampons internes par thread. À un certain point à l'intérieur de mkl_sparse_s_export_csr_data_i4_avx, il tente d'allouer (omp_get_max_threads() + 1) * num_rows * 4 octets; le nombre ne correspond pas à l'entier signé 32 bits. L'appel suivant à mkl_serv_malloc provoque une corruption de la mémoire et éventuellement une erreur de segmentation. Une solution possible consiste à modifier le nombre de threads OpenMP via l'appel omp_set_num_threads.