Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
7d72b6d
WIP: array api standard for torch cpu
Sep 12, 2026
aca08e9
WIP: ensure float, check and convert arrays
Sep 14, 2026
4b6db3e
WIP: move_to from private utility funcs
sdtemple Sep 19, 2026
1653503
WIP: activation functions with xp
Sep 21, 2026
f5283ca
WIP: zero must be tensor in max func
Sep 21, 2026
6f0a8f6
WIP,ENH: array api dtypes, sklearn tags, and fixtures
Sep 24, 2026
1833bc4
WIP,ENH: sklearn-based tests
Sep 28, 2026
553ac1a
WIP,ENH: array api checks local to some tests
Sep 28, 2026
c78321f
WIP,ENH: make_regression test for torch
Sep 29, 2026
45b7090
WIP,MAINT: xp.min instead of min or .min()
Sep 29, 2026
4112b43
WIP,ENH,TST: xp flexible tests for check values
Sep 29, 2026
8a05709
WIP,ENH,TST,BUG: need with context, atol and rtol control
Sep 29, 2026
403928c
WIP,ENH,TST: use yield for namespace, device, dtype
sdtemple Oct 12, 2026
fd5b32a
WIP: revise for strict Array API
sdtemple Oct 14, 2026
0f0a168
WIP,TST: no check array api for classifier
sdtemple Oct 14, 2026
ac565e5
WIP,MAINT: CI for array API
sdtemple Oct 19, 2026
b5672ab
WIP,MAINT: use xp for `sigmoid`, `log_sigmoid`
sdtemple Oct 19, 2026
5c590e6
WIP,ENH: `partial_fit` for array API
sdtemple Oct 20, 2026
a93a379
WIP,ENH: softmax; tighter atol, rtol bounds for float64
sdtemple Oct 20, 2026
d53840f
WIP,TST: `sklearn` api compliance already handles array API
sdtemple Oct 20, 2026
ee40304
WIP,ENH,TST: revisions after Emma's PR
sdtemple Oct 23, 2026
01c1228
WIP,TST: `xpx` assert, small `partial_fit` test
sdtemple Oct 26, 2026
1e84cdf
WIP,ENH: `xp.asarray` in `partial_fit`
sdtemple Oct 26, 2026
d1fa627
WIP, ENH: torch CPU for GFDLClassifier
Sep 14, 2026
29e15e0
WIP,ENH: fixes after rebase from regressor
Sep 29, 2026
4e24e9c
WIP,ENH,TST: revised tests, move_to classes
sdtemple Oct 15, 2026
44b6c8e
WIP,ENH: `partial_fit` for classifier
sdtemple Oct 20, 2026
3cf5506
WIP,ENH: ensure classes for `partial_fit` are on `np` `cpu`
sdtemple Oct 20, 2026
b2a3f2b
WIP,ENH: `softmax` instead of `scipy.linalg.solve`
sdtemple Oct 21, 2026
2b87cae
WIP,ENH: more revisions after Emma's PR
sdtemple Oct 23, 2026
c10ca08
WIP,TST: modified `test_model.py` for Array API
sdtemple Oct 26, 2026
d1d6708
WIP,TST: include multiclass in `xp` classifier test
sdtemple Oct 26, 2026
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
34 changes: 34 additions & 0 deletions .github/workflows/array-api.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Array API CI

on:
push:
branches:
- maintenance/**
pull_request:
branches:
- main
- maintenance/**

jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
python-version: ["3.14"]

steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install -v .
python -m pip install -v --group test
python -m pip install torch array-api-strict array-api-compat
- name: test
run: |
cd $RUNNER_TEMP
SCIPY_ARRAY_API=1 python -m pytest --pyargs gfdl --cov=gfdl --cov-report=term-missing
43 changes: 27 additions & 16 deletions src/gfdl/activations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
Activation functions for Gradient Free Deep Learning estimators.
"""

import numpy as np
import scipy
from sklearn.utils._array_api import get_namespace_and_device


def relu(z):
Expand All @@ -17,10 +16,12 @@ def relu(z):

Returns
-------
numpy.ndarray
array
The output array with only positive values.
"""
return np.maximum(0, z)
xp, _, device = get_namespace_and_device(z)
zero = xp.asarray(0, dtype=z.dtype, device=device)
return xp.maximum(zero, z)


def tanh(z):
Expand All @@ -34,14 +35,15 @@ def tanh(z):

Returns
-------
numpy.ndarray
array
The output array with hyperbolic tangent values.

See Also
--------
numpy.tanh : The hyperbolic tangent function.
"""
return np.tanh(z)
xp, _, _device = get_namespace_and_device(z)
return xp.tanh(z)


def sigmoid(z):
Expand All @@ -55,14 +57,15 @@ def sigmoid(z):

Returns
-------
numpy.ndarray
array
The output array with the function values.

See Also
--------
scipy.special.expit : The logistic sigmoid function.
"""
return scipy.special.expit(z)
xp, _, _ = get_namespace_and_device(z)
return xp.exp(-xp.logaddexp(xp.zeros_like(z), -z))


def identity(z):
Expand All @@ -76,7 +79,7 @@ def identity(z):

Returns
-------
numpy.ndarray
array
The input array is returned unchanged.
"""
return z
Expand All @@ -93,14 +96,17 @@ def softmax(z):

Returns
-------
numpy.ndarray
array
The output array with the function values.

See Also
--------
scipy.special.softmax : The softmax function.
"""
return scipy.special.softmax(z, axis=-1)
xp, _, _ = get_namespace_and_device(z)
tmp = z - xp.max(z, axis=1, keepdims=True)
exp_tmp = xp.exp(tmp)
return exp_tmp / xp.sum(exp_tmp, axis=1, keepdims=True)


def softmin(z):
Expand All @@ -116,7 +122,7 @@ def softmin(z):

Returns
-------
numpy.ndarray
array
The output array with the function values.

See Also
Expand All @@ -137,14 +143,15 @@ def log_sigmoid(z):

Returns
-------
numpy.ndarray
array
The output array with the function values.

See Also
--------
scipy.special.log_expit : The logistic sigmoid function.
"""
return scipy.special.log_expit(z)
xp, _, _ = get_namespace_and_device(z)
return -xp.logaddexp(xp.zeros_like(z), -z)


def log_softmax(z):
Expand All @@ -158,14 +165,18 @@ def log_softmax(z):

Returns
-------
numpy.ndarray
array
The output array with the function values.

See Also
--------
scipy.special.log_softmax : The logarithm of softmax function.
"""
return scipy.special.log_softmax(z, axis=-1)
xp, _, _ = get_namespace_and_device(z)
shifted = z - xp.max(z, axis=1, keepdims=True)
return shifted - xp.log(
xp.sum(xp.exp(shifted), axis=1, keepdims=True)
)


ACTIVATIONS = {
Expand Down
Loading
Loading