On Donnerstag, 28. Juli 2016 12:45:09 CEST Hartmut Kaiser wrote:
> Daniel,
> 
> > > > > Suppose we have a vector of futures of type T and we want to reduce
> > > 
> > > the
> > > 
> > > > > values contained in the futures using T op(T, T), with initial value
> > > 
> > > of
> > > 
> > > > > init. What is the HPX recommended way of doing this? What should the
> > > > > implementation of "future<T> myreduce(vector<future<T> > fs, T init,
> > > 
> > > Op
> > > 
> > > > > op)" be?
> > > > > 
> > > > > hpx::parallel::reduce can't be used with a vector of futures.
> > > > > hpx::lcos::reduce isn't what we're looking for as this isn't a
> > > 
> > > distributed
> > > 
> > > > > operation. One option is to use hpx::when_any and accumulate the
> > > 
> > > values as
> > > 
> > > > > they are ready. But this serializes the accumulation of the futures,
> > > 
> > > which
> > > 
> > > > > may not be desirable.
> > > > 
> > > > How about:
> > > > 
> > > > vector<future<T>> v = ...;
> > > > future<T> f =
> > > > dataflow(unwrapped(
> > > > [](vector<T> && data) -> T
> > > > {
> > > > return parallel::reduce(
> > > > par, data.begin(), data.end(), op);
> > > > }),
> > > > std::move(v)
> > > > );
> > > 
> > > This would work but wouldn't parallel::reduce not start until all of the
> > > futures in v are ready? I'd be concerned that waiting on all of v could
> > > take too long. Especially if this were the last task in an application
> > 
> > (no
> > 
> > > other asynchrony is available) and some elements in v may be ready much
> > > later than other elements in v.
> > 
> > Ahh! Yes, that would be the case. Reduce would run only once all input-
> > futures have become ready.
> > 
> > We don't have any way to work around that at this point short of re-
> > implementing reduce to start working on the input elements as they become
> > available.
> 
> Actually, if you assumed that the input futures will become ready one by one
> (not all at the same time) it might be beneficial to use when_each:

What we missed are "futurized" parallel algorithms, that are usable in the 
same sense as dataflow.

> 
>     vector<future<T>> v = ...;
>     T reduced_result = 0;
>     mutex mtx;
>     future<void> f =
>         when_each(
>             [&](future<T>& f)
>             {
>                 lock_guard<mutex> l(mtx);
>                 reduced_result += f.get();
>             },
>             std::move(v)
>         );
> 
>     // do other things
>     f.get();
> 
> as when_each calls the given function for each of the futures once they
> become ready. Alternatively you could use wait_each() which is equivalent,
> it just will return only after all futures have been processed.
> 
> If the locking/unlocking turns into a bottleneck you could also utilize
> something like a cilk hyperobject, for an example implementation see the
> file example/quickstart/safe_object.cpp.
> 
> HTH
> Regards Hartmut
> ---------------
> http://boost-spirit.com
> http://stellar.cct.lsu.edu
> 
> 
> 
> _______________________________________________
> hpx-users mailing list
> [email protected]
> https://mail.cct.lsu.edu/mailman/listinfo/hpx-users


_______________________________________________
hpx-users mailing list
[email protected]
https://mail.cct.lsu.edu/mailman/listinfo/hpx-users

Reply via email to