colvars icon indicating copy to clipboard operation
colvars copied to clipboard

[RFC] Change the atom group to SOA

Open HanatoK opened this issue 9 months ago • 21 comments

This is a PR with massive changes to introduce the SOA atom group class cvm::atom_group_soa, which tries to implement the first step in https://github.com/Colvars/colvars/discussions/655. ~~Currently there are two LAMMPS tests failed but I cannot figure out why for the time being.~~

HanatoK avatar Apr 12 '25 02:04 HanatoK

@HanatoK I looked quickly at the output of the LAMMPS tests. The errors are very small, and probably to be expected given the magnitude of the changes.

On a quick look this looks amazing :-D

We need to figure out how to decide that the tests we have (or those that we could add) are sufficient to make the COLVARS_SOA codepath the main one. As we discussed earlier, I am totally in agreement that the original data layout (now almost ~20 years old) no longer reflects the features of modern hardware.

giacomofiorin avatar Apr 12 '25 02:04 giacomofiorin

The issue with the LAMMPS tests should be solved by commit https://github.com/Colvars/colvars/pull/788/commits/d688465494037376bc62fc0ddecca02ae7654bf0. In my tests using TRPV1, this PR alone brings a 6-10% performance gain. I haven't tested combining this with #783 yet. benchmark_trpv1_soa

HanatoK avatar Apr 14 '25 20:04 HanatoK

RMSD benchmark results are attached here for future reference: benchmark_trpv1_soa_cudagm

For nested loops in coordNum and selfCoordNum, I think the performance is more compiler-dependent and also platform-dependent. With Clang 18 and above or GCC 15, users might see the performance improvement. However, with GCC 12/13, there is little to no difference, and with GCC 14, users might even see performance regression after switching to SOA. The micro-benchmark results are shown below: benchmark_selfcoordnum_0

HanatoK avatar Apr 16 '25 21:04 HanatoK

Great work @HanatoK! I don't have the Colvars knowledge to review all the changes but I noticed there is no changes for GROMACS related files. I guess this is mostly an internal rewrite with the proxy almost not modified hence the lack of changes?

HubLot avatar Apr 17 '25 07:04 HubLot

Great work @HanatoK! I don't have the Colvars knowledge to review all the changes but I noticed there is no changes for GROMACS related files. I guess this is mostly an internal rewrite with the proxy almost not modified hence the lack of changes?

Hi @HubLot ! This is a rewritten of the atom group class, and does not affect the proxy. However, since this PR relates to the performance, I would like to know how it affects the speed in GROMACS+Colvars simulations. I am not sure if the performance is improved or degraded under the default compiler flags of GROMACS. I used GROMACS some times but I am not an expert of it and I am sure that you know more about GROMACS than me. Do you have any test cases for profiling the Colvars performance in GROMACS?

HanatoK avatar Apr 17 '25 13:04 HanatoK

@HanatoK I disabled the check for GNU Make in LAMMPS (which will be removed after the upcoming LAMMPS stable release), so that the test failure for that doesn't stop the other library tests

giacomofiorin avatar Apr 18 '25 19:04 giacomofiorin

I don't know why the GROMACS tests suddenly failed. I will check them.

HanatoK avatar Apr 18 '25 20:04 HanatoK

It looks like https://gitlab.com/gromacs/gromacs/-/commit/f1d17c175a8bd98330e96dde45c92cb4b36a6bb3 changes the Colvars interface but the changes are not synchronized here. What should I do?

HanatoK avatar Apr 18 '25 20:04 HanatoK

It looks like https://gitlab.com/gromacs/gromacs/-/commit/f1d17c175a8bd98330e96dde45c92cb4b36a6bb3 changes the Colvars interface but the changes are not synchronized here. What should I do?

Ignore it for now. I want to take a look at that in a couple of weeks, unless @HubLot or @jhenin give it a try first. Fortunately GROMACS 2026 is still enough in the future

giacomofiorin avatar Apr 18 '25 20:04 giacomofiorin

This Gromacs story raises the point of how we track evolving Gromacs versions. Thanks to CI tests, the Gromacs repo is very likely to be self-consistent at a given point in time. This would argue in favor of not tracking these files at all, or at least not trying to update them if they are already present?

jhenin avatar Apr 22 '25 14:04 jhenin

This Gromacs story raises the point of how we track evolving Gromacs versions. Thanks to CI tests, the Gromacs repo is very likely to be self-consistent at a given point in time. This would argue in favor of not tracking these files at all, or at least not trying to update them if they are already present?

Is it possible to use a specific version of GROMACS for the CI testing in Colvars, just like NAMD?

HanatoK avatar Apr 22 '25 14:04 HanatoK

Hi @giacomofiorin and @jhenin! Aside from the atoms in cartesian, are the atoms in an atom group expected be aranged in the same order as their insertion order? In other way, can I sort the atoms in the atom group according to their proxy indices (except in cartesian)? I am trying another change (see https://github.com/HanatoK/colvars/commit/a66fe4655a5a26acfe74d55412499d40a889ecd8) but not quite sure if it breaks other things.

HanatoK avatar Apr 24 '25 19:04 HanatoK

See cvm::atom_group::create_sorted_ids(): you would certainly have to update sorted_atoms_ids and sorted_atoms_ids_map after changing the atom order.

I'm thinking on the rmsd and eigenvector components in particular. The value of rmsd depends on the order of atoms in the input, only if the reference coordinates are written directly in the configuration string (I don't know anyone who does it in practice, but that's supported). Same thing with the projection vector for the eigenvector component: if it's provided inline, then it will be kept in the order provided, and expected to match the order of atoms in the group.

EDIT: sorry, after the CVCs are initialized, it is too late to update the sorted atom maps. That's because cvm::load_coords uses it to remap input coordinates (assumed sorted) into the user-specified order of atoms in the atom group. So if you sort atoms after the reference positions are read, you need to re-order those as well. If the sorting is done just when the atom group is being initialized, before the CVC can read reference positions, we should be good.

jhenin avatar Apr 28 '25 16:04 jhenin

See cvm::atom_group::create_sorted_ids(): you would certainly have to update sorted_atoms_ids and sorted_atoms_ids_map after changing the atom order. I'm thinking on the rmsd and eigenvector components in particular. The value of rmsd depends on the order of atoms in the input, only if the reference coordinates are written directly in the configuration string (I don't know anyone who does it in practice, but that's supported). Same thing with the projection vector for the eigenvector component: if it's provided inline, then it will be kept in the order provided, and expected to match the order of atoms in the group.

The sorting of atom groups happens when they are created and before calling create_sorted_ids(). You can see that the changes do not break the tests (see https://github.com/HanatoK/colvars/commit/a66fe4655a5a26acfe74d55412499d40a889ecd8). However, I am not sure if the tests cover all corner cases.

HanatoK avatar Apr 28 '25 16:04 HanatoK

I was editing my message above as you replied. I don't think the tests have out-of-order atoms for this case, let me check.

jhenin avatar Apr 28 '25 16:04 jhenin

I can confirm, we don't have the right test for that. Here are good test colvars for the deca-alanine system:

colvar {
    name r1
    rmsd {
        atoms {
            atomNumbers 4 14 24 34
        }
        refPositions (0, 0, 0) (1, 1, 1) (2, 2, 2) (3, 3, 3)
    }
}

colvar {
    name r2
    rmsd {
        atoms {
            atomNumbers 14 24 34 4
        }
        refPositions (0, 0, 0) (1, 1, 1) (2, 2, 2) (3, 3, 3)
    }
}

jhenin avatar Apr 28 '25 16:04 jhenin

I'm thinking on the rmsd and eigenvector components in particular. The value of rmsd depends on the order of atoms in the input, only if the reference coordinates are written directly in the configuration string (I don't know anyone who does it in practice, but that's supported). Same thing with the projection vector for the eigenvector component: if it's provided inline, then it will be kept in the order provided, and expected to match the order of atoms in the group.

If it helps, we could also remove the inlined coordinates feature altogether. I don't think I have used it much myself in 20 years or so, i.e. from before we contributed the first version of Colvars into the NAMD repo.

It was a fall-back option for when you can't read PDB files, but the XYZ file reader added later made that redundant IMO.

giacomofiorin avatar Apr 28 '25 17:04 giacomofiorin

If it helps, we could also remove the inlined coordinates feature altogether. I don't think I have used it much myself in 20 years or so, i.e. from before we contributed the first version of Colvars into the NAMD repo.

Do you mean the refPositions? I have tried @jhenin's test case and https://github.com/HanatoK/colvars/commit/a66fe4655a5a26acfe74d55412499d40a889ecd8 indeed breaks it. In my opinion, the atoms in the atom group are better to be sorted according to their proxy indices, as this can probably make accessing the buffers in the proxy more memory-coalesced, which would be helpful in future GPU porting.

HanatoK avatar Apr 29 '25 02:04 HanatoK

Do you mean the refPositions? I have tried @jhenin's test case and HanatoK@a66fe46 indeed breaks it. In my opinion, the atoms in the atom group are better to be sorted according to their proxy indices, as this can probably make accessing the buffers in the proxy more memory-coalesced, which would be helpful in future GPU porting.

I agree. However, that also will mean sorting the colvarproxy buffers, which currently are populated in the order that the variables are defined but not sorted.

giacomofiorin avatar Apr 30 '25 23:04 giacomofiorin

Do you mean the refPositions? I have tried @jhenin's test case and HanatoK@a66fe46 indeed breaks it. In my opinion, the atoms in the atom group are better to be sorted according to their proxy indices, as this can probably make accessing the buffers in the proxy more memory-coalesced, which would be helpful in future GPU porting.

I agree. However, that also will mean sorting the colvarproxy buffers, which currently are populated in the order that the variables are defined but not sorted.

Maybe you are right. An MD engines may have its internal order as well, and it is indeed possible to sort the proxy buffers to match the internal order, but that could be a bit complicated as we have to sort the atom groups again. We can optimize them in the future of course.

HanatoK avatar May 01 '25 02:05 HanatoK

Commit https://github.com/Colvars/colvars/pull/788/commits/5eea84f9a213ce2883eddd91d261626cd04179c0 adds support of SOA atom groups in the NAMD CudaGlobalMaster interface.

HanatoK avatar May 13 '25 17:05 HanatoK