From 9ef35c8804dfb5a0cc383abf159bcb88ab8b4b13 Mon Sep 17 00:00:00 2001 From: nataraj2 Date: Tue, 16 Jun 2026 12:12:48 -0700 Subject: [PATCH 1/4] Update routine with nan info --- Source/ERF.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 9 deletions(-) diff --git a/Source/ERF.cpp b/Source/ERF.cpp index 182b43ce0..29acbf42f 100644 --- a/Source/ERF.cpp +++ b/Source/ERF.cpp @@ -3221,21 +3221,69 @@ ERF::writeNow(double cur_time, const int nstep, const int plot_int, const Real p } void -ERF::check_state_for_nans(MultiFab const& S) +ERF::check_state_for_nans (MultiFab const& S) { - bool any_have_nans = false; + amrex::Gpu::DeviceScalar d_found(0); + + // comp, i, j, k + amrex::Gpu::DeviceVector d_info(4, -1); + + for (MFIter mfi(S,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.tilebox(); + auto const& s_arr = S.const_array(mfi); + + const int ncomp = S.nComp(); - for (int i = 0; i < S.nComp(); i++) { + int* found = d_found.dataPtr(); + int* info = d_info.dataPtr(); - if (S.contains_nan(i,1,0)) + ParallelFor(bx, + [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { - amrex::Print() << "Component " << i << " of conserved variables contains NaNs" << '\n'; - any_have_nans = true; - } + // Somebody already found a NaN + if (*found) return; + + for (int n = 0; n < ncomp; ++n) + { + Real val = s_arr(i,j,k,n); + + if (val != val) // NaN test + { + // Only one thread wins + if (amrex::Gpu::Atomic::CAS(found,0,1) == 0) + { + info[0] = n; + info[1] = i; + info[2] = j; + info[3] = k; + } + return; + } + } + }); } - if (any_have_nans) { - exit(0); + amrex::Gpu::streamSynchronize(); + + if (d_found.dataValue()) + { + amrex::Vector h_info(4); + amrex::Print() << "Found flag = " << d_found.dataValue() << "\n"; + + amrex::Gpu::copy( + amrex::Gpu::deviceToHost, + d_info.begin(), + d_info.end(), + h_info.begin()); + + std::cout << "NaN found in component " << h_info[0] + << " at (i,j,k) = (" + << h_info[1] << ", " + << h_info[2] << ", " + << h_info[3] << ")\n"; + + amrex::Abort("NaN detected in state"); } } From ed8c408b31f3193ab1c4e1caa5ab4912d64e8a3b Mon Sep 17 00:00:00 2001 From: nataraj2 Date: Tue, 16 Jun 2026 15:09:07 -0700 Subject: [PATCH 2/4] Protecting against multiple inputs options --- Source/ERF.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/Source/ERF.cpp b/Source/ERF.cpp index 29acbf42f..037c80f73 100644 --- a/Source/ERF.cpp +++ b/Source/ERF.cpp @@ -2901,6 +2901,50 @@ ERF::ReadParameters () ParameterSanityChecks(); } +void CheckForDuplicateInputs () +{ + amrex::ParmParse pp; + const auto& tbl = pp.table(); + + bool found = false; + + for (const auto& [full_name, entry] : tbl) + { + std::string prefix; + std::string name; + + auto pos = full_name.find('.'); + + if (pos != std::string::npos) + { + prefix = full_name.substr(0, pos); + name = full_name.substr(pos + 1); + } + else + { + prefix = "global"; + name = full_name; + } + + if (entry.m_vals.size() > 1) + { + found = true; + + amrex::Print() << "Duplicate input: "; + + if (prefix == "global") + amrex::Print() << name; + else + amrex::Print() << prefix << "." << name; + + amrex::Print() << " (" << entry.m_vals.size() << " occurrences)\n"; + } + } + + if (found) + amrex::Abort("Duplicate inputs detected"); +} + // Read in some parameters from inputs file void ERF::ParameterSanityChecks () @@ -2966,6 +3010,8 @@ ERF::ParameterSanityChecks () if (solverChoice.coupling_type == CouplingType::TwoWay && cf_width > 0) { Abort("For two-way coupling you must set cf_width = 0"); } + + CheckForDuplicateInputs(); } // Create horizontal average quantities for 5 variables: From 5db1f72b7f79a23f475dd00aa38bc6a81c28a84e Mon Sep 17 00:00:00 2001 From: nataraj2 Date: Tue, 16 Jun 2026 16:58:30 -0700 Subject: [PATCH 3/4] Detect multiple inputs in inputs file but let CLI override --- Source/ERF_InputsName.H | 80 +++++++++++++++++++++++++++++++++++++++++ Source/main.cpp | 1 + 2 files changed, 81 insertions(+) diff --git a/Source/ERF_InputsName.H b/Source/ERF_InputsName.H index 5ca500adb..94fc10a07 100644 --- a/Source/ERF_InputsName.H +++ b/Source/ERF_InputsName.H @@ -5,4 +5,84 @@ extern std::string inputs_name; +namespace +{ + std::string trim_copy (std::string s) + { + auto b = s.find_first_not_of(" \t\r"); + if (b == std::string::npos) return ""; + + auto e = s.find_last_not_of(" \t\r"); + return s.substr(b, e - b + 1); + } +} + +inline void +CheckForDuplicateInputs (const std::string& inputs_file) +{ + std::ifstream ifs(inputs_file); + + if (!ifs.is_open()) { + amrex::Abort("Could not open inputs file: " + inputs_file); + } + + struct EntryInfo { + int line_number; + std::string value; + }; + + std::unordered_map seen; + + std::string line; + int line_number = 0; + bool found_duplicates = false; + + while (std::getline(ifs, line)) + { + ++line_number; + + // Remove comments + auto hash_pos = line.find('#'); + if (hash_pos != std::string::npos) { + line = line.substr(0, hash_pos); + } + + line = trim_copy(line); + + // Skip blank lines + if (line.empty()) continue; + + // Skip lines that are not assignments + auto eq_pos = line.find('='); + if (eq_pos == std::string::npos) continue; + + std::string key = trim_copy(line.substr(0, eq_pos)); + std::string value = trim_copy(line.substr(eq_pos + 1)); + + auto it = seen.find(key); + + if (it != seen.end()) + { + found_duplicates = true; + + amrex::Print() + << "\nDuplicate input detected:\n" + << " Key : " << key << "\n" + << " First line : " << it->second.line_number + << " Value : " << it->second.value << "\n" + << " Second line : " << line_number + << " Value : " << value << "\n"; + } + else + { + seen.emplace(key, EntryInfo{line_number, value}); + } + } + + if (found_duplicates) + { + amrex::Abort("Duplicate inputs detected in inputs file"); + } +} + #endif diff --git a/Source/main.cpp b/Source/main.cpp index de55722ac..0d90efcb3 100644 --- a/Source/main.cpp +++ b/Source/main.cpp @@ -128,6 +128,7 @@ return code; #else amrex::Initialize(argc,argv,true,MPI_COMM_WORLD,add_par); #endif + CheckForDuplicateInputs(argv[1]); #ifdef ERF_USE_KOKKOS // Initialize kokkos From 52606d8baa2ae3f1835a5e35a81a86b5d525a353 Mon Sep 17 00:00:00 2001 From: nataraj2 Date: Tue, 16 Jun 2026 16:58:46 -0700 Subject: [PATCH 4/4] Detect multiple inputs in inputs file but let CLI override --- Source/ERF.cpp | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) diff --git a/Source/ERF.cpp b/Source/ERF.cpp index 037c80f73..29acbf42f 100644 --- a/Source/ERF.cpp +++ b/Source/ERF.cpp @@ -2901,50 +2901,6 @@ ERF::ReadParameters () ParameterSanityChecks(); } -void CheckForDuplicateInputs () -{ - amrex::ParmParse pp; - const auto& tbl = pp.table(); - - bool found = false; - - for (const auto& [full_name, entry] : tbl) - { - std::string prefix; - std::string name; - - auto pos = full_name.find('.'); - - if (pos != std::string::npos) - { - prefix = full_name.substr(0, pos); - name = full_name.substr(pos + 1); - } - else - { - prefix = "global"; - name = full_name; - } - - if (entry.m_vals.size() > 1) - { - found = true; - - amrex::Print() << "Duplicate input: "; - - if (prefix == "global") - amrex::Print() << name; - else - amrex::Print() << prefix << "." << name; - - amrex::Print() << " (" << entry.m_vals.size() << " occurrences)\n"; - } - } - - if (found) - amrex::Abort("Duplicate inputs detected"); -} - // Read in some parameters from inputs file void ERF::ParameterSanityChecks () @@ -3010,8 +2966,6 @@ ERF::ParameterSanityChecks () if (solverChoice.coupling_type == CouplingType::TwoWay && cf_width > 0) { Abort("For two-way coupling you must set cf_width = 0"); } - - CheckForDuplicateInputs(); } // Create horizontal average quantities for 5 variables: