2017-04-25 25 views
17

LAPACK 및 다중 스레드 BLAS 루틴에 ATLAS를 사용하고 있는데, ATLAS가 ATLAS에서 BLAS의 다중 스레드 버전을 사용할 정도로 충분히 커지면 Valgrind에서 초기화 오류가 발생합니다.ATLAS 다중 스레드 BLAS 루틴에서 valgrind의 "초기화되지 않은 값"경고가 false positive입니까?

#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 

내가 "조건부 점프의 11 개 문맥에서 193 오류가 발생할 수 또는 이동은 dgetrf_ 및 dgetri_의 두 x 째 인스턴스가 _ 생할 때 초기화되지 않은 값 (들)에 따라 다 (니다.

==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

은 왜 자신이 소스에서 디버그 모드에서 3.10 ATLAS 구축하지? 그러면 Valgrind가 문제의 원인을 찾아 낼 수 있습니다. –

답변

13

가짜 오류가 발생합니까?

아니요.

--leak-check=yes으로 valgrind를 실행하는 대신 --track-origins=yes으로 실행하여 출력 끝에 valgrind가 제안한대로 초기화되지 않은 값의 출처를 확인해야합니다. 여기에 내가 --track-origins=yes에있어 무엇 :

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

그런 다음 줄에 dgetrf_()에 전달 m1을 초기화하는 데 사용됩니다

[ ~]$ 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) 

그래서 초기화되지 않은 값의 소스 코드의 라인 012.

저는 ATLAS 라이브러리에 익숙하지 않지만 어쨌든 temp 변수를 초기화해야합니다. 초기화하는 예 제로 들어 calloctemp이 모든 Valgrind의 오류를 해결합니다

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

ATLAS에 익숙하지 않지만,이 지점 바로 위의'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

"한편 베타 버전은이 코드에서 0.0이며, 임시 설정은 필요하지 않습니다. 이는 문서에도 명시되어 있습니다.이 점이 저를 조금 혼란스럽게합니다." 예, 이것은 나에게 @ ks1322를 혼란스럽게합니다. atlas의 멀티 스레딩 버전없이이 동일한 코드를 실행하면 temp의 값이 아직 초기화되지 않은 경우에도 초기화 오류가 발생하지 않습니다. – Emilie