Optimization benchmark functions and pytest-oriented evaluation helpers.
Project description
optfunc
optfunc provides differentiable PyTorch optfuncs, CVXPY-backed convex
benchmarks, and pytest-oriented helpers for evaluating first-order and
second-order optimizers.
The package is published as optfuncs and imported as optfunc.
Detailed user guides live under docs/.
Install
For CPU-only use:
pip install optfuncs
For convex-only CVXPY benchmarks:
pip install "optfuncs[convex]"
For CPU-only use plus convex benchmarks:
pip install "optfuncs[torch-cpu,convex]"
With uv in this repository:
uv sync --group torch-cpu
To enable the CVXPY convex benchmark suite:
uv sync --extra convex
Supported extras:
| Extra | Backend | Typical command |
|---|---|---|
convex |
CVXPY convex benchmarks, default MOSEK reference solve with SCS fallback | uv sync --extra convex |
torch-cpu |
CPU Torch runtime plus CPU native cone backend | pip install "optfuncs[torch-cpu]" |
torch-cu130 |
Torch CUDA 13.x plus optfuncs-cuda130 CUDA cone addon |
pip install "optfuncs[torch-cu130]" |
cupy-cu13 |
CuPy CUDA 13.x plus optfuncs-cuda130 CUDA cone addon |
pip install "optfuncs[cupy-cu13]" |
Torch hardware variants are also available as local uv dependency groups. Only choose one Torch group at a time:
| Local group | Backend | Typical command |
|---|---|---|
torch-cpu |
CPU, Linux/macOS/Windows | uv sync --group torch-cpu |
torch-cu118 |
CUDA 11.8, Linux/Windows, PyTorch 2.7.x | uv sync --group torch-cu118 |
torch-cu126 |
CUDA 12.6, Linux/Windows | uv sync --group torch-cu126 |
torch-cu128 |
CUDA 12.8, Linux/Windows | uv sync --group torch-cu128 |
torch-cu130 |
CUDA 13.0, Linux/Windows | uv sync --group torch-cu130 |
torch-rocm |
ROCm 7.1, Linux | uv sync --group torch-rocm |
torch-xpu |
Intel XPU, Linux/Windows | uv sync --group torch-xpu |
cupy-cu13 |
CuPy for CUDA 13.x cone interoperability tests | uv sync --group cupy-cu13 |
The CUDA 13 convex development environment is:
uv sync --group torch-cu130 --group cupy-cu13 --extra convex --dev
Detailed CPU/CUDA wheel behavior is documented in
docs/native-wheel-variants.md.
Using optfuncs from another uv project
When another uv project wants to expose multiple optional dependency sets,
add the convex/base benchmark support and the Torch backend support separately.
This keeps the target project's extras explicit and lets users choose the Torch
variant independently. optfuncs[convex] does not install or require Torch;
add a torch-* extra only when the target project also uses unconstrained
PyTorch optfuncs.
Recommended target-project extra layout:
| Target extra | Include |
|---|---|
test |
optfuncs[convex]>=0.0.7 for pytest helpers and CVXPY convex benchmarks |
torch |
optfuncs[torch-cu130]>=0.0.7 or another explicit hardware extra |
Example:
uv add --optional test "optfuncs[convex]>=0.0.7"
uv add --optional torch "optfuncs[torch-cu130]>=0.0.7"
For a CPU project, use:
uv add --optional test "optfuncs[convex]>=0.0.7"
uv add --optional torch "optfuncs[torch-cpu]>=0.0.7"
Then install the combination you need from the target project:
uv sync --extra test --extra torch
Keep the target project's Torch source/index selection aligned with the
selected optfuncs[...] hardware extra.
Helper scripts:
# bash/zsh on Linux or macOS, and Git Bash/MSYS/Cygwin on Windows
./scripts/sync_torch_variant.sh cpu
./scripts/sync_torch_variant.sh cu130
./scripts/sync_torch_variant.sh rocm
./scripts/sync_torch_variant.sh xpu
# Windows PowerShell or PowerShell 7 on Windows/Linux/macOS
.\scripts\sync_torch_variant.ps1 cpu
.\scripts\sync_torch_variant.ps1 cu130
.\scripts\sync_torch_variant.ps1 rocm
.\scripts\sync_torch_variant.ps1 xpu
If Windows blocks local PowerShell scripts, run:
powershell -ExecutionPolicy Bypass -File .\scripts\sync_torch_variant.ps1 cu130
Platform notes:
- CPU works on Linux, macOS, and Windows.
- CUDA extras work on Linux and Windows.
- ROCm works on Linux.
- XPU works on Linux and Windows.
- macOS should use
torch-cpuin this project configuration.
The backend indexes follow the official uv PyTorch guide and PyTorch install selector:
Optfunc Usage
The repository provides these built-in optfuncs:
| Registry name | Class | Known minimizer |
|---|---|---|
ackley |
Ackley |
all zeros |
dixonprice |
DixonPrice |
recursive Dixon-Price optimum |
griewank |
Griewank |
all zeros |
levy |
Levy |
all ones |
rastrigin |
Rastrigin |
all zeros |
rosenbrock |
Rosenbrock |
all ones |
rotatedhyperellipsoid |
RotatedHyperEllipsoid |
all zeros |
schwefel |
Schwefel |
near 420.968746 in every coordinate |
sphere |
Sphere |
all zeros |
styblinskitang |
StyblinskiTang |
near -2.903534 in every coordinate |
sumsquares |
SumSquares |
all zeros |
trid |
Trid |
x_i = i * (d + 1 - i) with 1-based indexing |
zakharov |
Zakharov |
all zeros |
Use a class directly when you know which function you want:
import torch
from optfunc import Sphere
opt_func = Sphere(dim=8, dtype=torch.float64)
x = torch.zeros(8, dtype=torch.float64)
value = opt_func(x)
grad = opt_func.grad(x)
hessian = opt_func.hessian(x)
hvp = opt_func.hvp(x, torch.ones_like(x))
x_star = opt_func.global_minimizer()
distance = opt_func.distance_to_optimum(x)
Use OptFuncRegistry when a test should select an optfunc by name:
from optfunc import OptFuncRegistry
opt_func = OptFuncRegistry.create("rosenbrock", dim=4)
print(OptFuncRegistry.available())
Use BenchmarkRegistry when the caller may switch between unconstrained
functions and one concrete convex benchmark instance:
from optfunc import BenchmarkRegistry
convex_problem = BenchmarkRegistry.create(
"gw_maxcut",
constraints="convex",
dim=8,
seed=19,
)
optimal_value = convex_problem.meta.optimal_value
X_star = convex_problem.known_solution("X")
cpp_data = convex_problem.problem_data
cvxpy_problem = convex_problem.problem # lazily constructed when requested
Use ConvexFamily when you want a family of parameterised convex programs:
from optfunc import ConvexFamily
family = ConvexFamily.create("gw_maxcut", dim=8)
theta = family.sample_parameters(seed=0)
problem = family.build_instance(theta)
theta_sequence = family.sample_parameters(5, seed=0)
problem_sequence = family.build_instance(theta_sequence)
same_problem_sequence = family.generate_sequence(5, seed=0)
Each optfunc uses the same conventions:
- input
xis a 1-D PyTorch tensor with shape(dim,); - output is a scalar tensor;
grad,hessian, andhvpuse PyTorch autograd unless a subclass provides a better implementation;global_minimizer()returns a known theoretical minimizer when available;distance_to_optimum(x)defaults to Euclidean distance toglobal_minimizer();project_to_bounds(x)clamps a point into the optfunc's documented search box.
Convex Benchmark Usage
The repository also provides CVXPY convex benchmarks behind
constraints="convex":
| Registry name | Cone | Shape parameter | Validation path |
|---|---|---|---|
zero, zero_cone_qp |
zero cone / equality constraints | vector dim |
known optimum |
nonneg, nonnegative_cone_qp |
nonnegative cone | vector dim |
known optimum |
psd, psd_cone_projection |
PSD cone | matrix side length dim |
known optimum |
gw_maxcut, maxcut_sdp |
PSD cone | graph vertex count dim |
analytic optimum |
Each convex benchmark family is generated from ConvexFamily and exposes
ProblemFamily methods:
sample_parameters(seed=0): sample one theta dictionary;sample_parameters(n, seed=0): sample a uniform theta sequence;sample_theta_*: family-specific sampling methods with the same single-or-many convention;build_instance(theta_or_theta_sequence): turn theta into one cpp-native problem instance or a list of instances;perturb(theta, n=None, magnitude=..., seed=0): produce one or more nearby theta dictionaries;perturb_*: family-specific perturbation methods that match the correspondingsample_theta_*naming;generate_sequence(n, seed=0): build a cpp-native problem sequence from the default seed theta sampler.
Each concrete CppNativeProblem exposes:
problem.to_cvxpy_problem()/problem.problem: the CVXPY problem converted from the native description;problem.data: deterministic random instance data used to build the problem;problem.problem_data: Clarabel-style canonical dataP,q,A,b, and ordered cone blocks;problem.cpp_native/problem.to_problem_data(): the native conic data used by cpp solver integrations;problem.solve(...): solve with CVXPY, defaulting to MOSEK and falling back to SCS if MOSEK is unavailable in the current environment;problem.known_solution()andproblem.distance_to_optimum()when the theoretical solution is encoded in the benchmark definition.
The internal conic data follows Clarabel's A x + s = b, s in K convention.
Cone blocks are stored in the order zero, nonnegative, second_order,
psd, then exponential. Use optfunc.cvxs.sort_cones,
add_cone_block, delete_cone_block, and to_ptf_text when building or
exporting solver-specific formats.
The gw_maxcut benchmark is a seeded Goemans-Williamson Max-Cut SDP relaxation
on a complete weighted bipartite graph. The seed fixes both the planted cut and
the positive edge weights. Its SDP relaxation optimum is known without calling a
solver: problem.meta.optimal_value is the total planted cut weight and
problem.known_solution("X") is the rank-one planted cut matrix.
If a convex benchmark does not have a closed-form theoretical solution yet, you
can leave that solution unspecified and use problem.solve() as the reference
value/solution path. The default reference solver is MOSEK.
The sequence API uses numpy.random.Generator for reproducible parameter
sampling, so ConvexFamily native problem generation and CVXPY conversion work
with the convex extra. Torch is required only for constraints="none" PyTorch
optfuncs.
Detailed Clarabel and gw_maxcut benchmark examples are available in
docs/convex-benchmark-usage.md.
Using C++ Cone Operators In External Conic Solvers
External conic solvers can use the cone descriptor and operator packages without
using CVXPY benchmark families. The minimum runtime path is NumPy plus the
compiled optfunc.cvxs.cones.cpp extension; convex, SciPy, CVXPY, Torch, and
CuPy are only needed when the downstream project explicitly uses those features.
Recommended imports:
import numpy as np
from optfunc.cvxs.cones import NonnegativeCone, PsdCone, make_cone_operator
from optfunc.cvxs.cones.cpp import NonnegativeOperatorCpp
cone = NonnegativeCone(3, name="ineq")
operator = make_cone_operator(cone, backend="cpp")
x = np.asarray([-1.0, 2.0, -3.0], dtype=np.float64)
projected = np.empty_like(x)
operator.project_into(x, projected)
assert projected.tolist() == [0.0, 2.0, 0.0]
assert operator.to_descriptor(name=cone.name) == cone
assert NonnegativeOperatorCpp(3).rows == cone.rows
The descriptor classes ZeroCone, NonnegativeCone, SecondOrderCone,
PsdCone, and ExponentialCone describe Clarabel-style cone metadata only:
kind, dim, rows, and optional name. The C++ operator classes implement
operations on cone vectors: project, project_into, contains, violation,
basis, unit_vector_into, project_batch_into, and workspace/fused helpers.
Downstream solvers may also pass their own descriptor objects to
make_cone_operator when they expose compatible attributes:
from dataclasses import dataclass
@dataclass(frozen=True)
class SolverCone:
kind: str
dim: int
rows: int
name: str | None = None
operator = make_cone_operator(
SolverCone(kind="psd", dim=2, rows=3, name="sdp_block"),
backend="cpp",
)
Use optfunc.cvxs.native.ConicProblemData and the P, q, A, b builder
helpers only when you want optfuncs to assemble Clarabel-style problem data.
Those utilities require SciPy sparse matrices. CVXPY-backed benchmark families
and translators require the convex extra.
Detailed installed-package guidance for external solver integration is
available in docs/cpp-cone-operators.md.
Pytest Optimizer Evaluation
The optimizer evaluation API lives in optfunc.testing. A standard test file
has three parts:
- Define or import an optimizer function.
- Configure one or more
OptimizerCaseobjects. - Assign
make_optimizer_tests(...)to a pytest-visible name such astest_my_optimizer.
Run the file with:
uv run pytest tests/test_my_optimizer.py -q --tb=short --optfunc-report
Each OptimizerCase becomes an independent pytest item. If one case fails or
raises an exception, pytest continues running the remaining cases.
--optfunc-report prints a final serial summary with function gap, distance to
the theoretical optimum, gradient norm, Hessian information, step count, and
error messages. Do not combine --optfunc-report with pytest-xdist -n in v1.
OptimizerBudget
OptimizerBudget describes the budget passed to the optimizer.
from optfunc.testing import OptimizerBudget
budget = OptimizerBudget(max_steps=500, lr=0.05)
Fields:
max_steps: positive integer iteration limit.lr: positive learning-rate-like scalar. The test harness does not enforce how the optimizer uses it; your optimizer reads it fromproblem.budget.lr.
For torch.optim.Adam, a typical use is:
optimizer = torch.optim.Adam([x], lr=problem.budget.lr)
for step in range(problem.budget.max_steps):
...
ConvergenceTolerances
ConvergenceTolerances decides whether a finished optimizer run passes.
from optfunc.testing import ConvergenceTolerances
tolerances = ConvergenceTolerances(
value_gap=1e-8,
x_distance=1e-4,
grad_norm=1e-4,
hessian_min_eig=0.0,
)
Fields:
value_gap: maximum allowed absolute gap between final value and the known theoretical optimum value. Set toNoneto skip this check.x_distance: maximum allowed distance from finalxto the known theoretical minimizer. Set toNoneto skip this check.grad_norm: maximum allowed Euclidean norm of the final gradient. Set toNoneto skip this check.hessian_min_eig: optional lower bound on the final Hessian's smallest eigenvalue. Set toNoneto skip this check.
The report still computes available metrics even when a tolerance is None;
None only disables that pass/fail check.
OptimizerCase
OptimizerCase describes one pytest item.
from optfunc.testing import OptimizerCase
from optfunc.testing import OptimizerBudget, ConvergenceTolerances
case = OptimizerCase(
opt_func="sphere",
constraints="none",
dim=8,
budget=OptimizerBudget(max_steps=350, lr=0.05),
tolerances=ConvergenceTolerances(value_gap=1e-8, x_distance=1e-4, grad_norm=1e-4),
start="near_minimizer",
start_radius=0.5,
seed=0,
hessian_max_dim=32,
)
Important fields:
opt_func: registry name such as"sphere"or an already-createdTorchOptFunctioninstance.constraints:"none"for the existing Torch optfunc suite, or"convex"for the CVXPY convex benchmark suite.dim: required whenopt_funcis a string.batch_size: forconstraints="convex", generate this many same-family problem instances.perturb_magnitude: for convex batches, controls successive parameter perturbations throughProblemFamily.perturb(...); when it is zero, the harness usesProblemFamily.sample_parameters(n, seed=...).budget:OptimizerBudgetpassed to the optimizer throughproblem.budget.tolerances:ConvergenceTolerancesused after the optimizer returns.case_id: optional pytest id; by default this is likesphere[8].x0: optional explicit initial point. If omitted, the harness builds one fromstart.start:"near_minimizer","random", or"zeros".start_radius: offset size used by"near_minimizer".seed: random seed used by"random".device: optional torch device string, for example"cuda"or"cpu".dtype: torch dtype, defaulttorch.float64.hessian_max_dim: largest dimension for dense Hessian report metrics. Larger cases skip dense Hessian metrics to avoid slow tests.
For constraints="convex", the optimizer receives a
ConvexOptimizationProblem with .instances, .parameters, and .problem
for single-instance cases. If the optimizer solves the CVXPY instances in
place and returns None, the harness checks objective gaps and known-solution
distances when those references are available.
make_optimizer_tests
make_optimizer_tests converts an optimizer plus cases into a pytest test
function.
from optfunc.testing import make_optimizer_tests
test_my_optimizer = make_optimizer_tests(
optimizer=my_optimizer,
cases=[case1, case2],
name="test_my_optimizer",
)
Rules:
- Assign the returned function to a module-level variable whose name starts with
test_, otherwise pytest will not collect it. - For
constraints="none",optimizermust accept oneOptimizationProblemargument. - For
constraints="none", the optimizer may return either a finaltorch.Tensoror anOptimizerResult. - Every case becomes an independent parametrized pytest item.
For convex cases, the optimizer accepts ConvexOptimizationProblem instead:
from optfunc.testing import (
ConvergenceTolerances,
ConvexOptimizationProblem,
OptimizerCase,
make_optimizer_tests,
)
def cvxpy_solver(problem: ConvexOptimizationProblem):
for instance in problem:
instance.solve()
test_convex_batch = make_optimizer_tests(
optimizer=cvxpy_solver,
cases=[
OptimizerCase(
opt_func="gw_maxcut",
constraints="convex",
dim=8,
batch_size=4,
perturb_magnitude=10.0,
seed=0,
tolerances=ConvergenceTolerances(value_gap=1e-5, x_distance=1e-3, grad_norm=None),
)
],
)
Standard Adam Test Example
This example shows the recommended shape for a user-owned optimizer wrapper.
The test harness does not hide torch.optim.Adam; the user function decides how
to initialize Adam, how to use the budget, and what history to expose.
Create tests/test_torch_adam.py:
import torch
from optfunc.testing import (
ConvergenceTolerances,
OptimizerBudget,
OptimizerCase,
OptimizerResult,
make_optimizer_tests,
optimizer_adapter,
)
def scalar_item(value):
return float(value.detach().cpu().item())
@optimizer_adapter(name="torch_adam")
def torch_adam(problem):
x = problem.x0.detach().clone().requires_grad_(True)
optimizer = torch.optim.Adam([x], lr=problem.budget.lr)
history = []
for step in range(1, problem.budget.max_steps + 1):
optimizer.zero_grad(set_to_none=True)
loss = problem.value(x)
loss.backward()
optimizer.step()
with torch.no_grad():
x.copy_(problem.project_to_bounds(x.detach()))
if step % 25 == 0 or step == problem.budget.max_steps:
x_now = x.detach()
grad = problem.grad(x_now)
history.append(
{
"step": step,
"value": scalar_item(problem.value(x_now)),
"grad_norm": scalar_item(torch.linalg.vector_norm(grad)),
"x_norm": scalar_item(torch.linalg.vector_norm(x_now)),
}
)
return OptimizerResult(
final_x=x.detach().clone(),
steps=problem.budget.max_steps,
history=history,
)
test_torch_adam = make_optimizer_tests(
optimizer=torch_adam,
cases=[
OptimizerCase(
opt_func="sphere",
dim=8,
budget=OptimizerBudget(max_steps=350, lr=0.05),
tolerances=ConvergenceTolerances(
value_gap=1e-8,
x_distance=1e-4,
grad_norm=1e-4,
),
start="near_minimizer",
start_radius=0.5,
),
OptimizerCase(
opt_func="rosenbrock",
dim=4,
budget=OptimizerBudget(max_steps=1200, lr=0.02),
tolerances=ConvergenceTolerances(
value_gap=5e-4,
x_distance=5e-2,
grad_norm=1e-2,
),
start="near_minimizer",
start_radius=0.25,
),
],
)
Run:
uv run pytest tests/test_torch_adam.py -q --tb=short --optfunc-report
The OptimizationProblem object passed into torch_adam exposes:
problem.opt_func: the selectedTorchOptFunction;problem.x0: the initial point for this case;problem.budget: theOptimizerBudget;problem.value(x): scalar objective value;problem.grad(x): gradient;problem.value_and_grad(x): objective and gradient;problem.hessian(x): dense Hessian;problem.hvp(x, v): Hessian-vector product;problem.project_to_bounds(x): clamp into the optfunc's bounds.
For second-order methods, call problem.hessian(x) or problem.hvp(x, v)
inside the same optimizer wrapper and return the same OptimizerResult shape.
Built-In Adam Helper
For smoke tests or examples, optfunc.testing.make_torch_adam() provides the
same Adam loop as a convenience:
from optfunc.testing import make_torch_adam, make_optimizer_tests
test_adam = make_optimizer_tests(
optimizer=make_torch_adam(),
cases=[...],
)
For production optimizer tests, prefer writing the small wrapper yourself so the learning rate, projection, stopping rule, and history format are explicit in your test file.
Development
Developer workflows, release steps, PyPI verification, project structure, and API design notes live in README.dev.md.
Optfunc definitions are adapted from SFU's optimization benchmark collection:
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file optfuncs-0.0.9.tar.gz.
File metadata
- Download URL: optfuncs-0.0.9.tar.gz
- Upload date:
- Size: 378.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
43091adad8a51e91444752f72544720a439f39821fb3855cf46e130cfc5ca1f8
|
|
| MD5 |
49085c42c95b7e4f227dfb5f67dccc1c
|
|
| BLAKE2b-256 |
23fce75bcb3575c48c733876c9d212ffc2648b770f212a1109a6aec89ab1607f
|
File details
Details for the file optfuncs-0.0.9-cp314-cp314-win_amd64.whl.
File metadata
- Download URL: optfuncs-0.0.9-cp314-cp314-win_amd64.whl
- Upload date:
- Size: 312.3 kB
- Tags: CPython 3.14, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e03bf610c6a38d60923b400fd891224db865620e915784588ee279b456ec693f
|
|
| MD5 |
882cc89adb112439c5818dc6e0050ede
|
|
| BLAKE2b-256 |
e9766a445e0851c8d21fe3ae3b0ae1903d06e50aea11e3acabe74468557a0d4b
|
File details
Details for the file optfuncs-0.0.9-cp314-cp314-manylinux_2_38_x86_64.whl.
File metadata
- Download URL: optfuncs-0.0.9-cp314-cp314-manylinux_2_38_x86_64.whl
- Upload date:
- Size: 491.7 kB
- Tags: CPython 3.14, manylinux: glibc 2.38+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7b8435ec62b7647a0974ac2fe59e7b18d7cabb020f12cf9710fd87422018062a
|
|
| MD5 |
54cc1c22427fe8cee5f4d1f6f43d9916
|
|
| BLAKE2b-256 |
660fad9f7537633133eab9648d72f4041aebbc2f2b95c31ce1abfdddf910ab74
|
File details
Details for the file optfuncs-0.0.9-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: optfuncs-0.0.9-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 309.6 kB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e45f848e91e1280b69bd0a19af99c055d98f26cce5ddb2d27075ae2a53c06a1
|
|
| MD5 |
c332558702741db0130c20f438f4a7bb
|
|
| BLAKE2b-256 |
9f4356f3fc24e1da7a836a6439cbcd39a052377ecac3a32721613b2e443da3ac
|
File details
Details for the file optfuncs-0.0.9-cp313-cp313-manylinux_2_38_x86_64.whl.
File metadata
- Download URL: optfuncs-0.0.9-cp313-cp313-manylinux_2_38_x86_64.whl
- Upload date:
- Size: 491.7 kB
- Tags: CPython 3.13, manylinux: glibc 2.38+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3623448c251b007a8eb3e67be4c1cb416fe7ebb015c266a47f32982d285d9e84
|
|
| MD5 |
bf4517ea11d1949c1d62cd888815b50d
|
|
| BLAKE2b-256 |
bf83c5fef76e1b88dc1b05be94af326d2b7c3f3d98243619c0769e3181f71db7
|
File details
Details for the file optfuncs-0.0.9-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: optfuncs-0.0.9-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 309.6 kB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9d337a3934c08e08ed8b2fcf49bd698318e6d257ad98db843dc4fb0266279385
|
|
| MD5 |
21a40876d373c50f76c45dd27cc05471
|
|
| BLAKE2b-256 |
ad9da8cd140064926ffc698922aa457bb8cc8fc6d48380ab2f78589c19c47077
|
File details
Details for the file optfuncs-0.0.9-cp312-cp312-manylinux_2_38_x86_64.whl.
File metadata
- Download URL: optfuncs-0.0.9-cp312-cp312-manylinux_2_38_x86_64.whl
- Upload date:
- Size: 491.8 kB
- Tags: CPython 3.12, manylinux: glibc 2.38+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
77898fd72ad61d46dd01a29163fa65323605c745d2f4f33d905d0d98919fdd19
|
|
| MD5 |
349a4677ee5033c1159a5d79f1e5a6b1
|
|
| BLAKE2b-256 |
5a0c877eaba9ce0591ef751fc2c307aa827d086e3ac6c8b881b1c8d0512a6734
|