Skip to content
Merged
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
4 changes: 3 additions & 1 deletion .github/workflows/build-and-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ jobs:
CIBW_ARCHS_LINUX: "auto aarch64"
CIBW_BEFORE_BUILD_LINUX: "yum install -y openblas-devel || apt-get install -y libopenblas-dev"
CIBW_BEFORE_BUILD_WINDOWS: "pip install delvewheel && vcpkg install openblas:x64-windows"
CIBW_ENVIRONMENT_WINDOWS: "CMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake"
# The engine turns MSVC /WX off under scikit-build for downstream
# builds; keep it on for our own wheels.
CIBW_ENVIRONMENT_WINDOWS: "CMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake SKBUILD_CMAKE_ARGS=-DSDE_WARNINGS_AS_ERRORS=ON"
# Bundle openblas.dll into the wheel (auditwheel/delocate handle this on Linux/macOS)
CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: "delvewheel repair -w {dest_dir} {wheel} --add-path C:/vcpkg/installed/x64-windows/bin"
# On free-threaded builds, assert the import did not re-enable the GIL.
Expand Down
37 changes: 37 additions & 0 deletions .github/workflows/conda-recipe.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: conda-forge recipe

# Builds conda.recipe/ with rattler-build against conda-forge, using the subset
# of conda-forge's pinning in conda.recipe/variants.yaml (e.g. netlib
# libblas/libcblas on Linux), as the feedstock would.

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

concurrency:
group: conda-recipe-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, macos-14, windows-latest ]

steps:
- uses: actions/checkout@v5
with:
submodules: recursive

- uses: prefix-dev/rattler-build-action@v0.2.39
with:
recipe-path: conda.recipe/recipe.yaml
rattler-build-version: v0.76.1
# --experimental enables load_from_file() for the version
build-args: --experimental --channel conda-forge
artifact-name: conda-package-${{ matrix.os }}
2 changes: 1 addition & 1 deletion SparseDiffEngine
Submodule SparseDiffEngine updated 53 files
+81 −0 .github/workflows/conda-forge.yml
+42 −3 CMakeLists.txt
+25 −8 include/expr.h
+19 −0 include/old-code/old_CSR_sum.h
+26 −0 include/old-code/old_mini_numpy.h
+8 −1 include/subexpr.h
+2 −11 include/utils/CSR_sum.h
+16 −44 include/utils/matrix.h
+0 −1 include/utils/mini_numpy.h
+19 −17 include/utils/permuted_dense.h
+7 −4 include/utils/sparse_matrix.h
+8 −0 include/utils/stacked_pd_linalg.h
+20 −6 src/atoms/affine/broadcast.c
+8 −3 src/atoms/affine/convolve.c
+4 −2 src/atoms/affine/hstack.c
+4 −5 src/atoms/affine/index.c
+8 −3 src/atoms/affine/kron.c
+8 −3 src/atoms/affine/left_matmul.c
+7 −0 src/atoms/affine/parameter.c
+7 −4 src/atoms/affine/promote.c
+8 −3 src/atoms/affine/scalar_mult.c
+35 −27 src/atoms/affine/sum.c
+5 −5 src/atoms/affine/transpose.c
+8 −3 src/atoms/affine/vector_mult.c
+8 −3 src/atoms/other/quad_form.c
+18 −5 src/expr.c
+196 −0 src/old-code/old_CSR_sum.c
+27 −0 src/old-code/old_mini_numpy.c
+7 −3 src/problem.c
+0 −187 src/utils/CSR_sum.c
+0 −8 src/utils/mini_numpy.c
+82 −294 src/utils/permuted_dense.c
+122 −164 src/utils/sparse_matrix.c
+29 −172 src/utils/stacked_pd.c
+38 −0 src/utils/stacked_pd_linalg.c
+34 −12 tests/all_tests.c
+64 −0 tests/jacobian_tests/affine/test_broadcast.h
+31 −0 tests/jacobian_tests/affine/test_promote.h
+77 −0 tests/jacobian_tests/affine/test_sum.h
+53 −0 tests/jacobian_tests/affine/test_transpose.h
+201 −0 tests/jacobian_tests/test_values_version.h
+13 −0 tests/problem/test_param_broadcast.h
+55 −0 tests/problem/test_param_source_refresh.h
+100 −0 tests/problem/test_problem.h
+132 −0 tests/profiling/profile_lasso.h
+11 −17 tests/profiling/profile_log_reg.h
+18 −0 tests/test_helpers.h
+8 −7 tests/utils/test_alloc_overflow.h
+3 −14 tests/utils/test_matmul_dispatchers.h
+20 −245 tests/utils/test_permuted_dense.h
+238 −0 tests/utils/test_row_gather.h
+286 −0 tests/utils/test_row_reduce.h
+22 −115 tests/utils/test_stacked_pd.h
83 changes: 83 additions & 0 deletions conda.recipe/recipe.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Mirror of the conda-forge recipe (conda-forge/staged-recipes#34978), built
# from this checkout instead of the PyPI sdist and without the BLAS patch, so
# CI catches changes that would break the conda-forge feedstock.
context:
name: sparsediffpy
version: ${{ load_from_file("pyproject.toml").project.version }}

package:
name: ${{ name }}
version: ${{ version }}

source:
path: ../

build:
number: 0
skip:
- match(python, "<3.11")
script:
- if: linux
then:
- export SKBUILD_CMAKE_ARGS="-DBLA_VENDOR=Generic"
# scikit-build-core otherwise falls back to "Unix Makefiles", and make
# isn't in the build env
- export CMAKE_GENERATOR=Ninja
- ${{ PYTHON }} -m pip install . -vv --no-deps --no-build-isolation

requirements:
build:
- if: build_platform != target_platform
then:
- python
- cross-python_${{ target_platform }}
- numpy
- ${{ compiler("c") }}
- ${{ stdlib("c") }}
- cmake
- ninja
host:
- python
- pip
- scikit-build-core >=0.10
- numpy
# macOS links the Accelerate framework
- if: linux
then:
- libblas
- libcblas
- blas-devel
- if: win
then:
- openblas
# openblas has no run_exports; libopenblas (which ships openblas.dll)
# does, so listing it here adds the runtime dependency
- libopenblas
run:
- python
- numpy >=2

tests:
- python:
imports:
- sparsediffpy
- sparsediffpy._sparsediffengine
pip_check: true
- files:
recipe:
- test_sparsediffpy.py
requirements:
run:
- python
- numpy
script:
- python test_sparsediffpy.py

about:
homepage: https://github.com/SparseDifferentiation/SparseDiffPy
repository: https://github.com/SparseDifferentiation/SparseDiffPy
summary: Python bindings for SparseDiffEngine algorithmic differentiation
license: Apache-2.0
license_file:
- LICENSE
- SparseDiffEngine/LICENSE
31 changes: 31 additions & 0 deletions conda.recipe/test_sparsediffpy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Smoke test: value, gradient and Hessian of small expressions through the
# C bindings. The dense quad_form path goes through CBLAS, so this also
# checks that BLAS is linked and callable.
import numpy as np

from sparsediffpy import _sparsediffengine as de


def check(expr, u, value, grad, hess):
prob = de.make_problem(expr, [], False)
de.problem_init_jacobian_coo(prob)
de.problem_init_hessian_coo_lower_triangular(prob)
np.testing.assert_allclose(de.problem_objective_forward(prob, u), value)
np.testing.assert_allclose(de.problem_gradient(prob), grad)
rows, cols, _ = de.get_problem_hessian_sparsity_coo(prob)
vals = de.problem_eval_hessian_vals_coo(prob, 1.0, np.zeros(0))
H = np.zeros((u.size, u.size))
H[rows, cols] = vals
np.testing.assert_allclose(np.tril(H), np.tril(hess))


u = np.array([1.0, -2.0, 0.5])

x = de.make_variable(3, 1, 0, 3)
check(de.make_sum(de.make_exp(x), -1), u, np.exp(u).sum(), np.exp(u), np.diag(np.exp(u)))

P = np.array([[2.0, 1.0, 0.0], [1.0, 3.0, 0.0], [0.0, 0.0, 4.0]])
x = de.make_variable(3, 1, 0, 3)
check(de.make_quad_form(None, x, "dense", P.flatten(order="F"), 3), u, u @ P @ u, 2 * P @ u, 2 * P)

print("sparsediffpy smoke test passed")
36 changes: 36 additions & 0 deletions conda.recipe/variants.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Subset of conda-forge's global pinning (conda-forge-pinning-feedstock
# recipe/conda_build_config.yaml), which rattler-build can't load directly.
# Only the oldest and newest supported Pythons are built.
c_compiler:
- if: linux
then: gcc
- if: osx
then: clang
- if: win
then: vs2022
c_compiler_version:
- if: linux
then: "15"
- if: osx
then: "21"
c_stdlib:
- if: linux
then: sysroot
- if: osx
then: macosx_deployment_target
- if: win
then: vs
c_stdlib_version:
- if: linux
then: "2.17"
- if: osx
then: "11.0"
python:
- 3.11.* *_cpython
- 3.14.* *_cp314
# conda-forge builds against netlib so packages link the switchable
# libblas.so.3/libcblas.so.3
libblas:
- 3.9.* *netlib
libcblas:
- 3.9.* *netlib
Loading