Skip to content

PRIK 0.4.2

Choose a tag to compare

@saidctb saidctb released this 31 Aug 10:50
· 11 commits to main since this release
  • The jupyter extra now accepts IPython 7.0 and newer instead of requiring
    8.0. The cell magics use only long-stable IPython APIs, and the higher floor
    made pip install prik[jupyter] upgrade the IPython that hosted notebook
    environments ship, which forced a runtime restart for no benefit. The qa
    extra installs prik[jupyter] rather than repeating that requirement, so
    the supported IPython range is stated once.

  • Added a runnable examples/notebooks/quickstart.ipynb and its guided
    tutorial, covering a Fortran cell, a C cell, and reshaping the generated API
    by editing its semantic contract in the same session. The home page, Getting
    Started, the tutorial, and the README offer it as a Colab run or a direct
    download, so the documented workflow can be tried before installing anything.

  • 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,
    so the same completed decision reaches a bridged Fortran character(len=1)
    dummy and a direct bind(C) entrypoint. Policy completion requires exactly
    one byte-representable character; invalid values and longer fixed-length
    literals are rejected before planning.

  • A @native_call computed projection can now state the integer type it is
    materialized as: Int32(Arg(0).shape[0]) beside the existing Int32(1)
    literal form. Shape, stride and length producers previously always crossed
    the boundary as SizeT, which is the right identity for a C size_t
    parameter but not for a default Fortran INTEGER, so those parameters had to
    stay visible in the Python signature. Fixed-width signed and unsigned integer
    contract types and SizeT are accepted; unresolved Int and UInt are
    rejected before planning. The explicit conversion is not range-checked.

  • Renamed the exact C scalar mechanism from "cast" to "identity" throughout the
    semantic IR and policy, matching the documented Exact C Scalar Identities
    vocabulary and freeing "cast" for the conversion above. The public contract
    helpers (CInt, CLongLong, and the rest) are unchanged. The semantic-IR
    JSON record emitted by prik semantics --json renames its native_cast
    projection key to native_c_identity and gains a value_cast key.

  • Added a Pythonic BLAS tutorial and runnable example that reshape DDOT,
    DNRM2, DGEMV and DGEMM into dot, norm, matvec and matmul, plus
    DenseMatrix. An edited .pyi contract owns the exact native mapping,
    extents, leading dimensions, transposition modes, array validation, fixed
    numeric values and result allocation. Matrix operations consume
    Fortran-contiguous storage directly, while DenseMatrix converts its matrix
    once at construction. The example reuses the existing Reference BLAS sources
    in a four-file contract, Python API, build and test workflow. The .pyi
    reference now states the native identity of shape and stride projections and
    the declared-character-literal form.

  • Reduced clean-build time for large projects under optimizing compiler flags.
    Generated bindings now bind each ordinary array argument through one shared
    prik_bind_array helper instead of emitting the whole validate, extract, and
    native-handle sequence at every array argument of every wrapper. A wrapper
    carries one call and a small table of required extents in place of the
    sequence, so the compiler optimizes the binding logic once rather than once
    per argument per wrapper. Building the 155-source reference BLAS with
    -O3 -march=native emits about a third less binding code and compiles it
    about 1.4x faster.

  • A binding is always one generated C file. Large procedure-only projects were
    previously split across <module>_wrapper_001.c and siblings so those units
    could compile concurrently; every project now generates only
    <module>_wrapper.c. Splitting raised total compiler work — each unit
    re-parsed Python.h and the NumPy headers — and paid off only where cores
    were idle, which a project's own sources rarely leave. Removing it lowers
    total build work and leaves one file to read when inspecting generated
    output.