Skip to content
Draft
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
3 changes: 0 additions & 3 deletions .github/workflows/ci-cmake_tests.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
name: Tests and Codecov
on:
pull_request:
branches:
- master
workflow_dispatch:
jobs:
BuildAndTest:
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/clang-format-check.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
name: clang-format Check
on:
pull_request:
workflow_dispatch:
jobs:
formatting-check:
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/conda_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ on:
push:
branches:
- master
pull_request:
branches:
- master
workflow_dispatch:

jobs:
Expand Down
78 changes: 78 additions & 0 deletions .github/workflows/release_pypi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: Release to PyPI

on:
pull_request:
workflow_dispatch:

jobs:
BuildWheel:
name: BuildWheel-${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-14, macos-15-intel]
# os: [ubuntu-latest]
defaults:
run:
shell: bash -l {0}

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

# When re-running a PR job, GitHub Actions uses the merge commit created at
# the time of the original run, not a fresh merge with the latest target branch.
# This step ensures we always test against the most recent target branch.
- name: Merge with latest target branch (pull_request only)
if: github.event_name == 'pull_request'
run: |
git fetch origin ${{ github.event.pull_request.base.ref }}
git merge --no-edit origin/${{ github.event.pull_request.base.ref }}

- name: Cache Ccache Directory (pull_request)
if: ${{ github.event_name == 'pull_request' }}
uses: actions/cache@v4
with:
path: |
~/.ccache
key: ccache-${{ runner.os }}-${{ github.event.pull_request.head.ref }}-${{ github.sha }}
restore-keys: |
ccache-${{ runner.os }}-${{ github.event.pull_request.head.ref }}-
ccache-${{ runner.os }}-${{ github.event.pull_request.base.ref }}-

- name: Set Ccache Directory
run: |
echo "Start building---------------------------------"
export CCACHE_DIR="${HOME}/.ccache"

- name: Setup macOS
if: matrix.os == 'macos-15-intel' || matrix.os == 'macos-14'
run: |
if [[ ${{ matrix.os }} == 'macos-15-intel' ]]; then
echo "MACOSX_DEPLOYMENT_TARGET=15.0" >> "$GITHUB_ENV"
elif [[ ${{ matrix.os }} == 'macos-14' ]]; then
echo "MACOSX_DEPLOYMENT_TARGET=14.0" >> "$GITHUB_ENV"
fi

- name: Build Wheels
uses: pypa/cibuildwheel@v3.3.0
env:
CMAKE_C_COMPILER_LAUNCHER: ccache
CMAKE_CXX_COMPILER_LAUNCHER: ccache
CMAKE_CUDA_COMPILER_LAUNCHER: ccache
# DO NOT enable this line because the script for conda build is not
# executed in a interactive shell, and "~" will not be expanded to the
# home directory. Export CCACHE_DIR in the run command instead.
# CCACHE_DIR: ~/.ccache
CCACHE_MAXSIZE: 1G # The limit of actions/cache is 10GB
# Pass environment variables into cibuildwheel build environments
# This is only needed on Linux becuase the wheels are built in docker
# images only on Linux.
CIBW_ENVIRONMENT_PASS_LINUX: CMAKE_C_COMPILER_LAUNCHER CMAKE_CXX_COMPILER_LAUNCHER CMAKE_CUDA_COMPILER_LAUNCHER CCACHE_MAXSIZE

- uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
path: ./wheelhouse/*.whl
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,14 @@ if(USE_CUDA)
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS 0)
endif()


# Print all environment variables for debugging
message(STATUS "==================== Environment Variables ====================")
execute_process(COMMAND ${CMAKE_COMMAND} -E environment
OUTPUT_VARIABLE ENV_OUTPUT)
message(STATUS "${ENV_OUTPUT}")
message(STATUS "================================================================")

# C++ uses link-time optimization anyway; this enables additionally -flto=auto,
# for parallel compilation
# It cannot enable on MacOS since it causes building errors when linking the library libcytnx.a.
Expand Down
32 changes: 32 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ cmake.args = [
# conflicts against the build process of HPTT.
"-G Unix Makefiles",
]
# Force the build directory to be "build" instead of a random temp folder. This helps
# ccache caches the compiler outputs successfully.
build-dir = "build/{wheel_tag}"
# cp39-cp39-macosx_14_0_arm64

[tool.scikit-build.metadata.version]
provider = "scikit_build_core.metadata.regex"
Expand All @@ -53,3 +57,31 @@ set\(\w+?VERSION_MINOR\s+(?P<minor>\d+)\)
set\(\w+?VERSION_PATCH\s+(?P<patch>\d+)\)
'''
result = "{major}.{minor}.{patch}"

[tool.cibuildwheel]
# The image used to build wheels for x86_64 on Linux is manylinux_2_28, which supports
# older version of Linux than manylinux_2_34. However, manylinux_2_28 is AlmaLinux 8
# based and AlmaLinux 8 ships Boost v1.66. The Boost's CMake configuration files are only
# available since v1.70, so AlmaLinux 9 based manylinux_2_34 is picked here.
# There is a caveat for manylinux_2_34. manylinux_2_34 assume the machines use x86-64-v2
# architecture which is an extension of x86_64, so the wheels built with manylinux_2_34
# may not support older machines. See https://github.com/pypa/manylinux?tab=readme-ov-file#manylinux_2_34-almalinux-9-based---alpha
# for more information.
manylinux-x86_64-image = "manylinux_2_34"
before-build = "python ./tools/cibuildwheel_before_build.py"

[tool.cibuildwheel.linux]
# before-all = "apt-get install -y arpack boost ccache libomp openblas"
before-all = "bash ./tools/cibuildwheel_before_all.sh"
# To include LAPACKE header.
environment = { CMAKE_PREFIX_PATH = "/usr/include/openblas", CCACHE_CONFIGPATH = "~/ccache.conf" }

[tool.cibuildwheel.macos]
before-all = "brew update; brew install arpack boost ccache libomp openblas"
environment = { CMAKE_PREFIX_PATH = "$(brew --prefix arpack):$(brew --prefix boost):$(brew --prefix libomp):$(brew --prefix openblas)", PATH = "$(brew --prefix ccache)/libexec:$PATH", CCACHE_CONFIGPATH = "~/ccache.conf" }

# [tool.cibuildwheel]
# before-build = "bash {project}/tools/cibuildwheel_before_build.sh"
# # environment = { CMAKE_PREFIX_PATH = "$(brew --prefix openblas)", PATH = "$(brew --prefix ccache)/libexec:$PATH" }
# # Alternative static configuration for macOS:
# environment = { CMAKE_PREFIX_PATH = "/opt/homebrew/opt/openblas", PATH = "/opt/homebrew/opt/ccache/libexec:$PATH" }
18 changes: 18 additions & 0 deletions tools/cibuildwheel_before_all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
set -xe

yum search lapack
yum --showduplicates list "lapack*"
# yum install -y arpack-devel boost-devel ccache lapack-devel libomp-devel openblas-devel
yum install -y arpack-devel boost-devel ccache libomp-devel openblas-devel
# On Red Hat/CentOS systems (which manylinux images are based on), the lapack-devel
# package typically provides the Fortran bindings and miss the C-interface header, so
# use lapacke.h shipped with openblas instead.
ls /usr/include
ln -s /usr/include/openblas/lapacke.h /usr/include/lapacke.h
ln -s /usr/include/openblas/lapack.h /usr/include/lapack.h
ln -s /usr/include/openblas/lapacke_mangling.h /usr/include/lapacke_mangling.h

ls /usr/include/openblas
# boost1.78-devel
# ls /usr/include/boost | head
# ls /usr/lib64/libboost_*.so
22 changes: 22 additions & 0 deletions tools/cibuildwheel_before_build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import os
import pathlib
import sys

import packaging.tags
tag = f'cp{sys.version_info.major}{sys.version_info.minor}'

ccache_config_path = os.getenv('CCACHE_CONFIGPATH')
if not ccache_config_path:
raise RuntimeError('The CCACHE_CONFIGPATH environment variable must be set.')

print("ccache_config_path:", ccache_config_path)
print("ccache_config_path:", pathlib.Path(ccache_config_path).absolute())


wheel_tag = str(next(packaging.tags.sys_tags()))
print("wheel_tag:", wheel_tag)

with open(ccache_config_path, 'w') as f:
f.writelines([
f'base_dir = /project/build/{wheel_tag}'
])
55 changes: 55 additions & 0 deletions tools/cibuildwheel_before_build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
set -xe

# Install OpenBLAS
# python -m pip install scipy-openblas64
# blas_lib_dir=$(python -c "import scipy_openblas64; print(scipy_openblas64.get_lib_dir())")
# blas_lib_name=$(python -c "import scipy_openblas64; print(scipy_openblas64.get_library())")
# # This handles different extensions (.so on Linux, .dylib on macOS)
# blas_lib_file=$(find "$blas_lib_dir" -name "*${blas_lib_name}.*" -type f | head -n 1)
# export BLAS_LIBRARIES="$blas_lib_file"

# # Verify BLAS_LIBRARIES points to an existing file
# if [ -f "$BLAS_LIBRARIES" ]; then
# echo "✓ BLAS_LIBRARIES points to existing file: $BLAS_LIBRARIES"
# else
# echo "✗ ERROR: BLAS_LIBRARIES does not point to a valid file: $BLAS_LIBRARIES"
# exit 1
# fi

# BLA_SIZEOF_INTEGER=8 matches the ILP64 openblas64_ interface
# that scipy-openblas64 provides; this avoids CMake thinking
# it found a 32-bit BLAS.
# export BLA_SIZEOF_INTEGER=8


uname -s
# Set up Homebrew for Linux
# Homebrew was removed from PATH on Linux:
# https://github.com/actions/runner-images/issues/6283
if [[ "$(uname -s)" == "Linux" ]]; then
# Find linuxbrew from root folder recursively
# Common locations: /home/linuxbrew/.linuxbrew, /home/*/linuxbrew/.linuxbrew
# brew_find=$(find / -name "*linuxbrew*" -type d 2>/dev/null)
# linuxbrew_bin=$(echo $brew_find | head -n 1)
# if [ -n "$linuxbrew_bin" ] && [ -d "$linuxbrew_bin/bin" ]; then
# echo "Found linuxbrew at: $linuxbrew_bin"
# export PATH="$linuxbrew_bin/bin:$PATH"
# else
# echo "Warning: linuxbrew not found, trying default path"
# export PATH="/home/linuxbrew/.linuxbrew/bin:$PATH"
# fi
export PATH="/host/home/linuxbrew/.linuxbrew/bin:$PATH"
fi

# Install boost, ccache and arpack-ng
# All Ubuntu and macOS GitHub action runners have Homebrew installed.
brew install boost ccache arpack openblas

brew --prefix openblas
ls $(brew --prefix openblas)
brew --prefix ccache
ls $(brew --prefix ccache)
brew --prefix arpack
ls $(brew --prefix arpack)
brew --prefix boost
ls $(brew --prefix boost)
Loading