numo-linalg 0.0.1

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 (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
+ }