scm2cpp-lasso 0.5.3__tar.gz → 0.5.3.1__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.
Files changed (19) hide show
  1. {scm2cpp_lasso-0.5.3 → scm2cpp_lasso-0.5.3.1}/PKG-INFO +24 -10
  2. {scm2cpp_lasso-0.5.3 → scm2cpp_lasso-0.5.3.1}/README.md +23 -9
  3. {scm2cpp_lasso-0.5.3 → scm2cpp_lasso-0.5.3.1}/pyproject.toml +1 -1
  4. {scm2cpp_lasso-0.5.3 → scm2cpp_lasso-0.5.3.1}/src/scm2cpp_lasso/__init__.py +8 -2
  5. {scm2cpp_lasso-0.5.3 → scm2cpp_lasso-0.5.3.1}/src/scm2cpp_lasso.egg-info/PKG-INFO +24 -10
  6. {scm2cpp_lasso-0.5.3 → scm2cpp_lasso-0.5.3.1}/setup.cfg +0 -0
  7. {scm2cpp_lasso-0.5.3 → scm2cpp_lasso-0.5.3.1}/setup.py +0 -0
  8. {scm2cpp_lasso-0.5.3 → scm2cpp_lasso-0.5.3.1}/src/scm2cpp_lasso/_generated/__init__.py +0 -0
  9. {scm2cpp_lasso-0.5.3 → scm2cpp_lasso-0.5.3.1}/src/scm2cpp_lasso/_generated/_loader.py +0 -0
  10. {scm2cpp_lasso-0.5.3 → scm2cpp_lasso-0.5.3.1}/src/scm2cpp_lasso/_generated/lasso_cov.cpp +0 -0
  11. {scm2cpp_lasso-0.5.3 → scm2cpp_lasso-0.5.3.1}/src/scm2cpp_lasso/_generated/lasso_cov.hpp +0 -0
  12. {scm2cpp_lasso-0.5.3 → scm2cpp_lasso-0.5.3.1}/src/scm2cpp_lasso/_generated/lasso_cov_capi.cpp +0 -0
  13. {scm2cpp_lasso-0.5.3 → scm2cpp_lasso-0.5.3.1}/src/scm2cpp_lasso/_generated/scm2cpp.hpp +0 -0
  14. {scm2cpp_lasso-0.5.3 → scm2cpp_lasso-0.5.3.1}/src/scm2cpp_lasso/_libfind.py +0 -0
  15. {scm2cpp_lasso-0.5.3 → scm2cpp_lasso-0.5.3.1}/src/scm2cpp_lasso/batch_capi.cu +0 -0
  16. {scm2cpp_lasso-0.5.3 → scm2cpp_lasso-0.5.3.1}/src/scm2cpp_lasso.egg-info/SOURCES.txt +0 -0
  17. {scm2cpp_lasso-0.5.3 → scm2cpp_lasso-0.5.3.1}/src/scm2cpp_lasso.egg-info/dependency_links.txt +0 -0
  18. {scm2cpp_lasso-0.5.3 → scm2cpp_lasso-0.5.3.1}/src/scm2cpp_lasso.egg-info/requires.txt +0 -0
  19. {scm2cpp_lasso-0.5.3 → scm2cpp_lasso-0.5.3.1}/src/scm2cpp_lasso.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scm2cpp-lasso
3
- Version: 0.5.3
3
+ Version: 0.5.3.1
4
4
  Summary: Lasso by covariance-update coordinate descent, translated from Scheme to C++ by scm2cpp; GPU batch solver included
5
5
  Author: Hirotaka Niitsuma
6
6
  License: MIT
@@ -117,15 +117,29 @@ this size its launch overhead dominates, while our GPU row
117
117
  parallelises *across* lambdas -- one CUDA thread per penalty, the axis
118
118
  a cross-validation grid actually offers.
119
119
 
120
- `CovLassoCV` is scikit-learn's `LassoCV` over this machinery: the same
121
- grid construction, the same contiguous folds, the same
122
- minimum-mean-MSE choice -- and where the two disagree it is by one
123
- grid step on a near-tie, which sklearn also resolves our way once its
124
- tolerance is tightened. A fold's training Gram is a subtraction
125
- (G - Xf'Xf; the Gram is additive over rows), and on the GPU every fold
126
- and every alpha is one thread of a single launch. At cv=10 with 1000
127
- alphas -- ten thousand independent problems -- that launch takes
128
- 1.2 s against sklearn's 1.7 s, with GPU and CPU agreeing to 1e-14.
120
+ `CovLassoCV` is scikit-learn's `LassoCV` over this machinery -- same
121
+ grid construction, same contiguous folds, same minimum-mean-MSE choice
122
+ -- with two structural savings. A fold's training Gram is a
123
+ *subtraction* (the Gram is additive over rows, so G - Xf'Xf costs one
124
+ fold's work where rebuilding costs four folds'), and once the Grams
125
+ exist nothing downstream ever touches the n rows again -- which is why
126
+ the gap grows with n. On the GPU every fold and every alpha can run
127
+ as one thread of a single launch; that launch replicates each fold's
128
+ Gram per alpha, so it is chosen only while the replication stays under
129
+ 512 MB, the CPU warm path taking over at large p. Measured at cv=5,
130
+ 100 alphas, one CPU core:
131
+
132
+ | n | p | `CovLassoCV` | sklearn `LassoCV` |
133
+ |---------|------|--------------|-------------------|
134
+ | 1,800 | 200 | 0.23 s | 0.20 s |
135
+ | 5,000 | 1000 | 1.1 s | 3.4 s |
136
+ | 100,000 | 200 | 0.44 s | 5.7 s |
137
+ | 100,000 | 500 | 0.90 s | 8.0 s |
138
+
139
+ At n=100,000 the chosen alpha is identical and the coefficients agree
140
+ to 7e-7; at small n a near-tie can leave the picks one grid step
141
+ apart, which sklearn resolves our way once its tolerance is
142
+ tightened. GPU and CPU agree to 1e-14 wherever both run.
129
143
 
130
144
  ## Which method
131
145
 
@@ -99,15 +99,29 @@ this size its launch overhead dominates, while our GPU row
99
99
  parallelises *across* lambdas -- one CUDA thread per penalty, the axis
100
100
  a cross-validation grid actually offers.
101
101
 
102
- `CovLassoCV` is scikit-learn's `LassoCV` over this machinery: the same
103
- grid construction, the same contiguous folds, the same
104
- minimum-mean-MSE choice -- and where the two disagree it is by one
105
- grid step on a near-tie, which sklearn also resolves our way once its
106
- tolerance is tightened. A fold's training Gram is a subtraction
107
- (G - Xf'Xf; the Gram is additive over rows), and on the GPU every fold
108
- and every alpha is one thread of a single launch. At cv=10 with 1000
109
- alphas -- ten thousand independent problems -- that launch takes
110
- 1.2 s against sklearn's 1.7 s, with GPU and CPU agreeing to 1e-14.
102
+ `CovLassoCV` is scikit-learn's `LassoCV` over this machinery -- same
103
+ grid construction, same contiguous folds, same minimum-mean-MSE choice
104
+ -- with two structural savings. A fold's training Gram is a
105
+ *subtraction* (the Gram is additive over rows, so G - Xf'Xf costs one
106
+ fold's work where rebuilding costs four folds'), and once the Grams
107
+ exist nothing downstream ever touches the n rows again -- which is why
108
+ the gap grows with n. On the GPU every fold and every alpha can run
109
+ as one thread of a single launch; that launch replicates each fold's
110
+ Gram per alpha, so it is chosen only while the replication stays under
111
+ 512 MB, the CPU warm path taking over at large p. Measured at cv=5,
112
+ 100 alphas, one CPU core:
113
+
114
+ | n | p | `CovLassoCV` | sklearn `LassoCV` |
115
+ |---------|------|--------------|-------------------|
116
+ | 1,800 | 200 | 0.23 s | 0.20 s |
117
+ | 5,000 | 1000 | 1.1 s | 3.4 s |
118
+ | 100,000 | 200 | 0.44 s | 5.7 s |
119
+ | 100,000 | 500 | 0.90 s | 8.0 s |
120
+
121
+ At n=100,000 the chosen alpha is identical and the coefficients agree
122
+ to 7e-7; at small n a near-tie can leave the picks one grid step
123
+ apart, which sklearn resolves our way once its tolerance is
124
+ tightened. GPU and CPU agree to 1e-14 wherever both run.
111
125
 
112
126
  ## Which method
113
127
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "scm2cpp-lasso"
7
- version = "0.5.3"
7
+ version = "0.5.3.1"
8
8
  description = "Lasso by covariance-update coordinate descent, translated from Scheme to C++ by scm2cpp; GPU batch solver included"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -31,7 +31,7 @@ from ._libfind import load_batch_lib
31
31
 
32
32
  __all__ = ["CovLasso", "CovRidge", "CovLogistic", "CovGroupLasso",
33
33
  "cuda_available", "kernel"]
34
- __version__ = "0.5.3"
34
+ __version__ = "0.5.3.1"
35
35
 
36
36
  _BATCH = load_batch_lib()
37
37
  _DP = ctypes.POINTER(ctypes.c_double)
@@ -323,7 +323,13 @@ class CovLassoCV:
323
323
  # sklearn's KFold(shuffle=False)
324
324
  bounds = np.linspace(0, n, self.cv + 1).astype(int)
325
325
  self.mse_path_ = np.empty((self.num, self.cv))
326
- gpu = cuda_available() and not self.force_cpu
326
+ # The single GPU launch replicates each fold's Gram once per
327
+ # alpha; at large p that replication is gigabytes of transfer
328
+ # and the CPU warm path wins, so the choice is made by the
329
+ # replication's size rather than by the GPU's mere presence.
330
+ gram_bytes = self.cv * self.num * full.p * full.p * 8
331
+ gpu = (cuda_available() and not self.force_cpu
332
+ and gram_bytes <= (1 << 29)) # 512 MB
327
333
  G = full.g.reshape(full.p, full.p)
328
334
  if gpu:
329
335
  return self._fit_gpu(X, y, full, G, bounds, n)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scm2cpp-lasso
3
- Version: 0.5.3
3
+ Version: 0.5.3.1
4
4
  Summary: Lasso by covariance-update coordinate descent, translated from Scheme to C++ by scm2cpp; GPU batch solver included
5
5
  Author: Hirotaka Niitsuma
6
6
  License: MIT
@@ -117,15 +117,29 @@ this size its launch overhead dominates, while our GPU row
117
117
  parallelises *across* lambdas -- one CUDA thread per penalty, the axis
118
118
  a cross-validation grid actually offers.
119
119
 
120
- `CovLassoCV` is scikit-learn's `LassoCV` over this machinery: the same
121
- grid construction, the same contiguous folds, the same
122
- minimum-mean-MSE choice -- and where the two disagree it is by one
123
- grid step on a near-tie, which sklearn also resolves our way once its
124
- tolerance is tightened. A fold's training Gram is a subtraction
125
- (G - Xf'Xf; the Gram is additive over rows), and on the GPU every fold
126
- and every alpha is one thread of a single launch. At cv=10 with 1000
127
- alphas -- ten thousand independent problems -- that launch takes
128
- 1.2 s against sklearn's 1.7 s, with GPU and CPU agreeing to 1e-14.
120
+ `CovLassoCV` is scikit-learn's `LassoCV` over this machinery -- same
121
+ grid construction, same contiguous folds, same minimum-mean-MSE choice
122
+ -- with two structural savings. A fold's training Gram is a
123
+ *subtraction* (the Gram is additive over rows, so G - Xf'Xf costs one
124
+ fold's work where rebuilding costs four folds'), and once the Grams
125
+ exist nothing downstream ever touches the n rows again -- which is why
126
+ the gap grows with n. On the GPU every fold and every alpha can run
127
+ as one thread of a single launch; that launch replicates each fold's
128
+ Gram per alpha, so it is chosen only while the replication stays under
129
+ 512 MB, the CPU warm path taking over at large p. Measured at cv=5,
130
+ 100 alphas, one CPU core:
131
+
132
+ | n | p | `CovLassoCV` | sklearn `LassoCV` |
133
+ |---------|------|--------------|-------------------|
134
+ | 1,800 | 200 | 0.23 s | 0.20 s |
135
+ | 5,000 | 1000 | 1.1 s | 3.4 s |
136
+ | 100,000 | 200 | 0.44 s | 5.7 s |
137
+ | 100,000 | 500 | 0.90 s | 8.0 s |
138
+
139
+ At n=100,000 the chosen alpha is identical and the coefficients agree
140
+ to 7e-7; at small n a near-tie can leave the picks one grid step
141
+ apart, which sklearn resolves our way once its tolerance is
142
+ tightened. GPU and CPU agree to 1e-14 wherever both run.
129
143
 
130
144
  ## Which method
131
145
 
File without changes
File without changes