BiCGStab с использованием подпрограмм CUDA cuSparse из Фортрана: CUSPARSE_INTERNAL_ERROR во время анализа

РЕДАКТИРОВАТЬ

Этот вопрос был помечен как не по теме «Вопросы, требующие помощи при отладке (« почему этот код не работает? ») Должны включать в себя желаемое поведение, конкретную проблему или ошибку и кратчайший код, необходимый для их воспроизведения в самом вопросе ...»

Я создал репозиторий GitHub, связанный ниже с двумя моими неудачными попытками BiCGStab (с ошибками, исходящими от функций * _analysis cuSparse). Поскольку этого недостаточно, я удалил все, что происходит после ошибок, и включил здесь код. Поскольку NVidia не предоставляет никаких привязок CUDA fortran-to-c (написанных на fortran), этот пример должен включать интерфейсный модуль.

Желаемое поведение: отсутствие возврата CUSPARSE_INTERNAL_ERROR из процедур анализа cuSparse, чтобы я мог реализовать BiCGStab в fortran.

Конкретная ошибка: CUSPARSE_INTERNAL_ERROR, при запуске с cuda-memcheck этот упрощенный пример возвращает вторую ошибку, опубликованную ниже (32 экземпляра чтения размера 4 в convert_CsrToCoo находятся за пределами границ)

!
! CUDA 
!
module cuda_cusolve_map_reduced

 interface

 ! cudaMemset
 integer (c_int) function cudaMemset( devPtr,value, count ) &
                              bind (C, name = "cudaMemset" ) 
   use iso_c_binding
   implicit none
   type (c_ptr),value  :: devPtr
   integer(c_int), value :: value
   integer(c_size_t), value :: count
 end function cudaMemset
 ! cudaMalloc
 integer (c_int) function cudaMalloc ( buffer, size ) &
                              bind (C, name = "cudaMalloc" ) 
   use iso_c_binding
   implicit none
   type (c_ptr)  :: buffer
   integer (c_size_t), value :: size
 end function cudaMalloc

 integer (c_int) function cudaMemcpy ( dst, src, count, kind ) &
                              bind (C, name = "cudaMemcpy" )
   ! note: cudaMemcpyHostToDevice = 1
   ! note: cudaMemcpyDeviceToHost = 2
   ! note: cudaMemcpyDeviceToDevice = 3
   use iso_c_binding
   type (c_ptr), value :: dst, src
   integer (c_size_t), value :: count, kind
 end function cudaMemcpy

 ! cudaFree
 integer (c_int) function cudaFree(buffer)  bind(C, name = "cudaFree")
   use iso_c_binding
   implicit none
   type (c_ptr), value :: buffer
 end function cudaFree

 integer (c_int) function cudaMemGetInfo(fre, tot) &
                              bind(C, name = "cudaMemGetInfo")
   use iso_c_binding
   implicit none
   type(c_ptr),value :: fre
   type(c_ptr),value :: tot
 end function cudaMemGetInfo

 integer(c_int) function cusparseCreate(cusparseHandle) &
                             bind(C,name = "cusparseCreate")

   use iso_c_binding
   implicit none
   type(c_ptr)::cusparseHandle
   end function cusparseCreate

 integer(c_int) function cudaStreamCreate(stream) &
                             bind(C,name = "cudaStreamCreate")

 use iso_c_binding
 implicit none
 type(c_ptr)::stream
 end function cudaStreamCreate

 integer(c_int) function cusolverSpSetStream(handle,stream) &
                             bind(C,name = "cusolverSpSetStream")

 use iso_c_binding
 implicit none
 type(c_ptr),value :: handle
 type(c_ptr),value :: stream
 end function cusolverSpSetStream

 integer(c_int) function cusparseSetStream(cusparseHandle,stream) &
                             bind(C,name = "cusparseSetStream")

 use iso_c_binding
 implicit none
 type(c_ptr),value :: cusparseHandle
 type(c_ptr),value :: stream
 end function cusparseSetStream

 integer(c_int) function cusparseCreateMatDescr(descrA) &
                             bind(C,name = "cusparseCreateMatDescr")

 use iso_c_binding
 implicit none
 type(c_ptr):: descrA
 end function cusparseCreateMatDescr


 integer(c_int) function cusparseSetMatType2(descrA,CUSPARSE_MATRIX_TYPE) &
                             bind(C,name = "cusparseSetMatType")

 use iso_c_binding
 implicit none
 type(c_ptr), value:: descrA
 integer(c_int),value :: CUSPARSE_MATRIX_TYPE
 end function cusparseSetMatType2

 integer(c_int) function cusparseSetMatIndexBase2(descrA,CUSPARSE_INDEX_BASE) &
                             bind(C,name = "cusparseSetMatIndexBase")

 use iso_c_binding
 implicit none
 type(c_ptr), value:: descrA
 integer(c_int),value :: CUSPARSE_INDEX_BASE
 end function cusparseSetMatIndexBase2

 integer(c_int) function cusparseSetMatFillMode(descrA,CUSPARSE_FILL_TYPE) &
                 bind(C,name = "cusparseSetMatFillMode")

 use iso_c_binding
 implicit none
 type(c_ptr), value:: descrA
 integer(c_int),value :: CUSPARSE_FILL_TYPE
 end function cusparseSetMatFillMode

 integer(c_int) function cusparseSetMatDiagType(descrA,CUSPARSE_DIAG_TYPE) &
                 bind(C,name = "cusparseSetMatDiagType")

 use iso_c_binding
 implicit none
 type(c_ptr), value:: descrA
 integer(c_int),value :: CUSPARSE_DIAG_TYPE
 end function cusparseSetMatDiagType


 integer(c_int) function cudaDeviceSynchronize() bind(C,name = "cudaDeviceSynchronize")

 use iso_c_binding
 implicit none
 end function cudaDeviceSynchronize


 integer(c_int) function cusparseDestroy(cusparseHandle) bind(C,name = "cusparseDestroy")

 use iso_c_binding
 implicit none
 type(c_ptr),value::cusparseHandle
 end function cusparseDestroy

 integer(c_int) function cudaStreamDestroy(stream) bind(C,name = "cudaStreamDestroy")

 use iso_c_binding
 implicit none
 type(c_ptr),value :: stream
 end function cudaStreamDestroy

 integer(c_int) function cusparseDestroyMatDescr(descrA) bind(C,name = "cusparseDestroyMatDescr")

 use iso_c_binding
 implicit none
 type(c_ptr), value:: descrA
 end function cusparseDestroyMatDescr

 integer(c_int) function cusparseCreateSolveAnalysisInfo(info) &
               bind(C,name = "cusparseCreateSolveAnalysisInfo")

 use iso_c_binding
 implicit none
 type(c_ptr) :: info
 end function cusparseCreateSolveAnalysisInfo

 integer(c_int) function cusparseDcsrsv_analysis(handle,transA, &
                 m,nnz,descrA,csrValA,csrRowPtrA,csrColIndA,info) &
                 bind(C,name = "cusparseDcsrsv_analysis")

 use iso_c_binding
 implicit none
 type(c_ptr), value :: handle
 integer(c_int), value :: transA
 integer(c_int), value :: m
 integer(c_int),value :: nnz
 type(c_ptr), value :: descrA
 type(c_ptr) :: csrValA
 type(c_ptr) :: csrRowPtrA
 type(c_ptr) :: csrColIndA
 type(c_ptr), value :: info
 end function cusparseDcsrsv_analysis

 integer(c_int) function cusparseDestroySolveAnalysisInfo(info) &
                 bind(C,name = "cusparseDestroySolveAnalysisInfo")

 use iso_c_binding
 implicit none
 type(c_ptr),value::info
 end function cusparseDestroySolveAnalysisInfo

 end interface  

end module cuda_cusolve_map_reduced
!
!======================================================================
!======================================================================
  program main
   implicit none
   integer n,inz,i
   parameter (n=5)
   parameter (inz=13)
   double precision x(n),x_known(n),rhs(n),b(inz)
   integer ib(n+1),jb(inz)

   write(*,'(A)') 'Setting up test system'
   b(1) = 1.0d0;b(2) = 1.0d0;b(3) = 5.0d0;b(4) = 2.0d0
   b(5) = 1.0d0;b(6) = 3.0d0;b(7) = 2.0d0;b(8) = 1.0d0
   b(9) = 6.0d0;b(10) = 3.0d0;b(11) = 1.0d0;b(12) = 2.0d0
   b(13) = 1.0d0
   rhs(1) = 1.0d0;rhs(2) = 2.0d0;rhs(3) = 1.0d0
   rhs(4) = 3.0d0;rhs(5) = 0.0d0

   ib(1) = 1;ib(2) = 5;ib(3) = 7
   ib(4) = 9;ib(5) = 12;ib(6) = 14

   jb(1) = 1;jb(2) = 2;jb(3) = 4;jb(4) = 5
   jb(5) = 2;jb(6) = 3;jb(7) = 2;jb(8) = 3
   jb(9) = 1;jb(10) = 3;jb(11) = 4;jb(12) = 4
   jb(13) = 5

   x_known(1) = 0.08d0;x_known(2) = 0.2d0;x_known(3) = 0.6d0
   x_known(4) = 0.72d0;x_known(5) = -1.44d0
   x(1)=1.0d0;x(2)=1.0d0;x(3)=1.0d0
   x(4)=1.0d0;x(5)=1.0d0


  write(*,'(A)') 'Starting iterative solve'
  call cuda_BiCGStab_error(n,rhs,x,inz,ib,jb,b)
  write(*,'(A)') 'Found and Known solutions'
  do 23 i = 1,n
     write(*,*) x(i),x_known(i)
23  continue

  end program main
!
!=========================================================
subroutine cuda_BiCGStab_error(n,rhs,x,inz,ib,jb,b)
!=========================================================
use iso_c_binding
use cuda_cusolve_map_reduced
implicit none
integer n, inz
double precision x(n), rhs(n), b(inz)
target rhs,b,x
integer ib(n+1),jb(inz)
target ib,jb
integer ii,ierr,ierr2

integer, parameter :: dp = kind(1.d0)

type(c_ptr) :: cusparseHandle
type(c_ptr) :: stream
type(c_ptr) :: descrA
type(c_ptr) :: descrM
type(c_ptr) :: info_l
type(c_ptr) :: info_u
type(c_ptr) :: ArowsIndex
type(c_ptr) :: AcolsIndex
type(c_ptr) :: Aval
type(c_ptr) :: h_x  
type(c_ptr) :: h_rhs

! -------------------- pointers to device memory    
type(c_ptr) :: devPtrArowsIndex
type(c_ptr) :: devPtrAcolsIndex
type(c_ptr) :: devPtrAval
type(c_ptr) :: devPtrMrowsIndex
type(c_ptr) :: devPtrMcolsIndex
type(c_ptr) :: devPtrMval
type(c_ptr) :: devPtrX
type(c_ptr) :: devPtrF

integer*8 Arow1_i_size,Arow_d_size,Acol_d_size,Annz_i_size,Annz_d_size

integer*8 cudaMemcpyDeviceToHost, cudaMemcpyHostToDevice, cudaMemcpyDeviceToDevice
integer*4 CUBLAS_OP_N, CUBLAS_OP_T, CUBLAS_OP_TRI
parameter (cudaMemcpyHostToDevice=1)
parameter (cudaMemcpyDeviceToHost=2)
parameter (cudaMemcpyDeviceToDevice=3)
parameter (CUBLAS_OP_N=0)
parameter (CUBLAS_OP_T=1)
parameter (CUBLAS_OP_TRI=3)

ierr2 = 0

! define pointers to host memory
ArowsIndex = c_loc(ib)
AcolsIndex = c_loc(jb)
Aval = c_loc(b)
h_x  = c_loc(x)  ! x = A \ b
h_rhs  = c_loc(rhs)  ! b = ones(m,1)

Arow1_i_size=sizeof(ib(1:n+1))
Arow_d_size=sizeof(rhs(1:n))
Acol_d_size=sizeof(x(1:n))
Annz_i_size=sizeof(jb(1:inz))
Annz_d_size=sizeof(b(1:inz))

! Define the CUDA stream and matrix parameters
ierr = cusparseCreate(cusparseHandle)
ierr2 = ierr2 + ierr
ierr = cusparseCreateMatDescr(descrA)
ierr2 = ierr2 + ierr
ierr = cusparseCreateMatDescr(descrM)
ierr2 = ierr2 + ierr
ierr = cudaStreamCreate(stream) 
ierr2 = ierr2 + ierr
ierr = cusparseSetStream(cusparseHandle,stream) 
ierr2 = ierr2 + ierr
ierr = cusparseSetMatType2(descrA,CUBLAS_OP_N) 
ierr2 = ierr2 + ierr
ierr = cusparseSetMatIndexBase2(descrA,CUBLAS_OP_T) 
ierr2 = ierr2 + ierr
ierr = cusparseSetMatType2(descrM,CUBLAS_OP_N) 
ierr2 = ierr2 + ierr
ierr = cusparseSetMatIndexBase2(descrM,CUBLAS_OP_T) 
ierr2 = ierr2 + ierr
if (ierr2.ne.0) then
  write(*,'(A, I2)') 'Error during matrix setup ',ierr2
  stop
end if 
write(*,*) 'Allocating GPU memory'
ierr = cudaMalloc(devPtrX,Arow_d_size)
ierr2 = ierr2 + ierr
ierr = cudaMalloc(devPtrF,Arow_d_size)
ierr2 = ierr2 + ierr
ierr = cudaMalloc(devPtrAval,Annz_d_size)
ierr2 = ierr2 + ierr
ierr = cudaMalloc(devPtrAcolsIndex,Annz_i_size)
ierr2 = ierr2 + ierr
ierr = cudaMalloc(devPtrArowsIndex,Arow1_i_size)
ierr2 = ierr2 + ierr
ierr = cudaMalloc(devPtrMval,Annz_d_size)
ierr2 = ierr2 + ierr
ierr = cudaDeviceSynchronize()
ierr2 = ierr2 + ierr
if (ierr2.ne.0) then
  write(*,'(A, I2)') 'Error during CUDA allocation: ',ierr2
  stop
end if 
write(*,*) 'Cleaning GPU memory'
ierr = cudaMemset(devPtrX,0,Arow_d_size)
ierr2 = ierr2 + ierr
ierr = cudaMemset(devPtrF,0,Arow_d_size)
ierr2 = ierr2 + ierr
ierr = cudaMemset(devPtrAval,0,Annz_d_size)
ierr2 = ierr2 + ierr
ierr = cudaMemset(devPtrAcolsIndex,0,Annz_i_size)
ierr2 = ierr2 + ierr
ierr = cudaMemset(devPtrArowsIndex,0,Arow1_i_size)
ierr2 = ierr2 + ierr
ierr = cudaMemset(devPtrMval,0,Annz_d_size)
ierr2 = ierr2 + ierr
ierr = cudaDeviceSynchronize()
ierr2 = ierr2 + ierr
if (ierr2.ne.0) then
  write(*,'(A, I3)') 'Error during CUDA memory cleaning : ',ierr2
  stop
end if 

! transfer memory over to GPU
write(*,*) 'Transferring memory to GPU'
ierr = cudaMemcpy(devPtrArowsIndex,ArowsIndex,Arow1_i_size,cudaMemcpyHostToDevice)
ierr2 = ierr2 + ierr
ierr = cudaMemcpy(devPtrAcolsIndex,AcolsIndex,Annz_i_size,cudaMemcpyHostToDevice)
ierr2 = ierr2 + ierr
ierr = cudaMemcpy(devPtrAval,Aval,Annz_d_size,cudaMemcpyHostToDevice)
ierr2 = ierr2 + ierr
ierr = cudaMemcpy(devPtrMval,devPtrAval,Annz_d_size,cudaMemcpyDeviceToDevice)
ierr2 = ierr2 + ierr
ierr = cudaMemcpy(devPtrX,h_x,Arow_d_size,cudaMemcpyHostToDevice)
ierr2 = ierr2 + ierr
ierr = cudaMemcpy(devPtrF,h_rhs,Arow_d_size,cudaMemcpyHostToDevice)
ierr2 = ierr2 + ierr
ierr = cudaDeviceSynchronize()
ierr2 = ierr2 + ierr
if (ierr2 .ne. 0 ) then
    write (*, '(A, I2)') " Error during cuda memcpy ", ierr2
    stop
end if

write(*,*) 'Creating analysis for LU'
ierr = cusparseCreateSolveAnalysisInfo(info_l)
ierr2 = ierr2 + ierr
ierr = cusparseCreateSolveAnalysisInfo(info_u)
ierr2 = ierr2 + ierr
if (ierr2 .ne. 0 ) then
    write (*, '(A, I2)') " Error during LU analysis creation ", ierr2
    stop
end if

write(*,*) 'Analyzing L of LU'
ierr = cusparseSetMatFillMode(descrM,CUBLAS_OP_N)
ierr2 = ierr2 + ierr
ierr = cusparseSetMatDiagType(descrM,CUBLAS_OP_T)
ierr2 = ierr2 + ierr
ierr = cudaDeviceSynchronize()
ierr2 = ierr2 + ierr
ierr = cusparseDcsrsv_analysis(cusparseHandle,CUBLAS_OP_N,n,inz,descrM,devPtrAval,&
                               devPtrArowsIndex,devPtrAcolsIndex,info_l)
ierr2 = ierr2 + ierr
if (ierr2 .ne. 0 ) then
    write (*, '(A, I2)') " Error during L of LU analyzing sub2 ", ierr2
    stop
end if
ierr = cudaDeviceSynchronize()
ierr2 = ierr2 + ierr
if (ierr2 .ne. 0 ) then
    write (*, '(A, I2)') " Error during L of LU analyzing ", ierr2
    stop
end if

ierr = cudaFree(devPtrArowsIndex)
ierr2 = ierr2 + ierr
ierr = cudaFree(devPtrAcolsIndex)
ierr2 = ierr2 + ierr
ierr = cudaFree(devPtrAval)
ierr2 = ierr2 + ierr
ierr = cudaFree(devPtrMrowsIndex)
ierr2 = ierr2 + ierr
ierr = cudaFree(devPtrMcolsIndex)
ierr2 = ierr2 + ierr
ierr = cudaFree(devPtrMval)
ierr2 = ierr2 + ierr
ierr = cudaFree(devPtrX)
ierr2 = ierr2 + ierr
ierr = cudaFree(devPtrF)
ierr2 = ierr2 + ierr
if (ierr2.ne.0) then
  write(*,'(A, I2)') 'Error during cudafree: ',ierr2
  stop
end if 

ierr = cusparseDestroy(cusparseHandle)
ierr2 = ierr2 + ierr
ierr = cudaStreamDestroy(stream)
ierr2 = ierr2 + ierr
ierr = cusparseDestroyMatDescr(descrA)
ierr2 = ierr2 + ierr
ierr = cusparseDestroyMatDescr(descrM)
ierr2 = ierr2 + ierr
ierr = cusparseDestroySolveAnalysisInfo(info_l)
ierr2 = ierr2 + ierr
ierr = cusparseDestroySolveAnalysisInfo(info_u)
ierr2 = ierr2 + ierr
if (ierr2.ne.0) then
  write(*,'(A, I2)') 'Error during cuda handle destruction: ',ierr2
  stop
end if 

return
end subroutine cuda_BiCGStab_error

КОНЕЦ РЕДАКТИРОВАНИЯ

Я пытаюсь добавить реализацию CUDA метода решателя BiCGStab в устаревший код Fortran 77 с дополнительным усложнением, заключающимся в ограничении использования только компилятора Fortran (интерфейс для функций CUDA должен быть в Fortran, а не c / C++). Последнее ограничение оказалось дополнительным осложнением и, вероятно, источником моих проблем, но мой руководитель проекта не уступает по этому запросу. Мне комфортно с Фортраном, но, по сути, я новичок в CUDA, поэтому меня нисколько не удивит, если я пропустил незначительную деталь или у меня есть фундаментальное недоразумение.

Все мои тесты проводились с помощью CUDA 9.1 Toolkit, iFort 17.0.4.196 и графического процессора Tesla P4.

После успешной реализации метода прямого решения с использованием QR-разложения (по сути, перевода образца CUDA cuSolverSp_LinearSolver.cpp в fortran) я столкнулся с проблемами при попытке реализовать итеративный метод BiCGStab (фактически перевод образца CUDA pbicgstab.cpp) . Моя первая попытка BiCGStab исходит непосредственно из примера (с использованием прекондиционера cusparseDcsrilu0), а вторая, предназначенная для проверки работоспособности первой, использует подпрограммы предварительной обработки cusparseDcsrilu02 схемы домино.

В обоих случаях BiCGStab фазы анализа (cusparseDcsrsv_analysis для первой попытки и cusparseDcsrilu02_analysis для второй попытки) возвращают флаг CUSPARSE_INTERNAL_ERRROR, который мне не удалось устранить.

Я сделал Репозиторий GitHub с необходимыми файлами, чтобы сформировать минимальный тестовый пример как методов BiCGStab, так и метода решателя QR с использованием матрицы 5x5 с 13 ненулевыми значениями и известного решения. QR работает, методы BiCGStab - нет.

Запуск cuda-memcheck со второй попыткой BiCGStab (cuda_BiCGStab2) приводит к:

========= Program hit cudaErrorInvalidValue (error 11) due to "invalid argument" on CUDA API call to cudaMemsetAsync.
=========     Saved host backtrace up to driver entry point at error
=========     Host Frame:/usr/lib64/nvidia/libcuda.so.1 [0x332863]
=========     Host Frame:/usr/local/cuda-9.1/targets/x86_64-linux/lib/libcusparse.so.9.1 [0x37f511]
=========     Host Frame:/usr/local/cuda-9.1/targets/x86_64-linux/lib/libcusparse.so.9.1 [0x29b7fd]
=========     Host Frame:test_cuda [0x68e9]
=========     Host Frame:test_cuda [0x3334]
=========     Host Frame:test_cuda [0x1f3e]
=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xfd) [0x1ed1d]
=========     Host Frame:test_cuda [0x1e49]
========= 
  Error during csrilu02_analysis  7
========= ERROR SUMMARY: 1 error

при запуске cuda-memcheck при первой попытке BiCGStab (cuda_BiCGStab) приводит к 32 (увеличивающимся идентификаторам потоков) экземплярам

========= Invalid __global__ read of size 4
=========     at 0x00000070 in void convert_CsrToCoo_kernel<int=1>(int const *, int, int, int*)
=========     by thread (0,0,0) in block (0,0,0)
=========     Address 0x0061e990 is out of bounds
=========     Saved host backtrace up to driver entry point at kernel launch time
=========     Host Frame:/usr/lib64/nvidia/libcuda.so.1 (cuLaunchKernel + 0x2cd) [0x23c06d]
=========     Host Frame:/usr/local/cuda-9.1/targets/x86_64-linux/lib/libcusparse.so.9.1 [0x34dabb]
=========     Host Frame:/usr/local/cuda-9.1/targets/x86_64-linux/lib/libcusparse.so.9.1 [0x36ad0e]
=========     Host Frame:/usr/local/cuda-9.1/targets/x86_64-linux/lib/libcusparse.so.9.1 [0x2f3339]
=========     Host Frame:/usr/local/cuda-9.1/targets/x86_64-linux/lib/libcusparse.so.9.1 (cusparseXcsr2coo + 0x1fd) [0x2f355d]
=========     Host Frame:/usr/local/cuda-9.1/targets/x86_64-linux/lib/libcusparse.so.9.1 [0x2fa027]
=========     Host Frame:/usr/local/cuda-9.1/targets/x86_64-linux/lib/libcusparse.so.9.1 [0xc4fa4]
=========     Host Frame:test_cuda [0xc9c0]
=========     Host Frame:test_cuda [0x2d6f]
=========     Host Frame:test_cuda [0x1f3e]
=========     Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xfd) [0x1ed1d]
=========     Host Frame:test_cuda [0x1e49]
=========
 Error during L of LU analyzing sub2  2
========= ERROR SUMMARY: 32 errors

Последняя строка, «Ошибка во время ...», исходит из моего кода и печатает целое число, возвращаемое функцией CUDA. Без cuda-memcheck оба метода BiCGStab возвращают значение 7, которое я интерпретировал как CUSPARSE_INTERNAL_ERROR, однако первая попытка BiCGStab возвращает 2 при запуске с cuda-memcheck.

Любая помощь в разрешении этой ошибки cusparse_internal_error или, откровенно говоря, просто советы по диагностике, будет принята с благодарностью.

TL / DR: застрял в диагностике CUSPARSE_INTERNAL_ERROR из реализованных fortran методов BiCGStab с использованием подпрограмм cuSparse через интерфейс fortran. Internal_error исходит от подпрограмм * _analysis в библиотеке cuSparse. Возможно, я пропустил что-то маленькое или у меня есть фундаментальное недопонимание Любой ввод / помощь приветствуются.

Выход cuda-memcheck полезен. Оба этих вывода предполагают ошибки использования API. В частности, я бы поискал случай, когда API ожидает указатель устройства, а вы передаете указатель хоста. Перевод API fortran-to-C также является частым источником ошибок, если вы, возможно, указали неправильный тип в одном из ваших интерфейсов. Если вы указали неправильный тип в аргументе указателя и эффективно передали указатель нежелательной почты, это также может привести к этому типу вывода cuda-memcheck.

Robert Crovella 02.05.2018 00:31

Ура, Роберт, я еще раз прочесываю документы fortran-to-c и CUDA; Я определенно продвигался через это быстрее с помощью более поздних функций. Помимо несоответствия типов, требуют ли указатели информационной структуры (из функций анализа) какой-либо специальной обработки помимо обычных указателей?

Guy P. 02.05.2018 03:52

Ваш код не компилируется. Атрибут target для ваших аргументов требует явного интерфейса (лучше всего использовать модуль). Это можно исправить, переместив за contains основной программы.

Vladimir F 03.05.2018 14:15

Спасибо за ответ Владимир. Меня не удивляет, что я мог что-то сделать с целями неправильно (я привык к f77), но я могу скомпилировать приведенный выше код как с ifort (17.0.4.196), так и с gfortran (4.4.7-18) без ошибки или предупреждения (используя <compiler> -ldl -mcmodel = medium -g min_test.f90 -I / usr / local / cuda / include -L / usr / local / cuda / lib64 -lcudart -lcusolver -lcusparse -lcublas -lm) и дает ту же ошибку CUDA. Устаревший код, который я в конечном итоге буду использовать, - это все f77, можно ли определить интерфейс только в файле f90, в котором находится подпрограмма решателя?

Guy P. 03.05.2018 15:56

gfortran 4.8 (правильно ИМХО) сообщает об ошибке, которую идентифицировал @VladimirF, и мне пришлось исправить ряд проблем в этом коде, чтобы заставить его скомпилировать, запустить и воспроизвести проблему

talonmies 03.05.2018 16:48
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
5
406
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Да, в вашем оригинальном репро-кейсе 2000+ LOC в конце ссылки на github есть ошибка в определении интерфейса для cusparseDcsrsv_analysis. Так должно быть

 integer(c_int) function cusparseDcsrsv_analysis(handle,transA, &
                 m,nnz,descrA,csrValA,csrRowPtrA,csrColIndA,info) &
                 bind(C,name = "cusparseDcsrsv_analysis")

  use iso_c_binding
  implicit none
  type(c_ptr), value :: handle
  integer(c_int), value :: transA
  integer(c_int), value :: m
  integer(c_int),value :: nnz
  type(c_ptr), value :: descrA
  type(c_ptr), value :: csrValA
  type(c_ptr), value :: csrRowPtrA
  type(c_ptr), value :: csrColIndA
  type(c_ptr), value :: info
 end function cusparseDcsrsv_analysis

то есть указатели устройств требуют, чтобы атрибут value был правильно передан в подпрограмму C.

Возможно, вы допустили эту ошибку где-то еще, и могут быть другие проблемы в другом месте вашей кодовой базы, но после исправления явных ошибок в MCVE, которые вы редактировали в своем вопросе, я мог бы получить модифицированную версию этого варианта воспроизведения для правильной работы.

Спасибо, таланты, похоже, это решает все мои проблемы (исправление Dcsrsv_analysis и последующее распространение утверждений о пропущенных значениях в более поздние функции). Оглядываясь назад, я не могу поверить, что смотрел на это, пока не видел недостающих атрибутов.

Guy P. 03.05.2018 17:10

Другие вопросы по теме