BOAST 2.0.2 → 2.1.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/BOAST.gemspec +4 -3
- data/lib/BOAST.rb +1 -0
- data/lib/BOAST/Language/Arithmetic.rb +5 -1
- data/lib/BOAST/Language/BOAST_OpenCL.rb +6 -6
- data/lib/BOAST/Language/Case.rb +11 -11
- data/lib/BOAST/Language/Comment.rb +2 -2
- data/lib/BOAST/Language/Config.rb +5 -5
- data/lib/BOAST/Language/DataTypes.rb +31 -29
- data/lib/BOAST/Language/Expression.rb +16 -16
- data/lib/BOAST/Language/For.rb +6 -6
- data/lib/BOAST/Language/FuncCall.rb +7 -7
- data/lib/BOAST/Language/HighLevelOperators.rb +6 -6
- data/lib/BOAST/Language/If.rb +7 -7
- data/lib/BOAST/Language/Index.rb +31 -31
- data/lib/BOAST/Language/Intrinsics.rb +27 -27
- data/lib/BOAST/Language/OpenMP.rb +19 -19
- data/lib/BOAST/Language/Operators.rb +62 -50
- data/lib/BOAST/Language/Pragma.rb +4 -4
- data/lib/BOAST/Language/Procedure.rb +47 -47
- data/lib/BOAST/Language/Slice.rb +14 -14
- data/lib/BOAST/Language/State.rb +1 -1
- data/lib/BOAST/Language/Transitions.rb +1 -1
- data/lib/BOAST/Language/Variable.rb +83 -90
- data/lib/BOAST/Language/While.rb +4 -4
- data/lib/BOAST/Optimization/Optimization.rb +61 -37
- data/lib/BOAST/Runtime/AffinityProbe.rb +99 -15
- data/lib/BOAST/Runtime/CRuntime.rb +18 -6
- data/lib/BOAST/Runtime/CUDARuntime.rb +11 -7
- data/lib/BOAST/Runtime/CoExecute.rb +77 -0
- data/lib/BOAST/Runtime/CompiledRuntime.rb +274 -110
- data/lib/BOAST/Runtime/Compilers.rb +15 -15
- data/lib/BOAST/Runtime/Config.rb +3 -0
- data/lib/BOAST/Runtime/EnergyProbe.rb +86 -71
- data/lib/BOAST/Runtime/FFIRuntime.rb +1 -1
- data/lib/BOAST/Runtime/FORTRANRuntime.rb +15 -5
- data/lib/BOAST/Runtime/MPPARuntime.rb +30 -19
- data/lib/BOAST/Runtime/OpenCLRuntime.rb +2 -2
- data/lib/BOAST/Runtime/Probe.rb +122 -41
- metadata +29 -8
@@ -1,26 +1,75 @@
|
|
1
1
|
module BOAST
|
2
2
|
|
3
3
|
# @private
|
4
|
-
module
|
4
|
+
module HwlocProbe
|
5
5
|
extend PrivateStateAccessor
|
6
6
|
|
7
|
+
class << self
|
8
|
+
attr_accessor :topology
|
9
|
+
end
|
10
|
+
@topology = nil
|
11
|
+
|
12
|
+
begin
|
13
|
+
require 'hwloc'
|
14
|
+
@topology = Hwloc::Topology::new
|
15
|
+
@topology.load
|
16
|
+
rescue LoadError => e
|
17
|
+
end
|
18
|
+
|
7
19
|
module_function
|
8
20
|
|
9
21
|
def cflags
|
10
|
-
return "-D_GNU_SOURCE"
|
11
22
|
end
|
12
23
|
|
13
24
|
def header
|
14
|
-
get_output.puts "#include <sched.h>"
|
15
25
|
end
|
16
26
|
|
27
|
+
def preamble
|
28
|
+
end
|
29
|
+
|
30
|
+
|
17
31
|
def decl
|
18
|
-
get_output.puts " cpu_set_t _boast_affinity_mask_old;"
|
19
|
-
get_output.puts " int _boast_affinity_set = 0;"
|
20
32
|
end
|
21
33
|
|
22
34
|
def configure
|
23
|
-
|
35
|
+
end
|
36
|
+
|
37
|
+
def start
|
38
|
+
end
|
39
|
+
|
40
|
+
def stop
|
41
|
+
end
|
42
|
+
|
43
|
+
def compute
|
44
|
+
end
|
45
|
+
|
46
|
+
def store
|
47
|
+
end
|
48
|
+
|
49
|
+
def is_available?
|
50
|
+
return !@topology.nil?
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
# @private
|
56
|
+
module PthreadAffinityProbe
|
57
|
+
extend PrivateStateAccessor
|
58
|
+
|
59
|
+
module_function
|
60
|
+
|
61
|
+
def cflags
|
62
|
+
return "-D_GNU_SOURCE"
|
63
|
+
end
|
64
|
+
|
65
|
+
def header
|
66
|
+
get_output.puts "#include <sched.h>"
|
67
|
+
end
|
68
|
+
|
69
|
+
def preamble
|
70
|
+
get_output.puts <<EOF
|
71
|
+
static int _boast_affinity_setup( VALUE _boast_rb_opts, cpu_set_t * _boast_affinity_mask_old );
|
72
|
+
static int _boast_affinity_setup( VALUE _boast_rb_opts, cpu_set_t * _boast_affinity_mask_old ) {
|
24
73
|
if( _boast_rb_opts != Qnil ) {
|
25
74
|
VALUE _boast_affinity_rb_ptr = Qnil;
|
26
75
|
|
@@ -31,18 +80,43 @@ module BOAST
|
|
31
80
|
int _boast_affinity_counter;
|
32
81
|
int _boast_affinity_cpu_number;
|
33
82
|
|
34
|
-
if( TYPE(_boast_affinity_rb_ptr) != T_ARRAY )
|
83
|
+
if( TYPE(_boast_affinity_rb_ptr) != T_ARRAY ) {
|
35
84
|
rb_raise(rb_eArgError, "Option :cpu_affinity should be an array!");
|
85
|
+
}
|
36
86
|
CPU_ZERO(&_boast_affinity_mask);
|
37
87
|
_boast_affinity_cpu_number = RARRAY_LEN(_boast_affinity_rb_ptr);
|
38
|
-
for( _boast_affinity_counter = 0; _boast_affinity_counter < _boast_affinity_cpu_number; _boast_affinity_counter++ )
|
88
|
+
for( _boast_affinity_counter = 0; _boast_affinity_counter < _boast_affinity_cpu_number; _boast_affinity_counter++ ) {
|
39
89
|
CPU_SET(FIX2INT(rb_ary_entry(_boast_affinity_rb_ptr,_boast_affinity_counter)), &_boast_affinity_mask);
|
40
|
-
|
41
|
-
|
90
|
+
}
|
91
|
+
pthread_getaffinity_np(pthread_self(), sizeof(*_boast_affinity_mask_old), _boast_affinity_mask_old);
|
92
|
+
if( pthread_setaffinity_np(pthread_self(), sizeof(_boast_affinity_mask), &_boast_affinity_mask) != 0) {
|
42
93
|
rb_raise(rb_eArgError, "Invalid affinity list provided!");
|
43
|
-
|
94
|
+
}
|
95
|
+
return 1;
|
44
96
|
}
|
45
97
|
}
|
98
|
+
return 0;
|
99
|
+
}
|
100
|
+
|
101
|
+
static int _boast_restore_affinity( int _boast_affinity_set, cpu_set_t * _boast_affinity_mask_old );
|
102
|
+
static int _boast_restore_affinity( int _boast_affinity_set, cpu_set_t * _boast_affinity_mask_old ){
|
103
|
+
if ( _boast_affinity_set == 1 ) {
|
104
|
+
pthread_setaffinity_np(pthread_self(), sizeof(*_boast_affinity_mask_old), _boast_affinity_mask_old);
|
105
|
+
}
|
106
|
+
return 0;
|
107
|
+
}
|
108
|
+
|
109
|
+
EOF
|
110
|
+
end
|
111
|
+
|
112
|
+
def decl
|
113
|
+
get_output.puts " cpu_set_t _boast_affinity_mask_old;"
|
114
|
+
get_output.puts " int _boast_affinity_set;"
|
115
|
+
end
|
116
|
+
|
117
|
+
def configure
|
118
|
+
get_output.print <<EOF
|
119
|
+
_boast_affinity_set = _boast_affinity_setup( _boast_rb_opts, &_boast_affinity_mask_old);
|
46
120
|
EOF
|
47
121
|
end
|
48
122
|
|
@@ -54,16 +128,26 @@ EOF
|
|
54
128
|
|
55
129
|
def compute
|
56
130
|
get_output.print <<EOF
|
57
|
-
|
58
|
-
sched_setaffinity(getpid(), sizeof(_boast_affinity_mask_old), &_boast_affinity_mask_old);
|
59
|
-
_boast_affinity_set = 0;
|
60
|
-
}
|
131
|
+
_boast_affinity_set = _boast_restore_affinity( _boast_affinity_set, &_boast_affinity_mask_old);
|
61
132
|
EOF
|
62
133
|
end
|
63
134
|
|
64
135
|
def store
|
65
136
|
end
|
66
137
|
|
138
|
+
def is_available?
|
139
|
+
return false if OS.mac?
|
140
|
+
return true
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
if HwlocProbe.is_available?
|
146
|
+
AffinityProbe = HwlocProbe
|
147
|
+
elsif PthreadAffinityProbe.is_available?
|
148
|
+
AffinityProbe = PthreadAffinityProbe
|
149
|
+
else
|
150
|
+
AffinityProbe = nil
|
67
151
|
end
|
68
152
|
|
69
153
|
end
|
@@ -25,18 +25,30 @@ module BOAST
|
|
25
25
|
get_output.write @code.read
|
26
26
|
end
|
27
27
|
|
28
|
+
def create_procedure_indirect_call_parameters
|
29
|
+
return @procedure.parameters.collect { |param|
|
30
|
+
par = "#{param_struct.struct_reference(param_struct.type.members[param.name.to_s])}".gsub("_boast_params.","_boast_params->")
|
31
|
+
if param.dimension then
|
32
|
+
"#{par}"
|
33
|
+
elsif param.direction == :out or param.direction == :inout or param.reference? then
|
34
|
+
"&#{par}"
|
35
|
+
else
|
36
|
+
"#{par}"
|
37
|
+
end
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
28
41
|
def create_procedure_call_parameters
|
29
|
-
|
30
|
-
|
42
|
+
return @procedure.parameters.collect { |param|
|
43
|
+
par = param_struct.struct_reference(param_struct.type.members[param.name.to_s])
|
31
44
|
if param.dimension then
|
32
|
-
|
45
|
+
"#{par}"
|
33
46
|
elsif param.direction == :out or param.direction == :inout or param.reference? then
|
34
|
-
|
47
|
+
"&#{par}"
|
35
48
|
else
|
36
|
-
|
49
|
+
"#{par}"
|
37
50
|
end
|
38
51
|
}
|
39
|
-
return params
|
40
52
|
end
|
41
53
|
|
42
54
|
end
|
@@ -13,6 +13,7 @@ module BOAST
|
|
13
13
|
alias fill_decl_module_params_old fill_decl_module_params
|
14
14
|
alias create_procedure_call_parameters_old create_procedure_call_parameters
|
15
15
|
alias store_results_old store_results
|
16
|
+
alias create_wrapper_old create_wrapper
|
16
17
|
|
17
18
|
def fill_module_header
|
18
19
|
fill_module_header_old
|
@@ -49,7 +50,7 @@ extern "C" {
|
|
49
50
|
EOF
|
50
51
|
end
|
51
52
|
|
52
|
-
def copy_array_param_from_ruby( param, ruby_param )
|
53
|
+
def copy_array_param_from_ruby(par, param, ruby_param )
|
53
54
|
rb_ptr = Variable::new("_boast_rb_ptr", CustomType, :type_name => "VALUE")
|
54
55
|
(rb_ptr === ruby_param).pr
|
55
56
|
get_output.print <<EOF
|
@@ -58,8 +59,8 @@ EOF
|
|
58
59
|
size_t _boast_array_size;
|
59
60
|
Data_Get_Struct(_boast_rb_ptr, struct NARRAY, _boast_n_ary);
|
60
61
|
_boast_array_size = _boast_n_ary->total * na_sizeof[_boast_n_ary->type];
|
61
|
-
cudaMalloc( (void **) &#{
|
62
|
-
cudaMemcpy(#{
|
62
|
+
cudaMalloc( (void **) &#{par}, _boast_array_size);
|
63
|
+
cudaMemcpy(#{par}, (void *) _boast_n_ary->ptr, _boast_array_size, cudaMemcpyHostToDevice);
|
63
64
|
} else {
|
64
65
|
rb_raise(rb_eArgError, "Wrong type of argument for %s, expecting array!", "#{param}");
|
65
66
|
}
|
@@ -127,8 +128,11 @@ EOF
|
|
127
128
|
EOF
|
128
129
|
end
|
129
130
|
|
131
|
+
def create_wrapper
|
132
|
+
end
|
133
|
+
|
130
134
|
def create_procedure_call_parameters
|
131
|
-
return create_procedure_call_parameters_old + ["_boast_block_number", "_boast_block_size", "_boast_repeat"]
|
135
|
+
return create_procedure_call_parameters_old + ["_boast_block_number", "_boast_block_size", "_boast_params._boast_repeat"]
|
132
136
|
end
|
133
137
|
|
134
138
|
def create_procedure_call
|
@@ -138,7 +142,7 @@ EOF
|
|
138
142
|
get_output.puts " );"
|
139
143
|
end
|
140
144
|
|
141
|
-
def copy_array_param_to_ruby(param, ruby_param)
|
145
|
+
def copy_array_param_to_ruby(par, param, ruby_param)
|
142
146
|
rb_ptr = Variable::new("_boast_rb_ptr", CustomType, :type_name => "VALUE")
|
143
147
|
(rb_ptr === ruby_param).pr
|
144
148
|
get_output.print <<EOF
|
@@ -150,11 +154,11 @@ EOF
|
|
150
154
|
size_t _boast_array_size;
|
151
155
|
Data_Get_Struct(_boast_rb_ptr, struct NARRAY, _boast_n_ary);
|
152
156
|
_boast_array_size = _boast_n_ary->total * na_sizeof[_boast_n_ary->type];
|
153
|
-
cudaMemcpy((void *) _boast_n_ary->ptr, #{
|
157
|
+
cudaMemcpy((void *) _boast_n_ary->ptr, #{par}, _boast_array_size, cudaMemcpyDeviceToHost);
|
154
158
|
EOF
|
155
159
|
end
|
156
160
|
get_output.print <<EOF
|
157
|
-
cudaFree( (void *) #{
|
161
|
+
cudaFree( (void *) #{par});
|
158
162
|
} else {
|
159
163
|
rb_raise(rb_eArgError, "Wrong type of argument for %s, expecting array!", "#{param}");
|
160
164
|
}
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module BOAST
|
2
|
+
|
3
|
+
class CKernel
|
4
|
+
|
5
|
+
module Synchro
|
6
|
+
extend FFI::Library
|
7
|
+
ffi_lib 'pthread'
|
8
|
+
typedef :pointer, :mutex
|
9
|
+
typedef :pointer, :cond
|
10
|
+
typedef :pointer, :spin
|
11
|
+
attach_function 'pthread_mutex_init', [ :mutex, :pointer ], :int
|
12
|
+
attach_function 'pthread_mutex_destroy', [ :mutex ], :int
|
13
|
+
#attach_function 'pthread_mutex_lock', [ :mutex ], :int
|
14
|
+
#attach_function 'pthread_mutex_unlock', [ :mutex ], :int
|
15
|
+
|
16
|
+
attach_function 'pthread_cond_init', [ :cond, :pointer ], :int
|
17
|
+
attach_function 'pthread_cond_destroy', [ :cond ], :int
|
18
|
+
#attach_function 'pthread_cond_wait', [ :cond, :mutex ], :int
|
19
|
+
#attach_function 'pthread_cond_broadcast', [ :cond ], :int
|
20
|
+
|
21
|
+
begin
|
22
|
+
attach_function 'pthread_spin_init', [ :spin, :int ], :int
|
23
|
+
attach_function 'pthread_spin_destroy', [ :spin ], :int
|
24
|
+
rescue FFI::NotFoundError => e
|
25
|
+
warn "spin functions not found"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.coexecute(kernels)
|
30
|
+
semaphore = Mutex.new
|
31
|
+
pval = FFI::MemoryPointer::new(:int)
|
32
|
+
pval.write_int(kernels.length)
|
33
|
+
if synchro == 'MUTEX' then
|
34
|
+
mutex = FFI::MemoryPointer::new(128)
|
35
|
+
Synchro.pthread_mutex_init(mutex, nil)
|
36
|
+
condition = FFI::MemoryPointer::new(128)
|
37
|
+
Synchro.pthread_cond_init(mutex, nil)
|
38
|
+
sync = [pval, mutex, condition]
|
39
|
+
else
|
40
|
+
spinlock = FFI::MemoryPointer::new(128)
|
41
|
+
Synchro.pthread_spin_init(spinlock, 0)
|
42
|
+
sync = [pval, spinlock]
|
43
|
+
end
|
44
|
+
threads = []
|
45
|
+
returns = []
|
46
|
+
args = []
|
47
|
+
kernels.each_index { |i|
|
48
|
+
kernels[i][0].build unless kernels[i][0].methods.include?(:run)
|
49
|
+
args[i] = kernels[i][1].dup
|
50
|
+
if args[i].last.kind_of?( Hash ) then
|
51
|
+
args[i][-1] = args[i].last.dup
|
52
|
+
args[i][-1][:coexecute] = sync
|
53
|
+
else
|
54
|
+
args[i].push( { :coexecute => sync } )
|
55
|
+
end
|
56
|
+
}
|
57
|
+
kernels.each_index { |i|
|
58
|
+
threads << Thread::new(i) { |j|
|
59
|
+
ret = kernels[j][0].run(*args[j])
|
60
|
+
semaphore.synchronize {
|
61
|
+
returns[j] = ret
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
65
|
+
threads.each { |thr| thr.join }
|
66
|
+
if synchro == 'MUTEX' then
|
67
|
+
Synchro.pthread_mutex_destroy(mutex)
|
68
|
+
Synchro.pthread_cond_destroy(condition)
|
69
|
+
else
|
70
|
+
Synchro.pthread_spin_destroy(spinlock)
|
71
|
+
end
|
72
|
+
return returns
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -41,6 +41,7 @@ module BOAST
|
|
41
41
|
module CompiledRuntime
|
42
42
|
attr_accessor :binary
|
43
43
|
attr_accessor :source
|
44
|
+
attr_reader :param_struct
|
44
45
|
|
45
46
|
private
|
46
47
|
|
@@ -206,6 +207,9 @@ module BOAST
|
|
206
207
|
#include "narray.h"
|
207
208
|
#endif
|
208
209
|
EOF
|
210
|
+
get_output.puts "#include <pthread.h>" unless executable?
|
211
|
+
get_output.puts "#include <sys/types.h>" unless executable?
|
212
|
+
get_output.puts "#include \"ruby/thread.h\"" unless executable?
|
209
213
|
@includes.each { |inc|
|
210
214
|
get_output.puts "#include \"#{inc}\""
|
211
215
|
}
|
@@ -214,42 +218,25 @@ EOF
|
|
214
218
|
def fill_module_preamble
|
215
219
|
get_output.print <<EOF
|
216
220
|
VALUE #{module_name} = Qnil;
|
221
|
+
|
222
|
+
static VALUE method_run(int _boast_argc, VALUE *_boast_argv, VALUE _boast_self);
|
223
|
+
|
217
224
|
void Init_#{module_name}();
|
218
|
-
VALUE method_run(int _boast_argc, VALUE *_boast_argv, VALUE _boast_self);
|
219
225
|
void Init_#{module_name}() {
|
220
226
|
#{module_name} = rb_define_module("#{module_name}");
|
221
|
-
rb_define_method(#{module_name}, "
|
227
|
+
rb_define_method(#{module_name}, "__run", method_run, -1);
|
222
228
|
}
|
223
|
-
EOF
|
224
|
-
end
|
225
229
|
|
226
|
-
|
227
|
-
|
228
|
-
VALUE _boast_rb_opts;
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
_boast_rb_opts = Qnil;
|
233
|
-
if( _boast_argc == #{@procedure.parameters.length + 1} ) {
|
234
|
-
_boast_rb_opts = _boast_argv[_boast_argc -1];
|
235
|
-
if ( _boast_rb_opts != Qnil ) {
|
236
|
-
if (TYPE(_boast_rb_opts) != T_HASH)
|
237
|
-
rb_raise(rb_eArgError, "Options should be passed as a hash");
|
238
|
-
}
|
239
|
-
}
|
240
|
-
EOF
|
241
|
-
end
|
230
|
+
static VALUE _boast_check_get_options(int _boast_argc, VALUE *_boast_argv);
|
231
|
+
static VALUE _boast_check_get_options(int _boast_argc, VALUE *_boast_argv) {
|
232
|
+
VALUE _boast_rb_opts = Qnil;
|
233
|
+
_boast_rb_opts = _boast_argv[_boast_argc -1];
|
234
|
+
return _boast_rb_opts;
|
235
|
+
}
|
242
236
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
_boast_run_opts = rb_const_get(rb_cObject, rb_intern("BOAST"));
|
247
|
-
_boast_run_opts = rb_funcall(_boast_run_opts, rb_intern("get_run_config"), 0);
|
248
|
-
if ( NUM2UINT(rb_funcall(_boast_run_opts, rb_intern("size"), 0)) > 0 ) {
|
249
|
-
if ( _boast_rb_opts != Qnil )
|
250
|
-
rb_funcall(_boast_run_opts, rb_intern("update"), 1, _boast_rb_opts);
|
251
|
-
_boast_rb_opts = _boast_run_opts;
|
252
|
-
}
|
237
|
+
static int _boast_get_repeat(VALUE _boast_rb_opts);
|
238
|
+
static int _boast_get_repeat(VALUE _boast_rb_opts) {
|
239
|
+
int _boast_repeat = 1;
|
253
240
|
if ( _boast_rb_opts != Qnil ){
|
254
241
|
VALUE _boast_repeat_value = Qnil;
|
255
242
|
_boast_repeat_value = rb_hash_aref(_boast_rb_opts, ID2SYM(rb_intern("repeat")));
|
@@ -258,25 +245,97 @@ EOF
|
|
258
245
|
if(_boast_repeat < 0)
|
259
246
|
_boast_repeat = 1;
|
260
247
|
}
|
248
|
+
return _boast_repeat;
|
249
|
+
}
|
250
|
+
EOF
|
251
|
+
|
252
|
+
if !executable? then
|
253
|
+
get_output.print <<EOF
|
254
|
+
struct _boast_synchro_struct {
|
255
|
+
volatile int * counter;
|
256
|
+
EOF
|
257
|
+
if get_synchro == 'MUTEX' then
|
258
|
+
get_output.print <<EOF
|
259
|
+
pthread_mutex_t * mutex;
|
260
|
+
pthread_cond_t * condition;
|
261
|
+
EOF
|
262
|
+
else
|
263
|
+
get_output.print <<EOF
|
264
|
+
pthread_spinlock_t * spin;
|
265
|
+
EOF
|
266
|
+
end
|
267
|
+
get_output.print <<EOF
|
268
|
+
};
|
269
|
+
static int _boast_get_coexecute(VALUE _boast_rb_opts, struct _boast_synchro_struct * _boast_synchro);
|
270
|
+
static int _boast_get_coexecute(VALUE _boast_rb_opts, struct _boast_synchro_struct * _boast_synchro) {
|
271
|
+
int _boast_coexecute = 0;
|
272
|
+
if ( _boast_rb_opts != Qnil ){
|
273
|
+
VALUE _boast_coexecute_value = Qnil;
|
274
|
+
_boast_coexecute_value = rb_hash_aref(_boast_rb_opts, ID2SYM(rb_intern("coexecute")));
|
275
|
+
if(_boast_coexecute_value != Qnil) {
|
276
|
+
VALUE address;
|
277
|
+
_boast_coexecute = 1;
|
278
|
+
address = rb_funcall(rb_ary_entry(_boast_coexecute_value, 0), rb_intern("address"), 0);
|
279
|
+
_boast_synchro->counter = sizeof(_boast_synchro->counter) == 4 ? (void *) NUM2ULONG(address) : (void *) NUM2ULL(address);
|
280
|
+
EOF
|
281
|
+
if get_synchro == 'MUTEX' then
|
282
|
+
get_output.print <<EOF
|
283
|
+
address = rb_funcall(rb_ary_entry(_boast_coexecute_value, 1), rb_intern("address"), 0);
|
284
|
+
_boast_synchro->mutex = sizeof(_boast_synchro->mutex) == 4 ? (void *) NUM2ULONG(address) : (void *) NUM2ULL(address);
|
285
|
+
address = rb_funcall(rb_ary_entry(_boast_coexecute_value, 2), rb_intern("address"), 0);
|
286
|
+
_boast_synchro->condition = sizeof(_boast_synchro->condition) == 4 ? (void *) NUM2ULONG(address) : (void *) NUM2ULL(address);
|
287
|
+
EOF
|
288
|
+
else
|
289
|
+
get_output.print <<EOF
|
290
|
+
address = rb_funcall(rb_ary_entry(_boast_coexecute_value, 1), rb_intern("address"), 0);
|
291
|
+
_boast_synchro->spin = sizeof(_boast_synchro->spin) == 4 ? (void *) NUM2ULONG(address) : (void *) NUM2ULL(address);
|
292
|
+
EOF
|
293
|
+
end
|
294
|
+
get_output.print <<EOF
|
295
|
+
}
|
296
|
+
}
|
297
|
+
return _boast_coexecute;
|
298
|
+
}
|
299
|
+
|
261
300
|
EOF
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
def fill_check_args
|
305
|
+
get_output.print <<EOF
|
306
|
+
VALUE _boast_rb_opts = Qnil;
|
307
|
+
_boast_rb_opts = _boast_check_get_options( _boast_argc, _boast_argv);
|
308
|
+
EOF
|
309
|
+
end
|
310
|
+
|
311
|
+
def add_run_options
|
312
|
+
get_output.print <<EOF
|
313
|
+
_boast_params._boast_repeat = _boast_get_repeat( _boast_rb_opts );
|
314
|
+
EOF
|
315
|
+
get_output.puts " _boast_params._boast_coexecute = _boast_get_coexecute( _boast_rb_opts, &_boast_params._boast_synchro );" unless executable?
|
316
|
+
end
|
317
|
+
|
318
|
+
def fill_param_struct
|
319
|
+
pars = @procedure.parameters.collect { |param|
|
320
|
+
param.copy(param.name, :const => nil, :constant => nil, :dir => nil, :direction => nil, :reference => nil )
|
321
|
+
}
|
322
|
+
pars.push @procedure.properties[:return].copy("_boast_ret") if @procedure.properties[:return]
|
323
|
+
pars.push Int("_boast_repeat")
|
324
|
+
pars.push Int("_boast_coexecute")
|
325
|
+
pars.push CStruct("_boast_timer", :type_name => "_boast_timer_struct", :members => [Int(:dummy)]) if @probes.include?(TimerProbe)
|
326
|
+
pars.push CStruct("_boast_synchro", :type_name => "_boast_synchro_struct", :members => [Int(:dummy)]) unless executable?
|
327
|
+
@param_struct = CStruct("_boast_params", :type_name => "_boast_#{@procedure.name}_params", :members => pars)
|
262
328
|
end
|
263
329
|
|
264
330
|
def fill_decl_module_params
|
265
331
|
push_env(:decl_module => true) {
|
266
|
-
|
267
|
-
param_copy = param.copy
|
268
|
-
param_copy.constant = nil
|
269
|
-
param_copy.direction = nil
|
270
|
-
param_copy.reference = nil
|
271
|
-
param_copy.decl
|
272
|
-
}
|
273
|
-
get_output.puts " #{@procedure.properties[:return].type.decl} _boast_ret;" if @procedure.properties[:return]
|
332
|
+
param_struct.decl
|
274
333
|
get_output.puts " VALUE _boast_stats = rb_hash_new();"
|
275
334
|
get_output.puts " VALUE _boast_rb_ptr = Qnil;"
|
276
335
|
refs = false
|
277
|
-
@procedure.parameters.
|
336
|
+
@procedure.parameters.each { |param|
|
278
337
|
refs = true if param.scalar_output?
|
279
|
-
|
338
|
+
}
|
280
339
|
if refs then
|
281
340
|
get_output.puts " VALUE _boast_refs = rb_hash_new();"
|
282
341
|
get_output.puts " rb_hash_aset(_boast_stats,ID2SYM(rb_intern(\"reference_return\")),_boast_refs);"
|
@@ -284,26 +343,26 @@ EOF
|
|
284
343
|
}
|
285
344
|
end
|
286
345
|
|
287
|
-
def copy_scalar_param_from_ruby( param, ruby_param )
|
346
|
+
def copy_scalar_param_from_ruby(str_par, param, ruby_param )
|
288
347
|
case param.type
|
289
348
|
when Int
|
290
|
-
(
|
291
|
-
(
|
349
|
+
(str_par === FuncCall::new("NUM2INT", ruby_param)).pr if param.type.size == 4
|
350
|
+
(str_par === FuncCall::new("NUM2LONG", ruby_param)).pr if param.type.size == 8
|
292
351
|
when Real
|
293
|
-
(
|
352
|
+
(str_par === FuncCall::new("NUM2DBL", ruby_param)).pr
|
294
353
|
end
|
295
354
|
end
|
296
355
|
|
297
|
-
def copy_array_param_from_ruby( param, ruby_param )
|
356
|
+
def copy_array_param_from_ruby(str_par, param, ruby_param )
|
298
357
|
rb_ptr = Variable::new("_boast_rb_ptr", CustomType, :type_name => "VALUE")
|
299
358
|
(rb_ptr === ruby_param).pr
|
300
359
|
get_output.print <<EOF
|
301
360
|
if (TYPE(_boast_rb_ptr) == T_STRING) {
|
302
361
|
#{
|
303
362
|
if param.dimension then
|
304
|
-
"#{
|
363
|
+
"#{str_par} = (void *)RSTRING_PTR(_boast_rb_ptr)"
|
305
364
|
else
|
306
|
-
(
|
365
|
+
(str_par === param.copy("*(void *)RSTRING_PTR(_boast_rb_ptr)", :dimension => Dim(), :vector_length => 1)).to_s
|
307
366
|
end
|
308
367
|
};
|
309
368
|
} else if ( IsNArray(_boast_rb_ptr) ) {
|
@@ -311,13 +370,13 @@ EOF
|
|
311
370
|
Data_Get_Struct(_boast_rb_ptr, struct NARRAY, _boast_n_ary);
|
312
371
|
#{
|
313
372
|
if param.dimension then
|
314
|
-
"#{
|
373
|
+
"#{str_par} = (void *) _boast_n_ary->ptr"
|
315
374
|
else
|
316
|
-
(
|
375
|
+
(str_par === param.copy("*(void *) _boast_n_ary->ptr", :dimension => Dim(), :vector_length => 1)).to_s
|
317
376
|
end
|
318
377
|
};
|
319
378
|
} else {
|
320
|
-
rb_raise(rb_eArgError, "Wrong type of argument for
|
379
|
+
rb_raise(rb_eArgError, "Wrong type of argument for #{param}, expecting array!");
|
321
380
|
}
|
322
381
|
EOF
|
323
382
|
end
|
@@ -328,81 +387,151 @@ EOF
|
|
328
387
|
push_env(:decl_module => true) {
|
329
388
|
@procedure.parameters.each_index do |i|
|
330
389
|
param = @procedure.parameters[i]
|
331
|
-
|
332
|
-
|
390
|
+
par = param_struct.struct_reference(param_struct.type.members[param.name.to_s])
|
391
|
+
if param.dimension? or param.vector? then
|
392
|
+
copy_array_param_from_ruby(par, param, argv[i])
|
333
393
|
else
|
334
|
-
|
394
|
+
copy_scalar_param_from_ruby(par, param, argv[i])
|
335
395
|
end
|
336
396
|
end
|
337
397
|
}
|
338
398
|
end
|
339
399
|
|
340
|
-
def
|
400
|
+
def create_wrapper
|
401
|
+
get_output.print <<EOF
|
402
|
+
static void * boast_wrapper( void * data ) {
|
403
|
+
struct _boast_#{@procedure.name}_params * _boast_params;
|
404
|
+
_boast_params = data;
|
405
|
+
EOF
|
406
|
+
if get_synchro == 'MUTEX' then
|
407
|
+
get_output.print <<EOF
|
408
|
+
pthread_mutex_lock(_boast_params->_boast_synchro.mutex);
|
409
|
+
*_boast_params->_boast_synchro.counter -= 1;
|
410
|
+
if( *_boast_params->_boast_synchro.counter == 0 ) {
|
411
|
+
pthread_cond_broadcast( _boast_params->_boast_synchro.condition );
|
412
|
+
}
|
413
|
+
while( *_boast_params->_boast_synchro.counter ) {
|
414
|
+
pthread_cond_wait( _boast_params->_boast_synchro.condition, _boast_params->_boast_synchro.mutex );
|
415
|
+
}
|
416
|
+
pthread_mutex_unlock(_boast_params->_boast_synchro.mutex);
|
417
|
+
EOF
|
418
|
+
else
|
419
|
+
get_output.print <<EOF
|
420
|
+
pthread_spin_lock(_boast_params->_boast_synchro.spin);
|
421
|
+
*_boast_params->_boast_synchro.counter -= 1;
|
422
|
+
while( *_boast_params->_boast_synchro.counter ) {
|
423
|
+
pthread_spin_unlock(_boast_params->_boast_synchro.spin);
|
424
|
+
pthread_spin_lock(_boast_params->_boast_synchro.spin);
|
425
|
+
}
|
426
|
+
pthread_spin_unlock(_boast_params->_boast_synchro.spin);
|
427
|
+
EOF
|
428
|
+
end
|
429
|
+
get_output.puts " _boast_timer_start(&_boast_params->_boast_timer);" if @probes.include?(TimerProbe)
|
430
|
+
create_procedure_indirect_call
|
431
|
+
get_output.puts " _boast_timer_stop(&_boast_params->_boast_timer);" if @probes.include?(TimerProbe)
|
432
|
+
get_output.print <<EOF
|
433
|
+
return NULL;
|
434
|
+
}
|
435
|
+
EOF
|
436
|
+
end
|
437
|
+
|
438
|
+
def create_procedure_wrapper_call
|
439
|
+
get_output.print <<EOF
|
440
|
+
rb_thread_call_without_gvl(boast_wrapper, &_boast_params, RUBY_UBF_PROCESS, NULL);
|
441
|
+
EOF
|
442
|
+
end
|
443
|
+
|
444
|
+
def create_procedure_indirect_call
|
341
445
|
get_output.puts " int _boast_i;"
|
342
|
-
get_output.puts " for(_boast_i = 0; _boast_i < _boast_repeat; ++_boast_i){"
|
343
|
-
get_output.print "
|
344
|
-
get_output.print "
|
345
|
-
get_output.print
|
346
|
-
get_output.print "
|
446
|
+
get_output.puts " for(_boast_i = 0; _boast_i < _boast_params->_boast_repeat; ++_boast_i){"
|
447
|
+
get_output.print " "
|
448
|
+
get_output.print "_boast_params->_boast_ret = " if @procedure.properties[:return]
|
449
|
+
get_output.print "#{method_name}( "
|
450
|
+
get_output.print create_procedure_indirect_call_parameters.join(", ")
|
451
|
+
get_output.puts " );"
|
347
452
|
get_output.puts " }"
|
348
453
|
end
|
349
454
|
|
350
|
-
def
|
455
|
+
def create_procedure_call
|
456
|
+
If("_boast_params._boast_coexecute" => lambda {
|
457
|
+
create_procedure_wrapper_call
|
458
|
+
}, :else => lambda {
|
459
|
+
TimerProbe.start if @probes.include?(TimerProbe)
|
460
|
+
get_output.puts " int _boast_i;"
|
461
|
+
get_output.puts " for(_boast_i = 0; _boast_i < _boast_params._boast_repeat; ++_boast_i){"
|
462
|
+
get_output.print " "
|
463
|
+
get_output.print "_boast_params._boast_ret = " if @procedure.properties[:return]
|
464
|
+
get_output.print "#{method_name}( "
|
465
|
+
get_output.print create_procedure_call_parameters.join(", ")
|
466
|
+
get_output.puts " );"
|
467
|
+
get_output.puts " }"
|
468
|
+
TimerProbe.stop if @probes.include?(TimerProbe)
|
469
|
+
}).pr
|
470
|
+
end
|
471
|
+
|
472
|
+
def copy_scalar_param_to_ruby(str_par, param, ruby_param)
|
351
473
|
if param.scalar_output? then
|
352
474
|
case param.type
|
353
475
|
when Int
|
354
|
-
|
355
|
-
|
476
|
+
if param.type.signed?
|
477
|
+
get_output.puts " rb_hash_aset(_boast_refs, ID2SYM(rb_intern(\"#{param}\")),rb_int_new((long long)#{str_par}));"
|
478
|
+
else
|
479
|
+
get_output.puts " rb_hash_aset(_boast_refs, ID2SYM(rb_intern(\"#{param}\")),rb_int_new((unsigned long long)#{str_par}));"
|
480
|
+
end
|
356
481
|
when Real
|
357
|
-
get_output.puts " rb_hash_aset(_boast_refs, ID2SYM(rb_intern(\"#{param}\")),rb_float_new((double)#{
|
482
|
+
get_output.puts " rb_hash_aset(_boast_refs, ID2SYM(rb_intern(\"#{param}\")),rb_float_new((double)#{str_par}));"
|
358
483
|
end
|
359
484
|
end
|
360
485
|
end
|
361
486
|
|
362
|
-
def copy_scalar_param_to_file(param, base_path)
|
487
|
+
def copy_scalar_param_to_file(str_par, param, base_path)
|
363
488
|
if param.scalar_output? then
|
364
489
|
get_output.puts <<EOF
|
365
490
|
__boast_f = fopen("#{base_path}/#{param}.out", "wb");
|
366
|
-
fwrite(
|
491
|
+
fwrite(&(#{str_par}), sizeof(#{str_par}), 1, __boast_f);
|
367
492
|
fclose(__boast_f);
|
368
493
|
EOF
|
369
494
|
end
|
370
495
|
end
|
371
496
|
|
372
|
-
def copy_scalar_param_from_file(param, base_path)
|
497
|
+
def copy_scalar_param_from_file(str_par, param, base_path)
|
373
498
|
get_output.puts <<EOF
|
374
499
|
__boast_f = fopen("#{base_path}/#{param}.in", "rb");
|
375
|
-
fread(
|
500
|
+
if( fread(&(#{str_par}), sizeof(#{str_par}), 1, __boast_f) != 1 ) {
|
501
|
+
exit(-1);
|
502
|
+
}
|
376
503
|
fclose(__boast_f);
|
377
504
|
EOF
|
378
505
|
end
|
379
506
|
|
380
|
-
def copy_array_param_to_ruby(param, ruby_param)
|
507
|
+
def copy_array_param_to_ruby(str_par, param, ruby_param)
|
381
508
|
end
|
382
509
|
|
383
|
-
def copy_array_param_to_file(param, base_path)
|
510
|
+
def copy_array_param_to_file(str_par, param, base_path)
|
384
511
|
if param.direction == :out or param.direction == :inout then
|
385
512
|
get_output.puts <<EOF
|
386
513
|
__boast_f = fopen("#{base_path}/#{param}.out", "wb");
|
387
|
-
fwrite(#{
|
514
|
+
fwrite(#{str_par}, 1, __boast_sizeof_#{param}, __boast_f);
|
388
515
|
fclose(__boast_f);
|
389
|
-
free(#{
|
516
|
+
free(#{str_par});
|
390
517
|
EOF
|
391
518
|
else
|
392
519
|
get_output.puts <<EOF
|
393
|
-
free(#{
|
520
|
+
free(#{str_par});
|
394
521
|
EOF
|
395
522
|
end
|
396
523
|
end
|
397
524
|
|
398
|
-
def copy_array_param_from_file(param, base_path)
|
525
|
+
def copy_array_param_from_file(str_par, param, base_path)
|
399
526
|
get_output.puts <<EOF
|
400
527
|
__boast_f = fopen("#{base_path}/#{param}.in", "rb");
|
401
528
|
fseek(__boast_f, 0L, SEEK_END);
|
402
529
|
__boast_sizeof_#{param} = ftell(__boast_f);
|
403
530
|
rewind(__boast_f);
|
404
|
-
#{
|
405
|
-
fread(#{
|
531
|
+
#{str_par} = malloc(__boast_sizeof_#{param});
|
532
|
+
if( fread(#{str_par}, 1, __boast_sizeof_#{param}, __boast_f) != __boast_sizeof_#{param} ) {
|
533
|
+
exit(-1);
|
534
|
+
}
|
406
535
|
fclose(__boast_f);
|
407
536
|
EOF
|
408
537
|
end
|
@@ -413,10 +542,11 @@ EOF
|
|
413
542
|
push_env(:decl_module => true) {
|
414
543
|
@procedure.parameters.each_index do |i|
|
415
544
|
param = @procedure.parameters[i]
|
416
|
-
|
417
|
-
|
545
|
+
par = param_struct.struct_reference(param_struct.type.members[param.name.to_s])
|
546
|
+
if param.dimension then
|
547
|
+
copy_array_param_to_ruby(par, param, argv[i])
|
418
548
|
else
|
419
|
-
|
549
|
+
copy_scalar_param_to_ruby(par, param, argv[i])
|
420
550
|
end
|
421
551
|
end
|
422
552
|
}
|
@@ -425,19 +555,20 @@ EOF
|
|
425
555
|
def store_results
|
426
556
|
if @procedure.properties[:return] then
|
427
557
|
type_ret = @procedure.properties[:return].type
|
428
|
-
get_output.puts " rb_hash_aset(_boast_stats,ID2SYM(rb_intern(\"return\")),rb_int_new((long long)_boast_ret));" if type_ret.kind_of?(Int) and type_ret.signed
|
429
|
-
get_output.puts " rb_hash_aset(_boast_stats,ID2SYM(rb_intern(\"return\")),rb_int_new((unsigned long long)_boast_ret));" if type_ret.kind_of?(Int) and not type_ret.signed
|
430
|
-
get_output.puts " rb_hash_aset(_boast_stats,ID2SYM(rb_intern(\"return\")),rb_float_new((double)_boast_ret));" if type_ret.kind_of?(Real)
|
558
|
+
get_output.puts " rb_hash_aset(_boast_stats,ID2SYM(rb_intern(\"return\")),rb_int_new((long long)_boast_params._boast_ret));" if type_ret.kind_of?(Int) and type_ret.signed
|
559
|
+
get_output.puts " rb_hash_aset(_boast_stats,ID2SYM(rb_intern(\"return\")),rb_int_new((unsigned long long)_boast_params._boast_ret));" if type_ret.kind_of?(Int) and not type_ret.signed
|
560
|
+
get_output.puts " rb_hash_aset(_boast_stats,ID2SYM(rb_intern(\"return\")),rb_float_new((double)_boast_params._boast_ret));" if type_ret.kind_of?(Real)
|
431
561
|
end
|
432
562
|
end
|
433
563
|
|
434
564
|
def get_executable_params_value( base_path )
|
435
565
|
push_env(:decl_module => true) {
|
436
566
|
@procedure.parameters.each do |param|
|
437
|
-
|
438
|
-
|
567
|
+
par = param_struct.struct_reference(param_struct.type.members[param.name.to_s])
|
568
|
+
if param.dimension? then
|
569
|
+
copy_array_param_from_file(par, param, base_path)
|
439
570
|
else
|
440
|
-
|
571
|
+
copy_scalar_param_from_file(par, param, base_path)
|
441
572
|
end
|
442
573
|
end
|
443
574
|
}
|
@@ -446,16 +577,18 @@ EOF
|
|
446
577
|
def get_executable_params_return_value( base_path )
|
447
578
|
push_env(:decl_module => true) {
|
448
579
|
@procedure.parameters.each do |param|
|
449
|
-
|
450
|
-
|
580
|
+
par = param_struct.struct_reference(param_struct.type.members[param.name.to_s])
|
581
|
+
if param.dimension then
|
582
|
+
copy_array_param_to_file(par, param, base_path)
|
451
583
|
else
|
452
|
-
|
584
|
+
copy_scalar_param_to_file(par, param, base_path)
|
453
585
|
end
|
454
586
|
end
|
455
587
|
}
|
456
588
|
end
|
457
589
|
|
458
590
|
def fill_executable_source
|
591
|
+
fill_param_struct
|
459
592
|
get_output.puts "#include <inttypes.h>"
|
460
593
|
get_output.puts "#include <stdlib.h>"
|
461
594
|
get_output.puts "#include <stdio.h>"
|
@@ -464,28 +597,24 @@ EOF
|
|
464
597
|
}
|
465
598
|
@probes.map(&:header)
|
466
599
|
@procedure.boast_header(@lang)
|
600
|
+
@probes.map(&:preamble)
|
467
601
|
|
602
|
+
param_struct.type.define
|
468
603
|
get_output.print <<EOF
|
469
|
-
void Init_#{base_name}(
|
470
|
-
int _boast_repeat
|
471
|
-
void Init_#{base_name}( void ) {
|
604
|
+
void Init_#{base_name}( int _boast_repeat );
|
605
|
+
void Init_#{base_name}( int _boast_repeat ) {
|
472
606
|
EOF
|
473
607
|
increment_indent_level
|
474
608
|
output.puts " FILE * __boast_f;"
|
609
|
+
param_struct.decl
|
475
610
|
push_env(:decl_module => true) {
|
476
611
|
@procedure.parameters.each { |param|
|
477
612
|
if param.dimension? then
|
478
613
|
output.puts " size_t __boast_sizeof_#{param};"
|
479
614
|
end
|
480
|
-
param_copy = param.copy
|
481
|
-
param_copy.constant = nil
|
482
|
-
param_copy.direction = nil
|
483
|
-
param_copy.reference = nil
|
484
|
-
param_copy.decl
|
485
615
|
}
|
486
|
-
get_output.puts " #{@procedure.properties[:return].type.decl} _boast_ret;" if @procedure.properties[:return]
|
487
616
|
}
|
488
|
-
@probes.reverse.map(&:decl)
|
617
|
+
@probes.reject{ |e| e ==TimerProbe }.reverse.map(&:decl)
|
489
618
|
@probes.map(&:configure)
|
490
619
|
|
491
620
|
get_executable_params_value( "#{@tmp_dir}/#{@procedure.name}/#{base_name}" )
|
@@ -495,7 +624,7 @@ EOF
|
|
495
624
|
get_output.puts " int _boast_i;"
|
496
625
|
get_output.puts " for(_boast_i = 0; _boast_i < _boast_repeat; ++_boast_i){"
|
497
626
|
get_output.print " "
|
498
|
-
get_output.print "_boast_ret = " if @procedure.properties[:return]
|
627
|
+
get_output.print "_boast_params._boast_ret = " if @procedure.properties[:return]
|
499
628
|
get_output.print "#{method_name}( "
|
500
629
|
get_output.print create_procedure_call_parameters.join(", ")
|
501
630
|
get_output.puts " );"
|
@@ -506,9 +635,9 @@ EOF
|
|
506
635
|
get_output.puts ' printf("---\n");'
|
507
636
|
if @procedure.properties[:return] then
|
508
637
|
type_ret = @procedure.properties[:return].type
|
509
|
-
get_output.puts ' printf(":return: %lld\n", (long long)_boast_ret);' if type_ret.kind_of?(Int) and type_ret.signed
|
510
|
-
get_output.puts ' printf(":return: %ulld\n", (unsigned long long)_boast_ret);' if type_ret.kind_of?(Int) and not type_ret.signed
|
511
|
-
get_output.puts ' printf(":return: %lf\n", (double)_boast_ret);' if type_ret.kind_of?(Real)
|
638
|
+
get_output.puts ' printf(":return: %lld\n", (long long)_boast_params._boast_ret);' if type_ret.kind_of?(Int) and type_ret.signed
|
639
|
+
get_output.puts ' printf(":return: %ulld\n", (unsigned long long)_boast_params._boast_ret);' if type_ret.kind_of?(Int) and not type_ret.signed
|
640
|
+
get_output.puts ' printf(":return: %lf\n", (double)_boast_params._boast_ret);' if type_ret.kind_of?(Real)
|
512
641
|
|
513
642
|
end
|
514
643
|
|
@@ -522,8 +651,7 @@ EOF
|
|
522
651
|
get_output.print <<EOF
|
523
652
|
}
|
524
653
|
int main(int argc, char * argv[]) {
|
525
|
-
|
526
|
-
Init_#{base_name}();
|
654
|
+
Init_#{base_name}(atoi(argv[1]));
|
527
655
|
return 0;
|
528
656
|
}
|
529
657
|
EOF
|
@@ -544,33 +672,41 @@ EOF
|
|
544
672
|
end
|
545
673
|
|
546
674
|
def fill_module_file_source
|
675
|
+
fill_param_struct
|
547
676
|
fill_module_header
|
548
677
|
@probes.map(&:header)
|
549
678
|
@procedure.boast_header(@lang)
|
550
679
|
|
551
680
|
fill_module_preamble
|
681
|
+
@probes.map(&:preamble)
|
552
682
|
|
553
683
|
set_transition("VALUE", "VALUE", :default, CustomType::new(:type_name => "VALUE"))
|
554
|
-
|
684
|
+
|
685
|
+
param_struct.type.define
|
686
|
+
|
687
|
+
create_wrapper
|
688
|
+
|
689
|
+
get_output.puts "static VALUE method_run(int _boast_argc, VALUE *_boast_argv, VALUE _boast_self) {"
|
690
|
+
|
555
691
|
increment_indent_level
|
556
692
|
|
693
|
+
fill_decl_module_params
|
694
|
+
|
557
695
|
fill_check_args
|
558
696
|
|
559
697
|
add_run_options
|
560
698
|
|
561
|
-
|
562
|
-
|
563
|
-
@probes.reverse.map(&:decl)
|
699
|
+
@probes.reject{ |e| e == TimerProbe }.reverse.map(&:decl)
|
564
700
|
|
565
701
|
get_params_value
|
566
702
|
|
567
703
|
@probes.map(&:configure)
|
568
704
|
|
569
|
-
@probes.reverse.map(&:start)
|
705
|
+
@probes.reject{ |e| e == TimerProbe }.reverse.map(&:start)
|
570
706
|
|
571
707
|
create_procedure_call
|
572
708
|
|
573
|
-
@probes.map(&:stop)
|
709
|
+
@probes.reject{ |e| e == TimerProbe }.map(&:stop)
|
574
710
|
|
575
711
|
get_results
|
576
712
|
|
@@ -720,7 +856,7 @@ EOF
|
|
720
856
|
elsif get_lang != CUDA then
|
721
857
|
@probes = [TimerProbe, PAPIProbe]
|
722
858
|
@probes.push EnergyProbe if EnergyProbe
|
723
|
-
@probes.push AffinityProbe
|
859
|
+
@probes.push AffinityProbe if AffinityProbe
|
724
860
|
end
|
725
861
|
@probes = [MPPAProbe] if @architecture == MPPA
|
726
862
|
linker, ldshared, ldshared_flags, ldflags = setup_compilers(@probes, compiler_options)
|
@@ -748,6 +884,34 @@ EOF
|
|
748
884
|
|
749
885
|
eval "self.extend(#{module_name})"
|
750
886
|
|
887
|
+
define_singleton_method(:run) { |*args, **options, &block|
|
888
|
+
raise "Wrong number of arguments for #{@procedure.name} (#{args.length} for #{@procedure.parameters.length})" if args.length != @procedure.parameters.length
|
889
|
+
config = BOAST::get_run_config
|
890
|
+
config.update(options)
|
891
|
+
res = nil
|
892
|
+
if get_lang != CUDA and config[:PAPI] then
|
893
|
+
require 'PAPI'
|
894
|
+
PAPI.init
|
895
|
+
if config[:coexecute] then
|
896
|
+
PAPI.thread_init
|
897
|
+
end
|
898
|
+
end
|
899
|
+
if AffinityProbe == HwlocProbe and config[:cpu_affinity] then
|
900
|
+
affinity = config[:cpu_affinity]
|
901
|
+
if affinity.kind_of?(Array) then
|
902
|
+
cpuset = Hwloc::Cpuset::new( affinity )
|
903
|
+
elsif affinity.kind_of?(Hwloc::Bitmap) then
|
904
|
+
cpuset = affinity
|
905
|
+
end
|
906
|
+
AffinityProbe.topology.set_cpubind(cpuset, Hwloc::CPUBIND_THREAD | Hwloc::CPUBIND_STRICT) {
|
907
|
+
res = __run(*args, config, &block)
|
908
|
+
}
|
909
|
+
else
|
910
|
+
res = __run(*args, config, &block)
|
911
|
+
end
|
912
|
+
res
|
913
|
+
}
|
914
|
+
|
751
915
|
return self
|
752
916
|
end
|
753
917
|
|