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