2

私は C# で ManagedCuda を使用していますが、答えが見つからない質問が 1 つあります。C++ と CUDA では、次のような変数 (配列) を宣言できることを読んでいました。

__constant__ double myVar[X];(これは X 要素の配列を保持すると想定されます)

後でこれを使用して、ホスト コードから値を設定します。

cudaMemcpyToSymbol(myVar, &arrayFromHost[0], sizeof(arrayFromHost) * numElements, 
                   size_t(0),cudaMemcpyHostToDevice);

したがって、次のようなものを使用できます。

__global__ void myFunction(double *res)
{
    *res = myVar[0] + 2.5;
}

myVarホストから設定された値を使用して...

しかし、ManagedCudaではそれができないようです...どうすればできますか??

  1. *.cu ファイルで定数変数を宣言する
  2. *.cs ファイルの値 (配列) をその定数に設定します
  3. 定数 1 の値を使用します。同じ *.cu ファイル内の関数で

(または__device__変数...わかりません...最初に実行されたときに(要素数が不明な)配列を受け取る変数になり、それ以降、関数はその変数を参照します値ですが、その変数は変更されません)

今は aCudaDeviceVariableを宣言するだけで二度と触れませんが、カーネルでは常に DevicePointer を送信する必要があるため、読むときに理解しにくいと思います...

現在、次のようになっています。

myKernel.Run(staticData.DevicePointer, moreData.DevicePointer, 
             evenMoreData.DevicePointer, numberOfElementsWhichNeverChange,            
             moreStaticData.DevicePointer, myResults.DevicePointer)

変更されないデータを持つ 3 つのパラメーターをスキップしてsetData.Run(numElements, staticData, moreStaticData);
、*.cu ファイル内の他の関数の定数またはデバイス変数から使用するような別の関数に設定したいと思います。

4

1 に答える 1

5

myKernel には、やりたいことを正確に実行するメソッド SetConstantVariable() があります。カーネルを起動する前に呼び出すだけです: *.cu ファイルで:

extern "C" 
{
    __constant__ double myConstVarInCuda[5];
    __global__ void myFunction(double *res) 
    { 
        *res = myConstVarInCuda[0] + 2.5; 
    } 
}

C# の場合:

 double[] myVarInCS = new double[] { 1.0, 2.0, 3.0, 4.0, 5.0 };    
    myKernel.SetConstantVariable("myConstVarInCuda", myVarInCS);
    myKernel.Run(...);

Cuda コードを extern "C" スコープで宣言しない場合、名前が壊れることに注意してください。その場合、PTX コードでマングルされた正確な名前を調べることができます。

于 2012-09-14T15:24:22.000 に答える