numo-linalg 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/README.md +80 -0
  4. data/Rakefile +18 -0
  5. data/ext/numo/linalg/blas/blas.c +352 -0
  6. data/ext/numo/linalg/blas/cblas.h +575 -0
  7. data/ext/numo/linalg/blas/cblas_t.h +563 -0
  8. data/ext/numo/linalg/blas/depend.erb +23 -0
  9. data/ext/numo/linalg/blas/extconf.rb +67 -0
  10. data/ext/numo/linalg/blas/gen/cogen.rb +72 -0
  11. data/ext/numo/linalg/blas/gen/decl.rb +203 -0
  12. data/ext/numo/linalg/blas/gen/desc.rb +8138 -0
  13. data/ext/numo/linalg/blas/gen/erbpp2.rb +339 -0
  14. data/ext/numo/linalg/blas/gen/replace_cblas_h.rb +27 -0
  15. data/ext/numo/linalg/blas/gen/spec.rb +93 -0
  16. data/ext/numo/linalg/blas/numo_blas.h +41 -0
  17. data/ext/numo/linalg/blas/tmpl/axpy.c +75 -0
  18. data/ext/numo/linalg/blas/tmpl/copy.c +57 -0
  19. data/ext/numo/linalg/blas/tmpl/def_c.c +3 -0
  20. data/ext/numo/linalg/blas/tmpl/def_d.c +3 -0
  21. data/ext/numo/linalg/blas/tmpl/def_s.c +3 -0
  22. data/ext/numo/linalg/blas/tmpl/def_z.c +3 -0
  23. data/ext/numo/linalg/blas/tmpl/dot.c +68 -0
  24. data/ext/numo/linalg/blas/tmpl/ger.c +114 -0
  25. data/ext/numo/linalg/blas/tmpl/init_class.c +20 -0
  26. data/ext/numo/linalg/blas/tmpl/init_module.c +12 -0
  27. data/ext/numo/linalg/blas/tmpl/lib.c +40 -0
  28. data/ext/numo/linalg/blas/tmpl/mm.c +214 -0
  29. data/ext/numo/linalg/blas/tmpl/module.c +9 -0
  30. data/ext/numo/linalg/blas/tmpl/mv.c +194 -0
  31. data/ext/numo/linalg/blas/tmpl/nrm2.c +79 -0
  32. data/ext/numo/linalg/blas/tmpl/rot.c +65 -0
  33. data/ext/numo/linalg/blas/tmpl/rotm.c +82 -0
  34. data/ext/numo/linalg/blas/tmpl/scal.c +69 -0
  35. data/ext/numo/linalg/blas/tmpl/sdsdot.c +77 -0
  36. data/ext/numo/linalg/blas/tmpl/set_prefix.c +16 -0
  37. data/ext/numo/linalg/blas/tmpl/swap.c +57 -0
  38. data/ext/numo/linalg/blas/tmpl/syr.c +102 -0
  39. data/ext/numo/linalg/blas/tmpl/syr2.c +110 -0
  40. data/ext/numo/linalg/blas/tmpl/syr2k.c +129 -0
  41. data/ext/numo/linalg/blas/tmpl/syrk.c +132 -0
  42. data/ext/numo/linalg/lapack/depend.erb +23 -0
  43. data/ext/numo/linalg/lapack/extconf.rb +45 -0
  44. data/ext/numo/linalg/lapack/gen/cogen.rb +74 -0
  45. data/ext/numo/linalg/lapack/gen/desc.rb +151278 -0
  46. data/ext/numo/linalg/lapack/gen/replace_lapacke_h.rb +32 -0
  47. data/ext/numo/linalg/lapack/gen/spec.rb +104 -0
  48. data/ext/numo/linalg/lapack/lapack.c +387 -0
  49. data/ext/numo/linalg/lapack/lapacke.h +16425 -0
  50. data/ext/numo/linalg/lapack/lapacke_config.h +119 -0
  51. data/ext/numo/linalg/lapack/lapacke_mangling.h +17 -0
  52. data/ext/numo/linalg/lapack/lapacke_t.h +10550 -0
  53. data/ext/numo/linalg/lapack/numo_lapack.h +42 -0
  54. data/ext/numo/linalg/lapack/tmpl/def_c.c +3 -0
  55. data/ext/numo/linalg/lapack/tmpl/def_d.c +7 -0
  56. data/ext/numo/linalg/lapack/tmpl/def_s.c +7 -0
  57. data/ext/numo/linalg/lapack/tmpl/def_z.c +3 -0
  58. data/ext/numo/linalg/lapack/tmpl/fact.c +179 -0
  59. data/ext/numo/linalg/lapack/tmpl/geev.c +123 -0
  60. data/ext/numo/linalg/lapack/tmpl/gels.c +232 -0
  61. data/ext/numo/linalg/lapack/tmpl/gesv.c +149 -0
  62. data/ext/numo/linalg/lapack/tmpl/gesvd.c +189 -0
  63. data/ext/numo/linalg/lapack/tmpl/ggev.c +138 -0
  64. data/ext/numo/linalg/lapack/tmpl/gqr.c +121 -0
  65. data/ext/numo/linalg/lapack/tmpl/init_class.c +20 -0
  66. data/ext/numo/linalg/lapack/tmpl/init_module.c +12 -0
  67. data/ext/numo/linalg/lapack/tmpl/lange.c +79 -0
  68. data/ext/numo/linalg/lapack/tmpl/lib.c +40 -0
  69. data/ext/numo/linalg/lapack/tmpl/module.c +9 -0
  70. data/ext/numo/linalg/lapack/tmpl/syev.c +91 -0
  71. data/ext/numo/linalg/lapack/tmpl/sygv.c +104 -0
  72. data/ext/numo/linalg/lapack/tmpl/trf.c +276 -0
  73. data/ext/numo/linalg/numo_linalg.h +115 -0
  74. data/lib/numo/linalg.rb +3 -0
  75. data/lib/numo/linalg/function.rb +1008 -0
  76. data/lib/numo/linalg/linalg.rb +7 -0
  77. data/lib/numo/linalg/loader.rb +174 -0
  78. data/lib/numo/linalg/use/atlas.rb +3 -0
  79. data/lib/numo/linalg/use/lapack.rb +3 -0
  80. data/lib/numo/linalg/use/mkl.rb +3 -0
  81. data/lib/numo/linalg/use/openblas.rb +3 -0
  82. data/lib/numo/linalg/version.rb +5 -0
  83. data/numo-linalg.gemspec +26 -0
  84. data/spec/lapack_spec.rb +13 -0
  85. metadata +172 -0
@@ -0,0 +1,32 @@
1
+ puts <<EOL
2
+ #ifndef NUMO_LAPACKE_T_H
3
+ #define NUMO_LAPACKE_T_H
4
+
5
+ EOL
6
+
7
+ ARGF.each_line do |line|
8
+ case line
9
+ when /C-LAPACK function prototypes/
10
+ puts line
11
+ break
12
+ end
13
+ end
14
+
15
+ type, name = nil,nil
16
+
17
+ ARGF.each_line do |line|
18
+ break if /^#define / =~ line
19
+ line.sub!(/^(\w+)\s+LAPACKE_(\w+)\s*\(/) do
20
+ type, name = $1,$2
21
+ "typedef #{type} (*#{name}_t)("
22
+ end
23
+ case name
24
+ when /^[id]?z/; line.gsub!(/\bvoid\s*\*/,"dcomplex *")
25
+ when /^[is]?c/; line.gsub!(/\bvoid\s*\*/,"scomplex *")
26
+ end
27
+ puts line
28
+ end
29
+
30
+ puts <<EOL
31
+ #endif
32
+ EOL
@@ -0,0 +1,104 @@
1
+ def_id "order"
2
+ def_id "uplo"
3
+ def_id "jobu"
4
+ def_id "jobvt"
5
+ def_id "jobz"
6
+ def_id "jobvl"
7
+ def_id "jobvr"
8
+ def_id "trans"
9
+ def_id "rcond"
10
+ def_id "itype"
11
+ def_id "norm"
12
+ def_id "axis"
13
+ def_id "keepdims"
14
+
15
+ if /[cz]/ =~ blas_char
16
+ def_id "real"
17
+ def_id "imag"
18
+ end
19
+
20
+ case blas_char
21
+ when "c"
22
+ real_char = "s"
23
+ when "z"
24
+ real_char = "d"
25
+ end
26
+
27
+
28
+ # norm
29
+
30
+ decl "?lange"
31
+
32
+ # linear system
33
+
34
+ decl "?gesv"
35
+ decl "?sysv", "gesv"
36
+ decl "?posv", "gesv"
37
+ case blas_char
38
+ when /c|z/
39
+ decl "?hesv", "gesv"
40
+ end
41
+
42
+ decl "?gesvd"
43
+ decl "?gesdd", "gesvd"
44
+
45
+ decl "?gels"
46
+ decl "?gelss", "gels"
47
+ decl "?gelsd", "gels"
48
+ decl "?gelsy", "gels"
49
+
50
+ # eigenvalue
51
+
52
+ decl "?geev"
53
+ decl "?ggev"
54
+
55
+ case blas_char
56
+ when /c|z/
57
+ decl "?heev", "syev"
58
+ decl "?heevd", "syev"
59
+ decl "?hegv", "sygv"
60
+ decl "?hegvd", "sygv"
61
+ else
62
+ decl "?syev"
63
+ decl "?syevd", "syev"
64
+ decl "?sygv"
65
+ decl "?sygvd", "sygv"
66
+ end
67
+
68
+ # factorize
69
+
70
+ decl "?geqrf", "fact"
71
+ decl "?gerqf", "fact"
72
+ decl "?geqlf", "fact"
73
+ decl "?gelqf", "fact"
74
+
75
+ decl "?geqp3", "fact"
76
+ decl "?tzrzf", "fact"
77
+
78
+ case blas_char
79
+ when /c|z/
80
+ decl "?ungqr", "gqr"
81
+ else
82
+ decl "?orgqr", "gqr"
83
+ end
84
+
85
+ # LU factorize
86
+
87
+ decl "?getrf", "trf"
88
+ decl "?getri", "trf"
89
+ decl "?getrs", "trf"
90
+
91
+ decl "?sytrf", "trf"
92
+ decl "?sytri", "trf"
93
+ decl "?sytrs", "trf"
94
+
95
+ case blas_char
96
+ when /c|z/
97
+ decl "?hetrf", "trf"
98
+ decl "?hetri", "trf"
99
+ decl "?hetrs", "trf"
100
+ end
101
+
102
+ decl "?potrf", "trf"
103
+ decl "?potri", "trf"
104
+ decl "?potrs", "trf"
@@ -0,0 +1,387 @@
1
+ /*
2
+ !!!!!!!!! Editing !!!!!!!!!!!
3
+
4
+ lapack.c
5
+ LAPACK wrapper for Ruby/Numo
6
+ (C) Copyright 2017 by Masahiro TANAKA
7
+
8
+ This program is free software.
9
+ NO WARRANTY.
10
+ */
11
+ #include <assert.h>
12
+ #include <ruby.h>
13
+ #include "numo/narray.h"
14
+ #include "numo/template.h"
15
+
16
+ // from ruby/ext/fiddle/fiddle.h
17
+ #if defined(HAVE_DLFCN_H)
18
+ # include <dlfcn.h>
19
+ # /* some stranger systems may not define all of these */
20
+ #ifndef RTLD_LAZY
21
+ #define RTLD_LAZY 0
22
+ #endif
23
+ #ifndef RTLD_GLOBAL
24
+ #define RTLD_GLOBAL 0
25
+ #endif
26
+ #ifndef RTLD_NOW
27
+ #define RTLD_NOW 0
28
+ #endif
29
+ #else
30
+ # if defined(_WIN32)
31
+ # include <windows.h>
32
+ # define dlopen(name,flag) ((void*)LoadLibrary(name))
33
+ # define dlerror() strerror(rb_w32_map_errno(GetLastError()))
34
+ # define dlsym(handle,name) ((void*)GetProcAddress((handle),(name)))
35
+ # define RTLD_LAZY -1
36
+ # define RTLD_NOW -1
37
+ # define RTLD_GLOBAL -1
38
+ # endif
39
+ #endif
40
+
41
+ #define lapack_complex_float scomplex
42
+ #define lapack_complex_double dcomplex
43
+ #include "lapacke.h"
44
+ #include "lapacke_t.h"
45
+
46
+ static void *lapack_handle = 0;
47
+ static char *lapack_prefix = 0;
48
+
49
+
50
+ VALUE
51
+ numo_lapacke_option_value(VALUE value, VALUE default_value)
52
+ {
53
+ switch(TYPE(value)) {
54
+ case T_NIL:
55
+ case T_UNDEF:
56
+ return default_value;
57
+ }
58
+ return value;
59
+ }
60
+
61
+ int
62
+ numo_lapacke_option_order(VALUE order)
63
+ {
64
+ int opt;
65
+ char *ptr;
66
+
67
+ switch(TYPE(order)) {
68
+ case T_NIL:
69
+ case T_UNDEF:
70
+ case T_FALSE:
71
+ return LAPACK_ROW_MAJOR;
72
+ case T_TRUE:
73
+ return LAPACK_COL_MAJOR;
74
+ case T_FIXNUM:
75
+ opt = FIX2INT(order);
76
+ if (opt == LAPACK_ROW_MAJOR || opt == LAPACK_COL_MAJOR) {
77
+ return opt;
78
+ }
79
+ break;
80
+ case T_SYMBOL:
81
+ order = rb_sym2str(order);
82
+ case T_STRING:
83
+ ptr = RSTRING_PTR(order);
84
+ if (RSTRING_LEN(order) > 0) {
85
+ switch(ptr[0]){
86
+ case 'R': case 'r':
87
+ return LAPACK_ROW_MAJOR;
88
+ case 'C': case 'c':
89
+ return LAPACK_COL_MAJOR;
90
+ }
91
+ }
92
+ break;
93
+ }
94
+ rb_raise(rb_eArgError,"invalid value for LAPACKE_ORDER");
95
+ return 0;
96
+ }
97
+
98
+ char
99
+ numo_lapacke_option_job(VALUE job, char true_char, char false_char)
100
+ {
101
+ char *ptr, c;
102
+
103
+ switch(TYPE(job)) {
104
+ case T_NIL:
105
+ case T_UNDEF:
106
+ case T_TRUE:
107
+ return true_char;
108
+ case T_FALSE:
109
+ return false_char;
110
+ case T_SYMBOL:
111
+ job = rb_sym2str(job);
112
+ case T_STRING:
113
+ ptr = RSTRING_PTR(job);
114
+ if (RSTRING_LEN(job) > 0) {
115
+ c = ptr[0];
116
+ if (c >= 'a' && c <= 'z') {
117
+ c -= 'a'-'A';
118
+ }
119
+ return c;
120
+ }
121
+ break;
122
+ }
123
+ rb_raise(rb_eArgError,"invalid value for JOB option");
124
+ return 0;
125
+ }
126
+
127
+ char
128
+ numo_lapacke_option_trans(VALUE trans)
129
+ {
130
+ int opt;
131
+ char *ptr;
132
+
133
+ switch(TYPE(trans)) {
134
+ case T_NIL:
135
+ case T_UNDEF:
136
+ case T_FALSE:
137
+ return 'N';
138
+ case T_TRUE:
139
+ return 'T';
140
+ case T_FIXNUM:
141
+ opt = FIX2INT(trans);
142
+ if (opt >= 'N' && opt <= 'C') {
143
+ return opt;
144
+ }
145
+ break;
146
+ case T_SYMBOL:
147
+ trans = rb_sym2str(trans);
148
+ case T_STRING:
149
+ ptr = RSTRING_PTR(trans);
150
+ if (RSTRING_LEN(trans) > 0) {
151
+ switch(ptr[0]){
152
+ case 'N': case 'n':
153
+ return 'N';
154
+ case 'T': case 't':
155
+ return 'T';
156
+ case 'C': case 'c':
157
+ return 'C';
158
+ }
159
+ }
160
+ break;
161
+ }
162
+ rb_raise(rb_eArgError,"invalid value for LAPACKE_TRANSPOSE");
163
+ return 0;
164
+ }
165
+
166
+ char
167
+ numo_lapacke_option_uplo(VALUE uplo)
168
+ {
169
+ int opt;
170
+ char *ptr;
171
+
172
+ switch(TYPE(uplo)) {
173
+ case T_NIL:
174
+ case T_UNDEF:
175
+ case T_TRUE:
176
+ return 'U';
177
+ case T_FALSE:
178
+ return 'L';
179
+ case T_FIXNUM:
180
+ opt = FIX2INT(uplo);
181
+ switch(opt){
182
+ case 'U':
183
+ case 'L':
184
+ return opt;
185
+ }
186
+ break;
187
+ case T_SYMBOL:
188
+ uplo = rb_sym2str(uplo);
189
+ case T_STRING:
190
+ ptr = RSTRING_PTR(uplo);
191
+ if (RSTRING_LEN(uplo) > 0) {
192
+ switch(ptr[0]){
193
+ case 'U': case 'u':
194
+ return 'U';
195
+ case 'L': case 'l':
196
+ return 'L';
197
+ }
198
+ }
199
+ break;
200
+ }
201
+ rb_raise(rb_eArgError,"invalid value for LAPACKE_UPLO");
202
+ return 0;
203
+ }
204
+
205
+ char
206
+ numo_lapacke_option_diag(VALUE diag)
207
+ {
208
+ int opt;
209
+ char *ptr;
210
+
211
+ switch(TYPE(diag)) {
212
+ case T_NIL:
213
+ case T_FALSE:
214
+ case T_UNDEF:
215
+ return 'N';
216
+ case T_TRUE:
217
+ return 'U';
218
+ case T_FIXNUM:
219
+ opt = FIX2INT(diag);
220
+ switch(opt){
221
+ case 'N':
222
+ case 'U':
223
+ return opt;
224
+ }
225
+ break;
226
+ case T_SYMBOL:
227
+ diag = rb_sym2str(diag);
228
+ case T_STRING:
229
+ ptr = RSTRING_PTR(diag);
230
+ if (RSTRING_LEN(diag) > 0) {
231
+ switch(ptr[0]){
232
+ case 'N': case 'n':
233
+ return 'N';
234
+ case 'U': case 'u':
235
+ return 'U';
236
+ }
237
+ }
238
+ break;
239
+ }
240
+ rb_raise(rb_eArgError,"invalid value for LAPACKE_DIAG");
241
+ return 0;
242
+ }
243
+
244
+ char
245
+ numo_lapacke_option_side(VALUE side)
246
+ {
247
+ int opt;
248
+ char *ptr;
249
+
250
+ switch(TYPE(side)) {
251
+ case T_NIL:
252
+ case T_UNDEF:
253
+ case T_FALSE:
254
+ return 'L';
255
+ case T_TRUE:
256
+ return 'R';
257
+ case T_FIXNUM:
258
+ opt = FIX2INT(side);
259
+ switch(opt){
260
+ case 'L':
261
+ case 'R':
262
+ return opt;
263
+ }
264
+ break;
265
+ case T_SYMBOL:
266
+ side = rb_sym2str(side);
267
+ case T_STRING:
268
+ ptr = RSTRING_PTR(side);
269
+ if (RSTRING_LEN(side) > 0) {
270
+ switch(ptr[0]){
271
+ case 'L': case 'l':
272
+ return 'L';
273
+ case 'R': case 'r':
274
+ return 'R';
275
+ }
276
+ }
277
+ break;
278
+ }
279
+ rb_raise(rb_eArgError,"invalid value for LAPACKE_SIDE");
280
+ return 0;
281
+ }
282
+
283
+ void
284
+ numo_lapacke_check_func(void **func, const char *name)
285
+ {
286
+ char *s, *error;
287
+
288
+ if (*func==0) {
289
+ if (lapack_handle==0) {
290
+ rb_raise(rb_eRuntimeError,"LAPACK library is not loaded");
291
+ }
292
+ if (lapack_prefix==0) {
293
+ rb_raise(rb_eRuntimeError,"LAPACKE prefix is not set");
294
+ }
295
+ s = alloca(strlen(lapack_prefix)+strlen(name)+1);
296
+ strcpy(s,lapack_prefix);
297
+ strcat(s,name);
298
+ dlerror();
299
+ *func = dlsym(lapack_handle, s);
300
+ error = dlerror();
301
+ if (error != NULL) {
302
+ rb_raise(rb_eRuntimeError, "%s", error);
303
+ }
304
+ }
305
+ }
306
+
307
+ /*
308
+ module definition: Numo::Linalg
309
+ */
310
+ static VALUE mLinalg;
311
+
312
+ /*
313
+ module definition: Numo::Linalg::Lapack
314
+ */
315
+ static VALUE mLapack;
316
+
317
+
318
+ static VALUE
319
+ lapack_s_dlopen(int argc, VALUE *argv, VALUE mod)
320
+ {
321
+ int i, f;
322
+ VALUE lib, flag;
323
+ char *error;
324
+ void *handle;
325
+
326
+ i = rb_scan_args(argc, argv, "11", &lib, &flag);
327
+ if (i==2) {
328
+ f = NUM2INT(flag);
329
+ } else {
330
+ f = RTLD_LAZY | RTLD_LOCAL;
331
+ }
332
+ dlerror();
333
+ handle = dlopen(StringValueCStr(lib), f);
334
+ error = dlerror();
335
+ if (error != NULL) {
336
+ rb_raise(rb_eRuntimeError, "%s", error);
337
+ }
338
+ lapack_handle = handle;
339
+ return Qnil;
340
+ }
341
+
342
+ static VALUE
343
+ lapack_s_prefix_set(VALUE mod, VALUE prefix)
344
+ {
345
+ long len;
346
+
347
+ if (TYPE(prefix) != T_STRING) {
348
+ rb_raise(rb_eTypeError,"argument must be string");
349
+ }
350
+ if (lapack_prefix) {
351
+ free(lapack_prefix);
352
+ }
353
+ len = RSTRING_LEN(prefix);
354
+ lapack_prefix = malloc(len+1);
355
+ strcpy(lapack_prefix, StringValueCStr(prefix));
356
+ return prefix;
357
+ }
358
+
359
+
360
+ void Init_numo_linalg_lapack_s();
361
+ void Init_numo_linalg_lapack_d();
362
+ void Init_numo_linalg_lapack_c();
363
+ void Init_numo_linalg_lapack_z();
364
+
365
+ void
366
+ Init_lapack(void)
367
+ {
368
+ VALUE mN;
369
+
370
+ mN = rb_define_module("Numo");
371
+ /*
372
+ Document-module: Numo::Linalg
373
+ */
374
+ mLinalg = rb_define_module_under(mN, "Linalg");
375
+ mLapack = rb_define_module_under(mLinalg, "Lapack");
376
+
377
+ rb_define_module_function(mLapack, "dlopen", lapack_s_dlopen, -1);
378
+ rb_define_module_function(mLapack, "prefix=", lapack_s_prefix_set, 1);
379
+
380
+ lapack_prefix = malloc(strlen("LAPACKE_")+1); // default prefix
381
+ strcpy(lapack_prefix,"LAPACKE_");
382
+
383
+ Init_numo_linalg_lapack_s();
384
+ Init_numo_linalg_lapack_d();
385
+ Init_numo_linalg_lapack_c();
386
+ Init_numo_linalg_lapack_z();
387
+ }