Repository navigation
Conversation
Remove SOLPROP_NATIVE_GEMM_PROVIDER and its CUSTOM, KOKKOSBLAS_NATIVE and KOKKOSBLAS_TPL values, with the cuda-custom, cuda-native and cuda-tpl presets that alone selected them. No shipped or CI build used them. custom_gemm stays as the hybrid provider's kernel for ineligible shapes, and the build record keeps gemm_provider (always HYBRID). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
benchmark_gemm.cpp compared the GEMM providers that are gone; the SOLPROP_NATIVE_BUILD_BENCHMARKS option built nothing else. End-to-end 'benchmarks ab' decides performance questions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No CI lane or shipped build uses icpx, and its special cases (the precise floating-point model, its LTO archiver, the pthreads FFTW requirement and MKL's Intel threading layer) cost about 45 CMake lines. Linux CPU builds now take GCC 14 or Clang/AOCC. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SOLPROP_NATIVE_ENABLE_THREADS had no C++ use, no CI lane and no shipped build; every CPU wheel, Windows included, runs OpenMP. A CPU build's execution space is now OpenMP only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Kokkos-FFT requires the single-precision FFTW libraries, but every fftwf_ call it makes sits behind an if constexpr on float that the double-only package never takes. Point FFTW_FLOAT_LIB and FFTW_FLOAT_OPENMP_LIB at the double libraries before Kokkos-FFT is configured, as the MKL branch already does, drop the single-precision FFTW builds from the wheel recipes, and make the wheel smoke test refuse a bundled libfftw3f or an fftwf_ import. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
size_cliffs and statistics_cost become benchmarks.size_cliffs and benchmarks.statistics_cost (statistics_cost builds ctc_reduced through the registry's builder and keeps m2_reduced's own table). The other native/benchmarks scripts (m1, m2, ctc, gemm_shapes, provider_sweep, device_record) predate 'python -m benchmarks track/ab', which covers their workloads, and nothing referenced them. cpu_timer.cpp, a Kokkos Tools timer with no build rule, goes too: the coverage label module counts and must not time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
check.sh hand-listed 40 files for clang-format and missed 43 of the 83 tracked ones; it now formats what 'git ls-files' lists under native/. .clang-format adds InsertNewlineAtEOF, RemoveSemicolon and regrouped include blocks (this package's headers, third-party libraries, the standard library, platform headers; conditional includes stay put). 'poe fmt-native' formats the same list in place. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It removes the semicolon that ends a KOKKOS_LAMBDA variable's declaration, which clang-format parses as a function definition. Declaring the macro would fix that, but makes formatting general.cpp take minutes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HAYtF4KqhYgzk6eBpqdfWA
Mechanical: clang-format 23.1.0 over the files the check now covers, with the regrouped include blocks and a newline at the end of each file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HAYtF4KqhYgzk6eBpqdfWA
The dev group pins clang-tidy 23.1.4, the PyPI wheel nearest the formatter's 23.1.0 (the wheels start at 23.1.3), and CMake looks for it beside the build's Python before any machine's LLVM. CI's tidy lane used Ubuntu 24.04's LLVM 18 and now uses the pinned one. On macOS the SDK is passed explicitly, as Homebrew's Clang finds it from a configuration file the PyPI build does not read. 'poe tidy-native [FILE...]' runs it on the given files, or on the C++ files that differ from main, with the cpu-tidy preset's compile commands (configured when missing). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HAYtF4KqhYgzk6eBpqdfWA
The project's sources now also compile with -Wundef, -Wnon-virtual-dtor and -Woverloaded-virtual; with -Wimplicit-fallthrough under Clang; and with -Wduplicated-cond, -Wduplicated-branches and -Wlogical-op under GCC. The list is defined once and feeds the targets' options, the coverage label module and the build record, which repeated it by hand. The one new finding (a test helper's conditional with identical branches) is fixed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HAYtF4KqhYgzk6eBpqdfWA
The cpu-sanitize preset turns on Kokkos_ENABLE_DEBUG_BOUNDS_CHECK, and sanitized targets compile with -fno-sanitize-recover=all, so a UBSan report fails the test whatever UBSAN_OPTIONS says. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HAYtF4KqhYgzk6eBpqdfWA
native-deep.yml (weekly and by hand, report-only) collects Clang source coverage over the GoogleTest and native pytest suites, runs the native pytest suite on an extension built with ASan, UBSan and Kokkos bounds checks (the bindings were never sanitized), and reports misc-include-cleaner's findings. cuda.yml adds compute-sanitizer's initcheck and synccheck beside memcheck and racecheck, and its comment now names the GCC 14 host compiler CMake requires. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HAYtF4KqhYgzk6eBpqdfWA
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HAYtF4KqhYgzk6eBpqdfWA
poe tidy-native and the include-cleaner report run clang-tidy after a configure alone, which does not generate sleef.h. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HAYtF4KqhYgzk6eBpqdfWA
clang-analyzer-security.ArrayBound: Table::value wrote every column of the table into its one double. Every caller reads a one-column table; the guard makes that a refusal instead of an out-of-bounds write. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HAYtF4KqhYgzk6eBpqdfWA
misc-redundant-expression: '1.0 / 1.0' is the same double as 1.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
misc-misplaced-const: 'const fftw_plan' makes the pointer const, not the plan, which the spelling suggests. The handles keep their meaning. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A reflowed NOLINTNEXTLINE would suppress its own continuation line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cppcoreguidelines-special-member-functions: AccelerateRamanPlan, BoundState, BoundSession and the test's SynthesisCapture delete their moves as they already deleted their copies (BoundState's address is held by the runtime's list of live states). The coupled flow's local RestoreFlow guard stays an aggregate, with a NOLINT. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bugprone-unchecked-optional-access: the transverse edge's record and held readings, the session's monitor plan and the bound marches' policies and stage tables are set whenever these lines run, by invariants the flow analysis does not follow (a validating lambda, an earlier stage of a state machine, a refusal in another member). A .value() read keeps them checked; it throws instead of reading an empty optional. The configuration counts .value() as checked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bugprone-throw-keyword-missing and bugprone-unused-raii read the temporaries that register the exception types as exceptions never thrown. Registration happens in the constructor either way. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bugprone-unused-return-value: the pointer was taken with get() before the capsule was made, so release() only gives up ownership. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
.clang-tidy moves from an allow-list of about 35 checks to the bugprone, performance, modernize, misc and readability families, the clang analyser and cppcoreguidelines-special-member-functions, each exclusion with its reason; warnings stay errors. The findings are fixed in the commits that follow, one check each. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/dev/tooling.md gains the native C++ tooling table, each tool's status and the reason for every rejection. native/AGENTS.md and the native README name the public API as solprop_native.__all__, add 'poe fmt-native', 'poe tidy-native' and the weekly native-deep.yml, and the changelog records the tooling change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
readability-use-concise-preprocessor-directives, applied by clang-tidy. Directives in inactive branches are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
readability-isolate-declaration, applied by clang-tidy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
modernize-use-nodiscard, applied by clang-tidy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
modernize-use-designated-initializers, applied by clang-tidy: each field is named where an aggregate is built. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
readability-implicit-bool-conversion, in two setup loops. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bugprone-integer-division: a plane node's row index (in the fluence-moment and second-moment kernels) and the rate tables' interval count are whole numbers by design; each is now an integer of its own before its conversion. The kernels' arithmetic is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bugprone-implicit-widening-of-multiplication-result: the envelope rule count and the packed radial inventory's limit were int products widened afterwards. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bugprone-branch-clone: without a vendor BLAS the envelope branch and the non-real branch both returned false. The guard is now one #if'd test, and the family test its own; the decisions are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The readability-inconsistent-ifelse-braces fix opened a brace on two 'else' arms that end at an #endif, and closed it outside: the CUDA and HIP builds, which skip the host branch, saw an unmatched brace. The closing brace now sits under the same condition. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
readability-suspicious-call-argument: a generic element functor, the FFT pool's lookup and the monitor's power callable take arguments whose names merely resemble other parameters'; each keeps a NOLINT. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
readability-implicit-bool-conversion (reported by the Linux tidy lane): SpaceAccessibility<...>::accessible is an enumerator. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On Linux it reports Kokkos's shared allocation records, freed through a reference count it cannot follow, as a leak inside Kokkos's own header when a view is constructed. The code holds no raw ownership, and the sanitizer builds check for leaks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
misc-use-internal-linkage (the Linux tidy lane): source_digest() is defined in the generated source_digest.cpp and declared and read in bindings.cpp, so it needs external linkage. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
clang-tidy has no PyPI wheel for Windows on Arm, so the Windows arm64 test lanes built LLVM from its sdist and timed out. The native gate that uses it is bash, run on Linux and macOS. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
benchmarks.statistics_cost built ctc_reduced through the registry's capillary builder, which changed the timed workload: tolerances, loss, temperature, seeded noise and n_save all differed from the deleted native/benchmarks/ctc.py. It now builds that case's own table exactly as the old harness did (rtol 1e-6, atol 1e-10, lossless, Raman, n_save 21, the defaults otherwise), as m2_reduced already did. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tidy.sh reconfigured only when the compile commands were missing, ran whatever clang-tidy was on PATH, and copied check.sh's compiler choice (without its /usr/local fallback). CMake now writes the clang-tidy command it runs, the resolved binary first, to clang_tidy_command.txt; tidy.sh reconfigures when that or the compile commands are missing or older than CMakeLists.txt, runs that command, and refuses a clang-tidy whose version is not the pinned one. The compiler and Raman provider choice moves to scripts/compiler.sh, sourced by both scripts, and the weekly include-cleaner report reads the same command file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The earlier guard threw from Table::value, a per-stage read. The loader now checks every scalar table (density, taper, Kerr density, chord, and each Raman, plasma and dispersive table) holds one value and refuses one that does not by name; Table::value keeps a debug assert. The test exercises the loader's refusal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
performance-unnecessary-value-param: the bindings' NOLINTBEGIN/END over whole files goes. The check's AllowedTypes now admits nanobind's reference-counted handles (nb::dict, nb::object, nb::handle, nb::ndarray and the bindings' ...Input and ...Array aliases of it), as it does Kokkos views; the one remaining finding, an optional dict copied into a bound lambda, now takes it by reference. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The block that names the double libraries for Kokkos-FFT's single-precision ones copied FindFFTW's search and dropped parts of it. It now makes one find_library per double library (fftw3, and fftw3_omp with OpenMP), with FFTW_ROOT or FFTWDIR as hints, honouring FFTW_USE_STATIC_LIBS, and points the FLOAT variable at each; FindFFTW keeps the cached results. The wheel smoke test still refuses an fftwf_ import. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
native-deep.yml's coverage job builds with Ubuntu's clang-18 and its extension job with ASan, configurations no pull-request lane compiles; with warnings as errors a new diagnostic there would stop the report. Both now build with SOLPROP_NATIVE_WARNINGS_AS_ERRORS=OFF. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
clang-tidy 23.1.4 joins the dev group's record beside clang-format 23.1.0, with why it is pinned and why only on Linux and macOS. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
workflow_dispatch reaches only workflows on the default branch, so a change to this report-only workflow could not be tried before merging. A pull request that edits the file now runs it; it still gates nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
main's lint now caps positional parameters at five (PLR0917). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Python loads no C++ runtime, so ASan, preloaded alone, could not resolve __cxa_throw at start-up and aborted at the first C++ exception the extension threw. libstdc++ is now preloaded beside it, and the report-only step records its outcome in the job summary instead of failing the job. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tor/native-structure-seam
refuse<Error>(parts...) and concat(parts...) (include/solprop_native/ refuse.hpp) replace the hand-built `"..." + std::to_string(n) + "..."` messages. Numbers keep std::to_string's text, so every message is byte-identical. The march's and the watch's own policy helpers are named refuse_policy so that they no longer shadow it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HAYtF5P9QqEd3HQx3WJkA3
include/solprop_native/build.hpp holds cuda, hip, device, host and openmp as inline constexpr bools. The #if blocks whose branches both compile in every build become constants or if constexpr: the crossing's device test, the real-signal switch, the register plane, the host pack layout, the Adams block width, the accepted-step fence, the band league and four host-only eligibility predicates. Blocks that name a device- or host-only facility keep their #if. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HAYtF5P9QqEd3HQx3WJkA3
dispatch_among<Values...> and dispatch_width<First, Last> (include/solprop_native/dispatch.hpp) turn a run-time extent into a compile-time one through a forced-inline comparison chain, which the compilers fold back into the switch. They replace the band filter's half-width ladder, the modal projection's lane ladder and the device Adams prediction's and element's width ladders. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HAYtF5P9QqEd3HQx3WJkA3
A private member template, GeneralState::with_team(function, arguments...), opens the workspace's CPU team scope and invokes the workspace's member on it; the 66 forwarders that opened the scope by hand become one call each. It is defined and instantiated in general.cpp alone, so the pImpl stays the firewall that keeps the workspace class from the strict units. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HAYtF5P9QqEd3HQx3WJkA3
clang-tidy's readability-avoid-return-with-void-value: the three void overloads no longer return their member's void, and with_team, which returns whatever its member returns, says why it may. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HAYtF5P9QqEd3HQx3WJkA3
native::Problem's 161 fields are grouped into sub-aggregates (dims, grid, spatial, flux, stepper, linear, absorber, transform, kerr, plasma, raman, general, flow, dispersive), every access renamed mechanically. The extension binds them with nb::class_ (FieldFamily with nb::enum_): a scalar field reads and writes as itself, a vector field as an exact NumPy array, float64, complex128, uint64 or bool, C-contiguous, of a declared rank where its count is laid out beside it, refused otherwise with the field's name. Problem::validate() keeps problem_from's presence and extent rules and their messages, and the CPU execution and FFT planning records still cross as dicts. The adapter's _lower(problem, request, plan) fills the structs in place of _native_problem's dict and its payload helpers; a lowering of 851 problems from the native test suites matched the old dict field for field, bit for bit, before the old path was removed. Tests address the struct fields instead of dict keys, with every assertion and match kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HAYtF5P9QqEd3HQx3WJkA3
The bound struct's fields read and write the same types, so the stub declares each as an attribute instead of a property and its setter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HAYtF5P9QqEd3HQx3WJkA3
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The first half of PR-5 of the lean-codebase plan: the native helpers, the bound problem struct and the workspace forwarders. Stacked on
feature/two-backends-binary64, withchore/native-toolingmerged in. It will be retargeted tomainlater. The split ofgeneral.cpp,close()by destruction, the decomposition of long functions and the dead-code removal (steps 4–7) come in a later PR.What changed
refuse<Error>(parts...)andconcat(parts...)(include/solprop_native/refuse.hpp) replace about 40 hand-built"..." + std::to_string(n)refusals. Every message keeps its exact text.include/solprop_native/build.hppdefinescuda,hip,device,hostandopenmp. Where both branches compile in every build,#ifblocks become constants orif constexpr. Blocks that name device-only or host-only facilities keep their#if, and so does the Adams flow guard that nvcc needs.dispatch_amonganddispatch_width(include/solprop_native/dispatch.hpp) replace the fourswitchladders: the band filter, the modal projection lanes, and the device Adams prediction and element.GeneralState::with_team(&GeneralWorkspace::f, args...)replaces the bodies of the 66 forwarders that opened the CPU team scope by hand. The declarations stay, because the pImpl keeps the workspace class out of the strict units.native::Problem's 161 fields are nested in 14 groups: dims, grid, spatial, flux, stepper, linear, absorber, transform, kerr, plasma, raman, general, flow and dispersive. Each group is bound withnb::class_, andFieldFamilywithnb::enum_.Problem::validate()holdsproblem_from's presence and extent rules, with the same messages._lower(problem, request, plan)replaces_native_problem, its dict and its payload helpers.match=was removed and no tolerance changed.Hot-path commits (for the A/B)
41f53f3cdispatch_width: the band filter (host and device), the modal projection lanes, and the device Adams prediction and element.9b6eec2fbuild facts: the Adams block width, the accepted-step fence and the band league. The others are cold predicates.f7f5ddc2with_team: everyGeneralStatecall,trial_stepand the Adams trials included, goes throughstd::invoke.2da322d9bound problem: a mechanical rename ofproblem_.xtoproblem_.group.xthroughoutgeneral.cpp, kernels included.d8d3af10refuse: the cold throw branches of the stage-table and z-table lookups and ofprepare_trial.Every commit is meant to give bitwise-identical results,
field_difference0.Sizes
tools/size_report.pycoverssrc/solprop, which this PR does not touch. Fornative/(git diff --shortstatfrom the base: 40 files, +4839 / −4316):src,include,tests/native)_core.pyiThe plan's savings are not reached yet. Most of them were to come from the part of step 2 that this PR leaves open (below).
Not done (step 2 remainder)
nb::class_, in place of the*_fromand*_todict conversions. Their dicts are produced and read in solprop as well as in the adapter.NB_MODULEintobind_state.cpp,bind_session.cppandbind_build.cpp.BoundStatelambdas into.def(&BoundState::f, nb::call_guard<...>()). Most lambdas convert NumPy inputs before releasing the GIL, so they first need an exact-array argument type._core.pyiwithnanobind.stubgen, with a freshness check. While most of the seam is untyped dicts, a generated stub would type them as baredictand break strict typing in the adapter. The problem's section of the stub was generated by stubgen, then written as plain attributes.Verification (Mac, Apple Clang via Homebrew LLVM, editable Release build, OpenMP CPU)
-n 4:test_api_contract,test_backend,test_envelope_plasma,test_mixtures,test_execution,test_band_plasma,test_session_failure,test_dispersive,test_free,test_envelope_statistics_refusal,test_coupled_flow,test_general_modal,test_radial,test_planning,test_raman_tailandtest_batch.tests/backends, also with-n 4: low storage, planar, far field, every statistic, dispersive Kerr, held plasma, node chunk, phi moments, z table, stage tables, march admission, rk/march traces, widths. Flow sessions and marches, resume history and helpers fromtests/driverandtests/test_helpers.pyran too.ruff, the native pyright configuration (0 errors) andclang-format.clang-tidyon the changed sources. One finding was fixed in its own commit.test_public_surface_is_exact: an uncommitted tree gives a.dYYYYMMDDversion suffix.test_response_column_boundary_preserves_full_and_tail_windows[19]: it fails the same way onmainhere.if constexprfacts are compiled on devices for the first time in the device-compile lanes.🤖 Generated with Claude Code
https://claude.ai/code/session_01HAYtF5P9QqEd3HQx3WJkA3