4

私は現在、ライブラリを作成中です。ユーザーが関数 ( として宣言restrict( amp )) を定義できるようにし、この関数をライブラリ関数の 1 つに渡してconcurrency::parallel_for_eachループ内で使用できるようにしたいと考えています。例えば:

template <typename T, typename Func>
void Foo( const concurrency::array_view<const T>& avParam, Func f ) 
{
     concurrency::array<T, 1> arrResult( avParam.extent );
     concurrency::parallel_for_each( avParam.extent, [=, &arrResult]( concurrency::index<1> index ) restrict(amp) {
          arrResult[index] = f( avParam[index] );
     } );

     // Do stuff...
}

関数ポインターをカーネル内の関数自体に直接f置き換えるかのように、有効な AMP 互換関数として宣言されている場合、これが機能することを期待します。fすべてが期待どおりに機能します。ただし、使用fすると次のエラーが発生します。

関数ポインター、関数参照、またはメンバー関数へのポインターはサポートされていません。

ユーザーがラムダ以外のファンクターを使用できないようにすることなく、目的の動作を得る方法はありますか?

4

3 に答える 3

0

ここには Windows ボックスがないため、再現またはテストすることはできません。

関数ポインター、関数参照、またはメンバー関数へのポインターはサポートされていません。

つまり、

  • 関数ポインタ 'pf' like in'R (*pf) (T)は、少なくともstd::function<R(T)> func(pf)

  • コールスタックを [in] として関数に渡したときfuncのように転送する必要があります。std::forward<std::function<R(T)>>(in_func)in_func

  • mem_fun_ptrs とにかくオフです。

[SKJJ12] p 9 から、まさにその関数、およびコールスタックのすべての関数または関数オブジェクトもマークされrestrict(amp)、その概念を満たす必要があると思います。

[SKJJ12] Sharlet, Kunze, Junkins Joshi 
Shevlin Park: Implementing C++ AMP with Clang/LLVM and OpenCL
http://llvm.org/devmtg/2012-11/Sharlet-ShevlinPark.pdf
于 2014-07-23T17:26:57.853 に答える
0

次があるとします。

template <typename T, typename Func>
void Foo( const concurrency::array_view<const T>& avParam, Func f ) 

int f(int x) restrict(amp) {return x+2;}

次に試してください:

Foo( avParam, [](int x) restrict(amp){ return f(x); } );`

への関数ポインターの代わりに、関数ポインターをf使用しないラムダを作成します。

これを自動化できます

#define AMP_OVERLOAD_SET(F) struct { \
  template<typename... Args> auto operator()(Args&&...args)const restrict(amp) \
  ->decltype( F(std::declval<Args>()...) ) \
  { return F( std::forward<Args>(args)... ); } \
}

static AMP_OVERLOAD_SET(f) amped_f; // declare an overload set object for `f`
Foo( vParam, amped_f ); // pass it to `Foo`

これは機能する場合と機能しない場合があります。

于 2014-07-24T19:23:14.983 に答える