From 6fc2770dd85986630967be4b06b2becbc614a1b8 Mon Sep 17 00:00:00 2001 From: "Harlow, Jordan" Date: Wed, 16 Sep 2026 12:17:27 -0600 Subject: [PATCH 1/5] task: agent-ready prep --- .github/pull_request_template.md | 25 +++++ .gitignore | 3 + CONTRIBUTING.md | 166 +++++++++++++++++++++++++++++++ README.md | 7 ++ 4 files changed, 201 insertions(+) create mode 100644 .github/pull_request_template.md create mode 100644 CONTRIBUTING.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..a34fbdef --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,25 @@ +# Description + + + +## Verification + + + +- Tests: +- Lint: + +## Not verified + + + +## Checklist + +- [ ] NumPy/SciPy FFT API compatibility preserved, or the break is intentional and called out above. +- [ ] Behavior changes have tests in `mkl_fft/tests/`; bug fixes have a regression test. +- [ ] `CHANGELOG.md` updated under `## [dev]` with a `[gh-NNN]` link. + + diff --git a/.gitignore b/.gitignore index 9468ae85..5c909764 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ mkl_fft/src/mklfft.c # ASV benchmark artifacts .asv/ + +# Developer-local coding agent settings +.claude/settings.local.json diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..98b1ccdd --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,166 @@ +# Contributing to `mkl_fft` + +This document covers the development +workflow: how to get a working build, how to run the checks, and how the code is +laid out so a change lands in the right layer. + +For end-user installation and API usage, see [README.md](README.md). Security +vulnerabilities go through the process in [SECURITY.md](SECURITY.md). + +--- + +## Development setup + +Building requires a C compiler, oneMKL headers and libraries (`mkl-devel`), and +NumPy. A conda environment is the least surprising way to get them: + +```sh +conda create -n mkl_fft-dev -c conda-forge python=3.12 pip mkl-devel numpy \ + meson-python ninja cmake cython pytest scipy mkl-service +conda activate mkl_fft-dev +``` + +Then build in place, which reuses the environment's MKL and NumPy: + +```sh +pip install -e ".[test]" --no-build-isolation --verbose +``` + +The `[test]` extra pulls in `pytest`, `scipy`, and `mkl-service`. Other extras +are declared in `pyproject.toml`: `scipy_interface` for the SciPy adapter at +runtime and `benchmark` for the ASV suite. + +`README.md` documents the non-editable install paths, including the isolated +build that resolves its own `mkl` and `numpy`. + +### Rebuilding + +`meson-python` rebuilds the extension on import for editable installs, so +editing `.pyx`, `.c.src`, or `meson.build` and rerunning `pytest` is usually +enough. Generated sources and the compiled extension live under `build//` +rather than in the source tree. If a build gets into a bad state, `rm -rf build` +and reinstall. + +## Running the checks + +```sh +pytest mkl_fft/tests # test suite +pre-commit run --all-files # lint and format hooks +``` + +Install the hooks once with `pre-commit install` and they run on each commit. +`.pre-commit-config.yaml` is the source of truth for the tooling; today it +covers `black`, `isort`, `flake8`, `pylint` (errors only), `cython-lint`, +`clang-format`, `codespell`, `shellcheck`, `gitleaks`, and `actionlint`. Line +length is 80 for Python, Cython, and TOML. + +### What CI runs + +`.github/workflows/*.yml` is canonical for platform and Python matrices. In +outline: + +| Workflow | Purpose | +| --- | --- | +| `conda-package.yml` | conda build and test against the Intel channel | +| `conda-package-cf.yml` | conda build and test against conda-forge only | +| `build_pip.yml` | editable pip build, including pre-release NumPy | +| `build-with-clang.yml` | build with the IntelLLVM `icx` compiler | +| `build-with-standard-clang.yml` | build with upstream clang | +| `pre-commit.yml` | lint and format | +| `coverity.yml` | static analysis (see `coverity/README.md`) | +| `openssf-scorecard.yml`, `zizmor.yml` | supply-chain and workflow security | + +To reproduce a conda packaging failure locally, build the recipe the same way CI +does — `conda build --python --numpy -c --override-channels conda-recipe` +(or `conda-recipe-cf` for the conda-forge variant). The recipe directories are +canonical for packaging intent and dependency pins. + +## How the code fits together + +Build configuration lives in `pyproject.toml` (with `meson-python` as the build +backend) and `meson.build`. The version is read from `mkl_fft/_version.py` by +`meson.build`, so that file is the single place a version is set. + +A transform call flows down through these layers: + +``` +mkl_fft.interfaces.numpy_fft / scipy_fft drop-in NumPy/SciPy adapters +mkl_fft (__init__.py) public FFT API +mkl_fft/_mkl_fft.py, _fft_utils.py argument handling, normalization, dispatch +mkl_fft/_pydfti.pyx Cython bindings +mkl_fft/src/mklfft.c.src -> mklfft.c C backend, generated at build time +oneMKL DFTI +``` + +Directories: + +- **`mkl_fft/`** — the package. `__init__.py` is the public API surface; + `_mkl_fft.py` and `_fft_utils.py` hold the Python-level FFT logic; + `_pydfti.pyx` is the Cython binding layer. +- **`mkl_fft/src/`** — the C backend, written as `*.c.src` templates. At build + time `_vendored/process_src_template.py` expands `mklfft.c.src` into + `mklfft.c`, which is compiled into the `_pydfti` extension. The generated + `.c` is regenerated on every build, so only template edits survive. +- **`mkl_fft/interfaces/`** — adapters presenting `numpy.fft`- and + `scipy.fft`-shaped APIs. `numpy_fft.py` and `scipy_fft.py` are the public + modules; the `_`-prefixed siblings are implementation. Upstream signatures and + semantics are the contract here. +- **`mkl_fft/`** patching layer — `patch.py`, `with_patch.py`, `_patch_numpy.py`, + `_patch_startup.py`, and the `__main__.py` CLI implement the monkey-patching + entry points documented in the README. The contract is that patching stays + reversible and observable: anything installed can be uninstalled, and + `is_patched()` reports the truth. +- **`mkl_fft/tests/`** — the suite. `helper.py` holds shared utilities and + `third_party/` carries tests adapted from upstream projects. +- **`_vendored/`** — build-time code-generation helpers vendored from NumPy. + They are excluded from `black` and `isort` in `pyproject.toml`. +- **`conda-recipe/`**, **`conda-recipe-cf/`** — Intel-channel and conda-forge + packaging. +- **`benchmarks/`** — ASV benchmarks, run with the `benchmark` extra. + +Each of these directories has an `AGENTS.md` stating the same boundaries for +coding agents; [`AGENTS.md`](AGENTS.md) at the root indexes them and is a useful +orientation map for humans too. + +## Dos and don'ts + +**Do** + +- Keep changes atomic and single-purpose. +- Preserve NumPy/SciPy FFT compatibility. This package is used as a drop-in + replacement, so a behavioral difference is a bug even when the new behavior is + arguably better. Call out an intentional break in the PR. +- Add tests in `mkl_fft/tests/` alongside behavior changes, and a regression + test with every bug fix. +- Keep tests deterministic. +- Edit the `*.c.src` templates for C backend changes. +- Keep patching reversible and observable. +- Cite the source-of-truth file for mutable details: `pyproject.toml`, + `meson.build`, `conda-recipe*/meta.yaml`, `.github/workflows/`. +- Give benchmark numbers reproducible context — hardware, versions, and the + command you ran. + +**Don't** + +- Commit generated artifacts, or hand-edit a generated `.c`. +- Hardcode versions, build flags, CI matrices, or channel URLs in documentation. +- Assert on timing or throughput in the test suite. +- Refactor `_vendored/` opportunistically. Keep local diffs minimal and send + fixes upstream where you can. +- Introduce ISA-specific assumptions outside explicit build configuration. + +## Submitting a change + +Work on a branch: the `no-commit-to-branch` hook blocks direct commits to +`master` and `maintenance/*`. + +Add a `CHANGELOG.md` entry under `## [dev]` in the matching section, with a +`[gh-NNN](https://github.com/IntelPython/mkl_fft/pull/NNN)` link. The format +follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project +follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +Then open the PR and fill in the template, including what you verified locally +and what you left to CI. + +By contributing you agree that your contributions are licensed under the +BSD-3-Clause terms in [LICENSE.txt](LICENSE.txt). diff --git a/README.md b/README.md index 14e5ebce..1bd73285 100644 --- a/README.md +++ b/README.md @@ -165,3 +165,10 @@ Optionally, install `scipy` to use the `mkl_fft.interfaces.scipy_fft` module: ```sh pip install scipy ``` + +--- +# Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md) for the development workflow: setting up a +build environment, running the tests and lint hooks, how the Python, Cython, and +C template layers fit together, and what to include in a pull request. From 602d08d74b20f69e6dc482ce537b32815034c044 Mon Sep 17 00:00:00 2001 From: "Harlow, Jordan" Date: Wed, 16 Sep 2026 12:46:22 -0600 Subject: [PATCH 2/5] chore: cleanup --- .github/pull_request_template.md | 2 +- CONTRIBUTING.md | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index a34fbdef..6cf5f9f6 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -20,6 +20,6 @@ conda build, the benchmarks. Write "none" if you ran everything relevant. - [ ] NumPy/SciPy FFT API compatibility preserved, or the break is intentional and called out above. - [ ] Behavior changes have tests in `mkl_fft/tests/`; bug fixes have a regression test. -- [ ] `CHANGELOG.md` updated under `## [dev]` with a `[gh-NNN]` link. +- [ ] `CHANGELOG.md` updated under `## [dev]` with a `[gh-NNN]` link, or the change isn't user-visible. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 98b1ccdd..1be86964 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -154,10 +154,12 @@ orientation map for humans too. Work on a branch: the `no-commit-to-branch` hook blocks direct commits to `master` and `maintenance/*`. -Add a `CHANGELOG.md` entry under `## [dev]` in the matching section, with a +If the change is user-visible — behavior, API, packaging, or build output — add +a `CHANGELOG.md` entry under `## [dev]` in the matching section, with a `[gh-NNN](https://github.com/IntelPython/mkl_fft/pull/NNN)` link. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project -follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Docs, +tooling, and CI-only changes are usually left out. Then open the PR and fill in the template, including what you verified locally and what you left to CI. From 714dc00ac6f10239fe6d85bdbb4faa21d6fdcf2e Mon Sep 17 00:00:00 2001 From: "Harlow, Jordan" Date: Wed, 16 Sep 2026 13:36:30 -0600 Subject: [PATCH 3/5] chore: more cleanup --- CONTRIBUTING.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1be86964..ba7560e0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,7 +15,8 @@ Building requires a C compiler, oneMKL headers and libraries (`mkl-devel`), and NumPy. A conda environment is the least surprising way to get them: ```sh -conda create -n mkl_fft-dev -c conda-forge python=3.12 pip mkl-devel numpy \ +# add python=X.Y to target a specific interpreter +conda create -n mkl_fft-dev -c conda-forge python pip mkl-devel numpy \ meson-python ninja cmake cython pytest scipy mkl-service conda activate mkl_fft-dev ``` @@ -26,6 +27,9 @@ Then build in place, which reuses the environment's MKL and NumPy: pip install -e ".[test]" --no-build-isolation --verbose ``` +`pyproject.toml` defines the supported Python range, and +`.github/workflows/build_pip.yml` is canonical for the versions CI covers. + The `[test]` extra pulls in `pytest`, `scipy`, and `mkl-service`. Other extras are declared in `pyproject.toml`: `scipy_interface` for the SciPy adapter at runtime and `benchmark` for the ASV suite. From 1cd29fb243481e1ac60d03f3374234bb82372000 Mon Sep 17 00:00:00 2001 From: "Harlow, Jordan" Date: Wed, 16 Sep 2026 15:52:35 -0600 Subject: [PATCH 4/5] task: more scanning and improvements --- .gitattributes | 3 ++ .github/ISSUE_TEMPLATE/bug_report.yml | 63 ++++++++++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 8 +++ .github/ISSUE_TEMPLATE/feature_request.yml | 38 +++++++++++++ .gitignore | 6 +++ AGENTS.md | 2 + benchmarks/AGENTS.md | 20 +++++++ 7 files changed, 140 insertions(+) create mode 100644 .gitattributes create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 benchmarks/AGENTS.md diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..64e22515 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +# Keep shell scripts LF on checkout so shellcheck and conda build scripts work +# the same on Windows and WSL checkouts with core.autocrlf enabled. +*.sh text eol=lf diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000..b1b81626 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,63 @@ +name: Bug report +description: Report incorrect results, a crash, or a build failure +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + For security vulnerabilities, do not open an issue — follow + [SECURITY.md](https://github.com/IntelPython/mkl_fft/blob/master/SECURITY.md). + + - type: textarea + id: description + attributes: + label: Description + description: What happened, and what did you expect instead? + validations: + required: true + + - type: textarea + id: reproducer + attributes: + label: Reproducer + description: A minimal, self-contained snippet. Include the input shape and dtype. + render: python + validations: + required: true + + - type: dropdown + id: install-source + attributes: + label: How was `mkl_fft` installed? + options: + - Intel channel (software.repos.intel.com) + - conda-forge + - pip / PyPI + - Built from source + validations: + required: true + + - type: textarea + id: versions + attributes: + label: Versions + description: | + Output of: + ``` + python -c "import mkl_fft, numpy, mkl; print(mkl_fft.__version__); print(numpy.__version__); print(mkl.get_version_string())" + ``` + Add your OS and Python version too. + render: shell + validations: + required: true + + - type: textarea + id: notes + attributes: + label: Anything else + description: | + Optional. Whether NumPy patching was active (`mkl_fft.is_patched()`), whether + the result differs from `numpy.fft`/`scipy.fft`, or a non-default + `MKL_NUM_THREADS`. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..6b116179 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: true +contact_links: + - name: Security vulnerability + url: https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html + about: Report security vulnerabilities through Intel's process, not a public issue. + - name: Question about usage + url: https://github.com/IntelPython/mkl_fft/blob/master/README.md + about: Check the README and the interfaces documentation first. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000..7d8c9e53 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,38 @@ +name: Feature request +description: Propose a new transform, interface, or capability +labels: ["enhancement"] +body: + - type: textarea + id: problem + attributes: + label: What problem does this solve? + description: The use case, not the implementation. + validations: + required: true + + - type: textarea + id: proposal + attributes: + label: Proposal + description: | + What you would like `mkl_fft` to do. If it mirrors a `numpy.fft` or + `scipy.fft` function, name it — upstream signature and semantics are the + contract for the interface layer. + validations: + required: true + + - type: input + id: upstream + attributes: + label: Upstream equivalent + description: Link to the NumPy or SciPy docs for the equivalent API, if there is one. + validations: + required: false + + - type: textarea + id: alternatives + attributes: + label: Alternatives considered + description: Optional. Workarounds you are using today. + validations: + required: false diff --git a/.gitignore b/.gitignore index 5c909764..56da2b25 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,12 @@ mkl_fft.egg-info/ # Byte-compiled / optimized / DLL files __pycache__/ +# Virtual environments, test caches, local env files +.venv/ +venv/ +.pytest_cache/ +.env + mkl_fft/_pydfti.c mkl_fft/_pydfti.cpython*.so mkl_fft/_pydfti.*-win_amd64.pyd diff --git a/AGENTS.md b/AGENTS.md index d909942c..d3454284 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -14,6 +14,7 @@ It provides accelerated FFT transforms while aiming to preserve upstream API beh - **Tests:** `mkl_fft/tests/` - **Vendored helpers:** `_vendored/` - **Packaging:** `conda-recipe/`, `conda-recipe-cf/` +- **Benchmarks:** `benchmarks/` ## Build/runtime basics - Build system: `pyproject.toml` + `meson.build` @@ -46,3 +47,4 @@ Use nearest local `AGENTS.md` when present: - `conda-recipe/AGENTS.md` — Intel-channel conda packaging - `conda-recipe-cf/AGENTS.md` — conda-forge recipe context - `_vendored/AGENTS.md` — vendored tooling boundaries +- `benchmarks/AGENTS.md` — ASV performance suite diff --git a/benchmarks/AGENTS.md b/benchmarks/AGENTS.md new file mode 100644 index 00000000..27459afa --- /dev/null +++ b/benchmarks/AGENTS.md @@ -0,0 +1,20 @@ +# AGENTS.md — benchmarks/ + +ASV performance suite for `mkl_fft`. + +## Scope +- `asv.conf.json` — ASV configuration, channels, and regression thresholds +- `benchmarks/` — benchmark modules (`bench_fft1d`, `bench_fftnd`, + `bench_interfaces`, `bench_memory`) plus shared bases in `_utils.py` +- `README.md` — coverage table, threading model, and run commands + +## Guardrails +- Treat `asv.conf.json` as canonical for ASV settings; treat `README.md` as + canonical for what each module covers. +- Comparability across machines depends on the thread default in + `benchmarks/__init__.py` and the DFTI warmup in each `setup`. Changing either + invalidates comparison against existing results — call it out explicitly. +- Keep inputs deterministic; benchmarks seed their own RNG. +- Report performance numbers with reproducible context: hardware, thread count, + versions, and the command used. +- Benchmark results under `.asv/` are local artifacts and are gitignored. From 90b86a4b6f760b863a71cba62b14e38cfb1fa394 Mon Sep 17 00:00:00 2001 From: "Harlow, Jordan" Date: Thu, 1 Oct 2026 11:35:17 -0600 Subject: [PATCH 5/5] chore: review --- CONTRIBUTING.md | 111 ++++++++++++++---------------------------------- README.md | 4 +- 2 files changed, 34 insertions(+), 81 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ba7560e0..9a2270dd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,10 +1,11 @@ # Contributing to `mkl_fft` -This document covers the development -workflow: how to get a working build, how to run the checks, and how the code is -laid out so a change lands in the right layer. +This document covers the development workflow: how to get a working build, how +to run the checks, and what to include in a pull request. -For end-user installation and API usage, see [README.md](README.md). Security +For end-user installation and API usage, see [README.md](README.md). For a map +of the source tree, see [`AGENTS.md`](AGENTS.md), which links to the local +`AGENTS.md` files in directories that have their own rules. Security vulnerabilities go through the process in [SECURITY.md](SECURITY.md). --- @@ -17,22 +18,31 @@ NumPy. A conda environment is the least surprising way to get them: ```sh # add python=X.Y to target a specific interpreter conda create -n mkl_fft-dev -c conda-forge python pip mkl-devel numpy \ - meson-python ninja cmake cython pytest scipy mkl-service + meson-python ninja cmake cython pytest conda activate mkl_fft-dev ``` Then build in place, which reuses the environment's MKL and NumPy: ```sh -pip install -e ".[test]" --no-build-isolation --verbose +pip install -e . --no-build-isolation --verbose ``` `pyproject.toml` defines the supported Python range, and `.github/workflows/build_pip.yml` is canonical for the versions CI covers. -The `[test]` extra pulls in `pytest`, `scipy`, and `mkl-service`. Other extras -are declared in `pyproject.toml`: `scipy_interface` for the SciPy adapter at -runtime and `benchmark` for the ASV suite. +SciPy and `mkl-service` are optional. They are needed only for the +`mkl_fft.interfaces.scipy_fft` adapter, and the tests that exercise it are +skipped without them. To use or test the SciPy interface, add both to the +environment: + +```sh +conda install -c conda-forge scipy mkl-service +``` + +The matching pip extras are declared in `pyproject.toml`: `scipy_interface` for +the SciPy adapter, `test` for `pytest` plus both packages, and `benchmark` for +the ASV suite. `README.md` documents the non-editable install paths, including the isolated build that resolves its own `mkl` and `numpy`. @@ -53,78 +63,19 @@ pre-commit run --all-files # lint and format hooks ``` Install the hooks once with `pre-commit install` and they run on each commit. -`.pre-commit-config.yaml` is the source of truth for the tooling; today it -covers `black`, `isort`, `flake8`, `pylint` (errors only), `cython-lint`, -`clang-format`, `codespell`, `shellcheck`, `gitleaks`, and `actionlint`. Line -length is 80 for Python, Cython, and TOML. - -### What CI runs - -`.github/workflows/*.yml` is canonical for platform and Python matrices. In -outline: +`.pre-commit-config.yaml` is the source of truth for the tooling. -| Workflow | Purpose | -| --- | --- | -| `conda-package.yml` | conda build and test against the Intel channel | -| `conda-package-cf.yml` | conda build and test against conda-forge only | -| `build_pip.yml` | editable pip build, including pre-release NumPy | -| `build-with-clang.yml` | build with the IntelLLVM `icx` compiler | -| `build-with-standard-clang.yml` | build with upstream clang | -| `pre-commit.yml` | lint and format | -| `coverity.yml` | static analysis (see `coverity/README.md`) | -| `openssf-scorecard.yml`, `zizmor.yml` | supply-chain and workflow security | +Opening a pull request also runs CI, which builds and tests the package across +platforms and Python versions and runs various lint and static-analysis checks. -To reproduce a conda packaging failure locally, build the recipe the same way CI -does — `conda build --python --numpy -c --override-channels conda-recipe` -(or `conda-recipe-cf` for the conda-forge variant). The recipe directories are -canonical for packaging intent and dependency pins. +## Code style -## How the code fits together - -Build configuration lives in `pyproject.toml` (with `meson-python` as the build -backend) and `meson.build`. The version is read from `mkl_fft/_version.py` by -`meson.build`, so that file is the single place a version is set. - -A transform call flows down through these layers: - -``` -mkl_fft.interfaces.numpy_fft / scipy_fft drop-in NumPy/SciPy adapters -mkl_fft (__init__.py) public FFT API -mkl_fft/_mkl_fft.py, _fft_utils.py argument handling, normalization, dispatch -mkl_fft/_pydfti.pyx Cython bindings -mkl_fft/src/mklfft.c.src -> mklfft.c C backend, generated at build time -oneMKL DFTI -``` +Style is loose, and the pre-commit hooks enforce most of it: -Directories: - -- **`mkl_fft/`** — the package. `__init__.py` is the public API surface; - `_mkl_fft.py` and `_fft_utils.py` hold the Python-level FFT logic; - `_pydfti.pyx` is the Cython binding layer. -- **`mkl_fft/src/`** — the C backend, written as `*.c.src` templates. At build - time `_vendored/process_src_template.py` expands `mklfft.c.src` into - `mklfft.c`, which is compiled into the `_pydfti` extension. The generated - `.c` is regenerated on every build, so only template edits survive. -- **`mkl_fft/interfaces/`** — adapters presenting `numpy.fft`- and - `scipy.fft`-shaped APIs. `numpy_fft.py` and `scipy_fft.py` are the public - modules; the `_`-prefixed siblings are implementation. Upstream signatures and - semantics are the contract here. -- **`mkl_fft/`** patching layer — `patch.py`, `with_patch.py`, `_patch_numpy.py`, - `_patch_startup.py`, and the `__main__.py` CLI implement the monkey-patching - entry points documented in the README. The contract is that patching stays - reversible and observable: anything installed can be uninstalled, and - `is_patched()` reports the truth. -- **`mkl_fft/tests/`** — the suite. `helper.py` holds shared utilities and - `third_party/` carries tests adapted from upstream projects. -- **`_vendored/`** — build-time code-generation helpers vendored from NumPy. - They are excluded from `black` and `isort` in `pyproject.toml`. -- **`conda-recipe/`**, **`conda-recipe-cf/`** — Intel-channel and conda-forge - packaging. -- **`benchmarks/`** — ASV benchmarks, run with the `benchmark` extra. - -Each of these directories has an `AGENTS.md` stating the same boundaries for -coding agents; [`AGENTS.md`](AGENTS.md) at the root indexes them and is a useful -orientation map for humans too. +- Python and Cython are formatted with `black` and `isort`, with a line length + of 80. +- C sources follow the repository's `.clang-format`. +- Otherwise, match the surrounding code. ## Dos and don'ts @@ -137,8 +88,10 @@ orientation map for humans too. - Add tests in `mkl_fft/tests/` alongside behavior changes, and a regression test with every bug fix. - Keep tests deterministic. -- Edit the `*.c.src` templates for C backend changes. -- Keep patching reversible and observable. +- Edit the `*.c.src` templates in `mkl_fft/src/` for C backend changes. The + `.c` files are generated from them on every build. +- Keep patching reversible and observable: anything installed can be + uninstalled, and `is_patched()` reports the truth. - Cite the source-of-truth file for mutable details: `pyproject.toml`, `meson.build`, `conda-recipe*/meta.yaml`, `.github/workflows/`. - Give benchmark numbers reproducible context — hardware, versions, and the diff --git a/README.md b/README.md index 1bd73285..638cc581 100644 --- a/README.md +++ b/README.md @@ -170,5 +170,5 @@ pip install scipy # Contributing See [CONTRIBUTING.md](CONTRIBUTING.md) for the development workflow: setting up a -build environment, running the tests and lint hooks, how the Python, Cython, and -C template layers fit together, and what to include in a pull request. +build environment, running the tests and lint hooks, code style, and what to +include in a pull request.