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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +47 -5
- data/ext/numo/linalg/blas/blas_common.h +30 -0
- data/ext/numo/linalg/blas/blas_util.c +39 -0
- data/ext/numo/linalg/blas/blas_util.h +11 -0
- data/ext/numo/linalg/{converter.h → blas/converter.h} +0 -2
- data/ext/numo/linalg/blas/dot.c +1 -1
- data/ext/numo/linalg/blas/dot.h +1 -6
- data/ext/numo/linalg/blas/dot_sub.c +1 -1
- data/ext/numo/linalg/blas/dot_sub.h +1 -6
- data/ext/numo/linalg/blas/gemm.c +21 -21
- data/ext/numo/linalg/blas/gemm.h +3 -9
- data/ext/numo/linalg/blas/gemv.c +10 -10
- data/ext/numo/linalg/blas/gemv.h +3 -9
- data/ext/numo/linalg/blas/nrm2.c +1 -1
- data/ext/numo/linalg/blas/nrm2.h +1 -6
- data/ext/numo/linalg/extconf.rb +33 -6
- data/ext/numo/linalg/lapack/gebal.h +1 -1
- data/ext/numo/linalg/lapack/gees.c +4 -4
- data/ext/numo/linalg/lapack/gees.h +1 -1
- data/ext/numo/linalg/lapack/geev.c +8 -24
- data/ext/numo/linalg/lapack/geev.h +1 -1
- data/ext/numo/linalg/lapack/gehrd.h +1 -1
- data/ext/numo/linalg/lapack/gelsd.h +1 -1
- data/ext/numo/linalg/lapack/geqrf.h +1 -1
- data/ext/numo/linalg/lapack/gerqf.h +1 -1
- data/ext/numo/linalg/lapack/gesdd.h +1 -1
- data/ext/numo/linalg/lapack/gesv.h +1 -1
- data/ext/numo/linalg/lapack/gesvd.h +1 -1
- data/ext/numo/linalg/lapack/getrf.h +1 -1
- data/ext/numo/linalg/lapack/getri.h +1 -1
- data/ext/numo/linalg/lapack/getrs.h +1 -1
- data/ext/numo/linalg/lapack/gges.c +4 -4
- data/ext/numo/linalg/lapack/gges.h +1 -1
- data/ext/numo/linalg/lapack/heev.c +1 -1
- data/ext/numo/linalg/lapack/heev.h +1 -1
- data/ext/numo/linalg/lapack/heevd.c +1 -1
- data/ext/numo/linalg/lapack/heevd.h +1 -1
- data/ext/numo/linalg/lapack/heevr.c +1 -1
- data/ext/numo/linalg/lapack/heevr.h +1 -1
- data/ext/numo/linalg/lapack/hegv.c +1 -1
- data/ext/numo/linalg/lapack/hegv.h +1 -1
- data/ext/numo/linalg/lapack/hegvd.c +1 -1
- data/ext/numo/linalg/lapack/hegvd.h +1 -1
- data/ext/numo/linalg/lapack/hegvx.c +1 -1
- data/ext/numo/linalg/lapack/hegvx.h +1 -1
- data/ext/numo/linalg/lapack/hetrf.h +1 -1
- data/ext/numo/linalg/lapack/lange.h +1 -1
- data/ext/numo/linalg/lapack/lapack_util.c +57 -0
- data/ext/numo/linalg/lapack/lapack_util.h +27 -0
- data/ext/numo/linalg/lapack/orghr.h +1 -1
- data/ext/numo/linalg/lapack/orgqr.h +1 -1
- data/ext/numo/linalg/lapack/orgrq.h +1 -1
- data/ext/numo/linalg/lapack/potrf.h +1 -1
- data/ext/numo/linalg/lapack/potri.h +1 -1
- data/ext/numo/linalg/lapack/potrs.h +1 -1
- data/ext/numo/linalg/lapack/syev.c +1 -1
- data/ext/numo/linalg/lapack/syev.h +1 -1
- data/ext/numo/linalg/lapack/syevd.c +1 -1
- data/ext/numo/linalg/lapack/syevd.h +1 -1
- data/ext/numo/linalg/lapack/syevr.c +1 -1
- data/ext/numo/linalg/lapack/syevr.h +1 -1
- data/ext/numo/linalg/lapack/sygv.c +1 -1
- data/ext/numo/linalg/lapack/sygv.h +1 -1
- data/ext/numo/linalg/lapack/sygvd.c +1 -1
- data/ext/numo/linalg/lapack/sygvd.h +1 -1
- data/ext/numo/linalg/lapack/sygvx.c +1 -1
- data/ext/numo/linalg/lapack/sygvx.h +1 -1
- data/ext/numo/linalg/lapack/sytrf.h +1 -1
- data/ext/numo/linalg/lapack/trtrs.h +1 -1
- data/ext/numo/linalg/lapack/unghr.h +1 -1
- data/ext/numo/linalg/lapack/ungqr.h +1 -1
- data/ext/numo/linalg/lapack/ungrq.h +1 -1
- data/ext/numo/linalg/linalg.c +2 -0
- data/ext/numo/linalg/linalg.h +14 -6
- data/lib/numo/linalg/version.rb +1 -1
- data/lib/numo/linalg.rb +68 -20
- metadata +9 -6
- data/ext/numo/linalg/util.c +0 -103
- data/ext/numo/linalg/util.h +0 -18
- /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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 94dfd3c199541e6dc2b71968e11450af79613c6dba382c3ac0cd64541f2d8461
|
|
4
|
+
data.tar.gz: 9a7bc15d245eeb94a97c524a474f10345b78a7693ab766b0cbea3353791e22b1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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,
|
|
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
|
-
|
|
21
|
-
|
|
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
|
data/ext/numo/linalg/blas/dot.c
CHANGED
|
@@ -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
|
|
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
|
} \
|
data/ext/numo/linalg/blas/dot.h
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
data/ext/numo/linalg/blas/gemm.c
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
enum CBLAS_ORDER order; \
|
|
8
8
|
enum CBLAS_TRANSPOSE transa; \
|
|
9
9
|
enum CBLAS_TRANSPOSE transb; \
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
|
22
|
-
const
|
|
23
|
-
const
|
|
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
|
|
37
|
-
const
|
|
38
|
-
const
|
|
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
|
|
52
|
-
const
|
|
53
|
-
const
|
|
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
|
|
126
|
-
const
|
|
127
|
-
const
|
|
128
|
-
const
|
|
129
|
-
const
|
|
130
|
-
const
|
|
131
|
-
const
|
|
132
|
-
const
|
|
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
|
-
|
|
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; \
|
data/ext/numo/linalg/blas/gemm.h
CHANGED
|
@@ -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
|
|
5
|
-
|
|
6
|
-
#include
|
|
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
|
|
data/ext/numo/linalg/blas/gemv.c
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
tDType beta; \
|
|
7
7
|
enum CBLAS_ORDER order; \
|
|
8
8
|
enum CBLAS_TRANSPOSE trans; \
|
|
9
|
-
|
|
10
|
-
|
|
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
|
|
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
|
|
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
|
|
101
|
-
const
|
|
102
|
-
const
|
|
103
|
-
const
|
|
104
|
-
const
|
|
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
|
-
|
|
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; \
|
data/ext/numo/linalg/blas/gemv.h
CHANGED
|
@@ -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
|
|
5
|
-
|
|
6
|
-
#include
|
|
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
|
|
data/ext/numo/linalg/blas/nrm2.c
CHANGED
|
@@ -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
|
|
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
|
} \
|
data/ext/numo/linalg/blas/nrm2.h
CHANGED
|
@@ -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
|
|
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
|
|
data/ext/numo/linalg/extconf.rb
CHANGED
|
@@ -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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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...'
|
|
@@ -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 =
|
|
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 ?
|
|
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 =
|
|
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 ?
|
|
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
|
\
|
|
@@ -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 =
|
|
39
|
-
const lapack_int ldvr =
|
|
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 ?
|
|
56
|
-
const char jobvr = kw_values[2] != Qundef ?
|
|
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 =
|
|
105
|
-
const lapack_int ldvr =
|
|
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 ?
|
|
122
|
-
const char jobvr = kw_values[2] != Qundef ?
|
|
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); \
|