우리는 Nvidia GPU 및 Intel Xeon Phi를 발전시키는 프로젝트를 가지고 있습니다. 호스트 코드와 GPU 코드는 Fortran으로 작성되고 pgfortran에 의해 컴파일됩니다. 우리 직업의 일부를 Phi에서 오프로드하려면 ifort (정적 링크가 작동하지 않음)로 컴파일 된 공유 라이브러리를 만들고 코드의 pgfortran 부분에서 공유 서브 루틴을 호출해야합니다. 그렇게함으로써, 코드의 pgfortran 부분에서 Xeon Phi와 통신 할 수있는 intel fortran 공유 라이브러리로 배열을 오프로드 할 수 있습니다.다른 컴파일러 (PGI 및 Intel)간에 할당 가능한 배열을 포함하는 포트란 파생 형식 전달
이제 할당 가능한 배열을 포함하는 파생 형식을 pgfortran 코드 부분에서 ifort 공유 라이브러리로 전달하려고합니다. 어떤 문제가있는 것처럼 보입니다. 여기
간단한 예이다 (더 인텔 MIC 현재 지시자를 오프로드 없음) :caller.f90 :
program caller
type cell
integer :: id
real, allocatable :: a(:)
real, allocatable :: b(:)
real, allocatable :: c(:)
end type cell
integer :: n,i,j
type(cell) :: cl(2)
n=10
do i=1,2
allocate(cl(i)%a(n))
allocate(cl(i)%b(n))
allocate(cl(i)%c(n))
end do
do j=1, 2
do i=1, n
cl(j)%a(i)=10*j+i
cl(j)%b(i)=10*i+j
end do
end do
call offload(cl(1))
print *, cl(1)%c
end program caller
called.f90 :
subroutine offload(cl)
type cell
integer :: id
real, allocatable :: a(:)
real, allocatable :: b(:)
real, allocatable :: c(:)
end type cell
type(cell) :: cl
integer :: n
print *, cl%a(1:10)
print *, cl%b(1:10)
end subroutine offload
메이크 :
run: caller.o libcalled.so
pgfortran -L. caller.o -lcalled -o [email protected]
caller.o: caller.f90
pgfortran -c caller.f90
libcalled.so: called.f90
ifort -shared -fPIC $^ -o [email protected]
"cl%a(1:10)
"여기에"(1:10)
"이 없으면 아무 것도 인쇄되지 않습니다.
이 코드는 마침내 cl(1)%a
의 요소를 인쇄 한 다음 배열 행 cl(1)%b
을 인쇄하려고 시도한 다음 줄에서 세그먼트 결함을 기록합니다.
"cl%a(1:10)
"을 "cl % a (1 : 100)"로 변경하고 "print *, cl%b(1:10)
"을 삭제하십시오. 우리는 B 배열의 요소가 있지만 난 그냥 "cl%b(1:10)
"로 그들을 가져올 수 없음을 찾을 수 있습니다
: 그것은 결과를 줄 것이다.
다른 컴파일러의 파생 형식 구조가 원인 일 수 있습니다. 하지만 저는 컴파일러간에 이런 종류의 파생 된 타입을 전달할 수있는 방법을 정말로 원합니다. 어떤 해결책?
감사합니다.
a (:), b (:), c (:) in cell.f90은 할당 가능한 배열 일 수 있습니까? 나는 그것을 시도했다, 그것은 두 번 무료 또는 부패 오류를 줄 것이다. 나는 그들 중 하나가 patatable offload에 할당 할 수있는 배열이 될 필요가있다. – zyc
아니, 될 수 없다. 할당 할 수있는 것은 특정 컴파일러에 의해 할당 된 메모리에만 있습니다. 다른 컴파일러에 의해 할당 된 경우 포인터로 가리켜 야합니다. –
그러나, 나는 당신이 allocatables로 그것을 컴파일 할 수 있었다고 나는 이해하지 못한다. 나의 대답에서 제안을 사용했다면, 가능해서는 안된다. 왜 네가 그걸 필요로하는지 이해가 안돼. 정말 필요한 경우 포인터 배열에서 값을 복사하면됩니다. –