From 06faea86607d0281eb3d983c3a6a4163f3b462b3 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sun, 8 Mar 2026 23:05:55 +0100 Subject: [PATCH 1/2] Error on insufficient NL parameters for large metatomic cutoffs Detect when the estimated neighbor count for the model cutoff and system density exceeds neigh_modify one, and error with a clear message telling the user exactly what neigh_modify line to add. Also add guards in the Kokkos NL builder (npair_kokkos, nbin_kokkos) to produce clear errors instead of SIGFPE when atoms_per_bin or mbins is zero. --- .../metatomic/in.kokkos.pair_metatomic | 4 +++ src/KOKKOS/nbin_kokkos.cpp | 5 +++ src/KOKKOS/npair_kokkos.cpp | 5 +++ src/ML-METATOMIC/fix_metatomic.cpp | 31 ++++++++++++++----- src/ML-METATOMIC/pair_metatomic.cpp | 21 +++++++++++++ 5 files changed, 59 insertions(+), 7 deletions(-) diff --git a/examples/PACKAGES/metatomic/in.kokkos.pair_metatomic b/examples/PACKAGES/metatomic/in.kokkos.pair_metatomic index 3b4be5bd662..c779bfabd9e 100644 --- a/examples/PACKAGES/metatomic/in.kokkos.pair_metatomic +++ b/examples/PACKAGES/metatomic/in.kokkos.pair_metatomic @@ -20,6 +20,10 @@ velocity all create 123 42 pair_style metatomic/kk nickel-lj.pt pair_coeff * * 28 +# For dense systems with large cutoffs (e.g. PET-MAD, ~5.5 A interaction range), +# pair_style metatomic will auto-adjust binsize, one, and page. To override: +# neigh_modify one 100000 page 1000000 binsize 5.5 + # pair_style hybrid/overlay/kk metatomic_1/kk nickel-lj.pt metatomic_2/kk nickel-lj.pt # pair_coeff * * metatomic_1/kk 28 # pair_coeff * * metatomic_2/kk 28 diff --git a/src/KOKKOS/nbin_kokkos.cpp b/src/KOKKOS/nbin_kokkos.cpp index 29ed21ca5bc..a444860e843 100644 --- a/src/KOKKOS/nbin_kokkos.cpp +++ b/src/KOKKOS/nbin_kokkos.cpp @@ -17,6 +17,7 @@ #include "atom_kokkos.h" #include "atom_masks.h" #include "comm.h" +#include "error.h" #include "kokkos.h" #include "memory_kokkos.h" #include "update.h" @@ -63,6 +64,10 @@ NBinKokkos::NBinKokkos(LAMMPS *lmp) : NBinStandard(lmp) { template void NBinKokkos::bin_atoms_setup(int nall) { + if (mbins <= 0) + error->one(FLERR, "Kokkos neighbor list produced zero bins; " + "try setting neigh_modify binsize to a smaller value"); + if (mbins > (int)k_bins.view_device().extent(0)) { MemoryKokkos::realloc_kokkos(k_bins,"Neighbor::d_bins",mbins,atoms_per_bin); bins = k_bins.view(); diff --git a/src/KOKKOS/npair_kokkos.cpp b/src/KOKKOS/npair_kokkos.cpp index dd7d18a9652..53659ebe11e 100644 --- a/src/KOKKOS/npair_kokkos.cpp +++ b/src/KOKKOS/npair_kokkos.cpp @@ -16,6 +16,7 @@ #include "atom_kokkos.h" #include "atom_masks.h" #include "domain_kokkos.h" +#include "error.h" #include "update.h" #include "neighbor_kokkos.h" #include "nbin_kokkos.h" @@ -234,6 +235,10 @@ void NPairKokkos::build(NeighList *list_) data.special_flag[2] = special_flag[2]; data.special_flag[3] = special_flag[3]; + if (atoms_per_bin <= 0) + error->one(FLERR, "Kokkos neighbor list bin size produced zero atoms_per_bin; " + "try increasing neigh_modify binsize"); + data.h_resize()=1; while (data.h_resize()) { data.h_new_maxneighs() = list->maxneighs; diff --git a/src/ML-METATOMIC/fix_metatomic.cpp b/src/ML-METATOMIC/fix_metatomic.cpp index 2f302fc153f..060082a7906 100644 --- a/src/ML-METATOMIC/fix_metatomic.cpp +++ b/src/ML-METATOMIC/fix_metatomic.cpp @@ -39,9 +39,11 @@ #include "neigh_list.h" #include "neigh_request.h" #include "comm.h" +#include "domain.h" #include #include +#include #include #include @@ -337,16 +339,31 @@ void FixMetatomic::init() { this->system_adaptor->add_nl_request(cutoff, options); } - // HACK: Explicitly set the binsize for the neighbor list if there is no - // pair_style that would set it instead. - // - // Otherwise, the default binsize of box[0] is used, which crashes kokkos - // for large-ish boxes (~40A), and slow down the simulation for non-kokkos. - if (strcmp(force->pair_style, "none") == 0) { + // Check that neighbor list parameters are sufficient for this cutoff. + // Dense systems with large cutoffs can overflow the default one/page + // and crash the Kokkos NL builder with SIGFPE. + if (!neighbor->binsizeflag) { + // Keep the existing binsize hack for fix metatomic neighbor->binsize_user = 0.5 * mta_data->max_cutoff; neighbor->binsizeflag = 1; } - // END HACK + + double volume = domain->xprd * domain->yprd * domain->zprd; + double density = (volume > 0) ? static_cast(atom->natoms) / volume : 0.0; + double cutoff_with_skin = mta_data->max_cutoff + neighbor->skin; + int est_neighbors = static_cast( + (4.0/3.0) * M_PI * pow(cutoff_with_skin, 3) * density * 2.0 + ); + if (est_neighbors > neighbor->oneatom) { + error->one(FLERR, + "The metatomic model cutoff ({:.4f}) with current system density " + "requires approximately {} neighbors per atom, but neigh_modify one " + "is only {}. Add 'neigh_modify one {} page {} binsize {:.4f}' " + "to your input script.", + mta_data->max_cutoff, est_neighbors, neighbor->oneatom, + est_neighbors, est_neighbors * 10, + 0.5 * mta_data->max_cutoff); + } } void FixMetatomic::pick_device(c10::Device& device, const char* requested) { diff --git a/src/ML-METATOMIC/pair_metatomic.cpp b/src/ML-METATOMIC/pair_metatomic.cpp index bd067026e86..a92043a8c99 100644 --- a/src/ML-METATOMIC/pair_metatomic.cpp +++ b/src/ML-METATOMIC/pair_metatomic.cpp @@ -38,6 +38,7 @@ #endif #include +#include #include #include @@ -559,6 +560,26 @@ void PairMetatomic::init_style() { auto request = neighbor->add_request(this, NeighConst::REQ_FULL | NeighConst::REQ_GHOST); request->set_cutoff(mta_data->max_cutoff); + // Check that neighbor list parameters are sufficient for this cutoff. + // Dense systems with large cutoffs can overflow the default one/page + // and crash the Kokkos NL builder with SIGFPE. + double volume = compute_volume(domain); + double density = (volume > 0) ? static_cast(atom->natoms) / volume : 0.0; + double cutoff_with_skin = mta_data->max_cutoff + neighbor->skin; + int est_neighbors = static_cast( + (4.0/3.0) * M_PI * pow(cutoff_with_skin, 3) * density * 2.0 + ); + if (est_neighbors > neighbor->oneatom) { + error->one(FLERR, + "The metatomic model cutoff ({:.4f}) with current system density " + "requires approximately {} neighbors per atom, but neigh_modify one " + "is only {}. Add 'neigh_modify one {} page {} binsize {:.4f}' " + "to your input script.", + mta_data->max_cutoff, est_neighbors, neighbor->oneatom, + est_neighbors, est_neighbors * 10, + 0.5 * mta_data->max_cutoff); + } + // Translate from the metatomic neighbor lists requests to LAMMPS neighbor // lists requests. auto requested_nl = mta_data->model->run_method("requested_neighbor_lists"); From b4814551db6162194d68786f4ef701fd78ab3577 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Wed, 11 Mar 2026 13:06:13 +0100 Subject: [PATCH 2/2] fix: auto-adjust neigh_modify one/page instead of erroring Per review: auto-set one/page when estimated neighbor count exceeds defaults, with an info message showing the adjustment. Users can still override manually. Also improve nbin_kokkos error message with explicit neigh_modify suggestion per PicoCentauri review. --- src/KOKKOS/nbin_kokkos.cpp | 3 ++- src/ML-METATOMIC/fix_metatomic.cpp | 19 +++++++++++-------- src/ML-METATOMIC/pair_metatomic.cpp | 19 +++++++++++-------- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/KOKKOS/nbin_kokkos.cpp b/src/KOKKOS/nbin_kokkos.cpp index a444860e843..ebc29a6df22 100644 --- a/src/KOKKOS/nbin_kokkos.cpp +++ b/src/KOKKOS/nbin_kokkos.cpp @@ -66,7 +66,8 @@ void NBinKokkos::bin_atoms_setup(int nall) { if (mbins <= 0) error->one(FLERR, "Kokkos neighbor list produced zero bins; " - "try setting neigh_modify binsize to a smaller value"); + "add 'neigh_modify binsize ' with a value smaller than " + "the shortest box dimension (e.g. half the pair cutoff)"); if (mbins > (int)k_bins.view_device().extent(0)) { MemoryKokkos::realloc_kokkos(k_bins,"Neighbor::d_bins",mbins,atoms_per_bin); diff --git a/src/ML-METATOMIC/fix_metatomic.cpp b/src/ML-METATOMIC/fix_metatomic.cpp index 060082a7906..554889bf8ba 100644 --- a/src/ML-METATOMIC/fix_metatomic.cpp +++ b/src/ML-METATOMIC/fix_metatomic.cpp @@ -355,14 +355,17 @@ void FixMetatomic::init() { (4.0/3.0) * M_PI * pow(cutoff_with_skin, 3) * density * 2.0 ); if (est_neighbors > neighbor->oneatom) { - error->one(FLERR, - "The metatomic model cutoff ({:.4f}) with current system density " - "requires approximately {} neighbors per atom, but neigh_modify one " - "is only {}. Add 'neigh_modify one {} page {} binsize {:.4f}' " - "to your input script.", - mta_data->max_cutoff, est_neighbors, neighbor->oneatom, - est_neighbors, est_neighbors * 10, - 0.5 * mta_data->max_cutoff); + // Auto-adjust one/page to avoid SIGFPE in Kokkos NL builder + if (comm->me == 0) { + error->message(FLERR, + "Metatomic model cutoff ({:.4f}) with current density requires " + "~{} neighbors per atom; auto-adjusting neigh_modify one/page. " + "To set manually, use at least: neigh_modify one {} page {}", + mta_data->max_cutoff, est_neighbors, + est_neighbors, est_neighbors * 10); + } + neighbor->oneatom = est_neighbors; + neighbor->pgsize = est_neighbors * 10; } } diff --git a/src/ML-METATOMIC/pair_metatomic.cpp b/src/ML-METATOMIC/pair_metatomic.cpp index a92043a8c99..83f99303090 100644 --- a/src/ML-METATOMIC/pair_metatomic.cpp +++ b/src/ML-METATOMIC/pair_metatomic.cpp @@ -570,14 +570,17 @@ void PairMetatomic::init_style() { (4.0/3.0) * M_PI * pow(cutoff_with_skin, 3) * density * 2.0 ); if (est_neighbors > neighbor->oneatom) { - error->one(FLERR, - "The metatomic model cutoff ({:.4f}) with current system density " - "requires approximately {} neighbors per atom, but neigh_modify one " - "is only {}. Add 'neigh_modify one {} page {} binsize {:.4f}' " - "to your input script.", - mta_data->max_cutoff, est_neighbors, neighbor->oneatom, - est_neighbors, est_neighbors * 10, - 0.5 * mta_data->max_cutoff); + // Auto-adjust one/page to avoid SIGFPE in Kokkos NL builder + if (comm->me == 0) { + error->message(FLERR, + "Metatomic model cutoff ({:.4f}) with current density requires " + "~{} neighbors per atom; auto-adjusting neigh_modify one/page. " + "To set manually, use at least: neigh_modify one {} page {}", + mta_data->max_cutoff, est_neighbors, + est_neighbors, est_neighbors * 10); + } + neighbor->oneatom = est_neighbors; + neighbor->pgsize = est_neighbors * 10; } // Translate from the metatomic neighbor lists requests to LAMMPS neighbor