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
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a5f5428ade2504c871f78f77e76a74efaad30853
4
+ data.tar.gz: 002524df9a6acb2c6701c234cc4216fde88a7e2e
5
+ SHA512:
6
+ metadata.gz: dfb994654259edc522233e5196bf461797fa0aa9d552e7530c3657da826c3e1ad8ca280e9fade6b3413bc961c81c39ce86314e31f2c37b7d3a282e476611fe49
7
+ data.tar.gz: 1ec749584936a93a62717aa9073cd1b391d3fd64b9858b28fcefd3973c4f0c63cb2fe9ba429ed30e492ecff8af7d183aa35029bd9e9c06be3eaf82ff3f9ad597
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in narray-devel.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # Numo::Linalg : Linear Algebra library with BLAS/LAPACK binding to Numo::NArray
2
+
3
+ [![Binder](http://mybinder.org/badge.svg)](http://mybinder.org/repo/ruby-numo/linalg)
4
+ [![Build Status](https://travis-ci.org/ruby-numo/linalg.svg?branch=master)](https://travis-ci.org/ruby-numo/linalg)
5
+
6
+ [GitHub](https://github.com/ruby-numo/linalg)
7
+
8
+ Under development!
9
+
10
+ ## Introduction
11
+
12
+ This is a binding of BLAS/LAPACK for Numo::NArray using dynamic linking loader.
13
+ This desgin allows you to change backend libraries without re-compiling.
14
+
15
+ ### [Numo::Linalg API](http://ruby-numo.github.io/linalg/yard/Numo/Linalg.html)
16
+
17
+ * Matrix and vector products
18
+ * dot, matmul
19
+ * Decomposition
20
+ * lu\_fact, lu\_inv, lu\_solve, cho\_fact, cho\_inv, cho\_solve
21
+ qr, svd, svdvals
22
+ * Matrix eigenvalues
23
+ * eig, eigh, eigvals, eigvalsh
24
+ * Norms and other numbers
25
+ * norm, cond, det, slogdet, matrix\_rank, matrix\_power
26
+ * Solving equations and inverting matrices
27
+ * solve, lstsq, inv, pinv
28
+
29
+ ### Low-level modules
30
+
31
+ * [Numo::Linalg::Blas](http://ruby-numo.github.io/linalg/yard/Numo/Linalg/Blas.html) - Low-level BLAS functions
32
+ * [Numo::Linalg::Lapack](http://ruby-numo.github.io/linalg/yard/Numo/Linalg/Lapack.html) - Low-level LAPACK functions
33
+
34
+ ## Installation
35
+
36
+ * Install [Numo::NArray](https://github.com/ruby-numo/narray)
37
+
38
+ * Install [LAPACK](http://www.netlib.org/lapack/) or alternative package.
39
+
40
+ * Numo::Linalg requires C-interface
41
+ [CBLAS](http://www.netlib.org/blas/#_cblas) and
42
+ [LAPACKE](http://www.netlib.org/lapack/lapacke.html) interface.
43
+ These are included in LAPACK package.
44
+
45
+ * Recommended: use one of following faster libraries:
46
+ * [ATLAS](https://sourceforge.net/projects/math-atlas/)
47
+ * [OpenBLAS](http://www.openblas.net/)
48
+ * [Intel MKL](https://software.intel.com/intel-mkl)
49
+
50
+ * Note that the performance depends on the backend library as shown in
51
+ [benchmark](https://github.com/ruby-numo/linalg/tree/master/bench).
52
+
53
+ * Install Numo::Linalg
54
+
55
+ ```shell
56
+ $ gem install numo-linalg
57
+ ```
58
+
59
+ or
60
+
61
+ ```shell
62
+ $ git clone https://github.com/ruby-numo/linalg.git
63
+ $ cd linalg
64
+ $ rake build
65
+ $ gem install pkg/numo-linalg-*.gem
66
+ ```
67
+
68
+ * Read also instruction for [Selecting Backend Library](https://github.com/ruby-numo/linalg/tree/master/doc/select-backend.md).
69
+
70
+ ## Authors
71
+
72
+ * Masahiro TANAKA
73
+ * Makoto KISHIMOTO
74
+ * This work is partly supported by 2016 Ruby Association Grant.
75
+
76
+ ## ToDo
77
+
78
+ * More functions
79
+ * write test
80
+ * Documentation
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ task :doc do
4
+ srcs = []
5
+ Dir.glob("ext/numo/linalg/*").each do |d|
6
+ if File.exist?(d+"/extconf.rb")
7
+ sh "cd #{d}; ruby extconf.rb; make clean; make src"
8
+ srcs << d+"/*.c"
9
+ end
10
+ end
11
+ srcs << "lib/numo/linalg.rb"
12
+ srcs << "lib/numo/linalg/*.rb"
13
+ sh "yard -m markdown -o yard -r README.md #{srcs.join(' ')}"
14
+ end
15
+
16
+ task :cleandoc do
17
+ sh "rm -r yard .yardoc"
18
+ end
@@ -0,0 +1,352 @@
1
+ /*
2
+ blas.c
3
+ BLAS wrapper for Ruby/Numo
4
+ (C) Copyright 2017 by Masahiro TANAKA
5
+
6
+ This program is free software.
7
+ NO WARRANTY.
8
+ */
9
+ #include <assert.h>
10
+ #include <ruby.h>
11
+ #include "numo/narray.h"
12
+ #include "numo/template.h"
13
+ #include "cblas.h"
14
+
15
+ // from ruby/ext/fiddle/fiddle.h
16
+ #if defined(HAVE_DLFCN_H)
17
+ # include <dlfcn.h>
18
+ # /* some stranger systems may not define all of these */
19
+ #ifndef RTLD_LAZY
20
+ #define RTLD_LAZY 0
21
+ #endif
22
+ #ifndef RTLD_GLOBAL
23
+ #define RTLD_GLOBAL 0
24
+ #endif
25
+ #ifndef RTLD_NOW
26
+ #define RTLD_NOW 0
27
+ #endif
28
+ #else
29
+ # if defined(_WIN32)
30
+ # include <windows.h>
31
+ # define dlopen(name,flag) ((void*)LoadLibrary(name))
32
+ # define dlerror() strerror(rb_w32_map_errno(GetLastError()))
33
+ # define dlsym(handle,name) ((void*)GetProcAddress((handle),(name)))
34
+ # define RTLD_LAZY -1
35
+ # define RTLD_NOW -1
36
+ # define RTLD_GLOBAL -1
37
+ # endif
38
+ #endif
39
+
40
+ static void *blas_handle = 0;
41
+ static char *blas_prefix = 0;
42
+
43
+ VALUE
44
+ numo_cblas_option_value(VALUE order, VALUE default_value)
45
+ {
46
+ switch(TYPE(order)) {
47
+ case T_NIL:
48
+ case T_UNDEF:
49
+ return default_value;
50
+ }
51
+ return order;
52
+ }
53
+
54
+ enum CBLAS_ORDER
55
+ numo_cblas_option_order(VALUE order)
56
+ {
57
+ int opt;
58
+ char *ptr;
59
+
60
+ switch(TYPE(order)) {
61
+ case T_NIL:
62
+ case T_UNDEF:
63
+ case T_FALSE:
64
+ return CblasRowMajor;
65
+ case T_TRUE:
66
+ return CblasColMajor;
67
+ case T_FIXNUM:
68
+ opt = FIX2INT(order);
69
+ if (opt >= CblasRowMajor && opt <= CblasColMajor) {
70
+ return opt;
71
+ }
72
+ break;
73
+ case T_SYMBOL:
74
+ order = rb_sym2str(order);
75
+ case T_STRING:
76
+ ptr = RSTRING_PTR(order);
77
+ if (RSTRING_LEN(order) > 0) {
78
+ switch(ptr[0]){
79
+ case 'R': case 'r':
80
+ return CblasRowMajor;
81
+ case 'C': case 'c':
82
+ return CblasColMajor;
83
+ }
84
+ }
85
+ break;
86
+ }
87
+ rb_raise(rb_eArgError,"invalid value for CBLAS_ORDER");
88
+ return 0;
89
+ }
90
+
91
+ enum CBLAS_TRANSPOSE
92
+ numo_cblas_option_trans(VALUE trans)
93
+ {
94
+ int opt;
95
+ char *ptr;
96
+
97
+ switch(TYPE(trans)) {
98
+ case T_NIL:
99
+ case T_UNDEF:
100
+ case T_FALSE:
101
+ return CblasNoTrans;
102
+ case T_TRUE:
103
+ return CblasTrans;
104
+ case T_FIXNUM:
105
+ opt = FIX2INT(trans);
106
+ if (opt >= CblasNoTrans && opt <= CblasConjTrans) {
107
+ return opt;
108
+ }
109
+ break;
110
+ case T_SYMBOL:
111
+ trans = rb_sym2str(trans);
112
+ case T_STRING:
113
+ ptr = RSTRING_PTR(trans);
114
+ if (RSTRING_LEN(trans) > 0) {
115
+ switch(ptr[0]){
116
+ case 'N': case 'n':
117
+ return CblasNoTrans;
118
+ case 'T': case 't':
119
+ return CblasTrans;
120
+ case 'C': case 'c':
121
+ return CblasConjTrans;
122
+ }
123
+ }
124
+ break;
125
+ }
126
+ rb_raise(rb_eArgError,"invalid value for CBLAS_TRANSPOSE");
127
+ return 0;
128
+ }
129
+
130
+ enum CBLAS_UPLO
131
+ numo_cblas_option_uplo(VALUE uplo)
132
+ {
133
+ int opt;
134
+ char *ptr;
135
+
136
+ switch(TYPE(uplo)) {
137
+ case T_NIL:
138
+ case T_UNDEF:
139
+ case T_FALSE:
140
+ return CblasUpper;
141
+ case T_TRUE:
142
+ return CblasLower;
143
+ case T_FIXNUM:
144
+ opt = FIX2INT(uplo);
145
+ switch(opt){
146
+ case CblasUpper:
147
+ case CblasLower:
148
+ return opt;
149
+ }
150
+ break;
151
+ case T_SYMBOL:
152
+ uplo = rb_sym2str(uplo);
153
+ case T_STRING:
154
+ ptr = RSTRING_PTR(uplo);
155
+ if (RSTRING_LEN(uplo) > 0) {
156
+ switch(ptr[0]){
157
+ case 'U': case 'u':
158
+ return CblasUpper;
159
+ case 'L': case 'l':
160
+ return CblasLower;
161
+ }
162
+ }
163
+ break;
164
+ }
165
+ rb_raise(rb_eArgError,"invalid value for CBLAS_UPLO");
166
+ return 0;
167
+ }
168
+
169
+ enum CBLAS_DIAG
170
+ numo_cblas_option_diag(VALUE diag)
171
+ {
172
+ int opt;
173
+ char *ptr;
174
+
175
+ switch(TYPE(diag)) {
176
+ case T_NIL:
177
+ case T_UNDEF:
178
+ case T_FALSE:
179
+ return CblasNonUnit;
180
+ case T_TRUE:
181
+ return CblasUnit;
182
+ case T_FIXNUM:
183
+ opt = FIX2INT(diag);
184
+ switch(opt){
185
+ case CblasNonUnit:
186
+ case CblasUnit:
187
+ return opt;
188
+ }
189
+ break;
190
+ case T_SYMBOL:
191
+ diag = rb_sym2str(diag);
192
+ case T_STRING:
193
+ ptr = RSTRING_PTR(diag);
194
+ if (RSTRING_LEN(diag) > 0) {
195
+ switch(ptr[0]){
196
+ case 'N': case 'n':
197
+ return CblasNonUnit;
198
+ case 'U': case 'u':
199
+ return CblasUnit;
200
+ }
201
+ }
202
+ break;
203
+ }
204
+ rb_raise(rb_eArgError,"invalid value for CBLAS_DIAG");
205
+ return 0;
206
+ }
207
+
208
+ enum CBLAS_SIDE
209
+ numo_cblas_option_side(VALUE side)
210
+ {
211
+ int opt;
212
+ char *ptr;
213
+
214
+ switch(TYPE(side)) {
215
+ case T_NIL:
216
+ case T_UNDEF:
217
+ case T_FALSE:
218
+ return CblasLeft;
219
+ case T_TRUE:
220
+ return CblasRight;
221
+ case T_FIXNUM:
222
+ opt = FIX2INT(side);
223
+ switch(opt){
224
+ case CblasLeft:
225
+ case CblasRight:
226
+ return opt;
227
+ }
228
+ break;
229
+ case T_SYMBOL:
230
+ side = rb_sym2str(side);
231
+ case T_STRING:
232
+ ptr = RSTRING_PTR(side);
233
+ if (RSTRING_LEN(side) > 0) {
234
+ switch(ptr[0]){
235
+ case 'L': case 'l':
236
+ return CblasLeft;
237
+ case 'R': case 'r':
238
+ return CblasRight;
239
+ }
240
+ }
241
+ break;
242
+ }
243
+ rb_raise(rb_eArgError,"invalid value for CBLAS_SIDE");
244
+ return 0;
245
+ }
246
+
247
+ void
248
+ numo_cblas_check_func(void **func, const char *name)
249
+ {
250
+ char *s, *error;
251
+
252
+ if (*func==0) {
253
+ if (blas_handle==0) {
254
+ rb_raise(rb_eRuntimeError,"BLAS library is not loaded");
255
+ }
256
+ if (blas_prefix==0) {
257
+ rb_raise(rb_eRuntimeError,"CBLAS prefix is not set");
258
+ }
259
+ s = alloca(strlen(blas_prefix)+strlen(name)+1);
260
+ strcpy(s,blas_prefix);
261
+ strcat(s,name);
262
+ dlerror();
263
+ *func = dlsym(blas_handle, s);
264
+ error = dlerror();
265
+ if (error != NULL) {
266
+ rb_raise(rb_eRuntimeError, "%s", error);
267
+ }
268
+ }
269
+ }
270
+
271
+ /*
272
+ module definition: Numo::Linalg
273
+ */
274
+ static VALUE mLinalg;
275
+
276
+ /*
277
+ module definition: Numo::Linalg::Blas
278
+ */
279
+ static VALUE mBlas;
280
+
281
+
282
+ static VALUE
283
+ blas_s_dlopen(int argc, VALUE *argv, VALUE mod)
284
+ {
285
+ int i, f;
286
+ VALUE lib, flag;
287
+ char *error;
288
+ void *handle;
289
+
290
+ i = rb_scan_args(argc, argv, "11", &lib, &flag);
291
+ if (i==2) {
292
+ f = NUM2INT(flag);
293
+ } else {
294
+ f = RTLD_LAZY | RTLD_LOCAL;
295
+ }
296
+ dlerror();
297
+ handle = dlopen(StringValueCStr(lib), f);
298
+ error = dlerror();
299
+ if (error != NULL) {
300
+ rb_raise(rb_eRuntimeError, "%s", error);
301
+ }
302
+ blas_handle = handle;
303
+ return Qnil;
304
+ }
305
+
306
+
307
+ static VALUE
308
+ blas_s_prefix_set(VALUE mod, VALUE prefix)
309
+ {
310
+ long len;
311
+
312
+ if (TYPE(prefix) != T_STRING) {
313
+ rb_raise(rb_eTypeError,"argument must be string");
314
+ }
315
+ if (blas_prefix) {
316
+ free(blas_prefix);
317
+ }
318
+ len = RSTRING_LEN(prefix);
319
+ blas_prefix = malloc(len+1);
320
+ strcpy(blas_prefix, StringValueCStr(prefix));
321
+ return prefix;
322
+ }
323
+
324
+
325
+ void Init_numo_linalg_blas_s();
326
+ void Init_numo_linalg_blas_d();
327
+ void Init_numo_linalg_blas_c();
328
+ void Init_numo_linalg_blas_z();
329
+
330
+ void
331
+ Init_blas(void)
332
+ {
333
+ VALUE mN;
334
+
335
+ mN = rb_define_module("Numo");
336
+ /*
337
+ Document-module: Numo::Linalg
338
+ */
339
+ mLinalg = rb_define_module_under(mN, "Linalg");
340
+ mBlas = rb_define_module_under(mLinalg, "Blas");
341
+
342
+ rb_define_module_function(mBlas, "dlopen", blas_s_dlopen, -1);
343
+ rb_define_module_function(mBlas, "prefix=", blas_s_prefix_set, 1);
344
+
345
+ blas_prefix = malloc(strlen("cblas_")+1); // default prefix
346
+ strcpy(blas_prefix,"cblas_");
347
+
348
+ Init_numo_linalg_blas_s();
349
+ Init_numo_linalg_blas_d();
350
+ Init_numo_linalg_blas_c();
351
+ Init_numo_linalg_blas_z();
352
+ }