BOAST 1.0.7 → 1.0.8

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.
@@ -66,6 +66,8 @@ module BOAST
66
66
  include PrivateStateAccessor
67
67
  include Inspectable
68
68
 
69
+ attr_accessor :shape
70
+
69
71
  def initialize(array,type = nil)
70
72
  super(array)
71
73
  @type = type::new if type
@@ -77,25 +79,30 @@ module BOAST
77
79
  end
78
80
 
79
81
  def to_s_fortran
82
+ arr = self.flatten
80
83
  s = ""
81
- return s if first.nil?
84
+ return s if arr.first.nil?
85
+ s += "reshape(" if @shape
82
86
  s += "(/ &\n"
83
- s += first.to_s
87
+ s += arr.first.to_s
84
88
  s += @type.suffix if @type
85
- self[1..-1].each { |v|
89
+ arr[1..-1].each { |v|
86
90
  s += ", &\n"+v.to_s
87
91
  s += @type.suffix if @type
88
92
  }
89
93
  s += " /)"
94
+ s += ", shape(#{@shape}))" if @shape
95
+ return s
90
96
  end
91
97
 
92
98
  def to_s_c
99
+ arr = self.flatten
93
100
  s = ""
94
- return s if first.nil?
101
+ return s if arr.first.nil?
95
102
  s += "{\n"
96
- s += first.to_s
103
+ s += arr.first.to_s
97
104
  s += @type.suffix if @type
98
- self[1..-1].each { |v|
105
+ arr[1..-1].each { |v|
99
106
  s += ",\n"+v.to_s
100
107
  s += @type.suffix if @type
101
108
  }
@@ -259,7 +266,7 @@ module BOAST
259
266
  end
260
267
 
261
268
  def set(x)
262
- return Expression::new(Set, self, x)
269
+ return self === Set(x,self)
263
270
  end
264
271
 
265
272
  def dereference
@@ -294,13 +301,13 @@ module BOAST
294
301
  s += "const " if constant? or @direction == :in
295
302
  s += @type.decl
296
303
  if dimension? then
297
- s += " *" unless use_vla?
304
+ s += " *" unless (use_vla? and lang != FORTRAN)
298
305
  end
299
306
  if not dimension? and ( lang == FORTRAN or @direction == :out or @direction == :inout ) then
300
307
  s += " *"
301
308
  end
302
309
  s += " #{@name}"
303
- if dimension? and use_vla? then
310
+ if dimension? and use_vla? and lang != FORTRAN then
304
311
  s += "["
305
312
  s += @dimension.reverse.collect { |d|
306
313
  dim = d.to_s
@@ -327,16 +334,57 @@ module BOAST
327
334
  return decl_c if [C, CL, CUDA].include?( lang )
328
335
  end
329
336
 
337
+ def __const?
338
+ return !!( constant? or @direction == :in )
339
+ end
340
+
341
+ def __global?
342
+ return !!( lang == CL and @direction and dimension? and not (@options[:register] or @options[:private] or local?) )
343
+ end
344
+
345
+ def __local?
346
+ return !!( lang == CL and local? )
347
+ end
348
+
349
+ def __shared?(device = false)
350
+ return !!( lang == CUDA and local? and not device )
351
+ end
352
+
353
+ def __vla_array?
354
+ return !!( use_vla? and dimension? and not decl_module? )
355
+ end
356
+
357
+ def __pointer_array?(device = false)
358
+ return !!( dimension? and not constant? and not ( allocate? and @allocate != :heap ) and (not local? or (local? and device)) )
359
+ end
360
+
361
+ def __pointer?(device = false)
362
+ return !!( ( not dimension? and ( @direction == :out or @direction == :inout ) ) or __pointer_array?(device) )
363
+ end
364
+
365
+ def __restrict?
366
+ return !!( restrict? and not decl_module? )
367
+ end
368
+
369
+ def __dimension?(device = false)
370
+ return !!( dimension? and ((local? and not device) or ( ( allocate? and @allocate != :heap ) and not constant?)) )
371
+ end
372
+
373
+ def __align?
374
+ return !!( dimension? and (align? or default_align > 1) and (constant? or (allocate? and @allocate != :heap ) ) )
375
+ end
376
+
330
377
  def decl_c_s(device = false)
331
378
  return decl_texture_s if texture?
332
379
  s = ""
333
- s += "const " if constant? or @direction == :in
334
- s += "__global " if @direction and dimension? and not (@options[:register] or @options[:private] or local?) and lang == CL
335
- s += "__local " if local? and lang == CL
336
- s += "__shared__ " if local? and not device and lang == CUDA
380
+ s += "const " if __const?
381
+ s += "__global " if __global?
382
+ s += "__local " if __local?
383
+ s += "__shared__ " if __shared?(device)
337
384
  s += @type.decl
338
- if use_vla? and dimension? and not decl_module? then
385
+ if __vla_array? then
339
386
  s += " #{@name}["
387
+ s += "__restrict__ " if __restrict?
340
388
  s += @dimension.reverse.collect { |d|
341
389
  dim = d.to_s
342
390
  if dim then
@@ -347,30 +395,25 @@ module BOAST
347
395
  }.join("][")
348
396
  s += "]"
349
397
  else
350
- if dimension? and not constant? and not ( allocate? and @allocate != :heap ) and (not local? or (local? and device)) then
351
- s += " *"
352
- if restrict? and not decl_module? then
353
- if lang == CL
354
- s += " restrict"
355
- else
356
- s += " __restrict__" unless use_vla?
357
- end
398
+ s += " *" if __pointer?(device)
399
+ if __pointer_array?(device) and __restrict? then
400
+ if lang == CL
401
+ s += " restrict"
402
+ else
403
+ s += " __restrict__" unless use_vla?
358
404
  end
359
405
  end
360
- if not dimension? and ( @direction == :out or @direction == :inout ) then
361
- s += " *"
362
- end
363
406
  s += " #{@name}"
364
407
  if dimension? and constant? then
365
408
  s += "[]"
366
409
  end
367
- if dimension? and ((local? and not device) or ( ( allocate? and @allocate != :heap ) and not constant?)) then
410
+ if __dimension?(device) then
368
411
  s +="[("
369
412
  s += @dimension.collect{ |d| d.to_s }.reverse.join(")*(")
370
413
  s +=")]"
371
414
  end
372
415
  end
373
- if dimension? and (align? or default_align > 1) and (constant? or (allocate? and @allocate != :heap ) ) then
416
+ if __align? then
374
417
  a = ( align? ? align : 1 )
375
418
  a = ( a >= default_align ? a : default_align )
376
419
  s+= " __attribute((aligned(#{a})))"
@@ -459,10 +502,16 @@ module BOAST
459
502
  return self
460
503
  end
461
504
 
462
- def alloc_c( dims = nil )
505
+ def alloc_c( dims = nil, align = get_address_size)
463
506
  s = ""
464
507
  s += indent
465
- s += "#{name} = (#{@type.decl} *)malloc( sizeof(#{@type.decl})*("
508
+ if align > (OS.bits/8) then
509
+ # check alignment is a power of 2
510
+ raise "Invalid alignment #{align}!" if align & (align - 1) != 0
511
+ s += "(#{@type.decl} *) posix_memalign( &#{name}, #{align}, sizeof(#{@type.decl})*("
512
+ else
513
+ s += "#{name} = (#{@type.decl} *) malloc( sizeof(#{@type.decl})*("
514
+ end
466
515
  s += dims.collect { |d| d.to_s }.reverse.join(")*(")
467
516
  s += ") )"
468
517
  s += finalize
@@ -470,12 +519,12 @@ module BOAST
470
519
  return self
471
520
  end
472
521
 
473
- def alloc( dims = nil )
522
+ def alloc( dims = nil, align = get_address_size )
474
523
  @dimension = [dims].flatten if dims
475
524
  dims = @dimension
476
525
  raise "Cannot allocate array with unknown dimension!" unless dims
477
526
  return alloc_fortran(dims) if lang == FORTRAN
478
- return alloc_c(dims) if lang == C
527
+ return alloc_c(dims, align) if lang == C
479
528
  end
480
529
 
481
530
  def dealloc_fortran
@@ -525,6 +574,7 @@ module BOAST
525
574
  end
526
575
  s += " :: #{@name}"
527
576
  if constant? then
577
+ @constant.shape = self if dimension? and @constant.kind_of?(ConstArray)
528
578
  s += " = #{@constant}"
529
579
  s += @type.suffix if not dimension? and @type
530
580
  end
@@ -77,8 +77,12 @@ module BOAST
77
77
  end
78
78
 
79
79
  def to_s
80
- @code.rewind
81
- return code.read
80
+ if @lang == FORTRAN then
81
+ return line_limited_source
82
+ else
83
+ @code.rewind
84
+ return code.read
85
+ end
82
86
  end
83
87
 
84
88
  def method_missing(meth, *args, &block)
@@ -4,6 +4,7 @@ module BOAST
4
4
  include CompiledRuntime
5
5
 
6
6
  def fill_library_header
7
+ get_output.puts "#include <stdlib.h>"
7
8
  get_output.puts "#include <inttypes.h>"
8
9
  get_output.puts "#define __assume_aligned(lvalueptr, align) lvalueptr = __builtin_assume_aligned (lvalueptr, align)" if @compiler_options[:CC].match("gcc")
9
10
  end
@@ -191,7 +191,7 @@ EOF
191
191
  end
192
192
 
193
193
  def fill_decl_module_params
194
- set_decl_module(true)
194
+ push_env(:decl_module => true)
195
195
  @procedure.parameters.each { |param|
196
196
  param_copy = param.copy
197
197
  param_copy.constant = nil
@@ -209,7 +209,7 @@ EOF
209
209
  get_output.puts " VALUE _boast_refs = rb_hash_new();"
210
210
  get_output.puts " rb_hash_aset(_boast_stats,ID2SYM(rb_intern(\"reference_return\")),_boast_refs);"
211
211
  end
212
- set_decl_module(false)
212
+ pop_env(:decl_module)
213
213
  end
214
214
 
215
215
  def copy_scalar_param_from_ruby( param, ruby_param )
@@ -242,7 +242,7 @@ EOF
242
242
  argc = @procedure.parameters.length
243
243
  argv = Variable::new("_boast_argv", CustomType, :type_name => "VALUE", :dimension => [ Dimension::new(0,argc-1) ] )
244
244
  rb_ptr = Variable::new("_boast_rb_ptr", CustomType, :type_name => "VALUE")
245
- set_decl_module(true)
245
+ push_env(:decl_module => true)
246
246
  @procedure.parameters.each_index do |i|
247
247
  param = @procedure.parameters[i]
248
248
  if not param.dimension then
@@ -251,7 +251,7 @@ EOF
251
251
  copy_array_param_from_ruby(param, argv[i])
252
252
  end
253
253
  end
254
- set_decl_module(false)
254
+ pop_env(:decl_module)
255
255
  end
256
256
 
257
257
  def create_procedure_call
@@ -280,7 +280,7 @@ EOF
280
280
  argc = @procedure.parameters.length
281
281
  argv = Variable::new("_boast_argv", CustomType, :type_name => "VALUE", :dimension => [ Dimension::new(0,argc-1) ] )
282
282
  rb_ptr = Variable::new("_boast_rb_ptr", CustomType, :type_name => "VALUE")
283
- set_decl_module(true)
283
+ push_env(:decl_module => true)
284
284
  @procedure.parameters.each_index do |i|
285
285
  param = @procedure.parameters[i]
286
286
  if not param.dimension then
@@ -289,7 +289,7 @@ EOF
289
289
  copy_array_param_to_ruby(param, argv[i])
290
290
  end
291
291
  end
292
- set_decl_module(false)
292
+ pop_env(:decl_module)
293
293
  end
294
294
 
295
295
  def store_results
@@ -341,10 +341,8 @@ EOF
341
341
 
342
342
  def create_module_file_source
343
343
  f = File::open(module_file_source, "w+")
344
- previous_lang = get_lang
345
- previous_output = get_output
346
- set_output(f)
347
- set_lang(C)
344
+ push_env(:lang => C)
345
+ push_env(:output => f)
348
346
 
349
347
  fill_module_file_source
350
348
 
@@ -352,8 +350,7 @@ EOF
352
350
  f.rewind
353
351
  puts f.read
354
352
  end
355
- set_output(previous_output)
356
- set_lang(previous_lang)
353
+ pop_env(:lang, :output)
357
354
  f.close
358
355
  end
359
356
 
@@ -46,6 +46,7 @@ module BOAST
46
46
  c_mppa_compiler = "k1-gcc"
47
47
  c_compiler = options[:CC]
48
48
  cflags = options[:CFLAGS]
49
+ cflags += " -march=#{get_model}"
49
50
  cflags += " -fPIC #{includes}"
50
51
  cflags += " -DHAVE_NARRAY_H" if narray_path
51
52
  cflags += " -I/usr/local/k1tools/include" if @architecture == MPPA
@@ -93,6 +94,7 @@ module BOAST
93
94
  def setup_fortran_compiler(options, runner)
94
95
  f_compiler = options[:FC]
95
96
  fcflags = options[:FCFLAGS]
97
+ fcflags += " -march=#{get_model}"
96
98
  fcflags += " -fPIC"
97
99
  fcflags += " -fno-second-underscore" if f_compiler == 'g95'
98
100
  if options[:openmp] and @lang == FORTRAN then
@@ -140,6 +142,7 @@ module BOAST
140
142
 
141
143
  def setup_linker(options)
142
144
  ldflags = options[:LDFLAGS]
145
+ ldflags += " -march=#{get_model}"
143
146
  ldflags += " -L#{RbConfig::CONFIG["libdir"]} #{RbConfig::CONFIG["LIBRUBYARG"]}"
144
147
  ldflags += " -lrt" if not OS.mac?
145
148
  ldflags += " -lcudart" if @lang == CUDA
@@ -40,10 +40,11 @@ module BOAST
40
40
  boolean_state_accessor :verbose
41
41
  boolean_state_accessor :debug_source
42
42
  boolean_state_accessor :ffi
43
- @@ffi = false
44
- @@verbose = false
45
- @@debug_source = false
46
- FORTRAN_LINE_LENGTH = 72
43
+ state_accessor :fortran_line_length
44
+ default_state_getter :ffi, false
45
+ default_state_getter :verbose, false
46
+ default_state_getter :debug_source, false
47
+ default_state_getter :fortran_line_length, 72
47
48
 
48
49
  module_function
49
50
 
@@ -78,9 +79,6 @@ module BOAST
78
79
  @@compiler_default_options[k] = ENV[k.to_s] if ENV[k.to_s]
79
80
  }
80
81
  @@compiler_default_options[:LD] = ENV["LD"] if ENV["LD"]
81
- @@verbose = ENV["VERBOSE"] if ENV["VERBOSE"]
82
- @@ffi = ENV["FFI"] if ENV["FFI"]
83
- @@debug_source = ENV["DEBUG_SOURCE"] if ENV["DEBUG_SOURCE"]
84
82
  end
85
83
 
86
84
  read_boast_config
@@ -7,25 +7,33 @@ module BOAST
7
7
  return @procedure.name + "_"
8
8
  end
9
9
 
10
- def fill_library_source
10
+ def line_limited_source
11
+ s = ""
11
12
  @code.rewind
12
13
  @code.each_line { |line|
13
- # check for omp pragmas
14
- if line.match(/^\s*!\$/) then
14
+ if line.match(/^\s*!\w*?\$/) then
15
15
  if line.match(/^\s*!\$(omp|OMP)/) then
16
- chunks = line.scan(/.{1,#{FORTRAN_LINE_LENGTH-7}}/)
17
- get_output.puts chunks.join("&\n!$omp&")
16
+ chunks = line.scan(/.{1,#{fortran_line_length-7}}/)
17
+ s += chunks.join("&\n!$omp&") + "\n"
18
+ elsif line.match(/^\s*!(DIR|dir)\$/) then
19
+ chunks = line.scan(/.{1,#{fortran_line_length-7}}/)
20
+ s += chunks.join("&\n!DIR$&") + "\n"
18
21
  else
19
- chunks = line.scan(/.{1,#{FORTRAN_LINE_LENGTH-4}}/)
20
- get_output.puts chunks.join("&\n!$&")
22
+ chunks = line.scan(/.{1,#{fortran_line_length-4}}/)
23
+ s += chunks.join("&\n!$&") + "\n"
21
24
  end
22
- elsif line.match(/^\w*!/) then
23
- get_output.write line
25
+ elsif line.match(/^\s*!/) then
26
+ s += line
24
27
  else
25
- chunks = line.scan(/.{1,#{FORTRAN_LINE_LENGTH-2}}/)
26
- get_output.puts chunks.join("&\n&")
28
+ chunks = line.scan(/.{1,#{fortran_line_length-2}}/)
29
+ s += chunks.join("&\n&") + "\n"
27
30
  end
28
31
  }
32
+ return s
33
+ end
34
+
35
+ def fill_library_source
36
+ get_output.print line_limited_source
29
37
  end
30
38
 
31
39
  def create_procedure_call_parameters
@@ -2,6 +2,13 @@ module BOAST
2
2
 
3
3
  module CompiledRuntime
4
4
  def maqao_analysis(options={})
5
+ maqao_models = {
6
+ "core2" => "CORE2_45",
7
+ "nehalem" => "NEHALEM",
8
+ "sandybridge" => "SANDY_BRIDGE",
9
+ "ivybridge" => "IVY_BRIDGE",
10
+ "haswell" => "HASWELL"
11
+ }
5
12
  compiler_options = BOAST::get_compiler_options
6
13
  compiler_options.update(options)
7
14
 
@@ -14,11 +21,11 @@ module BOAST
14
21
  @source.rewind
15
22
  f2.write( @source.read )
16
23
  f2.close
17
-
24
+ maqao_model = maqao_models[get_model]
18
25
  if verbose? then
19
- puts "#{compiler_options[:MAQAO]} cqa #{f1.path} --fct=#{@procedure.name} #{compiler_options[:MAQAO_FLAGS]}"
26
+ puts "#{compiler_options[:MAQAO]} cqa #{maqao_model ? "--uarch=#{maqao_model} " : ""}#{f1.path} --fct=#{@procedure.name} #{compiler_options[:MAQAO_FLAGS]}"
20
27
  end
21
- result = `#{compiler_options[:MAQAO]} cqa #{f1.path} --fct=#{@procedure.name} #{compiler_options[:MAQAO_FLAGS]}`
28
+ result = `#{compiler_options[:MAQAO]} cqa #{maqao_model ? "--uarch=#{maqao_model} " : ""}#{f1.path} --fct=#{@procedure.name} #{compiler_options[:MAQAO_FLAGS]}`
22
29
  File::unlink(library_object)
23
30
  File::unlink(library_source)
24
31
  return result
data/lib/BOAST.rb CHANGED
@@ -3,6 +3,8 @@ require 'BOAST/Language/Functors.rb'
3
3
  require 'BOAST/Language/Inspectable.rb'
4
4
  require 'BOAST/Language/Transitions.rb'
5
5
  require 'BOAST/Language/Arithmetic.rb'
6
+ require 'BOAST/Language/Architectures.rb'
7
+ require 'BOAST/Language/CPUID_by_name.rb'
6
8
  require 'BOAST/Language/Intrinsics.rb'
7
9
  require 'BOAST/Language/Operators.rb'
8
10
  require 'BOAST/Language/DataTypes.rb'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: BOAST
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.7
4
+ version: 1.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brice Videau
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-13 00:00:00.000000000 Z
11
+ date: 2015-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: narray
@@ -150,6 +150,26 @@ dependencies:
150
150
  - - ">="
151
151
  - !ruby/object:Gem::Version
152
152
  version: 1.9.3
153
+ - !ruby/object:Gem::Dependency
154
+ name: rgl
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '0.5'
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: 0.5.1
163
+ type: :runtime
164
+ prerelease: false
165
+ version_requirements: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - "~>"
168
+ - !ruby/object:Gem::Version
169
+ version: '0.5'
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: 0.5.1
153
173
  - !ruby/object:Gem::Dependency
154
174
  name: rake
155
175
  requirement: !ruby/object:Gem::Requirement
@@ -176,8 +196,10 @@ files:
176
196
  - README.md
177
197
  - lib/BOAST.rb
178
198
  - lib/BOAST/Language/Algorithm.rb
199
+ - lib/BOAST/Language/Architectures.rb
179
200
  - lib/BOAST/Language/Arithmetic.rb
180
201
  - lib/BOAST/Language/BOAST_OpenCL.rb
202
+ - lib/BOAST/Language/CPUID_by_name.rb
181
203
  - lib/BOAST/Language/Case.rb
182
204
  - lib/BOAST/Language/ControlStructure.rb
183
205
  - lib/BOAST/Language/DataTypes.rb