nmatrix 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.
- data/.autotest +23 -0
- data/.gemtest +0 -0
- data/Gemfile +7 -0
- data/History.txt +6 -0
- data/LICENSE.txt +21 -0
- data/Manifest.txt +51 -0
- data/README.rdoc +63 -0
- data/Rakefile +154 -0
- data/ext/nmatrix/cblas.c +150 -0
- data/ext/nmatrix/dense.c +307 -0
- data/ext/nmatrix/dense/blas_header.template.c +52 -0
- data/ext/nmatrix/dense/elementwise.template.c +107 -0
- data/ext/nmatrix/dense/gemm.template.c +159 -0
- data/ext/nmatrix/dense/gemv.template.c +130 -0
- data/ext/nmatrix/dense/rationalmath.template.c +68 -0
- data/ext/nmatrix/depend +18 -0
- data/ext/nmatrix/extconf.rb +143 -0
- data/ext/nmatrix/generator.rb +594 -0
- data/ext/nmatrix/generator/syntax_tree.rb +481 -0
- data/ext/nmatrix/list.c +774 -0
- data/ext/nmatrix/nmatrix.c +1977 -0
- data/ext/nmatrix/nmatrix.h +912 -0
- data/ext/nmatrix/rational.c +98 -0
- data/ext/nmatrix/yale.c +726 -0
- data/ext/nmatrix/yale/complexmath.template.c +71 -0
- data/ext/nmatrix/yale/elementwise.template.c +46 -0
- data/ext/nmatrix/yale/elementwise_op.template.c +73 -0
- data/ext/nmatrix/yale/numbmm.template.c +94 -0
- data/ext/nmatrix/yale/smmp1.template.c +21 -0
- data/ext/nmatrix/yale/smmp1_header.template.c +38 -0
- data/ext/nmatrix/yale/smmp2.template.c +43 -0
- data/ext/nmatrix/yale/smmp2_header.template.c +46 -0
- data/ext/nmatrix/yale/sort_columns.template.c +56 -0
- data/ext/nmatrix/yale/symbmm.template.c +54 -0
- data/ext/nmatrix/yale/transp.template.c +68 -0
- data/lib/array.rb +67 -0
- data/lib/nmatrix.rb +263 -0
- data/lib/string.rb +65 -0
- data/spec/nmatrix_spec.rb +395 -0
- data/spec/nmatrix_yale_spec.rb +239 -0
- data/spec/nvector_spec.rb +43 -0
- data/spec/syntax_tree_spec.rb +46 -0
- metadata +150 -0
@@ -0,0 +1,159 @@
|
|
1
|
+
|
2
|
+
int %%TYPE_ABBREV%%gemm(enum CBLAS_TRANSPOSE TransA, enum CBLAS_TRANSPOSE TransB,
|
3
|
+
const int M, const int N, const int K, const %%TYPE%% alpha,
|
4
|
+
const %%TYPE%%* A, const int lda,
|
5
|
+
const %%TYPE%%* B, const int ldb, const %%TYPE%% beta,
|
6
|
+
%%TYPE%%* C, const int ldc)
|
7
|
+
{
|
8
|
+
int num_rows_a, /*num_cols_a,*/ num_rows_b; // nrowa, ncola, nrowb
|
9
|
+
|
10
|
+
// use longest possible type for intermediate value storage:
|
11
|
+
%%TYPE_LONG%% temp;
|
12
|
+
%%= if [:rational,:complex,:value].include?(dtype.type); "#{dtype.long_dtype.sizeof} temp1, temp2;"; end%%
|
13
|
+
int i, j, l;
|
14
|
+
|
15
|
+
if (TransA == CblasNoTrans) num_rows_a = M;
|
16
|
+
else num_rows_a = K;
|
17
|
+
|
18
|
+
if (TransB == CblasNoTrans) num_rows_b = K;
|
19
|
+
else num_rows_b = N;
|
20
|
+
|
21
|
+
// Test the input parameters
|
22
|
+
if (TransA < 111 || TransA > 113) {
|
23
|
+
fprintf(stderr, "GEMM: TransA must be CblasNoTrans, CblasTrans, or CblasConjTrans\n");
|
24
|
+
return 0;
|
25
|
+
} else if (TransB < 111 || TransB > 113) {
|
26
|
+
fprintf(stderr, "GEMM: TransB must be CblasNoTrans, CblasTrans, or CblasConjTrans\n");
|
27
|
+
return 0;
|
28
|
+
} else if (M < 0) {
|
29
|
+
fprintf(stderr, "GEMM: Expected M >= 0\n");
|
30
|
+
return 0;
|
31
|
+
} else if (N < 0) {
|
32
|
+
fprintf(stderr, "GEMM: Expected N >= 0\n");
|
33
|
+
return 0;
|
34
|
+
} else if (K < 0) {
|
35
|
+
fprintf(stderr, "GEMM: Expected K >= 0\n");
|
36
|
+
return 0;
|
37
|
+
} else if (lda < NM_MAX(1, num_rows_a)) {
|
38
|
+
fprintf(stderr, "GEMM: Expected lda >= max(1, num_rows_a), with num_rows_a = %d; got lda=%d\n", num_rows_a, lda);
|
39
|
+
return 0;
|
40
|
+
} else if (ldb < NM_MAX(1, num_rows_b)) {
|
41
|
+
fprintf(stderr, "GEMM: Expected ldb >= max(1, num_rows_b), with num_rows_b = %d; got ldb=%d\n", num_rows_b, ldb);
|
42
|
+
return 0;
|
43
|
+
} else if (ldc < NM_MAX(1,M)) {
|
44
|
+
fprintf(stderr, "GEMM: Expected ldc >= max(1,M) with M=%d; got ldc=%d\n", M, ldc);
|
45
|
+
return 0;
|
46
|
+
}
|
47
|
+
|
48
|
+
// Quick return if possible
|
49
|
+
if (!M || !N || (%%TYPE alpha == 0%% || !K) && %%TYPE beta == 1%%) return 0;
|
50
|
+
|
51
|
+
// For alpha = 0
|
52
|
+
if (%%TYPE alpha == 0%%) {
|
53
|
+
if (%%TYPE beta == 0%%) {
|
54
|
+
for (j = 0; j < N; ++j)
|
55
|
+
for (i = 0; i < M; ++i) {
|
56
|
+
%%TYPE C[i+j*ldc] = 0%%
|
57
|
+
}
|
58
|
+
} else {
|
59
|
+
for (j = 0; j < N; ++j)
|
60
|
+
for (i = 0; i < M; ++i) {
|
61
|
+
%%TYPE C[i+j*ldc] *= beta%%
|
62
|
+
}
|
63
|
+
}
|
64
|
+
return 0;
|
65
|
+
}
|
66
|
+
|
67
|
+
// Start the operations
|
68
|
+
if (TransB == CblasNoTrans) {
|
69
|
+
if (TransA == CblasNoTrans) {
|
70
|
+
// C = alpha*A*B+beta*C
|
71
|
+
for (j = 0; j < N; ++j) {
|
72
|
+
if (%%TYPE beta == 0%%) {
|
73
|
+
for (i = 0; i < M; ++i) {
|
74
|
+
%%TYPE C[i+j*ldc] = 0%%
|
75
|
+
}
|
76
|
+
} else if (%%TYPE beta != 1%%) {
|
77
|
+
for (i = 0; i < M; ++i) {
|
78
|
+
%%TYPE C[i+j*ldc] *= beta%%
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
for (l = 0; l < K; ++l) {
|
83
|
+
if (%%TYPE B[l+j*ldb] != 0%%) {
|
84
|
+
%%TYPE_LONG temp = alpha * B[l+j*ldb]%%
|
85
|
+
for (i = 0; i < M; ++i) {
|
86
|
+
%%TYPE C[i+j*ldc] += A[i+l*lda] * temp%%
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
} else {
|
93
|
+
|
94
|
+
// C = alpha*A**T*B + beta*C
|
95
|
+
for (j = 0; j < N; ++j) {
|
96
|
+
for (i = 0; i < M; ++i) {
|
97
|
+
%%TYPE temp = 0%%
|
98
|
+
for (l = 0; l < K; ++l) {
|
99
|
+
%%TYPE_LONG temp += A[l+i*lda] * B[l+j*ldb]%%
|
100
|
+
}
|
101
|
+
|
102
|
+
if (%%TYPE beta == 0%%) {
|
103
|
+
%%TYPE C[i+j*ldc] = alpha*temp%%
|
104
|
+
} else {
|
105
|
+
%%TYPE C[i+j*ldc] = alpha*temp + beta*C[i+j*ldc]%%
|
106
|
+
}
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
}
|
111
|
+
|
112
|
+
} else if (TransA == CblasNoTrans) {
|
113
|
+
|
114
|
+
// C = alpha*A*B**T + beta*C
|
115
|
+
for (j = 0; j < N; ++j) {
|
116
|
+
if (%%TYPE beta == 0%%) {
|
117
|
+
for (i = 0; i < M; ++i) {
|
118
|
+
%%TYPE C[i+j*ldc] = 0%%
|
119
|
+
}
|
120
|
+
} else if (%%TYPE beta != 1%%) {
|
121
|
+
for (i = 0; i < M; ++i) {
|
122
|
+
%%TYPE C[i+j*ldc] *= beta%%
|
123
|
+
}
|
124
|
+
}
|
125
|
+
|
126
|
+
for (l = 0; l < K; ++l) {
|
127
|
+
if (%%TYPE B[j+l*ldb] != 0%%) {
|
128
|
+
%%TYPE_LONG temp = alpha * B[j+l*ldb]%%
|
129
|
+
for (i = 0; i < M; ++i) {
|
130
|
+
%%TYPE C[i+j*ldc] += A[i+l*lda] * temp%%
|
131
|
+
}
|
132
|
+
}
|
133
|
+
}
|
134
|
+
|
135
|
+
}
|
136
|
+
|
137
|
+
} else {
|
138
|
+
|
139
|
+
// C = alpha*A**T*B**T + beta*C
|
140
|
+
for (j = 0; j < N; ++j) {
|
141
|
+
for (i = 0; i < M; ++i) {
|
142
|
+
%%TYPE temp = 0%%
|
143
|
+
for (l = 0; l < K; ++l) {
|
144
|
+
%%TYPE_LONG temp += A[l+i*lda] * B[j+l*ldb]%%
|
145
|
+
}
|
146
|
+
|
147
|
+
if (%%TYPE beta == 0%%) {
|
148
|
+
%%TYPE C[i+j*ldc] = alpha*temp%%
|
149
|
+
} else {
|
150
|
+
%%TYPE C[i+j*ldc] = alpha*temp + beta*C[i+j*ldc]%%
|
151
|
+
}
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
}
|
156
|
+
|
157
|
+
return 0;
|
158
|
+
}
|
159
|
+
|
@@ -0,0 +1,130 @@
|
|
1
|
+
|
2
|
+
int %%TYPE_ABBREV%%gemv(enum CBLAS_TRANSPOSE Trans, const size_t M, const size_t N, const %%TYPE%% alpha,
|
3
|
+
const %%TYPE%%* A, const size_t lda, const %%TYPE%%* X, const int incX, const %%TYPE%% beta, %%TYPE%%* Y, const int incY)
|
4
|
+
{
|
5
|
+
size_t lenX, lenY, i, j;
|
6
|
+
int kx, ky, iy, jx, jy, ix;
|
7
|
+
%%TYPE_LONG%% temp;
|
8
|
+
%%= if [:rational,:complex,:value].include?(dtype.type); "#{dtype.long_dtype.sizeof} temp1;"; end%%
|
9
|
+
|
10
|
+
// Test the input parameters
|
11
|
+
if (Trans < 111 || Trans > 113) {
|
12
|
+
fprintf(stderr, "IGEMV: TransA must be CblasNoTrans, CblasTrans, or CblasConjTrans\n");
|
13
|
+
return 0;
|
14
|
+
} else if (lda < NM_MAX(1, N)) {
|
15
|
+
fprintf(stderr, "IGEMV: Expected lda >= max(1, N), with N = %d; got lda=%d\n", N, lda);
|
16
|
+
return 0;
|
17
|
+
} else if (incX == 0) {
|
18
|
+
fprintf(stderr, "IGEMV: Expected incX != 0\n");
|
19
|
+
return 0;
|
20
|
+
} else if (incY == 0) {
|
21
|
+
fprintf(stderr, "IGEMV: Expected incY != 0\n");
|
22
|
+
return 0;
|
23
|
+
}
|
24
|
+
|
25
|
+
// Quick return if possible
|
26
|
+
if (!M || !N || %%TYPE alpha == 0%% && %%TYPE beta == 1%%) return 0;
|
27
|
+
|
28
|
+
if (Trans == CblasNoTrans) {
|
29
|
+
lenX = N;
|
30
|
+
lenY = M;
|
31
|
+
} else {
|
32
|
+
lenX = M;
|
33
|
+
lenY = N;
|
34
|
+
}
|
35
|
+
|
36
|
+
if (incX > 0) kx = 0;
|
37
|
+
else kx = (lenX - 1) * -incX;
|
38
|
+
|
39
|
+
if (incY > 0) ky = 0;
|
40
|
+
else ky = (lenY - 1) * -incY;
|
41
|
+
|
42
|
+
// Start the operations. In this version, the elements of A are accessed sequentially with one pass through A.
|
43
|
+
if (%%TYPE beta != 1%%) {
|
44
|
+
if (incY == 1) {
|
45
|
+
if (%%TYPE beta == 0%%) {
|
46
|
+
for (i = 0; i < lenY; ++i) {
|
47
|
+
%%TYPE Y[i] = 0%%
|
48
|
+
}
|
49
|
+
} else {
|
50
|
+
for (i = 0; i < lenY; ++i) {
|
51
|
+
%%TYPE Y[i] *= beta%%
|
52
|
+
}
|
53
|
+
}
|
54
|
+
} else {
|
55
|
+
iy = ky;
|
56
|
+
if (%%TYPE beta == 0%%) {
|
57
|
+
for (i = 0; i < lenY; ++i) {
|
58
|
+
%%TYPE Y[iy] = 0%%
|
59
|
+
iy += incY;
|
60
|
+
}
|
61
|
+
} else {
|
62
|
+
for (i = 0; i < lenY; ++i) {
|
63
|
+
%%TYPE Y[iy] *= beta%%
|
64
|
+
iy += incY;
|
65
|
+
}
|
66
|
+
}
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
if (%%TYPE alpha == 0%%) return 0;
|
71
|
+
|
72
|
+
if (Trans == CblasNoTrans) {
|
73
|
+
|
74
|
+
// Form y := alpha*A*x + y.
|
75
|
+
jx = kx;
|
76
|
+
if (incY == 1) {
|
77
|
+
for (j = 0; j < N; ++j) {
|
78
|
+
if (%%TYPE X[jx] != 0%%) {
|
79
|
+
%%TYPE_LONG temp = alpha * X[jx]%%
|
80
|
+
for (i = 0; i < M; ++i) {
|
81
|
+
%%TYPE Y[i] += A[j+i*lda] * temp%%
|
82
|
+
}
|
83
|
+
}
|
84
|
+
jx += incX;
|
85
|
+
}
|
86
|
+
} else {
|
87
|
+
for (j = 0; j < N; ++j) {
|
88
|
+
if (%%TYPE X[jx] != 0%%) {
|
89
|
+
%%TYPE_LONG temp = alpha * X[jx]%%
|
90
|
+
iy = ky;
|
91
|
+
for (i = 0; i < M; ++i) {
|
92
|
+
%%TYPE Y[iy] += A[j+i*lda] * temp%%
|
93
|
+
iy += incY;
|
94
|
+
}
|
95
|
+
}
|
96
|
+
jx += incX;
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
} else { // TODO: Check that indices are correct! They're switched for C.
|
101
|
+
|
102
|
+
// Form y := alpha*A**T*x + y.
|
103
|
+
jy = ky;
|
104
|
+
|
105
|
+
if (incX == 1) {
|
106
|
+
for (j = 0; j < N; ++j) {
|
107
|
+
%%TYPE temp = 0%%
|
108
|
+
for (i = 0; i < M; ++i) {
|
109
|
+
%%TYPE_LONG temp += A[j+i*lda]*X[j]%%
|
110
|
+
}
|
111
|
+
%%TYPE Y[jy] += alpha * temp%%
|
112
|
+
jy += incY;
|
113
|
+
}
|
114
|
+
} else {
|
115
|
+
for (j = 0; j < N; ++j) {
|
116
|
+
%%TYPE temp = 0%%
|
117
|
+
ix = kx;
|
118
|
+
for (i = 0; i < M; ++i) {
|
119
|
+
%%TYPE_LONG temp += A[j+i*lda] * X[ix]%%
|
120
|
+
ix += incX;
|
121
|
+
}
|
122
|
+
|
123
|
+
%%TYPE Y[jy] += alpha * temp%%
|
124
|
+
jy += incY;
|
125
|
+
}
|
126
|
+
}
|
127
|
+
}
|
128
|
+
|
129
|
+
return 0;
|
130
|
+
} // end of GEMV
|
@@ -0,0 +1,68 @@
|
|
1
|
+
|
2
|
+
inline %%TYPE%% BOOL2%%= dtype.id.to_s.upcase%%(bool expr) {
|
3
|
+
%%TYPE%% result;
|
4
|
+
result.n = expr;
|
5
|
+
result.d = 1;
|
6
|
+
return result;
|
7
|
+
}
|
8
|
+
|
9
|
+
inline %%TYPE%% %%TYPE_ABBREV%%_bang(%%= dtype.sym == :rational128 ? "int64_t n, int64_t d" : (dtype.sym == :rational64 ? "int32_t n, int32_t d" : "int16_t n, int16_t d")%%)
|
10
|
+
{
|
11
|
+
%%TYPE%% result = {!n, 1};
|
12
|
+
return result;
|
13
|
+
}
|
14
|
+
|
15
|
+
inline %%TYPE%% %%TYPE_ABBREV%%_negate(%%= dtype.sym == :rational128 ? "int64_t n, int64_t d" : (dtype.sym == :rational64 ? "int32_t n, int32_t d" : "int16_t n, int16_t d")%%)
|
16
|
+
{
|
17
|
+
%%TYPE%% result = {-n, -d};
|
18
|
+
return result;
|
19
|
+
}
|
20
|
+
|
21
|
+
inline %%TYPE%% %%TYPE_ABBREV%%_muldiv(int64_t anum, int64_t aden, int64_t bnum, int64_t bden, char k) {
|
22
|
+
%%TYPE%% result;
|
23
|
+
int64_t t, g1, g2;
|
24
|
+
|
25
|
+
if (k == '/') { // Switch numerator and denominator for division (and move sign)
|
26
|
+
if (bnum < 0) {
|
27
|
+
anum = -anum;
|
28
|
+
bnum = -bnum;
|
29
|
+
}
|
30
|
+
t = bnum;
|
31
|
+
bnum = bden;
|
32
|
+
bden = t;
|
33
|
+
}
|
34
|
+
|
35
|
+
g1 = nmrb_gcd(anum, bden);
|
36
|
+
g2 = nmrb_gcd(aden, bnum);
|
37
|
+
|
38
|
+
result.n = (anum / g1) * (bnum / g2);
|
39
|
+
result.d = (aden / g2) * (bden / g1);
|
40
|
+
|
41
|
+
return result;
|
42
|
+
}
|
43
|
+
|
44
|
+
inline %%TYPE%% %%TYPE_ABBREV%%_addsub(int64_t anum, int64_t aden, int64_t bnum, int64_t bden, char k) {
|
45
|
+
%%TYPE%% result;
|
46
|
+
|
47
|
+
int64_t ig = nmrb_gcd(aden, bden);
|
48
|
+
int64_t a = anum * (bden / ig);
|
49
|
+
int64_t b = bnum * (aden / ig);
|
50
|
+
int64_t c;
|
51
|
+
|
52
|
+
if (k == '+') c=a+b;
|
53
|
+
else c=a-b;
|
54
|
+
|
55
|
+
b = aden / ig;
|
56
|
+
ig = nmrb_gcd(aden, ig);
|
57
|
+
result.n = c / ig;
|
58
|
+
a = bden / ig;
|
59
|
+
result.d = a*b;
|
60
|
+
|
61
|
+
return result;
|
62
|
+
}
|
63
|
+
|
64
|
+
inline %%TYPE%% %%TYPE_ABBREV%%_mod(%%= dtype.sym == :rational128 ? "int64_t anum, int64_t aden, int64_t bnum, int64_t bden" : (dtype.sym == :rational64 ? "int32_t anum, int32_t aden, int32_t bnum, int32_t bden" : "int16_t anum, int16_t aden, int16_t bnum, int16_t bden")%%)
|
65
|
+
{
|
66
|
+
// a - (b * int(a/b))
|
67
|
+
return %%TYPE_ABBREV%%_addsub(anum, aden, bnum*((int64_t)((anum * bden) / (aden * bnum))), bden, '-');
|
68
|
+
}
|
data/ext/nmatrix/depend
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
dtypes.h dtypes.c smmp1.c smmp2.c blas.c: generator.rb
|
2
|
+
$(RUBY) -I$(srcdir) $(srcdir)/generator.rb
|
3
|
+
|
4
|
+
blas.o: blas.c
|
5
|
+
|
6
|
+
smmp2.o: smmp1.c smmp2.c nmatrix.h yale/smmp2_header.template.c yale/symbmm.template.c yale/transp.template.c yale/numbmm.template.c
|
7
|
+
|
8
|
+
smmp1.o: smmp1.c nmatrix_config.h nmatrix.h yale/smmp1_header.template.c
|
9
|
+
|
10
|
+
dfuncs.o: dfuncs.c $(hdrdir)/ruby.h
|
11
|
+
|
12
|
+
$(DLLIB): dtypes.h dtypes.c dfuncs.c $(OBJS) Makefile
|
13
|
+
# $(ECHO) linking shared-object $(DLLIB)
|
14
|
+
@-$(RM) $(@)
|
15
|
+
$(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
|
16
|
+
|
17
|
+
soclean:
|
18
|
+
@-$(RM) *.so *.o *.bundle
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# = NMatrix
|
2
|
+
#
|
3
|
+
# A linear algebra library for scientific computation in Ruby.
|
4
|
+
# NMatrix is part of SciRuby.
|
5
|
+
#
|
6
|
+
# NMatrix was originally inspired by and derived from NArray, by
|
7
|
+
# Masahiro Tanaka: http://narray.rubyforge.org
|
8
|
+
#
|
9
|
+
# == Copyright Information
|
10
|
+
#
|
11
|
+
# SciRuby is Copyright (c) 2010 - 2012, Ruby Science Foundation
|
12
|
+
# NMatrix is Copyright (c) 2012, Ruby Science Foundation
|
13
|
+
#
|
14
|
+
# Please see LICENSE.txt for additional copyright notices.
|
15
|
+
#
|
16
|
+
# == Contributing
|
17
|
+
#
|
18
|
+
# By contributing source code to SciRuby, you agree to be bound by
|
19
|
+
# our Contributor Agreement:
|
20
|
+
#
|
21
|
+
# * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
|
22
|
+
#
|
23
|
+
# == extconf.rb
|
24
|
+
#
|
25
|
+
# This file mostly derived from NArray.
|
26
|
+
|
27
|
+
require "mkmf"
|
28
|
+
|
29
|
+
|
30
|
+
def have_type(type, header=nil)
|
31
|
+
printf "checking for %s... ", type
|
32
|
+
STDOUT.flush
|
33
|
+
|
34
|
+
src = <<"SRC"
|
35
|
+
#include <ruby.h>
|
36
|
+
SRC
|
37
|
+
|
38
|
+
|
39
|
+
src << <<"SRC" unless header.nil?
|
40
|
+
#include <#{header}>
|
41
|
+
SRC
|
42
|
+
|
43
|
+
r = try_link(src + <<"SRC")
|
44
|
+
int main() { return 0; }
|
45
|
+
int t() { #{type} a; return 0; }
|
46
|
+
SRC
|
47
|
+
|
48
|
+
unless r
|
49
|
+
print "no\n"
|
50
|
+
return false
|
51
|
+
end
|
52
|
+
|
53
|
+
$defs.push(format("-DHAVE_%s", type.upcase))
|
54
|
+
|
55
|
+
print "yes\n"
|
56
|
+
|
57
|
+
return true
|
58
|
+
end
|
59
|
+
|
60
|
+
def create_conf_h(file)
|
61
|
+
print "creating #{file}\n"
|
62
|
+
hfile = open(file, "w")
|
63
|
+
for line in $defs
|
64
|
+
line =~ /^-D(.*)/
|
65
|
+
hfile.printf "#define %s 1\n", $1
|
66
|
+
end
|
67
|
+
hfile.close
|
68
|
+
end
|
69
|
+
|
70
|
+
if RUBY_VERSION < '1.9'
|
71
|
+
raise(NotImplementedError, "Sorry, you need Ruby 1.9!")
|
72
|
+
else
|
73
|
+
$INSTALLFILES = [['nmatrix.h', '$(archdir)'], ['nmatrix_config.h', '$(archdir)']]
|
74
|
+
if /cygwin|mingw/ =~ RUBY_PLATFORM
|
75
|
+
$INSTALLFILES << ['libnmatrix.a', '$(archdir)']
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
if /cygwin|mingw/ =~ RUBY_PLATFORM
|
80
|
+
CONFIG["DLDFLAGS"] << " --output-lib libnmatrix.a"
|
81
|
+
end
|
82
|
+
|
83
|
+
$DEBUG = true
|
84
|
+
$CFLAGS = ["-Wall ",$CFLAGS].join(" ") #-BENCHMARK for comparing transp
|
85
|
+
|
86
|
+
srcs = %w(
|
87
|
+
nmatrix
|
88
|
+
list
|
89
|
+
dense
|
90
|
+
yale
|
91
|
+
dfuncs
|
92
|
+
smmp1
|
93
|
+
smmp2
|
94
|
+
cblas
|
95
|
+
blas
|
96
|
+
rational
|
97
|
+
)
|
98
|
+
# add smmp in to get generic transp; remove smmp2 to eliminate funcptr transp
|
99
|
+
|
100
|
+
header = "stdint.h"
|
101
|
+
unless have_header(header)
|
102
|
+
header = "sys/types.h"
|
103
|
+
unless have_header(header)
|
104
|
+
header = nil
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
have_type("u_int8_t", header)
|
109
|
+
have_type("uint8_t", header)
|
110
|
+
have_type("u_int16_t", header)
|
111
|
+
have_type("uint16_t", header)
|
112
|
+
have_type("int16_t", header)
|
113
|
+
have_type("int32_t", header)
|
114
|
+
have_type("u_int32_t", header)
|
115
|
+
have_type("uint32_t", header)
|
116
|
+
have_type("int64_t", header)
|
117
|
+
have_type("u_int64_t", header)
|
118
|
+
have_type("uint64_t", header)
|
119
|
+
|
120
|
+
unless have_type("size_t", header)
|
121
|
+
have_type("size_t", "stddef.h")
|
122
|
+
end
|
123
|
+
|
124
|
+
# dir_config("cblas")
|
125
|
+
# dir_config("atlas")
|
126
|
+
|
127
|
+
find_library("cblas", "cblas_dgemm", "/usr/local/lib", "/usr/local/atlas/lib")
|
128
|
+
find_library("atlas", "ATL_dgemmNN", "/usr/local/lib", "/usr/local/atlas/lib", "/usr/lib")
|
129
|
+
find_header("cblas.h", "/usr/local/include", "/usr/local/atlas/include")
|
130
|
+
|
131
|
+
have_library("f2c")
|
132
|
+
have_header("f2c.h")
|
133
|
+
|
134
|
+
|
135
|
+
$libs += " -lcblas -latlas "
|
136
|
+
|
137
|
+
$objs = srcs.collect{|i| i+".o" }
|
138
|
+
|
139
|
+
$CFLAGS += " -O0"
|
140
|
+
|
141
|
+
create_conf_h("nmatrix_config.h")
|
142
|
+
create_makefile("nmatrix")
|
143
|
+
|