============================== Testing with SciPy and NumPy ============================== semicolon-lapack ships a Fortran-ABI compatibility layer (``libsemilapack_fortran``) that allows projects expecting a standard Fortran LAPACK to use our library as a drop-in replacement. This page explains how to build SciPy and NumPy against it and run their test suites. How the Fortran Shim Works -------------------------- Fortran LAPACK symbols follow specific conventions that differ from our C API. The shim library bridges these differences by performing three conversions at the boundary: 1. **Trailing underscore** -- Fortran compilers append ``_`` to symbol names. The shim exports ``dgetrf_`` which internally calls our ``dgetrf``. 2. **Pass-by-pointer** -- Fortran passes all arguments by reference. The shim accepts pointer arguments and dereferences them before calling the C function. 3. **Index conversion** -- Our library uses 0-based indexing; Fortran LAPACK uses 1-based. The shim converts pivot arrays, ``ilo``/``ihi`` parameters, and other index quantities at the boundary so that callers and the library each see the convention they expect. The shim is generated by ``scripts/generate_fortran_shim.py`` from the public headers and built as a shared library (``libsemilapack_fortran.so``). A pkg-config file ``semicolon-lapack-fortran.pc`` is installed alongside it. Prerequisites ------------- - A conda environment with OpenBLAS, a C compiler, Meson, and Ninja. - Source checkouts of SciPy and/or NumPy. - The ``spin`` developer build tool (bundled with both projects). The examples below assume a conda environment called ``scipy-dev`` with OpenBLAS installed. Adjust paths if your setup differs. Step 1: Build and Install semicolon-lapack ------------------------------------------ .. code-block:: bash meson setup builddir --prefix=/tmp/semilapack -Dfabi_shim=true ninja -C builddir meson install -C builddir The ``-Dfabi_shim=true`` option enables the Fortran shim. Without it, only the native C library is built. After installation, the prefix contains: .. code-block:: text /tmp/semilapack/ ├── include/semicolon_lapack/... └── lib64/ ├── libsemilapack.a ├── libsemilapack_fortran.so └── pkgconfig/ ├── semicolon-lapack.pc └── semicolon-lapack-fortran.pc .. note:: The library directory may be ``lib/`` or ``lib64/`` depending on the platform. Check which one your Meson install produces and adjust ``PKG_CONFIG_PATH`` accordingly in the steps below. Step 2: Build SciPy -------------------- .. code-block:: bash cd /path/to/scipy spin build --clean \ -S -Dlapack=semicolon-lapack-fortran \ -S -Dpkg_config_path=/tmp/semilapack/lib64/pkgconfig:$CONDA_PREFIX/lib/pkgconfig ``-Dlapack=semicolon-lapack-fortran`` tells SciPy's Meson build to resolve the LAPACK dependency using our pkg-config package name instead of the default auto-detection. BLAS is left on auto and picks up OpenBLAS from conda. The chained ``pkg_config_path`` ensures both our install prefix and conda's OpenBLAS are visible to pkg-config. .. note:: SciPy's ``spin`` passes Meson setup arguments with the ``-S`` flag. Step 3: Build NumPy ------------------- .. code-block:: bash cd /path/to/numpy git submodule update --init spin build --clean -- \ -Dlapack=semicolon-lapack-fortran \ -Dpkg_config_path=/tmp/semilapack/lib64/pkgconfig:$CONDA_PREFIX/lib/pkgconfig The ``git submodule update --init`` step is required on a fresh clone because NumPy vendors its own copy of Meson as a submodule. .. note:: NumPy's ``spin`` uses ``--`` to separate Meson arguments from spin's own flags, whereas SciPy uses ``-S``. Step 4: Run Tests ----------------- **SciPy:** .. code-block:: bash cd /path/to/scipy spin test # full suite spin test -s linalg # linear algebra spin test -s sparse.linalg # sparse solvers (includes ARPACK) spin test -s optimize # optimization **NumPy:** .. code-block:: bash cd /path/to/numpy spin test # full suite Troubleshooting --------------- **pkg-config cannot find ``semicolon-lapack-fortran``** Verify that ``PKG_CONFIG_PATH`` includes the directory containing ``semicolon-lapack-fortran.pc``. Run ``pkg-config --modversion semicolon-lapack-fortran`` to confirm. **NumPy's ``spin build`` rejects ``-S``** NumPy and SciPy use different ``spin`` conventions for passing Meson arguments. NumPy expects ``-- -Dkey=value``; SciPy expects ``-S -Dkey=value``. **NumPy fails with "vendored-meson/meson submodule does not exist"** Run ``git submodule update --init`` in the NumPy source directory. **Wrong OpenBLAS picked up at runtime** If tests crash or produce wrong results, the runtime linker may be loading a system OpenBLAS instead of the conda one. Check with ``ldd`` (Linux) or ``otool -L`` (macOS) on the built extension modules, and ensure ``$CONDA_PREFIX/lib`` appears in ``LD_LIBRARY_PATH`` or the rpath.