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
