-
Notifications
You must be signed in to change notification settings - Fork 161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
move semantics not rigorously thought-out #151
Comments
Hello Johannes, thanks for the feedback. I am not sure I understood completely your comments, so let me go through them, and please correct me if I misunderstood.
You are welcome to head over to https://gitter.im/pagmo2/Lobby if you want to have a discussion about this. Cheers, Francesco. |
1 and 3. I think my issue was partially confusion, partially that the same code in python and c++ can behave differently. For instance, querying the number of function evaluations in python can be done with the original problem, even when using population and algorithm directly. |
Ok, here a concrete example of my issue. If I use "population" directly, it takes a reference to my problem (assuming I pass the constructor an lvalue, and I don't use std::move). algorithm::evolve, however, is defined such that it takes a const reference, meaning I have to override my population with the return value of evolve. This leads to behaviour that differs between pagmo and pygmo:
I think this is by design and has to do with UDPs in python not being thread-safe, so it's ok to keep a reference to the original problem around. I found this very confusing though, and it might be worth specifying how the population/algorithm/whatnot are intended to be chained together. |
We designed pagmo/pygmo's interface in a "functional" fashion, in the sense that usually we prefer functions that take an input parameter and return an output value, rather than modifying objects in-place. In particular, the pagmo::problem prob{ my_prob() };
pagmo::algorithm algo{ pagmo::bee_colony(20u) };
pagmo::population pop{ prob, 10u };
alg.evolve(pop);
cout << pop.champion_f(); what we see is the expected behaviour: the evolved population is returned by the pagmo::population pop{ prob, 10u };
pop = alg.evolve(pop);
cout << pop.champion_f(); This should print the champion of the evolved population. The behaviour should be the same in C++ and Python (otherwise it's a bug). Does that clear things up? |
Jup, that's exactly right. I'm just saying that in python this behaviour is not enforced, i.e. my second example from above works fine, which makes it hard at first to wrap your head around coding the same stuff in c++. I doubt it's a bug but probably just something that has to do with how python manages memory(i.e. that the original problem is just an alias, and the copy never actually happens---which is fine, since python UDPs are not thread-safe anyway). Another related "issue" (again, not a bug) is that if e.g. bee_colony takes population by value, there's a copy happening; now, since population contains the problem (can be move'd, great!), and population has a default copy constructor (i.e. deep-copy everything), one would assume that the problem is deep-copied too, which is terrible if the UDP is expensive to create or has a vast amount of allocated memory. Just that this is not what is happening. If one checks the constructor of problem, you pass it through make_unique, which forwards it to a new T(...) call, so now the problem contains a pointer (!) to detail::prob_inner, which contains the UDP, and which implements move semantics; this solves the copying-of-resources issue if the UDP is passed by rvalue reference in first place, and indeed it cannot be passed as lvalue---without having to care about move semantics for the UDP oneself. While I agree that this works (after digging through the code), it would be amazing if you could update your documentation that gives some information about your design decisions and guarantees when a copy is actually happening: the compiler error one gets because Let me add one last comment in support of this vague complaint: I'm happy to have this issue closed, as the "bug" was more my confusion, but I hope to have pointed out a potential pitfall for future people trying to wrap their heads around pagmo. |
Hi,
the following suggestions for pagmo:
Generally your usage of move semantics and references is not very thorough, so it would be worth spending some effort making the api more consistent.
Best,
Johannes
The text was updated successfully, but these errors were encountered: