kmat 0.0.3
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 +7 -0
- data/.gitattributes +3 -0
- data/.gitignore +15 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile +4 -0
- data/LICENSE.md +675 -0
- data/README.md +224 -0
- data/Rakefile +26 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ext/kmat/arith/binary.c +1121 -0
- data/ext/kmat/arith/logical.c +332 -0
- data/ext/kmat/arith/math.c +34 -0
- data/ext/kmat/arith/statistics.c +173 -0
- data/ext/kmat/arith/unary.c +165 -0
- data/ext/kmat/auto_collect.rb +118 -0
- data/ext/kmat/elementwise_function.rb +149 -0
- data/ext/kmat/extconf.rb +75 -0
- data/ext/kmat/id.txt +80 -0
- data/ext/kmat/id_sym.rb +40 -0
- data/ext/kmat/km_util.h +97 -0
- data/ext/kmat/kmat.h +96 -0
- data/ext/kmat/lapack_headers/blas.h +354 -0
- data/ext/kmat/lapack_headers/lapacke.h +19455 -0
- data/ext/kmat/lapack_headers/lapacke_config.h +119 -0
- data/ext/kmat/lapack_headers/lapacke_mangling.h +17 -0
- data/ext/kmat/lapack_headers/lapacke_utils.h +579 -0
- data/ext/kmat/linalg/dla.c +1629 -0
- data/ext/kmat/linalg/linalg.c +267 -0
- data/ext/kmat/linalg/norm.c +727 -0
- data/ext/kmat/linalg/vla.c +102 -0
- data/ext/kmat/linalg/working.c +240 -0
- data/ext/kmat/main.c +95 -0
- data/ext/kmat/smat/accessor.c +719 -0
- data/ext/kmat/smat/array.c +108 -0
- data/ext/kmat/smat/boxmuller.c +72 -0
- data/ext/kmat/smat/constructer.c +302 -0
- data/ext/kmat/smat/convert.c +375 -0
- data/ext/kmat/smat/elem.c +171 -0
- data/ext/kmat/smat/fund.c +702 -0
- data/ext/kmat/smat/share.c +427 -0
- data/ext/kmat/smat/smat.c +530 -0
- data/ext/kmat/smat/sort.c +1156 -0
- data/ext/kmat/sym.txt +34 -0
- data/kmat.gemspec +46 -0
- data/lib/kmat.rb +20 -0
- data/lib/kmat/accessor.rb +164 -0
- data/lib/kmat/arith.rb +189 -0
- data/lib/kmat/linalg.rb +279 -0
- data/lib/kmat/logical.rb +150 -0
- data/lib/kmat/misc.rb +122 -0
- data/lib/kmat/random.rb +106 -0
- data/lib/kmat/statistics.rb +98 -0
- data/lib/kmat/version.rb +3 -0
- metadata +156 -0
@@ -0,0 +1,165 @@
|
|
1
|
+
#include "../kmat.h"
|
2
|
+
|
3
|
+
static void
|
4
|
+
km_abs_func_d(double *ent, void *data)
|
5
|
+
{
|
6
|
+
*ent = fabs(*ent);
|
7
|
+
}
|
8
|
+
static void
|
9
|
+
km_abs_func_z(COMPLEX *ent, void *data)
|
10
|
+
{
|
11
|
+
*ent = cpack(cabs(*ent), 0.0);
|
12
|
+
}
|
13
|
+
static void
|
14
|
+
km_abs_func_i(int *ent, void *data)
|
15
|
+
{
|
16
|
+
*ent = ABS(*ent);
|
17
|
+
}
|
18
|
+
static void
|
19
|
+
km_abs_func_v(VALUE *ent, void *data)
|
20
|
+
{
|
21
|
+
*ent = rb_funcall(*ent, id_abs, 0);
|
22
|
+
}
|
23
|
+
VALUE
|
24
|
+
kmm_mat_abs_destl(VALUE self)
|
25
|
+
{
|
26
|
+
km_check_frozen(self);
|
27
|
+
SMAT *smat = km_mat2smat(self);
|
28
|
+
VT_SWITCH( smat->vtype,
|
29
|
+
km_smat_each_d(smat, km_abs_func_d, NULL);,
|
30
|
+
km_smat_each_z(smat, km_abs_func_z, NULL);,
|
31
|
+
km_smat_each_i(smat, km_abs_func_i, NULL);,
|
32
|
+
/* nothing to do */,
|
33
|
+
km_smat_each_v(smat, km_abs_func_v, NULL);
|
34
|
+
);
|
35
|
+
return self;
|
36
|
+
}
|
37
|
+
static void
|
38
|
+
km_cabs_func(double *dest, const COMPLEX *src, void *data)
|
39
|
+
{
|
40
|
+
*dest = cabs(*src);
|
41
|
+
}
|
42
|
+
VALUE
|
43
|
+
kmm_mat_abs(VALUE self)
|
44
|
+
{
|
45
|
+
SMAT *smat = km_mat2smat(self);
|
46
|
+
if ( smat->vtype == VT_COMPLEX ) {
|
47
|
+
VALUE ret = km_Mat(smat->m, smat->n, VT_DOUBLE);
|
48
|
+
km_smat_each2_dcz(km_mat2smat(ret), smat, km_cabs_func, NULL);
|
49
|
+
return ret;
|
50
|
+
} else {
|
51
|
+
return kmm_mat_abs_destl(rb_obj_dup(self));
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
static void
|
56
|
+
km_uminus_func_d(double *ent, void *data)
|
57
|
+
{
|
58
|
+
*ent = -(*ent);
|
59
|
+
}
|
60
|
+
static void
|
61
|
+
km_uminus_func_z(COMPLEX *ent, void *data)
|
62
|
+
{
|
63
|
+
*ent = -(*ent);
|
64
|
+
}
|
65
|
+
static void
|
66
|
+
km_uminus_func_i(int *ent, void *data)
|
67
|
+
{
|
68
|
+
*ent = -(*ent);
|
69
|
+
}
|
70
|
+
static void
|
71
|
+
km_uminus_func_v(VALUE *ent, void *data)
|
72
|
+
{
|
73
|
+
*ent = rb_funcall(*ent, id_op_uminus, 0);
|
74
|
+
}
|
75
|
+
VALUE
|
76
|
+
kmm_mat_uminus_destl(VALUE self)
|
77
|
+
{
|
78
|
+
km_check_frozen(self);
|
79
|
+
SMAT *smat = km_mat2smat(self);
|
80
|
+
VT_SWITCH( smat->vtype,
|
81
|
+
km_smat_each_d(smat, km_uminus_func_d, NULL);,
|
82
|
+
km_smat_each_z(smat, km_uminus_func_z, NULL);,
|
83
|
+
km_smat_each_i(smat, km_uminus_func_i, NULL);,
|
84
|
+
/* nothing to do */,
|
85
|
+
km_smat_each_v(smat, km_uminus_func_v, NULL);
|
86
|
+
);
|
87
|
+
return self;
|
88
|
+
}
|
89
|
+
// alias -@
|
90
|
+
VALUE
|
91
|
+
kmm_mat_uminus(VALUE self)
|
92
|
+
{
|
93
|
+
return kmm_mat_uminus_destl(rb_obj_dup(self));
|
94
|
+
}
|
95
|
+
|
96
|
+
static void
|
97
|
+
km_conj_func_z(COMPLEX *ent, void *data)
|
98
|
+
{
|
99
|
+
*ent = conj(*ent);
|
100
|
+
}
|
101
|
+
static void
|
102
|
+
km_conj_func_v(VALUE *ent, void *data)
|
103
|
+
{
|
104
|
+
*ent = rb_funcall(*ent, id_conj, 0);
|
105
|
+
}
|
106
|
+
// alias conjugate
|
107
|
+
VALUE
|
108
|
+
kmm_mat_conj_dest(VALUE self)
|
109
|
+
{
|
110
|
+
km_check_frozen(self);
|
111
|
+
SMAT *smat = km_mat2smat(self);
|
112
|
+
if ( smat->vtype == VT_COMPLEX ) {
|
113
|
+
km_smat_each_z(smat, km_conj_func_z, NULL);
|
114
|
+
} else if ( smat->vtype == VT_VALUE ) {
|
115
|
+
km_smat_each_v(smat, km_conj_func_v, NULL);
|
116
|
+
}
|
117
|
+
return self;
|
118
|
+
}
|
119
|
+
|
120
|
+
// trace
|
121
|
+
// alias tr
|
122
|
+
VALUE
|
123
|
+
kmm_mat_trace(VALUE self)
|
124
|
+
{
|
125
|
+
SMAT *smat = km_mat2smat(self);
|
126
|
+
int len = MIN(smat->m, smat->n);
|
127
|
+
if ( smat->vtype == VT_DOUBLE ) {
|
128
|
+
double ret = 0.0;
|
129
|
+
for ( int i=0; i<len; i++ ) {
|
130
|
+
ret += ENTITY(smat, d, i, i);
|
131
|
+
}
|
132
|
+
return rb_float_new(ret);
|
133
|
+
} else if ( smat->vtype == VT_COMPLEX ) {
|
134
|
+
COMPLEX ret = cpack(0.0, 0.0);
|
135
|
+
for ( int i=0; i<len; i++ ) {
|
136
|
+
ret += ENTITY(smat, z, i, i);
|
137
|
+
}
|
138
|
+
return km_c2v(ret);
|
139
|
+
} else if ( smat->vtype == VT_INT ) {
|
140
|
+
int ret = 0;
|
141
|
+
for ( int i=0; i<len; i++ ) {
|
142
|
+
ret += ENTITY(smat, i, i, i);
|
143
|
+
}
|
144
|
+
return INT2NUM(ret);
|
145
|
+
} else if ( smat->vtype == VT_BOOL ) {
|
146
|
+
bool ret = false;
|
147
|
+
for ( int i=0; i<len; i++ ) {
|
148
|
+
bool ent = ENTITY(smat, b, i, i);
|
149
|
+
ret = XOR(ret, ent);
|
150
|
+
}
|
151
|
+
return TF2V(ret);
|
152
|
+
} else if ( smat->vtype == VT_VALUE ) {
|
153
|
+
if ( len == 0 ) {
|
154
|
+
return INT2NUM(0);
|
155
|
+
} else {
|
156
|
+
VALUE ret = ENTITY(smat, v, 0, 0);
|
157
|
+
for ( int i=1; i<len; i++ ) {
|
158
|
+
ret = rb_funcall(ret, id_op_plus, 1, ENTITY(smat, v, i, i));
|
159
|
+
}
|
160
|
+
return ret;
|
161
|
+
}
|
162
|
+
} else {
|
163
|
+
rb_raise(km_eInternal, "unknown value type");
|
164
|
+
}
|
165
|
+
}
|
@@ -0,0 +1,118 @@
|
|
1
|
+
|
2
|
+
class MethodDefinition
|
3
|
+
def initialize(name_arg, comment)
|
4
|
+
comment = %r|//\s+(.*)|.match(comment)[1]
|
5
|
+
@als = /\Aalias (.+)/.match(comment)&.[](1)&.split(/[,\s]\s*/)
|
6
|
+
@meth = /\Akmm_/.match(name_arg)
|
7
|
+
return unless @meth
|
8
|
+
m = %r|\A(kmm_([^\(_]+)_([^\(]+))\((.+)\)\Z|.match(name_arg)
|
9
|
+
raise "unknown name_arg pattern `#{name_arg}' found" unless m
|
10
|
+
@funcname, @type, @name, arg = m[1], type_trans(m[2]), m[3], m[4]
|
11
|
+
if m = %r|(.+)_p\Z|.match(@name)
|
12
|
+
@name = m[1]+'?'
|
13
|
+
elsif m = %r|(.+)_dest\Z|.match(@name)
|
14
|
+
@name = m[1]
|
15
|
+
@dup_esc = true
|
16
|
+
elsif m = %r|(.+)_destl\Z|.match(@name)
|
17
|
+
@name = m[1]+'!'
|
18
|
+
end
|
19
|
+
if m = %r|(.+)_m2\Z|.match(@name)
|
20
|
+
@name = m[1]
|
21
|
+
@argc = -2
|
22
|
+
elsif m = %r|\Aint argc|.match(arg)
|
23
|
+
@argc = -1
|
24
|
+
else
|
25
|
+
@argc = arg.split(/,/).size-1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
attr_reader :meth
|
29
|
+
|
30
|
+
def type_trans(t)
|
31
|
+
case t
|
32
|
+
when 'obj'
|
33
|
+
'rb_cObject'
|
34
|
+
when 'mat'
|
35
|
+
'km_cMat'
|
36
|
+
when 'Mat'
|
37
|
+
'km_sMat'
|
38
|
+
when 'ary'
|
39
|
+
'rb_cArray'
|
40
|
+
when 'MATH'
|
41
|
+
['rb_mMath', 'rb_sMath']
|
42
|
+
when 'float'
|
43
|
+
'rb_cFloat'
|
44
|
+
else
|
45
|
+
raise "unknown type `#{t}' found"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_s(join="\n\t")
|
50
|
+
ret = []
|
51
|
+
if @type.kind_of?(Array)
|
52
|
+
ret << %Q|rb_define_module_function(#{@type[0]}, "#{@name}", #{@funcname}, #{@argc});|
|
53
|
+
elsif %r|\A\_|.match(@name)
|
54
|
+
ret << %Q|rb_define_private_method(#{@type}, "#{@name}", #{@funcname}, #{@argc});|
|
55
|
+
elsif @dup_esc
|
56
|
+
ret << %Q|rb_define_method(#{@type}, "#{@name}!", #{@funcname}, #{@argc});|
|
57
|
+
ret << %Q|rb_funcall(km_cMat, id__define_dup_escaped_method, 1, rb_str_new_cstr("#{@name}"));|
|
58
|
+
else
|
59
|
+
ret << %Q|rb_define_method(#{@type}, "#{@name}", #{@funcname}, #{@argc});|
|
60
|
+
end
|
61
|
+
@als&.each do |a|
|
62
|
+
if @type.kind_of?(Array)
|
63
|
+
ret << %Q|rb_define_alias(#{@type[0]}, "#{a}", "#{@name}");|
|
64
|
+
ret << %Q|rb_define_alias(#{@type[1]}, "#{a}", "#{@name}");|
|
65
|
+
else
|
66
|
+
ret << %Q|rb_define_alias(#{@type}, "#{a}", "#{@name}");|
|
67
|
+
ret << %Q|rb_define_alias(#{@type}, "#{a}!", "#{@name}!");| if @dup_esc
|
68
|
+
end
|
69
|
+
end
|
70
|
+
ret.join(join)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
defs, decs = [], []
|
75
|
+
|
76
|
+
# for all .c files
|
77
|
+
Dir.glob("#{__dir__}/**/*.c").each do |file|
|
78
|
+
# for lines that comment line (can be omitted), return type and modifier line, function name and argument line
|
79
|
+
File.read(file).gsub(%r|(//[^\n]+\n)?[^#/{}\n\s][^\n;]+\n[^#/{}\n\s][^\n;]+\n{\n|) do |m|
|
80
|
+
ary = m.split(/\n/)
|
81
|
+
# functions which name start with kmm_ are methods
|
82
|
+
if ary.size == 4
|
83
|
+
foo = MethodDefinition.new(ary[2], ary[0])
|
84
|
+
else
|
85
|
+
foo = MethodDefinition.new(ary[1], '// ')
|
86
|
+
end
|
87
|
+
defs << foo.to_s if foo.meth
|
88
|
+
# ignore static functions and static variables
|
89
|
+
unless /\Astatic/.match(ary[-3])
|
90
|
+
decs << "#{ary[-3]} #{ary[-2]};"
|
91
|
+
end
|
92
|
+
''
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
File.open('./auto_collected.h', 'w') do |f|
|
98
|
+
decs.each do |dec|
|
99
|
+
f.puts dec
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
File.open('./method_definitions.c', 'w') do |f|
|
104
|
+
f.puts "static void\nkm_define_methods(void)\n{"
|
105
|
+
defs.each do |def_|
|
106
|
+
f.puts "\t#{def_}"
|
107
|
+
end
|
108
|
+
f.puts '}'
|
109
|
+
end
|
110
|
+
|
111
|
+
File.open('./global_variables.h', 'w') do |f|
|
112
|
+
flg = false
|
113
|
+
File.foreach("#{__dir__}/main.c") do |line|
|
114
|
+
flg = true if line == "// km_global_variables_begin\n"
|
115
|
+
f.puts "extern #{line}" if flg && !%r|\A// km_global_variables|.match(line) && !%r|\A\s*\n\Z|.match(line)
|
116
|
+
break if line == "// km_global_variables_end\n"
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
both = %w(sin cos tan asin acos atan sinh cosh tanh asinh acosh atanh exp log sqrt)
|
2
|
+
fonly = %w(exp2 expm1 log10 log1p log2 logb cbrt erf erfc lgamma tgamma ceil floor round trunc sign)
|
3
|
+
dz = %w(real imag arg)
|
4
|
+
|
5
|
+
File.open('elementwise_function.c', 'w') do |f|
|
6
|
+
f.puts 'static double sign(double x){ return ( x==0.0 ? 0.0 : ( x>0.0 ? 1.0 : ( x<0.0 ? -1.0 : x ))); }'
|
7
|
+
|
8
|
+
both.each do |func|
|
9
|
+
f.puts <<"EOS"
|
10
|
+
static void
|
11
|
+
km_#{func}_d(double *ent, void *null)
|
12
|
+
{
|
13
|
+
*ent = #{func}(*ent);
|
14
|
+
}
|
15
|
+
static void
|
16
|
+
km_#{func}_z(COMPLEX *ent, void *null)
|
17
|
+
{
|
18
|
+
*ent = c#{func}(*ent);
|
19
|
+
}
|
20
|
+
static void
|
21
|
+
km_#{func}_v(VALUE *ent, void *null)
|
22
|
+
{
|
23
|
+
*ent = rb_funcall(rb_mMath, id_#{func}, 1, *ent);
|
24
|
+
}
|
25
|
+
VALUE
|
26
|
+
kmm_mat_#{func}_dest(VALUE self)
|
27
|
+
{
|
28
|
+
km_check_frozen(self);
|
29
|
+
SMAT *smat = km_mat2smat(self);
|
30
|
+
if ( smat->vtype == VT_DOUBLE ) {
|
31
|
+
km_smat_each_d(smat, km_#{func}_d, NULL);
|
32
|
+
} else if ( smat->vtype == VT_COMPLEX ) {
|
33
|
+
km_smat_each_z(smat, km_#{func}_z, NULL);
|
34
|
+
} else if ( smat->vtype == VT_VALUE ) {
|
35
|
+
km_smat_each_v(smat, km_#{func}_v, NULL);
|
36
|
+
} else {
|
37
|
+
rb_raise(km_eVT, "the method is available only for float or complex matricies");
|
38
|
+
}
|
39
|
+
return self;
|
40
|
+
}
|
41
|
+
EOS
|
42
|
+
end
|
43
|
+
|
44
|
+
fonly.each do |func|
|
45
|
+
f.puts <<"EOS"
|
46
|
+
static void
|
47
|
+
km_#{func}_d(double *ent, void *null)
|
48
|
+
{
|
49
|
+
*ent = #{func}(*ent);
|
50
|
+
}
|
51
|
+
static void
|
52
|
+
km_#{func}_v(VALUE *ent, void *null)
|
53
|
+
{
|
54
|
+
*ent = rb_funcall(rb_mMath, id_#{func}, 1, *ent);
|
55
|
+
}
|
56
|
+
VALUE
|
57
|
+
kmm_mat_#{func}_dest(VALUE self)
|
58
|
+
{
|
59
|
+
km_check_frozen(self);
|
60
|
+
SMAT *smat = km_mat2smat(self);
|
61
|
+
if ( smat->vtype == VT_DOUBLE ) {
|
62
|
+
km_smat_each_d(smat, km_#{func}_d, NULL);
|
63
|
+
} else if ( smat->vtype == VT_VALUE ) {
|
64
|
+
km_smat_each_v(smat, km_#{func}_v, NULL);
|
65
|
+
} else {
|
66
|
+
rb_raise(km_eVT, "the method is available only for float matricies");
|
67
|
+
}
|
68
|
+
return self;
|
69
|
+
}
|
70
|
+
EOS
|
71
|
+
end
|
72
|
+
f.puts <<'EOS'
|
73
|
+
static VALUE
|
74
|
+
km_zmat_e_funcapp(VALUE self, void (*func)(COMPLEX *, void *))
|
75
|
+
{
|
76
|
+
km_check_frozen(self);
|
77
|
+
SMAT *smat = km_mat2smat(self);
|
78
|
+
if ( smat->vtype != VT_COMPLEX ) {
|
79
|
+
rb_raise(km_eVT, "the method is available only for complex matrcies");
|
80
|
+
}
|
81
|
+
km_smat_each_z(smat, func, NULL);
|
82
|
+
return self;
|
83
|
+
}
|
84
|
+
static VALUE
|
85
|
+
km_zdmat_e_funcapp(VALUE self, VALUE op, void (*func)(double *, const COMPLEX *, void *))
|
86
|
+
{
|
87
|
+
km_check_frozen(op);
|
88
|
+
SMAT *dest = km_mat2smat(op), *src = km_mat2smat(self);
|
89
|
+
if ( dest->vtype != VT_DOUBLE || src->vtype != VT_COMPLEX ) {
|
90
|
+
rb_raise(km_eVT, "self(operand) and argument(output) must be complex and float matrix, respectively");
|
91
|
+
}
|
92
|
+
CHECK_SAME_SIZE(dest, src);
|
93
|
+
km_smat_each2_dcz(dest, src, func, NULL);
|
94
|
+
return op;
|
95
|
+
}
|
96
|
+
EOS
|
97
|
+
dz.each do |func|
|
98
|
+
f.puts <<"EOS"
|
99
|
+
static void
|
100
|
+
km_#{func}_z(COMPLEX *ent, void *null)
|
101
|
+
{
|
102
|
+
*ent = cpack(c#{func}(*ent), 0.0);
|
103
|
+
}
|
104
|
+
static void
|
105
|
+
km_#{func}_dcz(double *dest, const COMPLEX *src, void *null)
|
106
|
+
{
|
107
|
+
*dest = c#{func}(*src);
|
108
|
+
}
|
109
|
+
VALUE
|
110
|
+
kmm_mat_#{func}_destl(int argc, VALUE *argv, VALUE self)
|
111
|
+
{
|
112
|
+
rb_check_arity(argc, 0, 1);
|
113
|
+
if ( argc == 0 ) {
|
114
|
+
return km_zmat_e_funcapp(self, km_#{func}_z);
|
115
|
+
} else {
|
116
|
+
return km_zdmat_e_funcapp(self, argv[0], km_#{func}_dcz);
|
117
|
+
}
|
118
|
+
}
|
119
|
+
VALUE
|
120
|
+
kmm_mat_#{func}(VALUE self)
|
121
|
+
{
|
122
|
+
SMAT *smat = km_mat2smat(self);
|
123
|
+
return km_zdmat_e_funcapp(self, km_Mat(smat->m, smat->n, VT_DOUBLE), km_#{func}_dcz);
|
124
|
+
}
|
125
|
+
EOS
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
File.open('elementwise_function.h', 'w') do |f|
|
130
|
+
(both+fonly).each do |func|
|
131
|
+
f.puts "VALUE kmm_mat_#{func}_dest(VALUE self);"
|
132
|
+
end
|
133
|
+
dz.each do |func|
|
134
|
+
f.puts "VALUE kmm_mat_#{func}_destl(int argc, VALUE *argv, VALUE self);"
|
135
|
+
f.puts "VALUE kmm_mat_#{func}(VALUE self);"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
File.open('elementwise_function_definitions.c', 'w') do |f|
|
139
|
+
f.puts "static void\nkm_define_efs(void)\n{"
|
140
|
+
(both+fonly).each do |func|
|
141
|
+
f.puts %Q|\trb_define_method(km_cMat, "#{func}!", kmm_mat_#{func}_dest, 0);|
|
142
|
+
f.puts %Q|\trb_funcall(km_cMat, id__define_dup_escaped_method, 1, rb_str_new_cstr("#{func}"));|
|
143
|
+
end
|
144
|
+
dz.each do |func|
|
145
|
+
f.puts %Q|\trb_define_method(km_cMat, "#{func}!", kmm_mat_#{func}_destl, -1);|
|
146
|
+
f.puts %Q|\trb_define_method(km_cMat, "#{func}", kmm_mat_#{func}, 0);|
|
147
|
+
end
|
148
|
+
f.puts "}"
|
149
|
+
end
|
data/ext/kmat/extconf.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require "mkmf"
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
if find_library("mkl_rt", nil, "/opt/intel/mkl/lib/intel64")
|
5
|
+
puts "It is set to use Intel MKL for BLAS/LAPACK functions."
|
6
|
+
mkl = true
|
7
|
+
elsif have_library("blas") && have_library("lapack")
|
8
|
+
puts "It is set to use BLAS/LAPACK."
|
9
|
+
mkl = false
|
10
|
+
else
|
11
|
+
puts "Intel MKL or BLAS/LAPACK is neaded to build this library."
|
12
|
+
exit
|
13
|
+
end
|
14
|
+
|
15
|
+
$CFLAGS = "$(cflags) -std=c11"
|
16
|
+
$CFLAGS += " -m64" if mkl
|
17
|
+
|
18
|
+
#$warnflags = "-Wall -Wextra -Wdeprecated-declarations -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wmissing-noreturn -Wno-unused-parameter -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wno-maybe-uninitialized -Winit-self -Wshadow"
|
19
|
+
$warnflags = "-Wall -Wextra -Wdeprecated-declarations -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wmissing-noreturn -Wno-unused-parameter -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Winit-self -Wshadow -Wlogical-op -Wconversion"
|
20
|
+
|
21
|
+
$DLDFLAGS += " -Wl,-Bsymbolic -fPIC"
|
22
|
+
$DLDFLAGS += " -Wl,--no-as-needed" if mkl
|
23
|
+
|
24
|
+
|
25
|
+
# set .c files in subdirectories as source
|
26
|
+
$objs = Dir.glob("#{__dir__}/**/*.c").map do |file|
|
27
|
+
file[-1] = 'o'
|
28
|
+
obj = %r|#{__dir__}/(.+)|.match(file)[1]
|
29
|
+
if m = %r|(.+)/[^/]+|.match(obj)
|
30
|
+
FileUtils.mkdir_p(m[1]) unless FileTest.exist?(m[1])
|
31
|
+
end
|
32
|
+
obj
|
33
|
+
end
|
34
|
+
|
35
|
+
srcs = $objs.map do |file|
|
36
|
+
file = file.dup
|
37
|
+
file[-1] = 'c'
|
38
|
+
"$(srcdir)/#{file}"
|
39
|
+
end
|
40
|
+
|
41
|
+
create_makefile("kmat/kmat")
|
42
|
+
|
43
|
+
# change variables after Makefile created
|
44
|
+
File.open('./__Makefile__temp__', 'w') do |f|
|
45
|
+
File.foreach('Makefile') do |line|
|
46
|
+
if ARGV.include?('debug')
|
47
|
+
line.sub!(/^optflags.+/, 'optflags = -O0')
|
48
|
+
else
|
49
|
+
line.sub!(/^debugflags.+/, 'debugflags =')
|
50
|
+
end
|
51
|
+
f.puts line
|
52
|
+
end
|
53
|
+
end
|
54
|
+
File.unlink('./Makefile')
|
55
|
+
FileUtils.move('./__Makefile__temp__', './Makefile')
|
56
|
+
|
57
|
+
# add dependencies
|
58
|
+
File.open('./Makefile', 'a') do |f|
|
59
|
+
f.puts "true_srcs = #{srcs.join(' ')}"
|
60
|
+
|
61
|
+
# invoke auto_collect.rb
|
62
|
+
f.puts "auto_collected.h: auto_collect.rb $(true_srcs)"
|
63
|
+
f.puts "\truby $(srcdir)/auto_collect.rb"
|
64
|
+
|
65
|
+
# invoke id_sym.rb
|
66
|
+
f.puts "id_sym.c id_sym.h: id_sym.rb id.txt sym.txt"
|
67
|
+
f.puts "\truby $(srcdir)/id_sym.rb"
|
68
|
+
|
69
|
+
# invoke elementwise_functions.rb
|
70
|
+
f.puts "elementwise_function.h: elementwise_function.rb"
|
71
|
+
f.puts "\truby $(srcdir)/elementwise_function.rb"
|
72
|
+
|
73
|
+
f.puts '$(OBJS): auto_collected.h id_sym.h elementwise_function.h'
|
74
|
+
f.puts 'main.o: id_sym.c'
|
75
|
+
end
|