BOAST 1.0.7 → 1.0.8

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