cpp-hf 1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,65 @@
1
+ name: build-and-test
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+ branches: [ main ]
8
+ # Allow manual runs even if disabled via variable
9
+ workflow_dispatch:
10
+
11
+ jobs:
12
+ build:
13
+ # Skip on push/PR when repo variable DISABLE_BUILD_AND_TEST == 'true'.
14
+ # Still allow manual runs via the Actions tab.
15
+ if: ${{ vars.DISABLE_BUILD_AND_TEST != 'true' || github.event_name == 'workflow_dispatch' }}
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ os: [ubuntu-latest, macos-latest]
20
+ python: ["3.10", "3.11", "3.12"]
21
+ runs-on: ${{ matrix.os }}
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+ with:
25
+ fetch-depth: 0
26
+
27
+ - uses: actions/setup-python@v5
28
+ with:
29
+ python-version: ${{ matrix.python }}
30
+
31
+ # System dependencies (FFTW, CMake). Eigen is fetched if missing.
32
+ - name: Install system deps (Linux)
33
+ if: runner.os == 'Linux'
34
+ run: |
35
+ sudo apt-get update
36
+ sudo apt-get install -y libfftw3-dev cmake ninja-build pkg-config libboost-dev
37
+
38
+ - name: Install system deps (macOS)
39
+ if: runner.os == 'macOS'
40
+ run: |
41
+ brew update
42
+ brew install fftw cmake ninja libomp boost || true
43
+
44
+ - name: Build wheel (scikit-build-core)
45
+ run: |
46
+ python -m pip install -U pip build numpy scikit-build-core
47
+ python -m build -w \
48
+ -C cmake.define.HF_USE_OPENMP=ON \
49
+ -C cmake.define.HF_USE_FFTW_THREADS=ON
50
+
51
+ - name: Install and smoke test
52
+ run: |
53
+ python -m pip install dist/*.whl
54
+ python - << 'PY'
55
+ import numpy as np, cpp_hf
56
+ nk,d=8,2
57
+ w=np.ones((nk,nk))*((2/nk)*(2/nk)/(2*np.pi)**2)
58
+ H=np.zeros((nk,nk,d,d),np.complex128)
59
+ K=np.linspace(-1,1,nk)
60
+ V=(1.0/np.sqrt((K[:,None]**2+K[None,:]**2)+0.2)).astype(np.complex128)[...,None,None]
61
+ P0=np.zeros_like(H)
62
+ ne=0.5*d*w.sum()
63
+ P,F,E,mu,n=cpp_hf.hartreefock_iteration_cpp(w,H,V,P0,ne,0.2,1,1e-2,2,1.0)
64
+ print("cpp_hf ok: iters=", int(n), "mu=", float(mu))
65
+ PY
@@ -0,0 +1,237 @@
1
+ name: release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ sdist:
11
+ name: Build sdist
12
+ runs-on: ubuntu-latest
13
+ permissions:
14
+ contents: read
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ with:
18
+ fetch-depth: 0
19
+
20
+ - uses: actions/setup-python@v5
21
+ with:
22
+ python-version: "3.12"
23
+
24
+ - name: Build source distribution
25
+ run: |
26
+ python -m pip install -U pip build
27
+ python -m build -s
28
+
29
+ - name: Upload sdist
30
+ uses: actions/upload-artifact@v4
31
+ with:
32
+ name: dist-sdist
33
+ path: dist/*
34
+ if-no-files-found: error
35
+
36
+ # ----- Linux (native x86_64 + native aarch64) -----
37
+ wheels-linux:
38
+ name: Build Linux wheels (${{ matrix.arch }})
39
+ strategy:
40
+ fail-fast: false
41
+ matrix:
42
+ include:
43
+ - arch: x86_64
44
+ runner: ubuntu-latest
45
+ image_var: CIBW_MANYLINUX_X86_64_IMAGE
46
+ - arch: aarch64
47
+ runner: ubuntu-24.04-arm
48
+ image_var: CIBW_MANYLINUX_AARCH64_IMAGE
49
+ runs-on: ${{ matrix.runner }}
50
+ permissions:
51
+ contents: read
52
+ steps:
53
+ - uses: actions/checkout@v4
54
+ with:
55
+ fetch-depth: 0
56
+
57
+ - name: Restore ccache
58
+ uses: actions/cache@v4
59
+ with:
60
+ path: .ccache
61
+ key: ccache-linux-${{ matrix.arch }}-${{ hashFiles('**/CMakeLists.txt', '**/*.cmake', '**/*.cpp', '**/*.h', 'pyproject.toml') }}
62
+
63
+ - name: Build wheels with cibuildwheel (${{ matrix.arch }})
64
+ uses: pypa/cibuildwheel@v2.21.3
65
+ env:
66
+ CIBW_BUILD: cp310-* cp311-* cp312-*
67
+ CIBW_SKIP: pp* *-musllinux_*
68
+ CIBW_ARCHS_LINUX: ${{ matrix.arch }}
69
+ ${{ matrix.image_var }}: manylinux_2_28
70
+
71
+ # Install build tools + FFTW + Boost headers; robust ccache fallback (pkg -> prebuilt -> source)
72
+ CIBW_BEFORE_ALL_LINUX: |
73
+ set -eux
74
+
75
+ pm_install() {
76
+ if command -v dnf >/dev/null 2>&1; then
77
+ dnf -y install pkgconfig ninja-build unzip make which curl ca-certificates xz tar gzip cmake gcc-c++ fftw fftw-devel boost-devel libzstd libzstd-devel || true
78
+ elif command -v yum >/dev/null 2>&1; then
79
+ yum -y install pkgconfig ninja-build unzip make which curl ca-certificates xz tar gzip cmake gcc-c++ fftw fftw-devel boost-devel libzstd libzstd-devel || true
80
+ elif command -v microdnf >/dev/null 2>&1; then
81
+ microdnf -y install pkgconfig ninja-build unzip make which curl ca-certificates xz tar gzip cmake gcc-c++ fftw fftw-devel boost-devel libzstd libzstd-devel || true
82
+ elif command -v apt-get >/dev/null 2>&1; then
83
+ apt-get update -y
84
+ apt-get install -y --no-install-recommends \
85
+ pkg-config ninja-build unzip make curl ca-certificates xz-utils tar gzip cmake g++ \
86
+ libfftw3-3 libfftw3-dev libboost-all-dev zstd libzstd-dev
87
+ else
88
+ echo "No supported package manager found" >&2
89
+ exit 1
90
+ fi
91
+ }
92
+
93
+ install_ccache() {
94
+ # 1) Try package manager
95
+ if command -v dnf >/devnull 2>&1; then dnf -y install ccache || true; fi
96
+ if command -v yum >/devnull 2>&1; then yum -y install ccache || true; fi
97
+ if command -v microdnf >/devnull 2>&1; then microdnf -y install ccache || true; fi
98
+ if command -v apt-get >/devnull 2>&1; then apt-get install -y --no-install-recommends ccache || true; fi
99
+ if command -v ccache >/dev/null 2>&1; then return 0; fi
100
+
101
+ # 2) Try official prebuilt tarball
102
+ ver="4.11.3"
103
+ arch="$(uname -m)"
104
+ url="https://github.com/ccache/ccache/releases/download/v${ver}/ccache-${ver}-linux-${arch}.tar.xz"
105
+ if curl -fsSL "$url" -o /tmp/ccache.tar.xz; then
106
+ mkdir -p /usr/local/ccache
107
+ tar -xJf /tmp/ccache.tar.xz -C /usr/local/ccache --strip-components=1
108
+ ln -sf /usr/local/ccache/bin/ccache /usr/local/bin/ccache
109
+ fi
110
+ if command -v ccache >/dev/null 2>&1; then return 0; fi
111
+
112
+ # 3) Build from source with CMake (last resort)
113
+ src="4.11.3"
114
+ tmpd="$(mktemp -d)"
115
+ curl -fsSL "https://github.com/ccache/ccache/releases/download/v${src}/ccache-${src}.tar.gz" -o "${tmpd}/ccache.tar.gz"
116
+ tar -xzf "${tmpd}/ccache.tar.gz" -C "${tmpd}"
117
+ cmake -S "${tmpd}/ccache-${src}" -B "${tmpd}/build" -DCMAKE_BUILD_TYPE=Release
118
+ cmake --build "${tmpd}/build" -j"$(nproc)"
119
+ cmake --install "${tmpd}/build"
120
+ ln -sf /usr/local/bin/ccache /usr/local/ccache/bin/ccache || true
121
+ }
122
+
123
+ pm_install
124
+ install_ccache
125
+ command -v ccache >/dev/null || { echo "ccache still missing"; exit 1; }
126
+
127
+ CIBW_ENVIRONMENT_LINUX: >
128
+ CC=gcc
129
+ CXX=g++
130
+ CCACHE_DIR=/project/.ccache
131
+ CMAKE_ARGS="-G Ninja -DHF_USE_OPENMP=ON -DHF_USE_FFTW_THREADS=ON -DBOOST_INCLUDEDIR=/usr/include -DCMAKE_CXX_COMPILER_LAUNCHER=ccache"
132
+ CMAKE_BUILD_PARALLEL_LEVEL=$(nproc)
133
+
134
+ CIBW_REPAIR_WHEEL_COMMAND_LINUX: >
135
+ bash -lc 'auditwheel repair -w {dest_dir} {wheel}'
136
+
137
+ CIBW_TEST_REQUIRES: numpy
138
+ CIBW_TEST_COMMAND: |
139
+ python - <<'PY'
140
+ import numpy as np, cpp_hf
141
+ nk,d=4,2
142
+ w=np.ones((nk,nk))*((2/nk)*(2/nk)/(2*np.pi)**2)
143
+ H=np.zeros((nk,nk,d,d),np.complex128)
144
+ K=np.linspace(-1,1,nk)
145
+ V=(1.0/np.sqrt((K[:,None]**2+K[None,:]**2)+0.2)).astype(np.complex128)[...,None,None]
146
+ P0=np.zeros_like(H)
147
+ ne=0.5*d*w.sum()
148
+ P,F,E,mu,n=cpp_hf.hartreefock_iteration_cpp(w,H,V,P0,ne,0.2,1,1e-2,2,1.0)
149
+ print("wheel ok", int(n), float(mu))
150
+ PY
151
+
152
+ - name: Upload Linux ${{ matrix.arch }} wheels
153
+ uses: actions/upload-artifact@v4
154
+ with:
155
+ name: dist-wheels-linux-${{ matrix.arch }}
156
+ path: wheelhouse/*
157
+ if-no-files-found: error
158
+
159
+ # ----- macOS (Intel/Apple Silicon) -----
160
+ wheels-macos:
161
+ name: Build macOS wheels (Intel/Apple Silicon)
162
+ strategy:
163
+ fail-fast: false
164
+ matrix:
165
+ runner: [macos-13, macos-14]
166
+ runs-on: ${{ matrix.runner }}
167
+ env:
168
+ MACOSX_DEPLOYMENT_TARGET: ${{ matrix.runner == 'macos-14' && '14.0' || '13.0' }}
169
+ permissions:
170
+ contents: read
171
+ steps:
172
+ - uses: actions/checkout@v4
173
+ with:
174
+ fetch-depth: 0
175
+
176
+ - name: Install Homebrew deps
177
+ env:
178
+ HOMEBREW_NO_AUTO_UPDATE: "1"
179
+ run: |
180
+ rm -f "$HOME/Library/Caches/Homebrew/downloads/"*libomp* || true
181
+ brew install fftw libomp boost cmake ninja || true
182
+
183
+ - name: Build wheels with cibuildwheel
184
+ uses: pypa/cibuildwheel@v2.21.3
185
+ env:
186
+ CIBW_BUILD: cp310-* cp311-* cp312-*
187
+ CIBW_SKIP: pp*
188
+ CIBW_ARCHS_MACOS: native
189
+ CIBW_ENVIRONMENT_MACOS: >
190
+ PKG_CONFIG_PATH=/opt/homebrew/lib/pkgconfig:/usr/local/lib/pkgconfig
191
+ CMAKE_ARGS="-DHF_USE_OPENMP=ON -DHF_USE_FFTW_THREADS=ON -DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET}"
192
+ CIBW_REPAIR_WHEEL_COMMAND_MACOS: >
193
+ bash -lc 'delocate-listdeps -d {wheel} || true; MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} delocate-wheel -L /opt/homebrew/lib -L /usr/local/lib --require-archs {delocate_archs} -w {dest_dir} -v {wheel}'
194
+ CIBW_TEST_REQUIRES: numpy
195
+ CIBW_TEST_COMMAND: |
196
+ python - <<'PY'
197
+ import numpy as np, cpp_hf
198
+ nk,d=4,2
199
+ w=np.ones((nk,nk))*((2/nk)*(2/nk)/(2*np.pi)**2)
200
+ H=np.zeros((nk,nk,d,d),np.complex128)
201
+ K=np.linspace(-1,1,nk)
202
+ V=(1.0/np.sqrt((K[:,None]**2+K[None,:]**2)+0.2)).astype(np.complex128)[...,None,None]
203
+ P0=np.zeros_like(H)
204
+ ne=0.5*d*w.sum()
205
+ P,F,E,mu,n=cpp_hf.hartreefock_iteration_cpp(w,H,V,P0,ne,0.2,1,1e-2,2,1.0)
206
+ print("wheel ok", int(n), float(mu))
207
+ PY
208
+
209
+ - name: Upload macOS wheels
210
+ uses: actions/upload-artifact@v4
211
+ with:
212
+ name: dist-wheels-${{ matrix.runner }}
213
+ path: wheelhouse/*
214
+ if-no-files-found: error
215
+
216
+ # ----- Publish to PyPI -----
217
+ publish:
218
+ name: Publish to PyPI
219
+ needs: [sdist, wheels-linux, wheels-macos]
220
+ runs-on: ubuntu-latest
221
+ environment: cpp_hf_env
222
+ permissions:
223
+ contents: read
224
+ id-token: write
225
+ steps:
226
+ - name: Download all artifacts
227
+ uses: actions/download-artifact@v4
228
+ with:
229
+ pattern: dist-*
230
+ merge-multiple: true
231
+ path: dist
232
+
233
+ - name: Publish to PyPI via OIDC (Trusted Publisher)
234
+ if: startsWith(github.ref, 'refs/tags/v')
235
+ uses: pypa/gh-action-pypi-publish@release/v1
236
+ with:
237
+ packages-dir: dist/
cpp_hf-1.0/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ # Build artifacts
2
+ build/
3
+ dist/
4
+ wheelhouse/
5
+ *.egg-info/
6
+ __pycache__/
7
+
8
+ # Local outputs and generated images
9
+ outputs/
10
+
11
+ # Local tests and dev-only scripts
12
+ tests/
13
+ compare_cpp_vs_jax_bilayer.py
14
+ quick_sanity_check.py
15
+
16
+ # Editor/OS
17
+ .DS_Store
18
+ .vscode/
19
+ .idea/
20
+
@@ -0,0 +1,165 @@
1
+ cmake_minimum_required(VERSION 3.21)
2
+
3
+ # Prefer the project version provided by scikit-build-core when building wheels.
4
+ # This lets you set the version in one place (pyproject.toml), and CMake picks it up
5
+ # via the SKBUILD_PROJECT_VERSION cache variable. Fallback used for direct CMake builds.
6
+ if (DEFINED SKBUILD_PROJECT_VERSION AND NOT "${SKBUILD_PROJECT_VERSION}" STREQUAL "")
7
+ set(CPP_HF_VERSION "${SKBUILD_PROJECT_VERSION}")
8
+ else()
9
+ # Fallback for plain CMake builds without scikit-build-core
10
+ set(CPP_HF_VERSION "0.0")
11
+ endif()
12
+
13
+ project(cpp_hf VERSION ${CPP_HF_VERSION} LANGUAGES CXX)
14
+
15
+ # Prefer CONFIG packages for Boost on newer CMake
16
+ if (POLICY CMP0167)
17
+ cmake_policy(SET CMP0167 NEW)
18
+ endif()
19
+
20
+ # Options
21
+ option(HF_USE_OPENMP "Enable OpenMP parallelization over k-points" ON)
22
+ option(HF_USE_FFTW_THREADS "Link FFTW threads and enable fftw_init_threads()" ON)
23
+
24
+ # Python + NumPy
25
+ find_package(Python REQUIRED COMPONENTS Interpreter Development.Module NumPy)
26
+
27
+ # pybind11
28
+ find_package(pybind11 CONFIG QUIET)
29
+ if (NOT pybind11_FOUND)
30
+ include(FetchContent)
31
+ FetchContent_Declare(
32
+ pybind11
33
+ GIT_REPOSITORY https://github.com/pybind/pybind11.git
34
+ GIT_TAG v2.12.0
35
+ )
36
+ FetchContent_MakeAvailable(pybind11)
37
+ endif()
38
+
39
+ # Eigen3
40
+ find_package(Eigen3 QUIET NO_MODULE)
41
+ if (NOT Eigen3_FOUND)
42
+ include(FetchContent)
43
+ FetchContent_Declare(
44
+ Eigen
45
+ GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
46
+ GIT_TAG 3.4.0
47
+ )
48
+ FetchContent_MakeAvailable(Eigen)
49
+ # Some Eigen builds already define Eigen3::Eigen; only create an interface
50
+ # target if it is missing (header-only include target).
51
+ if (NOT TARGET Eigen3::Eigen)
52
+ add_library(Eigen3::Eigen INTERFACE IMPORTED)
53
+ target_include_directories(Eigen3::Eigen INTERFACE "${eigen_SOURCE_DIR}")
54
+ endif()
55
+ endif()
56
+
57
+ # Boost headers (for Boost.Math). Try CONFIG first; fallback to include path.
58
+ set(BOOST_HEADERS_TARGET "")
59
+ find_package(Boost 1.70 QUIET CONFIG COMPONENTS headers)
60
+ if (Boost_FOUND)
61
+ if (TARGET Boost::headers)
62
+ set(BOOST_HEADERS_TARGET Boost::headers)
63
+ elseif (TARGET Boost::boost)
64
+ set(BOOST_HEADERS_TARGET Boost::boost)
65
+ endif()
66
+ else()
67
+ find_path(BOOST_INCLUDE_DIR
68
+ NAMES boost/math/tools/toms748_solve.hpp
69
+ PATHS /opt/homebrew/include /usr/local/include
70
+ DOC "Path to Boost headers")
71
+ if (NOT BOOST_INCLUDE_DIR)
72
+ message(FATAL_ERROR "Boost headers not found; install Boost (brew install boost) or set CMAKE_PREFIX_PATH.")
73
+ endif()
74
+ endif()
75
+
76
+ # FFTW (pkg-config preferred; fallback to CMake config and manual find)
77
+ set(HF_FFTW_LIBS "")
78
+ set(HF_HAVE_FFTW_THREADS FALSE)
79
+ find_package(PkgConfig QUIET)
80
+ if (PkgConfig_FOUND)
81
+ pkg_check_modules(FFTW3 QUIET IMPORTED_TARGET fftw3)
82
+ if (FFTW3_FOUND)
83
+ list(APPEND HF_FFTW_LIBS PkgConfig::FFTW3)
84
+ endif()
85
+ if (HF_USE_FFTW_THREADS)
86
+ pkg_check_modules(FFTW3_THREADS QUIET IMPORTED_TARGET fftw3_threads)
87
+ if (FFTW3_THREADS_FOUND)
88
+ list(APPEND HF_FFTW_LIBS PkgConfig::FFTW3_THREADS)
89
+ set(HF_HAVE_FFTW_THREADS TRUE)
90
+ endif()
91
+ endif()
92
+ endif()
93
+ if (HF_FFTW_LIBS STREQUAL "")
94
+ find_package(FFTW3 CONFIG QUIET)
95
+ if (FFTW3_FOUND)
96
+ if (TARGET FFTW3::fftw3)
97
+ list(APPEND HF_FFTW_LIBS FFTW3::fftw3)
98
+ endif()
99
+ if (HF_USE_FFTW_THREADS AND TARGET FFTW3::fftw3_threads)
100
+ list(APPEND HF_FFTW_LIBS FFTW3::fftw3_threads)
101
+ set(HF_HAVE_FFTW_THREADS TRUE)
102
+ endif()
103
+ endif()
104
+ endif()
105
+ if (HF_FFTW_LIBS STREQUAL "")
106
+ message(FATAL_ERROR "FFTW3 not found. Install with 'brew install fftw' or set PKG_CONFIG_PATH/FFTW3_DIR.")
107
+ endif()
108
+ if (HF_USE_FFTW_THREADS AND NOT HF_HAVE_FFTW_THREADS)
109
+ find_library(FFTW3_THREADS_LIB NAMES fftw3_threads fftw_threads PATHS /opt/homebrew/lib /usr/local/lib ENV LIBRARY_PATH)
110
+ if (FFTW3_THREADS_LIB)
111
+ list(APPEND HF_FFTW_LIBS ${FFTW3_THREADS_LIB})
112
+ set(HF_HAVE_FFTW_THREADS TRUE)
113
+ else()
114
+ message(WARNING "Requested HF_USE_FFTW_THREADS=ON but libfftw3_threads not found; building without FFTW threading.")
115
+ endif()
116
+ endif()
117
+
118
+ # OpenMP (optional)
119
+ set(HF_OPENMP_LIB "")
120
+ if (HF_USE_OPENMP)
121
+ find_package(OpenMP QUIET)
122
+ if (OpenMP_CXX_FOUND)
123
+ set(HF_OPENMP_LIB OpenMP::OpenMP_CXX)
124
+ endif()
125
+ endif()
126
+
127
+ # Build module (Python name: cpp_hf)
128
+ pybind11_add_module(cpp_hf cpp_hf_module.cpp)
129
+ target_compile_features(cpp_hf PRIVATE cxx_std_17)
130
+ if (MSVC)
131
+ target_compile_options(cpp_hf PRIVATE /O2 /DNDEBUG)
132
+ target_compile_definitions(cpp_hf PRIVATE _SILENCE_CXX17_RESULT_OF_DEPRECATION_WARNING)
133
+ else()
134
+ target_compile_options(cpp_hf PRIVATE -O3 -DNDEBUG -fvisibility=hidden)
135
+ endif()
136
+ if (APPLE)
137
+ set_target_properties(cpp_hf PROPERTIES MACOSX_RPATH ON)
138
+ endif()
139
+
140
+ # Headers
141
+ target_include_directories(cpp_hf PRIVATE ${Python_NumPy_INCLUDE_DIRS})
142
+ if (DEFINED BOOST_INCLUDE_DIR)
143
+ target_include_directories(cpp_hf PRIVATE ${BOOST_INCLUDE_DIR})
144
+ endif()
145
+
146
+ # Link
147
+ target_link_libraries(cpp_hf PRIVATE
148
+ Eigen3::Eigen
149
+ ${BOOST_HEADERS_TARGET}
150
+ ${HF_FFTW_LIBS}
151
+ ${HF_OPENMP_LIB}
152
+ )
153
+ if (HF_HAVE_FFTW_THREADS)
154
+ target_compile_definitions(cpp_hf PRIVATE FFTW3_THREADS=1)
155
+ endif()
156
+
157
+ # Install
158
+ if (NOT DEFINED SKBUILD_PLATLIB_DIR OR SKBUILD_PLATLIB_DIR STREQUAL "")
159
+ set(SKBUILD_PLATLIB_DIR "${CMAKE_CURRENT_BINARY_DIR}/python" CACHE PATH "Python package output dir")
160
+ endif()
161
+ install(TARGETS cpp_hf
162
+ LIBRARY DESTINATION ${SKBUILD_PLATLIB_DIR}
163
+ RUNTIME DESTINATION ${SKBUILD_PLATLIB_DIR}
164
+ ARCHIVE DESTINATION ${SKBUILD_PLATLIB_DIR}
165
+ )