BLAS SUBROUTINES DGEMM, DGEMV 및 DDOT가 스칼라와 함께 작동하지 않습니까?
문제
BLAS 'Subroutines DGEMM, DGEMV 및 DDOT를 사용하는 Fortran Subroutine이 있습니다. 매트릭스 * 매트릭스, 매트릭스 * 벡터 및 벡터 * 벡터를 계산합니다. 나는 m * m 행렬과 m * 1 벡터가 있습니다. 경우에 따라 m = 1. 그 서브 루틴은 그 경우에 잘 작동하지 않는 것 같습니다. 그들은 오류를주지 않지만 결과에는 수치 적으로 불안정한 것 같습니다. 그래서 나는 다음과 같은 것을 써야합니다.
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)
내 실제 질문은 M = 1 일 때 BLAS의 서브 루틴이 제대로 작동하지 않는다는 것입니다. 아니면 내 코드에 문제가 있습니까? 컴파일러가 이것에 영향을 줄 수 있습니까? Gfortran을 사용하고 있습니다.
해결책
BLAS 루틴은 크기 1의 객체로 올바르게 행동해야합니다. 컴파일러에 의존 할 수는 없지만 의존하는 BLA의 구현에 의존 할 수 있다고 생각합니다. 구현). 참조 (읽기 : 대상 최적화되지 않음) BLA의 구현. netlib, 해당 케이스를 잘 처리합니다.
크기 1의 두 배열 모두에서 약간의 테스트를 수행했으며 더 큰 배열의 크기 1 조각 (자신의 코드에서와 같이)이 모두 잘 작동합니다.
$ 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
이 문제를 더욱 디버그하기 위해 고려해야 할 사항 :
- 당신을 확인하십시오
ddot
정의가 정확합니다 - 참조 BLA를 최적화 된 블라스로 대체하여 변경 사항을 확인하십시오 (단지 컴파일하고 링크 할 수 있습니다.
ddot.f
내 답변에서 앞서 링크 한 파일)
제휴하지 않습니다 StackOverflow