From 9952c200adf7afe98e846c0163e06d7ebbb4f07c Mon Sep 17 00:00:00 2001 From: tommoral Date: Mon, 21 Jul 2025 00:38:14 +0200 Subject: [PATCH 1/9] FIX adapt the code to new API with literal requirements --- solvers/cuml.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/solvers/cuml.py b/solvers/cuml.py index 17138fa..63774da 100644 --- a/solvers/cuml.py +++ b/solvers/cuml.py @@ -25,10 +25,10 @@ class Solver(BaseSolver): install_cmd = "conda" requirements = [ - "rapidsai:rapids", - f"nvidia:cudatoolkit={cuda_version}", + "rapidsai::rapids", + "nvidia::'cuda-version>=11.4,<=12.8'", "dask-sql", "cupy" - ] if cuda_version is not None else [] + ] parameters = { "solver": [ From f89faadaa03ba0c193ef68b6146c9ce39354107e Mon Sep 17 00:00:00 2001 From: tommoral Date: Mon, 21 Jul 2025 00:41:36 +0200 Subject: [PATCH 2/9] CI trigger From 5e2ba59829532efb8b714ce7fbd33cd64c2b0594 Mon Sep 17 00:00:00 2001 From: tommoral Date: Mon, 21 Jul 2025 00:43:15 +0200 Subject: [PATCH 3/9] ENH limit the schedule runs to once a month --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f2a61a1..fa35db0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,8 +11,8 @@ on: branches: - main schedule: - # Run every day at 7:42am UTC. - - cron: '42 7 * * *' + # Run every 3rd of the month at 7:42am UTC. + - cron: '42 7 3 * *' jobs: benchopt_dev: From 43f09d28e63cd58ac95f1acc83f4ec99df9cdd29 Mon Sep 17 00:00:00 2001 From: tommoral Date: Tue, 22 Jul 2025 15:01:26 +0200 Subject: [PATCH 4/9] CLN update to benchopt 1.7 --- datasets/finance.py | 2 +- datasets/libsvm.py | 2 +- objective.py | 2 +- solvers/blitz.py | 2 +- solvers/celer.py | 2 +- solvers/cyanure.py | 2 +- solvers/lightning.py | 2 +- solvers/modopt_fista.py | 4 +--- solvers/modopt_pogm.py | 4 +--- solvers/skglm.py | 4 +--- solvers/snapml.py | 2 +- 11 files changed, 11 insertions(+), 17 deletions(-) diff --git a/datasets/finance.py b/datasets/finance.py index 1da540c..ecfdfcb 100644 --- a/datasets/finance.py +++ b/datasets/finance.py @@ -16,7 +16,7 @@ class Dataset(BaseDataset): is_sparse = True install_cmd = 'conda' - requirements = ['pip:libsvmdata'] + requirements = ['pip::libsvmdata'] def __init__(self): self.X, self.y = None, None diff --git a/datasets/libsvm.py b/datasets/libsvm.py index 8303117..9ec1e29 100644 --- a/datasets/libsvm.py +++ b/datasets/libsvm.py @@ -17,7 +17,7 @@ class Dataset(BaseDataset): } install_cmd = 'conda' - requirements = ['pip:git+https://github.com/mathurinm/libsvmdata@main'] + requirements = ['pip::git+https://github.com/mathurinm/libsvmdata@main'] references = [ "C. Chang and CJ. Lin, " "'ACM transactions on intelligent systems and technology (TIST)', " diff --git a/objective.py b/objective.py index 935795e..13b57bd 100644 --- a/objective.py +++ b/objective.py @@ -8,7 +8,7 @@ class Objective(BaseObjective): """L1 regularized linear regression. """ name = "Lasso Regression" - min_benchopt_version = "1.5" + min_benchopt_version = "1.7" parameters = { 'fit_intercept': [True, False], diff --git a/solvers/blitz.py b/solvers/blitz.py index 67aeae3..5dc9740 100644 --- a/solvers/blitz.py +++ b/solvers/blitz.py @@ -16,7 +16,7 @@ class Solver(BaseSolver): install_cmd = 'conda' requirements = [ - 'pip:git+https://github.com/tbjohns/blitzl1.git@master' + 'pip::git+https://github.com/tbjohns/blitzl1.git@master' ] def set_objective(self, X, y, lmbd, fit_intercept): diff --git a/solvers/celer.py b/solvers/celer.py index b10d062..a711d26 100644 --- a/solvers/celer.py +++ b/solvers/celer.py @@ -18,7 +18,7 @@ class Solver(BaseSolver): sampling_strategy = 'iteration' install_cmd = 'conda' - requirements = ['pip:celer'] + requirements = ['pip::celer'] def set_objective(self, X, y, lmbd, fit_intercept): self.X, self.y, self.lmbd = X, y, lmbd diff --git a/solvers/cyanure.py b/solvers/cyanure.py index 2e55fe4..9094828 100644 --- a/solvers/cyanure.py +++ b/solvers/cyanure.py @@ -12,7 +12,7 @@ class Solver(BaseSolver): name = 'Cyanure' install_cmd = 'conda' - requirements = ['mkl', 'pip:cyanure-mkl'] + requirements = ['mkl', 'pip::cyanure-mkl'] references = [ 'J. Mairal, "Cyanure: An Open-Source Toolbox for Empirical Risk' ' Minimization for Python, C++, and soon more," ' diff --git a/solvers/lightning.py b/solvers/lightning.py index b9613d3..80504ab 100644 --- a/solvers/lightning.py +++ b/solvers/lightning.py @@ -15,7 +15,7 @@ class Solver(BaseSolver): install_cmd = 'conda' requirements = [ 'cython', - 'pip:git+https://github.com/scikit-learn-contrib/lightning.git' + 'pip::git+https://github.com/scikit-learn-contrib/lightning.git' ] references = [ 'M. Blondel, K. Seki and K. Uehara, ' diff --git a/solvers/modopt_fista.py b/solvers/modopt_fista.py index 1a1540e..f2d770a 100644 --- a/solvers/modopt_fista.py +++ b/solvers/modopt_fista.py @@ -16,9 +16,7 @@ class Solver(BaseSolver): name = 'ModOpt-FISTA' sampling_strategy = 'callback' install_cmd = 'conda' - requirements = [ - 'pip:modopt', - ] + requirements = ['pip::modopt'] parameters = { 'restart_strategy': ['greedy', 'adaptive-1'], } diff --git a/solvers/modopt_pogm.py b/solvers/modopt_pogm.py index 481c9de..fffb71c 100644 --- a/solvers/modopt_pogm.py +++ b/solvers/modopt_pogm.py @@ -17,9 +17,7 @@ class Solver(BaseSolver): sampling_strategy = 'callback' install_cmd = 'conda' - requirements = [ - 'pip:modopt', - ] + requirements = ['pip::modopt'] references = [ 'S. Farrens, A. Grigis, L. El Gueddari, Z. Ramzi, G. R. Chaithya, ' 'S. Starck, B. Sarthou, H. Cherkaoui, P. Ciuciu and J.-L. Starck, ' diff --git a/solvers/skglm.py b/solvers/skglm.py index b4e5dab..ba9d616 100644 --- a/solvers/skglm.py +++ b/solvers/skglm.py @@ -17,9 +17,7 @@ class Solver(BaseSolver): sampling_strategy = "iteration" install_cmd = 'conda' - requirements = [ - 'pip:skglm' - ] + requirements = ['pip::skglm'] def set_objective(self, X, y, lmbd, fit_intercept): self.X, self.y, self.lmbd = X, y, lmbd diff --git a/solvers/snapml.py b/solvers/snapml.py index e564055..8b13a51 100644 --- a/solvers/snapml.py +++ b/solvers/snapml.py @@ -11,7 +11,7 @@ class Solver(BaseSolver): name = "snapml" install_cmd = "conda" - requirements = ["pip:snapml"] + requirements = ["pip::snapml"] stopping_criterion = SufficientDescentCriterion(eps=1e-10, patience=7) From ec95fefc394d2c339291718a9a7e91b3876cdea0 Mon Sep 17 00:00:00 2001 From: tommoral Date: Tue, 22 Jul 2025 16:22:11 +0200 Subject: [PATCH 5/9] CI skip snapML on OSX --- test_config.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test_config.py b/test_config.py index bd18317..3d09f5d 100644 --- a/test_config.py +++ b/test_config.py @@ -18,6 +18,10 @@ def check_test_solver_install(solver_class): if "spams" in solver_class.name.lower(): pytest.skip("python-spams is not released for python 3.9 yet") + if "snapml" in solver_class.name.lower(): + if sys.platform == "darwin": + pytest.xfail("SnapML is not supported on MacOS.") + if "cuml" in solver_class.name.lower(): if sys.platform == "darwin": pytest.xfail("Cuml is not supported on MacOS.") From 9df812ad29a7122d8c51e67a3c9abe6981fc1a77 Mon Sep 17 00:00:00 2001 From: tommoral Date: Tue, 22 Jul 2025 16:34:33 +0200 Subject: [PATCH 6/9] FIX remove deprecated normalize argument in LassoLars --- solvers/lars.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/solvers/lars.py b/solvers/lars.py index 152121c..01d43f6 100644 --- a/solvers/lars.py +++ b/solvers/lars.py @@ -28,8 +28,7 @@ def set_objective(self, X, y, lmbd, fit_intercept): n_samples = self.X.shape[0] self.clf = LassoLars( - alpha=self.lmbd / n_samples, fit_intercept=fit_intercept, - normalize=False, + alpha=self.lmbd / n_samples, fit_intercept=fit_intercept ) warnings.filterwarnings("ignore", category=ConvergenceWarning) From 74d546644be8cf02d3347335f4ee693530326acd Mon Sep 17 00:00:00 2001 From: tommoral Date: Tue, 22 Jul 2025 18:00:33 +0200 Subject: [PATCH 7/9] FIX skglm 0.4 is not working with scikit-learn 1.7.1, using dev version --- solvers/skglm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solvers/skglm.py b/solvers/skglm.py index ba9d616..56ceb13 100644 --- a/solvers/skglm.py +++ b/solvers/skglm.py @@ -17,7 +17,7 @@ class Solver(BaseSolver): sampling_strategy = "iteration" install_cmd = 'conda' - requirements = ['pip::skglm'] + requirements = ['pip::git+https://github.com/scikit-learn-contrib/skglm.git'] def set_objective(self, X, y, lmbd, fit_intercept): self.X, self.y, self.lmbd = X, y, lmbd From abe6490b83d73e91237b6585d6591fc66ca8bd34 Mon Sep 17 00:00:00 2001 From: tommoral Date: Tue, 22 Jul 2025 18:01:58 +0200 Subject: [PATCH 8/9] FIX linter --- solvers/skglm.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/solvers/skglm.py b/solvers/skglm.py index 56ceb13..c928462 100644 --- a/solvers/skglm.py +++ b/solvers/skglm.py @@ -17,7 +17,9 @@ class Solver(BaseSolver): sampling_strategy = "iteration" install_cmd = 'conda' - requirements = ['pip::git+https://github.com/scikit-learn-contrib/skglm.git'] + requirements = [ + 'pip::git+https://github.com/scikit-learn-contrib/skglm.git' + ] def set_objective(self, X, y, lmbd, fit_intercept): self.X, self.y, self.lmbd = X, y, lmbd From 6fe788a3a5fcc1c4ea1f9829059d27f8871afd16 Mon Sep 17 00:00:00 2001 From: tommoral Date: Tue, 22 Jul 2025 18:43:33 +0200 Subject: [PATCH 9/9] MTN remove lightning as the repo as been discontinued --- solvers/lightning.py | 50 -------------------------------------------- 1 file changed, 50 deletions(-) delete mode 100644 solvers/lightning.py diff --git a/solvers/lightning.py b/solvers/lightning.py deleted file mode 100644 index 80504ab..0000000 --- a/solvers/lightning.py +++ /dev/null @@ -1,50 +0,0 @@ -from benchopt import BaseSolver -from benchopt import safe_import_context - - -with safe_import_context() as import_ctx: - import numpy as np - from lightning.regression import CDRegressor - - -# TODO: lightning always fit an intercept -# it is thus not optimizing the same cost function -class Solver(BaseSolver): - name = 'Lightning' - - install_cmd = 'conda' - requirements = [ - 'cython', - 'pip::git+https://github.com/scikit-learn-contrib/lightning.git' - ] - references = [ - 'M. Blondel, K. Seki and K. Uehara, ' - '"Block coordinate descent algorithms for large-scale sparse ' - 'multiclass classification" ' - 'Mach. Learn., vol. 93, no. 1, pp. 31-52 (2013)' - ] - - def skip(self, X, y, lmbd, fit_intercept): - if fit_intercept: - return True, f"{self.name} does not handle fit_intercept" - - return False, None - - def set_objective(self, X, y, lmbd, fit_intercept): - self.X, self.y, self.lmbd = X, y, lmbd - self.fit_intercept = fit_intercept - - self.clf = CDRegressor( - loss='squared', penalty='l1', C=.5, alpha=self.lmbd, - tol=1e-15, random_state=0, permute=False, shrinking=False, - ) - - def run(self, n_iter): - self.clf.max_iter = n_iter - self.clf.fit(self.X, self.y) - - def get_result(self): - beta = self.clf.coef_.flatten() - if self.fit_intercept: - beta = np.r_[beta, self.clf.intercept_] - return dict(beta=beta)