簡體   English   中英

Rcpp中的英特爾MKL SVD:結果不一致

[英]Intel MKL SVD in Rcpp: inconsistent results

我編寫了一個共享的C ++庫,現在嘗試使用.Call函數進行R擴展,以從該庫中調用函數。 該函數使用英特爾MKL函數LAPACKE_dgesdd,該函數執行矩陣的SVD。

當我有一個大小為m = 5000且n = 8的矩陣時,R擴展和本機C ++版本的輸出(U,S,V'矩陣)完全相同(小數點后15位)可能會期望。 但是,當m = 5000和n = 12時,R版本的輸出不一致,它與本機C ++版本略有不同。 此外,每次運行它時,R版本都會為我提供稍有不同的輸出(與n = 8一致的情況不同)。

我真的不知道如何解釋這種奇怪的行為。 有人有想法嗎?

代碼如下:

function.cpp:

#include <iostream>
#include "mkl_lapacke.h"
#include "mkl.h"
#include <chrono>


  int testSvd(){
    int m=5000;
    int l=12;
    //Allocate matrices
    double * s2 = (double *)mkl_malloc( l*sizeof( double ), 64 );
    double * Rt2 = (double *)mkl_malloc( l*l*sizeof( double ), 64 );
    double * U_l2 = (double *)mkl_malloc( m*l*sizeof( double ), 64 );
    double * AQ2 = (double *)mkl_malloc( m*l*sizeof( double ), 64 );

    populate_matrix_random (m,l,AQ2); //Note that this populates AQ2 with the same matrix every time it is run

    //Perform the svd
    LAPACKE_dgesdd( LAPACK_ROW_MAJOR, 'S', m, l, AQ2, l, s2, U_l2, l, Rt2, l );

    for (int i=0; i<50; i++ ){
          printf( " %6.12f", U_l2[i] );
    }
    printf("\n\s:");
    for (int i=0; i<50; i++ ){
                    printf( " %6.12f", s2[i] );
    }
    printf("\n\Rt\n:");
     for (int i=0; i<50; i++ ){
                    printf( " %6.12f", Rt2[i] );
    }
 }

mainR.cpp:

#include "function.cpp"
#include <Rcpp.h>
RcppExport SEXP testSvdR() {
    testSvd();
}

然后是R代碼:

library(Rcpp);
rm(list = ls())
dyn.load("/opt/intel/composer_xe_2015/mkl/lib/intel64/libmkl_rt.so",     local=FALSE);
dyn.load("mainR.so", local=FALSE);
result = .Call('testSvdR');

我通過在編譯function.cpp時靜態鏈接MKL解決了這個問題(之前我是動態鏈接的)。

我發現此鏈接也有幫助: https : //software.intel.com/zh-cn/articles/intel-mkl-custom-static-linkage

我不清楚在進行動態鏈接時為什么會有如此奇怪的結果。 我能想到的是,也許MKL的某些依賴項是從R自動加載的OpenBLAS或LAPACKE庫中提取的。 我真的不知道。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM