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