I have a fix that does Monte Carlo type moves (initial_integrate attempts a move, final_integrate rejects if needed), and I’m trying to use it with the symmetrix kokkos pair style. The whole thing is quite complicated, but I think I have a fairly simple description of the behavior I’m seeing, which I don’t understand:
“lmp.command("run N post no”) with my fix and the symmetrix kokkos pair style
lmp.numpy.extract_atom(“x”) - the returned pointer has some values
lmp.command(“run 0 post no”)
lmp.numpy.extract_atom(“x”) - the values appear to be different
I’ve confirmed that by the time the pair style’s compute method is being executed during the “run 0”, the x values are consistent with the ones I see from python after the “run 0”, and different from what I see immediately after the “run N”.
What could possibly make the values change between steps 2 and 3 in this sequence? Are there any convenient places (in the lammps source) to check the values during the execution flow
from the top level parser invoked by step 3
to the actual call to the pair style compute method
Your run 0 command without “pre no” will run a full setup with a new domain decomposition, new ghost atom creation and a full neighbor list rebuild. That will also reorder atoms and thus would explain differences because extract accesses atoms in “local” order.
OK, good to know. As it happens, what I’m printing is the sum of the absolute values of all the components of all the atoms, so reordering shouldn’t make more than a tiny change, and my observed changes are large. But maybe something else is changing - I guess I could print all the values and see if I notice anything systematic.
I’ve added more debugging prints, and it looks like after the end of VerletKokkos::run(N) (I print out at the very end of the function) but before the very beginning of the subsequent VerletKokkos::run(0) (I print out at the very beginning of the function),the kokkos pair style ::compute is called, and it already has the different atomic positions.
Is the pair style’s compute expected to be called again outside of the run loops, e.g. as part of a post or pre action maybe? I do call lmp.extract_compute(“pe”) in between - does that generate a recalculation, or does it just grab the value from the previous time it was evaluated?
[added] I am reasonably confident that I’m only printing the first nlocal positions, so a change in ghost atom selection shouldn’t affect the numbers I see
It is near impossible to discuss these matters “in the abstract”. There are just too many details that are only know to you. Using KOKKOS acceleration is a further complication.
From where I stand, this looks a lot like you are trying to do something from the python level (and rather inefficiently because of the restrictions of the library interface), that is better done in C++ by writing your own “driver”.
While I agree that it’s hard to discuss these things “in the abstract”, I specifically asked if the pair style’s compute can be called outside of the verlet loop (between a “run N” and “run 0”), and you mentioned the pre-stage doing domain decomposition, ghost atoms, and neighbor lists rebuilds, but neglected to mention that it does, in fact, also call compute.
Regardless, I figured out for myself that it does, and that in fact that’s the first call that has the strange position/energy values. However, it looks like the atomic position value changes are entirely due to PBC jumps, so the real question is why symmetrix kokkos is returning a different energy after these changes. I’ll look into that with Chuck Witt who wrote that pair style.
This is what the documentation is for: 4.7. How a timestep works — LAMMPS documentation
or based on that, you need to look up the details in the source code, if that information is insufficient.
While you are in your right to feel that your request was well within the limits of what is reasonable, I am also in my right to feel differently. Since I volunteer my time here, like anybody else, there is no entitlement for any level of service. I genuinely feel very uncomfortable having to figure out answers when I don’t know much context, even more so if I am lacking any chance to reproduce it. I am sorry if that is inconvenient and annoying for you, but that is just how these matters work in a public forum.
I do appreciate that you’re volunteering here, so perhaps what I need is just a pointer into some documentation. It turns out that the correct value is the one after the setup for run 0, probably because I’ve messed something up in my fix and the ghost atoms or neighbor list are not being rebuilt when they should be.
I was running with `neigh_modify delay 0 every 1 check yes, but for whatever reason it was still evaluating the energy with something wrong. Is there any documentation of what flags a fix might need to set to get the skin mechanism to work in the presence of position changes, cell changes, and (perhaps) species changes? By looking at fix_nh I found box_change |= BOX_CHANGE_X | ... and no_change_box=1 , but I’m wondering if I missed something else along those lines.
From what I can tell based on the few details you mentioned, you are asking to have control at a granularity that is simply not available through the library interface and what it was not designed for. My recommendation stands: you will be better off in the long run to write your own C++ “driver” where you have full access to all C++ internals and not just the abstraction of the library interface (of course you can also shoot yourself in the foot in many more ways this way).
There are about 400 pages (according to the manual PDF) worth of programmer documentation. I already pointed out the main workflow within the top-level C++ classes, details about related flags are in the header file comments and about the functions in the corresponding comments in the C++ implementation files.
You are, again, asking about details without sufficient context. I categorically refuse to comment on that, since nothing in LAMMPS works without context and many details work differently depending on what settings are active.
My problems (now that I understand them) have nothing to do with granularity. The problem happens entirely inside my fix, which is in pure C++
I can assure you that for me, at least, the 400 pages of documentation are not particularly useful in practice. For example, I know empirically that I need to set box_change |= CHANGE_BOX_X | … and yet that attribute is not mentioned anywhere, at least not as returned by the web site’s search interface. Can I find it in fix.h? Yes. Are the other attributes explained enough that I can figure out what they actually do? Often no.
Anyway, I agree that this discussion is no longer useful, and will now stop bothering you
As I mentioned before, my assessment is based on the available context.
By denying me information I need you are inviting to get bad or unsuitable advice.
This kind of language is not exactly helpful. It does not improve the situation and frustrates the people that have put in effort to improve it. I understand your disappointment, but you have to consider what effect your statements have, too.