How to modify gpu variant of sw pair style?

Hello,

I am running a coarse-grained simulations on GPU using SW pair style. To improve the performanc of my simulations, I would like to alter the gpu variant of sw pair-style so it does not iterate over three-body interactions if the multiplier lambda==0. I believe the files to change are “pair_sw_gpu.cpp” and “pair_sw_gpu.h” located under the “src/gpu” directory, correct?
But, there are some functions in the .cpp file that I do not find them in the .cpp file itself. For example, “sw_gpu_compute_n”, “sw_gpu_compute” , and “sw_gpu_init”. Where can I find them? Also, do I need to change anything in the “pair_sw.cpp” file, as class PairSWGPU inherits from public PairSW.
Thanks!

The bulk of the GPU package code is in the lib/gpu folder. The part in src/GPU is mostly to interface to LAMMPS.

$ grep sw_gpu_init lib/gpu/*.* src/GPU/*.*
lib/gpu/lal_sw_ext.cpp:int sw_gpu_init(const int ntypes, const int inum, const int nall,
src/GPU/pair_sw_gpu.cpp:int sw_gpu_init(const int ntypes, const int inum, const int nall, const int max_nbors,
src/GPU/pair_sw_gpu.cpp:  int success = sw_gpu_init(tp1, atom->nlocal, atom->nlocal + atom->nghost, mnf, cell_size,

That is for you to find out and test. Since I don’t know what kind of changes you are going to do where, I cannot tell what else is required. Of course, I would assume that you are setting up some test simulations and compare the results (with GPU support compiled for double precision, the results should be very close). If you feel fancy, you could also set up an specific test case in the unit test framework as a new YAML file under unittest/force-styles/tests. See: 3.11. Development build options — LAMMPS documentation and 4.11. Adding tests for unit testing — LAMMPS documentation

Thanks very much @akohlmey

I was able to find the device code (lal_sw.cu) for SW potential. There is a “threebody” function that is called iteratively to calculate the three-body potential for each “ijk” permutation of atoms. I intend to change the code such that when sw_lambda_epsilon_ijk=0, then we dont call “threebody” function as the three-body potential will be equal to zero, regardless of all other parameters.
However, this “threebody” function is called by two other functions named: “k_sw_three_center”,“k_sw_three_end_vatom”. And I do not know what are the difference between these two callers! I can see that in the first function “k_sw_three_center”, the force vector is updated using both fij and fik magnitudes, yet for the second function only fij is used to update fi.
Also there is anothe function “threebody_half” called by “k_sw_three_end” function, which I guess determines only two-body force magnitudes.
Is there any manual for the code so I can read more about these functions? Thank you!

No. The source code is all you have.

1 Like

@m.adibi For implementation details, the paper by the code author gives useful information including the kernel names (Comput. Phys. Commun., 184, 2785 (2013); DOI: 10.1016/j.cpc.2013.08.002). From my understanding, the functions with the prefix k_ in the .cu file are the kernels to be launched on the GPU. The three_center and three_end are the kernels used to compute the force on a given atom i, when it is the center of a triplet (j-i-k), or when it is an “end” atom of a triple like (i-j-k) or (j-k-i), respectively. The _vatom kernel is used only when energy and virial per atom is needed. If the values of sw_lambda_epsilon_ijk =0 for all triplets (ijk) in your system and you want to skip the three body term, then you can look at lal_sw.cpp in the loop() function where the kernel is launched (lines 173-202). If this value depends on the triplet (ijk) types, it’s not clear if putting a check inside the 3-body kernels would make significant difference in performance.

I would recommend, instead of modifying the SW class source code directly, you derive a new class from it and find a way to override the appropriate function(s) (although this may still require some modification in the SW class declaration, such as changing private into protected). Hope it helps.