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,3846 @@
1
+
2
+ #ifndef GPU_HPP
3
+ #define GPU_HPP
4
+ #define SCM2CPP_MINIMAL
5
+ #include <array>
6
+ #include "scm2cpp-cuda.hpp"
7
+ #include <vector>
8
+ #include <math.h>
9
+ #include "scm2cpp.hpp"
10
+
11
+ SCM2CPP_FN double
12
+ eig_hypot( double a, double b );
13
+ int
14
+ sym_eigen( scm2cpp::span<double> a, scm2cpp::span<double> v, scm2cpp::span<double> ev, scm2cpp::span<double> e, int m );
15
+ SCM2CPP_FN double
16
+ eig_abs( double a );
17
+ int
18
+ eig_order( scm2cpp::cspan<double> ev, scm2cpp::span<int> ord, int m );
19
+ int
20
+ sym_eigen_top( scm2cpp::span<double> a, scm2cpp::span<double> v, scm2cpp::span<double> ev, scm2cpp::span<double> e, int m, int k );
21
+ int
22
+ sym_eigen_gen( scm2cpp::span<double> a, scm2cpp::span<double> b, scm2cpp::span<double> v, scm2cpp::span<double> ev, scm2cpp::span<double> e, int m );
23
+ SCM2CPP_FN double
24
+ ica_tanh( double x );
25
+ int
26
+ ica_sym( scm2cpp::span<double> w, scm2cpp::span<double> a, scm2cpp::span<double> v, scm2cpp::span<double> ev, scm2cpp::span<double> e, scm2cpp::span<double> t, int m );
27
+ int
28
+ fastica( scm2cpp::cspan<double> x, scm2cpp::cspan<double> winit, scm2cpp::span<double> comps, scm2cpp::span<double> white, scm2cpp::span<double> unmix, scm2cpp::span<double> mean, int maxiter, double tol, int n, int p, int nc );
29
+ int
30
+ gmm_mstep( scm2cpp::cspan<double> x, scm2cpp::cspan<double> resp, scm2cpp::span<double> weights, scm2cpp::span<double> means, scm2cpp::span<double> prec, scm2cpp::span<double> dw, scm2cpp::span<double> cov, scm2cpp::span<double> l, scm2cpp::span<double> u, double reg, int norm, int n, int p, int kc );
31
+ double
32
+ gmm_estep( scm2cpp::cspan<double> x, scm2cpp::span<double> resp, scm2cpp::cspan<double> weights, scm2cpp::cspan<double> means, scm2cpp::cspan<double> prec, scm2cpp::span<double> wlp, scm2cpp::span<double> y, scm2cpp::span<double> u, scm2cpp::span<double> mu, int n, int p, int kc );
33
+ SCM2CPP_FN double
34
+ gmm_abs( double a );
35
+ int
36
+ gmm( scm2cpp::cspan<double> x, scm2cpp::span<double> resp, scm2cpp::span<double> weights, scm2cpp::span<double> means, scm2cpp::span<double> prec, scm2cpp::span<double> labels, scm2cpp::span<double> out, int maxiter, double tol, double reg, int n, int p, int kc );
37
+ double
38
+ logistic_fg( scm2cpp::cspan<double> coef, scm2cpp::span<double> g, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> z, double l2, int multi, int fitint, int n, int p, int k );
39
+ int
40
+ logistic_lbfgs( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> coef, scm2cpp::span<double> out, double c, int maxiter, double tol, int multi, int fitint, int n, int p, int k );
41
+ double
42
+ huber_fg( scm2cpp::cspan<double> coef, scm2cpp::span<double> g, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> z, double epsilon, double alpha, int fitint, int n, int p );
43
+ int
44
+ huber( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> coef, scm2cpp::span<double> out, double epsilon, double alpha, int maxiter, double tol, int fitint, int n, int p );
45
+ double
46
+ glm_fg( scm2cpp::cspan<double> coef, scm2cpp::span<double> g, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> z, int family, double power, double l2, int fitint, int n, int p );
47
+ int
48
+ glm( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> coef, scm2cpp::span<double> out, int family, double power, double alpha, int maxiter, double tol, int fitint, int n, int p );
49
+ SCM2CPP_FN double
50
+ lb_abs( double a );
51
+ SCM2CPP_FN double
52
+ lb_max( double a, double b );
53
+ SCM2CPP_FN double
54
+ lb_min( double a, double b );
55
+ SCM2CPP_FN int
56
+ lb_dcstep( std::array<double,8> & cs, double fp, double dp, double stpmin, double stpmax );
57
+ SCM2CPP_FN int
58
+ lb_search_start( std::array<double,16> & ls, double f, double g, double stp, double stpmin, double stpmax, double ftol );
59
+ SCM2CPP_FN int
60
+ lb_search_step( std::array<double,16> & ls, std::array<double,8> & cs, double f, double g, double ftol, double gtol, double xtol, double stpmin, double stpmax );
61
+ double
62
+ lb_dot( scm2cpp::cspan<double> a, scm2cpp::cspan<double> b, int nv );
63
+ double
64
+ lb_dot_row( scm2cpp::cspan<double> mem, int slot, scm2cpp::cspan<double> v, int nv );
65
+ double
66
+ lb_dot_rows( scm2cpp::cspan<double> a, int ra, scm2cpp::cspan<double> b, int rb, int nv );
67
+ SCM2CPP_FN double
68
+ lb_projgr( scm2cpp::cspan<double> g, scm2cpp::cspan<double> w, int ib, double lbv, int nv );
69
+ int
70
+ lb_hv( scm2cpp::span<double> q, scm2cpp::cspan<double> smem, scm2cpp::cspan<double> ymem, scm2cpp::cspan<double> rho, scm2cpp::span<double> al, double theta, int col, int head, int m, int nv );
71
+ double
72
+ lb_vbv( scm2cpp::cspan<double> v, scm2cpp::cspan<double> smem, scm2cpp::cspan<double> ymem, scm2cpp::cspan<double> rho, scm2cpp::span<double> bm, scm2cpp::span<double> sb, double theta, int col, int head, int m, int nv );
73
+ int
74
+ lb_direction( scm2cpp::cspan<double> w, scm2cpp::cspan<double> g, scm2cpp::span<double> d, scm2cpp::span<double> q, scm2cpp::span<double> e, scm2cpp::cspan<double> smem, scm2cpp::cspan<double> ymem, scm2cpp::cspan<double> rho, scm2cpp::span<double> al, scm2cpp::span<double> bm, scm2cpp::span<double> sb, double theta, int col, int head, int m, int ib, double lbv, int nv );
75
+ int
76
+ lbfgs( int kind, scm2cpp::span<double> w, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, const std::array<double,4> & aux, scm2cpp::span<double> work, scm2cpp::span<double> out, int m, int maxiter, double pgtol, double ftol, int maxls, int ib, double lbv, int nv, int n, int p, int k );
77
+ SCM2CPP_FN double
78
+ lbfgs_fg( int kind, scm2cpp::cspan<double> w, scm2cpp::span<double> g, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, const std::array<double,4> & aux, scm2cpp::span<double> work, int n, int p, int k );
79
+
80
+
81
+
82
+ SCM2CPP_FN inline double
83
+ eig_hypot( double a, double b )
84
+ {
85
+ double aa = ( ( a < 0.0 ) ? ((0.0-a)) : (a) );
86
+ double bb = ( ( b < 0.0 ) ? ((0.0-b)) : (b) );
87
+ if( aa > bb ) {
88
+ return (aa*sqrt((1.0+((bb/aa)*(bb/aa))))) ;
89
+ }
90
+ else {
91
+ if( bb == 0.0 ) {
92
+ return 0.0 ;
93
+ }
94
+ else {
95
+ return (bb*sqrt((1.0+((aa/bb)*(aa/bb))))) ;
96
+ }
97
+ }
98
+ }
99
+ static __global__ void scm2cpp_k1(long scm2cpp_cnt, int scm2cpp_lo, const double* a, int i, int m, int j, double* scm2cpp_red) {
100
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
101
+ if (scm2cpp_t >= scm2cpp_cnt) return;
102
+ int k = scm2cpp_lo + (int)scm2cpp_t;
103
+ double g3 = 0.0;
104
+ { g3 = (g3+(a[((i*m)+k)]*a[((k*m)+j)])) ;
105
+ }
106
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, g3);
107
+ }
108
+ static __global__ void scm2cpp_k2(long scm2cpp_cnt, int scm2cpp_lo, double* v, const double* a, int m, double* scm2cpp_red) {
109
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
110
+ if (scm2cpp_t >= scm2cpp_cnt) return;
111
+ int i = scm2cpp_lo + (int)scm2cpp_t;
112
+ { for( int j = 0 ; !(j == m) ; j = (j+1) ) {
113
+ v[ ((j*m)+i) ] = a[((i*m)+j)] ;
114
+ } ;
115
+ }
116
+ }
117
+
118
+
119
+ inline int
120
+ sym_eigen( scm2cpp::span<double> a, scm2cpp::span<double> v, scm2cpp::span<double> ev, scm2cpp::span<double> e, int m )
121
+ { scm2cpp::cu::need_host(a);
122
+ scm2cpp::cu::need_host(e);
123
+ scm2cpp::cu::need_host(ev);
124
+ for( int ii = 0 ; !(ii == (m-1)) ; ii = (ii+1) ) {
125
+ int i = ((m-1)-ii);
126
+ int l = (i-1);
127
+ double h = 0.0;
128
+ double scale = 0.0;
129
+ if( l > 0 ) {
130
+ for( int k = 0 ; !(k > l) ; k = (k+1) ) {
131
+ double ak = a[((i*m)+k)];
132
+ scale = (scale+( ( ak < 0.0 ) ? ((0.0-ak)) : (ak) )) ;
133
+ ;
134
+ } ;
135
+ if( scale == 0.0 ) {
136
+ e[ i ] = a[((i*m)+l)] ;
137
+ } else {
138
+ for( int k = 0 ; !(k > l) ; k = (k+1) ) {
139
+ a[ ((i*m)+k) ] = (a[((i*m)+k)]/scale) ;
140
+ h = (h+(a[((i*m)+k)]*a[((i*m)+k)])) ;
141
+ } ;
142
+ double f = a[((i*m)+l)];
143
+ double g = ( ( f >= 0.0 ) ? ((0.0-sqrt(h))) : (sqrt(h)) );
144
+ e[ i ] = (scale*g) ;
145
+ h = (h-(f*g)) ;
146
+ a[ ((i*m)+l) ] = (f-g) ;
147
+ double ff = 0.0;
148
+ for( int j = 0 ; !(j > l) ; j = (j+1) ) {
149
+ a[ ((j*m)+i) ] = (a[((i*m)+j)]/h) ;
150
+ double gg = 0.0;
151
+ for( int k = 0 ; !(k > j) ; k = (k+1) ) {
152
+ gg = (gg+(a[((j*m)+k)]*a[((i*m)+k)])) ;
153
+ } ;
154
+ for( int k = (j+1) ; !(k > l) ; k = (k+1) ) {
155
+ gg = (gg+(a[((k*m)+j)]*a[((i*m)+k)])) ;
156
+ } ;
157
+ e[ j ] = (gg/h) ;
158
+ ff = (ff+(e[j]*a[((i*m)+j)])) ;
159
+ ;
160
+ } ;
161
+ double hh = (ff/(h+h));
162
+ for( int j = 0 ; !(j > l) ; j = (j+1) ) {
163
+ double f2 = a[((i*m)+j)];
164
+ double g2 = (e[j]-(hh*f2));
165
+ e[ j ] = g2 ;
166
+ for( int k = 0 ; !(k > j) ; k = (k+1) ) {
167
+ a[ ((j*m)+k) ] = (a[((j*m)+k)]-((f2*e[k])+(g2*a[((i*m)+k)]))) ;
168
+ } ;
169
+ ;
170
+ ;
171
+ } ;
172
+ ;
173
+ ;
174
+ ;
175
+ ;
176
+ } ;
177
+ } else {
178
+ e[ i ] = a[((i*m)+l)] ;
179
+ } ;
180
+ ev[ i ] = h ;
181
+ ;
182
+ ;
183
+ } ;
184
+ scm2cpp::cu::wrote_host(e);
185
+ scm2cpp::cu::wrote_host(a);
186
+ scm2cpp::cu::wrote_host(ev);
187
+ scm2cpp::cu::need_host(ev);
188
+ ev[ 0 ] = 0.0 ;
189
+ scm2cpp::cu::wrote_host(ev);
190
+ scm2cpp::cu::need_host(e);
191
+ e[ 0 ] = 0.0 ;
192
+ scm2cpp::cu::wrote_host(e);
193
+ for( int i = 0 ; !(i == m) ; i = (i+1) ) {
194
+ scm2cpp::cu::need_host(ev);
195
+ if( !(ev[i] == 0.0) ) {
196
+ for( int j = 0 ; !(j == i) ; j = (j+1) ) {
197
+ double g3 = 0.0;
198
+ {
199
+ long scm2cpp_cnt = (long)(i) - (long)(0);
200
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
201
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
202
+ scm2cpp_k1<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(a), i, m, j, scm2cpp_red);
203
+ scm2cpp::cu::launched("scm2cpp_k1");
204
+ g3 = g3 + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
205
+ } else {
206
+ scm2cpp::cu::need_host(a);
207
+ for( int k = 0 ; !(k == i) ; k = (k+1) ) {
208
+ g3 = (g3+(a[((i*m)+k)]*a[((k*m)+j)])) ;
209
+ }
210
+ }
211
+ } ;
212
+ scm2cpp::cu::need_host(a);
213
+ for( int k = 0 ; !(k == i) ; k = (k+1) ) {
214
+ a[ ((k*m)+j) ] = (a[((k*m)+j)]-(g3*a[((k*m)+i)])) ;
215
+ } ;
216
+ scm2cpp::cu::wrote_host(a);
217
+ ;
218
+ } ;
219
+ } else {
220
+ 0 ;
221
+ } ;
222
+ scm2cpp::cu::need_host(ev);
223
+ scm2cpp::cu::need_host(a);
224
+ ev[ i ] = a[((i*m)+i)] ;
225
+ scm2cpp::cu::wrote_host(ev);
226
+ scm2cpp::cu::need_host(a);
227
+ a[ ((i*m)+i) ] = 1.0 ;
228
+ scm2cpp::cu::wrote_host(a);
229
+ scm2cpp::cu::need_host(a);
230
+ for( int j = 0 ; !(j == i) ; j = (j+1) ) {
231
+ a[ ((j*m)+i) ] = 0.0 ;
232
+ a[ ((i*m)+j) ] = 0.0 ;
233
+ } ;
234
+ scm2cpp::cu::wrote_host(a);
235
+ } ;
236
+ { long scm2cpp_cnt = (long)(m) - (long)(0);
237
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
238
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
239
+ scm2cpp_k2<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(v), scm2cpp::cu::dev(a), m, scm2cpp_red);
240
+ scm2cpp::cu::launched("scm2cpp_k2");
241
+ scm2cpp::cu::wrote_dev(v);
242
+ } else {
243
+ scm2cpp::cu::need_host(v);
244
+ scm2cpp::cu::need_host(a);
245
+ for( int i = 0 ; !(i == m) ; i = (i+1) ) {
246
+ for( int j = 0 ; !(j == m) ; j = (j+1) ) {
247
+ v[ ((j*m)+i) ] = a[((i*m)+j)] ;
248
+ } ;
249
+ }
250
+ scm2cpp::cu::wrote_host(v);
251
+ }
252
+ } ;
253
+ scm2cpp::cu::need_host(e);
254
+ for( int i = 1 ; !(i == m) ; i = (i+1) ) {
255
+ e[ (i-1) ] = e[i] ;
256
+ } ;
257
+ scm2cpp::cu::wrote_host(e);
258
+ scm2cpp::cu::need_host(e);
259
+ e[ (m-1) ] = 0.0 ;
260
+ scm2cpp::cu::wrote_host(e);
261
+ scm2cpp::cu::need_host(ev);
262
+ scm2cpp::cu::need_host(e);
263
+ scm2cpp::cu::need_host(v);
264
+ for( int l = 0 ; !(l == m) ; l = (l+1) ) {
265
+ int fin = 0;
266
+ int iter = 0;
267
+ for( ; !((fin == 1 || iter > 60)) ; ) {
268
+ int mm = l;
269
+ int found = 0;
270
+ for( ; !((found == 1 || mm >= (m-1))) ; ) {
271
+ double dd = (eig_abs(ev[mm])+eig_abs(ev[(mm+1)]));
272
+ if( (eig_abs(e[mm])+dd) == dd ) {
273
+ found = 1 ;
274
+ } else {
275
+ mm = (mm+1) ;
276
+ } ;
277
+ ;
278
+ } ;
279
+ if( mm == l ) {
280
+ fin = 1 ;
281
+ } else {
282
+ iter = (iter+1) ;
283
+ double g = ((ev[(l+1)]-ev[l])/(2.0*e[l]));
284
+ double r = eig_hypot(g,1.0);
285
+ double g4 = ((ev[mm]-ev[l])+(e[l]/(g+( ( g >= 0.0 ) ? (eig_abs(r)) : ((0.0-eig_abs(r))) ))));
286
+ double s = 1.0;
287
+ double c = 1.0;
288
+ double pp = 0.0;
289
+ double gq = g4;
290
+ int under = 0;
291
+ int i = (mm-1);
292
+ for( ; !((under == 1 || i < l)) ; ) {
293
+ double f = (s*e[i]);
294
+ double b = (c*e[i]);
295
+ double r2 = eig_hypot(f,gq);
296
+ e[ (i+1) ] = r2 ;
297
+ if( r2 == 0.0 ) {
298
+ ev[ (i+1) ] = (ev[(i+1)]-pp) ;
299
+ e[ mm ] = 0.0 ;
300
+ under = 1 ;
301
+ } else {
302
+ s = (f/r2) ;
303
+ c = (gq/r2) ;
304
+ double g5 = (ev[(i+1)]-pp);
305
+ double r3 = (((ev[i]-g5)*s)+(2.0*(c*b)));
306
+ pp = (s*r3) ;
307
+ ev[ (i+1) ] = (g5+pp) ;
308
+ gq = ((c*r3)-b) ;
309
+ ;
310
+ ;
311
+ for( int k = 0 ; !(k == m) ; k = (k+1) ) {
312
+ double zf = v[(((i+1)*m)+k)];
313
+ double zi = v[((i*m)+k)];
314
+ v[ (((i+1)*m)+k) ] = ((s*zi)+(c*zf)) ;
315
+ v[ ((i*m)+k) ] = ((c*zi)-(s*zf)) ;
316
+ ;
317
+ } ;
318
+ i = (i-1) ;
319
+ } ;
320
+ ;
321
+ ;
322
+ } ;
323
+ if( under == 0 ) {
324
+ ev[ l ] = (ev[l]-pp) ;
325
+ e[ l ] = gq ;
326
+ e[ mm ] = 0.0 ;
327
+ } else {
328
+ 0 ;
329
+ } ;
330
+ ;
331
+ ;
332
+ ;
333
+ ;
334
+ } ;
335
+ ;
336
+ } ;
337
+ ;
338
+ } ;
339
+ scm2cpp::cu::wrote_host(e);
340
+ scm2cpp::cu::wrote_host(ev);
341
+ scm2cpp::cu::wrote_host(v);
342
+ scm2cpp::cu::need_host(v);
343
+ for( int i = 0 ; !(i == m) ; i = (i+1) ) {
344
+ for( int j = (i+1) ; !(j >= m) ; j = (j+1) ) {
345
+ double tmp = v[((i*m)+j)];
346
+ v[ ((i*m)+j) ] = v[((j*m)+i)] ;
347
+ v[ ((j*m)+i) ] = tmp ;
348
+ ;
349
+ } ;
350
+ } ;
351
+ scm2cpp::cu::wrote_host(v);
352
+ return 0 ;
353
+ }
354
+
355
+
356
+ SCM2CPP_FN inline double
357
+ eig_abs( double a )
358
+ {
359
+ if( a < 0.0 ) {
360
+ return (0.0-a) ;
361
+ }
362
+ else {
363
+ return a ;
364
+ }
365
+ }
366
+ static __global__ void scm2cpp_k3(long scm2cpp_cnt, int scm2cpp_lo, int* ord, double* scm2cpp_red) {
367
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
368
+ if (scm2cpp_t >= scm2cpp_cnt) return;
369
+ int j = scm2cpp_lo + (int)scm2cpp_t;
370
+ { ord[ j ] = j ;
371
+ }
372
+ }
373
+
374
+
375
+ inline int
376
+ eig_order( scm2cpp::cspan<double> ev, scm2cpp::span<int> ord, int m )
377
+ { { long scm2cpp_cnt = (long)(m) - (long)(0);
378
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
379
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
380
+ scm2cpp_k3<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(ord), scm2cpp_red);
381
+ scm2cpp::cu::launched("scm2cpp_k3");
382
+ scm2cpp::cu::wrote_dev(ord);
383
+ } else {
384
+ scm2cpp::cu::need_host(ord);
385
+ for( int j = 0 ; !(j == m) ; j = (j+1) ) {
386
+ ord[ j ] = j ;
387
+ }
388
+ scm2cpp::cu::wrote_host(ord);
389
+ }
390
+ } ;
391
+ scm2cpp::cu::need_host(ev);
392
+ scm2cpp::cu::need_host(ord);
393
+ for( int j = 0 ; !(j == m) ; j = (j+1) ) {
394
+ int best = j;
395
+ for( int r = (j+1) ; !(r >= m) ; r = (r+1) ) {
396
+ if( ev[ord[r]] > ev[ord[best]] ) {
397
+ best = r ;
398
+ } else {
399
+ 0 ;
400
+ } ;
401
+ } ;
402
+ int tmp = ord[j];
403
+ ord[ j ] = ord[best] ;
404
+ ord[ best ] = tmp ;
405
+ ;
406
+ ;
407
+ } ;
408
+ scm2cpp::cu::wrote_host(ord);
409
+ return 0 ;
410
+ }
411
+ static __global__ void scm2cpp_k4(long scm2cpp_cnt, int scm2cpp_lo, const int* ord, double* ev, const double* evf, double* v, const double* vf, int m, int k, double* scm2cpp_red) {
412
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
413
+ if (scm2cpp_t >= scm2cpp_cnt) return;
414
+ int c = scm2cpp_lo + (int)scm2cpp_t;
415
+ { int col = ord[c];
416
+ ev[ c ] = evf[col] ;
417
+ for( int j = 0 ; !(j == m) ; j = (j+1) ) {
418
+ v[ ((j*k)+c) ] = vf[((j*m)+col)] ;
419
+ } ;
420
+ ;
421
+ }
422
+ }
423
+
424
+
425
+ inline int
426
+ sym_eigen_top( scm2cpp::span<double> a, scm2cpp::span<double> v, scm2cpp::span<double> ev, scm2cpp::span<double> e, int m, int k )
427
+ { std::vector<double> vf((m*m),0.0);
428
+ scm2cpp::cu::fresh(vf);
429
+ std::vector<double> evf(m,0.0);
430
+ scm2cpp::cu::fresh(evf);
431
+ std::vector<int> ord(m,0);
432
+ scm2cpp::cu::fresh(ord);
433
+ sym_eigen(a,vf,evf,e,m) ;
434
+ eig_order(evf,ord,m) ;
435
+ { long scm2cpp_cnt = (long)(k) - (long)(0);
436
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
437
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
438
+ scm2cpp_k4<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(ord), scm2cpp::cu::dev(ev), scm2cpp::cu::dev(evf), scm2cpp::cu::dev(v), scm2cpp::cu::dev(vf), m, k, scm2cpp_red);
439
+ scm2cpp::cu::launched("scm2cpp_k4");
440
+ scm2cpp::cu::wrote_dev(ev);
441
+ scm2cpp::cu::wrote_dev(v);
442
+ } else {
443
+ scm2cpp::cu::need_host(ord);
444
+ scm2cpp::cu::need_host(ev);
445
+ scm2cpp::cu::need_host(evf);
446
+ scm2cpp::cu::need_host(v);
447
+ scm2cpp::cu::need_host(vf);
448
+ for( int c = 0 ; !(c == k) ; c = (c+1) ) {
449
+ int col = ord[c];
450
+ ev[ c ] = evf[col] ;
451
+ for( int j = 0 ; !(j == m) ; j = (j+1) ) {
452
+ v[ ((j*k)+c) ] = vf[((j*m)+col)] ;
453
+ } ;
454
+ ;
455
+ }
456
+ scm2cpp::cu::wrote_host(ev);
457
+ scm2cpp::cu::wrote_host(v);
458
+ }
459
+ } ;
460
+ return 0 ;
461
+ }
462
+
463
+
464
+ inline int
465
+ sym_eigen_gen( scm2cpp::span<double> a, scm2cpp::span<double> b, scm2cpp::span<double> v, scm2cpp::span<double> ev, scm2cpp::span<double> e, int m )
466
+ { scm2cpp::cu::need_host(b);
467
+ for( int j = 0 ; !(j == m) ; j = (j+1) ) {
468
+ double d = b[((j*m)+j)];
469
+ for( int l = 0 ; !(l == j) ; l = (l+1) ) {
470
+ d = (d-(b[((j*m)+l)]*b[((j*m)+l)])) ;
471
+ } ;
472
+ b[ ((j*m)+j) ] = sqrt(d) ;
473
+ for( int i = (j+1) ; !(i >= m) ; i = (i+1) ) {
474
+ double s = b[((i*m)+j)];
475
+ for( int l = 0 ; !(l == j) ; l = (l+1) ) {
476
+ s = (s-(b[((i*m)+l)]*b[((j*m)+l)])) ;
477
+ } ;
478
+ b[ ((i*m)+j) ] = (s/b[((j*m)+j)]) ;
479
+ ;
480
+ } ;
481
+ ;
482
+ } ;
483
+ scm2cpp::cu::wrote_host(b);
484
+ scm2cpp::cu::need_host(a);
485
+ scm2cpp::cu::need_host(b);
486
+ for( int c = 0 ; !(c == m) ; c = (c+1) ) {
487
+ for( int i = 0 ; !(i == m) ; i = (i+1) ) {
488
+ double s = a[((i*m)+c)];
489
+ for( int l = 0 ; !(l == i) ; l = (l+1) ) {
490
+ s = (s-(b[((i*m)+l)]*a[((l*m)+c)])) ;
491
+ } ;
492
+ a[ ((i*m)+c) ] = (s/b[((i*m)+i)]) ;
493
+ ;
494
+ } ;
495
+ } ;
496
+ scm2cpp::cu::wrote_host(a);
497
+ scm2cpp::cu::need_host(a);
498
+ scm2cpp::cu::need_host(b);
499
+ for( int r = 0 ; !(r == m) ; r = (r+1) ) {
500
+ for( int i = 0 ; !(i == m) ; i = (i+1) ) {
501
+ double s = a[((r*m)+i)];
502
+ for( int l = 0 ; !(l == i) ; l = (l+1) ) {
503
+ s = (s-(b[((i*m)+l)]*a[((r*m)+l)])) ;
504
+ } ;
505
+ a[ ((r*m)+i) ] = (s/b[((i*m)+i)]) ;
506
+ ;
507
+ } ;
508
+ } ;
509
+ scm2cpp::cu::wrote_host(a);
510
+ scm2cpp::cu::need_host(a);
511
+ for( int i = 0 ; !(i == m) ; i = (i+1) ) {
512
+ for( int j = 0 ; !(j == i) ; j = (j+1) ) {
513
+ double s = (0.5*(a[((i*m)+j)]+a[((j*m)+i)]));
514
+ a[ ((i*m)+j) ] = s ;
515
+ a[ ((j*m)+i) ] = s ;
516
+ ;
517
+ } ;
518
+ } ;
519
+ scm2cpp::cu::wrote_host(a);
520
+ sym_eigen(a,v,ev,e,m) ;
521
+ scm2cpp::cu::need_host(v);
522
+ scm2cpp::cu::need_host(b);
523
+ for( int c = 0 ; !(c == m) ; c = (c+1) ) {
524
+ for( int ii = 0 ; !(ii == m) ; ii = (ii+1) ) {
525
+ int i = ((m-1)-ii);
526
+ double s = v[((i*m)+c)];
527
+ for( int l = (i+1) ; !(l >= m) ; l = (l+1) ) {
528
+ s = (s-(b[((l*m)+i)]*v[((l*m)+c)])) ;
529
+ } ;
530
+ v[ ((i*m)+c) ] = (s/b[((i*m)+i)]) ;
531
+ ;
532
+ ;
533
+ } ;
534
+ } ;
535
+ scm2cpp::cu::wrote_host(v);
536
+ return 0 ;
537
+ }
538
+
539
+
540
+ SCM2CPP_FN inline double
541
+ ica_tanh( double x )
542
+ {
543
+ return (1.0-(2.0/(exp((2.0*x))+1.0))) ;
544
+ }
545
+ static __global__ void scm2cpp_k5(long scm2cpp_cnt, int scm2cpp_lo, const double* w, double* a, int m, double* scm2cpp_red) {
546
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
547
+ if (scm2cpp_t >= scm2cpp_cnt) return;
548
+ int i = scm2cpp_lo + (int)scm2cpp_t;
549
+ { for( int j = 0 ; !(j == m) ; j = (j+1) ) {
550
+ double acc = 0.0;
551
+ for( int r = 0 ; !(r == m) ; r = (r+1) ) {
552
+ acc = (acc+(w[((i*m)+r)]*w[((j*m)+r)])) ;
553
+ } ;
554
+ a[ ((i*m)+j) ] = acc ;
555
+ ;
556
+ } ;
557
+ }
558
+ }
559
+ static __global__ void scm2cpp_k6(long scm2cpp_cnt, int scm2cpp_lo, const double* w, double* a, int m, int i, double* scm2cpp_red) {
560
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
561
+ if (scm2cpp_t >= scm2cpp_cnt) return;
562
+ int j = scm2cpp_lo + (int)scm2cpp_t;
563
+ { double acc = 0.0;
564
+ for( int r = 0 ; !(r == m) ; r = (r+1) ) {
565
+ acc = (acc+(w[((i*m)+r)]*w[((j*m)+r)])) ;
566
+ } ;
567
+ a[ ((i*m)+j) ] = acc ;
568
+ ;
569
+ }
570
+ }
571
+ static __global__ void scm2cpp_k7(long scm2cpp_cnt, int scm2cpp_lo, const double* w, int i, int m, int j, double* scm2cpp_red) {
572
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
573
+ if (scm2cpp_t >= scm2cpp_cnt) return;
574
+ int r = scm2cpp_lo + (int)scm2cpp_t;
575
+ double acc = 0.0;
576
+ { acc = (acc+(w[((i*m)+r)]*w[((j*m)+r)])) ;
577
+ }
578
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, acc);
579
+ }
580
+ static __global__ void scm2cpp_k8(long scm2cpp_cnt, int scm2cpp_lo, const double* ev, const double* v, double* t, int m, double* scm2cpp_red) {
581
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
582
+ if (scm2cpp_t >= scm2cpp_cnt) return;
583
+ int i = scm2cpp_lo + (int)scm2cpp_t;
584
+ { for( int j = 0 ; !(j == m) ; j = (j+1) ) {
585
+ double acc = 0.0;
586
+ for( int r = 0 ; !(r == m) ; r = (r+1) ) {
587
+ double sr = ( ( ev[r] < 2.2250738585072014e-308 ) ? (2.2250738585072014e-308) : (ev[r]) );
588
+ acc = (acc+((v[((i*m)+r)]/sqrt(sr))*v[((j*m)+r)])) ;
589
+ ;
590
+ } ;
591
+ t[ ((i*m)+j) ] = acc ;
592
+ ;
593
+ } ;
594
+ }
595
+ }
596
+ static __global__ void scm2cpp_k9(long scm2cpp_cnt, int scm2cpp_lo, const double* ev, const double* v, double* t, int m, int i, double* scm2cpp_red) {
597
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
598
+ if (scm2cpp_t >= scm2cpp_cnt) return;
599
+ int j = scm2cpp_lo + (int)scm2cpp_t;
600
+ { double acc = 0.0;
601
+ for( int r = 0 ; !(r == m) ; r = (r+1) ) {
602
+ double sr = ( ( ev[r] < 2.2250738585072014e-308 ) ? (2.2250738585072014e-308) : (ev[r]) );
603
+ acc = (acc+((v[((i*m)+r)]/sqrt(sr))*v[((j*m)+r)])) ;
604
+ ;
605
+ } ;
606
+ t[ ((i*m)+j) ] = acc ;
607
+ ;
608
+ }
609
+ }
610
+ static __global__ void scm2cpp_k10(long scm2cpp_cnt, int scm2cpp_lo, const double* ev, const double* v, int i, int m, int j, double* scm2cpp_red) {
611
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
612
+ if (scm2cpp_t >= scm2cpp_cnt) return;
613
+ int r = scm2cpp_lo + (int)scm2cpp_t;
614
+ double acc = 0.0;
615
+ { double sr = ( ( ev[r] < 2.2250738585072014e-308 ) ? (2.2250738585072014e-308) : (ev[r]) );
616
+ acc = (acc+((v[((i*m)+r)]/sqrt(sr))*v[((j*m)+r)])) ;
617
+ ;
618
+ }
619
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, acc);
620
+ }
621
+ static __global__ void scm2cpp_k11(long scm2cpp_cnt, int scm2cpp_lo, const double* t, const double* w, double* a, int m, double* scm2cpp_red) {
622
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
623
+ if (scm2cpp_t >= scm2cpp_cnt) return;
624
+ int i = scm2cpp_lo + (int)scm2cpp_t;
625
+ { for( int j = 0 ; !(j == m) ; j = (j+1) ) {
626
+ double acc = 0.0;
627
+ for( int r = 0 ; !(r == m) ; r = (r+1) ) {
628
+ acc = (acc+(t[((i*m)+r)]*w[((r*m)+j)])) ;
629
+ } ;
630
+ a[ ((i*m)+j) ] = acc ;
631
+ ;
632
+ } ;
633
+ }
634
+ }
635
+ static __global__ void scm2cpp_k12(long scm2cpp_cnt, int scm2cpp_lo, const double* t, const double* w, double* a, int m, int i, double* scm2cpp_red) {
636
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
637
+ if (scm2cpp_t >= scm2cpp_cnt) return;
638
+ int j = scm2cpp_lo + (int)scm2cpp_t;
639
+ { double acc = 0.0;
640
+ for( int r = 0 ; !(r == m) ; r = (r+1) ) {
641
+ acc = (acc+(t[((i*m)+r)]*w[((r*m)+j)])) ;
642
+ } ;
643
+ a[ ((i*m)+j) ] = acc ;
644
+ ;
645
+ }
646
+ }
647
+ static __global__ void scm2cpp_k13(long scm2cpp_cnt, int scm2cpp_lo, const double* t, const double* w, int i, int m, int j, double* scm2cpp_red) {
648
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
649
+ if (scm2cpp_t >= scm2cpp_cnt) return;
650
+ int r = scm2cpp_lo + (int)scm2cpp_t;
651
+ double acc = 0.0;
652
+ { acc = (acc+(t[((i*m)+r)]*w[((r*m)+j)])) ;
653
+ }
654
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, acc);
655
+ }
656
+ static __global__ void scm2cpp_k14(long scm2cpp_cnt, int scm2cpp_lo, double* w, const double* a, double* scm2cpp_red) {
657
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
658
+ if (scm2cpp_t >= scm2cpp_cnt) return;
659
+ int t2 = scm2cpp_lo + (int)scm2cpp_t;
660
+ { w[ t2 ] = a[t2] ;
661
+ }
662
+ }
663
+
664
+
665
+ inline int
666
+ ica_sym( scm2cpp::span<double> w, scm2cpp::span<double> a, scm2cpp::span<double> v, scm2cpp::span<double> ev, scm2cpp::span<double> e, scm2cpp::span<double> t, int m )
667
+ { { long scm2cpp_cnt = (long)(m) - (long)(0);
668
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
669
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
670
+ scm2cpp_k5<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(w), scm2cpp::cu::dev(a), m, scm2cpp_red);
671
+ scm2cpp::cu::launched("scm2cpp_k5");
672
+ scm2cpp::cu::wrote_dev(a);
673
+ } else {
674
+ for( int i = 0 ; !(i == m) ; i = (i+1) ) {
675
+ {
676
+ long scm2cpp_cnt = (long)(m) - (long)(0);
677
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
678
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
679
+ scm2cpp_k6<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(w), scm2cpp::cu::dev(a), m, i, scm2cpp_red);
680
+ scm2cpp::cu::launched("scm2cpp_k6");
681
+ scm2cpp::cu::wrote_dev(a);
682
+ } else {
683
+ for( int j = 0 ; !(j == m) ; j = (j+1) ) {
684
+ double acc = 0.0;
685
+ {
686
+ long scm2cpp_cnt = (long)(m) - (long)(0);
687
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
688
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
689
+ scm2cpp_k7<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(w), i, m, j, scm2cpp_red);
690
+ scm2cpp::cu::launched("scm2cpp_k7");
691
+ acc = acc + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
692
+ } else {
693
+ scm2cpp::cu::need_host(w);
694
+ for( int r = 0 ; !(r == m) ; r = (r+1) ) {
695
+ acc = (acc+(w[((i*m)+r)]*w[((j*m)+r)])) ;
696
+ }
697
+ }
698
+ } ;
699
+ scm2cpp::cu::need_host(a);
700
+ a[ ((i*m)+j) ] = acc ;
701
+ scm2cpp::cu::wrote_host(a);
702
+ ;
703
+ }
704
+ }
705
+ } ;
706
+ }
707
+ }
708
+ } ;
709
+ sym_eigen(a,v,ev,e,m) ;
710
+ { long scm2cpp_cnt = (long)(m) - (long)(0);
711
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
712
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
713
+ scm2cpp_k8<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(ev), scm2cpp::cu::dev(v), scm2cpp::cu::dev(t), m, scm2cpp_red);
714
+ scm2cpp::cu::launched("scm2cpp_k8");
715
+ scm2cpp::cu::wrote_dev(t);
716
+ } else {
717
+ for( int i = 0 ; !(i == m) ; i = (i+1) ) {
718
+ {
719
+ long scm2cpp_cnt = (long)(m) - (long)(0);
720
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
721
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
722
+ scm2cpp_k9<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(ev), scm2cpp::cu::dev(v), scm2cpp::cu::dev(t), m, i, scm2cpp_red);
723
+ scm2cpp::cu::launched("scm2cpp_k9");
724
+ scm2cpp::cu::wrote_dev(t);
725
+ } else {
726
+ for( int j = 0 ; !(j == m) ; j = (j+1) ) {
727
+ double acc = 0.0;
728
+ {
729
+ long scm2cpp_cnt = (long)(m) - (long)(0);
730
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
731
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
732
+ scm2cpp_k10<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(ev), scm2cpp::cu::dev(v), i, m, j, scm2cpp_red);
733
+ scm2cpp::cu::launched("scm2cpp_k10");
734
+ acc = acc + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
735
+ } else {
736
+ scm2cpp::cu::need_host(ev);
737
+ scm2cpp::cu::need_host(v);
738
+ for( int r = 0 ; !(r == m) ; r = (r+1) ) {
739
+ double sr = ( ( ev[r] < 2.2250738585072014e-308 ) ? (2.2250738585072014e-308) : (ev[r]) );
740
+ acc = (acc+((v[((i*m)+r)]/sqrt(sr))*v[((j*m)+r)])) ;
741
+ ;
742
+ }
743
+ }
744
+ } ;
745
+ scm2cpp::cu::need_host(t);
746
+ t[ ((i*m)+j) ] = acc ;
747
+ scm2cpp::cu::wrote_host(t);
748
+ ;
749
+ }
750
+ }
751
+ } ;
752
+ }
753
+ }
754
+ } ;
755
+ { long scm2cpp_cnt = (long)(m) - (long)(0);
756
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
757
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
758
+ scm2cpp_k11<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(t), scm2cpp::cu::dev(w), scm2cpp::cu::dev(a), m, scm2cpp_red);
759
+ scm2cpp::cu::launched("scm2cpp_k11");
760
+ scm2cpp::cu::wrote_dev(a);
761
+ } else {
762
+ for( int i = 0 ; !(i == m) ; i = (i+1) ) {
763
+ {
764
+ long scm2cpp_cnt = (long)(m) - (long)(0);
765
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
766
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
767
+ scm2cpp_k12<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(t), scm2cpp::cu::dev(w), scm2cpp::cu::dev(a), m, i, scm2cpp_red);
768
+ scm2cpp::cu::launched("scm2cpp_k12");
769
+ scm2cpp::cu::wrote_dev(a);
770
+ } else {
771
+ for( int j = 0 ; !(j == m) ; j = (j+1) ) {
772
+ double acc = 0.0;
773
+ {
774
+ long scm2cpp_cnt = (long)(m) - (long)(0);
775
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
776
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
777
+ scm2cpp_k13<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(t), scm2cpp::cu::dev(w), i, m, j, scm2cpp_red);
778
+ scm2cpp::cu::launched("scm2cpp_k13");
779
+ acc = acc + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
780
+ } else {
781
+ scm2cpp::cu::need_host(t);
782
+ scm2cpp::cu::need_host(w);
783
+ for( int r = 0 ; !(r == m) ; r = (r+1) ) {
784
+ acc = (acc+(t[((i*m)+r)]*w[((r*m)+j)])) ;
785
+ }
786
+ }
787
+ } ;
788
+ scm2cpp::cu::need_host(a);
789
+ a[ ((i*m)+j) ] = acc ;
790
+ scm2cpp::cu::wrote_host(a);
791
+ ;
792
+ }
793
+ }
794
+ } ;
795
+ }
796
+ }
797
+ } ;
798
+ { long scm2cpp_cnt = (long)((m*m)) - (long)(0);
799
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
800
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
801
+ scm2cpp_k14<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(w), scm2cpp::cu::dev(a), scm2cpp_red);
802
+ scm2cpp::cu::launched("scm2cpp_k14");
803
+ scm2cpp::cu::wrote_dev(w);
804
+ } else {
805
+ scm2cpp::cu::need_host(w);
806
+ scm2cpp::cu::need_host(a);
807
+ for( int t2 = 0 ; !(t2 == (m*m)) ; t2 = (t2+1) ) {
808
+ w[ t2 ] = a[t2] ;
809
+ }
810
+ scm2cpp::cu::wrote_host(w);
811
+ }
812
+ } ;
813
+ return 0 ;
814
+ }
815
+ static __global__ void scm2cpp_k15(long scm2cpp_cnt, int scm2cpp_lo, double* mean, double* scm2cpp_red) {
816
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
817
+ if (scm2cpp_t >= scm2cpp_cnt) return;
818
+ int j = scm2cpp_lo + (int)scm2cpp_t;
819
+ { mean[ j ] = 0.0 ;
820
+ }
821
+ }
822
+ static __global__ void scm2cpp_k16(long scm2cpp_cnt, int scm2cpp_lo, double* mean, const double* x, int i, int p, double* scm2cpp_red) {
823
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
824
+ if (scm2cpp_t >= scm2cpp_cnt) return;
825
+ int j = scm2cpp_lo + (int)scm2cpp_t;
826
+ { mean[ j ] = (mean[j]+x[((i*p)+j)]) ;
827
+ }
828
+ }
829
+ static __global__ void scm2cpp_k17(long scm2cpp_cnt, int scm2cpp_lo, double* mean, int n, double* scm2cpp_red) {
830
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
831
+ if (scm2cpp_t >= scm2cpp_cnt) return;
832
+ int j = scm2cpp_lo + (int)scm2cpp_t;
833
+ { mean[ j ] = (mean[j]/double(n)) ;
834
+ }
835
+ }
836
+ static __global__ void scm2cpp_k18(long scm2cpp_cnt, int scm2cpp_lo, double* xc, const double* x, const double* mean, int p, double* scm2cpp_red) {
837
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
838
+ if (scm2cpp_t >= scm2cpp_cnt) return;
839
+ int i = scm2cpp_lo + (int)scm2cpp_t;
840
+ { for( int j = 0 ; !(j == p) ; j = (j+1) ) {
841
+ xc[ ((i*p)+j) ] = (x[((i*p)+j)]-mean[j]) ;
842
+ } ;
843
+ }
844
+ }
845
+ static __global__ void scm2cpp_k19(long scm2cpp_cnt, int scm2cpp_lo, double* xc, const double* x, const double* mean, int i, int p, double* scm2cpp_red) {
846
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
847
+ if (scm2cpp_t >= scm2cpp_cnt) return;
848
+ int j = scm2cpp_lo + (int)scm2cpp_t;
849
+ { xc[ ((i*p)+j) ] = (x[((i*p)+j)]-mean[j]) ;
850
+ }
851
+ }
852
+ static __global__ void scm2cpp_k20(long scm2cpp_cnt, int scm2cpp_lo, const int* ord, const double* u, const double* ev, double* white, int p, double* scm2cpp_red) {
853
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
854
+ if (scm2cpp_t >= scm2cpp_cnt) return;
855
+ int c = scm2cpp_lo + (int)scm2cpp_t;
856
+ { int col = ord[c];
857
+ double sg = ( ( u[col] < 0.0 ) ? (-1.0) : (( ( u[col] > 0.0 ) ? (1.0) : (0.0) )) );
858
+ double d = sqrt(ev[col]);
859
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
860
+ white[ ((c*p)+j) ] = ((sg*u[((j*p)+col)])/d) ;
861
+ } ;
862
+ ;
863
+ ;
864
+ }
865
+ }
866
+ static __global__ void scm2cpp_k21(long scm2cpp_cnt, int scm2cpp_lo, double* white, const double* u, int c, int p, double sg, int col, double d, double* scm2cpp_red) {
867
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
868
+ if (scm2cpp_t >= scm2cpp_cnt) return;
869
+ int j = scm2cpp_lo + (int)scm2cpp_t;
870
+ { white[ ((c*p)+j) ] = ((sg*u[((j*p)+col)])/d) ;
871
+ }
872
+ }
873
+ static __global__ void scm2cpp_k22(long scm2cpp_cnt, int scm2cpp_lo, double* x1, double sn, double* scm2cpp_red) {
874
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
875
+ if (scm2cpp_t >= scm2cpp_cnt) return;
876
+ int t = scm2cpp_lo + (int)scm2cpp_t;
877
+ { x1[ t ] = (x1[t]*sn) ;
878
+ }
879
+ }
880
+ static __global__ void scm2cpp_k23(long scm2cpp_cnt, int scm2cpp_lo, double* unmix, const double* winit, double* scm2cpp_red) {
881
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
882
+ if (scm2cpp_t >= scm2cpp_cnt) return;
883
+ int t = scm2cpp_lo + (int)scm2cpp_t;
884
+ { unmix[ t ] = winit[t] ;
885
+ }
886
+ }
887
+ static __global__ void scm2cpp_k24(long scm2cpp_cnt, int scm2cpp_lo, double* gw, double* gx, int n, double* scm2cpp_red) {
888
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
889
+ if (scm2cpp_t >= scm2cpp_cnt) return;
890
+ int c = scm2cpp_lo + (int)scm2cpp_t;
891
+ { double acc = 0.0;
892
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
893
+ double th = ica_tanh(gw[((c*n)+i)]);
894
+ gw[ ((c*n)+i) ] = th ;
895
+ acc = (acc+(1.0-(th*th))) ;
896
+ ;
897
+ } ;
898
+ gx[ c ] = (acc/double(n)) ;
899
+ ;
900
+ }
901
+ }
902
+ static __global__ void scm2cpp_k25(long scm2cpp_cnt, int scm2cpp_lo, double* gw, int c, int n, double* scm2cpp_red) {
903
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
904
+ if (scm2cpp_t >= scm2cpp_cnt) return;
905
+ int i = scm2cpp_lo + (int)scm2cpp_t;
906
+ double acc = 0.0;
907
+ { double th = ica_tanh(gw[((c*n)+i)]);
908
+ gw[ ((c*n)+i) ] = th ;
909
+ acc = (acc+(1.0-(th*th))) ;
910
+ ;
911
+ }
912
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, acc);
913
+ }
914
+ static __global__ void scm2cpp_k26(long scm2cpp_cnt, int scm2cpp_lo, double* w1, const double* gx, const double* unmix, int nc, int n, double* scm2cpp_red) {
915
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
916
+ if (scm2cpp_t >= scm2cpp_cnt) return;
917
+ int c = scm2cpp_lo + (int)scm2cpp_t;
918
+ { for( int j = 0 ; !(j == nc) ; j = (j+1) ) {
919
+ w1[ ((c*nc)+j) ] = ((w1[((c*nc)+j)]/double(n))-(gx[c]*unmix[((c*nc)+j)])) ;
920
+ } ;
921
+ }
922
+ }
923
+ static __global__ void scm2cpp_k27(long scm2cpp_cnt, int scm2cpp_lo, double* w1, const double* gx, const double* unmix, int c, int nc, int n, double* scm2cpp_red) {
924
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
925
+ if (scm2cpp_t >= scm2cpp_cnt) return;
926
+ int j = scm2cpp_lo + (int)scm2cpp_t;
927
+ { w1[ ((c*nc)+j) ] = ((w1[((c*nc)+j)]/double(n))-(gx[c]*unmix[((c*nc)+j)])) ;
928
+ }
929
+ }
930
+ static __global__ void scm2cpp_k28(long scm2cpp_cnt, int scm2cpp_lo, const double* w1, const double* unmix, int c, int nc, double* scm2cpp_red) {
931
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
932
+ if (scm2cpp_t >= scm2cpp_cnt) return;
933
+ int j = scm2cpp_lo + (int)scm2cpp_t;
934
+ double acc = 0.0;
935
+ { acc = (acc+(w1[((c*nc)+j)]*unmix[((c*nc)+j)])) ;
936
+ }
937
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, acc);
938
+ }
939
+ static __global__ void scm2cpp_k29(long scm2cpp_cnt, int scm2cpp_lo, double* unmix, const double* w1, double* scm2cpp_red) {
940
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
941
+ if (scm2cpp_t >= scm2cpp_cnt) return;
942
+ int t = scm2cpp_lo + (int)scm2cpp_t;
943
+ { unmix[ t ] = w1[t] ;
944
+ }
945
+ }
946
+ static __global__ void scm2cpp_k30(long scm2cpp_cnt, int scm2cpp_lo, const double* unmix, const double* white, double* comps, int p, int nc, double* scm2cpp_red) {
947
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
948
+ if (scm2cpp_t >= scm2cpp_cnt) return;
949
+ int c = scm2cpp_lo + (int)scm2cpp_t;
950
+ { for( int j = 0 ; !(j == p) ; j = (j+1) ) {
951
+ double acc = 0.0;
952
+ for( int r = 0 ; !(r == nc) ; r = (r+1) ) {
953
+ acc = (acc+(unmix[((c*nc)+r)]*white[((r*p)+j)])) ;
954
+ } ;
955
+ comps[ ((c*p)+j) ] = acc ;
956
+ ;
957
+ } ;
958
+ }
959
+ }
960
+ static __global__ void scm2cpp_k31(long scm2cpp_cnt, int scm2cpp_lo, const double* unmix, const double* white, double* comps, int nc, int c, int p, double* scm2cpp_red) {
961
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
962
+ if (scm2cpp_t >= scm2cpp_cnt) return;
963
+ int j = scm2cpp_lo + (int)scm2cpp_t;
964
+ { double acc = 0.0;
965
+ for( int r = 0 ; !(r == nc) ; r = (r+1) ) {
966
+ acc = (acc+(unmix[((c*nc)+r)]*white[((r*p)+j)])) ;
967
+ } ;
968
+ comps[ ((c*p)+j) ] = acc ;
969
+ ;
970
+ }
971
+ }
972
+ static __global__ void scm2cpp_k32(long scm2cpp_cnt, int scm2cpp_lo, const double* unmix, const double* white, int c, int nc, int p, int j, double* scm2cpp_red) {
973
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
974
+ if (scm2cpp_t >= scm2cpp_cnt) return;
975
+ int r = scm2cpp_lo + (int)scm2cpp_t;
976
+ double acc = 0.0;
977
+ { acc = (acc+(unmix[((c*nc)+r)]*white[((r*p)+j)])) ;
978
+ }
979
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, acc);
980
+ }
981
+ static __global__ void scm2cpp_k33(long scm2cpp_cnt, int scm2cpp_lo, const double* gw, double* unmix, int n, int nc, double* scm2cpp_red) {
982
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
983
+ if (scm2cpp_t >= scm2cpp_cnt) return;
984
+ int c = scm2cpp_lo + (int)scm2cpp_t;
985
+ { double m1 = 0.0;
986
+ double v1 = 0.0;
987
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
988
+ m1 = (m1+gw[((c*n)+i)]) ;
989
+ } ;
990
+ m1 = (m1/double(n)) ;
991
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
992
+ double dd = (gw[((c*n)+i)]-m1);
993
+ v1 = (v1+(dd*dd)) ;
994
+ ;
995
+ } ;
996
+ double sd = sqrt((v1/double(n)));
997
+ for( int j = 0 ; !(j == nc) ; j = (j+1) ) {
998
+ unmix[ ((c*nc)+j) ] = (unmix[((c*nc)+j)]/sd) ;
999
+ } ;
1000
+ ;
1001
+ ;
1002
+ }
1003
+ }
1004
+ static __global__ void scm2cpp_k34(long scm2cpp_cnt, int scm2cpp_lo, const double* gw, int c, int n, double* scm2cpp_red) {
1005
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1006
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1007
+ int i = scm2cpp_lo + (int)scm2cpp_t;
1008
+ double m1 = 0.0;
1009
+ { m1 = (m1+gw[((c*n)+i)]) ;
1010
+ }
1011
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, m1);
1012
+ }
1013
+ static __global__ void scm2cpp_k35(long scm2cpp_cnt, int scm2cpp_lo, const double* gw, int c, int n, double m1, double* scm2cpp_red) {
1014
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1015
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1016
+ int i = scm2cpp_lo + (int)scm2cpp_t;
1017
+ double v1 = 0.0;
1018
+ { double dd = (gw[((c*n)+i)]-m1);
1019
+ v1 = (v1+(dd*dd)) ;
1020
+ ;
1021
+ }
1022
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, v1);
1023
+ }
1024
+ static __global__ void scm2cpp_k36(long scm2cpp_cnt, int scm2cpp_lo, double* unmix, int c, int nc, double sd, double* scm2cpp_red) {
1025
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1026
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1027
+ int j = scm2cpp_lo + (int)scm2cpp_t;
1028
+ { unmix[ ((c*nc)+j) ] = (unmix[((c*nc)+j)]/sd) ;
1029
+ }
1030
+ }
1031
+ static __global__ void scm2cpp_k37(long scm2cpp_cnt, int scm2cpp_lo, const double* unmix, const double* white, double* comps, int p, int nc, double* scm2cpp_red) {
1032
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1033
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1034
+ int c = scm2cpp_lo + (int)scm2cpp_t;
1035
+ { for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1036
+ double acc = 0.0;
1037
+ for( int r = 0 ; !(r == nc) ; r = (r+1) ) {
1038
+ acc = (acc+(unmix[((c*nc)+r)]*white[((r*p)+j)])) ;
1039
+ } ;
1040
+ comps[ ((c*p)+j) ] = acc ;
1041
+ ;
1042
+ } ;
1043
+ }
1044
+ }
1045
+ static __global__ void scm2cpp_k38(long scm2cpp_cnt, int scm2cpp_lo, const double* unmix, const double* white, double* comps, int nc, int c, int p, double* scm2cpp_red) {
1046
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1047
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1048
+ int j = scm2cpp_lo + (int)scm2cpp_t;
1049
+ { double acc = 0.0;
1050
+ for( int r = 0 ; !(r == nc) ; r = (r+1) ) {
1051
+ acc = (acc+(unmix[((c*nc)+r)]*white[((r*p)+j)])) ;
1052
+ } ;
1053
+ comps[ ((c*p)+j) ] = acc ;
1054
+ ;
1055
+ }
1056
+ }
1057
+ static __global__ void scm2cpp_k39(long scm2cpp_cnt, int scm2cpp_lo, const double* unmix, const double* white, int c, int nc, int p, int j, double* scm2cpp_red) {
1058
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1059
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1060
+ int r = scm2cpp_lo + (int)scm2cpp_t;
1061
+ double acc = 0.0;
1062
+ { acc = (acc+(unmix[((c*nc)+r)]*white[((r*p)+j)])) ;
1063
+ }
1064
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, acc);
1065
+ }
1066
+
1067
+
1068
+ inline int
1069
+ fastica( scm2cpp::cspan<double> x, scm2cpp::cspan<double> winit, scm2cpp::span<double> comps, scm2cpp::span<double> white, scm2cpp::span<double> unmix, scm2cpp::span<double> mean, int maxiter, double tol, int n, int p, int nc )
1070
+ { std::vector<double> xc((n*p),0.0);
1071
+ scm2cpp::cu::fresh(xc);
1072
+ std::vector<double> g((p*p),0.0);
1073
+ scm2cpp::cu::fresh(g);
1074
+ std::vector<double> u((p*p),0.0);
1075
+ scm2cpp::cu::fresh(u);
1076
+ std::vector<double> ev(p,0.0);
1077
+ scm2cpp::cu::fresh(ev);
1078
+ std::vector<int> ord(p,0);
1079
+ scm2cpp::cu::fresh(ord);
1080
+ std::vector<double> x1((nc*n),0.0);
1081
+ scm2cpp::cu::fresh(x1);
1082
+ std::vector<double> gw((nc*n),0.0);
1083
+ scm2cpp::cu::fresh(gw);
1084
+ std::vector<double> w1((nc*nc),0.0);
1085
+ scm2cpp::cu::fresh(w1);
1086
+ std::vector<double> gx(nc,0.0);
1087
+ scm2cpp::cu::fresh(gx);
1088
+ std::vector<double> sa((nc*nc),0.0);
1089
+ scm2cpp::cu::fresh(sa);
1090
+ std::vector<double> sv((nc*nc),0.0);
1091
+ scm2cpp::cu::fresh(sv);
1092
+ std::vector<double> se(nc,0.0);
1093
+ scm2cpp::cu::fresh(se);
1094
+ std::vector<double> se2(nc,0.0);
1095
+ scm2cpp::cu::fresh(se2);
1096
+ std::vector<double> pe(p,0.0);
1097
+ scm2cpp::cu::fresh(pe);
1098
+ std::vector<double> st((nc*nc),0.0);
1099
+ scm2cpp::cu::fresh(st);
1100
+ int it = 0;
1101
+ int done = 0;
1102
+ { long scm2cpp_cnt = (long)(p) - (long)(0);
1103
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1104
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1105
+ scm2cpp_k15<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(mean), scm2cpp_red);
1106
+ scm2cpp::cu::launched("scm2cpp_k15");
1107
+ scm2cpp::cu::wrote_dev(mean);
1108
+ } else {
1109
+ scm2cpp::cu::need_host(mean);
1110
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1111
+ mean[ j ] = 0.0 ;
1112
+ }
1113
+ scm2cpp::cu::wrote_host(mean);
1114
+ }
1115
+ } ;
1116
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
1117
+ {
1118
+ long scm2cpp_cnt = (long)(p) - (long)(0);
1119
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1120
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1121
+ scm2cpp_k16<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(mean), scm2cpp::cu::dev(x), i, p, scm2cpp_red);
1122
+ scm2cpp::cu::launched("scm2cpp_k16");
1123
+ scm2cpp::cu::wrote_dev(mean);
1124
+ } else {
1125
+ scm2cpp::cu::need_host(mean);
1126
+ scm2cpp::cu::need_host(x);
1127
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1128
+ mean[ j ] = (mean[j]+x[((i*p)+j)]) ;
1129
+ }
1130
+ scm2cpp::cu::wrote_host(mean);
1131
+ }
1132
+ } ;
1133
+ } ;
1134
+ { long scm2cpp_cnt = (long)(p) - (long)(0);
1135
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1136
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1137
+ scm2cpp_k17<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(mean), n, scm2cpp_red);
1138
+ scm2cpp::cu::launched("scm2cpp_k17");
1139
+ scm2cpp::cu::wrote_dev(mean);
1140
+ } else {
1141
+ scm2cpp::cu::need_host(mean);
1142
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1143
+ mean[ j ] = (mean[j]/double(n)) ;
1144
+ }
1145
+ scm2cpp::cu::wrote_host(mean);
1146
+ }
1147
+ } ;
1148
+ { long scm2cpp_cnt = (long)(n) - (long)(0);
1149
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1150
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1151
+ scm2cpp_k18<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(xc), scm2cpp::cu::dev(x), scm2cpp::cu::dev(mean), p, scm2cpp_red);
1152
+ scm2cpp::cu::launched("scm2cpp_k18");
1153
+ scm2cpp::cu::wrote_dev(xc);
1154
+ } else {
1155
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
1156
+ {
1157
+ long scm2cpp_cnt = (long)(p) - (long)(0);
1158
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1159
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1160
+ scm2cpp_k19<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(xc), scm2cpp::cu::dev(x), scm2cpp::cu::dev(mean), i, p, scm2cpp_red);
1161
+ scm2cpp::cu::launched("scm2cpp_k19");
1162
+ scm2cpp::cu::wrote_dev(xc);
1163
+ } else {
1164
+ scm2cpp::cu::need_host(xc);
1165
+ scm2cpp::cu::need_host(x);
1166
+ scm2cpp::cu::need_host(mean);
1167
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1168
+ xc[ ((i*p)+j) ] = (x[((i*p)+j)]-mean[j]) ;
1169
+ }
1170
+ scm2cpp::cu::wrote_host(xc);
1171
+ }
1172
+ } ;
1173
+ }
1174
+ }
1175
+ } ;
1176
+ scm2cpp::cu::blas_syrk(g, xc, 1.0, 0.0, 1, p, n) ;
1177
+ sym_eigen(g,u,ev,pe,p) ;
1178
+ eig_order(ev,ord,p) ;
1179
+ { long scm2cpp_cnt = (long)(nc) - (long)(0);
1180
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1181
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1182
+ scm2cpp_k20<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(ord), scm2cpp::cu::dev(u), scm2cpp::cu::dev(ev), scm2cpp::cu::dev(white), p, scm2cpp_red);
1183
+ scm2cpp::cu::launched("scm2cpp_k20");
1184
+ scm2cpp::cu::wrote_dev(white);
1185
+ } else {
1186
+ for( int c = 0 ; !(c == nc) ; c = (c+1) ) {
1187
+ scm2cpp::cu::need_host(ord);
1188
+ int col = ord[c];
1189
+ scm2cpp::cu::need_host(u);
1190
+ scm2cpp::cu::need_host(ev);
1191
+ double sg = ( ( u[col] < 0.0 ) ? (-1.0) : (( ( u[col] > 0.0 ) ? (1.0) : (0.0) )) );
1192
+ double d = sqrt(ev[col]);
1193
+ {
1194
+ long scm2cpp_cnt = (long)(p) - (long)(0);
1195
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1196
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1197
+ scm2cpp_k21<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(white), scm2cpp::cu::dev(u), c, p, sg, col, d, scm2cpp_red);
1198
+ scm2cpp::cu::launched("scm2cpp_k21");
1199
+ scm2cpp::cu::wrote_dev(white);
1200
+ } else {
1201
+ scm2cpp::cu::need_host(white);
1202
+ scm2cpp::cu::need_host(u);
1203
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1204
+ white[ ((c*p)+j) ] = ((sg*u[((j*p)+col)])/d) ;
1205
+ }
1206
+ scm2cpp::cu::wrote_host(white);
1207
+ }
1208
+ } ;
1209
+ ;
1210
+ ;
1211
+ }
1212
+ }
1213
+ } ;
1214
+ scm2cpp::cu::blas_gemm(x1, white, xc, 1.0, 0.0, 0, 1, nc, n, p) ;
1215
+ double sn = sqrt(double(n));
1216
+ {
1217
+ long scm2cpp_cnt = (long)((nc*n)) - (long)(0);
1218
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1219
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1220
+ scm2cpp_k22<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(x1), sn, scm2cpp_red);
1221
+ scm2cpp::cu::launched("scm2cpp_k22");
1222
+ scm2cpp::cu::wrote_dev(x1);
1223
+ } else {
1224
+ scm2cpp::cu::need_host(x1);
1225
+ for( int t = 0 ; !(t == (nc*n)) ; t = (t+1) ) {
1226
+ x1[ t ] = (x1[t]*sn) ;
1227
+ }
1228
+ scm2cpp::cu::wrote_host(x1);
1229
+ }
1230
+ } ;
1231
+ ;
1232
+ { long scm2cpp_cnt = (long)((nc*nc)) - (long)(0);
1233
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1234
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1235
+ scm2cpp_k23<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(unmix), scm2cpp::cu::dev(winit), scm2cpp_red);
1236
+ scm2cpp::cu::launched("scm2cpp_k23");
1237
+ scm2cpp::cu::wrote_dev(unmix);
1238
+ } else {
1239
+ scm2cpp::cu::need_host(unmix);
1240
+ scm2cpp::cu::need_host(winit);
1241
+ for( int t = 0 ; !(t == (nc*nc)) ; t = (t+1) ) {
1242
+ unmix[ t ] = winit[t] ;
1243
+ }
1244
+ scm2cpp::cu::wrote_host(unmix);
1245
+ }
1246
+ } ;
1247
+ ica_sym(unmix,sa,sv,se,se2,st,nc) ;
1248
+ for( ; !((done == 1 || it >= maxiter)) ; ) {
1249
+ scm2cpp::cu::blas_gemm(gw, unmix, x1, 1.0, 0.0, 0, 0, nc, n, nc) ;
1250
+ { long scm2cpp_cnt = (long)(nc) - (long)(0);
1251
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1252
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1253
+ scm2cpp_k24<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(gw), scm2cpp::cu::dev(gx), n, scm2cpp_red);
1254
+ scm2cpp::cu::launched("scm2cpp_k24");
1255
+ scm2cpp::cu::wrote_dev(gw);
1256
+ scm2cpp::cu::wrote_dev(gx);
1257
+ } else {
1258
+ for( int c = 0 ; !(c == nc) ; c = (c+1) ) {
1259
+ double acc = 0.0;
1260
+ {
1261
+ long scm2cpp_cnt = (long)(n) - (long)(0);
1262
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1263
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1264
+ scm2cpp_k25<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(gw), c, n, scm2cpp_red);
1265
+ scm2cpp::cu::launched("scm2cpp_k25");
1266
+ scm2cpp::cu::wrote_dev(gw);
1267
+ acc = acc + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
1268
+ } else {
1269
+ scm2cpp::cu::need_host(gw);
1270
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
1271
+ double th = ica_tanh(gw[((c*n)+i)]);
1272
+ gw[ ((c*n)+i) ] = th ;
1273
+ acc = (acc+(1.0-(th*th))) ;
1274
+ ;
1275
+ }
1276
+ scm2cpp::cu::wrote_host(gw);
1277
+ }
1278
+ } ;
1279
+ scm2cpp::cu::need_host(gx);
1280
+ gx[ c ] = (acc/double(n)) ;
1281
+ scm2cpp::cu::wrote_host(gx);
1282
+ ;
1283
+ }
1284
+ }
1285
+ } ;
1286
+ scm2cpp::cu::blas_gemm(w1, gw, x1, 1.0, 0.0, 0, 1, nc, nc, n) ;
1287
+ { long scm2cpp_cnt = (long)(nc) - (long)(0);
1288
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1289
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1290
+ scm2cpp_k26<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(w1), scm2cpp::cu::dev(gx), scm2cpp::cu::dev(unmix), nc, n, scm2cpp_red);
1291
+ scm2cpp::cu::launched("scm2cpp_k26");
1292
+ scm2cpp::cu::wrote_dev(w1);
1293
+ } else {
1294
+ for( int c = 0 ; !(c == nc) ; c = (c+1) ) {
1295
+ {
1296
+ long scm2cpp_cnt = (long)(nc) - (long)(0);
1297
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1298
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1299
+ scm2cpp_k27<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(w1), scm2cpp::cu::dev(gx), scm2cpp::cu::dev(unmix), c, nc, n, scm2cpp_red);
1300
+ scm2cpp::cu::launched("scm2cpp_k27");
1301
+ scm2cpp::cu::wrote_dev(w1);
1302
+ } else {
1303
+ scm2cpp::cu::need_host(w1);
1304
+ scm2cpp::cu::need_host(gx);
1305
+ scm2cpp::cu::need_host(unmix);
1306
+ for( int j = 0 ; !(j == nc) ; j = (j+1) ) {
1307
+ w1[ ((c*nc)+j) ] = ((w1[((c*nc)+j)]/double(n))-(gx[c]*unmix[((c*nc)+j)])) ;
1308
+ }
1309
+ scm2cpp::cu::wrote_host(w1);
1310
+ }
1311
+ } ;
1312
+ }
1313
+ }
1314
+ } ;
1315
+ ica_sym(w1,sa,sv,se,se2,st,nc) ;
1316
+ double lim = 0.0;
1317
+ for( int c = 0 ; !(c == nc) ; c = (c+1) ) {
1318
+ double acc = 0.0;
1319
+ {
1320
+ long scm2cpp_cnt = (long)(nc) - (long)(0);
1321
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1322
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1323
+ scm2cpp_k28<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(w1), scm2cpp::cu::dev(unmix), c, nc, scm2cpp_red);
1324
+ scm2cpp::cu::launched("scm2cpp_k28");
1325
+ acc = acc + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
1326
+ } else {
1327
+ scm2cpp::cu::need_host(w1);
1328
+ scm2cpp::cu::need_host(unmix);
1329
+ for( int j = 0 ; !(j == nc) ; j = (j+1) ) {
1330
+ acc = (acc+(w1[((c*nc)+j)]*unmix[((c*nc)+j)])) ;
1331
+ }
1332
+ }
1333
+ } ;
1334
+ double dv = (( ( acc < 0.0 ) ? ((0.0-acc)) : (acc) )-1.0);
1335
+ double av = ( ( dv < 0.0 ) ? ((0.0-dv)) : (dv) );
1336
+ if( av > lim ) {
1337
+ lim = av ;
1338
+ } else {
1339
+ 0 ;
1340
+ } ;
1341
+ ;
1342
+ ;
1343
+ ;
1344
+ } ;
1345
+ { long scm2cpp_cnt = (long)((nc*nc)) - (long)(0);
1346
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1347
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1348
+ scm2cpp_k29<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(unmix), scm2cpp::cu::dev(w1), scm2cpp_red);
1349
+ scm2cpp::cu::launched("scm2cpp_k29");
1350
+ scm2cpp::cu::wrote_dev(unmix);
1351
+ } else {
1352
+ scm2cpp::cu::need_host(unmix);
1353
+ scm2cpp::cu::need_host(w1);
1354
+ for( int t = 0 ; !(t == (nc*nc)) ; t = (t+1) ) {
1355
+ unmix[ t ] = w1[t] ;
1356
+ }
1357
+ scm2cpp::cu::wrote_host(unmix);
1358
+ }
1359
+ } ;
1360
+ it = (it+1) ;
1361
+ if( lim < tol ) {
1362
+ done = 1 ;
1363
+ } else {
1364
+ 0 ;
1365
+ } ;
1366
+ ;
1367
+ } ;
1368
+ { long scm2cpp_cnt = (long)(nc) - (long)(0);
1369
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1370
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1371
+ scm2cpp_k30<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(unmix), scm2cpp::cu::dev(white), scm2cpp::cu::dev(comps), p, nc, scm2cpp_red);
1372
+ scm2cpp::cu::launched("scm2cpp_k30");
1373
+ scm2cpp::cu::wrote_dev(comps);
1374
+ } else {
1375
+ for( int c = 0 ; !(c == nc) ; c = (c+1) ) {
1376
+ {
1377
+ long scm2cpp_cnt = (long)(p) - (long)(0);
1378
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1379
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1380
+ scm2cpp_k31<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(unmix), scm2cpp::cu::dev(white), scm2cpp::cu::dev(comps), nc, c, p, scm2cpp_red);
1381
+ scm2cpp::cu::launched("scm2cpp_k31");
1382
+ scm2cpp::cu::wrote_dev(comps);
1383
+ } else {
1384
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1385
+ double acc = 0.0;
1386
+ {
1387
+ long scm2cpp_cnt = (long)(nc) - (long)(0);
1388
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1389
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1390
+ scm2cpp_k32<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(unmix), scm2cpp::cu::dev(white), c, nc, p, j, scm2cpp_red);
1391
+ scm2cpp::cu::launched("scm2cpp_k32");
1392
+ acc = acc + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
1393
+ } else {
1394
+ scm2cpp::cu::need_host(unmix);
1395
+ scm2cpp::cu::need_host(white);
1396
+ for( int r = 0 ; !(r == nc) ; r = (r+1) ) {
1397
+ acc = (acc+(unmix[((c*nc)+r)]*white[((r*p)+j)])) ;
1398
+ }
1399
+ }
1400
+ } ;
1401
+ scm2cpp::cu::need_host(comps);
1402
+ comps[ ((c*p)+j) ] = acc ;
1403
+ scm2cpp::cu::wrote_host(comps);
1404
+ ;
1405
+ }
1406
+ }
1407
+ } ;
1408
+ }
1409
+ }
1410
+ } ;
1411
+ scm2cpp::cu::blas_gemm(gw, comps, xc, 1.0, 0.0, 0, 1, nc, n, p) ;
1412
+ { long scm2cpp_cnt = (long)(nc) - (long)(0);
1413
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1414
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1415
+ scm2cpp_k33<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(gw), scm2cpp::cu::dev(unmix), n, nc, scm2cpp_red);
1416
+ scm2cpp::cu::launched("scm2cpp_k33");
1417
+ scm2cpp::cu::wrote_dev(unmix);
1418
+ } else {
1419
+ for( int c = 0 ; !(c == nc) ; c = (c+1) ) {
1420
+ double m1 = 0.0;
1421
+ double v1 = 0.0;
1422
+ {
1423
+ long scm2cpp_cnt = (long)(n) - (long)(0);
1424
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1425
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1426
+ scm2cpp_k34<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(gw), c, n, scm2cpp_red);
1427
+ scm2cpp::cu::launched("scm2cpp_k34");
1428
+ m1 = m1 + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
1429
+ } else {
1430
+ scm2cpp::cu::need_host(gw);
1431
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
1432
+ m1 = (m1+gw[((c*n)+i)]) ;
1433
+ }
1434
+ }
1435
+ } ;
1436
+ m1 = (m1/double(n)) ;
1437
+ { long scm2cpp_cnt = (long)(n) - (long)(0);
1438
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1439
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1440
+ scm2cpp_k35<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(gw), c, n, m1, scm2cpp_red);
1441
+ scm2cpp::cu::launched("scm2cpp_k35");
1442
+ v1 = v1 + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
1443
+ } else {
1444
+ scm2cpp::cu::need_host(gw);
1445
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
1446
+ double dd = (gw[((c*n)+i)]-m1);
1447
+ v1 = (v1+(dd*dd)) ;
1448
+ ;
1449
+ }
1450
+ }
1451
+ } ;
1452
+ double sd = sqrt((v1/double(n)));
1453
+ {
1454
+ long scm2cpp_cnt = (long)(nc) - (long)(0);
1455
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1456
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1457
+ scm2cpp_k36<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(unmix), c, nc, sd, scm2cpp_red);
1458
+ scm2cpp::cu::launched("scm2cpp_k36");
1459
+ scm2cpp::cu::wrote_dev(unmix);
1460
+ } else {
1461
+ scm2cpp::cu::need_host(unmix);
1462
+ for( int j = 0 ; !(j == nc) ; j = (j+1) ) {
1463
+ unmix[ ((c*nc)+j) ] = (unmix[((c*nc)+j)]/sd) ;
1464
+ }
1465
+ scm2cpp::cu::wrote_host(unmix);
1466
+ }
1467
+ } ;
1468
+ ;
1469
+ ;
1470
+ }
1471
+ }
1472
+ } ;
1473
+ { long scm2cpp_cnt = (long)(nc) - (long)(0);
1474
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1475
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1476
+ scm2cpp_k37<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(unmix), scm2cpp::cu::dev(white), scm2cpp::cu::dev(comps), p, nc, scm2cpp_red);
1477
+ scm2cpp::cu::launched("scm2cpp_k37");
1478
+ scm2cpp::cu::wrote_dev(comps);
1479
+ } else {
1480
+ for( int c = 0 ; !(c == nc) ; c = (c+1) ) {
1481
+ {
1482
+ long scm2cpp_cnt = (long)(p) - (long)(0);
1483
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1484
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1485
+ scm2cpp_k38<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(unmix), scm2cpp::cu::dev(white), scm2cpp::cu::dev(comps), nc, c, p, scm2cpp_red);
1486
+ scm2cpp::cu::launched("scm2cpp_k38");
1487
+ scm2cpp::cu::wrote_dev(comps);
1488
+ } else {
1489
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1490
+ double acc = 0.0;
1491
+ {
1492
+ long scm2cpp_cnt = (long)(nc) - (long)(0);
1493
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1494
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1495
+ scm2cpp_k39<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(unmix), scm2cpp::cu::dev(white), c, nc, p, j, scm2cpp_red);
1496
+ scm2cpp::cu::launched("scm2cpp_k39");
1497
+ acc = acc + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
1498
+ } else {
1499
+ scm2cpp::cu::need_host(unmix);
1500
+ scm2cpp::cu::need_host(white);
1501
+ for( int r = 0 ; !(r == nc) ; r = (r+1) ) {
1502
+ acc = (acc+(unmix[((c*nc)+r)]*white[((r*p)+j)])) ;
1503
+ }
1504
+ }
1505
+ } ;
1506
+ scm2cpp::cu::need_host(comps);
1507
+ comps[ ((c*p)+j) ] = acc ;
1508
+ scm2cpp::cu::wrote_host(comps);
1509
+ ;
1510
+ }
1511
+ }
1512
+ } ;
1513
+ }
1514
+ }
1515
+ } ;
1516
+ return it ;
1517
+ }
1518
+ static __global__ void scm2cpp_k40(long scm2cpp_cnt, int scm2cpp_lo, double* weights, double* scm2cpp_red) {
1519
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1520
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1521
+ int c = scm2cpp_lo + (int)scm2cpp_t;
1522
+ { weights[ c ] = 0.0 ;
1523
+ }
1524
+ }
1525
+ static __global__ void scm2cpp_k41(long scm2cpp_cnt, int scm2cpp_lo, double* weights, const double* resp, int i, int kc, double* scm2cpp_red) {
1526
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1527
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1528
+ int c = scm2cpp_lo + (int)scm2cpp_t;
1529
+ { weights[ c ] = (weights[c]+resp[((i*kc)+c)]) ;
1530
+ }
1531
+ }
1532
+ static __global__ void scm2cpp_k42(long scm2cpp_cnt, int scm2cpp_lo, double* weights, double* scm2cpp_red) {
1533
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1534
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1535
+ int c = scm2cpp_lo + (int)scm2cpp_t;
1536
+ double tot = 0.0;
1537
+ { weights[ c ] = (weights[c]+(10.0*2.220446049250313e-16)) ;
1538
+ tot = (tot+weights[c]) ;
1539
+ }
1540
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, tot);
1541
+ }
1542
+ static __global__ void scm2cpp_k43(long scm2cpp_cnt, int scm2cpp_lo, double* means, int c, int p, double nk, double* scm2cpp_red) {
1543
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1544
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1545
+ int j = scm2cpp_lo + (int)scm2cpp_t;
1546
+ { means[ ((c*p)+j) ] = (means[((c*p)+j)]/nk) ;
1547
+ }
1548
+ }
1549
+ static __global__ void scm2cpp_k44(long scm2cpp_cnt, int scm2cpp_lo, const double* resp, const double* x, const double* means, double* u, double* dw, int kc, int c, int p, double* scm2cpp_red) {
1550
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1551
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1552
+ int i = scm2cpp_lo + (int)scm2cpp_t;
1553
+ { double r = resp[((i*kc)+c)];
1554
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1555
+ double dv = (x[((i*p)+j)]-means[((c*p)+j)]);
1556
+ u[ ((i*p)+j) ] = dv ;
1557
+ dw[ ((i*p)+j) ] = (r*dv) ;
1558
+ ;
1559
+ } ;
1560
+ ;
1561
+ }
1562
+ }
1563
+ static __global__ void scm2cpp_k45(long scm2cpp_cnt, int scm2cpp_lo, const double* x, const double* means, double* u, double* dw, int i, int p, int c, double r, double* scm2cpp_red) {
1564
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1565
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1566
+ int j = scm2cpp_lo + (int)scm2cpp_t;
1567
+ { double dv = (x[((i*p)+j)]-means[((c*p)+j)]);
1568
+ u[ ((i*p)+j) ] = dv ;
1569
+ dw[ ((i*p)+j) ] = (r*dv) ;
1570
+ ;
1571
+ }
1572
+ }
1573
+ static __global__ void scm2cpp_k46(long scm2cpp_cnt, int scm2cpp_lo, double* cov, double nk, double* scm2cpp_red) {
1574
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1575
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1576
+ int t = scm2cpp_lo + (int)scm2cpp_t;
1577
+ { cov[ t ] = (cov[t]/nk) ;
1578
+ }
1579
+ }
1580
+ static __global__ void scm2cpp_k47(long scm2cpp_cnt, int scm2cpp_lo, double* prec, int c, int p, double* scm2cpp_red) {
1581
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1582
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1583
+ int t = scm2cpp_lo + (int)scm2cpp_t;
1584
+ { prec[ ((c*(p*p))+t) ] = 0.0 ;
1585
+ }
1586
+ }
1587
+ static __global__ void scm2cpp_k48(long scm2cpp_cnt, int scm2cpp_lo, double* weights, int norm, int n, double tot, double* scm2cpp_red) {
1588
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1589
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1590
+ int c = scm2cpp_lo + (int)scm2cpp_t;
1591
+ { weights[ c ] = (weights[c]/( ( norm == 1 ) ? (double(n)) : (tot) )) ;
1592
+ }
1593
+ }
1594
+
1595
+
1596
+ inline int
1597
+ gmm_mstep( scm2cpp::cspan<double> x, scm2cpp::cspan<double> resp, scm2cpp::span<double> weights, scm2cpp::span<double> means, scm2cpp::span<double> prec, scm2cpp::span<double> dw, scm2cpp::span<double> cov, scm2cpp::span<double> l, scm2cpp::span<double> u, double reg, int norm, int n, int p, int kc )
1598
+ { double tot = 0.0;
1599
+ { long scm2cpp_cnt = (long)(kc) - (long)(0);
1600
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1601
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1602
+ scm2cpp_k40<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(weights), scm2cpp_red);
1603
+ scm2cpp::cu::launched("scm2cpp_k40");
1604
+ scm2cpp::cu::wrote_dev(weights);
1605
+ } else {
1606
+ scm2cpp::cu::need_host(weights);
1607
+ for( int c = 0 ; !(c == kc) ; c = (c+1) ) {
1608
+ weights[ c ] = 0.0 ;
1609
+ }
1610
+ scm2cpp::cu::wrote_host(weights);
1611
+ }
1612
+ } ;
1613
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
1614
+ {
1615
+ long scm2cpp_cnt = (long)(kc) - (long)(0);
1616
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1617
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1618
+ scm2cpp_k41<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(weights), scm2cpp::cu::dev(resp), i, kc, scm2cpp_red);
1619
+ scm2cpp::cu::launched("scm2cpp_k41");
1620
+ scm2cpp::cu::wrote_dev(weights);
1621
+ } else {
1622
+ scm2cpp::cu::need_host(weights);
1623
+ scm2cpp::cu::need_host(resp);
1624
+ for( int c = 0 ; !(c == kc) ; c = (c+1) ) {
1625
+ weights[ c ] = (weights[c]+resp[((i*kc)+c)]) ;
1626
+ }
1627
+ scm2cpp::cu::wrote_host(weights);
1628
+ }
1629
+ } ;
1630
+ } ;
1631
+ { long scm2cpp_cnt = (long)(kc) - (long)(0);
1632
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1633
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1634
+ scm2cpp_k42<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(weights), scm2cpp_red);
1635
+ scm2cpp::cu::launched("scm2cpp_k42");
1636
+ scm2cpp::cu::wrote_dev(weights);
1637
+ tot = tot + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
1638
+ } else {
1639
+ scm2cpp::cu::need_host(weights);
1640
+ for( int c = 0 ; !(c == kc) ; c = (c+1) ) {
1641
+ weights[ c ] = (weights[c]+(10.0*2.220446049250313e-16)) ;
1642
+ tot = (tot+weights[c]) ;
1643
+ }
1644
+ scm2cpp::cu::wrote_host(weights);
1645
+ }
1646
+ } ;
1647
+ scm2cpp::cu::blas_gemm(means, resp, x, 1.0, 0.0, 1, 0, kc, p, n) ;
1648
+ for( int c = 0 ; !(c == kc) ; c = (c+1) ) {
1649
+ scm2cpp::cu::need_host(weights);
1650
+ double nk = weights[c];
1651
+ {
1652
+ long scm2cpp_cnt = (long)(p) - (long)(0);
1653
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1654
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1655
+ scm2cpp_k43<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(means), c, p, nk, scm2cpp_red);
1656
+ scm2cpp::cu::launched("scm2cpp_k43");
1657
+ scm2cpp::cu::wrote_dev(means);
1658
+ } else {
1659
+ scm2cpp::cu::need_host(means);
1660
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1661
+ means[ ((c*p)+j) ] = (means[((c*p)+j)]/nk) ;
1662
+ }
1663
+ scm2cpp::cu::wrote_host(means);
1664
+ }
1665
+ } ;
1666
+ { long scm2cpp_cnt = (long)(n) - (long)(0);
1667
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1668
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1669
+ scm2cpp_k44<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(resp), scm2cpp::cu::dev(x), scm2cpp::cu::dev(means), scm2cpp::cu::dev(u), scm2cpp::cu::dev(dw), kc, c, p, scm2cpp_red);
1670
+ scm2cpp::cu::launched("scm2cpp_k44");
1671
+ scm2cpp::cu::wrote_dev(u);
1672
+ scm2cpp::cu::wrote_dev(dw);
1673
+ } else {
1674
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
1675
+ scm2cpp::cu::need_host(resp);
1676
+ double r = resp[((i*kc)+c)];
1677
+ {
1678
+ long scm2cpp_cnt = (long)(p) - (long)(0);
1679
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1680
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1681
+ scm2cpp_k45<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(x), scm2cpp::cu::dev(means), scm2cpp::cu::dev(u), scm2cpp::cu::dev(dw), i, p, c, r, scm2cpp_red);
1682
+ scm2cpp::cu::launched("scm2cpp_k45");
1683
+ scm2cpp::cu::wrote_dev(u);
1684
+ scm2cpp::cu::wrote_dev(dw);
1685
+ } else {
1686
+ scm2cpp::cu::need_host(x);
1687
+ scm2cpp::cu::need_host(means);
1688
+ scm2cpp::cu::need_host(u);
1689
+ scm2cpp::cu::need_host(dw);
1690
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1691
+ double dv = (x[((i*p)+j)]-means[((c*p)+j)]);
1692
+ u[ ((i*p)+j) ] = dv ;
1693
+ dw[ ((i*p)+j) ] = (r*dv) ;
1694
+ ;
1695
+ }
1696
+ scm2cpp::cu::wrote_host(u);
1697
+ scm2cpp::cu::wrote_host(dw);
1698
+ }
1699
+ } ;
1700
+ ;
1701
+ }
1702
+ }
1703
+ } ;
1704
+ scm2cpp::cu::blas_gemm(cov, dw, u, 1.0, 0.0, 1, 0, p, p, n) ;
1705
+ { long scm2cpp_cnt = (long)((p*p)) - (long)(0);
1706
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1707
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1708
+ scm2cpp_k46<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(cov), nk, scm2cpp_red);
1709
+ scm2cpp::cu::launched("scm2cpp_k46");
1710
+ scm2cpp::cu::wrote_dev(cov);
1711
+ } else {
1712
+ scm2cpp::cu::need_host(cov);
1713
+ for( int t = 0 ; !(t == (p*p)) ; t = (t+1) ) {
1714
+ cov[ t ] = (cov[t]/nk) ;
1715
+ }
1716
+ scm2cpp::cu::wrote_host(cov);
1717
+ }
1718
+ } ;
1719
+ scm2cpp::cu::need_host(cov);
1720
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1721
+ cov[ ((j*p)+j) ] = (cov[((j*p)+j)]+reg) ;
1722
+ } ;
1723
+ scm2cpp::cu::wrote_host(cov);
1724
+ scm2cpp::cu::need_host(cov);
1725
+ scm2cpp::cu::need_host(l);
1726
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1727
+ double s = cov[((j*p)+j)];
1728
+ for( int m = 0 ; !(m == j) ; m = (m+1) ) {
1729
+ s = (s-(l[((j*p)+m)]*l[((j*p)+m)])) ;
1730
+ } ;
1731
+ l[ ((j*p)+j) ] = sqrt(s) ;
1732
+ for( int i = (j+1) ; !(i >= p) ; i = (i+1) ) {
1733
+ double t2 = cov[((i*p)+j)];
1734
+ for( int m = 0 ; !(m == j) ; m = (m+1) ) {
1735
+ t2 = (t2-(l[((i*p)+m)]*l[((j*p)+m)])) ;
1736
+ } ;
1737
+ l[ ((i*p)+j) ] = (t2/l[((j*p)+j)]) ;
1738
+ ;
1739
+ } ;
1740
+ ;
1741
+ } ;
1742
+ scm2cpp::cu::wrote_host(l);
1743
+ { long scm2cpp_cnt = (long)((p*p)) - (long)(0);
1744
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1745
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1746
+ scm2cpp_k47<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(prec), c, p, scm2cpp_red);
1747
+ scm2cpp::cu::launched("scm2cpp_k47");
1748
+ scm2cpp::cu::wrote_dev(prec);
1749
+ } else {
1750
+ scm2cpp::cu::need_host(prec);
1751
+ for( int t = 0 ; !(t == (p*p)) ; t = (t+1) ) {
1752
+ prec[ ((c*(p*p))+t) ] = 0.0 ;
1753
+ }
1754
+ scm2cpp::cu::wrote_host(prec);
1755
+ }
1756
+ } ;
1757
+ scm2cpp::cu::need_host(l);
1758
+ scm2cpp::cu::need_host(prec);
1759
+ for( int e = 0 ; !(e == p) ; e = (e+1) ) {
1760
+ for( int i = e ; !(i == p) ; i = (i+1) ) {
1761
+ double t3 = ( ( i == e ) ? (1.0) : (0.0) );
1762
+ for( int m = e ; !(m == i) ; m = (m+1) ) {
1763
+ t3 = (t3-(l[((i*p)+m)]*prec[((c*(p*p))+((e*p)+m))])) ;
1764
+ } ;
1765
+ prec[ ((c*(p*p))+((e*p)+i)) ] = (t3/l[((i*p)+i)]) ;
1766
+ ;
1767
+ } ;
1768
+ } ;
1769
+ scm2cpp::cu::wrote_host(prec);
1770
+ ;
1771
+ } ;
1772
+ { long scm2cpp_cnt = (long)(kc) - (long)(0);
1773
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1774
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1775
+ scm2cpp_k48<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(weights), norm, n, tot, scm2cpp_red);
1776
+ scm2cpp::cu::launched("scm2cpp_k48");
1777
+ scm2cpp::cu::wrote_dev(weights);
1778
+ } else {
1779
+ scm2cpp::cu::need_host(weights);
1780
+ for( int c = 0 ; !(c == kc) ; c = (c+1) ) {
1781
+ weights[ c ] = (weights[c]/( ( norm == 1 ) ? (double(n)) : (tot) )) ;
1782
+ }
1783
+ scm2cpp::cu::wrote_host(weights);
1784
+ }
1785
+ } ;
1786
+ return 0 ;
1787
+ }
1788
+ static __global__ void scm2cpp_k49(long scm2cpp_cnt, int scm2cpp_lo, double* u, const double* prec, int c, int p, double* scm2cpp_red) {
1789
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1790
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1791
+ int t = scm2cpp_lo + (int)scm2cpp_t;
1792
+ { u[ t ] = prec[((c*(p*p))+t)] ;
1793
+ }
1794
+ }
1795
+ static __global__ void scm2cpp_k50(long scm2cpp_cnt, int scm2cpp_lo, const double* u, const double* means, double* mu, int p, int c, double* scm2cpp_red) {
1796
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1797
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1798
+ int j = scm2cpp_lo + (int)scm2cpp_t;
1799
+ double logdet = 0.0;
1800
+ { logdet = (logdet+log(u[((j*p)+j)])) ;
1801
+ double acc = 0.0;
1802
+ for( int m = 0 ; !(m == p) ; m = (m+1) ) {
1803
+ acc = (acc+(means[((c*p)+m)]*u[((m*p)+j)])) ;
1804
+ } ;
1805
+ mu[ j ] = acc ;
1806
+ ;
1807
+ }
1808
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, logdet);
1809
+ }
1810
+ static __global__ void scm2cpp_k51(long scm2cpp_cnt, int scm2cpp_lo, const double* means, const double* u, int c, int p, int j, double* scm2cpp_red) {
1811
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1812
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1813
+ int m = scm2cpp_lo + (int)scm2cpp_t;
1814
+ double acc = 0.0;
1815
+ { acc = (acc+(means[((c*p)+m)]*u[((m*p)+j)])) ;
1816
+ }
1817
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, acc);
1818
+ }
1819
+ static __global__ void scm2cpp_k52(long scm2cpp_cnt, int scm2cpp_lo, const double* y, const double* mu, int i, int p, double* scm2cpp_red) {
1820
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1821
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1822
+ int j = scm2cpp_lo + (int)scm2cpp_t;
1823
+ double sq = 0.0;
1824
+ { double v = (y[((i*p)+j)]-mu[j]);
1825
+ sq = (sq+(v*v)) ;
1826
+ ;
1827
+ }
1828
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, sq);
1829
+ }
1830
+ static __global__ void scm2cpp_k53(long scm2cpp_cnt, int scm2cpp_lo, const double* wlp, double* resp, int kc, double* scm2cpp_red) {
1831
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1832
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1833
+ int i = scm2cpp_lo + (int)scm2cpp_t;
1834
+ double lb = 0.0;
1835
+ { double amax = wlp[(i*kc)];
1836
+ double se = 0.0;
1837
+ for( int c = 1 ; !(c == kc) ; c = (c+1) ) {
1838
+ if( wlp[((i*kc)+c)] > amax ) {
1839
+ amax = wlp[((i*kc)+c)] ;
1840
+ } else {
1841
+ 0 ;
1842
+ } ;
1843
+ } ;
1844
+ for( int c = 0 ; !(c == kc) ; c = (c+1) ) {
1845
+ se = (se+exp((wlp[((i*kc)+c)]-amax))) ;
1846
+ } ;
1847
+ double lse = (log(se)+amax);
1848
+ lb = (lb+lse) ;
1849
+ for( int c = 0 ; !(c == kc) ; c = (c+1) ) {
1850
+ resp[ ((i*kc)+c) ] = exp((wlp[((i*kc)+c)]-lse)) ;
1851
+ } ;
1852
+ ;
1853
+ ;
1854
+ }
1855
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, lb);
1856
+ }
1857
+ static __global__ void scm2cpp_k54(long scm2cpp_cnt, int scm2cpp_lo, const double* wlp, int i, int kc, double amax, double* scm2cpp_red) {
1858
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1859
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1860
+ int c = scm2cpp_lo + (int)scm2cpp_t;
1861
+ double se = 0.0;
1862
+ { se = (se+exp((wlp[((i*kc)+c)]-amax))) ;
1863
+ }
1864
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, se);
1865
+ }
1866
+ static __global__ void scm2cpp_k55(long scm2cpp_cnt, int scm2cpp_lo, double* resp, const double* wlp, int i, int kc, double lse, double* scm2cpp_red) {
1867
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
1868
+ if (scm2cpp_t >= scm2cpp_cnt) return;
1869
+ int c = scm2cpp_lo + (int)scm2cpp_t;
1870
+ { resp[ ((i*kc)+c) ] = exp((wlp[((i*kc)+c)]-lse)) ;
1871
+ }
1872
+ }
1873
+
1874
+
1875
+ inline double
1876
+ gmm_estep( scm2cpp::cspan<double> x, scm2cpp::span<double> resp, scm2cpp::cspan<double> weights, scm2cpp::cspan<double> means, scm2cpp::cspan<double> prec, scm2cpp::span<double> wlp, scm2cpp::span<double> y, scm2cpp::span<double> u, scm2cpp::span<double> mu, int n, int p, int kc )
1877
+ { for( int c = 0 ; !(c == kc) ; c = (c+1) ) {
1878
+ scm2cpp::cu::need_host(weights);
1879
+ double logdet = 0.0;
1880
+ double lw = log(weights[c]);
1881
+ {
1882
+ long scm2cpp_cnt = (long)((p*p)) - (long)(0);
1883
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1884
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1885
+ scm2cpp_k49<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(u), scm2cpp::cu::dev(prec), c, p, scm2cpp_red);
1886
+ scm2cpp::cu::launched("scm2cpp_k49");
1887
+ scm2cpp::cu::wrote_dev(u);
1888
+ } else {
1889
+ scm2cpp::cu::need_host(u);
1890
+ scm2cpp::cu::need_host(prec);
1891
+ for( int t = 0 ; !(t == (p*p)) ; t = (t+1) ) {
1892
+ u[ t ] = prec[((c*(p*p))+t)] ;
1893
+ }
1894
+ scm2cpp::cu::wrote_host(u);
1895
+ }
1896
+ } ;
1897
+ { long scm2cpp_cnt = (long)(p) - (long)(0);
1898
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1899
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1900
+ scm2cpp_k50<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(u), scm2cpp::cu::dev(means), scm2cpp::cu::dev(mu), p, c, scm2cpp_red);
1901
+ scm2cpp::cu::launched("scm2cpp_k50");
1902
+ scm2cpp::cu::wrote_dev(mu);
1903
+ logdet = logdet + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
1904
+ } else {
1905
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1906
+ scm2cpp::cu::need_host(u);
1907
+ logdet = (logdet+log(u[((j*p)+j)])) ;
1908
+ double acc = 0.0;
1909
+ {
1910
+ long scm2cpp_cnt = (long)(p) - (long)(0);
1911
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1912
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1913
+ scm2cpp_k51<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(means), scm2cpp::cu::dev(u), c, p, j, scm2cpp_red);
1914
+ scm2cpp::cu::launched("scm2cpp_k51");
1915
+ acc = acc + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
1916
+ } else {
1917
+ scm2cpp::cu::need_host(means);
1918
+ scm2cpp::cu::need_host(u);
1919
+ for( int m = 0 ; !(m == p) ; m = (m+1) ) {
1920
+ acc = (acc+(means[((c*p)+m)]*u[((m*p)+j)])) ;
1921
+ }
1922
+ }
1923
+ } ;
1924
+ scm2cpp::cu::need_host(mu);
1925
+ mu[ j ] = acc ;
1926
+ scm2cpp::cu::wrote_host(mu);
1927
+ ;
1928
+ }
1929
+ }
1930
+ } ;
1931
+ scm2cpp::cu::blas_gemm(y, x, u, 1.0, 0.0, 0, 0, n, p, p) ;
1932
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
1933
+ double sq = 0.0;
1934
+ {
1935
+ long scm2cpp_cnt = (long)(p) - (long)(0);
1936
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1937
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1938
+ scm2cpp_k52<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(y), scm2cpp::cu::dev(mu), i, p, scm2cpp_red);
1939
+ scm2cpp::cu::launched("scm2cpp_k52");
1940
+ sq = sq + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
1941
+ } else {
1942
+ scm2cpp::cu::need_host(y);
1943
+ scm2cpp::cu::need_host(mu);
1944
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
1945
+ double v = (y[((i*p)+j)]-mu[j]);
1946
+ sq = (sq+(v*v)) ;
1947
+ ;
1948
+ }
1949
+ }
1950
+ } ;
1951
+ scm2cpp::cu::need_host(wlp);
1952
+ wlp[ ((i*kc)+c) ] = (((-0.5*((double(p)*1.8378770664093453)+sq))+logdet)+lw) ;
1953
+ scm2cpp::cu::wrote_host(wlp);
1954
+ ;
1955
+ } ;
1956
+ ;
1957
+ } ;
1958
+ double lb = 0.0;
1959
+ {
1960
+ long scm2cpp_cnt = (long)(n) - (long)(0);
1961
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1962
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1963
+ scm2cpp_k53<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(wlp), scm2cpp::cu::dev(resp), kc, scm2cpp_red);
1964
+ scm2cpp::cu::launched("scm2cpp_k53");
1965
+ scm2cpp::cu::wrote_dev(resp);
1966
+ lb = lb + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
1967
+ } else {
1968
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
1969
+ scm2cpp::cu::need_host(wlp);
1970
+ double amax = wlp[(i*kc)];
1971
+ double se = 0.0;
1972
+ scm2cpp::cu::need_host(wlp);
1973
+ for( int c = 1 ; !(c == kc) ; c = (c+1) ) {
1974
+ if( wlp[((i*kc)+c)] > amax ) {
1975
+ amax = wlp[((i*kc)+c)] ;
1976
+ } else {
1977
+ 0 ;
1978
+ } ;
1979
+ } ;
1980
+ { long scm2cpp_cnt = (long)(kc) - (long)(0);
1981
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1982
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1983
+ scm2cpp_k54<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(wlp), i, kc, amax, scm2cpp_red);
1984
+ scm2cpp::cu::launched("scm2cpp_k54");
1985
+ se = se + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
1986
+ } else {
1987
+ scm2cpp::cu::need_host(wlp);
1988
+ for( int c = 0 ; !(c == kc) ; c = (c+1) ) {
1989
+ se = (se+exp((wlp[((i*kc)+c)]-amax))) ;
1990
+ }
1991
+ }
1992
+ } ;
1993
+ double lse = (log(se)+amax);
1994
+ lb = (lb+lse) ;
1995
+ { long scm2cpp_cnt = (long)(kc) - (long)(0);
1996
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
1997
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
1998
+ scm2cpp_k55<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(resp), scm2cpp::cu::dev(wlp), i, kc, lse, scm2cpp_red);
1999
+ scm2cpp::cu::launched("scm2cpp_k55");
2000
+ scm2cpp::cu::wrote_dev(resp);
2001
+ } else {
2002
+ scm2cpp::cu::need_host(resp);
2003
+ scm2cpp::cu::need_host(wlp);
2004
+ for( int c = 0 ; !(c == kc) ; c = (c+1) ) {
2005
+ resp[ ((i*kc)+c) ] = exp((wlp[((i*kc)+c)]-lse)) ;
2006
+ }
2007
+ scm2cpp::cu::wrote_host(resp);
2008
+ }
2009
+ } ;
2010
+ ;
2011
+ ;
2012
+ }
2013
+ }
2014
+ } ;
2015
+ return (lb/double(n)) ;
2016
+ }
2017
+
2018
+
2019
+ SCM2CPP_FN inline double
2020
+ gmm_abs( double a )
2021
+ {
2022
+ if( a < 0.0 ) {
2023
+ return (0.0-a) ;
2024
+ }
2025
+ else {
2026
+ return a ;
2027
+ }
2028
+ }
2029
+ static __global__ void scm2cpp_k56(long scm2cpp_cnt, int scm2cpp_lo, const double* resp, double* labels, int kc, double* scm2cpp_red) {
2030
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
2031
+ if (scm2cpp_t >= scm2cpp_cnt) return;
2032
+ int i = scm2cpp_lo + (int)scm2cpp_t;
2033
+ { int best = 0;
2034
+ double bv = resp[(i*kc)];
2035
+ for( int c = 1 ; !(c == kc) ; c = (c+1) ) {
2036
+ if( resp[((i*kc)+c)] > bv ) {
2037
+ bv = resp[((i*kc)+c)] ;
2038
+ best = c ;
2039
+ } else {
2040
+ 0 ;
2041
+ } ;
2042
+ } ;
2043
+ labels[ i ] = double(best) ;
2044
+ ;
2045
+ }
2046
+ }
2047
+
2048
+
2049
+ inline int
2050
+ gmm( scm2cpp::cspan<double> x, scm2cpp::span<double> resp, scm2cpp::span<double> weights, scm2cpp::span<double> means, scm2cpp::span<double> prec, scm2cpp::span<double> labels, scm2cpp::span<double> out, int maxiter, double tol, double reg, int n, int p, int kc )
2051
+ { std::vector<double> dw((n*p),0.0);
2052
+ scm2cpp::cu::fresh(dw);
2053
+ std::vector<double> y((n*p),0.0);
2054
+ scm2cpp::cu::fresh(y);
2055
+ std::vector<double> wlp((n*kc),0.0);
2056
+ scm2cpp::cu::fresh(wlp);
2057
+ std::vector<double> cov((p*p),0.0);
2058
+ scm2cpp::cu::fresh(cov);
2059
+ std::vector<double> l((p*p),0.0);
2060
+ scm2cpp::cu::fresh(l);
2061
+ std::vector<double> u((p*p),0.0);
2062
+ scm2cpp::cu::fresh(u);
2063
+ std::vector<double> mu(p,0.0);
2064
+ scm2cpp::cu::fresh(mu);
2065
+ double lb = -1e+300;
2066
+ int it = 0;
2067
+ int conv = 0;
2068
+ int done = 0;
2069
+ gmm_mstep(x,resp,weights,means,prec,dw,cov,l,y,reg,1,n,p,kc) ;
2070
+ for( ; !((done == 1 || it >= maxiter)) ; ) {
2071
+ double prev = lb;
2072
+ lb = gmm_estep(x,resp,weights,means,prec,wlp,y,u,mu,n,p,kc) ;
2073
+ gmm_mstep(x,resp,weights,means,prec,dw,cov,l,y,reg,0,n,p,kc) ;
2074
+ it = (it+1) ;
2075
+ if( (it > 1 && gmm_abs(double((lb-prev))) < tol) ) {
2076
+ conv = 1 ;
2077
+ done = 1 ;
2078
+ } else {
2079
+ 0 ;
2080
+ } ;
2081
+ ;
2082
+ } ;
2083
+ gmm_estep(x,resp,weights,means,prec,wlp,y,u,mu,n,p,kc) ;
2084
+ { long scm2cpp_cnt = (long)(n) - (long)(0);
2085
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
2086
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
2087
+ scm2cpp_k56<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(resp), scm2cpp::cu::dev(labels), kc, scm2cpp_red);
2088
+ scm2cpp::cu::launched("scm2cpp_k56");
2089
+ scm2cpp::cu::wrote_dev(labels);
2090
+ } else {
2091
+ scm2cpp::cu::need_host(resp);
2092
+ scm2cpp::cu::need_host(labels);
2093
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2094
+ int best = 0;
2095
+ double bv = resp[(i*kc)];
2096
+ for( int c = 1 ; !(c == kc) ; c = (c+1) ) {
2097
+ if( resp[((i*kc)+c)] > bv ) {
2098
+ bv = resp[((i*kc)+c)] ;
2099
+ best = c ;
2100
+ } else {
2101
+ 0 ;
2102
+ } ;
2103
+ } ;
2104
+ labels[ i ] = double(best) ;
2105
+ ;
2106
+ }
2107
+ scm2cpp::cu::wrote_host(labels);
2108
+ }
2109
+ } ;
2110
+ scm2cpp::cu::need_host(out);
2111
+ out[ 0 ] = lb ;
2112
+ scm2cpp::cu::wrote_host(out);
2113
+ scm2cpp::cu::need_host(out);
2114
+ out[ 1 ] = double(conv) ;
2115
+ scm2cpp::cu::wrote_host(out);
2116
+ return it ;
2117
+ }
2118
+ static __global__ void scm2cpp_k57(long scm2cpp_cnt, int scm2cpp_lo, double* z, const double* coef, int k, int p, double* scm2cpp_red) {
2119
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
2120
+ if (scm2cpp_t >= scm2cpp_cnt) return;
2121
+ int i = scm2cpp_lo + (int)scm2cpp_t;
2122
+ { for( int c = 0 ; !(c == k) ; c = (c+1) ) {
2123
+ z[ ((i*k)+c) ] = (z[((i*k)+c)]+coef[((k*p)+c)]) ;
2124
+ } ;
2125
+ }
2126
+ }
2127
+ static __global__ void scm2cpp_k58(long scm2cpp_cnt, int scm2cpp_lo, double* z, const double* coef, int i, int k, int p, double* scm2cpp_red) {
2128
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
2129
+ if (scm2cpp_t >= scm2cpp_cnt) return;
2130
+ int c = scm2cpp_lo + (int)scm2cpp_t;
2131
+ { z[ ((i*k)+c) ] = (z[((i*k)+c)]+coef[((k*p)+c)]) ;
2132
+ }
2133
+ }
2134
+ static __global__ void scm2cpp_k59(long scm2cpp_cnt, int scm2cpp_lo, double* z, const double* y, double* scm2cpp_red) {
2135
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
2136
+ if (scm2cpp_t >= scm2cpp_cnt) return;
2137
+ int i = scm2cpp_lo + (int)scm2cpp_t;
2138
+ double loss = 0.0;
2139
+ { double zi = z[i];
2140
+ double yi = y[i];
2141
+ if( zi <= -2.0 ) {
2142
+ double e1 = exp(zi);
2143
+ if( zi <= -37.0 ) {
2144
+ loss = (loss+(e1-(yi*zi))) ;
2145
+ z[ i ] = (e1-yi) ;
2146
+ } else {
2147
+ loss = (loss+(log((1.0+e1))-(yi*zi))) ;
2148
+ z[ i ] = ((((1.0-yi)*e1)-yi)/(1.0+e1)) ;
2149
+ } ;
2150
+ ;
2151
+ } else {
2152
+ double e2 = exp((0.0-zi));
2153
+ loss = (loss+(( ( zi <= 18.0 ) ? (log((1.0+e2))) : (e2) )+((1.0-yi)*zi))) ;
2154
+ z[ i ] = (((1.0-yi)-(yi*e2))/(1.0+e2)) ;
2155
+ ;
2156
+ } ;
2157
+ ;
2158
+ }
2159
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, loss);
2160
+ }
2161
+ static __global__ void scm2cpp_k60(long scm2cpp_cnt, int scm2cpp_lo, double* z, int i, int k, double zmax, double* scm2cpp_red) {
2162
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
2163
+ if (scm2cpp_t >= scm2cpp_cnt) return;
2164
+ int c = scm2cpp_lo + (int)scm2cpp_t;
2165
+ double se = 0.0;
2166
+ { double ec = exp((z[((i*k)+c)]-zmax));
2167
+ z[ ((i*k)+c) ] = ec ;
2168
+ se = (se+ec) ;
2169
+ ;
2170
+ }
2171
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, se);
2172
+ }
2173
+ static __global__ void scm2cpp_k61(long scm2cpp_cnt, int scm2cpp_lo, double* z, int i, int k, double se, double* scm2cpp_red) {
2174
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
2175
+ if (scm2cpp_t >= scm2cpp_cnt) return;
2176
+ int c = scm2cpp_lo + (int)scm2cpp_t;
2177
+ { z[ ((i*k)+c) ] = (z[((i*k)+c)]/se) ;
2178
+ }
2179
+ }
2180
+ static __global__ void scm2cpp_k62(long scm2cpp_cnt, int scm2cpp_lo, const double* coef, double* g, int n, double l2, double* scm2cpp_red) {
2181
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
2182
+ if (scm2cpp_t >= scm2cpp_cnt) return;
2183
+ int t = scm2cpp_lo + (int)scm2cpp_t;
2184
+ double pen = 0.0;
2185
+ { double wt = coef[t];
2186
+ pen = (pen+(wt*wt)) ;
2187
+ g[ t ] = ((g[t]/double(n))+(l2*wt)) ;
2188
+ ;
2189
+ }
2190
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, pen);
2191
+ }
2192
+ static __global__ void scm2cpp_k63(long scm2cpp_cnt, int scm2cpp_lo, const double* z, double* g, int fitint, int n, int k, int p, double* scm2cpp_red) {
2193
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
2194
+ if (scm2cpp_t >= scm2cpp_cnt) return;
2195
+ int c = scm2cpp_lo + (int)scm2cpp_t;
2196
+ { double acc = 0.0;
2197
+ if( fitint == 1 ) {
2198
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2199
+ acc = (acc+z[((i*k)+c)]) ;
2200
+ } ;
2201
+ } else {
2202
+ 0 ;
2203
+ } ;
2204
+ g[ ((k*p)+c) ] = (acc/double(n)) ;
2205
+ ;
2206
+ }
2207
+ }
2208
+ static __global__ void scm2cpp_k64(long scm2cpp_cnt, int scm2cpp_lo, const double* z, int k, int c, double* scm2cpp_red) {
2209
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
2210
+ if (scm2cpp_t >= scm2cpp_cnt) return;
2211
+ int i = scm2cpp_lo + (int)scm2cpp_t;
2212
+ double acc = 0.0;
2213
+ { acc = (acc+z[((i*k)+c)]) ;
2214
+ }
2215
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, acc);
2216
+ }
2217
+
2218
+
2219
+ inline double
2220
+ logistic_fg( scm2cpp::cspan<double> coef, scm2cpp::span<double> g, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> z, double l2, int multi, int fitint, int n, int p, int k )
2221
+ { double loss = 0.0;
2222
+ double pen = 0.0;
2223
+ scm2cpp::cu::blas_gemm(z, x, coef, 1.0, 0.0, 0, 1, n, k, p) ;
2224
+ { long scm2cpp_cnt = (long)(n) - (long)(0);
2225
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
2226
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
2227
+ scm2cpp_k57<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(z), scm2cpp::cu::dev(coef), k, p, scm2cpp_red);
2228
+ scm2cpp::cu::launched("scm2cpp_k57");
2229
+ scm2cpp::cu::wrote_dev(z);
2230
+ } else {
2231
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2232
+ {
2233
+ long scm2cpp_cnt = (long)(k) - (long)(0);
2234
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
2235
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
2236
+ scm2cpp_k58<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(z), scm2cpp::cu::dev(coef), i, k, p, scm2cpp_red);
2237
+ scm2cpp::cu::launched("scm2cpp_k58");
2238
+ scm2cpp::cu::wrote_dev(z);
2239
+ } else {
2240
+ scm2cpp::cu::need_host(z);
2241
+ scm2cpp::cu::need_host(coef);
2242
+ for( int c = 0 ; !(c == k) ; c = (c+1) ) {
2243
+ z[ ((i*k)+c) ] = (z[((i*k)+c)]+coef[((k*p)+c)]) ;
2244
+ }
2245
+ scm2cpp::cu::wrote_host(z);
2246
+ }
2247
+ } ;
2248
+ }
2249
+ }
2250
+ } ;
2251
+ if( multi == 0 ) {
2252
+ {
2253
+ long scm2cpp_cnt = (long)(n) - (long)(0);
2254
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
2255
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
2256
+ scm2cpp_k59<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(z), scm2cpp::cu::dev(y), scm2cpp_red);
2257
+ scm2cpp::cu::launched("scm2cpp_k59");
2258
+ scm2cpp::cu::wrote_dev(z);
2259
+ loss = loss + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
2260
+ } else {
2261
+ scm2cpp::cu::need_host(z);
2262
+ scm2cpp::cu::need_host(y);
2263
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2264
+ double zi = z[i];
2265
+ double yi = y[i];
2266
+ if( zi <= -2.0 ) {
2267
+ double e1 = exp(zi);
2268
+ if( zi <= -37.0 ) {
2269
+ loss = (loss+(e1-(yi*zi))) ;
2270
+ z[ i ] = (e1-yi) ;
2271
+ } else {
2272
+ loss = (loss+(log((1.0+e1))-(yi*zi))) ;
2273
+ z[ i ] = ((((1.0-yi)*e1)-yi)/(1.0+e1)) ;
2274
+ } ;
2275
+ ;
2276
+ } else {
2277
+ double e2 = exp((0.0-zi));
2278
+ loss = (loss+(( ( zi <= 18.0 ) ? (log((1.0+e2))) : (e2) )+((1.0-yi)*zi))) ;
2279
+ z[ i ] = (((1.0-yi)-(yi*e2))/(1.0+e2)) ;
2280
+ ;
2281
+ } ;
2282
+ ;
2283
+ }
2284
+ scm2cpp::cu::wrote_host(z);
2285
+ }
2286
+ } ;
2287
+ } else {
2288
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2289
+ scm2cpp::cu::need_host(z);
2290
+ scm2cpp::cu::need_host(y);
2291
+ double zmax = z[(i*k)];
2292
+ double se = 0.0;
2293
+ double yc = y[i];
2294
+ scm2cpp::cu::need_host(z);
2295
+ for( int c = 1 ; !(c == k) ; c = (c+1) ) {
2296
+ if( z[((i*k)+c)] > zmax ) {
2297
+ zmax = z[((i*k)+c)] ;
2298
+ } else {
2299
+ 0 ;
2300
+ } ;
2301
+ } ;
2302
+ scm2cpp::cu::need_host(z);
2303
+ loss = (loss-z[((i*k)+int(yc))]) ;
2304
+ { long scm2cpp_cnt = (long)(k) - (long)(0);
2305
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
2306
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
2307
+ scm2cpp_k60<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(z), i, k, zmax, scm2cpp_red);
2308
+ scm2cpp::cu::launched("scm2cpp_k60");
2309
+ scm2cpp::cu::wrote_dev(z);
2310
+ se = se + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
2311
+ } else {
2312
+ scm2cpp::cu::need_host(z);
2313
+ for( int c = 0 ; !(c == k) ; c = (c+1) ) {
2314
+ double ec = exp((z[((i*k)+c)]-zmax));
2315
+ z[ ((i*k)+c) ] = ec ;
2316
+ se = (se+ec) ;
2317
+ ;
2318
+ }
2319
+ scm2cpp::cu::wrote_host(z);
2320
+ }
2321
+ } ;
2322
+ loss = (loss+(zmax+log(se))) ;
2323
+ { long scm2cpp_cnt = (long)(k) - (long)(0);
2324
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
2325
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
2326
+ scm2cpp_k61<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(z), i, k, se, scm2cpp_red);
2327
+ scm2cpp::cu::launched("scm2cpp_k61");
2328
+ scm2cpp::cu::wrote_dev(z);
2329
+ } else {
2330
+ scm2cpp::cu::need_host(z);
2331
+ for( int c = 0 ; !(c == k) ; c = (c+1) ) {
2332
+ z[ ((i*k)+c) ] = (z[((i*k)+c)]/se) ;
2333
+ }
2334
+ scm2cpp::cu::wrote_host(z);
2335
+ }
2336
+ } ;
2337
+ scm2cpp::cu::need_host(z);
2338
+ int iy = ((i*k)+int(yc));
2339
+ z[ iy ] = (z[iy]-1.0) ;
2340
+ ;
2341
+ scm2cpp::cu::wrote_host(z);
2342
+ ;
2343
+ } ;
2344
+ } ;
2345
+ scm2cpp::cu::blas_gemm(g, z, x, 1.0, 0.0, 1, 0, k, p, n) ;
2346
+ { long scm2cpp_cnt = (long)((k*p)) - (long)(0);
2347
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
2348
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
2349
+ scm2cpp_k62<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(coef), scm2cpp::cu::dev(g), n, l2, scm2cpp_red);
2350
+ scm2cpp::cu::launched("scm2cpp_k62");
2351
+ scm2cpp::cu::wrote_dev(g);
2352
+ pen = pen + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
2353
+ } else {
2354
+ scm2cpp::cu::need_host(coef);
2355
+ scm2cpp::cu::need_host(g);
2356
+ for( int t = 0 ; !(t == (k*p)) ; t = (t+1) ) {
2357
+ double wt = coef[t];
2358
+ pen = (pen+(wt*wt)) ;
2359
+ g[ t ] = ((g[t]/double(n))+(l2*wt)) ;
2360
+ ;
2361
+ }
2362
+ scm2cpp::cu::wrote_host(g);
2363
+ }
2364
+ } ;
2365
+ { long scm2cpp_cnt = (long)(k) - (long)(0);
2366
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
2367
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
2368
+ scm2cpp_k63<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(z), scm2cpp::cu::dev(g), fitint, n, k, p, scm2cpp_red);
2369
+ scm2cpp::cu::launched("scm2cpp_k63");
2370
+ scm2cpp::cu::wrote_dev(g);
2371
+ } else {
2372
+ for( int c = 0 ; !(c == k) ; c = (c+1) ) {
2373
+ double acc = 0.0;
2374
+ if( fitint == 1 ) {
2375
+ {
2376
+ long scm2cpp_cnt = (long)(n) - (long)(0);
2377
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
2378
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
2379
+ scm2cpp_k64<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(z), k, c, scm2cpp_red);
2380
+ scm2cpp::cu::launched("scm2cpp_k64");
2381
+ acc = acc + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
2382
+ } else {
2383
+ scm2cpp::cu::need_host(z);
2384
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2385
+ acc = (acc+z[((i*k)+c)]) ;
2386
+ }
2387
+ }
2388
+ } ;
2389
+ } else {
2390
+ 0 ;
2391
+ } ;
2392
+ scm2cpp::cu::need_host(g);
2393
+ g[ ((k*p)+c) ] = (acc/double(n)) ;
2394
+ scm2cpp::cu::wrote_host(g);
2395
+ ;
2396
+ }
2397
+ }
2398
+ } ;
2399
+ return ((loss/double(n))+(0.5*(l2*pen))) ;
2400
+ }
2401
+
2402
+
2403
+ inline int
2404
+ logistic_lbfgs( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> coef, scm2cpp::span<double> out, double c, int maxiter, double tol, int multi, int fitint, int n, int p, int k )
2405
+ { std::array<double,4> aux = scm2cpp::filled_array<double,4>(0.0);
2406
+ scm2cpp::cu::fresh(aux);
2407
+ std::vector<double> work((n*k),0.0);
2408
+ scm2cpp::cu::fresh(work);
2409
+ scm2cpp::cu::need_host(aux);
2410
+ aux[ 0 ] = (1.0/(c*double(n))) ;
2411
+ scm2cpp::cu::wrote_host(aux);
2412
+ scm2cpp::cu::need_host(aux);
2413
+ aux[ 1 ] = ( ( multi == 1 ) ? (1.0) : (0.0) ) ;
2414
+ scm2cpp::cu::wrote_host(aux);
2415
+ scm2cpp::cu::need_host(aux);
2416
+ aux[ 2 ] = ( ( fitint == 1 ) ? (1.0) : (0.0) ) ;
2417
+ scm2cpp::cu::wrote_host(aux);
2418
+ return lbfgs(0,coef,x,y,aux,work,out,10,maxiter,tol,(64.0*2.220446049250313e-16),50,-1,0.0,(k*(p+1)),n,p,k) ;
2419
+ }
2420
+ static __global__ void scm2cpp_k65(long scm2cpp_cnt, int scm2cpp_lo, const double* coef, double* g, double alpha, double* scm2cpp_red) {
2421
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
2422
+ if (scm2cpp_t >= scm2cpp_cnt) return;
2423
+ int j = scm2cpp_lo + (int)scm2cpp_t;
2424
+ double ww = 0.0;
2425
+ { double wj = coef[j];
2426
+ ww = (ww+(wj*wj)) ;
2427
+ g[ j ] = (g[j]+(2.0*(alpha*wj))) ;
2428
+ ;
2429
+ }
2430
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, ww);
2431
+ }
2432
+
2433
+
2434
+ inline double
2435
+ huber_fg( scm2cpp::cspan<double> coef, scm2cpp::span<double> g, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> z, double epsilon, double alpha, int fitint, int n, int p )
2436
+ { scm2cpp::cu::need_host(coef);
2437
+ double b = coef[p];
2438
+ double sigma = coef[(p+1)];
2439
+ int nout = 0;
2440
+ double outsum = 0.0;
2441
+ double sq = 0.0;
2442
+ double csum = 0.0;
2443
+ double ww = 0.0;
2444
+ scm2cpp::cu::blas_gemv(z, x, coef, 1.0, 0.0, 0, n, p) ;
2445
+ scm2cpp::cu::need_host(y);
2446
+ scm2cpp::cu::need_host(z);
2447
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2448
+ double r = ((y[i]-z[i])-b);
2449
+ double a = lb_abs(r);
2450
+ if( a > (epsilon*sigma) ) {
2451
+ nout = (nout+1) ;
2452
+ outsum = (outsum+a) ;
2453
+ z[ i ] = (-2.0*(epsilon*( ( r < 0.0 ) ? (-1.0) : (1.0) ))) ;
2454
+ } else {
2455
+ sq = (sq+(r*r)) ;
2456
+ z[ i ] = ((-2.0*r)/sigma) ;
2457
+ } ;
2458
+ csum = (csum+z[i]) ;
2459
+ ;
2460
+ ;
2461
+ } ;
2462
+ scm2cpp::cu::wrote_host(z);
2463
+ scm2cpp::cu::blas_gemv(g, x, z, 1.0, 0.0, 1, p, n) ;
2464
+ { long scm2cpp_cnt = (long)(p) - (long)(0);
2465
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
2466
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
2467
+ scm2cpp_k65<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(coef), scm2cpp::cu::dev(g), alpha, scm2cpp_red);
2468
+ scm2cpp::cu::launched("scm2cpp_k65");
2469
+ scm2cpp::cu::wrote_dev(g);
2470
+ ww = ww + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
2471
+ } else {
2472
+ scm2cpp::cu::need_host(coef);
2473
+ scm2cpp::cu::need_host(g);
2474
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2475
+ double wj = coef[j];
2476
+ ww = (ww+(wj*wj)) ;
2477
+ g[ j ] = (g[j]+(2.0*(alpha*wj))) ;
2478
+ ;
2479
+ }
2480
+ scm2cpp::cu::wrote_host(g);
2481
+ }
2482
+ } ;
2483
+ scm2cpp::cu::need_host(g);
2484
+ g[ p ] = ( ( fitint == 1 ) ? (csum) : (0.0) ) ;
2485
+ scm2cpp::cu::wrote_host(g);
2486
+ scm2cpp::cu::need_host(g);
2487
+ double sqloss = (sq/sigma);
2488
+ double eps2 = (epsilon*epsilon);
2489
+ g[ (p+1) ] = ((double(n)-(double(nout)*eps2))-(sqloss/sigma)) ;
2490
+ return ((((double(n)*sigma)+sqloss)+((2.0*(epsilon*outsum))-(sigma*(double(nout)*eps2))))+(alpha*ww)) ;
2491
+ }
2492
+
2493
+
2494
+ inline int
2495
+ huber( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> coef, scm2cpp::span<double> out, double epsilon, double alpha, int maxiter, double tol, int fitint, int n, int p )
2496
+ { std::array<double,4> aux = scm2cpp::filled_array<double,4>(0.0);
2497
+ scm2cpp::cu::fresh(aux);
2498
+ std::vector<double> work(n,0.0);
2499
+ scm2cpp::cu::fresh(work);
2500
+ scm2cpp::cu::need_host(aux);
2501
+ aux[ 0 ] = epsilon ;
2502
+ scm2cpp::cu::wrote_host(aux);
2503
+ scm2cpp::cu::need_host(aux);
2504
+ aux[ 1 ] = alpha ;
2505
+ scm2cpp::cu::wrote_host(aux);
2506
+ scm2cpp::cu::need_host(aux);
2507
+ aux[ 2 ] = ( ( fitint == 1 ) ? (1.0) : (0.0) ) ;
2508
+ scm2cpp::cu::wrote_host(aux);
2509
+ return lbfgs(1,coef,x,y,aux,work,out,10,maxiter,tol,(10000000.0*2.220446049250313e-16),20,(p+1),(10.0*2.220446049250313e-16),(p+2),n,p,1) ;
2510
+ }
2511
+ static __global__ void scm2cpp_k66(long scm2cpp_cnt, int scm2cpp_lo, double* z, const double* y, double b, int family, double power, double* scm2cpp_red) {
2512
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
2513
+ if (scm2cpp_t >= scm2cpp_cnt) return;
2514
+ int i = scm2cpp_lo + (int)scm2cpp_t;
2515
+ double loss = 0.0;
2516
+ { double zi = (z[i]+b);
2517
+ double yi = y[i];
2518
+ if( (family == 0 || (family == 2 && power == 1.0)) ) {
2519
+ double e = exp(zi);
2520
+ loss = (loss+(e-(yi*zi))) ;
2521
+ z[ i ] = (e-yi) ;
2522
+ ;
2523
+ } else {
2524
+ if( (family == 1 || (family == 2 && power == 2.0)) ) {
2525
+ double e2 = exp((0.0-zi));
2526
+ loss = (loss+(zi+(yi*e2))) ;
2527
+ z[ i ] = (1.0-(yi*e2)) ;
2528
+ ;
2529
+ } else {
2530
+ if( family == 3 ) {
2531
+ double r = (zi-yi);
2532
+ loss = (loss+(0.5*(r*r))) ;
2533
+ z[ i ] = r ;
2534
+ ;
2535
+ } else {
2536
+ if( power == 0.0 ) {
2537
+ double e3 = exp(zi);
2538
+ loss = (loss+(0.5*((e3-yi)*(e3-yi)))) ;
2539
+ z[ i ] = (e3*(e3-yi)) ;
2540
+ ;
2541
+ } else {
2542
+ double e1 = exp(((1.0-power)*zi));
2543
+ double e4 = exp(((2.0-power)*zi));
2544
+ loss = (loss+((e4/(2.0-power))-((yi*e1)/(1.0-power)))) ;
2545
+ z[ i ] = (e4-(yi*e1)) ;
2546
+ ;
2547
+ } ;
2548
+ } ;
2549
+ } ;
2550
+ } ;
2551
+ ;
2552
+ }
2553
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, loss);
2554
+ }
2555
+ static __global__ void scm2cpp_k67(long scm2cpp_cnt, int scm2cpp_lo, const double* coef, double* g, int n, double l2, double* scm2cpp_red) {
2556
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
2557
+ if (scm2cpp_t >= scm2cpp_cnt) return;
2558
+ int j = scm2cpp_lo + (int)scm2cpp_t;
2559
+ double pen = 0.0;
2560
+ { double wj = coef[j];
2561
+ pen = (pen+(wj*wj)) ;
2562
+ g[ j ] = ((g[j]/double(n))+(l2*wj)) ;
2563
+ ;
2564
+ }
2565
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, pen);
2566
+ }
2567
+ static __global__ void scm2cpp_k68(long scm2cpp_cnt, int scm2cpp_lo, const double* z, double* scm2cpp_red) {
2568
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
2569
+ if (scm2cpp_t >= scm2cpp_cnt) return;
2570
+ int i = scm2cpp_lo + (int)scm2cpp_t;
2571
+ double acc = 0.0;
2572
+ { acc = (acc+z[i]) ;
2573
+ }
2574
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, acc);
2575
+ }
2576
+
2577
+
2578
+ inline double
2579
+ glm_fg( scm2cpp::cspan<double> coef, scm2cpp::span<double> g, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> z, int family, double power, double l2, int fitint, int n, int p )
2580
+ { scm2cpp::cu::need_host(coef);
2581
+ double loss = 0.0;
2582
+ double pen = 0.0;
2583
+ double b = coef[p];
2584
+ scm2cpp::cu::blas_gemv(z, x, coef, 1.0, 0.0, 0, n, p) ;
2585
+ { long scm2cpp_cnt = (long)(n) - (long)(0);
2586
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
2587
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
2588
+ scm2cpp_k66<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(z), scm2cpp::cu::dev(y), b, family, power, scm2cpp_red);
2589
+ scm2cpp::cu::launched("scm2cpp_k66");
2590
+ scm2cpp::cu::wrote_dev(z);
2591
+ loss = loss + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
2592
+ } else {
2593
+ scm2cpp::cu::need_host(z);
2594
+ scm2cpp::cu::need_host(y);
2595
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2596
+ double zi = (z[i]+b);
2597
+ double yi = y[i];
2598
+ if( (family == 0 || (family == 2 && power == 1.0)) ) {
2599
+ double e = exp(zi);
2600
+ loss = (loss+(e-(yi*zi))) ;
2601
+ z[ i ] = (e-yi) ;
2602
+ ;
2603
+ } else {
2604
+ if( (family == 1 || (family == 2 && power == 2.0)) ) {
2605
+ double e2 = exp((0.0-zi));
2606
+ loss = (loss+(zi+(yi*e2))) ;
2607
+ z[ i ] = (1.0-(yi*e2)) ;
2608
+ ;
2609
+ } else {
2610
+ if( family == 3 ) {
2611
+ double r = (zi-yi);
2612
+ loss = (loss+(0.5*(r*r))) ;
2613
+ z[ i ] = r ;
2614
+ ;
2615
+ } else {
2616
+ if( power == 0.0 ) {
2617
+ double e3 = exp(zi);
2618
+ loss = (loss+(0.5*((e3-yi)*(e3-yi)))) ;
2619
+ z[ i ] = (e3*(e3-yi)) ;
2620
+ ;
2621
+ } else {
2622
+ double e1 = exp(((1.0-power)*zi));
2623
+ double e4 = exp(((2.0-power)*zi));
2624
+ loss = (loss+((e4/(2.0-power))-((yi*e1)/(1.0-power)))) ;
2625
+ z[ i ] = (e4-(yi*e1)) ;
2626
+ ;
2627
+ } ;
2628
+ } ;
2629
+ } ;
2630
+ } ;
2631
+ ;
2632
+ }
2633
+ scm2cpp::cu::wrote_host(z);
2634
+ }
2635
+ } ;
2636
+ scm2cpp::cu::blas_gemv(g, x, z, 1.0, 0.0, 1, p, n) ;
2637
+ { long scm2cpp_cnt = (long)(p) - (long)(0);
2638
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
2639
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
2640
+ scm2cpp_k67<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(coef), scm2cpp::cu::dev(g), n, l2, scm2cpp_red);
2641
+ scm2cpp::cu::launched("scm2cpp_k67");
2642
+ scm2cpp::cu::wrote_dev(g);
2643
+ pen = pen + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
2644
+ } else {
2645
+ scm2cpp::cu::need_host(coef);
2646
+ scm2cpp::cu::need_host(g);
2647
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2648
+ double wj = coef[j];
2649
+ pen = (pen+(wj*wj)) ;
2650
+ g[ j ] = ((g[j]/double(n))+(l2*wj)) ;
2651
+ ;
2652
+ }
2653
+ scm2cpp::cu::wrote_host(g);
2654
+ }
2655
+ } ;
2656
+ double acc = 0.0;
2657
+ if( fitint == 1 ) {
2658
+ {
2659
+ long scm2cpp_cnt = (long)(n) - (long)(0);
2660
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
2661
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
2662
+ scm2cpp_k68<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(z), scm2cpp_red);
2663
+ scm2cpp::cu::launched("scm2cpp_k68");
2664
+ acc = acc + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
2665
+ } else {
2666
+ scm2cpp::cu::need_host(z);
2667
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2668
+ acc = (acc+z[i]) ;
2669
+ }
2670
+ }
2671
+ } ;
2672
+ } else {
2673
+ 0 ;
2674
+ } ;
2675
+ scm2cpp::cu::need_host(g);
2676
+ g[ p ] = (acc/double(n)) ;
2677
+ scm2cpp::cu::wrote_host(g);
2678
+ ;
2679
+ return ((loss/double(n))+(0.5*(l2*pen))) ;
2680
+ }
2681
+ static __global__ void scm2cpp_k69(long scm2cpp_cnt, int scm2cpp_lo, double* coef, double* scm2cpp_red) {
2682
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
2683
+ if (scm2cpp_t >= scm2cpp_cnt) return;
2684
+ int j = scm2cpp_lo + (int)scm2cpp_t;
2685
+ { coef[ j ] = 0.0 ;
2686
+ }
2687
+ }
2688
+ static __global__ void scm2cpp_k70(long scm2cpp_cnt, int scm2cpp_lo, const double* y, double* scm2cpp_red) {
2689
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
2690
+ if (scm2cpp_t >= scm2cpp_cnt) return;
2691
+ int i = scm2cpp_lo + (int)scm2cpp_t;
2692
+ double ym = 0.0;
2693
+ { ym = (ym+y[i]) ;
2694
+ }
2695
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, ym);
2696
+ }
2697
+
2698
+
2699
+ inline int
2700
+ glm( scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, scm2cpp::span<double> coef, scm2cpp::span<double> out, int family, double power, double alpha, int maxiter, double tol, int fitint, int n, int p )
2701
+ { std::array<double,4> aux = scm2cpp::filled_array<double,4>(0.0);
2702
+ scm2cpp::cu::fresh(aux);
2703
+ std::vector<double> work(n,0.0);
2704
+ scm2cpp::cu::fresh(work);
2705
+ double ym = 0.0;
2706
+ scm2cpp::cu::need_host(aux);
2707
+ aux[ 0 ] = alpha ;
2708
+ scm2cpp::cu::wrote_host(aux);
2709
+ scm2cpp::cu::need_host(aux);
2710
+ aux[ 1 ] = double(family) ;
2711
+ scm2cpp::cu::wrote_host(aux);
2712
+ scm2cpp::cu::need_host(aux);
2713
+ aux[ 2 ] = ( ( fitint == 1 ) ? (1.0) : (0.0) ) ;
2714
+ scm2cpp::cu::wrote_host(aux);
2715
+ scm2cpp::cu::need_host(aux);
2716
+ aux[ 3 ] = power ;
2717
+ scm2cpp::cu::wrote_host(aux);
2718
+ { long scm2cpp_cnt = (long)(p) - (long)(0);
2719
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
2720
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
2721
+ scm2cpp_k69<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(coef), scm2cpp_red);
2722
+ scm2cpp::cu::launched("scm2cpp_k69");
2723
+ scm2cpp::cu::wrote_dev(coef);
2724
+ } else {
2725
+ scm2cpp::cu::need_host(coef);
2726
+ for( int j = 0 ; !(j == p) ; j = (j+1) ) {
2727
+ coef[ j ] = 0.0 ;
2728
+ }
2729
+ scm2cpp::cu::wrote_host(coef);
2730
+ }
2731
+ } ;
2732
+ { long scm2cpp_cnt = (long)(n) - (long)(0);
2733
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
2734
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
2735
+ scm2cpp_k70<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(y), scm2cpp_red);
2736
+ scm2cpp::cu::launched("scm2cpp_k70");
2737
+ ym = ym + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
2738
+ } else {
2739
+ scm2cpp::cu::need_host(y);
2740
+ for( int i = 0 ; !(i == n) ; i = (i+1) ) {
2741
+ ym = (ym+y[i]) ;
2742
+ }
2743
+ }
2744
+ } ;
2745
+ ym = (ym/double(n)) ;
2746
+ scm2cpp::cu::need_host(coef);
2747
+ coef[ p ] = ( ( fitint == 1 ) ? (( ( family == 3 ) ? (ym) : (log(ym)) )) : (0.0) ) ;
2748
+ scm2cpp::cu::wrote_host(coef);
2749
+ return lbfgs(2,coef,x,y,aux,work,out,10,maxiter,tol,(64.0*2.220446049250313e-16),50,-1,0.0,(p+1),n,p,1) ;
2750
+ }
2751
+
2752
+
2753
+ SCM2CPP_FN inline double
2754
+ lb_abs( double a )
2755
+ {
2756
+ if( a < 0.0 ) {
2757
+ return (0.0-a) ;
2758
+ }
2759
+ else {
2760
+ return a ;
2761
+ }
2762
+ }
2763
+
2764
+
2765
+ SCM2CPP_FN inline double
2766
+ lb_max( double a, double b )
2767
+ {
2768
+ if( a > b ) {
2769
+ return a ;
2770
+ }
2771
+ else {
2772
+ return b ;
2773
+ }
2774
+ }
2775
+
2776
+
2777
+ SCM2CPP_FN inline double
2778
+ lb_min( double a, double b )
2779
+ {
2780
+ if( a < b ) {
2781
+ return a ;
2782
+ }
2783
+ else {
2784
+ return b ;
2785
+ }
2786
+ }
2787
+
2788
+
2789
+ SCM2CPP_FN inline int
2790
+ lb_dcstep( std::array<double,8> & cs, double fp, double dp, double stpmin, double stpmax )
2791
+ { double stx = cs[0];
2792
+ double fx = cs[1];
2793
+ double dx = cs[2];
2794
+ double sty = cs[3];
2795
+ double fy = cs[4];
2796
+ double dy = cs[5];
2797
+ double stp = cs[6];
2798
+ double brackt = cs[7];
2799
+ double stpf = 0.0;
2800
+ double sgnd = (dp*(dx/lb_abs(dx)));
2801
+ if( fp > fx ) {
2802
+ double th1 = ((((3.0*(fx-fp))/(stp-stx))+dx)+dp);
2803
+ double s1 = lb_max(lb_abs(th1),lb_max(lb_abs(dx),lb_abs(dp)));
2804
+ double ga1 = (s1*sqrt((((th1/s1)*(th1/s1))-((dx/s1)*(dp/s1)))));
2805
+ double gm1 = ( ( stp < stx ) ? ((0.0-ga1)) : (ga1) );
2806
+ double r1 = (((gm1-dx)+th1)/(((gm1-dx)+gm1)+dp));
2807
+ double stpc1 = (stx+(r1*(stp-stx)));
2808
+ double stpq1 = (stx+(((dx/(((fx-fp)/(stp-stx))+dx))/2.0)*(stp-stx)));
2809
+ if( lb_abs(double((stpc1-stx))) < lb_abs(double((stpq1-stx))) ) {
2810
+ stpf = stpc1 ;
2811
+ } else {
2812
+ stpf = (stpc1+((stpq1-stpc1)/2.0)) ;
2813
+ } ;
2814
+ brackt = 1.0 ;
2815
+ ;
2816
+ ;
2817
+ ;
2818
+ ;
2819
+ ;
2820
+ ;
2821
+ 0 ;
2822
+ } else {
2823
+ if( sgnd < 0.0 ) {
2824
+ double th2 = ((((3.0*(fx-fp))/(stp-stx))+dx)+dp);
2825
+ double s2 = lb_max(lb_abs(th2),lb_max(lb_abs(dx),lb_abs(dp)));
2826
+ double ga2 = (s2*sqrt((((th2/s2)*(th2/s2))-((dx/s2)*(dp/s2)))));
2827
+ double gm2 = ( ( stp > stx ) ? ((0.0-ga2)) : (ga2) );
2828
+ double r2 = (((gm2-dp)+th2)/(((gm2-dp)+gm2)+dx));
2829
+ double stpc2 = (stp+(r2*(stx-stp)));
2830
+ double stpq2 = (stp+((dp/(dp-dx))*(stx-stp)));
2831
+ if( lb_abs(double((stpc2-stp))) > lb_abs(double((stpq2-stp))) ) {
2832
+ stpf = stpc2 ;
2833
+ } else {
2834
+ stpf = stpq2 ;
2835
+ } ;
2836
+ brackt = 1.0 ;
2837
+ ;
2838
+ ;
2839
+ ;
2840
+ ;
2841
+ ;
2842
+ ;
2843
+ 0 ;
2844
+ } else {
2845
+ if( lb_abs(dp) < lb_abs(dx) ) {
2846
+ double th3 = ((((3.0*(fx-fp))/(stp-stx))+dx)+dp);
2847
+ double s3 = lb_max(lb_abs(th3),lb_max(lb_abs(dx),lb_abs(dp)));
2848
+ double ga3 = (s3*sqrt(lb_max(0.0,double((((th3/s3)*(th3/s3))-((dx/s3)*(dp/s3)))))));
2849
+ double gm3 = ( ( stp > stx ) ? ((0.0-ga3)) : (ga3) );
2850
+ double r3 = (((gm3-dp)+th3)/((gm3+(dx-dp))+gm3));
2851
+ double stpc3 = ( ( (r3 < 0.0 && !(gm3 == 0.0)) ) ? ((stp+(r3*(stx-stp)))) : (( ( stp > stx ) ? (stpmax) : (stpmin) )) );
2852
+ double stpq3 = (stp+((dp/(dp-dx))*(stx-stp)));
2853
+ if( brackt == 1.0 ) {
2854
+ if( lb_abs(double((stpc3-stp))) < lb_abs(double((stpq3-stp))) ) {
2855
+ stpf = stpc3 ;
2856
+ } else {
2857
+ stpf = stpq3 ;
2858
+ } ;
2859
+ if( stp > stx ) {
2860
+ stpf = lb_min(double((stp+(0.66*(sty-stp)))),stpf) ;
2861
+ } else {
2862
+ stpf = lb_max(double((stp+(0.66*(sty-stp)))),stpf) ;
2863
+ } ;
2864
+ } else {
2865
+ if( lb_abs(double((stpc3-stp))) > lb_abs(double((stpq3-stp))) ) {
2866
+ stpf = stpc3 ;
2867
+ } else {
2868
+ stpf = stpq3 ;
2869
+ } ;
2870
+ stpf = lb_min(stpmax,stpf) ;
2871
+ stpf = lb_max(stpmin,stpf) ;
2872
+ } ;
2873
+ ;
2874
+ ;
2875
+ ;
2876
+ ;
2877
+ ;
2878
+ ;
2879
+ 0 ;
2880
+ } else {
2881
+ if( brackt == 1.0 ) {
2882
+ double th4 = ((((3.0*(fp-fy))/(sty-stp))+dy)+dp);
2883
+ double s4 = lb_max(lb_abs(th4),lb_max(lb_abs(dy),lb_abs(dp)));
2884
+ double ga4 = (s4*sqrt((((th4/s4)*(th4/s4))-((dy/s4)*(dp/s4)))));
2885
+ double gm4 = ( ( stp > sty ) ? ((0.0-ga4)) : (ga4) );
2886
+ double r4 = (((gm4-dp)+th4)/(((gm4-dp)+gm4)+dy));
2887
+ stpf = (stp+(r4*(sty-stp))) ;
2888
+ ;
2889
+ ;
2890
+ ;
2891
+ ;
2892
+ ;
2893
+ 0 ;
2894
+ } else {
2895
+ if( stp > stx ) {
2896
+ stpf = stpmax ;
2897
+ } else {
2898
+ stpf = stpmin ;
2899
+ } ;
2900
+ } ;
2901
+ } ;
2902
+ } ;
2903
+ } ;
2904
+ if( fp > fx ) {
2905
+ cs[ 3 ] = stp ;
2906
+ cs[ 4 ] = fp ;
2907
+ cs[ 5 ] = dp ;
2908
+ } else {
2909
+ if( sgnd < 0.0 ) {
2910
+ cs[ 3 ] = stx ;
2911
+ cs[ 4 ] = fx ;
2912
+ cs[ 5 ] = dx ;
2913
+ } else {
2914
+ 0 ;
2915
+ } ;
2916
+ cs[ 0 ] = stp ;
2917
+ cs[ 1 ] = fp ;
2918
+ cs[ 2 ] = dp ;
2919
+ } ;
2920
+ cs[ 6 ] = stpf ;
2921
+ cs[ 7 ] = brackt ;
2922
+ return 0 ;
2923
+ }
2924
+
2925
+
2926
+ SCM2CPP_FN inline int
2927
+ lb_search_start( std::array<double,16> & ls, double f, double g, double stp, double stpmin, double stpmax, double ftol )
2928
+ { ls[ 0 ] = 0.0 ;
2929
+ ls[ 1 ] = f ;
2930
+ ls[ 2 ] = g ;
2931
+ ls[ 3 ] = 0.0 ;
2932
+ ls[ 4 ] = f ;
2933
+ ls[ 5 ] = g ;
2934
+ ls[ 6 ] = 0.0 ;
2935
+ ls[ 7 ] = 1.0 ;
2936
+ ls[ 8 ] = f ;
2937
+ ls[ 9 ] = g ;
2938
+ ls[ 10 ] = (ftol*g) ;
2939
+ ls[ 11 ] = (stpmax-stpmin) ;
2940
+ ls[ 12 ] = ((stpmax-stpmin)/0.5) ;
2941
+ ls[ 13 ] = 0.0 ;
2942
+ ls[ 14 ] = (stp+(4.0*stp)) ;
2943
+ ls[ 15 ] = stp ;
2944
+ return 0 ;
2945
+ }
2946
+
2947
+
2948
+ SCM2CPP_FN inline int
2949
+ lb_search_step( std::array<double,16> & ls, std::array<double,8> & cs, double f, double g, double ftol, double gtol, double xtol, double stpmin, double stpmax )
2950
+ { double stp = ls[15];
2951
+ double finit = ls[8];
2952
+ double ginit = ls[9];
2953
+ double gtest = ls[10];
2954
+ int task = 0;
2955
+ double ftest = (finit+(stp*gtest));
2956
+ if( (ls[7] == 1.0 && (f <= ftest && g >= 0.0)) ) {
2957
+ ls[ 7 ] = 2.0 ;
2958
+ } else {
2959
+ 0 ;
2960
+ } ;
2961
+ if( (ls[6] == 1.0 && (stp <= ls[13] || stp >= ls[14])) ) {
2962
+ task = 2 ;
2963
+ } else {
2964
+ 0 ;
2965
+ } ;
2966
+ if( (ls[6] == 1.0 && (ls[14]-ls[13]) <= (xtol*ls[14])) ) {
2967
+ task = 2 ;
2968
+ } else {
2969
+ 0 ;
2970
+ } ;
2971
+ if( (stp == stpmax && (f <= ftest && g <= gtest)) ) {
2972
+ task = 2 ;
2973
+ } else {
2974
+ 0 ;
2975
+ } ;
2976
+ if( (stp == stpmin && (f > ftest || g >= gtest)) ) {
2977
+ task = 2 ;
2978
+ } else {
2979
+ 0 ;
2980
+ } ;
2981
+ if( (f <= ftest && lb_abs(g) <= (gtol*(0.0-ginit))) ) {
2982
+ task = 1 ;
2983
+ } else {
2984
+ 0 ;
2985
+ } ;
2986
+ if( task == 0 ) {
2987
+ cs[ 0 ] = ls[0] ;
2988
+ cs[ 3 ] = ls[3] ;
2989
+ cs[ 6 ] = stp ;
2990
+ cs[ 7 ] = ls[6] ;
2991
+ if( (ls[7] == 1.0 && (f <= ls[1] && f > ftest)) ) {
2992
+ cs[ 1 ] = (ls[1]-(ls[0]*gtest)) ;
2993
+ cs[ 2 ] = (ls[2]-gtest) ;
2994
+ cs[ 4 ] = (ls[4]-(ls[3]*gtest)) ;
2995
+ cs[ 5 ] = (ls[5]-gtest) ;
2996
+ lb_dcstep(cs,double((f-(stp*gtest))),double((g-gtest)),ls[13],ls[14]) ;
2997
+ ls[ 1 ] = (cs[1]+(cs[0]*gtest)) ;
2998
+ ls[ 2 ] = (cs[2]+gtest) ;
2999
+ ls[ 4 ] = (cs[4]+(cs[3]*gtest)) ;
3000
+ ls[ 5 ] = (cs[5]+gtest) ;
3001
+ } else {
3002
+ cs[ 1 ] = ls[1] ;
3003
+ cs[ 2 ] = ls[2] ;
3004
+ cs[ 4 ] = ls[4] ;
3005
+ cs[ 5 ] = ls[5] ;
3006
+ lb_dcstep(cs,f,g,ls[13],ls[14]) ;
3007
+ ls[ 1 ] = cs[1] ;
3008
+ ls[ 2 ] = cs[2] ;
3009
+ ls[ 4 ] = cs[4] ;
3010
+ ls[ 5 ] = cs[5] ;
3011
+ } ;
3012
+ ls[ 0 ] = cs[0] ;
3013
+ ls[ 3 ] = cs[3] ;
3014
+ ls[ 6 ] = cs[7] ;
3015
+ double nstp = cs[6];
3016
+ double stx = cs[0];
3017
+ double sty = cs[3];
3018
+ if( ls[6] == 1.0 ) {
3019
+ if( lb_abs(double((sty-stx))) >= (0.66*ls[12]) ) {
3020
+ nstp = (stx+(0.5*(sty-stx))) ;
3021
+ } else {
3022
+ 0 ;
3023
+ } ;
3024
+ ls[ 12 ] = ls[11] ;
3025
+ ls[ 11 ] = lb_abs(double((sty-stx))) ;
3026
+ } else {
3027
+ 0 ;
3028
+ } ;
3029
+ if( ls[6] == 1.0 ) {
3030
+ ls[ 13 ] = lb_min(stx,sty) ;
3031
+ ls[ 14 ] = lb_max(stx,sty) ;
3032
+ } else {
3033
+ ls[ 13 ] = (nstp+(1.1*(nstp-stx))) ;
3034
+ ls[ 14 ] = (nstp+(4.0*(nstp-stx))) ;
3035
+ } ;
3036
+ nstp = lb_max(nstp,stpmin) ;
3037
+ nstp = lb_min(nstp,stpmax) ;
3038
+ if( (ls[6] == 1.0 && ((nstp <= ls[13] || nstp >= ls[14]) || (ls[14]-ls[13]) <= (xtol*ls[14]))) ) {
3039
+ nstp = stx ;
3040
+ } else {
3041
+ 0 ;
3042
+ } ;
3043
+ ls[ 15 ] = nstp ;
3044
+ ;
3045
+ } else {
3046
+ 0 ;
3047
+ } ;
3048
+ return task ;
3049
+ }
3050
+ static __global__ void scm2cpp_k71(long scm2cpp_cnt, int scm2cpp_lo, const double* a, const double* b, double* scm2cpp_red) {
3051
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
3052
+ if (scm2cpp_t >= scm2cpp_cnt) return;
3053
+ int j = scm2cpp_lo + (int)scm2cpp_t;
3054
+ double acc = 0.0;
3055
+ { acc = (acc+(a[j]*b[j])) ;
3056
+ }
3057
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, acc);
3058
+ }
3059
+
3060
+
3061
+ inline double
3062
+ lb_dot( scm2cpp::cspan<double> a, scm2cpp::cspan<double> b, int nv )
3063
+ { double acc = 0.0;
3064
+ { long scm2cpp_cnt = (long)(nv) - (long)(0);
3065
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
3066
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
3067
+ scm2cpp_k71<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(a), scm2cpp::cu::dev(b), scm2cpp_red);
3068
+ scm2cpp::cu::launched("scm2cpp_k71");
3069
+ acc = acc + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
3070
+ } else {
3071
+ scm2cpp::cu::need_host(a);
3072
+ scm2cpp::cu::need_host(b);
3073
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
3074
+ acc = (acc+(a[j]*b[j])) ;
3075
+ }
3076
+ }
3077
+ } ;
3078
+ return acc ;
3079
+ }
3080
+ static __global__ void scm2cpp_k72(long scm2cpp_cnt, int scm2cpp_lo, const double* mem, const double* v, int slot, int nv, double* scm2cpp_red) {
3081
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
3082
+ if (scm2cpp_t >= scm2cpp_cnt) return;
3083
+ int j = scm2cpp_lo + (int)scm2cpp_t;
3084
+ double acc = 0.0;
3085
+ { acc = (acc+(mem[((slot*nv)+j)]*v[j])) ;
3086
+ }
3087
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, acc);
3088
+ }
3089
+
3090
+
3091
+ inline double
3092
+ lb_dot_row( scm2cpp::cspan<double> mem, int slot, scm2cpp::cspan<double> v, int nv )
3093
+ { double acc = 0.0;
3094
+ { long scm2cpp_cnt = (long)(nv) - (long)(0);
3095
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
3096
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
3097
+ scm2cpp_k72<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(mem), scm2cpp::cu::dev(v), slot, nv, scm2cpp_red);
3098
+ scm2cpp::cu::launched("scm2cpp_k72");
3099
+ acc = acc + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
3100
+ } else {
3101
+ scm2cpp::cu::need_host(mem);
3102
+ scm2cpp::cu::need_host(v);
3103
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
3104
+ acc = (acc+(mem[((slot*nv)+j)]*v[j])) ;
3105
+ }
3106
+ }
3107
+ } ;
3108
+ return acc ;
3109
+ }
3110
+ static __global__ void scm2cpp_k73(long scm2cpp_cnt, int scm2cpp_lo, const double* a, const double* b, int ra, int nv, int rb, double* scm2cpp_red) {
3111
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
3112
+ if (scm2cpp_t >= scm2cpp_cnt) return;
3113
+ int j = scm2cpp_lo + (int)scm2cpp_t;
3114
+ double acc = 0.0;
3115
+ { acc = (acc+(a[((ra*nv)+j)]*b[((rb*nv)+j)])) ;
3116
+ }
3117
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, acc);
3118
+ }
3119
+
3120
+
3121
+ inline double
3122
+ lb_dot_rows( scm2cpp::cspan<double> a, int ra, scm2cpp::cspan<double> b, int rb, int nv )
3123
+ { double acc = 0.0;
3124
+ { long scm2cpp_cnt = (long)(nv) - (long)(0);
3125
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
3126
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
3127
+ scm2cpp_k73<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(a), scm2cpp::cu::dev(b), ra, nv, rb, scm2cpp_red);
3128
+ scm2cpp::cu::launched("scm2cpp_k73");
3129
+ acc = acc + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
3130
+ } else {
3131
+ scm2cpp::cu::need_host(a);
3132
+ scm2cpp::cu::need_host(b);
3133
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
3134
+ acc = (acc+(a[((ra*nv)+j)]*b[((rb*nv)+j)])) ;
3135
+ }
3136
+ }
3137
+ } ;
3138
+ return acc ;
3139
+ }
3140
+
3141
+
3142
+ SCM2CPP_FN inline double
3143
+ lb_projgr( scm2cpp::cspan<double> g, scm2cpp::cspan<double> w, int ib, double lbv, int nv )
3144
+ { double acc = 0.0;
3145
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
3146
+ double gj = g[j];
3147
+ double gp = ( ( (j == ib && gj >= 0.0) ) ? (lb_min(double((w[j]-lbv)),gj)) : (gj) );
3148
+ double v = lb_abs(gp);
3149
+ if( v > acc ) {
3150
+ acc = v ;
3151
+ } else {
3152
+ 0 ;
3153
+ } ;
3154
+ ;
3155
+ ;
3156
+ ;
3157
+ } ;
3158
+ return acc ;
3159
+ }
3160
+ static __global__ void scm2cpp_k74(long scm2cpp_cnt, int scm2cpp_lo, double* q, const double* ymem, double a, int slot, int nv, double* scm2cpp_red) {
3161
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
3162
+ if (scm2cpp_t >= scm2cpp_cnt) return;
3163
+ int j = scm2cpp_lo + (int)scm2cpp_t;
3164
+ { q[ j ] = (q[j]-(a*ymem[((slot*nv)+j)])) ;
3165
+ }
3166
+ }
3167
+ static __global__ void scm2cpp_k75(long scm2cpp_cnt, int scm2cpp_lo, double* q, double theta, double* scm2cpp_red) {
3168
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
3169
+ if (scm2cpp_t >= scm2cpp_cnt) return;
3170
+ int j = scm2cpp_lo + (int)scm2cpp_t;
3171
+ { q[ j ] = (q[j]/theta) ;
3172
+ }
3173
+ }
3174
+ static __global__ void scm2cpp_k76(long scm2cpp_cnt, int scm2cpp_lo, double* q, const double* al, const double* smem, int slot2, double bb, int nv, double* scm2cpp_red) {
3175
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
3176
+ if (scm2cpp_t >= scm2cpp_cnt) return;
3177
+ int j = scm2cpp_lo + (int)scm2cpp_t;
3178
+ { q[ j ] = (q[j]+((al[slot2]-bb)*smem[((slot2*nv)+j)])) ;
3179
+ }
3180
+ }
3181
+
3182
+
3183
+ inline int
3184
+ lb_hv( scm2cpp::span<double> q, scm2cpp::cspan<double> smem, scm2cpp::cspan<double> ymem, scm2cpp::cspan<double> rho, scm2cpp::span<double> al, double theta, int col, int head, int m, int nv )
3185
+ { for( int ii = 0 ; !(ii == col) ; ii = (ii+1) ) {
3186
+ int slot = ((head+((col-1)-ii)) % m);
3187
+ scm2cpp::cu::need_host(rho);
3188
+ scm2cpp::cu::need_host(smem);
3189
+ scm2cpp::cu::need_host(q);
3190
+ double a = (rho[slot]*lb_dot_row(smem,slot,q,nv));
3191
+ scm2cpp::cu::need_host(al);
3192
+ al[ slot ] = a ;
3193
+ scm2cpp::cu::wrote_host(al);
3194
+ { long scm2cpp_cnt = (long)(nv) - (long)(0);
3195
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
3196
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
3197
+ scm2cpp_k74<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(q), scm2cpp::cu::dev(ymem), a, slot, nv, scm2cpp_red);
3198
+ scm2cpp::cu::launched("scm2cpp_k74");
3199
+ scm2cpp::cu::wrote_dev(q);
3200
+ } else {
3201
+ scm2cpp::cu::need_host(q);
3202
+ scm2cpp::cu::need_host(ymem);
3203
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
3204
+ q[ j ] = (q[j]-(a*ymem[((slot*nv)+j)])) ;
3205
+ }
3206
+ scm2cpp::cu::wrote_host(q);
3207
+ }
3208
+ } ;
3209
+ ;
3210
+ ;
3211
+ } ;
3212
+ { long scm2cpp_cnt = (long)(nv) - (long)(0);
3213
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
3214
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
3215
+ scm2cpp_k75<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(q), theta, scm2cpp_red);
3216
+ scm2cpp::cu::launched("scm2cpp_k75");
3217
+ scm2cpp::cu::wrote_dev(q);
3218
+ } else {
3219
+ scm2cpp::cu::need_host(q);
3220
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
3221
+ q[ j ] = (q[j]/theta) ;
3222
+ }
3223
+ scm2cpp::cu::wrote_host(q);
3224
+ }
3225
+ } ;
3226
+ for( int ii = 0 ; !(ii == col) ; ii = (ii+1) ) {
3227
+ int slot2 = ((head+ii) % m);
3228
+ scm2cpp::cu::need_host(rho);
3229
+ scm2cpp::cu::need_host(ymem);
3230
+ scm2cpp::cu::need_host(q);
3231
+ double bb = (rho[slot2]*lb_dot_row(ymem,slot2,q,nv));
3232
+ {
3233
+ long scm2cpp_cnt = (long)(nv) - (long)(0);
3234
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
3235
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
3236
+ scm2cpp_k76<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(q), scm2cpp::cu::dev(al), scm2cpp::cu::dev(smem), slot2, bb, nv, scm2cpp_red);
3237
+ scm2cpp::cu::launched("scm2cpp_k76");
3238
+ scm2cpp::cu::wrote_dev(q);
3239
+ } else {
3240
+ scm2cpp::cu::need_host(q);
3241
+ scm2cpp::cu::need_host(al);
3242
+ scm2cpp::cu::need_host(smem);
3243
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
3244
+ q[ j ] = (q[j]+((al[slot2]-bb)*smem[((slot2*nv)+j)])) ;
3245
+ }
3246
+ scm2cpp::cu::wrote_host(q);
3247
+ }
3248
+ } ;
3249
+ ;
3250
+ ;
3251
+ } ;
3252
+ return 0 ;
3253
+ }
3254
+ static __global__ void scm2cpp_k77(long scm2cpp_cnt, int scm2cpp_lo, double* bm, const double* smem, int ii, int nv, double theta, int si, double* scm2cpp_red) {
3255
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
3256
+ if (scm2cpp_t >= scm2cpp_cnt) return;
3257
+ int j = scm2cpp_lo + (int)scm2cpp_t;
3258
+ { bm[ ((ii*nv)+j) ] = (theta*smem[((si*nv)+j)]) ;
3259
+ }
3260
+ }
3261
+
3262
+
3263
+ inline double
3264
+ lb_vbv( scm2cpp::cspan<double> v, scm2cpp::cspan<double> smem, scm2cpp::cspan<double> ymem, scm2cpp::cspan<double> rho, scm2cpp::span<double> bm, scm2cpp::span<double> sb, double theta, int col, int head, int m, int nv )
3265
+ { for( int ii = 0 ; !(ii == col) ; ii = (ii+1) ) {
3266
+ int si = ((head+ii) % m);
3267
+ { long scm2cpp_cnt = (long)(nv) - (long)(0);
3268
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
3269
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
3270
+ scm2cpp_k77<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(bm), scm2cpp::cu::dev(smem), ii, nv, theta, si, scm2cpp_red);
3271
+ scm2cpp::cu::launched("scm2cpp_k77");
3272
+ scm2cpp::cu::wrote_dev(bm);
3273
+ } else {
3274
+ scm2cpp::cu::need_host(bm);
3275
+ scm2cpp::cu::need_host(smem);
3276
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
3277
+ bm[ ((ii*nv)+j) ] = (theta*smem[((si*nv)+j)]) ;
3278
+ }
3279
+ scm2cpp::cu::wrote_host(bm);
3280
+ }
3281
+ } ;
3282
+ for( int jj = 0 ; !(jj == ii) ; jj = (jj+1) ) {
3283
+ int sj = ((head+jj) % m);
3284
+ scm2cpp::cu::need_host(bm);
3285
+ scm2cpp::cu::need_host(smem);
3286
+ scm2cpp::cu::need_host(sb);
3287
+ scm2cpp::cu::need_host(rho);
3288
+ scm2cpp::cu::need_host(ymem);
3289
+ double cb = (lb_dot_rows(bm,jj,smem,si,nv)/sb[jj]);
3290
+ double cy = (rho[sj]*lb_dot_rows(ymem,sj,smem,si,nv));
3291
+ scm2cpp::cu::need_host(bm);
3292
+ scm2cpp::cu::need_host(ymem);
3293
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
3294
+ bm[ ((ii*nv)+j) ] = ((bm[((ii*nv)+j)]-(cb*bm[((jj*nv)+j)]))+(cy*ymem[((sj*nv)+j)])) ;
3295
+ } ;
3296
+ scm2cpp::cu::wrote_host(bm);
3297
+ ;
3298
+ ;
3299
+ } ;
3300
+ sb[ ii ] = lb_dot_rows(bm,ii,smem,si,nv) ;
3301
+ ;
3302
+ } ;
3303
+ scm2cpp::cu::need_host(v);
3304
+ double acc = (theta*lb_dot(v,v,nv));
3305
+ for( int ii = 0 ; !(ii == col) ; ii = (ii+1) ) {
3306
+ int si2 = ((head+ii) % m);
3307
+ scm2cpp::cu::need_host(bm);
3308
+ scm2cpp::cu::need_host(v);
3309
+ scm2cpp::cu::need_host(ymem);
3310
+ double bv = lb_dot_row(bm,ii,v,nv);
3311
+ double yv = lb_dot_row(ymem,si2,v,nv);
3312
+ scm2cpp::cu::need_host(sb);
3313
+ scm2cpp::cu::need_host(rho);
3314
+ acc = ((acc-((bv*bv)/sb[ii]))+(rho[si2]*(yv*yv))) ;
3315
+ ;
3316
+ ;
3317
+ } ;
3318
+ return acc ;
3319
+ }
3320
+ static __global__ void scm2cpp_k78(long scm2cpp_cnt, int scm2cpp_lo, double* q, const double* g, double* scm2cpp_red) {
3321
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
3322
+ if (scm2cpp_t >= scm2cpp_cnt) return;
3323
+ int j = scm2cpp_lo + (int)scm2cpp_t;
3324
+ { q[ j ] = g[j] ;
3325
+ }
3326
+ }
3327
+ static __global__ void scm2cpp_k79(long scm2cpp_cnt, int scm2cpp_lo, double* d, const double* q, double* scm2cpp_red) {
3328
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
3329
+ if (scm2cpp_t >= scm2cpp_cnt) return;
3330
+ int j = scm2cpp_lo + (int)scm2cpp_t;
3331
+ { d[ j ] = (0.0-q[j]) ;
3332
+ }
3333
+ }
3334
+ static __global__ void scm2cpp_k80(long scm2cpp_cnt, int scm2cpp_lo, double* e, double* scm2cpp_red) {
3335
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
3336
+ if (scm2cpp_t >= scm2cpp_cnt) return;
3337
+ int j = scm2cpp_lo + (int)scm2cpp_t;
3338
+ { e[ j ] = 0.0 ;
3339
+ }
3340
+ }
3341
+ static __global__ void scm2cpp_k81(long scm2cpp_cnt, int scm2cpp_lo, double* d, const double* e, double lam, double* scm2cpp_red) {
3342
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
3343
+ if (scm2cpp_t >= scm2cpp_cnt) return;
3344
+ int j = scm2cpp_lo + (int)scm2cpp_t;
3345
+ { d[ j ] = (d[j]+(lam*e[j])) ;
3346
+ }
3347
+ }
3348
+ static __global__ void scm2cpp_k82(long scm2cpp_cnt, int scm2cpp_lo, const double* g, double* d, double dtm, double alpha, double* scm2cpp_red) {
3349
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
3350
+ if (scm2cpp_t >= scm2cpp_cnt) return;
3351
+ int j = scm2cpp_lo + (int)scm2cpp_t;
3352
+ { double xcpj = ((0.0-dtm)*g[j]);
3353
+ d[ j ] = (xcpj+(alpha*(d[j]-xcpj))) ;
3354
+ ;
3355
+ }
3356
+ }
3357
+
3358
+
3359
+ inline int
3360
+ lb_direction( scm2cpp::cspan<double> w, scm2cpp::cspan<double> g, scm2cpp::span<double> d, scm2cpp::span<double> q, scm2cpp::span<double> e, scm2cpp::cspan<double> smem, scm2cpp::cspan<double> ymem, scm2cpp::cspan<double> rho, scm2cpp::span<double> al, scm2cpp::span<double> bm, scm2cpp::span<double> sb, double theta, int col, int head, int m, int ib, double lbv, int nv )
3361
+ { { long scm2cpp_cnt = (long)(nv) - (long)(0);
3362
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
3363
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
3364
+ scm2cpp_k78<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(q), scm2cpp::cu::dev(g), scm2cpp_red);
3365
+ scm2cpp::cu::launched("scm2cpp_k78");
3366
+ scm2cpp::cu::wrote_dev(q);
3367
+ } else {
3368
+ scm2cpp::cu::need_host(q);
3369
+ scm2cpp::cu::need_host(g);
3370
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
3371
+ q[ j ] = g[j] ;
3372
+ }
3373
+ scm2cpp::cu::wrote_host(q);
3374
+ }
3375
+ } ;
3376
+ lb_hv(q,smem,ymem,rho,al,theta,col,head,m,nv) ;
3377
+ { long scm2cpp_cnt = (long)(nv) - (long)(0);
3378
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
3379
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
3380
+ scm2cpp_k79<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(d), scm2cpp::cu::dev(q), scm2cpp_red);
3381
+ scm2cpp::cu::launched("scm2cpp_k79");
3382
+ scm2cpp::cu::wrote_dev(d);
3383
+ } else {
3384
+ scm2cpp::cu::need_host(d);
3385
+ scm2cpp::cu::need_host(q);
3386
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
3387
+ d[ j ] = (0.0-q[j]) ;
3388
+ }
3389
+ scm2cpp::cu::wrote_host(d);
3390
+ }
3391
+ } ;
3392
+ if( ib >= 0 ) {
3393
+ scm2cpp::cu::need_host(g);
3394
+ scm2cpp::cu::need_host(w);
3395
+ double gs = g[ib];
3396
+ double tl = (w[ib]-lbv);
3397
+ int fixed = 0;
3398
+ double delta = 0.0;
3399
+ double dtm = 0.0;
3400
+ if( (tl <= 0.0 && gs >= 0.0) ) {
3401
+ fixed = 1 ;
3402
+ } else {
3403
+ dtm = (lb_dot(g,g,nv)/lb_vbv(g,smem,ymem,rho,bm,sb,theta,col,head,m,nv)) ;
3404
+ if( (gs > 0.0 && dtm >= (tl/gs)) ) {
3405
+ fixed = 1 ;
3406
+ delta = (0.0-tl) ;
3407
+ } else {
3408
+ 0 ;
3409
+ } ;
3410
+ } ;
3411
+ if( fixed == 1 ) {
3412
+ {
3413
+ long scm2cpp_cnt = (long)(nv) - (long)(0);
3414
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
3415
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
3416
+ scm2cpp_k80<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(e), scm2cpp_red);
3417
+ scm2cpp::cu::launched("scm2cpp_k80");
3418
+ scm2cpp::cu::wrote_dev(e);
3419
+ } else {
3420
+ scm2cpp::cu::need_host(e);
3421
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
3422
+ e[ j ] = 0.0 ;
3423
+ }
3424
+ scm2cpp::cu::wrote_host(e);
3425
+ }
3426
+ } ;
3427
+ scm2cpp::cu::need_host(e);
3428
+ e[ ib ] = 1.0 ;
3429
+ scm2cpp::cu::wrote_host(e);
3430
+ lb_hv(e,smem,ymem,rho,al,theta,col,head,m,nv) ;
3431
+ scm2cpp::cu::need_host(q);
3432
+ scm2cpp::cu::need_host(e);
3433
+ double lam = ((delta+q[ib])/e[ib]);
3434
+ {
3435
+ long scm2cpp_cnt = (long)(nv) - (long)(0);
3436
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
3437
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
3438
+ scm2cpp_k81<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(d), scm2cpp::cu::dev(e), lam, scm2cpp_red);
3439
+ scm2cpp::cu::launched("scm2cpp_k81");
3440
+ scm2cpp::cu::wrote_dev(d);
3441
+ } else {
3442
+ scm2cpp::cu::need_host(d);
3443
+ scm2cpp::cu::need_host(e);
3444
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
3445
+ d[ j ] = (d[j]+(lam*e[j])) ;
3446
+ }
3447
+ scm2cpp::cu::wrote_host(d);
3448
+ }
3449
+ } ;
3450
+ ;
3451
+ scm2cpp::cu::need_host(d);
3452
+ d[ ib ] = delta ;
3453
+ scm2cpp::cu::wrote_host(d);
3454
+ } else {
3455
+ scm2cpp::cu::need_host(w);
3456
+ scm2cpp::cu::need_host(d);
3457
+ if( (w[ib]+d[ib]) < lbv ) {
3458
+ scm2cpp::cu::need_host(d);
3459
+ scm2cpp::cu::need_host(g);
3460
+ scm2cpp::cu::need_host(w);
3461
+ double ddp = ((lb_dot(d,g,nv)-(d[ib]*gs))+((lbv-w[ib])*gs));
3462
+ if( ddp > 0.0 ) {
3463
+ scm2cpp::cu::need_host(d);
3464
+ scm2cpp::cu::need_host(w);
3465
+ double dus = (d[ib]-((0.0-dtm)*gs));
3466
+ double xcps = (w[ib]-(dtm*gs));
3467
+ double alpha = 1.0;
3468
+ if( dus < 0.0 ) {
3469
+ double temp2 = (lbv-xcps);
3470
+ if( temp2 >= 0.0 ) {
3471
+ alpha = 0.0 ;
3472
+ } else {
3473
+ if( dus < temp2 ) {
3474
+ alpha = (temp2/dus) ;
3475
+ } else {
3476
+ 0 ;
3477
+ } ;
3478
+ } ;
3479
+ ;
3480
+ } else {
3481
+ 0 ;
3482
+ } ;
3483
+ { long scm2cpp_cnt = (long)(nv) - (long)(0);
3484
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
3485
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
3486
+ scm2cpp_k82<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(g), scm2cpp::cu::dev(d), dtm, alpha, scm2cpp_red);
3487
+ scm2cpp::cu::launched("scm2cpp_k82");
3488
+ scm2cpp::cu::wrote_dev(d);
3489
+ } else {
3490
+ scm2cpp::cu::need_host(g);
3491
+ scm2cpp::cu::need_host(d);
3492
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
3493
+ double xcpj = ((0.0-dtm)*g[j]);
3494
+ d[ j ] = (xcpj+(alpha*(d[j]-xcpj))) ;
3495
+ ;
3496
+ }
3497
+ scm2cpp::cu::wrote_host(d);
3498
+ }
3499
+ } ;
3500
+ scm2cpp::cu::need_host(d);
3501
+ scm2cpp::cu::need_host(w);
3502
+ if( alpha < 1.0 ) {
3503
+ d[ ib ] = (lbv-w[ib]) ;
3504
+ } else {
3505
+ 0 ;
3506
+ } ;
3507
+ scm2cpp::cu::wrote_host(d);
3508
+ ;
3509
+ } else {
3510
+ scm2cpp::cu::need_host(d);
3511
+ scm2cpp::cu::need_host(w);
3512
+ d[ ib ] = (lbv-w[ib]) ;
3513
+ scm2cpp::cu::wrote_host(d);
3514
+ } ;
3515
+ ;
3516
+ } else {
3517
+ 0 ;
3518
+ } ;
3519
+ } ;
3520
+ ;
3521
+ } else {
3522
+ 0 ;
3523
+ } ;
3524
+ return 0 ;
3525
+ }
3526
+ static __global__ void scm2cpp_k83(long scm2cpp_cnt, int scm2cpp_lo, double* t, const double* w, double* gold, const double* g, double* scm2cpp_red) {
3527
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
3528
+ if (scm2cpp_t >= scm2cpp_cnt) return;
3529
+ int j = scm2cpp_lo + (int)scm2cpp_t;
3530
+ { t[ j ] = w[j] ;
3531
+ gold[ j ] = g[j] ;
3532
+ }
3533
+ }
3534
+ static __global__ void scm2cpp_k84(long scm2cpp_cnt, int scm2cpp_lo, double* w, const double* t, const double* d, double stp, double* scm2cpp_red) {
3535
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
3536
+ if (scm2cpp_t >= scm2cpp_cnt) return;
3537
+ int j = scm2cpp_lo + (int)scm2cpp_t;
3538
+ { w[ j ] = (t[j]+(stp*d[j])) ;
3539
+ }
3540
+ }
3541
+ static __global__ void scm2cpp_k85(long scm2cpp_cnt, int scm2cpp_lo, double* w, const double* t, double* g, const double* gold, double* scm2cpp_red) {
3542
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
3543
+ if (scm2cpp_t >= scm2cpp_cnt) return;
3544
+ int j = scm2cpp_lo + (int)scm2cpp_t;
3545
+ { w[ j ] = t[j] ;
3546
+ g[ j ] = gold[j] ;
3547
+ }
3548
+ }
3549
+ static __global__ void scm2cpp_k86(long scm2cpp_cnt, int scm2cpp_lo, const double* g, const double* gold, double* smem, const double* d, double* ymem, int slot3, int nv, double stp2, double* scm2cpp_red) {
3550
+ long scm2cpp_t = blockIdx.x * (long)blockDim.x + threadIdx.x;
3551
+ if (scm2cpp_t >= scm2cpp_cnt) return;
3552
+ int j = scm2cpp_lo + (int)scm2cpp_t;
3553
+ double rr = 0.0;
3554
+ { double yj = (g[j]-gold[j]);
3555
+ smem[ ((slot3*nv)+j) ] = (stp2*d[j]) ;
3556
+ ymem[ ((slot3*nv)+j) ] = yj ;
3557
+ rr = (rr+(yj*yj)) ;
3558
+ ;
3559
+ }
3560
+ scm2cpp::cu::atomic_add(scm2cpp_red + 0, rr);
3561
+ }
3562
+
3563
+
3564
+ inline int
3565
+ lbfgs( int kind, scm2cpp::span<double> w, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, const std::array<double,4> & aux, scm2cpp::span<double> work, scm2cpp::span<double> out, int m, int maxiter, double pgtol, double ftol, int maxls, int ib, double lbv, int nv, int n, int p, int k )
3566
+ { std::vector<double> g(nv,0.0);
3567
+ scm2cpp::cu::fresh(g);
3568
+ std::vector<double> gold(nv,0.0);
3569
+ scm2cpp::cu::fresh(gold);
3570
+ std::vector<double> d(nv,0.0);
3571
+ scm2cpp::cu::fresh(d);
3572
+ std::vector<double> t(nv,0.0);
3573
+ scm2cpp::cu::fresh(t);
3574
+ std::vector<double> q(nv,0.0);
3575
+ scm2cpp::cu::fresh(q);
3576
+ std::vector<double> e(nv,0.0);
3577
+ scm2cpp::cu::fresh(e);
3578
+ std::vector<double> smem((m*nv),0.0);
3579
+ scm2cpp::cu::fresh(smem);
3580
+ std::vector<double> ymem((m*nv),0.0);
3581
+ scm2cpp::cu::fresh(ymem);
3582
+ std::vector<double> bm((m*nv),0.0);
3583
+ scm2cpp::cu::fresh(bm);
3584
+ std::vector<double> rho(m,0.0);
3585
+ scm2cpp::cu::fresh(rho);
3586
+ std::vector<double> sb(m,0.0);
3587
+ scm2cpp::cu::fresh(sb);
3588
+ std::vector<double> al(m,0.0);
3589
+ scm2cpp::cu::fresh(al);
3590
+ std::array<double,16> ls = scm2cpp::filled_array<double,16>(0.0);
3591
+ scm2cpp::cu::fresh(ls);
3592
+ std::array<double,8> cs = scm2cpp::filled_array<double,8>(0.0);
3593
+ scm2cpp::cu::fresh(cs);
3594
+ double eps = 2.220446049250313e-16;
3595
+ int iter = 0;
3596
+ int col = 0;
3597
+ int head = 0;
3598
+ double theta = 1.0;
3599
+ int nfg = 0;
3600
+ int done = 0;
3601
+ scm2cpp::cu::need_host(w);
3602
+ scm2cpp::cu::need_host(g);
3603
+ scm2cpp::cu::need_host(x);
3604
+ scm2cpp::cu::need_host(y);
3605
+ scm2cpp::cu::need_host(aux);
3606
+ scm2cpp::cu::need_host(work);
3607
+ double f = lbfgs_fg(kind,w,g,x,y,aux,work,n,p,k);
3608
+ nfg = 1 ;
3609
+ scm2cpp::cu::need_host(g);
3610
+ scm2cpp::cu::need_host(w);
3611
+ if( lb_projgr(g,w,ib,lbv,nv) <= pgtol ) {
3612
+ done = 1 ;
3613
+ } else {
3614
+ 0 ;
3615
+ } ;
3616
+ for( ; !(done == 1) ; ) {
3617
+ lb_direction(w,g,d,q,e,smem,ymem,rho,al,bm,sb,theta,col,head,m,ib,lbv,nv) ;
3618
+ { long scm2cpp_cnt = (long)(nv) - (long)(0);
3619
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
3620
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
3621
+ scm2cpp_k83<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(t), scm2cpp::cu::dev(w), scm2cpp::cu::dev(gold), scm2cpp::cu::dev(g), scm2cpp_red);
3622
+ scm2cpp::cu::launched("scm2cpp_k83");
3623
+ scm2cpp::cu::wrote_dev(t);
3624
+ scm2cpp::cu::wrote_dev(gold);
3625
+ } else {
3626
+ scm2cpp::cu::need_host(t);
3627
+ scm2cpp::cu::need_host(w);
3628
+ scm2cpp::cu::need_host(gold);
3629
+ scm2cpp::cu::need_host(g);
3630
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
3631
+ t[ j ] = w[j] ;
3632
+ gold[ j ] = g[j] ;
3633
+ }
3634
+ scm2cpp::cu::wrote_host(t);
3635
+ scm2cpp::cu::wrote_host(gold);
3636
+ }
3637
+ } ;
3638
+ scm2cpp::cu::need_host(d);
3639
+ scm2cpp::cu::need_host(g);
3640
+ double fold = f;
3641
+ double dnorm = sqrt(lb_dot(d,d,nv));
3642
+ double gdold = lb_dot(g,d,nv);
3643
+ double stpmx = 10000000000.0;
3644
+ double gd = 0.0;
3645
+ int task = 0;
3646
+ int ifun = 0;
3647
+ int fail = 0;
3648
+ scm2cpp::cu::need_host(d);
3649
+ scm2cpp::cu::need_host(w);
3650
+ if( ib >= 0 ) {
3651
+ if( iter == 0 ) {
3652
+ stpmx = 1.0 ;
3653
+ } else {
3654
+ if( d[ib] < 0.0 ) {
3655
+ double a2 = (lbv-w[ib]);
3656
+ if( a2 >= 0.0 ) {
3657
+ stpmx = 0.0 ;
3658
+ } else {
3659
+ if( (d[ib]*stpmx) < a2 ) {
3660
+ stpmx = (a2/d[ib]) ;
3661
+ } else {
3662
+ 0 ;
3663
+ } ;
3664
+ } ;
3665
+ ;
3666
+ } else {
3667
+ 0 ;
3668
+ } ;
3669
+ } ;
3670
+ } else {
3671
+ 0 ;
3672
+ } ;
3673
+ if( gdold >= 0.0 ) {
3674
+ fail = 1 ;
3675
+ } else {
3676
+ scm2cpp::cu::need_host(ls);
3677
+ lb_search_start(ls,f,gdold,( ( iter == 0 ) ? (lb_min(double((1.0/dnorm)),stpmx)) : (1.0) ),0.0,stpmx,0.001) ;
3678
+ scm2cpp::cu::wrote_host(ls);
3679
+ for( ; !((fail == 1 || !(task == 0))) ; ) {
3680
+ ifun = (ifun+1) ;
3681
+ if( ifun > maxls ) {
3682
+ fail = 1 ;
3683
+ } else {
3684
+ scm2cpp::cu::need_host(ls);
3685
+ double stp = ls[15];
3686
+ {
3687
+ long scm2cpp_cnt = (long)(nv) - (long)(0);
3688
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
3689
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
3690
+ scm2cpp_k84<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(w), scm2cpp::cu::dev(t), scm2cpp::cu::dev(d), stp, scm2cpp_red);
3691
+ scm2cpp::cu::launched("scm2cpp_k84");
3692
+ scm2cpp::cu::wrote_dev(w);
3693
+ } else {
3694
+ scm2cpp::cu::need_host(w);
3695
+ scm2cpp::cu::need_host(t);
3696
+ scm2cpp::cu::need_host(d);
3697
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
3698
+ w[ j ] = (t[j]+(stp*d[j])) ;
3699
+ }
3700
+ scm2cpp::cu::wrote_host(w);
3701
+ }
3702
+ } ;
3703
+ f = lbfgs_fg(kind,w,g,x,y,aux,work,n,p,k) ;
3704
+ nfg = (nfg+1) ;
3705
+ gd = lb_dot(g,d,nv) ;
3706
+ scm2cpp::cu::need_host(ls);
3707
+ scm2cpp::cu::need_host(cs);
3708
+ task = lb_search_step(ls,cs,f,gd,0.001,0.9,0.1,0.0,stpmx) ;
3709
+ scm2cpp::cu::wrote_host(ls);
3710
+ scm2cpp::cu::wrote_host(cs);
3711
+ ;
3712
+ } ;
3713
+ } ;
3714
+ } ;
3715
+ if( fail == 1 ) {
3716
+ {
3717
+ long scm2cpp_cnt = (long)(nv) - (long)(0);
3718
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
3719
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
3720
+ scm2cpp_k85<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(w), scm2cpp::cu::dev(t), scm2cpp::cu::dev(g), scm2cpp::cu::dev(gold), scm2cpp_red);
3721
+ scm2cpp::cu::launched("scm2cpp_k85");
3722
+ scm2cpp::cu::wrote_dev(w);
3723
+ scm2cpp::cu::wrote_dev(g);
3724
+ } else {
3725
+ scm2cpp::cu::need_host(w);
3726
+ scm2cpp::cu::need_host(t);
3727
+ scm2cpp::cu::need_host(g);
3728
+ scm2cpp::cu::need_host(gold);
3729
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
3730
+ w[ j ] = t[j] ;
3731
+ g[ j ] = gold[j] ;
3732
+ }
3733
+ scm2cpp::cu::wrote_host(w);
3734
+ scm2cpp::cu::wrote_host(g);
3735
+ }
3736
+ } ;
3737
+ f = fold ;
3738
+ if( col == 0 ) {
3739
+ done = 1 ;
3740
+ } else {
3741
+ col = 0 ;
3742
+ head = 0 ;
3743
+ theta = 1.0 ;
3744
+ } ;
3745
+ } else {
3746
+ scm2cpp::cu::need_host(ls);
3747
+ double stp2 = ls[15];
3748
+ iter = (iter+1) ;
3749
+ if( iter >= maxiter ) {
3750
+ done = 1 ;
3751
+ } else {
3752
+ 0 ;
3753
+ } ;
3754
+ scm2cpp::cu::need_host(g);
3755
+ scm2cpp::cu::need_host(w);
3756
+ if( lb_projgr(g,w,ib,lbv,nv) <= pgtol ) {
3757
+ done = 1 ;
3758
+ } else {
3759
+ 0 ;
3760
+ } ;
3761
+ if( (fold-f) <= (ftol*lb_max(lb_max(lb_abs(fold),lb_abs(f)),1.0)) ) {
3762
+ done = 1 ;
3763
+ } else {
3764
+ 0 ;
3765
+ } ;
3766
+ if( done == 0 ) {
3767
+ double dr = ((gd-gdold)*stp2);
3768
+ double ddum = ((0.0-gdold)*stp2);
3769
+ if( dr > (eps*ddum) ) {
3770
+ int slot3 = ( ( col < m ) ? (((head+col) % m)) : (head) );
3771
+ double rr = 0.0;
3772
+ {
3773
+ long scm2cpp_cnt = (long)(nv) - (long)(0);
3774
+ if (scm2cpp_cnt >= scm2cpp::cu::min_trip()) {
3775
+ double* scm2cpp_red = scm2cpp::cu::reduction_slots(1);
3776
+ scm2cpp_k86<<<(unsigned)((scm2cpp_cnt + 255) / 256), 256>>>(scm2cpp_cnt, 0, scm2cpp::cu::dev(g), scm2cpp::cu::dev(gold), scm2cpp::cu::dev(smem), scm2cpp::cu::dev(d), scm2cpp::cu::dev(ymem), slot3, nv, stp2, scm2cpp_red);
3777
+ scm2cpp::cu::launched("scm2cpp_k86");
3778
+ scm2cpp::cu::wrote_dev(smem);
3779
+ scm2cpp::cu::wrote_dev(ymem);
3780
+ rr = rr + scm2cpp::cu::reduction_value(scm2cpp_red, 0);
3781
+ } else {
3782
+ scm2cpp::cu::need_host(g);
3783
+ scm2cpp::cu::need_host(gold);
3784
+ scm2cpp::cu::need_host(smem);
3785
+ scm2cpp::cu::need_host(d);
3786
+ scm2cpp::cu::need_host(ymem);
3787
+ for( int j = 0 ; !(j == nv) ; j = (j+1) ) {
3788
+ double yj = (g[j]-gold[j]);
3789
+ smem[ ((slot3*nv)+j) ] = (stp2*d[j]) ;
3790
+ ymem[ ((slot3*nv)+j) ] = yj ;
3791
+ rr = (rr+(yj*yj)) ;
3792
+ ;
3793
+ }
3794
+ scm2cpp::cu::wrote_host(smem);
3795
+ scm2cpp::cu::wrote_host(ymem);
3796
+ }
3797
+ } ;
3798
+ scm2cpp::cu::need_host(rho);
3799
+ rho[ slot3 ] = (1.0/dr) ;
3800
+ scm2cpp::cu::wrote_host(rho);
3801
+ theta = (rr/dr) ;
3802
+ if( col < m ) {
3803
+ col = (col+1) ;
3804
+ } else {
3805
+ head = ((head+1) % m) ;
3806
+ } ;
3807
+ ;
3808
+ ;
3809
+ 0 ;
3810
+ } else {
3811
+ 0 ;
3812
+ } ;
3813
+ ;
3814
+ } else {
3815
+ 0 ;
3816
+ } ;
3817
+ ;
3818
+ } ;
3819
+ ;
3820
+ } ;
3821
+ scm2cpp::cu::need_host(out);
3822
+ out[ 0 ] = f ;
3823
+ scm2cpp::cu::wrote_host(out);
3824
+ scm2cpp::cu::need_host(out);
3825
+ out[ 1 ] = double(nfg) ;
3826
+ scm2cpp::cu::wrote_host(out);
3827
+ return iter ;
3828
+ }
3829
+
3830
+
3831
+ SCM2CPP_FN inline double
3832
+ lbfgs_fg( int kind, scm2cpp::cspan<double> w, scm2cpp::span<double> g, scm2cpp::cspan<double> x, scm2cpp::cspan<double> y, const std::array<double,4> & aux, scm2cpp::span<double> work, int n, int p, int k )
3833
+ {
3834
+ if( kind == 0 ) {
3835
+ return logistic_fg(w,g,x,y,work,aux[0],( ( aux[1] == 1.0 ) ? (1) : (0) ),( ( aux[2] == 1.0 ) ? (1) : (0) ),n,p,k) ;
3836
+ }
3837
+ else {
3838
+ if( kind == 1 ) {
3839
+ return huber_fg(w,g,x,y,work,aux[0],aux[1],( ( aux[2] == 1.0 ) ? (1) : (0) ),n,p) ;
3840
+ }
3841
+ else {
3842
+ return glm_fg(w,g,x,y,work,int(aux[1]),aux[3],aux[0],( ( aux[2] == 1.0 ) ? (1) : (0) ),n,p) ;
3843
+ }
3844
+ }
3845
+ }
3846
+ #endif // GPU_HPP