BOAST 1.0.3 → 1.0.4
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 +2 -31
- data/README.md +240 -0
- data/lib/BOAST/{OpenMP.rb → Language/OpenMP.rb} +1 -0
- data/lib/BOAST/{Variable.rb → Language/Variable.rb} +2 -1
- data/lib/BOAST/Runtime/CKernel.rb +94 -0
- data/lib/BOAST/Runtime/CRuntime.rb +32 -0
- data/lib/BOAST/Runtime/CUDARuntime.rb +158 -0
- data/lib/BOAST/Runtime/CompiledRuntime.rb +398 -0
- data/lib/BOAST/Runtime/Compilers.rb +205 -0
- data/lib/BOAST/Runtime/Config.rb +94 -0
- data/lib/BOAST/Runtime/FFIRuntime.rb +104 -0
- data/lib/BOAST/Runtime/FORTRANRuntime.rb +45 -0
- data/lib/BOAST/Runtime/MPPARuntime.rb +464 -0
- data/lib/BOAST/Runtime/NonRegression.rb +157 -0
- data/lib/BOAST/Runtime/OpenCLRuntime.rb +181 -0
- data/lib/BOAST/Runtime/Probe.rb +136 -0
- data/lib/BOAST.rb +37 -26
- metadata +40 -28
- data/lib/BOAST/CKernel.rb +0 -1236
- /data/lib/BOAST/{Algorithm.rb → Language/Algorithm.rb} +0 -0
- /data/lib/BOAST/{Arithmetic.rb → Language/Arithmetic.rb} +0 -0
- /data/lib/BOAST/{BOAST_OpenCL.rb → Language/BOAST_OpenCL.rb} +0 -0
- /data/lib/BOAST/{Case.rb → Language/Case.rb} +0 -0
- /data/lib/BOAST/{ControlStructure.rb → Language/ControlStructure.rb} +0 -0
- /data/lib/BOAST/{DataTypes.rb → Language/DataTypes.rb} +0 -0
- /data/lib/BOAST/{Expression.rb → Language/Expression.rb} +0 -0
- /data/lib/BOAST/{For.rb → Language/For.rb} +0 -0
- /data/lib/BOAST/{FuncCall.rb → Language/FuncCall.rb} +0 -0
- /data/lib/BOAST/{Functors.rb → Language/Functors.rb} +0 -0
- /data/lib/BOAST/{If.rb → Language/If.rb} +0 -0
- /data/lib/BOAST/{Index.rb → Language/Index.rb} +0 -0
- /data/lib/BOAST/{Inspectable.rb → Language/Inspectable.rb} +0 -0
- /data/lib/BOAST/{Operators.rb → Language/Operators.rb} +0 -0
- /data/lib/BOAST/{Optimization.rb → Language/Optimization.rb} +0 -0
- /data/lib/BOAST/{Parens.rb → Language/Parens.rb} +0 -0
- /data/lib/BOAST/{Pragma.rb → Language/Pragma.rb} +0 -0
- /data/lib/BOAST/{Print.rb → Language/Print.rb} +0 -0
- /data/lib/BOAST/{Procedure.rb → Language/Procedure.rb} +0 -0
- /data/lib/BOAST/{Slice.rb → Language/Slice.rb} +0 -0
- /data/lib/BOAST/{State.rb → Language/State.rb} +0 -0
- /data/lib/BOAST/{Transitions.rb → Language/Transitions.rb} +0 -0
- /data/lib/BOAST/{While.rb → Language/While.rb} +0 -0
@@ -0,0 +1,398 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require 'rake'
|
3
|
+
require 'tempfile'
|
4
|
+
require 'rbconfig'
|
5
|
+
require 'systemu'
|
6
|
+
require 'pathname'
|
7
|
+
require 'os'
|
8
|
+
|
9
|
+
class Dir
|
10
|
+
module Tmpname
|
11
|
+
module_function
|
12
|
+
def make_tmpname(prefix_suffix, n)
|
13
|
+
case prefix_suffix
|
14
|
+
when String
|
15
|
+
prefix = prefix_suffix
|
16
|
+
suffix = ""
|
17
|
+
when Array
|
18
|
+
prefix = prefix_suffix[0]
|
19
|
+
suffix = prefix_suffix[1]
|
20
|
+
else
|
21
|
+
raise ArgumentError, "unexpected prefix_suffix: #{prefix_suffix.inspect}"
|
22
|
+
end
|
23
|
+
t = Time.now.strftime("%Y%m%d")
|
24
|
+
path = "#{prefix}#{t}_#{$$}_#{rand(0x100000000).to_s(36)}"
|
25
|
+
path << "_#{n}" if n
|
26
|
+
path << suffix
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module BOAST
|
32
|
+
|
33
|
+
module CompiledRuntime
|
34
|
+
@@extensions = {
|
35
|
+
C => ".c",
|
36
|
+
CUDA => ".cu",
|
37
|
+
FORTRAN => ".f90"
|
38
|
+
}
|
39
|
+
|
40
|
+
def base_name
|
41
|
+
return File::split(@marker.path)[1]
|
42
|
+
end
|
43
|
+
|
44
|
+
def module_name
|
45
|
+
return "Mod_" + base_name#.gsub("-","_")
|
46
|
+
end
|
47
|
+
|
48
|
+
def directory
|
49
|
+
return File::split(@marker.path)[0]
|
50
|
+
end
|
51
|
+
|
52
|
+
def module_file_base_name
|
53
|
+
return "Mod_" + base_name
|
54
|
+
end
|
55
|
+
|
56
|
+
def module_file_base_path
|
57
|
+
return "#{directory}/#{module_file_base_name}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def module_file_path
|
61
|
+
return "#{module_file_base_path}.#{RbConfig::CONFIG["DLEXT"]}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def module_file_source
|
65
|
+
return module_file_base_path + ".c"
|
66
|
+
end
|
67
|
+
|
68
|
+
def module_file_object
|
69
|
+
return "#{module_file_base_path}.#{RbConfig::CONFIG["OBJEXT"]}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def base_path
|
73
|
+
return "#{directory}/#{base_name}"
|
74
|
+
end
|
75
|
+
|
76
|
+
def library_source
|
77
|
+
return base_path + @@extensions[@lang]
|
78
|
+
end
|
79
|
+
|
80
|
+
def library_object
|
81
|
+
return "#{base_path}.#{RbConfig::CONFIG["OBJEXT"]}"
|
82
|
+
end
|
83
|
+
|
84
|
+
def library_path
|
85
|
+
return "#{base_path}.#{RbConfig::CONFIG["DLEXT"]}"
|
86
|
+
end
|
87
|
+
|
88
|
+
def target
|
89
|
+
return module_file_path
|
90
|
+
end
|
91
|
+
|
92
|
+
def target_depends
|
93
|
+
return [ module_file_object, library_object ]
|
94
|
+
end
|
95
|
+
|
96
|
+
def save_binary
|
97
|
+
f = File::open(library_object,"rb")
|
98
|
+
@binary = StringIO::new
|
99
|
+
@binary.write( f.read )
|
100
|
+
f.close
|
101
|
+
end
|
102
|
+
|
103
|
+
def create_targets( linker, ldshared, ldflags, kernel_files)
|
104
|
+
file target => target_depends do
|
105
|
+
#puts "#{linker} #{ldshared} -o #{target} #{target_depends.join(" ")} #{(kernel_files.collect {|f| f.path}).join(" ")} #{ldflags}"
|
106
|
+
sh "#{linker} #{ldshared} -o #{target} #{target_depends.join(" ")} #{(kernel_files.collect {|f| f.path}).join(" ")} #{ldflags}"
|
107
|
+
end
|
108
|
+
Rake::Task[target].invoke
|
109
|
+
end
|
110
|
+
|
111
|
+
def method_name
|
112
|
+
return @procedure.name
|
113
|
+
end
|
114
|
+
|
115
|
+
def get_sub_kernels
|
116
|
+
kernel_files = []
|
117
|
+
@kernels.each { |kernel|
|
118
|
+
kernel_file = Tempfile::new([kernel.procedure.name,".#{RbConfig::CONFIG["OBJEXT"]}"])
|
119
|
+
kernel.binary.rewind
|
120
|
+
kernel_file.write( kernel.binary.read )
|
121
|
+
kernel_file.close
|
122
|
+
kernel_files.push(kernel_file)
|
123
|
+
}
|
124
|
+
return kernel_files
|
125
|
+
end
|
126
|
+
|
127
|
+
def create_library_source
|
128
|
+
f = File::open(library_source,"w+")
|
129
|
+
previous_lang = get_lang
|
130
|
+
previous_output = get_output
|
131
|
+
set_output(f)
|
132
|
+
set_lang(@lang)
|
133
|
+
|
134
|
+
fill_library_source
|
135
|
+
|
136
|
+
if debug_source? then
|
137
|
+
f.rewind
|
138
|
+
puts f.read
|
139
|
+
end
|
140
|
+
set_output(previous_output)
|
141
|
+
set_lang(previous_lang)
|
142
|
+
f.close
|
143
|
+
end
|
144
|
+
|
145
|
+
def fill_module_header
|
146
|
+
get_output.print <<EOF
|
147
|
+
#include "ruby.h"
|
148
|
+
#include <inttypes.h>
|
149
|
+
#ifdef HAVE_NARRAY_H
|
150
|
+
#include "narray.h"
|
151
|
+
#endif
|
152
|
+
EOF
|
153
|
+
end
|
154
|
+
|
155
|
+
def fill_module_preamble
|
156
|
+
get_output.print <<EOF
|
157
|
+
VALUE #{module_name} = Qnil;
|
158
|
+
void Init_#{module_name}();
|
159
|
+
VALUE method_run(int _boast_argc, VALUE *_boast_argv, VALUE _boast_self);
|
160
|
+
void Init_#{module_name}() {
|
161
|
+
#{module_name} = rb_define_module("#{module_name}");
|
162
|
+
rb_define_method(#{module_name}, "run", method_run, -1);
|
163
|
+
}
|
164
|
+
EOF
|
165
|
+
end
|
166
|
+
|
167
|
+
def fill_check_args
|
168
|
+
get_output.print <<EOF
|
169
|
+
VALUE _boast_rb_opts;
|
170
|
+
if( _boast_argc < #{@procedure.parameters.length} || _boast_argc > #{@procedure.parameters.length + 1} )
|
171
|
+
rb_raise(rb_eArgError, "Wrong number of arguments for #{@procedure.name} (%d for #{@procedure.parameters.length})!", _boast_argc);
|
172
|
+
_boast_rb_opts = Qnil;
|
173
|
+
if( _boast_argc == #{@procedure.parameters.length + 1} ) {
|
174
|
+
_boast_rb_opts = _boast_argv[_boast_argc -1];
|
175
|
+
if ( _boast_rb_opts != Qnil ) {
|
176
|
+
if (TYPE(_boast_rb_opts) != T_HASH)
|
177
|
+
rb_raise(rb_eArgError, "Options should be passed as a hash");
|
178
|
+
}
|
179
|
+
}
|
180
|
+
EOF
|
181
|
+
end
|
182
|
+
|
183
|
+
def fill_decl_module_params
|
184
|
+
set_decl_module(true)
|
185
|
+
@procedure.parameters.each { |param|
|
186
|
+
param_copy = param.copy
|
187
|
+
param_copy.constant = nil
|
188
|
+
param_copy.direction = nil
|
189
|
+
param_copy.decl
|
190
|
+
}
|
191
|
+
get_output.puts " #{@procedure.properties[:return].type.decl} _boast_ret;" if @procedure.properties[:return]
|
192
|
+
get_output.puts " VALUE _boast_stats = rb_hash_new();"
|
193
|
+
get_output.puts " VALUE _boast_rb_ptr = Qnil;"
|
194
|
+
refs = false
|
195
|
+
@procedure.parameters.each_with_index do |param,i|
|
196
|
+
refs = true if param.scalar_output?
|
197
|
+
end
|
198
|
+
if refs then
|
199
|
+
get_output.puts " VALUE _boast_refs = rb_hash_new();"
|
200
|
+
get_output.puts " rb_hash_aset(_boast_stats,ID2SYM(rb_intern(\"reference_return\")),_boast_refs);"
|
201
|
+
end
|
202
|
+
set_decl_module(false)
|
203
|
+
end
|
204
|
+
|
205
|
+
def copy_scalar_param_from_ruby( param, ruby_param )
|
206
|
+
case param.type
|
207
|
+
when Int
|
208
|
+
(param === FuncCall::new("NUM2INT", ruby_param)).pr if param.type.size == 4
|
209
|
+
(param === FuncCall::new("NUM2LONG", ruby_param)).pr if param.type.size == 8
|
210
|
+
when Real
|
211
|
+
(param === FuncCall::new("NUM2DBL", ruby_param)).pr
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def copy_array_param_from_ruby( param, ruby_param )
|
216
|
+
rb_ptr = Variable::new("_boast_rb_ptr", CustomType, :type_name => "VALUE")
|
217
|
+
(rb_ptr === ruby_param).pr
|
218
|
+
get_output.print <<EOF
|
219
|
+
if (TYPE(_boast_rb_ptr) == T_STRING) {
|
220
|
+
#{param} = (void *) RSTRING_PTR(_boast_rb_ptr);
|
221
|
+
} else if ( IsNArray(_boast_rb_ptr) ) {
|
222
|
+
struct NARRAY *_boast_n_ary;
|
223
|
+
Data_Get_Struct(_boast_rb_ptr, struct NARRAY, _boast_n_ary);
|
224
|
+
#{param} = (void *) _boast_n_ary->ptr;
|
225
|
+
} else {
|
226
|
+
rb_raise(rb_eArgError, "Wrong type of argument for %s, expecting array!", "#{param}");
|
227
|
+
}
|
228
|
+
EOF
|
229
|
+
end
|
230
|
+
|
231
|
+
def get_params_value
|
232
|
+
argc = @procedure.parameters.length
|
233
|
+
argv = Variable::new("_boast_argv", CustomType, :type_name => "VALUE", :dimension => [ Dimension::new(0,argc-1) ] )
|
234
|
+
rb_ptr = Variable::new("_boast_rb_ptr", CustomType, :type_name => "VALUE")
|
235
|
+
set_decl_module(true)
|
236
|
+
@procedure.parameters.each_index do |i|
|
237
|
+
param = @procedure.parameters[i]
|
238
|
+
if not param.dimension then
|
239
|
+
copy_scalar_param_from_ruby(param, argv[i])
|
240
|
+
else
|
241
|
+
copy_array_param_from_ruby(param, argv[i])
|
242
|
+
end
|
243
|
+
end
|
244
|
+
set_decl_module(false)
|
245
|
+
end
|
246
|
+
|
247
|
+
def create_procedure_call
|
248
|
+
get_output.print " _boast_ret = " if @procedure.properties[:return]
|
249
|
+
get_output.print " #{method_name}( "
|
250
|
+
get_output.print create_procedure_call_parameters.join(", ")
|
251
|
+
get_output.puts " );"
|
252
|
+
end
|
253
|
+
|
254
|
+
def copy_scalar_param_to_ruby(param, ruby_param)
|
255
|
+
if param.scalar_output? then
|
256
|
+
case param.type
|
257
|
+
when Int
|
258
|
+
get_output.puts " rb_hash_aset(_boast_refs, ID2SYM(rb_intern(\"#{param}\")),rb_int_new((long long)#{param}));" if param.type.signed?
|
259
|
+
get_output.puts " rb_hash_aset(_boast_refs, ID2SYM(rb_intern(\"#{param}\")),rb_int_new((unsigned long long)#{param}));" if not param.type.signed?
|
260
|
+
when Real
|
261
|
+
get_output.puts " rb_hash_aset(_boast_refs, ID2SYM(rb_intern(\"#{param}\")),rb_float_new((double)#{param}));"
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
def copy_array_param_to_ruby(param, ruby_param)
|
267
|
+
end
|
268
|
+
|
269
|
+
def get_results
|
270
|
+
argc = @procedure.parameters.length
|
271
|
+
argv = Variable::new("_boast_argv", CustomType, :type_name => "VALUE", :dimension => [ Dimension::new(0,argc-1) ] )
|
272
|
+
rb_ptr = Variable::new("_boast_rb_ptr", CustomType, :type_name => "VALUE")
|
273
|
+
set_decl_module(true)
|
274
|
+
@procedure.parameters.each_index do |i|
|
275
|
+
param = @procedure.parameters[i]
|
276
|
+
if not param.dimension then
|
277
|
+
copy_scalar_param_to_ruby(param, argv[i])
|
278
|
+
else
|
279
|
+
copy_array_param_to_ruby(param, argv[i])
|
280
|
+
end
|
281
|
+
end
|
282
|
+
set_decl_module(false)
|
283
|
+
end
|
284
|
+
|
285
|
+
def store_results
|
286
|
+
if @procedure.properties[:return] then
|
287
|
+
type_ret = @procedure.properties[:return].type
|
288
|
+
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
|
289
|
+
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
|
290
|
+
get_output.puts " rb_hash_aset(_boast_stats,ID2SYM(rb_intern(\"return\")),rb_float_new((double)_boast_ret));" if type_ret.kind_of?(Real)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
def fill_module_file_source
|
295
|
+
fill_module_header
|
296
|
+
@probes.map(&:header)
|
297
|
+
@procedure.boast_header(@lang)
|
298
|
+
|
299
|
+
fill_module_preamble
|
300
|
+
|
301
|
+
set_transition("VALUE", "VALUE", :default, CustomType::new(:type_name => "VALUE"))
|
302
|
+
get_output.puts "VALUE method_run(int _boast_argc, VALUE *_boast_argv, VALUE _boast_self) {"
|
303
|
+
increment_indent_level
|
304
|
+
|
305
|
+
fill_check_args
|
306
|
+
|
307
|
+
fill_decl_module_params
|
308
|
+
|
309
|
+
@probes.reverse.map(&:decl)
|
310
|
+
|
311
|
+
get_params_value
|
312
|
+
|
313
|
+
@probes.map(&:configure)
|
314
|
+
|
315
|
+
@probes.reverse.map(&:start)
|
316
|
+
|
317
|
+
create_procedure_call
|
318
|
+
|
319
|
+
@probes.map(&:stop)
|
320
|
+
|
321
|
+
@probes.map(&:compute)
|
322
|
+
|
323
|
+
get_results
|
324
|
+
|
325
|
+
store_results
|
326
|
+
|
327
|
+
get_output.puts " return _boast_stats;"
|
328
|
+
decrement_indent_level
|
329
|
+
get_output.puts "}"
|
330
|
+
end
|
331
|
+
|
332
|
+
def create_module_file_source
|
333
|
+
f = File::open(module_file_source, "w+")
|
334
|
+
previous_lang = get_lang
|
335
|
+
previous_output = get_output
|
336
|
+
set_output(f)
|
337
|
+
set_lang(C)
|
338
|
+
|
339
|
+
fill_module_file_source
|
340
|
+
|
341
|
+
if debug_source? then
|
342
|
+
f.rewind
|
343
|
+
puts f.read
|
344
|
+
end
|
345
|
+
set_output(previous_output)
|
346
|
+
set_lang(previous_lang)
|
347
|
+
f.close
|
348
|
+
end
|
349
|
+
|
350
|
+
def create_sources
|
351
|
+
create_library_source
|
352
|
+
create_module_file_source
|
353
|
+
end
|
354
|
+
|
355
|
+
def load_module
|
356
|
+
require module_file_path
|
357
|
+
end
|
358
|
+
|
359
|
+
def target_sources
|
360
|
+
return [ module_file_source, library_source ]
|
361
|
+
end
|
362
|
+
|
363
|
+
def cleanup(kernel_files)
|
364
|
+
([target] + target_depends + target_sources).each { |fn|
|
365
|
+
File::unlink(fn)
|
366
|
+
}
|
367
|
+
kernel_files.each { |f|
|
368
|
+
f.unlink
|
369
|
+
}
|
370
|
+
end
|
371
|
+
|
372
|
+
def build(options={})
|
373
|
+
compiler_options = BOAST::get_compiler_options
|
374
|
+
compiler_options.update(options)
|
375
|
+
linker, ldshared, ldflags = setup_compilers(compiler_options)
|
376
|
+
|
377
|
+
@marker = Tempfile::new([@procedure.name,""])
|
378
|
+
|
379
|
+
kernel_files = get_sub_kernels
|
380
|
+
|
381
|
+
create_sources
|
382
|
+
|
383
|
+
create_targets(linker, ldshared, ldflags, kernel_files)
|
384
|
+
|
385
|
+
save_binary
|
386
|
+
|
387
|
+
load_module
|
388
|
+
|
389
|
+
cleanup(kernel_files)
|
390
|
+
|
391
|
+
eval "self.extend(#{module_name})"
|
392
|
+
|
393
|
+
return self
|
394
|
+
end
|
395
|
+
|
396
|
+
end
|
397
|
+
|
398
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rbconfig'
|
3
|
+
require 'systemu'
|
4
|
+
require 'os'
|
5
|
+
|
6
|
+
module BOAST
|
7
|
+
|
8
|
+
module Compilers
|
9
|
+
include Rake::DSL
|
10
|
+
|
11
|
+
def get_openmp_flags(compiler)
|
12
|
+
openmp_flags = BOAST::get_openmp_flags[compiler]
|
13
|
+
if not openmp_flags then
|
14
|
+
keys = BOAST::get_openmp_flags.keys
|
15
|
+
keys.each { |k|
|
16
|
+
openmp_flags = BOAST::get_openmp_flags[k] if compiler.match(k)
|
17
|
+
}
|
18
|
+
end
|
19
|
+
return openmp_flags
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_includes(narray_path)
|
23
|
+
includes = "-I#{RbConfig::CONFIG["archdir"]}"
|
24
|
+
includes += " -I#{RbConfig::CONFIG["rubyhdrdir"]} -I#{RbConfig::CONFIG["rubyhdrdir"]}/#{RbConfig::CONFIG["arch"]}"
|
25
|
+
includes += " -I#{RbConfig::CONFIG["rubyarchhdrdir"]}" if RbConfig::CONFIG["rubyarchhdrdir"]
|
26
|
+
includes += " -I#{narray_path}" if narray_path
|
27
|
+
return includes
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_narray_path
|
31
|
+
narray_path = nil
|
32
|
+
begin
|
33
|
+
spec = Gem::Specification::find_by_name('narray')
|
34
|
+
narray_path = spec.full_gem_path
|
35
|
+
rescue Gem::LoadError => e
|
36
|
+
rescue NoMethodError => e
|
37
|
+
spec = Gem::available?('narray')
|
38
|
+
if spec then
|
39
|
+
require 'narray'
|
40
|
+
narray_path = Gem.loaded_specs['narray'].full_gem_path
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def setup_c_compiler(options, includes, narray_path, runner)
|
46
|
+
c_mppa_compiler = "k1-gcc"
|
47
|
+
c_compiler = options[:CC]
|
48
|
+
cflags = options[:CFLAGS]
|
49
|
+
cflags += " -fPIC #{includes}"
|
50
|
+
cflags += " -DHAVE_NARRAY_H" if narray_path
|
51
|
+
cflags += " -I/usr/local/k1tools/include" if @architecture == MPPA
|
52
|
+
objext = RbConfig::CONFIG["OBJEXT"]
|
53
|
+
if options[:openmp] and @lang == C then
|
54
|
+
openmp_cflags = get_openmp_flags(c_compiler)
|
55
|
+
raise "unkwown openmp flags for: #{c_compiler}" if not openmp_cflags
|
56
|
+
cflags += " #{openmp_cflags}"
|
57
|
+
end
|
58
|
+
|
59
|
+
rule ".#{objext}" => '.c' do |t|
|
60
|
+
c_call_string = "#{c_compiler} #{cflags} -c -o #{t.name} #{t.source}"
|
61
|
+
runner.call(t, c_call_string)
|
62
|
+
end
|
63
|
+
|
64
|
+
rule ".#{objext}io" => ".cio" do |t|
|
65
|
+
c_call_string = "#{c_mppa_compiler} -mcore=k1io -mos=rtems"
|
66
|
+
c_call_string += " -mboard=developer -x c -c -o #{t.name} #{t.source}"
|
67
|
+
runner.call(t, c_call_string)
|
68
|
+
end
|
69
|
+
|
70
|
+
rule ".#{objext}comp" => ".ccomp" do |t|
|
71
|
+
c_call_string = "#{c_mppa_compiler} -mcore=k1dp -mos=nodeos"
|
72
|
+
c_call_string += " -mboard=developer -x c -c -o #{t.name} #{t.source}"
|
73
|
+
runner.call(t, c_call_string)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def setup_cxx_compiler(options, includes, runner)
|
78
|
+
cxx_compiler = options[:CXX]
|
79
|
+
cxxflags = options[:CXXFLAGS]
|
80
|
+
cxxflags += " -fPIC #{includes}"
|
81
|
+
if options[:openmp] and @lang == C then
|
82
|
+
openmp_cxxflags = get_openmp_flags(cxx_compiler)
|
83
|
+
raise "unkwown openmp flags for: #{cxx_compiler}" if not openmp_cxxflags
|
84
|
+
cxxflags += " #{openmp_cxxflags}"
|
85
|
+
end
|
86
|
+
|
87
|
+
rule ".#{RbConfig::CONFIG["OBJEXT"]}" => '.cpp' do |t|
|
88
|
+
cxx_call_string = "#{cxx_compiler} #{cxxflags} -c -o #{t.name} #{t.source}"
|
89
|
+
runner.call(t, cxx_call_string)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def setup_fortran_compiler(options, runner)
|
94
|
+
f_compiler = options[:FC]
|
95
|
+
fcflags = options[:FCFLAGS]
|
96
|
+
fcflags += " -fPIC"
|
97
|
+
fcflags += " -fno-second-underscore" if f_compiler == 'g95'
|
98
|
+
if options[:openmp] and @lang == FORTRAN then
|
99
|
+
openmp_fcflags = get_openmp_flags(f_compiler)
|
100
|
+
raise "unkwown openmp flags for: #{f_compiler}" if not openmp_fcflags
|
101
|
+
fcflags += " #{openmp_fcflags}"
|
102
|
+
end
|
103
|
+
|
104
|
+
rule ".#{RbConfig::CONFIG["OBJEXT"]}" => '.f90' do |t|
|
105
|
+
f_call_string = "#{f_compiler} #{fcflags} -c -o #{t.name} #{t.source}"
|
106
|
+
runner.call(t, f_call_string)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def setup_cuda_compiler(options, runner)
|
111
|
+
cuda_compiler = options[:NVCC]
|
112
|
+
cudaflags = options[:NVCCFLAGS]
|
113
|
+
cudaflags += " --compiler-options '-fPIC'"
|
114
|
+
|
115
|
+
rule ".#{RbConfig::CONFIG["OBJEXT"]}" => '.cu' do |t|
|
116
|
+
cuda_call_string = "#{cuda_compiler} #{cudaflags} -c -o #{t.name} #{t.source}"
|
117
|
+
runner.call(t, cuda_call_string)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def setup_linker_mppa(options, runner)
|
122
|
+
objext = RbConfig::CONFIG["OBJEXT"]
|
123
|
+
ldflags = options[:LDFLAGS]
|
124
|
+
board = " -mboard=developer"
|
125
|
+
ldflags += " -lmppaipc"
|
126
|
+
|
127
|
+
linker = "k1-gcc"
|
128
|
+
|
129
|
+
rule ".bincomp" => ".#{objext}comp" do |t|
|
130
|
+
linker_string = "#{linker} -o #{t.name} #{t.source} -mcore=k1dp #{board} -mos=nodeos #{ldflags}"
|
131
|
+
runner.call(t, linker_string)
|
132
|
+
end
|
133
|
+
|
134
|
+
rule ".binio" => ".#{objext}io" do |t|
|
135
|
+
linker_string = "#{linker} -o #{t.name} #{t.source} -mcore=k1io #{board} -mos=rtems #{ldflags}"
|
136
|
+
runner.call(t, linker_string)
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
def setup_linker(options)
|
142
|
+
ldflags = options[:LDFLAGS]
|
143
|
+
ldflags += " -L#{RbConfig::CONFIG["libdir"]} #{RbConfig::CONFIG["LIBRUBYARG"]}"
|
144
|
+
ldflags += " -lrt" if not OS.mac?
|
145
|
+
ldflags += " -lcudart" if @lang == CUDA
|
146
|
+
ldflags += " -L/usr/local/k1tools/lib64 -lmppaipc -lpcie -lz -lelf -lmppa_multiloader" if @architecture == MPPA
|
147
|
+
ldflags += " -lmppamon -lmppabm -lm -lmppalock" if @architecture == MPPA
|
148
|
+
c_compiler = options[:CC]
|
149
|
+
c_compiler = "cc" if not c_compiler
|
150
|
+
linker = options[:LD]
|
151
|
+
linker = c_compiler if not linker
|
152
|
+
if options[:openmp] then
|
153
|
+
openmp_ldflags = get_openmp_flags(linker)
|
154
|
+
raise "unknown openmp flags for: #{linker}" if not openmp_ldflags
|
155
|
+
ldflags += " #{openmp_ldflags}"
|
156
|
+
end
|
157
|
+
|
158
|
+
if OS.mac? then
|
159
|
+
ldflags = "-Wl,-undefined,dynamic_lookup -Wl,-multiply_defined,suppress #{ldflags}"
|
160
|
+
ldshared = "-dynamic -bundle"
|
161
|
+
else
|
162
|
+
ldflags = "-Wl,-Bsymbolic-functions -Wl,-z,relro -rdynamic -Wl,-export-dynamic #{ldflags}"
|
163
|
+
ldshared = "-shared"
|
164
|
+
end
|
165
|
+
|
166
|
+
return [linker, ldshared, ldflags]
|
167
|
+
end
|
168
|
+
|
169
|
+
def setup_compilers(options = {})
|
170
|
+
Rake::Task::clear
|
171
|
+
verbose = options[:verbose]
|
172
|
+
verbose = get_verbose if not verbose
|
173
|
+
Rake::verbose(verbose)
|
174
|
+
Rake::FileUtilsExt.verbose_flag=verbose
|
175
|
+
|
176
|
+
narray_path = get_narray_path
|
177
|
+
includes = get_includes(narray_path)
|
178
|
+
|
179
|
+
runner = lambda { |t, call_string|
|
180
|
+
if verbose then
|
181
|
+
sh call_string
|
182
|
+
else
|
183
|
+
status, stdout, stderr = systemu call_string
|
184
|
+
if not status.success? then
|
185
|
+
puts stderr
|
186
|
+
fail "#{t.source}: compilation failed"
|
187
|
+
end
|
188
|
+
status.success?
|
189
|
+
end
|
190
|
+
}
|
191
|
+
|
192
|
+
setup_c_compiler(options, includes, narray_path, runner)
|
193
|
+
setup_cxx_compiler(options, includes, runner)
|
194
|
+
setup_fortran_compiler(options, runner)
|
195
|
+
setup_cuda_compiler(options, runner)
|
196
|
+
|
197
|
+
setup_linker_mppa(options, runner) if @architecture == MPPA
|
198
|
+
|
199
|
+
return setup_linker(options)
|
200
|
+
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module BOAST
|
4
|
+
|
5
|
+
@@compiler_default_options = {
|
6
|
+
:FC => 'gfortran',
|
7
|
+
:FCFLAGS => '-O2 -Wall',
|
8
|
+
:CC => 'gcc',
|
9
|
+
:CFLAGS => '-O2 -Wall',
|
10
|
+
:CXX => 'g++',
|
11
|
+
:CXXFLAGS => '-O2 -Wall',
|
12
|
+
:NVCC => 'nvcc',
|
13
|
+
:NVCCFLAGS => '-O2',
|
14
|
+
:LDFLAGS => '',
|
15
|
+
:CLFLAGS => '',
|
16
|
+
:CLVENDOR => nil,
|
17
|
+
:CLPLATFORM => nil,
|
18
|
+
:CLDEVICE => nil,
|
19
|
+
:CLDEVICETYPE => nil,
|
20
|
+
:openmp => false
|
21
|
+
}
|
22
|
+
|
23
|
+
@@openmp_default_flags = {
|
24
|
+
"gcc" => "-fopenmp",
|
25
|
+
"icc" => "-openmp",
|
26
|
+
"gfortran" => "-fopenmp",
|
27
|
+
"ifort" => "-openmp",
|
28
|
+
"g++" => "-fopenmp",
|
29
|
+
"icpc" => "-openmp"
|
30
|
+
}
|
31
|
+
|
32
|
+
module PrivateStateAccessor
|
33
|
+
private_boolean_state_accessor :verbose
|
34
|
+
private_boolean_state_accessor :debug_source
|
35
|
+
private_boolean_state_accessor :ffi
|
36
|
+
end
|
37
|
+
|
38
|
+
boolean_state_accessor :verbose
|
39
|
+
boolean_state_accessor :debug_source
|
40
|
+
boolean_state_accessor :ffi
|
41
|
+
@@ffi = false
|
42
|
+
@@verbose = false
|
43
|
+
@@debug_source = false
|
44
|
+
FORTRAN_LINE_LENGTH = 72
|
45
|
+
|
46
|
+
module_function
|
47
|
+
|
48
|
+
def read_boast_config
|
49
|
+
home_config_dir = ENV["XDG_CONFIG_HOME"]
|
50
|
+
home_config_dir = "#{Dir.home}/.config" if not home_config_dir
|
51
|
+
Dir.mkdir( home_config_dir ) if not File::exist?( home_config_dir )
|
52
|
+
return if not File::directory?(home_config_dir)
|
53
|
+
boast_config_dir = "#{home_config_dir}/BOAST"
|
54
|
+
Dir.mkdir( boast_config_dir ) if not File::exist?( boast_config_dir )
|
55
|
+
compiler_options_file = "#{boast_config_dir}/compiler_options"
|
56
|
+
if File::exist?( compiler_options_file ) then
|
57
|
+
File::open( compiler_options_file, "r" ) { |f|
|
58
|
+
@@compiler_default_options.update( YAML::load( f.read ) )
|
59
|
+
}
|
60
|
+
else
|
61
|
+
File::open( compiler_options_file, "w" ) { |f|
|
62
|
+
f.write YAML::dump( @@compiler_default_options )
|
63
|
+
}
|
64
|
+
end
|
65
|
+
openmp_flags_file = "#{boast_config_dir}/openmp_flags"
|
66
|
+
if File::exist?( openmp_flags_file ) then
|
67
|
+
File::open( openmp_flags_file, "r" ) { |f|
|
68
|
+
@@openmp_default_flags.update( YAML::load( f.read ) )
|
69
|
+
}
|
70
|
+
else
|
71
|
+
File::open( openmp_flags_file, "w" ) { |f|
|
72
|
+
f.write YAML::dump( @@openmp_default_flags )
|
73
|
+
}
|
74
|
+
end
|
75
|
+
@@compiler_default_options.each_key { |k|
|
76
|
+
@@compiler_default_options[k] = ENV[k.to_s] if ENV[k.to_s]
|
77
|
+
}
|
78
|
+
@@compiler_default_options[:LD] = ENV["LD"] if ENV["LD"]
|
79
|
+
@@verbose = ENV["VERBOSE"] if ENV["VERBOSE"]
|
80
|
+
@@ffi = ENV["FFI"] if ENV["FFI"]
|
81
|
+
@@debug_source = ENV["DEBUG_SOURCE"] if ENV["DEBUG_SOURCE"]
|
82
|
+
end
|
83
|
+
|
84
|
+
read_boast_config
|
85
|
+
|
86
|
+
def get_openmp_flags
|
87
|
+
return @@openmp_default_flags.clone
|
88
|
+
end
|
89
|
+
|
90
|
+
def get_compiler_options
|
91
|
+
return @@compiler_default_options.clone
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|