2017-04-25 66 views
17

Używam ATLAS dla procedur LAPACK i wielowątkowych BLAS. Zauważyłem, że kiedy moje macierze są wystarczająco duże, aby ATLAS mógł korzystać z wielowątkowych wersji BLAS, otrzymuję błędy inicjalizacji od Valgrind. Oto minimalne przykład z mojego kodu:Czy ostrzeżenia valgrind "niezainicjowana wartość" są fałszywie dodatnie w procedurach wielowątkowych BLAS ATLAS?

#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; 
} 

(Uwaga:. I zostały sprawdzone, aby upewnić się macierze nie są w liczbie pojedynczej, a nie są)

skompilować program:

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

I uruchomić valgrind:

valgrind --leak-check=yes ./fermi 

Gdy to zrobić otrzymuję 193 błędy od 11 kontekstów „skok warunkowy lub przenieść zależy od niezainicjowanych wartości "po napotkaniu drugiego wystąpienia dgetrf_ i 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) 

Znalazłem kilka linków, które sugerują, że to mógłby być fałszywie dodatni pochodzących z okazji biblioteka jest robienie rzeczy, choć nie są one związane bardzo dużo do mojego kontekstu.

memory leak in dgemm_

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

więc moje pytanie: jest valgrind dając mi fałszywie dodatnie błędy?

+2

Dlaczego nie można zbudować samemu ATLAS 3.10 od źródła oraz w trybie debugowania? Wtedy Valgrind będzie w stanie wskazać ci przyczynę twoich problemów. –

Odpowiedz

13

Czy valgrind daje mi fałszywe pozytywne błędy?

Wygląda na to, że nie.

Zamiast używać valgrind z --leak-check=yes powinieneś uruchomić go z --track-origins=yes, aby zobaczyć, skąd pochodzą niezainicjowane wartości sugerowane przez valgrind na końcu wyjścia. Oto co mam z --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) 

Więc źródłem wartości zainicjalizowana jest ta linia kodu:

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

To jest następnie wykorzystywany do zainicjowania m1 który jest przekazywany do dgetrf_() on line 50.

Nie znam biblioteki ATLAS, ale domyślam się, że powinieneś jakoś zainicjalizować zmienną temp. Na przykład zerowej inicjalizacji temp z calloc rozwiązuje wszystkie te błędy Valgrind:

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

Nie jestem również zaznajomiony z ATLAS'em, ale zaczynam wołać do 'dgemm_' bezpośrednio powyżej tego punktu, aby zainicjować wszystkie elementy' temp'. Zobacz http://www.netlib.org/lapack/explore-html/d1/d54/group__double__blas__level3_gaeda3cbd99c8fb834a60a6412878226e1.html # gaeda3cbd99c8fb834a60a6412878226e1 – zwol

+1

@ Pozwala, 'temp' jest zarówno parametrem wejściowym, jak i wyjściowym do' dgemm_'. Więc jeśli 'temp' nie zostanie zainicjalizowany, wynik zapisany w' temp' będzie zależał od niezainicjowanych wartości. Z drugiej strony 'beta' w tym kodzie to' 0.0', a 'temp' nie musi być ustawiony, co jest również określone w dokumentacji. To mnie trochę dezorientuje. – ks1322

+0

"Z drugiej strony beta w tym kodzie to 0,0, a temperatura nie musi być ustawiona, co jest również określone w dokumentacji. To mnie trochę dezorientuje." Tak, to także mnie dezorientuje @ ks1322. Jeśli uruchomię ten sam kod bez wielowątkowej wersji atlasu, nie otrzymam błędu inicjalizacji, mimo że wartości temp są nadal niezainicjowane. – Emilie