Using user defined function in parallel_for_each in C ++ AMP

I am currently writing a library, and I want to be able to allow the user to define a function (declared as restrict( amp )) and allow them to pass this function to one of my library functions for use within the loop concurrency::parallel_for_each. For instance:

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...
}

I would expect this to work if fdeclared as a valid AMP-compatible function, as if I would immediately replace the function pointer fin the kernel with the function itself; everything works as expected. However, use fresults in the following error:

Function pointer, function reference, or member function pointer is not supported.

, , lambdas?

+4
3

( ) , . , .. ; .

, . . , . - , , , , . amp , , , :

  • RTTI

-, (amp). :

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...
}

template <typename T>
class Bar
{
public:
    T operator()(const T& v) const restrict(amp)
    {
        return v + 2;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    std::vector<int> result(100, 0);
    array_view<const int, 1> result_av(result.size(), result);

    Foo(result_av, Bar<int>());

    return 0;
}

, , , , ++ AMP . .

+2

, .

, - .

,

  • 'pf', 'R (*pf) (T), , , std::function<R(T)> func(pf)

  • func , std::forward<std::function<R(T)>>(in_func), [in] 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
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;}

then try:

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

which, instead of a function pointer, finstead creates a lambda that does not use a function pointer.

We can automate this

#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`

which may or may not work.

0
source

All Articles