============================
SESUM COMPILATION GUIDE
============================

Requirements:
-------------
Please search online on how to install these for your specific system:
- CMake
- GCC
- G++
- Python (ensure Numpy is installed)

Platform-Specific Requirements:
-------------------------------
- Windows:
  * Install the compiler: MinGW Distro 18.0
    Download link: https://nuwen.net/mingw.html
    After installation, remember to add the path to the compiler binaries to your system's PATH.
    You do not need a separate Boost installation, it is included in the MinGW Distro.

- macOS:
  * Use GCC from Homebrew. 
    Download link: https://formulae.brew.sh/formula/gcc


Compilation Steps:
--------------------------------------
Summary:

cmake -S . -B build-portable -DCMAKE_BUILD_TYPE=Release
cmake --build build-portable --target sr -j 8

The default is distributable on the current architecture: AVX2 on x86-64,
ARMv8-A on Linux ARM64, and the existing portable compiler defaults on Apple
and Windows ARM64.

Detailed instructions:

1. Configure and build a portable baseline:

- For macOS, provide the Homebrew GCC version installed:

CXX=g++-12 CC=gcc-12 cmake -S . -B build-portable -DCMAKE_BUILD_TYPE=Release
cmake --build build-portable --target sr -j 8

- For other platforms:

cmake -S . -B build-portable -DCMAKE_BUILD_TYPE=Release
cmake --build build-portable --target sr -j 8

2. x86-64 variants:

The default x86-64 profile is the portable AVX2 baseline. To build both
distributable variants on the same AVX-512 machine, use separate build
directories. These profiles are explicit and do not depend on the CPU of the
build host:

cmake -S . -B build-avx2 -DCMAKE_BUILD_TYPE=Release -DSESUM_X86_TARGET=avx2
cmake --build build-avx2 --target sr -j 8

cmake -S . -B build-avx512 -DCMAKE_BUILD_TYPE=Release -DSESUM_X86_TARGET=avx512
cmake --build build-avx512 --target sr -j 8

The avx2 profile targets the common Haswell-class AVX2 feature set and
explicitly disables AVX-512. The avx512 profile targets the Skylake-X
AVX-512F/CD/DQ/BW/VL feature set. Sesum verifies the corresponding CPU and
operating-system register support before loading either library.

For local profiling only, a host-tuned build remains available:

cmake -S . -B build-native -DCMAKE_BUILD_TYPE=Release -DSESUM_X86_TARGET=native
cmake --build build-native --target sr -j 8

Native builds are stored in `sesum/<platform>_native`. They are not selected
automatically and are never included in a wheel.

At runtime, x86-64 Sesum automatically selects the highest supported library
that is actually present. It uses AVX-512 only when both the CPU/OS state and
the `<platform>_avx512` library satisfy the AVX-512F/CD/DQ/BW/VL contract; it
otherwise falls back to the available `<platform>_avx2` library. A native
library is never selected by this automatic path.

Two environment variables provide explicit expert/debug overrides:

- `SESUM_FORCE_X86_VARIANT=avx2|avx512|native` selects exactly
  `sesum/<platform>_<variant>/libsr.<platform suffix>`.
- `SESUM_LIBRARY_DIR=/path/to/dir` bypasses the packaged layout completely and
  loads the platform-specific `libsr` filename from that exact directory.

These are deliberate trust overrides. When either is set, verifying that the
chosen library's ABI and instruction set are compatible with the running
Python process and CPU/OS state is the user's responsibility.

3. Linux ARM64 variants:

The default Linux ARM64 profile uses the portable ARMv8-A baseline and writes
`sesum/linux_arm64/libsr.so`. It can also be selected explicitly:

cmake -S . -B build-arm64 -DCMAKE_BUILD_TYPE=Release -DSESUM_LINUX_ARM64_TARGET=portable
cmake --build build-arm64 --target sr -j 8

A host-tuned Linux ARM64 build is intended only for local profiling:

cmake -S . -B build-arm64-native -DCMAKE_BUILD_TYPE=Release -DSESUM_LINUX_ARM64_TARGET=native
cmake --build build-arm64-native --target sr -j 8

It is stored in `sesum/linux_native` and is never packaged. Apple ARM64 and
Windows ARM64 retain their existing portable build behavior.

Note: 
The "sesum" folder now has the dynamic library named 'libsr'.
'libsr' is stored in nine portable backend subfolders in the release source
tree. A normal installed platform wheel contains only the backends for its
operating system and process architecture: both AVX2 and AVX-512 on x86-64,
or the single ARM64 backend on ARM64. At runtime, `sr.py` loads exactly the
compatible backend present in that wheel.

To create all six platform wheels, collect these nine release artifacts in the
source tree first:

sesum/linux_arm64/libsr.so
sesum/linux_avx2/libsr.so
sesum/linux_avx512/libsr.so
sesum/mac_arm64/libsr.dylib
sesum/mac_avx2/libsr.dylib
sesum/mac_avx512/libsr.dylib
sesum/windows_arm64/libsr.dll
sesum/windows_avx2/libsr.dll
sesum/windows_avx512/libsr.dll

The Windows ARM64 wheel additionally contains `windows_arm64/libomp.dll`.
Then install the packaging tools and build the complete release set:

pip install wheel setuptools

cd wheel_build
python setup.py bdist_platform_wheels

The command builds Linux x86-64, Linux ARM64, macOS x86-64, macOS ARM64,
Windows x86-64, and Windows ARM64 wheels in isolated temporary directories.
Both Linux wheels use the `manylinux_2_18` compatibility floor and therefore
target mainstream glibc 2.18-or-newer systems; installing perennial manylinux
tags requires pip 20.3 or newer. Alpine/musl is not covered.
Only after all six pass their architecture, dependency, payload, ZIP CRC,
platform-tag, and RECORD validation are they copied to `wheel_build/dist/`.
Every wheel also contains the complete buildable source as `sesum/src/src.zip`.
A missing, empty, fat, mislabeled, or dynamically runtime-dependent portable
backend stops the release build. Host-tuned `<platform>_native` directories
are never included.

All six files use the same package name and version, so users still install
Sesum normally and `pip` chooses the compatible wheel automatically:

pip install sesum

To build only one target, set `SESUM_WHEEL_TARGET` to one of
`linux_x86_64`, `linux_arm64`, `mac_x86_64`, `mac_arm64`,
`windows_x86_64`, or `windows_arm64`, and run `python setup.py bdist_wheel`.
Leaving the variable unset preserves the optional combined/offline wheel with
all nine backends and all six platform tags.


Usage:
--------------------------------------
Refer to "main_sesum.py" for usage instructions.

Happy coding!
