Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ examples, build or CI workflows, benchmark methodology, or documented
limitations. Keep entries concise and outcome-focused; do not add release
notes for internal cleanup that has no visible effect.

Write user documentation as a concise guide to the current product. Lead with
the task a user wants to complete, show the necessary command or example, and
state only the behavior, choices, and limitations needed to use it correctly.
Do not narrate implementation history, prior bugs, rejected designs, internal
mechanics, defensive checks, or why a newly added behavior differs from an old
one unless that context changes what the user must do. Integrate changes into
the existing workflow instead of appending a change report, and remove any
sentence whose only purpose is to justify the implementation or record the
development process.

Treat developer documentation as durable guides, not as per-change
implementation logs. Do not update developer pages merely because code changed,
and do not add incidental low-level details that are unnecessary for following
Expand Down
63 changes: 63 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,69 @@ release tags add a leading `v` to the package version.

## Unreleased

- Generated contracts now represent a one-level primitive C pointer as
runtime-rank `T[...]` NumPy storage instead of choosing a scalar temporary.
It accepts ranks 0 through 15 with any strides, so a Fortran-ordered array
or a strided slice reaches the native call unchanged, and it can be narrowed
to contiguous, rank-zero, fixed-rank, or scalar-address storage in an edited
contract. `Arg(i).size` supplies the total element count to a native
parameter, alongside the existing `Arg(i).shape[d]` and `Arg(i).strides[d]`
layout projections; an axis projection against storage that has no such axis
now raises `TypeError` instead of reading past the actual's shape.

- Getting Started now offers complete Fortran and C paths for toolchain
verification, building the same first function, and the edit-review-build-test
loop. Fortran modules now begin in their task-focused User Guide page instead
of a separate mandatory beginner step.

- Added a dedicated C section to the User Guide for scalar functions, pointer
contracts, arrays and strings, outputs and errors, and native symbols and
dependencies. The C Support page now serves as a concise capability and
boundary map with the same wrapper-area, boundary, and source-entry structure
as Fortran Support. User Guide navigation presents separate Fortran and C
paths followed by their shared build workflows.

- An array argument now requires the NumPy storage of the C element type its
source declares, rather than the canonical storage of the same width. A
target's `int64_t` may be `long` or `long long`, and NumPy independently
gives `NPY_INT64` to whichever of the two is 64 bits, so those two choices
could disagree: a `long long *` buffer asked for `numpy.longlong` on one
target and `numpy.int64` on another. One C source now keeps one accepted
dtype everywhere.

- A scalar argument whose native parameter is a 64-bit C integer now accepts
either NumPy spelling of that width and converts it, so `np.int64` and
`np.longlong` are both valid for a `long long` or `long` parameter whichever
one the target calls `int64_t`. Array arguments are unchanged: an element
buffer cannot be converted, so it still requires the exact native dtype.

- A cell magic that reads a dash-prefixed flag value as another option now
names the equals form and, for the flag groups, the quoted-group form.

- Added optional `%%fortran`, `%%c`, and `%%pyi` IPython/Jupyter cell magics.
Native-source cells compile directly or, with `--pyi`, persist their exact
source and insert editable per-module or direct-declaration contract cells.
Executing the generated `%%pyi` cell recovers the source language from its
digest, builds against that cached source, and publishes declared Fortran
modules or standalone declarations directly in the notebook namespace.
Exact cells reuse a persistent SHA-256 build cache unless `--force` is
selected, and PRIK does not expose an internal package entry. Wrapped
functions follow the published notebook path (`maths.square` or standalone
`square`) instead of exposing the private cache extension name; ordinary
file builds retain their user-selected package root, such as
`geometry.maths.square`. Existing notebook build artifacts are rebuilt once
so cached extensions cannot retain the old private function identity.
Multi-module `--pyi` cells are presented sequentially in terminal IPython,
whose next-input prompt can hold only one editable contract, while Jupyter
frontends continue to receive every generated module cell immediately. All
cells in one generated contract bundle retain the source cell's effective
compiler and build flags; changing that configuration requires regenerating
the bundle and is rejected before compiler execution. Independently authored
`%%pyi` cells can instead name one or more existing implementation files with
`--native-fortran-sources` or `--native-c-sources`; each cell builds and
publishes only its own contract module, and native file-content changes
invalidate its persistent cache.

- A one-character `@native_call` literal is now buildable: `String[1]("N")`
declares the character a native parameter receives instead of leaving it a
visible Python argument. It crosses the boundary as an interoperable `char`,
Expand Down
47 changes: 37 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ public APIs may still change before `1.0`.
PRIK supports both languages. Fortran currently has the broader, more mature
wrapper surface. C currently supports a focused wrapper subset: primitive
values, one-level pointers, NumPy arrays, and strings. In both languages, editable
`.pyi` contracts let you shape the Python API. See [C
`.pyi` contracts let you shape the Python API. See the [C User
Guide](https://pynumlab.github.io/prik/user/guide/c/) for C workflows and [C
Support](https://pynumlab.github.io/prik/user/language-support/c-support/) for
C examples and current limits.
current coverage.

[Read the documentation](https://pynumlab.github.io/prik/) for installation,
the user guide, examples, and reference material.
Expand All @@ -40,6 +41,7 @@ the user guide, examples, and reference material.
- [C support](#c-support)
- [Current C limitations](#current-c-limitations)
- [Installation & Quick Start](#installation--quick-start)
- [IPython and Jupyter](#ipython-and-jupyter)
- [How it works](#how-it-works)
- [Python API](#python-api)
- [Development](#development)
Expand Down Expand Up @@ -183,7 +185,8 @@ compiler matrix; each project guide also records its own tested platforms.
## Key Features

- **Native APIs that feel like Python.** Fortran modules become Python
namespaces, while derived types become classes with fields and methods.
namespaces, derived types become classes, and C functions expose designed
scalar, array, string, and output interfaces.
- **First-class NumPy array interop.** Pass ordinary NumPy arrays to native
procedures, including multidimensional and in-place data, with generated
dtype, shape, layout, and mutability handling at the language boundary.
Expand All @@ -194,6 +197,9 @@ compiler matrix; each project guide also records its own tested platforms.
- **Editable contracts for reshaping APIs.** Edit the generated `.pyi` contract to
rename, hide, reorganize, or overload the public interface, backed by readable
generated docstrings.
- **Interactive notebook builds.** Compile Fortran and C cells with
`%%fortran` and `%%c`, or edit a generated semantic contract in a `%%pyi`
cell.
- **Unsupported contracts fail before the build.** PRIK identifies the exact
boundary and reason before attempting code generation or compilation.

Expand Down Expand Up @@ -241,7 +247,7 @@ code generation with a diagnostic naming the boundary and the reason.

The [language feature matrix](https://pynumlab.github.io/prik/user/language-support/feature-matrix/)
records the full support status of every feature with its evidence. The
[C support guide](https://pynumlab.github.io/prik/user/language-support/c-support/)
[C Support page](https://pynumlab.github.io/prik/user/language-support/c-support/)
states the current C wrapper boundary.

## C support
Expand Down Expand Up @@ -334,8 +340,8 @@ structs, unions, function pointers, or callbacks. Unsupported declarations
stop before wrapper generation or compilation; parsing a declaration alone does
not promise that it can be built.

[Read the C support guide for executable source, `.pyi`, CLI, and Python API
examples.](https://pynumlab.github.io/prik/user/language-support/c-support/)
[Continue with the C User Guide for source, `.pyi`, CLI, and Python API
workflows.](https://pynumlab.github.io/prik/user/guide/c/)

## Installation & Quick Start

Expand Down Expand Up @@ -435,6 +441,24 @@ The custom wrapper flags appear in the relevant command lines:
<fortran compiler> -shared ... -O2 ... geometry_debug ...
```

## IPython and Jupyter

Install the optional notebook integration and load it once per session:

```bash
python3 -m pip install "prik[jupyter]"
```

```ipython
%load_ext prik.jupyter
```

Use `%%fortran` or `%%c` to compile native source in a cell. Add `--pyi` to
review and edit the generated contract before compilation, or use `%%pyi` with
existing native source files. See [IPython and Jupyter
Notebooks](https://pynumlab.github.io/prik/user/guide/notebooks/) for the
complete workflow.

## How it works

```text
Expand Down Expand Up @@ -470,7 +494,8 @@ print(result.shared_library)

Use `build_c_extension("api.c", output_dir="build")` for a C source build, or
`build_pyi_extension(..., native_language="c", native_c_sources=[...])`
for an authored C contract. The C support guide shows complete examples.
for an authored C contract. The [C User
Guide](https://pynumlab.github.io/prik/user/guide/c/) shows complete examples.

## Development

Expand Down Expand Up @@ -513,11 +538,13 @@ notice when redistributed.

- **[Documentation](https://pynumlab.github.io/prik/)** — Learn how to install and use PRIK
- **[Project Vision](https://github.com/PyNumLab/prik/wiki)** — Long-term direction for PRIK's semantic interoperability model
- **[Getting Started](https://pynumlab.github.io/prik/user/getting-started/)** — Installation, verification, standalone procedures, modules, and rebuild workflow
- **[User Guide](https://pynumlab.github.io/prik/user/guide/)** — Data types, functions, modules, arrays, derived types, callbacks, ownership, and runtime behavior
- **[Getting Started](https://pynumlab.github.io/prik/user/getting-started/)** — Installation, verification, matched Fortran and C first functions, and rebuild workflow
- **[User Guide](https://pynumlab.github.io/prik/user/guide/)** — Separate Fortran and C paths followed by shared build workflows
- **[C User Guide](https://pynumlab.github.io/prik/user/guide/c/)** — C functions, pointer contracts, arrays, strings, outputs, errors, symbols, headers, and dependencies
- **[IPython and Jupyter](https://pynumlab.github.io/prik/user/guide/notebooks/)** — Compile native cells and edit semantic contracts interactively
- **[`.pyi` Format](https://pynumlab.github.io/prik/user/reference/pyi-format/)** — Contract projects, declarations, decorators, types, storage, metadata, and C and Fortran forms
- **[Editing `.pyi` Contracts](https://pynumlab.github.io/prik/user/reference/pyi-contracts/)** — Supported recipes for reshaping the generated Python API
- **[C Support](https://pynumlab.github.io/prik/user/language-support/c-support/)** — C ABI scope, contracts, CLI, Python API, and executable examples
- **[C Support](https://pynumlab.github.io/prik/user/language-support/c-support/)** — Supported C wrapper areas, boundaries, source inputs, and public entry points
- **[CLI Reference](https://pynumlab.github.io/prik/user/reference/cli-commands/)** — Every command, option, and checked workflow
- **[Language Support](https://pynumlab.github.io/prik/user/language-support/)** — Supported, partially supported, and unsupported native-language features
- **[FAQ](https://pynumlab.github.io/prik/user/faq/)** — Concise answers to common questions
Expand Down
1 change: 1 addition & 0 deletions docs/developer/codebase-map.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ to its documentation and evidence.
| --- | --- |
| `prik/__init__.py` | Public build entry points and version. |
| `prik/cli.py` | CLI argument validation, stage selection, and output routing. |
| `prik/jupyter/` | Optional IPython cell-magic parsing, editable-contract cell insertion, persistent source/build caching, extension loading, and notebook namespace publication. |
| `prik/pipeline/build.py` | Source-first and contract-first extension-build orchestration. |
| `prik/pipeline/pyi.py` | Semantic `.pyi` loading and external-type reconciliation. |
| `prik/pipeline/wrapper.py` | Completed plan to rendered-wrapper orchestration and artifact records. |
Expand Down
4 changes: 2 additions & 2 deletions docs/developer/feature-to-code-map.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ change crosses a stage boundary.
| Derived objects, allocatables, pointers, and lifetimes | [Derived types](../user/guide/wrapping-derived-types.md), [allocatables](../user/guide/allocatables.md), [pointers](../user/guide/pointers.md), [memory management](../user/guide/memory-management.md) | `prik/policy/ownership.py` → `prik/policy/construction.py` → `prik/policy/native_array_handles.py` → `prik/planning/planner.py` → `prik/runtime/handles.py` | `tests/fortran/derived_types/`, `tests/fortran/allocatables/`, `tests/fortran/pointers/` |
| Callbacks | [Callbacks](../user/guide/callbacks.md) | `prik/policy/models.py` → `prik/policy/completion.py` → `prik/planning/planner.py` → `prik/codegen/c/binding.py` and `prik/codegen/fortran/bridge.py` | `tests/fortran/callbacks/` |
| Projected errors | [Error handling](../user/guide/error-handling.md) | `prik/policy/models.py` → `prik/policy/completion.py` → `prik/planning/planner.py` → `prik/codegen/c/binding.py` and `prik/codegen/fortran/bridge.py` | `tests/fortran/error_handling/` |
| C values, pointers, arrays, strings, outputs, and status | [C Support](../user/language-support/c-support.md) | `prik/semantics/c2ir.py` or `prik/semantics/pyi2ir.py` → `prik/policy/completion.py` → `prik/planning/planner.py` → `prik/codegen/c/binding.py` → `prik/pipeline/build.py` | `tests/c/primitive_scalars/`, `tests/c/primitive_pointers/`, `tests/c/primitive_strings/`, `tests/c/infrastructure/building/` |
| C binding-header symbol collisions | [Collision forwarders](../user/language-support/c-support.md#symbols-your-bindings-own-headers-declare) | `prik/pipeline/build.py` → `prik/planning/planner.py` → `prik/codegen/c/binding.py` → C-only compilation and link | `tests/c/symbol_collisions/codegen/`, `tests/c/symbol_collisions/end_to_end/` |
| C values, pointers, arrays, strings, outputs, and status | [C User Guide](../user/guide/c/index.md) | `prik/semantics/c2ir.py` or `prik/semantics/pyi2ir.py` → `prik/policy/completion.py` → `prik/planning/planner.py` → `prik/codegen/c/binding.py` → `prik/pipeline/build.py` | `tests/c/primitive_scalars/`, `tests/c/primitive_pointers/`, `tests/c/primitive_strings/`, `tests/c/infrastructure/building/` |
| C binding-header symbol collisions | [Collision forwarders](../user/guide/c/symbols-headers-and-dependencies.md#symbols-declared-by-binding-headers) | `prik/pipeline/build.py` → `prik/planning/planner.py` → `prik/codegen/c/binding.py` → C-only compilation and link | `tests/c/symbol_collisions/codegen/`, `tests/c/symbol_collisions/end_to_end/` |
| Native compilation, extension runtime, and public build API | [Compiler](packages/compiler.md), [Quality Assurance](workflows/quality-assurance.md) | `prik/__init__.py` → `prik/pipeline/build.py` → `prik/compiler/objects.py` → `prik/compiler/compilers.py` → `prik/compiler/native_support.py` → `prik/runtime/native_support/` | `tests/fortran/infrastructure/building/end_to_end/test_runtime_compatibility.py`, `tests/fortran/infrastructure/parsing/test_public_entrypoints.py` |

Each change route begins with the first owner for a capability; it is not a
Expand Down
8 changes: 8 additions & 0 deletions docs/developer/packages/codegen/c-binding.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ ModulePlan.binding + ModulePlan.entrypoint
`require_supported()` checks that the already selected primitive spellings are
available. It is capability preflight, not a second policy pass.

`BindingModulePlan` also supplies the public package root used for Python
function metadata. The binding combines that completed root with each planned
namespace path; it does not infer notebook execution or reuse the private
extension-loading name as presentation. An empty public root means the caller
is publishing directly into an interactive namespace. Generated filenames,
the `PyInit_*` symbol, and native helper symbols continue to use the plan's
internal owner path.

Numeric scalar boundaries retain their exact NumPy contract without using the
generic dtype-conversion path on a successful call. The native support helper
checks the planned NumPy scalar class, reads its typed payload directly, and
Expand Down
10 changes: 6 additions & 4 deletions docs/developer/packages/planning.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,12 @@ whether the binding or bridge implements the callable; the opposite side uses
the same record as its declaration/call contract. Static CPython helpers and
bridge-internal procedures are deliberately absent.

`BindingModulePlan` separately records which derived-type owners need
binding-local capsule and holder surfaces. Those static CPython helpers are not
entrypoints, but their membership is still planned rather than rediscovered by
C lowering. `BridgeModulePlan` likewise records the broad typed-holder
`BindingModulePlan` records the public Python package root separately from the
internal module owner used for generated symbols and extension loading. It also
records which derived-type owners need binding-local capsule and holder
surfaces. Those static CPython helpers are not entrypoints, but their membership
is still planned rather than rediscovered by C lowering. `BridgeModulePlan`
likewise records the broad typed-holder
definitions required by adapter calls and the narrower holder field-support
inventories. Planning derives both backend-local inventories and the external
support-procedure registry together. Validation requires every planned local
Expand Down
7 changes: 4 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ PRIK supports both languages. Fortran currently has the broader, more mature
wrapper surface. C currently supports a focused wrapper subset: primitive
values, one-level pointers, NumPy arrays, and strings. In both languages,
editable `.pyi` contracts let you shape the Python API. See [C
Support](user/language-support/c-support.md) for C examples and current limits.
User Guide](user/guide/c/index.md) for C workflows and [C
Support](user/language-support/c-support.md) for current coverage.

---

Expand Down Expand Up @@ -103,7 +104,7 @@ print(native_math.add(np.float64(3.0), np.float64(2.5))) # 5.5
```

This source build also writes an editable contract. For C pointers, arrays,
and authored contracts, see [C Support](user/language-support/c-support.md).
and authored contracts, see the [C User Guide](user/guide/c/index.md).

## Shape the Python API

Expand Down Expand Up @@ -324,7 +325,7 @@ values below `1.0×` favor f2py.

**Wrapping a supported C API?**

[Read C Support →](user/language-support/c-support.md){ .prik-primary-cta }
[Read the C User Guide →](user/guide/c/index.md){ .prik-primary-cta }

**Working on PRIK itself?**

Expand Down
2 changes: 1 addition & 1 deletion docs/user/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ native libraries through natural Python APIs.
PRIK supports **Fortran-to-Python and C-to-Python interoperability**, with a
focus on native behavior that traditional wrapper generators often cannot
represent reliably. In both languages, editable `.pyi` contracts let you shape
the Python API. The [C support guide](language-support/c-support.md) describes
the Python API. The [C Support](language-support/c-support.md) page describes
its current coverage. PRIK is for Python users who need native numerical,
scientific, or systems code without having to design and maintain the entire
language boundary themselves.
Expand Down
Loading
Loading