Can you give me the full source code of the small example you're referring
to, please?

Regards Hartmut
---------------
http://boost-spirit.com
http://stellar.cct.lsu.edu


> -----Original Message-----
> From: Kilian Werner [mailto:[email protected]]
> Sent: Tuesday, November 15, 2016 9:06 AM
> To: [email protected]; [email protected]
> Subject: Re: [hpx-users] HPX(promise_already_satisfied)
> 
> On Tue, 15 Nov 2016 07:18:13 -0600
>   "Hartmut Kaiser" <[email protected]> wrote:
> >
> >> in our current HPX driven project we encounter the
> >> following runtime error:
> >>
> >>      data has already been set for this future:
> >> HPX(promise_already_satisfied)
> >>
> >> The relevant code is as follows:
> >>
> >> void Image::compose ( const Image& other);
> >> hpx::future<Image> Container::render();
> >>
> >> [...]
> >>
> >>   std::vector<hpx::future<Image>> imageFutures;
> >>   for (int i = 0; i < containers.size(); ++i)
> >>         imageFutures.push_back(containers[i].render());
> >>
> >>    Image image;
> >>    hpx::lcos::local::spinlock mtx;
> >>
> >>    hpx::lcos::wait_each([&](hpx::future<Image> img)
> >>    {
> >>        std::lock_guard<hpx::lcos::local::spinlock>
> >> lk(mtx);
> >>        image.compose(img.get());
> >>    }, imageFutures);
> >>
> >>    return image;
> >>
> >> The runtime error does not occur, when the line
> >> "image.compose(img.get());" is substituted with just
> >> "img.get();"
> >> Note the argument of compose is a const reference.
> >>
> >> So what exactly does the error message mean? At no point
> >> are we explicitly setting or modifying the data of a
> >> future.
> >> The error only occurs when actually using the future,
> >> getting the future without further usage is safe.
> >>
> >> The Container Class is a client side representation of a
> >> Container Component, so the render methods could run in
> >> parallel and possibly on remote machines.
> >> The error only occurs if the vector imageFutures has
> >>more
> >> than one element, so only if there are multiple futures
> >>to
> >> wait on / multiple instances of render running.
> >>
> >> What can cause this error in general? How to go about
> >> debugging it and what could be the problem with our
> >> implementation.
> >
> > This error is thrown whenever a promise (the other end
> >of a future) has its
> > value set more than once. I.e. essentially something
> >like:
> >
> > void set_value(promise<int> p)
> > {
> >    p.set_value(42);
> >    p.set_value(42);   // <-- here
> > }
> >
> > void foo()
> > {
> >    promise<int> p;
> >    future<int> f = p.get_promise();
> >    async(&set_value, std::move(p));
> >    f.get();
> > }
> >
> > or similar.
> >
> >>From what I see from your code, the only explanation
> >>would be a bug in
> > wait_each() which manifests itself under certain timings
> >only. Could you
> > create a small reproducing use case for use to debug
> >things?
> >
> > Thanks!
> > 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
> 
> 
>  From what I've learned in the meantime, the bug seems not
> to be in wait_each.
> 
> While trying to narrow the problem down to your requested
> minimal example I observed, that the vector of futures
> "containerImageFutures" itsels seems to be corrupt.
> 
> Consider the following Code:
> 
> std::vector<hpx::shared_future<Image>>
> containerImageFutures;
> 
> for (int i = 0; i < containers.size(); ++i)
>       containerImageFutures.push_back(containers[i].render());
> 
> LogDebug() << "Size: " << containerImageFutures.size();
> 
> int i = 0;
> for ( const hpx::shared_future<Image>& future :
> containerImageFutures) {
>       try {
>             future.get();
>             LogDebug() << "ForEach Loop verifies existence
> of " << i << " while obvserving length " <<
> containerImageFutures.size();
>              i++;
>       }
>              catch (const std::out_of_range& oor) {
>                     std::cerr << "Out of Range error: " <<
> oor.what() << '\n';
>              }
>       }
> 
> LogDebug() << "Size: " << containerImageFutures.size();
> 
> return;
> 
> It produces the output:
> 
> [15:54:50] Size: 2
> [15:54:56] ForEach Loop verifies existence of 0 while
> obvserving length 2
> Out of Range error: vector::_M_range_check: __n (which is
> 0) >= this->size() (which is 0)
> [15:54:56] Size: 2
> 
> When deleting the line "future.get()" from the loop and
> instead using
> "hpx::lcos::wait_all(containerImageFutures);" before
> calling the loop the output is:
> [15:58:55] Size: 2
> [15:58:55] ForEach Loop verifies existence of 0 while
> obvserving length 2
> [15:58:55] ForEach Loop verifies existence of 1 while
> obvserving length 2
> [15:58:55] Size: 2
> 
> This leads to the conclusion, that the second element of
> the vector is only valid and reachable if .get() was not
> called on the first element.
> A vector that is distorted in such a way would of course
> omit invalid behavior for a wait_each command working on
> it.
> However it is unclear how this underlying error is
> created.
> 
> For your information. The HPX version we are working with
> was compiled from the master branch, june this year. We
> will try to update and see if the error changed somehow.
> Also note, that for testing we're running two localities
> locally using mpirun -np 2 program.
> 
> Best Regards,
> 
> Kilian Werner

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

Reply via email to