scm2cpp-learn 0.18.0__py3-none-win_amd64.whl

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 (72) hide show
  1. scm2cpp_learn/__init__.py +3836 -0
  2. scm2cpp_learn/_classifiers.cp312-win_amd64.pyd +0 -0
  3. scm2cpp_learn/_compat.py +284 -0
  4. scm2cpp_learn/_generated/__init__.py +0 -0
  5. scm2cpp_learn/_generated/_loader.py +41 -0
  6. scm2cpp_learn/_generated/_loader_accel_cublas.py +173 -0
  7. scm2cpp_learn/_generated/_loader_classifiers.py +308 -0
  8. scm2cpp_learn/_generated/_loader_derived_blas.py +29 -0
  9. scm2cpp_learn/_generated/_loader_derived_cublas.py +29 -0
  10. scm2cpp_learn/_generated/_loader_derived_loops.py +29 -0
  11. scm2cpp_learn/_generated/_loader_gpu_cuda.py +313 -0
  12. scm2cpp_learn/_generated/_loader_gramops_blas.py +692 -0
  13. scm2cpp_learn/_generated/_loader_gramops_loops.py +711 -0
  14. scm2cpp_learn/_generated/_loader_nmf_blas.py +29 -0
  15. scm2cpp_learn/_generated/_loader_nmf_cublas.py +29 -0
  16. scm2cpp_learn/_generated/_loader_nmf_loops.py +29 -0
  17. scm2cpp_learn/_generated/accel_cublas/accel.cpp +24 -0
  18. scm2cpp_learn/_generated/accel_cublas/accel.hpp +1178 -0
  19. scm2cpp_learn/_generated/accel_cublas/accel_capi.cpp +76 -0
  20. scm2cpp_learn/_generated/classifiers.cpp +37 -0
  21. scm2cpp_learn/_generated/classifiers.hpp +3745 -0
  22. scm2cpp_learn/_generated/classifiers_capi.cpp +115 -0
  23. scm2cpp_learn/_generated/derived_blas/lasso_design.cpp +5 -0
  24. scm2cpp_learn/_generated/derived_blas/lasso_design.hpp +156 -0
  25. scm2cpp_learn/_generated/derived_blas/lasso_design_capi.cpp +19 -0
  26. scm2cpp_learn/_generated/derived_cublas/lasso_design.cpp +5 -0
  27. scm2cpp_learn/_generated/derived_cublas/lasso_design.hpp +158 -0
  28. scm2cpp_learn/_generated/derived_cublas/lasso_design_capi.cpp +19 -0
  29. scm2cpp_learn/_generated/derived_loops/lasso_design.cpp +5 -0
  30. scm2cpp_learn/_generated/derived_loops/lasso_design.hpp +179 -0
  31. scm2cpp_learn/_generated/derived_loops/lasso_design_capi.cpp +19 -0
  32. scm2cpp_learn/_generated/gpu_cuda/gpu.cpp +37 -0
  33. scm2cpp_learn/_generated/gpu_cuda/gpu.hpp +3846 -0
  34. scm2cpp_learn/_generated/gpu_cuda/gpu_capi.cpp +308 -0
  35. scm2cpp_learn/_generated/gramops_blas/gramops.cpp +82 -0
  36. scm2cpp_learn/_generated/gramops_blas/gramops.hpp +5411 -0
  37. scm2cpp_learn/_generated/gramops_blas/gramops_capi.cpp +244 -0
  38. scm2cpp_learn/_generated/gramops_loops/gramops.cpp +82 -0
  39. scm2cpp_learn/_generated/gramops_loops/gramops.hpp +6395 -0
  40. scm2cpp_learn/_generated/gramops_loops/gramops_capi.cpp +250 -0
  41. scm2cpp_learn/_generated/lasso_cov.cpp +7 -0
  42. scm2cpp_learn/_generated/lasso_cov.hpp +152 -0
  43. scm2cpp_learn/_generated/lasso_cov_capi.cpp +25 -0
  44. scm2cpp_learn/_generated/nmf_blas/nmf_cd.cpp +5 -0
  45. scm2cpp_learn/_generated/nmf_blas/nmf_cd.hpp +132 -0
  46. scm2cpp_learn/_generated/nmf_blas/nmf_cd_capi.cpp +19 -0
  47. scm2cpp_learn/_generated/nmf_cublas/nmf_cd.cpp +5 -0
  48. scm2cpp_learn/_generated/nmf_cublas/nmf_cd.hpp +136 -0
  49. scm2cpp_learn/_generated/nmf_cublas/nmf_cd_capi.cpp +19 -0
  50. scm2cpp_learn/_generated/nmf_loops/nmf_cd.cpp +5 -0
  51. scm2cpp_learn/_generated/nmf_loops/nmf_cd.hpp +167 -0
  52. scm2cpp_learn/_generated/nmf_loops/nmf_cd_capi.cpp +19 -0
  53. scm2cpp_learn/_generated/scm2cpp-blas.hpp +158 -0
  54. scm2cpp_learn/_generated/scm2cpp-cublas.hpp +155 -0
  55. scm2cpp_learn/_generated/scm2cpp-cuda.hpp +285 -0
  56. scm2cpp_learn/_generated/scm2cpp.hpp +1627 -0
  57. scm2cpp_learn/_gramops_blas.cp312-win_amd64.pyd +0 -0
  58. scm2cpp_learn/_lasso_cov.cp312-win_amd64.pyd +0 -0
  59. scm2cpp_learn/_lasso_derived_blas.cp312-win_amd64.pyd +0 -0
  60. scm2cpp_learn/_libfind.py +153 -0
  61. scm2cpp_learn/_nmf_blas.cp312-win_amd64.pyd +0 -0
  62. scm2cpp_learn/batch_capi.cu +428 -0
  63. scm2cpp_learn-0.18.0.dist-info/DELVEWHEEL +2 -0
  64. scm2cpp_learn-0.18.0.dist-info/METADATA +1171 -0
  65. scm2cpp_learn-0.18.0.dist-info/RECORD +72 -0
  66. scm2cpp_learn-0.18.0.dist-info/WHEEL +5 -0
  67. scm2cpp_learn-0.18.0.dist-info/top_level.txt +1 -0
  68. scm2cpp_learn.libs/.load-order-scm2cpp_learn-0.18.0 +4 -0
  69. scm2cpp_learn.libs/libopenblas-0486735c359a67419d8832e3c40e2837.dll +4 -0
  70. scm2cpp_learn.libs/msvcp140-73438573e87f9a2fd944b01def13566d.dll +0 -0
  71. scm2cpp_learn.libs/vcruntime140-052ad6a20d375957e82aa6a3c441ea54.dll +0 -0
  72. scm2cpp_learn.libs/vcruntime140_1-a198370e11c6e7469d1cf0ef5b3f433d.dll +0 -0
@@ -0,0 +1,285 @@
1
+ // The device back end of --cuda: arrays that live on the device across
2
+ // statements, the kernels the translator emits for parallel loops, and
3
+ // the products of the array algebra on those device arrays.
4
+ //
5
+ // Every host array a device statement touches gets a mirror: a device
6
+ // buffer of the same length and two flags, host_ok and dev_ok, saying
7
+ // which side holds the current values. The translator brackets each
8
+ // statement:
9
+ //
10
+ // a device statement (a kernel launch, a product) takes dev(v) for
11
+ // every array it uses -- uploading only when dev_ok is false -- and
12
+ // marks the arrays it writes with wrote_dev(v) (host_ok false);
13
+ //
14
+ // a host statement first calls need_host(v) for the arrays it uses --
15
+ // downloading only when host_ok is false -- and then wrote_host(v) for
16
+ // the arrays it may write (dev_ok false).
17
+ //
18
+ // So an array the host never touches between device statements stays on
19
+ // the device, and one only the host uses never goes there. A fresh
20
+ // allocation calls fresh(v), which drops a mirror left at the same
21
+ // address by an array that no longer exists. end_call() -- at the
22
+ // return of every extern "C" entry -- forgets what the host has not
23
+ // seen and frees every mirror; the caller may change its arrays before
24
+ // the next call, and nothing survives it. (The wrapper first brings back
25
+ // the caller's arrays with need_host; end_call itself copies nothing.)
26
+ //
27
+ // Compile with nvcc; link with -lcublas.
28
+ #ifndef SCM2CPP_CUDA_HPP
29
+ #define SCM2CPP_CUDA_HPP
30
+
31
+ #include <cublas_v2.h>
32
+ #include <cuda_runtime.h>
33
+ #include <cstdio>
34
+ #include <cstdlib>
35
+ #include <type_traits>
36
+ #include <unordered_map>
37
+
38
+ namespace scm2cpp {
39
+ namespace cu {
40
+
41
+ inline void check(cudaError_t e, const char* what) {
42
+ if (e != cudaSuccess) {
43
+ std::fprintf(stderr, "scm2cpp-cuda: %s: %s\n", what, cudaGetErrorString(e));
44
+ std::abort();
45
+ }
46
+ }
47
+ inline void check_blas(cublasStatus_t s, const char* what) {
48
+ if (s != CUBLAS_STATUS_SUCCESS) {
49
+ std::fprintf(stderr, "scm2cpp-cuda: %s: status %d\n", what, (int)s);
50
+ std::abort();
51
+ }
52
+ }
53
+
54
+ // SCM2CPP_CUDA_DEBUG=1: every launch synchronised and checked, every
55
+ // transfer reported, on stderr
56
+ inline bool debug() {
57
+ static int d = -1;
58
+ if (d < 0) d = std::getenv("SCM2CPP_CUDA_DEBUG") ? 1 : 0;
59
+ return d == 1;
60
+ }
61
+
62
+ inline cublasHandle_t handle() {
63
+ static cublasHandle_t h = 0;
64
+ if (!h) check_blas(cublasCreate(&h), "cublasCreate");
65
+ return h;
66
+ }
67
+
68
+ struct mirror {
69
+ void* d;
70
+ size_t bytes;
71
+ bool host_ok, dev_ok;
72
+ };
73
+
74
+ inline std::unordered_map<const void*, mirror>& registry() {
75
+ static std::unordered_map<const void*, mirror> r;
76
+ return r;
77
+ }
78
+
79
+ // Containers are anything with data() and size(); a scalar takes the
80
+ // no-op overloads, so the translator may pass every variable a statement
81
+ // mentions without knowing which are arrays.
82
+ template <class V, class = void>
83
+ struct is_array : std::false_type {};
84
+ template <class V>
85
+ struct is_array<V, std::void_t<decltype(std::declval<V&>().data()),
86
+ decltype(std::declval<V&>().size())>> : std::true_type {};
87
+
88
+ template <class V>
89
+ inline mirror& entry(V& v) {
90
+ const void* key = (const void*)v.data();
91
+ auto& r = registry();
92
+ auto it = r.find(key);
93
+ size_t bytes = v.size() * sizeof(*v.data());
94
+ if (it != r.end() && it->second.bytes == bytes) return it->second;
95
+ if (it != r.end()) {
96
+ cudaFree(it->second.d);
97
+ r.erase(it);
98
+ }
99
+ mirror m{nullptr, bytes, true, false};
100
+ if (bytes) check(cudaMalloc(&m.d, bytes), "cudaMalloc");
101
+ return r.emplace(key, m).first->second;
102
+ }
103
+
104
+ template <class V>
105
+ inline auto dev(V& v) -> typename std::remove_reference<decltype(*v.data())>::type* {
106
+ typedef typename std::remove_reference<decltype(*v.data())>::type T;
107
+ mirror& m = entry(v);
108
+ if (!m.dev_ok) {
109
+ if (debug()) std::fprintf(stderr, "cu: upload %p %zu bytes\n", (const void*)v.data(), m.bytes);
110
+ if (m.bytes)
111
+ check(cudaMemcpy(m.d, (const void*)v.data(), m.bytes, cudaMemcpyHostToDevice), "upload");
112
+ m.dev_ok = true;
113
+ }
114
+ return (T*)m.d;
115
+ }
116
+
117
+ template <class V>
118
+ inline void wrote_dev(V& v) {
119
+ mirror& m = entry(v);
120
+ m.dev_ok = true;
121
+ m.host_ok = false;
122
+ }
123
+
124
+ template <class V>
125
+ inline typename std::enable_if<is_array<V>::value>::type need_host(V& v) {
126
+ auto& r = registry();
127
+ auto it = r.find((const void*)v.data());
128
+ if (it == r.end() || it->second.host_ok) return;
129
+ if (debug()) std::fprintf(stderr, "cu: download %p %zu bytes (span %zu)\n", (const void*)v.data(), it->second.bytes, v.size() * sizeof(*v.data()));
130
+ check(cudaMemcpy((void*)v.data(), it->second.d, it->second.bytes, cudaMemcpyDeviceToHost),
131
+ "download");
132
+ it->second.host_ok = true;
133
+ }
134
+ template <class V>
135
+ inline typename std::enable_if<!is_array<V>::value>::type need_host(const V&) {}
136
+
137
+ template <class V>
138
+ inline typename std::enable_if<is_array<V>::value>::type wrote_host(V& v) {
139
+ auto& r = registry();
140
+ auto it = r.find((const void*)v.data());
141
+ if (it == r.end()) return;
142
+ it->second.dev_ok = false;
143
+ it->second.host_ok = true;
144
+ }
145
+ template <class V>
146
+ inline typename std::enable_if<!is_array<V>::value>::type wrote_host(const V&) {}
147
+
148
+ template <class V>
149
+ inline void fresh(V& v) {
150
+ auto& r = registry();
151
+ auto it = r.find((const void*)v.data());
152
+ if (it == r.end()) return;
153
+ cudaFree(it->second.d);
154
+ r.erase(it);
155
+ }
156
+
157
+ // Every mirror goes, nothing copied back: the end of one extern "C" call,
158
+ // after the wrapper has called need_host on the caller's own arrays (the
159
+ // other mirrors belong to arrays that no longer exist, and copying into
160
+ // them would write freed memory).
161
+ inline void end_call() {
162
+ auto& r = registry();
163
+ for (auto& kv : r) cudaFree(kv.second.d);
164
+ r.clear();
165
+ }
166
+
167
+ // The sums the kernels' reductions add into: K doubles on the device,
168
+ // zeroed before a launch and read back after it.
169
+ inline double* reduction_slots(int k) {
170
+ static double* d = nullptr;
171
+ static int cap = 0;
172
+ if (k > cap) {
173
+ if (d) cudaFree(d);
174
+ check(cudaMalloc(&d, k * sizeof(double)), "cudaMalloc reduction");
175
+ cap = k;
176
+ }
177
+ check(cudaMemset(d, 0, k * sizeof(double)), "cudaMemset reduction");
178
+ return d;
179
+ }
180
+ inline double reduction_value(const double* d, int i) {
181
+ double v;
182
+ check(cudaMemcpy(&v, d + i, sizeof(double), cudaMemcpyDeviceToHost), "reduction read");
183
+ return v;
184
+ }
185
+
186
+ // The reductions' atomic sum: the hardware's on sm_60 and later, a
187
+ // compare-and-swap loop before that (nvcc's default target is older).
188
+ __device__ inline double atomic_add(double* a, double v) {
189
+ #if !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 600
190
+ return atomicAdd(a, v);
191
+ #else
192
+ unsigned long long* p = (unsigned long long*)a;
193
+ unsigned long long old = *p, assumed;
194
+ do {
195
+ assumed = old;
196
+ old = atomicCAS(p, assumed, __double_as_longlong(v + __longlong_as_double(assumed)));
197
+ } while (assumed != old);
198
+ return __longlong_as_double(old);
199
+ #endif
200
+ }
201
+
202
+ inline void launched(const char* what) {
203
+ check(cudaGetLastError(), what);
204
+ if (debug()) {
205
+ check(cudaDeviceSynchronize(), what);
206
+ std::fprintf(stderr, "cu: ran %s\n", what);
207
+ }
208
+ }
209
+
210
+ // Below this many iterations a parallel loop runs on the host (the launch
211
+ // and the transfer it may force cost more than the loop); SCM2CPP_CUDA_MIN
212
+ // overrides it.
213
+ inline long min_trip() {
214
+ static long m = -1;
215
+ if (m < 0) {
216
+ const char* s = std::getenv("SCM2CPP_CUDA_MIN");
217
+ m = s ? std::atol(s) : 4096;
218
+ }
219
+ return m;
220
+ }
221
+
222
+ // The products, on device arrays: the same signatures as the cblas back
223
+ // end (scm2cpp-blas.hpp), every operand through dev(), the result marked.
224
+ template <class Y, class A, class B>
225
+ inline void blas_gemm(Y& y, A& a, B& b, double alpha, double beta, int ta, int tb, int m,
226
+ int n, int k) {
227
+ double* dy = beta != 0.0 ? dev(y) : (wrote_dev(y), (double*)entry(y).d);
228
+ check_blas(cublasDgemm(handle(), tb ? CUBLAS_OP_T : CUBLAS_OP_N, ta ? CUBLAS_OP_T : CUBLAS_OP_N,
229
+ n, m, k, &alpha, dev(b), tb ? k : n, dev(a), ta ? m : k, &beta, dy, n),
230
+ "cublasDgemm");
231
+ wrote_dev(y);
232
+ }
233
+
234
+ template <class Y, class A, class B>
235
+ inline void blas_gemm_batched(Y& y, A& a, B& b, double alpha, double beta, int ta, int tb,
236
+ int m, int n, int k, int batch) {
237
+ double* dy = beta != 0.0 ? dev(y) : (wrote_dev(y), (double*)entry(y).d);
238
+ check_blas(cublasDgemmStridedBatched(
239
+ handle(), tb ? CUBLAS_OP_T : CUBLAS_OP_N, ta ? CUBLAS_OP_T : CUBLAS_OP_N, n, m,
240
+ k, &alpha, dev(b), tb ? k : n, (long long)k * n, dev(a), ta ? m : k,
241
+ (long long)m * k, &beta, dy, n, (long long)m * n, batch),
242
+ "cublasDgemmStridedBatched");
243
+ wrote_dev(y);
244
+ }
245
+
246
+ template <class Y, class A, class V>
247
+ inline void blas_gemv(Y& y, A& a, V& v, double alpha, double beta, int ta, int m, int k) {
248
+ double* dy = beta != 0.0 ? dev(y) : (wrote_dev(y), (double*)entry(y).d);
249
+ if (ta)
250
+ check_blas(cublasDgemv(handle(), CUBLAS_OP_N, m, k, &alpha, dev(a), m, dev(v), 1, &beta, dy,
251
+ 1),
252
+ "cublasDgemv");
253
+ else
254
+ check_blas(cublasDgemv(handle(), CUBLAS_OP_T, k, m, &alpha, dev(a), k, dev(v), 1, &beta, dy,
255
+ 1),
256
+ "cublasDgemv");
257
+ wrote_dev(y);
258
+ }
259
+
260
+ // the row-major upper triangle from the lower one dsyrk wrote (a template
261
+ // so that the header may be included from several translation units)
262
+ template <int = 0>
263
+ __global__ void mirror_upper(double* y, int m) {
264
+ int i = blockIdx.y, j = blockIdx.x * blockDim.x + threadIdx.x;
265
+ if (j < m && j > i) y[i * m + j] = y[j * m + i];
266
+ }
267
+
268
+ // y (m x m) = alpha op(a) op(a)^T + beta y: dsyrk fills one triangle of
269
+ // the column-major reading, a kernel mirrors it, all on the device.
270
+ template <class Y, class A>
271
+ inline void blas_syrk(Y& y, A& a, double alpha, double beta, int ta, int m, int k) {
272
+ double* dy = beta != 0.0 ? dev(y) : (wrote_dev(y), (double*)entry(y).d);
273
+ check_blas(cublasDsyrk(handle(), CUBLAS_FILL_MODE_UPPER, ta ? CUBLAS_OP_N : CUBLAS_OP_T, m, k,
274
+ &alpha, dev(a), ta ? m : k, &beta, dy, m),
275
+ "cublasDsyrk");
276
+ dim3 grid((m + 255) / 256, m);
277
+ mirror_upper<<<grid, 256>>>(dy, m);
278
+ launched("mirror_upper");
279
+ wrote_dev(y);
280
+ }
281
+
282
+ } // namespace cu
283
+ } // namespace scm2cpp
284
+
285
+ #endif