GPUを使用してガウスの直交数値積分を使用して積分を計算するプログラムを作成しようとしました。私はこのプログラムがなぜ機能していないのか理解しようとしています。私は関数呼び出しd_oneで渡されたパラメータがcudaのcコードに正しくコピーされていないという事実に固定していると思います。なぜこれが起こっているのか分かりません。私はそれを理解しようと多くの時間を費やしましたが、どこでもそれを得ることができませんでした。プログラムの出力は12.49999でなければなりません変数が誤ってFortranからcuda cプログラムにコピーされました
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cuda.h>
#include <cuda_runtime.h>
__global__ void loop_d(float *a, float *b, int N, float *ans)
{
__shared__ float temp[66];
int idx = threadIdx.x;
if (idx < 66)
{
temp[idx] = a[idx] * b[idx];
}
__syncthreads();
if (0 == idx)
{
float sum = 0.0;
for (int i=0; i < 66; i++)
{
sum += temp[i];
}
*ans = sum;
}
}
// The following function is called from the Fortran program
extern "C" void d_one_(float *a, float *b, int *Np, float *ans)
{
float *a_d, *b_d, *ans_d; // Declaring GPU Copies of the parameters passed
int blocks = 1; // Number of blocks used
int N = *Np; // Number of threads is determined by the parameter nptx passed from the Fortran program
// Allocating GPU memory
cudaMalloc((void **)&a_d, sizeof(float) * N);
cudaMalloc((void **)&b_d, sizeof(float) * N);
cudaMalloc((void **)&ans_d, sizeof(float));
// Copying information from CPU to GPU
cudaMemcpy(a_d, a, sizeof(float) * N, cudaMemcpyHostToDevice);
cudaMemcpy(b_d, b, sizeof(float) * N, cudaMemcpyHostToDevice);
cudaMemcpy(ans_d, ans, sizeof(float), cudaMemcpyHostToDevice);
// Calling the function on the GPU
loop_d<<< blocks, N >>>(a_d, b_d, N, ans_d);
cudaMemcpy(a, a_d, sizeof(float) * N, cudaMemcpyDeviceToHost);
cudaMemcpy(b, b_d, sizeof(float) * N, cudaMemcpyDeviceToHost);
cudaMemcpy(ans, ans_d, sizeof(float), cudaMemcpyDeviceToHost);
// Freeing GPU memory
cudaFree(a_d);
cudaFree(b_d);
cudaFree(ans_d);
return;
}
:
のFortranプログラム:
implicit real*8(a-h,o-z)
parameter (nlinx = 22) ! Total number of mesh regions
dimension sx(3*nlinx),swx(3*nlinx)
xa = 0.d0
xb = 5.d0
! In the following "nptx" is the total number of integration
! points. So, it is (nlinx * 3)
call meshwt1(xa,xb,nlinx,ntan,sx,swx,nptx)
ans0 = 0.d0
CAll d_one(sx, swx, nptx, ans0)
print *, ans0
stop
end
SUBROUTINE MESHWT1(A,B,N,NT,X,W,NTOT)
implicit real*8(a-h,o-z)
!3*N LINEAR POINTS FOR A TO B
!NT=0 OR 1, 3*NT TAN PTS FOR B TO INFINITY
!NTOT= 3*(N+NT)
DIMENSION X(*),W(*),G(3),GW(3)
G(1) = -0.7745966
G(2) = 0.0000000
G(3) = -G(1)
GW(2) = 0.8888888
GW(1) = 0.5555555
GW(3) = GW(1)
Y = N
DX = (B - A)/Y
K = 0
XA = A - DX
XB = A
DO 2 I = 1, N
XA = XA + DX
XB = XB + DX
DO 2 J = 1, 3
K = K + 1
X(K) = 0.5 * (XA + XB) + 0.5 * (XB - XA) * G(J)
2 W(K) = 0.5 * (XB - XA) * GW(J)
NTOT = K
IF(NT .EQ. 1) GO TO 3
GO TO 5
3 NTOT = K + 3
DO 4 J = 1, 3
K = K + 1
Y = (1.0 + G(J)) * 3.14159 * 0.25
X(K) = XB + DTAN(Y)
4 W(K) = GW(J) * 3.14159 * 0.25/(DCOS(Y)) ** 2
5 CONTINUE
RETURN
END
CUDAプログラムここで
2つのプログラムです。私は-314の順番で答えを得ています。あなたが提供していただきありがとうございます!
21世紀の暗黙のタイピングを使っている人は誰でも、ターンパイクを下ろしてくる苦痛に遭遇するでしょう。おそらくあなたが報告したエラーの原因ではありませんが、それがエラーの原因である可能性を排除するためにプログラムを修正するのは数秒です。 –
はHPMと完全に同意します。 FORTRANが好きなのは、どのコードも 'IMPLICIT NONE'で始まるからです。 Imhoは一般的にコーディングのための最高のモットーです。 – user463035818
少なくとも、明示的な 'implicit'ステートメントを使っています。これは、' real * 8'変数を 'float'に渡そうとしていることを明らかにしていません。 – tera