svd의 값이 MKLNUMTHREADS에 따라 춤을 춘다. (11.0 Update 3부터 이런 문제를 일으키는 것 같다.)
예를 들어 다음과 같이 armadillo library와 mkl을 사용하는 경우
/* -*- mode: c++; -*- */ #include <armadillo> int main(int argc, char *argv[]) { using namespace arma; mat M = randu(957, 957); mat U, V; vec s; svd(U, s, V, M); mat newM = U * diagmat(s) * V.t(); printf("norm: %f\n", arma::norm(M - newM,2)); return 0; }
이런 결과가 나오고
$ MKL_NUM_THREADS=1 ./main norm: 0.000000 $ MKL_NUM_THREADS=2 ./main norm: 0.000000 $ MKL_NUM_THREADS=3 ./main norm: 0.000000 $ MKL_NUM_THREADS=4 ./main norm: 0.000000 $ MKL_NUM_THREADS=5 ./main norm: 371.303371 $ MKL_NUM_THREADS=6 ./main norm: 138.622780 $ MKL_NUM_THREADS=7 ./main norm: 138.622780
mkl만 사용하는 다음 프로그램을 짜서 돌려보면
/* -*- mode: c++; -*- */ #include <mkl.h> #include <string.h> #include <math.h> #include <stdio.h> int main(int argc, char *argv[]) { lapack_int M = 958; double *mat = new double[M * M]; double *mat_orig = new double[M * M]; double *s = new double[M]; double *diags = new double[M*M]; double *U = new double[M * M]; double *Vt = new double[M * M]; double *superb = new double[M-1]; for (int i=0; i<M*M; ++i) mat[i] = static_cast<double>(rand())/RAND_MAX; memcpy(mat_orig, mat, sizeof(double) * M * M); LAPACKE_dgesvd(LAPACK_COL_MAJOR, 'a', 'a', M, M, mat, M, s, U, M, Vt, M, superb); memset(diags, 0, sizeof(double) * M * M); for (int i=0; i<M; ++i) diags[i * M + i] = s[i]; cblas_dgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, M, M, M, 1.0, U, M, diags, M, 0.0, mat, M); cblas_dgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, M, M, M, 1.0, mat, M, Vt, M, 0.0, U, M); double res = 0.0; for (int i=0; i<M*M; ++i) { double t = mat_orig[i] - U[i]; res += (t*t); } printf("norm: %f\n", sqrt(res)); delete[] superb; delete[] Vt; delete[] U; delete[] diags; delete[] s; delete[] mat_orig; delete[] mat; return 0; }
결과가 매우 심각하다. ㅡㅡ
$ MKL_NUM_THREADS=1 ./main2 norm: 0.000000 $ MKL_NUM_THREADS=2 ./main2 norm: 0.000000 $ MKL_NUM_THREADS=3 ./main2 norm: 0.000000 $ MKL_NUM_THREADS=4 ./main2 norm: 0.000000 $ MKL_NUM_THREADS=5 ./main2 norm: 457.024091 $ MKL_NUM_THREADS=6 ./main2 Segmentation fault (core dumped) $ MKL_NUM_THREADS=7 ./main2 Segmentation fault (core dumped)
댓글
댓글 쓰기