문제

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 내 답변에서 앞서 링크 한 파일)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top