BLAS Subroutinen dgemm, dgemv und ddot funktioniert nicht mit Skalare?
Frage
Ich habe ein Fortran-Unterprogramm, das verwendet BLAS‘Subroutinen dgemm, dgemv und ddot, die Matrix-Matrix *, * Matrix-Vektor-und Vektor-Vektor * berechnen. Ich habe m * m-Matrizen und m * 1 Vektoren. In einigen Fällen m = 1. Es scheint, dass diese Subroutinen nicht gut in diesen Fällen nicht funktioniert. Sie geben keine Fehler, aber es scheint in den Ergebnissen einige numerische Instabilität zu sein. Also muss ich etwas schreiben wie:
if(m>1) then
vtuni(i,t) = yt(i,t) - ct(i,t) - ddot(m, zt(i,1:m,(t-1)*tvar(3)+1), 1, arec, 1)
else
vtuni(i,t) = yt(i,t) - ct(i,t) - zt(i,1,(t-1)*tvar(3)+1)*arec(1)
Also meine eigentliche Frage ist, bin ich richtig, dass diejenigen BLAS‘Subroutinen funktioniert nicht richtig, wenn m = 1, oder es ist nur etwas falsch in meinem Code? Der Compiler kann diese beeinflussen? Ich verwende gfortran.
Lösung
BLAS Routinen sollen korrekt 1. mit den Objekten der Größe verhalten Ich glaube nicht, dass es auf Compiler abhängen kann, aber es könnte möglich über die Umsetzung von BLAS abhängen Sie sich auf (obwohl ich es betrachten würde ein Fehler der Implementierung). Die Referenz (sprich: nicht zieloptimiert) Implementierung von BLAS, die auf Netlib , behandelt diesen Fall in Ordnung.
Ich habe einige Tests auf beiden Arrays der Größe 1 durchgeführt, und die Größe-1 Scheiben größeren Arrays (wie in Ihrem eigenen Code), und beide funktionieren:
$ cat a.f90 implicit none double precision :: u(1), v(1) double precision, external :: ddot u(:) = 2 v(:) = 3 print *, ddot(1, u, 1, v, 1) end $ gfortran a.f90 -lblas && ./a.out 6.0000000000000000 $ cat b.f90 implicit none double precision, allocatable :: u(:,:,:), v(:) double precision, external :: ddot integer :: i, j allocate(u(3,1,3),v(1)) u(:,:,:) = 2 v(:) = 3 i = 2 j = 2 print *, ddot(1, u(i,1:1,j), 1, v, 1) end $ gfortran b.f90 -lblas && ./a.out 6.0000000000000000
Dinge, die ich würde erwägen, dieses Problem zu debuggen weiter:
- Überprüfen Sie, ob Ihre
ddot
Definition ist richtig - Ersetzen Sie die Referenz BLAS auf Ihr eine optimierte, um zu überprüfen, ob es etwas ändert (können Sie einfach zusammenstellen und Link in der
ddot.f
Datei verknüpft ich bereits in meiner Antwort auf)