Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.

parallel_reduce question

levicivita
Beginner
520 Views
This might reveal my lack of understanding of TBB, but this doesn't work and I am not 100% sure why, or what would be an equivalent / better way to do this. Let's work off the tutorial example:

[cpp]val Foo(double x)
{
// x++;
for (int i=0; i<10; i++) x = cos(x); return x;
}

class SumFoo
{
val *const my_a;
public:
val my_sum;
void operator()( const blocked_range& r ) {
val *a = my_a;
val sum = my_sum;
size_t end = r.end();
for (size_t i=r.begin(); i!=end; ++i)
sum += Foo(a);
my_sum = sum;
}
SumFoo( val *a ) : my_a(a), my_sum(0) { }
SumFoo( SumFoo &x, split ) : my_a(x.my_a), my_sum(0) { }
void join( const SumFoo& y) { my_sum +=y.my_sum; }
void runme(int n)
{
parallel_reduce(blocked_range(0, n), this, auto_partitioner() );
}
};
[/cpp]
This should be pretty much the default example, with the exception of the runme method. Everything works fine unless I add it, at which point I get an extremely verbose error. I imagine the error has to do with the fact that 'this' is a SumFoo * const pointer, but I am not sure.

What is wrong with having a separate function kick off parallel_reduce on the SumFoo instance like in the tutorial? Nothing, except I wanted to have the SumFoo class automaticaly run the simulation as soon as it is constructed without any outside prompting, so as soon as I declare SumFoo sf(a), the sum should be calcuated. Is that doable somehow?

I take full responsibility if this is a trivial question.
0 Kudos
1 Solution
RafSchietekat
Valued Contributor III
520 Views
What happens if you use *this instead (the template function takes a reference)?

View solution in original post

0 Kudos
2 Replies
RafSchietekat
Valued Contributor III
521 Views
What happens if you use *this instead (the template function takes a reference)?
0 Kudos
levicivita
Beginner
520 Views
Quoting - Raf Schietekat
What happens if you use *this instead (the template function takes a reference)?

...that works. That was the first thing I tried this morning, and that of course worked. The only thing I have to say in my defense (other than I was tired) is that the error message was not particularly helpful:

[shell]/bin/tbb21_20081109oss/include/tbb/parallel_reduce.h: In member function `tbb::task* tbb::internal::start_reduce::execute() [with Range = tbb::blocked_range, Body = SumFoo* const, Partitioner = tbb::auto_partitioner]':
main.cpp:69:   instantiated from here
/bin/tbb21_20081109oss/include/tbb/parallel_reduce.h:149: error: `*((tbb::internal::start_reduce*)this)->tbb::internal::start_reduce::my_body' cannot be used as a function
/bin/tbb21_20081109oss/include/tbb/parallel_reduce.h: In member function `void tbb::internal::start_reduce::note_affinity(tbb::internal::affinity_id) [with Range = tbb::blocked_range, Body = SumFoo* const, Partitioner = tbb::auto_partitioner]':
main.cpp:69:   instantiated from here
/bin/tbb21_20081109oss/include/tbb/parallel_reduce.h:120: error: invalid conversion from `const void*' to `void*'
/bin/tbb21_20081109oss/include/tbb/parallel_reduce.h:120: error:   initializing argument 2 of `void* operator new(size_t, void*)'
/bin/tbb21_20081109oss/include/tbb/parallel_reduce.h:120: error: new initializer expression list treated as compound expression
/bin/tbb21_20081109oss/include/tbb/parallel_reduce.h:120: error: cannot convert `tbb::split' to `SumFoo* const' in initialization
/bin/tbb21_20081109oss/include/tbb/parallel_reduce.h: In member function `tbb::task* tbb::internal::finish_reduce::execute() [with Body = SumFoo* const]':
main.cpp:70:   instantiated from here
/bin/tbb21_20081109oss/include/tbb/parallel_reduce.h:80: error: request for member `join' in `*(SumFoo* const*)((tbb::internal::finish_reduce*)this)->tbb::internal::finish_reduce::my_body', which is of non-class type `SumFoo* const'
make: *** [release] Error 1
lx-chspgd03:/home/cbontas/cpp/tbb/parallel_reduce_selfcall $ [/shell]

0 Kudos
Reply