BOAST 1.3.5 → 2.0.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 +1 -1
- data/LICENSE +13 -1
- data/README.md +62 -13
- data/lib/BOAST.rb +3 -1
- data/lib/BOAST/Language/ARMCPUID_by_name.rb +3752 -0
- data/lib/BOAST/Language/Algorithm.rb +4 -24
- data/lib/BOAST/Language/Architectures.rb +5 -0
- data/lib/BOAST/Language/Arithmetic.rb +38 -5
- data/lib/BOAST/Language/BOAST_OpenCL.rb +7 -8
- data/lib/BOAST/Language/Case.rb +10 -3
- data/lib/BOAST/Language/Config.rb +36 -12
- data/lib/BOAST/Language/ControlStructure.rb +7 -3
- data/lib/BOAST/Language/DataTypes.rb +6 -0
- data/lib/BOAST/Language/Expression.rb +26 -2
- data/lib/BOAST/Language/For.rb +59 -30
- data/lib/BOAST/Language/FuncCall.rb +9 -5
- data/lib/BOAST/Language/Functors.rb +1 -1
- data/lib/BOAST/Language/HighLevelOperators.rb +172 -0
- data/lib/BOAST/Language/If.rb +25 -9
- data/lib/BOAST/Language/Index.rb +5 -5
- data/lib/BOAST/Language/Intrinsics.rb +40 -27
- data/lib/BOAST/Language/OpenMP.rb +1 -0
- data/lib/BOAST/Language/Operators.rb +221 -34
- data/lib/BOAST/Language/Parens.rb +3 -2
- data/lib/BOAST/Language/Procedure.rb +18 -5
- data/lib/BOAST/Language/Slice.rb +176 -44
- data/lib/BOAST/Language/Variable.rb +99 -56
- data/lib/BOAST/Language/While.rb +18 -3
- data/lib/BOAST/Language/{CPUID_by_name.rb → X86CPUID_by_name.rb} +0 -0
- data/lib/BOAST/Optimization/Optimization.rb +2 -0
- data/lib/BOAST/Runtime/AffinityProbe.rb +7 -3
- data/lib/BOAST/Runtime/CKernel.rb +3 -0
- data/lib/BOAST/Runtime/CRuntime.rb +4 -0
- data/lib/BOAST/Runtime/CompiledRuntime.rb +404 -77
- data/lib/BOAST/Runtime/Compilers.rb +44 -18
- data/lib/BOAST/Runtime/Config.rb +9 -0
- data/lib/BOAST/Runtime/EnergyProbe.rb +19 -3
- data/lib/BOAST/Runtime/FFIRuntime.rb +23 -0
- data/lib/BOAST/Runtime/FORTRANRuntime.rb +1 -1
- data/lib/BOAST/Runtime/MAQAO.rb +29 -0
- data/lib/BOAST/Runtime/NonRegression.rb +64 -3
- data/lib/BOAST/Runtime/OpenCLRuntime.rb +16 -6
- data/lib/BOAST/Runtime/Probe.rb +21 -1
- metadata +5 -3
data/lib/BOAST/Language/While.rb
CHANGED
@@ -7,7 +7,11 @@ module BOAST
|
|
7
7
|
|
8
8
|
attr_reader :condition
|
9
9
|
|
10
|
+
# Creates a new instance of the While construct.
|
11
|
+
# @param [Expression] condition
|
12
|
+
# @param [Proc,nil] block if given, will be evaluated when {pr} is called
|
10
13
|
def initialize(condition, &block)
|
14
|
+
super()
|
11
15
|
@condition = condition
|
12
16
|
@block = block
|
13
17
|
end
|
@@ -30,10 +34,13 @@ module BOAST
|
|
30
34
|
eval token_string_generator( * %w{while cond} )
|
31
35
|
eval token_string_generator( * %w{end} )
|
32
36
|
|
37
|
+
# Returns a string representation of the While construct.
|
33
38
|
def to_s
|
34
39
|
return while_string(@condition)
|
35
40
|
end
|
36
41
|
|
42
|
+
# Opens the While construct (keyword, condition, opening bracket in C like languages). The result is printed to the BOAST output.
|
43
|
+
# @return [self]
|
37
44
|
def open
|
38
45
|
s=""
|
39
46
|
s += indent
|
@@ -43,16 +50,24 @@ module BOAST
|
|
43
50
|
return self
|
44
51
|
end
|
45
52
|
|
46
|
-
|
53
|
+
# Prints the While construct to the BOAST output (see {open}).
|
54
|
+
# If a block is provided during initialization, it will be printed and the construct will be closed (see {close}).
|
55
|
+
# @param [Array<Object>] args any number of arguments to pass to the block
|
56
|
+
# @param [Proc] block an optional block to be evaluated. Supersede the one given at initialization
|
57
|
+
# @return [self]
|
58
|
+
def pr(*args, &block)
|
47
59
|
args = @args if args.length == 0 and @args
|
60
|
+
block = @block unless block
|
48
61
|
open
|
49
|
-
if
|
50
|
-
|
62
|
+
if block then
|
63
|
+
block.call(*args)
|
51
64
|
close
|
52
65
|
end
|
53
66
|
return self
|
54
67
|
end
|
55
68
|
|
69
|
+
# Closes the While construct (keyword, closing bracket in C like languages). The result is printed to the BOAST output.
|
70
|
+
# @return [self]
|
56
71
|
def close
|
57
72
|
decrement_indent_level
|
58
73
|
s = ""
|
File without changes
|
@@ -6,10 +6,11 @@ module BOAST
|
|
6
6
|
|
7
7
|
module_function
|
8
8
|
|
9
|
+
def cflags
|
10
|
+
return "-D_GNU_SOURCE"
|
11
|
+
end
|
12
|
+
|
9
13
|
def header
|
10
|
-
get_output.puts "#ifndef _GNU_SOURCE"
|
11
|
-
get_output.puts "#define _GNU_SOURCE"
|
12
|
-
get_output.puts "#endif"
|
13
14
|
get_output.puts "#include <sched.h>"
|
14
15
|
end
|
15
16
|
|
@@ -60,6 +61,9 @@ EOF
|
|
60
61
|
EOF
|
61
62
|
end
|
62
63
|
|
64
|
+
def store
|
65
|
+
end
|
66
|
+
|
63
67
|
end
|
64
68
|
|
65
69
|
end
|
@@ -23,6 +23,7 @@ module BOAST
|
|
23
23
|
attr_accessor :architecture
|
24
24
|
attr_accessor :kernels
|
25
25
|
attr_accessor :cost_function
|
26
|
+
attr_accessor :includes
|
26
27
|
|
27
28
|
# Creates a new CKernel object. BOAST output is redirected to the CKernel. If the chain_code state is set the current BOAST output, as returned by {BOAST.get_output}, is used.
|
28
29
|
# @param [Hash] options contains named options
|
@@ -55,6 +56,8 @@ module BOAST
|
|
55
56
|
else
|
56
57
|
@architecture = get_architecture
|
57
58
|
end
|
59
|
+
@includes = []
|
60
|
+
@includes = [options[:includes]].flatten if options[:includes]
|
58
61
|
|
59
62
|
case @lang
|
60
63
|
when CL
|
@@ -9,6 +9,10 @@ module BOAST
|
|
9
9
|
def fill_library_header
|
10
10
|
get_output.puts "#include <stdlib.h>"
|
11
11
|
get_output.puts "#include <inttypes.h>"
|
12
|
+
get_output.puts "#include <math.h>"
|
13
|
+
@includes.each { |inc|
|
14
|
+
get_output.puts "#include \"#{inc}\""
|
15
|
+
}
|
12
16
|
get_output.puts "#define __assume_aligned(lvalueptr, align) lvalueptr = __builtin_assume_aligned (lvalueptr, align)" if @compiler_options[:CC].match("gcc")
|
13
17
|
end
|
14
18
|
|
@@ -8,7 +8,12 @@ require 'os'
|
|
8
8
|
|
9
9
|
class Dir
|
10
10
|
module Tmpname
|
11
|
-
|
11
|
+
class << self
|
12
|
+
undef_method :make_tmpname
|
13
|
+
end
|
14
|
+
|
15
|
+
undef_method :make_tmpname
|
16
|
+
|
12
17
|
def make_tmpname(prefix_suffix, n)
|
13
18
|
case prefix_suffix
|
14
19
|
when String
|
@@ -25,6 +30,9 @@ class Dir
|
|
25
30
|
path << "_#{n}" if n
|
26
31
|
path << suffix
|
27
32
|
end
|
33
|
+
|
34
|
+
module_function :make_tmpname
|
35
|
+
|
28
36
|
end
|
29
37
|
end
|
30
38
|
|
@@ -86,6 +94,10 @@ module BOAST
|
|
86
94
|
return "#{base_path}.#{RbConfig::CONFIG["OBJEXT"]}"
|
87
95
|
end
|
88
96
|
|
97
|
+
def library_nofpic_object
|
98
|
+
return "#{base_path}.nofpic#{RbConfig::CONFIG["OBJEXT"]}"
|
99
|
+
end
|
100
|
+
|
89
101
|
def library_path
|
90
102
|
return "#{base_path}.#{RbConfig::CONFIG["DLEXT"]}"
|
91
103
|
end
|
@@ -94,10 +106,26 @@ module BOAST
|
|
94
106
|
return module_file_path
|
95
107
|
end
|
96
108
|
|
109
|
+
def executable_source
|
110
|
+
return "#{base_path}_executable.c"
|
111
|
+
end
|
112
|
+
|
113
|
+
def executable_object
|
114
|
+
return "#{base_path}_executable.nofpic#{RbConfig::CONFIG["OBJEXT"]}"
|
115
|
+
end
|
116
|
+
|
117
|
+
def target_executable
|
118
|
+
return "#{base_path}_executable"
|
119
|
+
end
|
120
|
+
|
97
121
|
def target_depends
|
98
122
|
return [ module_file_object, library_object ]
|
99
123
|
end
|
100
124
|
|
125
|
+
def target_executable_depends
|
126
|
+
return [ library_nofpic_object, executable_object ]
|
127
|
+
end
|
128
|
+
|
101
129
|
def save_binary
|
102
130
|
f = File::open(library_object,"rb")
|
103
131
|
@binary = StringIO::new
|
@@ -112,14 +140,35 @@ module BOAST
|
|
112
140
|
f.close
|
113
141
|
end
|
114
142
|
|
115
|
-
def
|
143
|
+
def save_module
|
144
|
+
f = File::open(module_file_path, "rb")
|
145
|
+
@module_binary = StringIO::new
|
146
|
+
@module_binary.write( f.read )
|
147
|
+
f.close
|
148
|
+
end
|
149
|
+
|
150
|
+
def save_executable
|
151
|
+
f = File::open(target_executable, "rb")
|
152
|
+
@executable = StringIO::new
|
153
|
+
@executable.write( f.read )
|
154
|
+
f.close
|
155
|
+
end
|
156
|
+
|
157
|
+
def create_targets( linker, ldshared, ldshared_flags, ldflags, kernel_files)
|
116
158
|
file target => target_depends do
|
117
|
-
#puts "#{linker} #{ldshared} -o #{target} #{target_depends.join(" ")} #{(kernel_files.collect {|f| f.path}).join(" ")} #{ldflags}"
|
118
|
-
sh "#{linker} #{ldshared} -o #{target} #{target_depends.join(" ")} #{(kernel_files.collect {|f| f.path}).join(" ")} #{ldflags}"
|
159
|
+
#puts "#{linker} #{ldshared} -o #{target} #{target_depends.join(" ")} #{(kernel_files.collect {|f| f.path}).join(" ")} #{ldshared_flags} #{ldflags}"
|
160
|
+
sh "#{linker} #{ldshared} -o #{target} #{target_depends.join(" ")} #{(kernel_files.collect {|f| f.path}).join(" ")} #{ldshared_flags} #{ldflags}"
|
119
161
|
end
|
120
162
|
Rake::Task[target].invoke
|
121
163
|
end
|
122
164
|
|
165
|
+
def create_executable_target( linker, ldflags, kernel_files)
|
166
|
+
file target_executable => target_executable_depends do
|
167
|
+
sh "#{linker} -o #{target_executable} #{target_executable_depends.join(" ")} #{(kernel_files.collect {|f| f.path}).join(" ")} #{ldflags}"
|
168
|
+
end
|
169
|
+
Rake::Task[target_executable].invoke
|
170
|
+
end
|
171
|
+
|
123
172
|
def method_name
|
124
173
|
return @procedure.name
|
125
174
|
end
|
@@ -138,19 +187,14 @@ module BOAST
|
|
138
187
|
|
139
188
|
def create_library_source
|
140
189
|
f = File::open(library_source,"w+")
|
141
|
-
|
142
|
-
|
143
|
-
set_output(f)
|
144
|
-
set_lang(@lang)
|
145
|
-
|
146
|
-
fill_library_source
|
190
|
+
push_env( :output => f, :lang => @lang ) {
|
191
|
+
fill_library_source
|
147
192
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
set_lang(previous_lang)
|
193
|
+
if debug_source? or debug_kernel_source? then
|
194
|
+
f.rewind
|
195
|
+
puts f.read
|
196
|
+
end
|
197
|
+
}
|
154
198
|
f.close
|
155
199
|
end
|
156
200
|
|
@@ -162,6 +206,9 @@ module BOAST
|
|
162
206
|
#include "narray.h"
|
163
207
|
#endif
|
164
208
|
EOF
|
209
|
+
@includes.each { |inc|
|
210
|
+
get_output.puts "#include \"#{inc}\""
|
211
|
+
}
|
165
212
|
end
|
166
213
|
|
167
214
|
def fill_module_preamble
|
@@ -215,26 +262,26 @@ EOF
|
|
215
262
|
end
|
216
263
|
|
217
264
|
def fill_decl_module_params
|
218
|
-
push_env(:decl_module => true)
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
265
|
+
push_env(:decl_module => true) {
|
266
|
+
@procedure.parameters.each { |param|
|
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]
|
274
|
+
get_output.puts " VALUE _boast_stats = rb_hash_new();"
|
275
|
+
get_output.puts " VALUE _boast_rb_ptr = Qnil;"
|
276
|
+
refs = false
|
277
|
+
@procedure.parameters.each_with_index do |param,i|
|
278
|
+
refs = true if param.scalar_output?
|
279
|
+
end
|
280
|
+
if refs then
|
281
|
+
get_output.puts " VALUE _boast_refs = rb_hash_new();"
|
282
|
+
get_output.puts " rb_hash_aset(_boast_stats,ID2SYM(rb_intern(\"reference_return\")),_boast_refs);"
|
283
|
+
end
|
225
284
|
}
|
226
|
-
get_output.puts " #{@procedure.properties[:return].type.decl} _boast_ret;" if @procedure.properties[:return]
|
227
|
-
get_output.puts " VALUE _boast_stats = rb_hash_new();"
|
228
|
-
get_output.puts " VALUE _boast_rb_ptr = Qnil;"
|
229
|
-
refs = false
|
230
|
-
@procedure.parameters.each_with_index do |param,i|
|
231
|
-
refs = true if param.scalar_output?
|
232
|
-
end
|
233
|
-
if refs then
|
234
|
-
get_output.puts " VALUE _boast_refs = rb_hash_new();"
|
235
|
-
get_output.puts " rb_hash_aset(_boast_stats,ID2SYM(rb_intern(\"reference_return\")),_boast_refs);"
|
236
|
-
end
|
237
|
-
pop_env(:decl_module)
|
238
285
|
end
|
239
286
|
|
240
287
|
def copy_scalar_param_from_ruby( param, ruby_param )
|
@@ -252,11 +299,23 @@ EOF
|
|
252
299
|
(rb_ptr === ruby_param).pr
|
253
300
|
get_output.print <<EOF
|
254
301
|
if (TYPE(_boast_rb_ptr) == T_STRING) {
|
255
|
-
#{
|
302
|
+
#{
|
303
|
+
if param.dimension then
|
304
|
+
"#{param} = (void *)RSTRING_PTR(_boast_rb_ptr)"
|
305
|
+
else
|
306
|
+
(param === param.copy("*(void *)RSTRING_PTR(_boast_rb_ptr)", :dimension => Dim(), :vector_length => 1)).to_s
|
307
|
+
end
|
308
|
+
};
|
256
309
|
} else if ( IsNArray(_boast_rb_ptr) ) {
|
257
310
|
struct NARRAY *_boast_n_ary;
|
258
311
|
Data_Get_Struct(_boast_rb_ptr, struct NARRAY, _boast_n_ary);
|
259
|
-
#{
|
312
|
+
#{
|
313
|
+
if param.dimension then
|
314
|
+
"#{param} = (void *) _boast_n_ary->ptr"
|
315
|
+
else
|
316
|
+
(param === param.copy("*(void *) _boast_n_ary->ptr", :dimension => Dim(), :vector_length => 1)).to_s
|
317
|
+
end
|
318
|
+
};
|
260
319
|
} else {
|
261
320
|
rb_raise(rb_eArgError, "Wrong type of argument for %s, expecting array!", "#{param}");
|
262
321
|
}
|
@@ -266,17 +325,16 @@ EOF
|
|
266
325
|
def get_params_value
|
267
326
|
argc = @procedure.parameters.length
|
268
327
|
argv = Variable::new("_boast_argv", CustomType, :type_name => "VALUE", :dimension => [ Dimension::new(0,argc-1) ] )
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
328
|
+
push_env(:decl_module => true) {
|
329
|
+
@procedure.parameters.each_index do |i|
|
330
|
+
param = @procedure.parameters[i]
|
331
|
+
if not param.dimension? and not param.vector? then
|
332
|
+
copy_scalar_param_from_ruby(param, argv[i])
|
333
|
+
else
|
334
|
+
copy_array_param_from_ruby(param, argv[i])
|
335
|
+
end
|
277
336
|
end
|
278
|
-
|
279
|
-
pop_env(:decl_module)
|
337
|
+
}
|
280
338
|
end
|
281
339
|
|
282
340
|
def create_procedure_call
|
@@ -301,23 +359,67 @@ EOF
|
|
301
359
|
end
|
302
360
|
end
|
303
361
|
|
362
|
+
def copy_scalar_param_to_file(param, base_path)
|
363
|
+
if param.scalar_output? then
|
364
|
+
get_output.puts <<EOF
|
365
|
+
__boast_f = fopen("#{base_path}/#{param}.out", "wb");
|
366
|
+
fwrite(&#{param}, sizeof(#{param}), 1, __boast_f);
|
367
|
+
fclose(__boast_f);
|
368
|
+
EOF
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
def copy_scalar_param_from_file(param, base_path)
|
373
|
+
get_output.puts <<EOF
|
374
|
+
__boast_f = fopen("#{base_path}/#{param}.in", "rb");
|
375
|
+
fread(&#{param}, sizeof(#{param}), 1, __boast_f);
|
376
|
+
fclose(__boast_f);
|
377
|
+
EOF
|
378
|
+
end
|
379
|
+
|
304
380
|
def copy_array_param_to_ruby(param, ruby_param)
|
305
381
|
end
|
306
382
|
|
383
|
+
def copy_array_param_to_file(param, base_path)
|
384
|
+
if param.direction == :out or param.direction == :inout then
|
385
|
+
get_output.puts <<EOF
|
386
|
+
__boast_f = fopen("#{base_path}/#{param}.out", "wb");
|
387
|
+
fwrite(#{param}, 1, __boast_sizeof_#{param}, __boast_f);
|
388
|
+
fclose(__boast_f);
|
389
|
+
free(#{param});
|
390
|
+
EOF
|
391
|
+
else
|
392
|
+
get_output.puts <<EOF
|
393
|
+
free(#{param});
|
394
|
+
EOF
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
def copy_array_param_from_file(param, base_path)
|
399
|
+
get_output.puts <<EOF
|
400
|
+
__boast_f = fopen("#{base_path}/#{param}.in", "rb");
|
401
|
+
fseek(__boast_f, 0L, SEEK_END);
|
402
|
+
__boast_sizeof_#{param} = ftell(__boast_f);
|
403
|
+
rewind(__boast_f);
|
404
|
+
#{param} = malloc(__boast_sizeof_#{param});
|
405
|
+
fread(#{param}, 1, __boast_sizeof_#{param}, __boast_f);
|
406
|
+
fclose(__boast_f);
|
407
|
+
EOF
|
408
|
+
end
|
409
|
+
|
307
410
|
def get_results
|
308
411
|
argc = @procedure.parameters.length
|
309
412
|
argv = Variable::new("_boast_argv", CustomType, :type_name => "VALUE", :dimension => [ Dimension::new(0,argc-1) ] )
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
413
|
+
push_env(:decl_module => true) {
|
414
|
+
@procedure.parameters.each_index do |i|
|
415
|
+
param = @procedure.parameters[i]
|
416
|
+
if not param.dimension then
|
417
|
+
copy_scalar_param_to_ruby(param, argv[i])
|
418
|
+
else
|
419
|
+
copy_array_param_to_ruby(param, argv[i])
|
420
|
+
end
|
318
421
|
end
|
319
|
-
|
320
|
-
pop_env(:decl_module)
|
422
|
+
}
|
321
423
|
end
|
322
424
|
|
323
425
|
def store_results
|
@@ -329,6 +431,118 @@ EOF
|
|
329
431
|
end
|
330
432
|
end
|
331
433
|
|
434
|
+
def get_executable_params_value( base_path )
|
435
|
+
push_env(:decl_module => true) {
|
436
|
+
@procedure.parameters.each do |param|
|
437
|
+
if not param.dimension? then
|
438
|
+
copy_scalar_param_from_file(param, base_path)
|
439
|
+
else
|
440
|
+
copy_array_param_from_file(param, base_path)
|
441
|
+
end
|
442
|
+
end
|
443
|
+
}
|
444
|
+
end
|
445
|
+
|
446
|
+
def get_executable_params_return_value( base_path )
|
447
|
+
push_env(:decl_module => true) {
|
448
|
+
@procedure.parameters.each do |param|
|
449
|
+
if not param.dimension then
|
450
|
+
copy_scalar_param_to_file(param, base_path)
|
451
|
+
else
|
452
|
+
copy_array_param_to_file(param, base_path)
|
453
|
+
end
|
454
|
+
end
|
455
|
+
}
|
456
|
+
end
|
457
|
+
|
458
|
+
def fill_executable_source
|
459
|
+
get_output.puts "#include <inttypes.h>"
|
460
|
+
get_output.puts "#include <stdlib.h>"
|
461
|
+
get_output.puts "#include <stdio.h>"
|
462
|
+
@includes.each { |inc|
|
463
|
+
get_output.puts "#include \"#{inc}\""
|
464
|
+
}
|
465
|
+
@probes.map(&:header)
|
466
|
+
@procedure.boast_header(@lang)
|
467
|
+
|
468
|
+
get_output.print <<EOF
|
469
|
+
void Init_#{base_name}( void );
|
470
|
+
int _boast_repeat;
|
471
|
+
void Init_#{base_name}( void ) {
|
472
|
+
EOF
|
473
|
+
increment_indent_level
|
474
|
+
output.puts " FILE * __boast_f;"
|
475
|
+
push_env(:decl_module => true) {
|
476
|
+
@procedure.parameters.each { |param|
|
477
|
+
if param.dimension? then
|
478
|
+
output.puts " size_t __boast_sizeof_#{param};"
|
479
|
+
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
|
+
}
|
486
|
+
get_output.puts " #{@procedure.properties[:return].type.decl} _boast_ret;" if @procedure.properties[:return]
|
487
|
+
}
|
488
|
+
@probes.reverse.map(&:decl)
|
489
|
+
@probes.map(&:configure)
|
490
|
+
|
491
|
+
get_executable_params_value( "#{@tmp_dir}/#{@procedure.name}/#{base_name}" )
|
492
|
+
|
493
|
+
@probes.reverse.map(&:start)
|
494
|
+
|
495
|
+
get_output.puts " int _boast_i;"
|
496
|
+
get_output.puts " for(_boast_i = 0; _boast_i < _boast_repeat; ++_boast_i){"
|
497
|
+
get_output.print " "
|
498
|
+
get_output.print "_boast_ret = " if @procedure.properties[:return]
|
499
|
+
get_output.print "#{method_name}( "
|
500
|
+
get_output.print create_procedure_call_parameters.join(", ")
|
501
|
+
get_output.puts " );"
|
502
|
+
get_output.puts " }"
|
503
|
+
|
504
|
+
@probes.map(&:stop)
|
505
|
+
|
506
|
+
get_output.puts ' printf("---\n");'
|
507
|
+
if @procedure.properties[:return] then
|
508
|
+
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)
|
512
|
+
|
513
|
+
end
|
514
|
+
|
515
|
+
get_executable_params_return_value( "#{@tmp_dir}/#{@procedure.name}/#{base_name}" )
|
516
|
+
|
517
|
+
@probes.map(&:compute)
|
518
|
+
|
519
|
+
@probes.map(&:to_yaml)
|
520
|
+
|
521
|
+
decrement_indent_level
|
522
|
+
get_output.print <<EOF
|
523
|
+
}
|
524
|
+
int main(int argc, char * argv[]) {
|
525
|
+
_boast_repeat=atoi(argv[1]);
|
526
|
+
Init_#{base_name}();
|
527
|
+
return 0;
|
528
|
+
}
|
529
|
+
EOF
|
530
|
+
|
531
|
+
end
|
532
|
+
|
533
|
+
def create_executable_source
|
534
|
+
f = File::open(executable_source, "w+")
|
535
|
+
push_env(:output => f, :lang => C) {
|
536
|
+
fill_executable_source
|
537
|
+
|
538
|
+
if debug_source? then
|
539
|
+
f.rewind
|
540
|
+
puts f.read
|
541
|
+
end
|
542
|
+
}
|
543
|
+
f.close
|
544
|
+
end
|
545
|
+
|
332
546
|
def fill_module_file_source
|
333
547
|
fill_module_header
|
334
548
|
@probes.map(&:header)
|
@@ -360,7 +574,10 @@ EOF
|
|
360
574
|
|
361
575
|
get_results
|
362
576
|
|
363
|
-
@probes.
|
577
|
+
@probes.each { |p|
|
578
|
+
p.compute
|
579
|
+
p.store
|
580
|
+
}
|
364
581
|
|
365
582
|
store_results
|
366
583
|
|
@@ -371,16 +588,14 @@ EOF
|
|
371
588
|
|
372
589
|
def create_module_file_source
|
373
590
|
f = File::open(module_file_source, "w+")
|
374
|
-
push_env(:lang => C)
|
375
|
-
|
376
|
-
|
377
|
-
fill_module_file_source
|
591
|
+
push_env(:output => f, :lang => C) {
|
592
|
+
fill_module_file_source
|
378
593
|
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
594
|
+
if debug_source? then
|
595
|
+
f.rewind
|
596
|
+
puts f.read
|
597
|
+
end
|
598
|
+
}
|
384
599
|
f.close
|
385
600
|
end
|
386
601
|
|
@@ -397,6 +612,10 @@ EOF
|
|
397
612
|
return [ module_file_source, library_source ]
|
398
613
|
end
|
399
614
|
|
615
|
+
def target_executable_sources
|
616
|
+
return [ executable_source, library_source ]
|
617
|
+
end
|
618
|
+
|
400
619
|
def cleanup(kernel_files)
|
401
620
|
([target] + target_depends + target_sources).each { |fn|
|
402
621
|
File::unlink(fn)
|
@@ -406,35 +625,123 @@ EOF
|
|
406
625
|
}
|
407
626
|
end
|
408
627
|
|
628
|
+
def cleanup_executable(kernel_files)
|
629
|
+
( [target_executable] + target_executable_depends + target_executable_sources ).each { |fn|
|
630
|
+
File::unlink(fn)
|
631
|
+
}
|
632
|
+
kernel_files.each { |f|
|
633
|
+
f.unlink
|
634
|
+
}
|
635
|
+
end
|
636
|
+
|
637
|
+
def run_executable(*params)
|
638
|
+
options = {:repeat => 1}
|
639
|
+
if params.last.kind_of?(Hash) then
|
640
|
+
options.update(params.last)
|
641
|
+
ps = params[0..-2]
|
642
|
+
else
|
643
|
+
ps = params[0..-1]
|
644
|
+
end
|
645
|
+
|
646
|
+
Dir::mkdir(@tmp_dir, 0700) unless Dir::exist?(@tmp_dir)
|
647
|
+
|
648
|
+
dump_executable
|
649
|
+
dump_ref_inputs( { base_name => ps }, @tmp_dir )
|
650
|
+
boast_ret = YAML::load `#{target_executable} #{options[:repeat]}`
|
651
|
+
File::unlink(target_executable) unless keep_temp
|
652
|
+
|
653
|
+
res = load_ref_outputs(@tmp_dir)["#{@tmp_dir}/#{@procedure.name}/#{base_name}"]
|
654
|
+
@procedure.parameters.each_with_index { |param, indx|
|
655
|
+
if param.direction == :in or param.constant then
|
656
|
+
next
|
657
|
+
end
|
658
|
+
if param.dimension then
|
659
|
+
ps[indx][0..-1] = res[indx][0..-1]
|
660
|
+
else
|
661
|
+
boast_ret[:reference_return] = {} unless boast_ret[:reference_return]
|
662
|
+
boast_ret[:reference_return][param.name.to_sym] = res[indx]
|
663
|
+
end
|
664
|
+
}
|
665
|
+
p = Pathname::new("#{@tmp_dir}/#{@procedure.name}/#{base_name}")
|
666
|
+
p.children.each { |f| File::unlink f }
|
667
|
+
unless keep_temp then
|
668
|
+
Dir::rmdir("#{@tmp_dir}/#{@procedure.name}/#{base_name}")
|
669
|
+
Dir::rmdir("#{@tmp_dir}/#{@procedure.name}")
|
670
|
+
Dir::rmdir("#{@tmp_dir}")
|
671
|
+
end
|
672
|
+
return boast_ret
|
673
|
+
end
|
674
|
+
|
675
|
+
def build_executable(options={})
|
676
|
+
compiler_options = BOAST::get_compiler_options
|
677
|
+
compiler_options.update(options)
|
678
|
+
@probes = [TimerProbe]
|
679
|
+
linker, _, _, ldflags = setup_compilers(@probes, compiler_options)
|
680
|
+
@compiler_options = compiler_options
|
681
|
+
|
682
|
+
@marker = Tempfile::new([@procedure.name,""])
|
683
|
+
Dir::mktmpdir { |dir|
|
684
|
+
@tmp_dir = "#{dir}"
|
685
|
+
}
|
686
|
+
|
687
|
+
kernel_files = get_sub_kernels
|
688
|
+
|
689
|
+
create_library_source
|
690
|
+
|
691
|
+
create_executable_source
|
692
|
+
|
693
|
+
save_source
|
694
|
+
|
695
|
+
create_executable_target(linker, ldflags, kernel_files)
|
696
|
+
|
697
|
+
save_executable
|
698
|
+
|
699
|
+
instance_eval <<EOF
|
700
|
+
def run(*args, &block)
|
701
|
+
run_executable(*args, &block)
|
702
|
+
end
|
703
|
+
EOF
|
704
|
+
|
705
|
+
cleanup_executable(kernel_files) unless keep_temp
|
706
|
+
|
707
|
+
return self
|
708
|
+
|
709
|
+
end
|
710
|
+
|
409
711
|
public
|
410
712
|
|
411
713
|
def build(options={})
|
714
|
+
return build_executable(options) if executable? and (@lang == C or @lang == FORTRAN)
|
412
715
|
compiler_options = BOAST::get_compiler_options
|
413
716
|
compiler_options.update(options)
|
414
|
-
linker, ldshared, ldflags = setup_compilers(compiler_options)
|
415
|
-
@compiler_options = compiler_options
|
416
717
|
@probes = []
|
417
|
-
if
|
418
|
-
@probes =
|
419
|
-
elsif get_lang != CUDA
|
718
|
+
if compiler_options[:probes] then
|
719
|
+
@probes = compiler_options[:probes]
|
720
|
+
elsif get_lang != CUDA then
|
420
721
|
@probes = [TimerProbe, PAPIProbe]
|
421
722
|
@probes.push EnergyProbe if EnergyProbe
|
422
723
|
@probes.push AffinityProbe unless OS.mac?
|
423
724
|
end
|
424
725
|
@probes = [MPPAProbe] if @architecture == MPPA
|
726
|
+
linker, ldshared, ldshared_flags, ldflags = setup_compilers(@probes, compiler_options)
|
727
|
+
@compiler_options = compiler_options
|
425
728
|
|
426
729
|
@marker = Tempfile::new([@procedure.name,""])
|
427
730
|
|
731
|
+
extend MAQAO if @compiler_options[:MAQAO_PASS]
|
732
|
+
|
428
733
|
kernel_files = get_sub_kernels
|
429
734
|
|
430
735
|
create_sources
|
431
736
|
|
432
737
|
save_source
|
433
738
|
|
434
|
-
create_targets(linker, ldshared, ldflags, kernel_files)
|
739
|
+
create_targets(linker, ldshared, ldshared_flags, ldflags, kernel_files)
|
435
740
|
|
436
741
|
save_binary
|
437
742
|
|
743
|
+
save_module
|
744
|
+
|
438
745
|
load_module
|
439
746
|
|
440
747
|
cleanup(kernel_files) unless keep_temp
|
@@ -444,20 +751,40 @@ EOF
|
|
444
751
|
return self
|
445
752
|
end
|
446
753
|
|
447
|
-
def dump_binary
|
448
|
-
f = File::open(library_object,"wb")
|
754
|
+
def dump_binary(path = nil)
|
755
|
+
f = path ? File::open(path,"wb") : File::open(library_object,"wb")
|
449
756
|
@binary.rewind
|
450
757
|
f.write( @binary.read )
|
451
758
|
f.close
|
452
759
|
end
|
453
760
|
|
454
|
-
def dump_source
|
455
|
-
f = File::open(library_source,"wb")
|
761
|
+
def dump_source(path = nil)
|
762
|
+
f = path ? File::open(path,"wb") : File::open(library_source,"wb")
|
456
763
|
@source.rewind
|
457
764
|
f.write( @source.read )
|
458
765
|
f.close
|
459
766
|
end
|
460
767
|
|
768
|
+
def dump_module(path = nil)
|
769
|
+
f = path ? File::open(path,"wb") : File::open(module_file_path,"wb")
|
770
|
+
@module_binary.rewind
|
771
|
+
f.write( @module_binary.read )
|
772
|
+
f.close
|
773
|
+
end
|
774
|
+
|
775
|
+
def dump_executable(path = nil)
|
776
|
+
f = path ? File::open(path,"wb",0700) : File::open(target_executable,"wb",0700)
|
777
|
+
@executable.rewind
|
778
|
+
f.write( @executable.read )
|
779
|
+
f.close
|
780
|
+
end
|
781
|
+
|
782
|
+
def reload_module
|
783
|
+
raise "Missing binary library data!" unless @module_binary
|
784
|
+
$LOADED_FEATURES.delete(module_file_path)
|
785
|
+
require module_file_path
|
786
|
+
end
|
787
|
+
|
461
788
|
end
|
462
789
|
|
463
790
|
end
|