デバイスからホストにデータをコピーするときに問題が発生します。私のデータは、構造体に配置されている:デバイスからホストにデータをコピーするときに無効な引数エラーが発生する
typedef struct Array2D {
double* arr;
int rows;
int cols;
} Array2D;
arr
は「フラット」配列です。 rows
およびcols
は寸法を記載する。
次のコードは、私が戻ってホストにデータをコピーしようとしています方法を示しています。
h_output = (Array2D*) malloc(sizeof(Array2D));
cudaMemcpy(h_output, d_output, sizeof(Array2D), cudaMemcpyDeviceToHost);
double* h_arr = (double*) malloc(h_output->cols*h_output->rows*sizeof(double));
cudaMemcpy(h_arr, h_output->arr, h_output->cols*h_output->rows*sizeof(double), cudaMemcpyDeviceToHost);
h_output->arr = h_arr;
はしかし、4行目の実行は、CUDAエラー11(無効な引数)で失敗します。なぜこれが起こっているのか分かりません。配列のサイズは正しいので、ホストからh_output
とh_array
の両方にアクセスすることができ、どちらも '本当の'アドレスを持っています。
EDIT 詳細(=複数のコード)の要求に遅れて応答するため申し訳ありません。
私は、ホスト上のデバイスポインタの値にアクセスしようとすると、ポインタd_output->arr
がデバイスポインタであることをテストしました。予想どおり、d_output->arr
が実際には有効なデバイスポインタであるという考えで私を去らせることは許されませんでした。
コードの目的は、4次のルンゲクッタ法を使用してチエールの微分方程式を解くことです。
EDIT2
class CalculationSpecification
{
/* FUNCTIONS OMITTED */
public:
__device__ void RK4_n(CalculationSpecification* cs, CalcData data, Array2D* d_output)
{
double* rk4data = (double*)malloc((data.pdata->endYear - data.pdata->startYear + 1)*data.pdata->states*sizeof(double));
/* CALCULATION STUFF HAPPENS HERE */
// We know that rows = 51, cols = 1 and that rk4data contains 51 values as it should.
// This was confirmed by using printf directly in this function.
d_output->arr = rk4data;
d_output->rows = data.pdata->endYear - data.pdata->startYear + 1;
d_output->cols = data.pdata->states;
}
};
class PureEndowment : CalculationSpecification
{
/* FUNCTIONS OMITTED */
public:
__device__ void Compute(Array2D *result, CalcData data)
{
RK4_n(this, data, result);
}
};
__global__ void kernel2(Array2D *d_output)
{
/* Other code that initializes 'cd'. */
PureEndowment pe;
pe.Compute(d_output,cd);
}
void prepareOutputSet(Array2D* h_output, Array2D* d_output, int count)
{
h_output = (Array2D*) malloc(sizeof(Array2D));
cudaMemcpy(h_output, d_output, sizeof(Array2D), cudaMemcpyDeviceToHost); // After this call I can read the correct values of row, col as well as the address of the pointer.
double* h_arr = (double*) malloc(h_output->cols*h_output->rows*sizeof(double));
cudaMemcpy(h_arr, h_output->arr, h_output->cols*h_output->rows*sizeof(double), cudaMemcpyDeviceToHost)
h_output->arr = h_arr;
}
int main()
{
Array2D *h_output, *d_output;
cudaMalloc((void**)&d_output, sizeof(Array2D));
kernel2<<<1,1>>>(d_output);
cudaDeviceSynchronize();
prepareOutputSet(h_output, d_output, 1);
getchar();
return 0;
}
はまた、私は今、デバイス上で実行されている
d_output->arr
の値が
prepareOutputSet
の最初の
cudaMemcpy
-call後
h_output->arr
の値と同一であることをテストしています。
エラーの原因としては、 'houtput-> arr'が有効なデバイスポインタではないことが考えられます。 'd_output'の内容をデバイスにどのように割り当ててコピーするかを示すためにコードを少し拡張できますか? – talonmies
'd_output'とその内容は' malloc() 'を使ってデバイス上に割り当てられます。 'd_output-> arr'の内容を出力しようとしたときに実際のデータが入っていると確信して、期待される出力を得ました。 – ssnielsen
'h_output' _とその内容を意味しますか? 'd_output'はあなたのサンプルコードには表示されないからです。 – pQB