nvcc (CUDA 5.0) を使用して以下のコードをコンパイルすると、「メモリ修飾子の不正な組み合わせ」というエラーが表示されます。クラスにグローバル カーネルを含めることは明らかに不可能であるためです。
class A
{
public:
__global__ static void kernel();
};
__global__ void A::kernel()
{}
非静的メンバーを扱うときのこの制限は理解できますが、カーネルが静的であると宣言されている場合でもエラーが発生するのはなぜですか? このようなメンバーの呼び出しは、名前空間で宣言されているときに関数を呼び出すことと同じです (A
この場合)。
A::kernel <<< 1, 1 >>> ();
これが(まだ)実装されていない理由について、私が見逃している理由はありますか?
編集:回答とコメントの両方の回答に基づいて、質問について十分に明確ではありませんでした。私の質問は、エラーが表示される理由ではありません。明らかに、これは実装されていないためです。私の質問は、なぜそれが実装されていないかです。これまでのところ、この機能が実装されない理由を思いつきませんでした。問題を複雑にする特別なケースを忘れていた可能性があることに気付いたので、質問します。
これが合理的な機能であると私が信じる理由は次のとおりです。
- 静的関数にはポインターがありません。
this
そのため、カーネルがホスト上に存在するオブジェクトで呼び出されたとしても、このデータにはそもそもアクセスできないため (どのオブジェクトからのデータ?? )。 - クラスに関連付けられた静的データがホスト上に存在する場合、これは原則として静的カーネルからアクセスできるべきであると主張できます。ただし、静的データもサポートされていないため、競合は発生しません。
- 通常の C++ で使用されているように、ホスト上のオブジェクトで静的カーネルを
A a; a.staticKernel<<<...,...>>>();)
呼び出す (オブジェクトをまったく使用せずに呼び出すのとまったく同じです ( ))。A::staticKernel<<<...,...>>>();
私は何が欠けていますか?