numo-linalg-alt 0.5.0 → 0.6.0

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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/README.md +47 -5
  4. data/ext/numo/linalg/blas/blas_common.h +30 -0
  5. data/ext/numo/linalg/blas/blas_util.c +39 -0
  6. data/ext/numo/linalg/blas/blas_util.h +11 -0
  7. data/ext/numo/linalg/{converter.h → blas/converter.h} +0 -2
  8. data/ext/numo/linalg/blas/dot.c +1 -1
  9. data/ext/numo/linalg/blas/dot.h +1 -6
  10. data/ext/numo/linalg/blas/dot_sub.c +1 -1
  11. data/ext/numo/linalg/blas/dot_sub.h +1 -6
  12. data/ext/numo/linalg/blas/gemm.c +21 -21
  13. data/ext/numo/linalg/blas/gemm.h +3 -9
  14. data/ext/numo/linalg/blas/gemv.c +10 -10
  15. data/ext/numo/linalg/blas/gemv.h +3 -9
  16. data/ext/numo/linalg/blas/nrm2.c +1 -1
  17. data/ext/numo/linalg/blas/nrm2.h +1 -6
  18. data/ext/numo/linalg/extconf.rb +33 -6
  19. data/ext/numo/linalg/lapack/gebal.h +1 -1
  20. data/ext/numo/linalg/lapack/gees.c +4 -4
  21. data/ext/numo/linalg/lapack/gees.h +1 -1
  22. data/ext/numo/linalg/lapack/geev.c +8 -24
  23. data/ext/numo/linalg/lapack/geev.h +1 -1
  24. data/ext/numo/linalg/lapack/gehrd.h +1 -1
  25. data/ext/numo/linalg/lapack/gelsd.h +1 -1
  26. data/ext/numo/linalg/lapack/geqrf.h +1 -1
  27. data/ext/numo/linalg/lapack/gerqf.h +1 -1
  28. data/ext/numo/linalg/lapack/gesdd.h +1 -1
  29. data/ext/numo/linalg/lapack/gesv.h +1 -1
  30. data/ext/numo/linalg/lapack/gesvd.h +1 -1
  31. data/ext/numo/linalg/lapack/getrf.h +1 -1
  32. data/ext/numo/linalg/lapack/getri.h +1 -1
  33. data/ext/numo/linalg/lapack/getrs.h +1 -1
  34. data/ext/numo/linalg/lapack/gges.c +4 -4
  35. data/ext/numo/linalg/lapack/gges.h +1 -1
  36. data/ext/numo/linalg/lapack/heev.c +1 -1
  37. data/ext/numo/linalg/lapack/heev.h +1 -1
  38. data/ext/numo/linalg/lapack/heevd.c +1 -1
  39. data/ext/numo/linalg/lapack/heevd.h +1 -1
  40. data/ext/numo/linalg/lapack/heevr.c +1 -1
  41. data/ext/numo/linalg/lapack/heevr.h +1 -1
  42. data/ext/numo/linalg/lapack/hegv.c +1 -1
  43. data/ext/numo/linalg/lapack/hegv.h +1 -1
  44. data/ext/numo/linalg/lapack/hegvd.c +1 -1
  45. data/ext/numo/linalg/lapack/hegvd.h +1 -1
  46. data/ext/numo/linalg/lapack/hegvx.c +1 -1
  47. data/ext/numo/linalg/lapack/hegvx.h +1 -1
  48. data/ext/numo/linalg/lapack/hetrf.h +1 -1
  49. data/ext/numo/linalg/lapack/lange.h +1 -1
  50. data/ext/numo/linalg/lapack/lapack_util.c +57 -0
  51. data/ext/numo/linalg/lapack/lapack_util.h +27 -0
  52. data/ext/numo/linalg/lapack/orghr.h +1 -1
  53. data/ext/numo/linalg/lapack/orgqr.h +1 -1
  54. data/ext/numo/linalg/lapack/orgrq.h +1 -1
  55. data/ext/numo/linalg/lapack/potrf.h +1 -1
  56. data/ext/numo/linalg/lapack/potri.h +1 -1
  57. data/ext/numo/linalg/lapack/potrs.h +1 -1
  58. data/ext/numo/linalg/lapack/syev.c +1 -1
  59. data/ext/numo/linalg/lapack/syev.h +1 -1
  60. data/ext/numo/linalg/lapack/syevd.c +1 -1
  61. data/ext/numo/linalg/lapack/syevd.h +1 -1
  62. data/ext/numo/linalg/lapack/syevr.c +1 -1
  63. data/ext/numo/linalg/lapack/syevr.h +1 -1
  64. data/ext/numo/linalg/lapack/sygv.c +1 -1
  65. data/ext/numo/linalg/lapack/sygv.h +1 -1
  66. data/ext/numo/linalg/lapack/sygvd.c +1 -1
  67. data/ext/numo/linalg/lapack/sygvd.h +1 -1
  68. data/ext/numo/linalg/lapack/sygvx.c +1 -1
  69. data/ext/numo/linalg/lapack/sygvx.h +1 -1
  70. data/ext/numo/linalg/lapack/sytrf.h +1 -1
  71. data/ext/numo/linalg/lapack/trtrs.h +1 -1
  72. data/ext/numo/linalg/lapack/unghr.h +1 -1
  73. data/ext/numo/linalg/lapack/ungqr.h +1 -1
  74. data/ext/numo/linalg/lapack/ungrq.h +1 -1
  75. data/ext/numo/linalg/linalg.c +2 -0
  76. data/ext/numo/linalg/linalg.h +14 -6
  77. data/lib/numo/linalg/version.rb +1 -1
  78. data/lib/numo/linalg.rb +68 -20
  79. metadata +9 -6
  80. data/ext/numo/linalg/util.c +0 -103
  81. data/ext/numo/linalg/util.h +0 -18
  82. /data/ext/numo/linalg/{converter.c → blas/converter.c} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 25f768b7f68b0526d390891b70e65e41ef16ef61a31614100c53250bb3d29baa
4
- data.tar.gz: ebeb6d483949b617d5567f0265b2cd2cdee992fe8494006875595aa2dbb80adf
3
+ metadata.gz: 94dfd3c199541e6dc2b71968e11450af79613c6dba382c3ac0cd64541f2d8461
4
+ data.tar.gz: 9a7bc15d245eeb94a97c524a474f10345b78a7693ab766b0cbea3353791e22b1
5
5
  SHA512:
6
- metadata.gz: bba4f496a60bd9fe7aad51f07c6123855d8cbf4c1f1d2d4bb2858482c8ad3daeea5de8425176b242c5d84376874a0d0f93e80e46b0e39a2ff671721acb083fb3
7
- data.tar.gz: 40d7100c495cad8021d5678ba1a0a3a3a9bdcfb53262e985234c653d207270c5d88f4a8d67ae8d00caab578f94142b1bdae198cf5ee3799cfc997f55486525cc
6
+ metadata.gz: 2cc8b7019527b642d0827f3f1b1943e7f16889ec83af93c8ba85b6b2209f6fb17c33b457c362679ea296f48b64c6bc03811b2bb6f4ace28d9a859d18d049fcea
7
+ data.tar.gz: d68a26e612d144410100b56706157ef7434a6844c96d4540748cb08ebbe11843445de84667c9406e591274f3622e72f4176231f9af979a3782893b72fbd5abc7
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [[0.6.0](https://github.com/yoshoku/numo-linalg-alt/compare/v0.5.0...v0.6.0)] - 2025-11-02
2
+
3
+ - add `--with-blas` and `--with-lapacke` options for selecting backend libraries.
4
+ - add `logm`, `sqrtm`, and `signm` module functions to Numo::Linalg.
5
+ - add error handling for LAPACK functions such as gesv, getri, and potrs.
6
+ - FIX: ensure pinv returns contiguous array instead of NArray's view.
7
+
1
8
  ## [[0.5.0](https://github.com/yoshoku/numo-linalg-alt/compare/v0.4.1...v0.5.0)] - 2025-10-25
2
9
 
3
10
  - FIX: correct Numo::Linalg::Lapack.xlange return type to Float for Numo::DComplex and Numo::SComplex.
data/README.md CHANGED
@@ -7,18 +7,19 @@
7
7
 
8
8
  Numo::Linalg Alternative (numo-linalg-alt) is an alternative to [Numo::Linalg](https://github.com/ruby-numo/numo-linalg).
9
9
  Unlike Numo::Linalg, numo-linalg-alt depends on [Numo::NArray Alterntive](https://github.com/yoshoku/numo-narray-alt).
10
-
11
10
  Please note that this gem was forked from [Numo::TinyLinalg](https://github.com/yoshoku/numo-tiny_linalg),
12
- not Numo::Linalg, and therefore it does not support changing backend libraries for BLAS and LAPACK.
13
- In addition, the version numbering rule is not compatible with that of Numo::Linalg.
11
+ not Numo::Linalg, so its version numbering rule is not compatible with that of Numo::Linalg.
14
12
 
15
13
  The project owner has the utmost respect for Numo::Linalg and its creator, Prof. [Masahiro Tanaka](https://github.com/masa16).
16
14
  This project is in no way intended to adversely affect the development of the original Numo::Linalg.
17
15
 
18
16
  ## Installation
19
17
 
20
- Unlike Numo::Linalg, numo-linalg-alt only supports [OpenBLAS](https://github.com/OpenMathLib/OpenBLAS)
21
- as a backend library.
18
+ numo-linalg-alt uses [OpenBLAS](https://github.com/OpenMathLib/OpenBLAS) as the default backend library.
19
+ If BLAS/LAPACKE-related libraries and include files are not found during installation,
20
+ the gem will automatically download and build OpenBLAS from source.
21
+ This process can significantly increase installation time,
22
+ so pre-installing OpenBLAS is recommended.
22
23
 
23
24
  Install the OpenBLAS.
24
25
 
@@ -63,6 +64,47 @@ Ubuntu:
63
64
  $ gem install numo-linalg-alt
64
65
  ```
65
66
 
67
+ ### Using alternative backend libraries
68
+
69
+ The `--with-blas` and `--with-lapacke` options allow you to specify which BLAS/LAPACKE libraries
70
+ to use as the backend. The following instructions are intended for Ubuntu.
71
+
72
+ #### BLIS
73
+
74
+ Install the BLIS:
75
+
76
+ ```sh
77
+ $ sudo apt-get install libblis-dev liblapacke-dev
78
+ ```
79
+
80
+ To use BLIS as the BLAS library, execute the following gem command.
81
+ The `--with-lapacke` option is not required as LAPACKE is automatically selected.
82
+
83
+ ```sh
84
+ $ gem install numo-linalg-alt -- --with-blas=blis
85
+ ```
86
+
87
+ #### Intel MKL
88
+
89
+ Install the Intel MKL:
90
+
91
+ ```sh
92
+ sudo apt-get install intel-mkl
93
+ ```
94
+
95
+ Run the following command to use Intel MKL's `mkl_lapacke.h` as `lapacke.h`:
96
+
97
+ ```sh
98
+ sudo update-alternatives --install /usr/include/x86_64-linux-gnu/lapacke.h lapacke.h-x86_64-linux-gnu /usr/include/mkl/mkl_lapacke.h 10
99
+ ```
100
+
101
+ To use Intel MKL as the BLAS/LAPACKE libraries, execute the following gem command.
102
+ The `--with-lapacke` option is not required as the `mkl_rt` library includes LAPACKE functions.
103
+
104
+ ```sh
105
+ $ gem install numo-linalg-alt -- --with-blas=mkl_rt
106
+ ```
107
+
66
108
  ## Documentation
67
109
 
68
110
  - [API Documentation](https://gemdocs.org/gems/numo-linalg-alt/0.4.1/)
@@ -0,0 +1,30 @@
1
+ #ifndef NUMO_LINALG_ALT_BLAS_COMMON_H
2
+ #define NUMO_LINALG_ALT_BLAS_COMMON_H 1
3
+
4
+ #include <ruby.h>
5
+
6
+ #include <numo/narray.h>
7
+ #include <numo/template.h>
8
+
9
+ #ifndef _DEFINED_SCOMPLEX
10
+ #define _DEFINED_SCOMPLEX 1
11
+ #endif
12
+ #ifndef _DEFINED_DCOMPLEX
13
+ #define _DEFINED_DCOMPLEX 1
14
+ #endif
15
+
16
+ #include <cblas.h>
17
+
18
+ #ifndef CBLAS_INT
19
+ #if defined(BLIS_TYPE_DEFS_H)
20
+ #define CBLAS_INT f77_int
21
+ #elif defined(_MKL_TYPES_H_)
22
+ #define CBLAS_INT MKL_INT
23
+ #elif defined(OPENBLAS_CONFIG_H)
24
+ #define CBLAS_INT blasint
25
+ #else
26
+ #define CBLAS_INT int
27
+ #endif
28
+ #endif
29
+
30
+ #endif /* NUMO_LINALG_ALT_BLAS_COMMON_H */
@@ -0,0 +1,39 @@
1
+ #include "blas_util.h"
2
+
3
+ enum CBLAS_TRANSPOSE get_cblas_trans(VALUE val) {
4
+ const char option = NUM2CHR(val);
5
+ enum CBLAS_TRANSPOSE res = CblasNoTrans;
6
+
7
+ switch (option) {
8
+ case 'n':
9
+ case 'N':
10
+ res = CblasNoTrans;
11
+ break;
12
+ case 't':
13
+ case 'T':
14
+ res = CblasTrans;
15
+ break;
16
+ case 'c':
17
+ case 'C':
18
+ res = CblasConjTrans;
19
+ break;
20
+ }
21
+
22
+ return res;
23
+ }
24
+
25
+ enum CBLAS_ORDER get_cblas_order(VALUE val) {
26
+ const char option = NUM2CHR(val);
27
+
28
+ switch (option) {
29
+ case 'r':
30
+ case 'R':
31
+ break;
32
+ case 'c':
33
+ case 'C':
34
+ rb_warn("Numo::Linalg does not support column major.");
35
+ break;
36
+ }
37
+
38
+ return CblasRowMajor;
39
+ }
@@ -0,0 +1,11 @@
1
+ #ifndef NUMO_LINALG_ALT_BLAS_UTIL_H
2
+ #define NUMO_LINALG_ALT_BLAS_UTIL_H 1
3
+
4
+ #include <ruby.h>
5
+
6
+ #include <cblas.h>
7
+
8
+ enum CBLAS_TRANSPOSE get_cblas_trans(VALUE val);
9
+ enum CBLAS_ORDER get_cblas_order(VALUE val);
10
+
11
+ #endif // NUMO_LINALG_ALT_BLAS_UTIL_H
@@ -3,8 +3,6 @@
3
3
 
4
4
  #include <ruby.h>
5
5
 
6
- #include <cblas.h>
7
-
8
6
  #include <numo/narray.h>
9
7
 
10
8
  double conv_double(VALUE val);
@@ -5,7 +5,7 @@
5
5
  tDType* x = (tDType*)NDL_PTR(lp, 0); \
6
6
  tDType* y = (tDType*)NDL_PTR(lp, 1); \
7
7
  tDType* d = (tDType*)NDL_PTR(lp, 2); \
8
- const blasint n = (blasint)NDL_SHAPE(lp, 0)[0]; \
8
+ const CBLAS_INT n = (CBLAS_INT)NDL_SHAPE(lp, 0)[0]; \
9
9
  tDType ret = cblas_##fBlasFunc(n, x, 1, y, 1); \
10
10
  *d = ret; \
11
11
  } \
@@ -1,12 +1,7 @@
1
1
  #ifndef NUMO_LINALG_ALT_BLAS_DOT_H
2
2
  #define NUMO_LINALG_ALT_BLAS_DOT_H 1
3
3
 
4
- #include <ruby.h>
5
-
6
- #include <cblas.h>
7
-
8
- #include <numo/narray.h>
9
- #include <numo/template.h>
4
+ #include "blas_common.h"
10
5
 
11
6
  void define_linalg_blas_dot(VALUE mBlas);
12
7
 
@@ -5,7 +5,7 @@
5
5
  tDType* x = (tDType*)NDL_PTR(lp, 0); \
6
6
  tDType* y = (tDType*)NDL_PTR(lp, 1); \
7
7
  tDType* d = (tDType*)NDL_PTR(lp, 2); \
8
- const blasint n = (blasint)NDL_SHAPE(lp, 0)[0]; \
8
+ const CBLAS_INT n = (CBLAS_INT)NDL_SHAPE(lp, 0)[0]; \
9
9
  cblas_##fBlasFunc(n, x, 1, y, 1, d); \
10
10
  } \
11
11
  \
@@ -1,12 +1,7 @@
1
1
  #ifndef NUMO_LINALG_ALT_BLAS_DOT_SUB_H
2
2
  #define NUMO_LINALG_ALT_BLAS_DOT_SUB_H 1
3
3
 
4
- #include <ruby.h>
5
-
6
- #include <cblas.h>
7
-
8
- #include <numo/narray.h>
9
- #include <numo/template.h>
4
+ #include "blas_common.h"
10
5
 
11
6
  void define_linalg_blas_dot_sub(VALUE mBlas);
12
7
 
@@ -7,9 +7,9 @@
7
7
  enum CBLAS_ORDER order; \
8
8
  enum CBLAS_TRANSPOSE transa; \
9
9
  enum CBLAS_TRANSPOSE transb; \
10
- blasint m; \
11
- blasint n; \
12
- blasint k; \
10
+ CBLAS_INT m; \
11
+ CBLAS_INT n; \
12
+ CBLAS_INT k; \
13
13
  };
14
14
 
15
15
  #define DEF_LINALG_ITER_FUNC(tDType, fBlasFunc) \
@@ -18,9 +18,9 @@
18
18
  const tDType* b = (tDType*)NDL_PTR(lp, 1); \
19
19
  tDType* c = (tDType*)NDL_PTR(lp, 2); \
20
20
  const struct _gemm_options_##tDType* opt = (struct _gemm_options_##tDType*)(lp->opt_ptr); \
21
- const blasint lda = opt->transa == CblasNoTrans ? opt->k : opt->m; \
22
- const blasint ldb = opt->transb == CblasNoTrans ? opt->n : opt->k; \
23
- const blasint ldc = opt->n; \
21
+ const CBLAS_INT lda = opt->transa == CblasNoTrans ? opt->k : opt->m; \
22
+ const CBLAS_INT ldb = opt->transb == CblasNoTrans ? opt->n : opt->k; \
23
+ const CBLAS_INT ldc = opt->n; \
24
24
  cblas_##fBlasFunc( \
25
25
  opt->order, opt->transa, opt->transb, opt->m, opt->n, opt->k, opt->alpha, a, lda, b, \
26
26
  ldb, opt->beta, c, ldc \
@@ -33,9 +33,9 @@
33
33
  const tDType* b = (tDType*)NDL_PTR(lp, 1); \
34
34
  tDType* c = (tDType*)NDL_PTR(lp, 2); \
35
35
  const struct _gemm_options_##tDType* opt = (struct _gemm_options_##tDType*)(lp->opt_ptr); \
36
- const blasint lda = opt->transa == CblasNoTrans ? opt->k : opt->m; \
37
- const blasint ldb = opt->transb == CblasNoTrans ? opt->n : opt->k; \
38
- const blasint ldc = opt->n; \
36
+ const CBLAS_INT lda = opt->transa == CblasNoTrans ? opt->k : opt->m; \
37
+ const CBLAS_INT ldb = opt->transb == CblasNoTrans ? opt->n : opt->k; \
38
+ const CBLAS_INT ldc = opt->n; \
39
39
  cblas_##fBlasFunc( \
40
40
  opt->order, opt->transa, opt->transb, opt->m, opt->n, opt->k, &opt->alpha, a, lda, b, \
41
41
  ldb, &opt->beta, c, ldc \
@@ -48,9 +48,9 @@
48
48
  const tDType* b = (tDType*)NDL_PTR(lp, 1); \
49
49
  tDType* c = (tDType*)NDL_PTR(lp, 2); \
50
50
  const struct _gemm_options_##tDType* opt = (struct _gemm_options_##tDType*)(lp->opt_ptr); \
51
- const blasint lda = opt->transa == CblasNoTrans ? opt->k : opt->m; \
52
- const blasint ldb = opt->transb == CblasNoTrans ? opt->n : opt->k; \
53
- const blasint ldc = opt->n; \
51
+ const CBLAS_INT lda = opt->transa == CblasNoTrans ? opt->k : opt->m; \
52
+ const CBLAS_INT ldb = opt->transb == CblasNoTrans ? opt->n : opt->k; \
53
+ const CBLAS_INT ldc = opt->n; \
54
54
  cblas_##fBlasFunc( \
55
55
  opt->order, opt->transa, opt->transb, opt->m, opt->n, opt->k, opt->alpha, a, lda, b, \
56
56
  ldb, opt->beta, c, ldc \
@@ -122,14 +122,14 @@
122
122
  return Qnil; \
123
123
  } \
124
124
  \
125
- const blasint ma = (blasint)NA_SHAPE(a_nary)[0]; \
126
- const blasint ka = (blasint)NA_SHAPE(a_nary)[1]; \
127
- const blasint kb = (blasint)NA_SHAPE(b_nary)[0]; \
128
- const blasint nb = (blasint)NA_SHAPE(b_nary)[1]; \
129
- const blasint m = transa == CblasNoTrans ? ma : ka; \
130
- const blasint n = transb == CblasNoTrans ? nb : kb; \
131
- const blasint k = transa == CblasNoTrans ? ka : ma; \
132
- const blasint l = transb == CblasNoTrans ? kb : nb; \
125
+ const CBLAS_INT ma = (CBLAS_INT)NA_SHAPE(a_nary)[0]; \
126
+ const CBLAS_INT ka = (CBLAS_INT)NA_SHAPE(a_nary)[1]; \
127
+ const CBLAS_INT kb = (CBLAS_INT)NA_SHAPE(b_nary)[0]; \
128
+ const CBLAS_INT nb = (CBLAS_INT)NA_SHAPE(b_nary)[1]; \
129
+ const CBLAS_INT m = transa == CblasNoTrans ? ma : ka; \
130
+ const CBLAS_INT n = transb == CblasNoTrans ? nb : kb; \
131
+ const CBLAS_INT k = transa == CblasNoTrans ? ka : ma; \
132
+ const CBLAS_INT l = transb == CblasNoTrans ? kb : nb; \
133
133
  \
134
134
  if (k != l) { \
135
135
  rb_raise(nary_eShapeError, "shape1[1](=%d) != shape2[0](=%d)", k, l); \
@@ -144,7 +144,7 @@
144
144
  if (!NIL_P(c)) { \
145
145
  narray_t* c_nary = NULL; \
146
146
  GetNArray(c, c_nary); \
147
- blasint nc = (blasint)NA_SHAPE(c_nary)[0]; \
147
+ CBLAS_INT nc = (CBLAS_INT)NA_SHAPE(c_nary)[0]; \
148
148
  if (m > nc) { \
149
149
  rb_raise(nary_eShapeError, "shape3[0](=%d) >= shape1[0]=%d", nc, m); \
150
150
  return Qnil; \
@@ -1,15 +1,9 @@
1
1
  #ifndef NUMO_LINALG_ALT_BLAS_GEMM_H
2
2
  #define NUMO_LINALG_ALT_BLAS_GEMM_H 1
3
3
 
4
- #include <ruby.h>
5
-
6
- #include <cblas.h>
7
-
8
- #include <numo/narray.h>
9
- #include <numo/template.h>
10
-
11
- #include "../converter.h"
12
- #include "../util.h"
4
+ #include "blas_common.h"
5
+ #include "blas_util.h"
6
+ #include "converter.h"
13
7
 
14
8
  void define_linalg_blas_gemm(VALUE mBlas);
15
9
 
@@ -6,8 +6,8 @@
6
6
  tDType beta; \
7
7
  enum CBLAS_ORDER order; \
8
8
  enum CBLAS_TRANSPOSE trans; \
9
- blasint m; \
10
- blasint n; \
9
+ CBLAS_INT m; \
10
+ CBLAS_INT n; \
11
11
  };
12
12
 
13
13
  #define DEF_LINALG_ITER_FUNC(tDType, fBlasFunc) \
@@ -16,7 +16,7 @@
16
16
  const tDType* x = (tDType*)NDL_PTR(lp, 1); \
17
17
  tDType* y = (tDType*)NDL_PTR(lp, 2); \
18
18
  const struct _gemv_options_##tDType* opt = (struct _gemv_options_##tDType*)(lp->opt_ptr); \
19
- const blasint lda = opt->n; \
19
+ const CBLAS_INT lda = opt->n; \
20
20
  cblas_##fBlasFunc( \
21
21
  opt->order, opt->trans, opt->m, opt->n, opt->alpha, a, lda, x, 1, opt->beta, y, 1 \
22
22
  ); \
@@ -28,7 +28,7 @@
28
28
  const tDType* x = (tDType*)NDL_PTR(lp, 1); \
29
29
  tDType* y = (tDType*)NDL_PTR(lp, 2); \
30
30
  const struct _gemv_options_##tDType* opt = (struct _gemv_options_##tDType*)(lp->opt_ptr); \
31
- const blasint lda = opt->n; \
31
+ const CBLAS_INT lda = opt->n; \
32
32
  cblas_##fBlasFunc( \
33
33
  opt->order, opt->trans, opt->m, opt->n, &opt->alpha, a, lda, x, 1, &opt->beta, y, 1 \
34
34
  ); \
@@ -97,11 +97,11 @@
97
97
  return Qnil; \
98
98
  } \
99
99
  \
100
- const blasint ma = (blasint)NA_SHAPE(a_nary)[0]; \
101
- const blasint na = (blasint)NA_SHAPE(a_nary)[1]; \
102
- const blasint mx = (blasint)NA_SHAPE(x_nary)[0]; \
103
- const blasint m = trans == CblasNoTrans ? ma : na; \
104
- const blasint n = trans == CblasNoTrans ? na : ma; \
100
+ const CBLAS_INT ma = (CBLAS_INT)NA_SHAPE(a_nary)[0]; \
101
+ const CBLAS_INT na = (CBLAS_INT)NA_SHAPE(a_nary)[1]; \
102
+ const CBLAS_INT mx = (CBLAS_INT)NA_SHAPE(x_nary)[0]; \
103
+ const CBLAS_INT m = trans == CblasNoTrans ? ma : na; \
104
+ const CBLAS_INT n = trans == CblasNoTrans ? na : ma; \
105
105
  \
106
106
  if (n != mx) { \
107
107
  rb_raise(nary_eShapeError, "shape1[1](=%d) != shape2[0](=%d)", n, mx); \
@@ -116,7 +116,7 @@
116
116
  if (!NIL_P(y)) { \
117
117
  narray_t* y_nary = NULL; \
118
118
  GetNArray(y, y_nary); \
119
- blasint my = (blasint)NA_SHAPE(y_nary)[0]; \
119
+ CBLAS_INT my = (CBLAS_INT)NA_SHAPE(y_nary)[0]; \
120
120
  if (m > my) { \
121
121
  rb_raise(nary_eShapeError, "shape3[0](=%d) >= shape1[0]=%d", my, m); \
122
122
  return Qnil; \
@@ -1,15 +1,9 @@
1
1
  #ifndef NUMO_LINALG_ALT_BLAS_GEMV_H
2
2
  #define NUMO_LINALG_ALT_BLAS_GEMV_H 1
3
3
 
4
- #include <ruby.h>
5
-
6
- #include <cblas.h>
7
-
8
- #include <numo/narray.h>
9
- #include <numo/template.h>
10
-
11
- #include "../converter.h"
12
- #include "../util.h"
4
+ #include "blas_common.h"
5
+ #include "blas_util.h"
6
+ #include "converter.h"
13
7
 
14
8
  void define_linalg_blas_gemv(VALUE mBlas);
15
9
 
@@ -4,7 +4,7 @@
4
4
  static void _iter_##fBlasFunc(na_loop_t* const lp) { \
5
5
  tDType* x = (tDType*)NDL_PTR(lp, 0); \
6
6
  tRtDType* d = (tRtDType*)NDL_PTR(lp, 1); \
7
- const blasint n = (blasint)NDL_SHAPE(lp, 0)[0]; \
7
+ const CBLAS_INT n = (CBLAS_INT)NDL_SHAPE(lp, 0)[0]; \
8
8
  tRtDType ret = cblas_##fBlasFunc(n, x, 1); \
9
9
  *d = ret; \
10
10
  } \
@@ -1,12 +1,7 @@
1
1
  #ifndef NUMO_LINALG_ALT_BLAS_NRM2_H
2
2
  #define NUMO_LINALG_ALT_BLAS_NRM2_H 1
3
3
 
4
- #include <ruby.h>
5
-
6
- #include <cblas.h>
7
-
8
- #include <numo/narray.h>
9
- #include <numo/template.h>
4
+ #include "blas_common.h"
10
5
 
11
6
  void define_linalg_blas_nrm2(VALUE mBlas);
12
7
 
@@ -30,14 +30,41 @@ if on_windows
30
30
  abort 'libnarray.a is not found' unless have_library('narray', 'nary_new')
31
31
  end
32
32
 
33
+ blas = with_config('blas')
34
+ lapacke = with_config('lapacke')
35
+
36
+ if blas.nil?
37
+ unless lapacke.nil? # BLAS is OpenBLAS, LAPACKE is specified by user.
38
+ abort("LAPACKE library '#{lapacke}' is not found.") unless have_library(lapacke)
39
+ abort("BLAS library 'openblas' is not found.") unless have_library('openblas')
40
+ abort('cblas.h is not found.') unless have_header('cblas.h')
41
+ abort('lapacke.h is not found.') unless have_header('lapacke.h')
42
+ abort('openblas_config.h is not found.') unless have_header('openblas_config.h')
43
+ end
44
+ else
45
+ unless find_library(blas, 'LAPACKE_dsyevr') # Check if BLAS library has LAPACKE function (OpenBLAS).
46
+ abort("BLAS library '#{blas}' is not found.") unless have_library(blas)
47
+ if lapacke.nil?
48
+ abort("LAPACKE library 'lapacke' is not found.") unless have_library('lapacke')
49
+ else
50
+ abort("LAPACKE library '#{lapacke}' is not found.") unless have_library(lapacke)
51
+ end
52
+ end
53
+ abort('cblas.h is not found.') unless have_header('cblas.h')
54
+ abort('lapacke.h is not found.') unless have_header('lapacke.h')
55
+ have_header('openblas_config.h')
56
+ end
57
+
33
58
  build_openblas = false
34
- unless find_library('openblas', 'LAPACKE_dsyevr')
35
- build_openblas = true unless have_library('openblas')
36
- build_openblas = true unless have_library('lapacke')
59
+ if blas.nil? && lapacke.nil?
60
+ unless find_library('openblas', 'LAPACKE_dsyevr')
61
+ build_openblas = true unless have_library('openblas')
62
+ build_openblas = true unless have_library('lapacke')
63
+ end
64
+ build_openblas = true unless have_header('cblas.h')
65
+ build_openblas = true unless have_header('lapacke.h')
66
+ build_openblas = true unless have_header('openblas_config.h')
37
67
  end
38
- build_openblas = true unless have_header('cblas.h')
39
- build_openblas = true unless have_header('lapacke.h')
40
- build_openblas = true unless have_header('openblas_config.h')
41
68
 
42
69
  if build_openblas
43
70
  warn 'BLAS and LAPACKE APIs are not found. Downloading and Building OpenBLAS...'
@@ -8,7 +8,7 @@
8
8
  #include <numo/narray.h>
9
9
  #include <numo/template.h>
10
10
 
11
- #include "../util.h"
11
+ #include "lapack_util.h"
12
12
 
13
13
  void define_linalg_lapack_gebal(VALUE mLapack);
14
14
 
@@ -90,7 +90,7 @@
90
90
  (lapack_int)(opt->matrix_layout == LAPACK_ROW_MAJOR ? NDL_SHAPE(lp, 0)[0] \
91
91
  : NDL_SHAPE(lp, 0)[1]); \
92
92
  const lapack_int lda = n; \
93
- const lapack_int ldvs = (opt->jobvs == 'N') ? 1 : n; \
93
+ const lapack_int ldvs = n; \
94
94
  lapack_int s = 0; \
95
95
  lapack_int i = LAPACKE_##fLapackFunc( \
96
96
  opt->matrix_layout, opt->jobvs, opt->sort, opt->select, n, a, lda, &s, wr, wi, vs, ldvs \
@@ -108,7 +108,7 @@
108
108
  rb_get_kwargs(kw_args, kw_table, 0, 3, kw_values); \
109
109
  const int matrix_layout = \
110
110
  kw_values[0] != Qundef ? get_matrix_layout(kw_values[0]) : LAPACK_ROW_MAJOR; \
111
- const char jobvs = kw_values[1] != Qundef ? get_jobvs(kw_values[1]) : 'V'; \
111
+ const char jobvs = kw_values[1] != Qundef ? get_job(kw_values[1], "jobvs") : 'V'; \
112
112
  VALUE sort_val = kw_values[2] != Qundef ? kw_values[2] : Qnil; \
113
113
  const char sort_ch = NIL_P(sort_val) ? 'N' : 'S'; \
114
114
  \
@@ -174,7 +174,7 @@
174
174
  (lapack_int)(opt->matrix_layout == LAPACK_ROW_MAJOR ? NDL_SHAPE(lp, 0)[0] \
175
175
  : NDL_SHAPE(lp, 0)[1]); \
176
176
  const lapack_int lda = n; \
177
- const lapack_int ldvs = (opt->jobvs == 'N') ? 1 : n; \
177
+ const lapack_int ldvs = n; \
178
178
  lapack_int s = 0; \
179
179
  lapack_int i = LAPACKE_##fLapackFunc( \
180
180
  opt->matrix_layout, opt->jobvs, opt->sort, opt->select, n, a, lda, &s, w, vs, ldvs \
@@ -192,7 +192,7 @@
192
192
  rb_get_kwargs(kw_args, kw_table, 0, 3, kw_values); \
193
193
  const int matrix_layout = \
194
194
  kw_values[0] != Qundef ? get_matrix_layout(kw_values[0]) : LAPACK_ROW_MAJOR; \
195
- const char jobvs = kw_values[1] != Qundef ? get_jobvs(kw_values[1]) : 'V'; \
195
+ const char jobvs = kw_values[1] != Qundef ? get_job(kw_values[1], "jobvs") : 'V'; \
196
196
  VALUE sort_val = kw_values[2] != Qundef ? kw_values[2] : Qnil; \
197
197
  const char sort_ch = NIL_P(sort_val) ? 'N' : 'S'; \
198
198
  \
@@ -8,7 +8,7 @@
8
8
  #include <numo/narray.h>
9
9
  #include <numo/template.h>
10
10
 
11
- #include "../util.h"
11
+ #include "lapack_util.h"
12
12
 
13
13
  void define_linalg_lapack_gees(VALUE mLapack);
14
14
 
@@ -6,22 +6,6 @@ struct _geev_option {
6
6
  char jobvr;
7
7
  };
8
8
 
9
- char _get_jobvl(VALUE val) {
10
- const char jobvl = NUM2CHR(val);
11
- if (jobvl != 'N' && jobvl != 'V') {
12
- rb_raise(rb_eArgError, "jobvl must be 'N' or 'V'");
13
- }
14
- return jobvl;
15
- }
16
-
17
- char _get_jobvr(VALUE val) {
18
- const char jobvr = NUM2CHR(val);
19
- if (jobvr != 'N' && jobvr != 'V') {
20
- rb_raise(rb_eArgError, "jobvr must be 'N' or 'V'");
21
- }
22
- return jobvr;
23
- }
24
-
25
9
  #define DEF_LINALG_FUNC(tDType, tNAryClass, fLapackFunc) \
26
10
  static void _iter_##fLapackFunc(na_loop_t* const lp) { \
27
11
  tDType* a = (tDType*)NDL_PTR(lp, 0); \
@@ -35,8 +19,8 @@ char _get_jobvr(VALUE val) {
35
19
  (lapack_int)(opt->matrix_layout == LAPACK_ROW_MAJOR ? NDL_SHAPE(lp, 0)[0] \
36
20
  : NDL_SHAPE(lp, 0)[1]); \
37
21
  const lapack_int lda = n; \
38
- const lapack_int ldvl = (opt->jobvl == 'N') ? 1 : n; \
39
- const lapack_int ldvr = (opt->jobvr == 'N') ? 1 : n; \
22
+ const lapack_int ldvl = n; \
23
+ const lapack_int ldvr = n; \
40
24
  lapack_int i = LAPACKE_##fLapackFunc( \
41
25
  opt->matrix_layout, opt->jobvl, opt->jobvr, n, a, lda, wr, wi, vl, ldvl, vr, ldvr \
42
26
  ); \
@@ -52,8 +36,8 @@ char _get_jobvr(VALUE val) {
52
36
  rb_get_kwargs(kw_args, kw_table, 0, 3, kw_values); \
53
37
  const int matrix_layout = \
54
38
  kw_values[0] != Qundef ? get_matrix_layout(kw_values[0]) : LAPACK_ROW_MAJOR; \
55
- const char jobvl = kw_values[1] != Qundef ? _get_jobvl(kw_values[1]) : 'V'; \
56
- const char jobvr = kw_values[2] != Qundef ? _get_jobvr(kw_values[2]) : 'V'; \
39
+ const char jobvl = kw_values[1] != Qundef ? get_job(kw_values[1], "jobvl") : 'V'; \
40
+ const char jobvr = kw_values[2] != Qundef ? get_job(kw_values[2], "jobvr") : 'V'; \
57
41
  \
58
42
  if (CLASS_OF(a_vnary) != tNAryClass) { \
59
43
  a_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, a_vnary); \
@@ -101,8 +85,8 @@ char _get_jobvr(VALUE val) {
101
85
  (lapack_int)(opt->matrix_layout == LAPACK_ROW_MAJOR ? NDL_SHAPE(lp, 0)[0] \
102
86
  : NDL_SHAPE(lp, 0)[1]); \
103
87
  const lapack_int lda = n; \
104
- const lapack_int ldvl = (opt->jobvl == 'N') ? 1 : n; \
105
- const lapack_int ldvr = (opt->jobvr == 'N') ? 1 : n; \
88
+ const lapack_int ldvl = n; \
89
+ const lapack_int ldvr = n; \
106
90
  lapack_int i = LAPACKE_##fLapackFunc( \
107
91
  opt->matrix_layout, opt->jobvl, opt->jobvr, n, a, lda, w, vl, ldvl, vr, ldvr \
108
92
  ); \
@@ -118,8 +102,8 @@ char _get_jobvr(VALUE val) {
118
102
  rb_get_kwargs(kw_args, kw_table, 0, 3, kw_values); \
119
103
  const int matrix_layout = \
120
104
  kw_values[0] != Qundef ? get_matrix_layout(kw_values[0]) : LAPACK_ROW_MAJOR; \
121
- const char jobvl = kw_values[1] != Qundef ? _get_jobvl(kw_values[1]) : 'V'; \
122
- const char jobvr = kw_values[2] != Qundef ? _get_jobvr(kw_values[2]) : 'V'; \
105
+ const char jobvl = kw_values[1] != Qundef ? get_job(kw_values[1], "jobvl") : 'V'; \
106
+ const char jobvr = kw_values[2] != Qundef ? get_job(kw_values[2], "jobvr") : 'V'; \
123
107
  \
124
108
  if (CLASS_OF(a_vnary) != tNAryClass) { \
125
109
  a_vnary = rb_funcall(tNAryClass, rb_intern("cast"), 1, a_vnary); \
@@ -8,7 +8,7 @@
8
8
  #include <numo/narray.h>
9
9
  #include <numo/template.h>
10
10
 
11
- #include "../util.h"
11
+ #include "lapack_util.h"
12
12
 
13
13
  void define_linalg_lapack_geev(VALUE mLapack);
14
14