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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/BOAST.gemspec +2 -31
  3. data/README.md +240 -0
  4. data/lib/BOAST/{OpenMP.rb → Language/OpenMP.rb} +1 -0
  5. data/lib/BOAST/{Variable.rb → Language/Variable.rb} +2 -1
  6. data/lib/BOAST/Runtime/CKernel.rb +94 -0
  7. data/lib/BOAST/Runtime/CRuntime.rb +32 -0
  8. data/lib/BOAST/Runtime/CUDARuntime.rb +158 -0
  9. data/lib/BOAST/Runtime/CompiledRuntime.rb +398 -0
  10. data/lib/BOAST/Runtime/Compilers.rb +205 -0
  11. data/lib/BOAST/Runtime/Config.rb +94 -0
  12. data/lib/BOAST/Runtime/FFIRuntime.rb +104 -0
  13. data/lib/BOAST/Runtime/FORTRANRuntime.rb +45 -0
  14. data/lib/BOAST/Runtime/MPPARuntime.rb +464 -0
  15. data/lib/BOAST/Runtime/NonRegression.rb +157 -0
  16. data/lib/BOAST/Runtime/OpenCLRuntime.rb +181 -0
  17. data/lib/BOAST/Runtime/Probe.rb +136 -0
  18. data/lib/BOAST.rb +37 -26
  19. metadata +40 -28
  20. data/lib/BOAST/CKernel.rb +0 -1236
  21. /data/lib/BOAST/{Algorithm.rb → Language/Algorithm.rb} +0 -0
  22. /data/lib/BOAST/{Arithmetic.rb → Language/Arithmetic.rb} +0 -0
  23. /data/lib/BOAST/{BOAST_OpenCL.rb → Language/BOAST_OpenCL.rb} +0 -0
  24. /data/lib/BOAST/{Case.rb → Language/Case.rb} +0 -0
  25. /data/lib/BOAST/{ControlStructure.rb → Language/ControlStructure.rb} +0 -0
  26. /data/lib/BOAST/{DataTypes.rb → Language/DataTypes.rb} +0 -0
  27. /data/lib/BOAST/{Expression.rb → Language/Expression.rb} +0 -0
  28. /data/lib/BOAST/{For.rb → Language/For.rb} +0 -0
  29. /data/lib/BOAST/{FuncCall.rb → Language/FuncCall.rb} +0 -0
  30. /data/lib/BOAST/{Functors.rb → Language/Functors.rb} +0 -0
  31. /data/lib/BOAST/{If.rb → Language/If.rb} +0 -0
  32. /data/lib/BOAST/{Index.rb → Language/Index.rb} +0 -0
  33. /data/lib/BOAST/{Inspectable.rb → Language/Inspectable.rb} +0 -0
  34. /data/lib/BOAST/{Operators.rb → Language/Operators.rb} +0 -0
  35. /data/lib/BOAST/{Optimization.rb → Language/Optimization.rb} +0 -0
  36. /data/lib/BOAST/{Parens.rb → Language/Parens.rb} +0 -0
  37. /data/lib/BOAST/{Pragma.rb → Language/Pragma.rb} +0 -0
  38. /data/lib/BOAST/{Print.rb → Language/Print.rb} +0 -0
  39. /data/lib/BOAST/{Procedure.rb → Language/Procedure.rb} +0 -0
  40. /data/lib/BOAST/{Slice.rb → Language/Slice.rb} +0 -0
  41. /data/lib/BOAST/{State.rb → Language/State.rb} +0 -0
  42. /data/lib/BOAST/{Transitions.rb → Language/Transitions.rb} +0 -0
  43. /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