BOAST 1.3.5 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|