2017-04-25 31 views
17

我使用ATLAS的LAPACK和多線程BLAS例程,並已經注意到,當我得到的矩陣足夠大的ATLAS使用BLAS的多線程版本,我從Valgrind的初始化錯誤。下面是從我的代碼小例子:ATLAS多線程BLAS例程中的valgrind「未初始化值」警告是否爲誤報?

#include <stdio.h> 
#include <stdlib.h> 

extern void dgetrf_(int *, int *, double *, int *, int *, int *); 
extern void dgetri_(int *, double *, int *, int *, double *, int *, int *); 
extern void dgemm_(char *, char *, int *, int *, int *, double *, double *, int *, double *, int *, double *, double *, int *); 

int main(void) 
{ 
    double *m1,*m2,*work,*temp; 
    int dim = 576; 
    int i,j,info; 
    int lwork = dim * dim; 
    int *ipiv; 
    char transA = 'N'; 
    char transB = 'N'; 
    double alpha = 1.0; 
    double beta = 0.0; 

    m1 = malloc(dim*dim*sizeof(double)); 
    m2 = malloc(dim*dim*sizeof(double)); 
    temp = malloc(dim*dim*sizeof(double)); 
    ipiv = malloc(dim*sizeof(int)); 
    work = malloc(lwork*sizeof(double)); 

    for(i=0; i<dim; i++) 
    { 
     for(j=0; j<dim; j++) 
     { 
      if(i==j) 
      { 
      m1[i+dim*j] = .25; 
      m2[i+dim*j] = .5; 
      } 
      else 
      { 
      m1[i+dim*j] = 0.0; 
      m2[i+dim*j] = 0.0; 
      } 
     } 
    } 

    dgetrf_(&dim, &dim, m1, &dim, ipiv, &info); 
    dgetri_(&dim, m1, &dim, ipiv, work, &lwork, &info); 

    dgemm_(&transA, &transB, &dim, &dim, &dim, &alpha, m1, &dim, m2, &dim, &beta, temp, &dim); 
    for(i=0; i<dim*dim; i++) 
     m1[i] = temp[i]; 

    dgetrf_(&dim, &dim, m1, &dim, ipiv, &info); 
    dgetri_(&dim, m1, &dim, ipiv, work, &lwork, &info); 

    free(m1); 
    free(m2); 
    free(ipiv); 
    free(work); 
    free(temp); 

    return 0; 
} 

(注:我檢查,以確保該矩陣是奇異的不,他們都沒有)

我編譯程序:

gcc -Wall -DATLAS -m64 -g -c fermi.c 
gcc -o fermi fermi.o -L/usr/lib64/atlas/ -lm -ltatlas 

而且Valgrind的運行:

valgrind --leak-check=yes ./fermi 

當我這樣做,我得到193個錯誤,從「條件跳轉的11個上下文或移動取決於未初始化的值「,當遇到dgetrf_和dgetri_的第二個實例時。

==24999== Memcheck, a memory error detector 
==24999== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. 
==24999== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info 
==24999== Command: ./fermi 
==24999== 
==24999== Conditional jump or move depends on uninitialised value(s) 
==24999== at 0x524C62B: ??? (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51C29E3: ATL_dgetf2 (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x520F538: atl_f77wrap_dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x5210416: dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x400A97: main (fermi.c:52) 
==24999== 
==24999== Conditional jump or move depends on uninitialised value(s) 
==24999== at 0x524C66A: ??? (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51C29E3: ATL_dgetf2 (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x520F538: atl_f77wrap_dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x5210416: dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x400A97: main (fermi.c:52) 
==24999== 
==24999== Conditional jump or move depends on uninitialised value(s) 
==24999== at 0x524C6BE: ??? (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51C29E3: ATL_dgetf2 (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x520F538: atl_f77wrap_dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x5210416: dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x400A97: main (fermi.c:52) 
==24999== 
==24999== Conditional jump or move depends on uninitialised value(s) 
==24999== at 0x51C2A0B: ATL_dgetf2 (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x520F538: atl_f77wrap_dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x5210416: dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x400A97: main (fermi.c:52) 
==24999== 
==24999== Conditional jump or move depends on uninitialised value(s) 
==24999== at 0x51C2A0D: ATL_dgetf2 (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x520F538: atl_f77wrap_dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x5210416: dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x400A97: main (fermi.c:52) 
==24999== 
==24999== Conditional jump or move depends on uninitialised value(s) 
==24999== at 0x51C2A4E: ATL_dgetf2 (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x520F538: atl_f77wrap_dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x5210416: dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x400A97: main (fermi.c:52) 
==24999== 
==24999== Conditional jump or move depends on uninitialised value(s) 
==24999== at 0x51C2A61: ATL_dgetf2 (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x520F538: atl_f77wrap_dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x5210416: dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x400A97: main (fermi.c:52) 
==24999== 
==24999== Conditional jump or move depends on uninitialised value(s) 
==24999== at 0x524C2D7: ATL_daxpy (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x53426BB: ATL_dgerk_axpy (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51C2AC7: ATL_dgetf2 (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x520F538: atl_f77wrap_dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x5210416: dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x400A97: main (fermi.c:52) 
==24999== 
==24999== Conditional jump or move depends on uninitialised value(s) 
==24999== at 0x524C751: ??? (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51C29E3: ATL_dgetf2 (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51CD2BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x520F538: atl_f77wrap_dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x5210416: dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x400A97: main (fermi.c:52) 
==24999== 
==24999== Conditional jump or move depends on uninitialised value(s) 
==24999== at 0x51CD8E5: ATL_dtrtri (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51C2EC3: ATL_dgetriC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x520EFA5: atl_f77wrap_dgetri_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x520F684: dgetri_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x400AC0: main (fermi.c:53) 
==24999== 
==24999== Conditional jump or move depends on uninitialised value(s) 
==24999== at 0x51CD8E7: ATL_dtrtri (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x51C2EC3: ATL_dgetriC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x520EFA5: atl_f77wrap_dgetri_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x520F684: dgetri_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==24999== by 0x400AC0: main (fermi.c:53) 
==24999== 
==24999== 
==24999== HEAP SUMMARY: 
==24999==  in use at exit: 0 bytes in 0 blocks 
==24999== total heap usage: 2,024 allocs, 2,024 frees, 54,831,424 bytes allocated 
==24999== 
==24999== All heap blocks were freed -- no leaks are possible 
==24999== 
==24999== For counts of detected and suppressed errors, rerun with: -v 
==24999== Use --track-origins=yes to see where uninitialised values come from 
==24999== ERROR SUMMARY: 193 errors from 11 contexts (suppressed: 0 from 0) 

我已經發現了一些鏈接,建議這可能是從庫是做事情的方式誤報到來,但他們都沒有關係很符合我的上下文。

memory leak in dgemm_

https://www.open-mpi.org/community/lists/users/2007/05/3192.php

所以我的問題:的valgrind是給我的假陽性錯誤?

+2

你爲什麼不建立自己ATLAS 3.10從源和在調試模式?然後Valgrind將能夠指出你的問題的原因。 –

回答

13

的valgrind是給我的假陽性錯誤?

貌似沒有。

而不是運行valgrind與--leak-check=yes你應該已經運行它與--track-origins=yes來查看未初始化值來自valgrind在輸出結束時建議的位置。這裏是我得到了與--track-origins=yes

[ ~]$ valgrind --track-origins=yes ./a.out 
==17533== Memcheck, a memory error detector 
==17533== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. 
==17533== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info 
==17533== Command: ./a.out 
==17533== 
==17533== Conditional jump or move depends on uninitialised value(s) 
==17533== at 0x4F4362B: ??? (in /usr/lib64/atlas/libtatlas.so.3.10) 
==17533== by 0x4EB99E3: ATL_dgetf2 (in /usr/lib64/atlas/libtatlas.so.3.10) 
==17533== by 0x4EC42BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==17533== by 0x4EC42BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==17533== by 0x4EC42BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==17533== by 0x4EC42BF: ATL_dtgetrfC (in /usr/lib64/atlas/libtatlas.so.3.10) 
==17533== by 0x4F06538: atl_f77wrap_dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==17533== by 0x4F07416: dgetrf_ (in /usr/lib64/atlas/libtatlas.so.3.10) 
==17533== by 0x400A29: main (fermi.c:50) 
==17533== Uninitialised value was created by a heap allocation 
==17533== at 0x4C2DB9D: malloc (vg_replace_malloc.c:299) 
==17533== by 0x40080B: main (fermi.c:22) 

所以未初始化值的來源是這行代碼:

temp = malloc(dim*dim*sizeof(double)); 

它然後用於初始化被傳遞到dgetrf_()上線m1 50.

我不熟悉的ATLAS庫,但我猜你應該以某種方式初始化temp變量。例如零初始化tempcalloc解決所有這些的valgrind錯誤:

temp = calloc(dim*dim,sizeof(double)); 
+0

我不熟悉的ATLAS下去,但我_think_爲'dgemm_'緊接本點以上應該調用初始化了的temp''所有元素。見http://www.netlib.org/lapack/explore-html/d1/d54/group__double__blas__level3_gaeda3cbd99c8fb834a60a6412878226e1。html#gaeda3cbd99c8fb834a60a6412878226e1 – zwol

+1

@zwol,'temp'是'dgemm_'的輸入和輸出參數。所以如果'temp'沒有被初始化,存儲在'temp'中的結果將取決於未初始化的值。另一方面,在這段代碼中'beta'是'0.0','temp'不需要設置,這在文檔中也有說明。這讓我有些困惑。 – ks1322

+0

「另一方面,此代碼中的beta爲0.0,不需要設置temp,這在文檔中也有說明。這讓我感到困惑。」是的,這也讓我感到困惑@ ks1322。如果我在沒有多線程版本的圖集的情況下運行相同的代碼,即使temp的值仍未初始化,我也不會收到初始化錯誤。 – Emilie

相關問題