0

問題の原因を突き止めることはできません。最後の行に「アクセス違反の書き込み場所」エラーが表示されます。メモリを正しく割り当てていないのですか?CUDA:ポインタメモリアクセスへのポインタ

typedef struct { 
    doubleXYZW cen_sum; //struct with 4 doubles 
    double STS[6]; 
    XYZW *Points;// //struct with 4 floats 
}BUNDLE; 

BUNDLE *cpu_data = NULL; 
size_t bundle_size = NUM_POINTS * sizeof(XYZW) + sizeof(doubleXYZW) + 6*sizeof(double); 
HANDLE_ERROR(cudaMallocHost((BUNDLE**)&cpu_data, bundle_size)); 
//error in the next line 
cpu_data->Points[0].x = 0; //x is the first element in the XYZW struct 

答えて

2

2つの割り当てを行う必要があり、そのうちの1つだけを実行しています。

cpu_dataポインター用にいくつかのストレージを割り当てていますが、Pointsポインターのストレージを割り当てていません。したがって、参照を解除するときにポイント:

cpu_data->Points[0].x = 0; 
     ^ ^
     |  this dereferences the Points pointer (NOT allocated!) 
     | 
     this dereferences the cpu_data pointer (allocated) 

あなたは割り当てられていないポインタを逆参照しているので無効です。そのような方法で何かにアクセスしようとすると、無効なアクセスが生成されます。

次の2つのオプション(少なくとも)それを修正する必要があります。

  1. をあなたはcpu_pointsのためのスペースを割り当てた後、あなたがPointsの大きさを知っていればあなたはcpu_points->Points
  2. に別のcudaMallocHost配分を行うことができます配列は、(あなたが行うように思える - NUM_POINTSを)その後、あなただけの静的にそれを割り当てることができます:

    typedef struct { 
    doubleXYZW cen_sum; //struct with 4 doubles 
    double STS[6]; 
    XYZW Points[NUM_POINTS];// //struct with 4 floats 
    }BUNDLE; 
    

bundle_sizeの計算は、2番目の方法が提案されているように計算されています。最初の方法を使用すると、bundle_sizeの計算が正しく行われません。いずれにせよ、いずれの方法でもbundle_sizesizeof(BUNDLE)と計算するほうが簡単です。

明確にするために、ここにはCUDA固有のものはありません(たとえば、cudaMallocHostの代わりにmallocを使用した場合はエラーが発生します)。この問題は、CUDAではなくCの基本的な理解に根ざしています。

+0

詳細レッスンありがとうございます。それは理にかなっている。私は明らかに、Cでこのレベルの複雑さを実装していないので、CUDAと遭遇しました。あなたが提案したように、2番目のオプションはうまくいき、割り当て時間も節約されるでしょう。 – Nenu

関連する問題