BOAST 0.99996 → 0.99997

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 40c21d4b9f3af7ba3e0a34a8a55b9a7d65329f8f
4
- data.tar.gz: dd8c7914a2b7918295453dbeffd172a505014cf6
3
+ metadata.gz: bb89f1443e6a90d1e3de87c5d9d6a23987b4c18a
4
+ data.tar.gz: c305d01f65fbdf595bb9a381589cd7220c67e5eb
5
5
  SHA512:
6
- metadata.gz: 2bbe1a51a60e2cd46ceaa611e45d51e294d893c3b2d528fd586fdbd89bdd1ba0b8a0c3189569989a0c2e5a532b16a71e02b3ce5835a44b0b238214d8cf9e4340
7
- data.tar.gz: f661fa69d0309e6c6b2f294925c08b1c6ddf9f854f745d1b1bb8d1f79d6519d105b8f854eb8514c6f75e96bffbd181ff71ee6fd2028ef1f05f6a8f4bcfc126ce
6
+ metadata.gz: a3a43dac0e6441cb2b1cc646bb40953974f861d5c8fb2e199ea60c517964c08eca4e20aba5a4831932b246cb1164633ca8d53196e3b77413bac0aa6eca7176d8
7
+ data.tar.gz: 94959453ffdf64b5e73429771eaaf1cc809369fd214be89668b51a27ae896554cdc053271af1877aa7ed4b42d5be1b4e3b116b9d5c9a6684f9467bffa7bfef89
data/BOAST.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'BOAST'
3
- s.version = "0.99996"
3
+ s.version = "0.99997"
4
4
  s.author = "Brice Videau"
5
5
  s.email = "brice.videau@imag.fr"
6
6
  s.homepage = "https://forge.imag.fr/projects/boast/"
@@ -34,6 +34,7 @@ Gem::Specification.new do |s|
34
34
  lib/BOAST/State.rb
35
35
  lib/BOAST/Optimization.rb
36
36
  lib/BOAST/OpenMP.rb
37
+ lib/BOAST/Slice.rb
37
38
  )
38
39
  s.has_rdoc = true
39
40
  s.license = 'BSD'
@@ -20,6 +20,8 @@ module BOAST
20
20
  private_boolean_state_accessor :default_int_signed
21
21
  private_boolean_state_accessor :chain_code
22
22
  private_boolean_state_accessor :debug
23
+ private_boolean_state_accessor :use_vla
24
+ private_boolean_state_accessor :decl_module
23
25
 
24
26
  private
25
27
  def push_env(*args)
@@ -53,6 +55,8 @@ module BOAST
53
55
  boolean_state_accessor :default_int_signed
54
56
  boolean_state_accessor :chain_code
55
57
  boolean_state_accessor :debug
58
+ boolean_state_accessor :use_vla
59
+ boolean_state_accessor :decl_module
56
60
 
57
61
  module_function
58
62
 
@@ -68,6 +72,12 @@ module BOAST
68
72
  return debug
69
73
  end
70
74
 
75
+ def get_default_use_vla
76
+ use_vla = false
77
+ use_vla = ENV["USE_VLA"] if ENV["USE_VLA"]
78
+ return use_vla
79
+ end
80
+
71
81
  @@output = STDOUT
72
82
  @@lang = get_default_lang
73
83
  @@replace_constants = true
@@ -80,6 +90,8 @@ module BOAST
80
90
  @@chain_code = false
81
91
  @@architecture = X86
82
92
  @@debug = get_default_debug
93
+ @@use_vla = get_default_use_vla
94
+ @@decl_module = false
83
95
 
84
96
  @@env = Hash::new{|h, k| h[k] = []}
85
97
 
data/lib/BOAST/CKernel.rb CHANGED
@@ -662,12 +662,14 @@ EOF
662
662
  end
663
663
 
664
664
  def decl_module_params(module_file)
665
+ set_decl_module(true)
665
666
  @procedure.parameters.each { |param|
666
667
  param_copy = param.copy
667
668
  param_copy.constant = nil
668
669
  param_copy.direction = nil
669
670
  param_copy.decl
670
671
  }
672
+ set_decl_module(false)
671
673
  module_file.print " #{@procedure.properties[:return].type.decl} ret;\n" if @procedure.properties[:return]
672
674
  module_file.print " VALUE stats = rb_hash_new();\n"
673
675
  module_file.print " struct timespec start, stop;\n"
data/lib/BOAST/Case.rb CHANGED
@@ -25,28 +25,24 @@ module BOAST
25
25
  end
26
26
  end
27
27
 
28
- @@c_strings = {
29
- :switch => '"switch (#{expr}) {"',
30
- :case => '"case #{constants.join(" : case")} :"',
31
- :default => '"default :"',
32
- :break => '"break;"',
33
- :end => '"}"'
34
- }
28
+ def get_c_strings
29
+ return { :switch => '"switch (#{expr}) {"',
30
+ :case => '"case #{constants.join(" : case")} :"',
31
+ :default => '"default :"',
32
+ :break => '"break;"',
33
+ :end => '"}"' }
34
+ end
35
35
 
36
- @@f_strings = {
37
- :switch => '"select case (#{expr})"',
38
- :case => '"case (#{constants.join(" : ")})"',
39
- :default => '"case default"',
40
- :break => 'nil',
41
- :end => '"end select"'
42
- }
36
+ def get_fortran_strings
37
+ return { :switch => '"select case (#{expr})"',
38
+ :case => '"case (#{constants.join(" : ")})"',
39
+ :default => '"case default"',
40
+ :break => 'nil',
41
+ :end => '"end select"' }
42
+ end
43
43
 
44
- @@strings = {
45
- C => @@c_strings,
46
- CL => @@c_strings,
47
- CUDA => @@c_strings,
48
- FORTRAN => @@f_strings
49
- }
44
+ alias get_cl_strings get_c_strings
45
+ alias get_cuda_strings get_c_strings
50
46
 
51
47
  eval token_string_generator( * %w{switch expr})
52
48
  eval token_string_generator( * %w{case constants})
@@ -8,10 +8,17 @@ module BOAST
8
8
  child.extend Functor
9
9
  end
10
10
 
11
+ def get_strings
12
+ return { C => get_c_strings,
13
+ CL => get_cl_strings,
14
+ CUDA => get_cuda_strings,
15
+ FORTRAN => get_fortran_strings }
16
+ end
17
+
11
18
  def self.token_string_generator(name, *args)
12
19
  s = <<EOF
13
20
  def #{name}_string(#{args.join(",")})
14
- return eval @@strings[get_lang][:#{name}]
21
+ return eval get_strings[get_lang][:#{name}]
15
22
  end
16
23
  EOF
17
24
  end
data/lib/BOAST/For.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  module BOAST
2
2
 
3
3
  class For < ControlStructure
4
- include OpenMP::Pragma
5
4
 
6
5
  attr_reader :iterator
7
6
  attr_reader :begin
@@ -18,10 +17,12 @@ module BOAST
18
17
  @operator = "<="
19
18
  @block = block
20
19
  @openmp = default_options[:openmp]
21
- if @openmp and @openmp.kind_of?(Hash) then
22
- @openmp_clauses = @openmp
23
- else
24
- @openmp_clauses = {}
20
+ if @openmp then
21
+ if @openmp.kind_of?(Hash) then
22
+ @openmp = OpenMP::For(@openmp)
23
+ else
24
+ @openmp = OpenMP::For({})
25
+ end
25
26
  end
26
27
  begin
27
28
  push_env( :replace_constants => true )
@@ -40,31 +41,21 @@ module BOAST
40
41
  end
41
42
  end
42
43
 
43
- @@c_strings = {
44
- :for => '"for (#{i} = #{b}; #{i} #{o} #{e}; #{i} += #{s}) {"',
45
- :end => '"}"',
46
- :openmp_for => '"#pragma omp for #{c}"',
47
- :openmp_end => '""'
48
- }
44
+ def get_c_strings
45
+ return { :for => '"for (#{i} = #{b}; #{i} #{o} #{e}; #{i} += #{s}) {"',
46
+ :end => '"}"' }
47
+ end
49
48
 
50
- @@f_strings = {
51
- :for => '"do #{i} = #{b}, #{e}, #{s}"',
52
- :end => '"end do"',
53
- :openmp_for => '"!$omp do #{c}"',
54
- :openmp_end => '"!$omp end do #{c}"'
55
- }
49
+ def get_fortran_strings
50
+ return { :for => '"do #{i} = #{b}, #{e}, #{s}"',
51
+ :end => '"end do"' }
52
+ end
56
53
 
57
- @@strings = {
58
- C => @@c_strings,
59
- CL => @@c_strings,
60
- CUDA => @@c_strings,
61
- FORTRAN => @@f_strings
62
- }
54
+ alias get_cl_strings get_c_strings
55
+ alias get_cuda_strings get_c_strings
63
56
 
64
57
  eval token_string_generator( * %w{for i b e s o})
65
58
  eval token_string_generator( * %w{end})
66
- eval token_string_generator( * %w{openmp_for c})
67
- eval token_string_generator( * %w{openmp_end c})
68
59
 
69
60
  def to_s
70
61
  s = for_string(@iterator, @begin, @end, @step, @operator)
@@ -115,7 +106,7 @@ module BOAST
115
106
  end
116
107
 
117
108
  def open
118
- output.puts openmp_for_string(openmp_clauses_to_s) if @openmp
109
+ @openmp.open if @openmp
119
110
  s=""
120
111
  s += indent
121
112
  s += to_s
@@ -139,7 +130,8 @@ module BOAST
139
130
  s += indent
140
131
  s += end_string
141
132
  output.puts s
142
- output.puts openmp_end_string(openmp_end_clauses_to_s) if @openmp and openmp_end_string(openmp_end_clauses_to_s) != ""
133
+ @openmp.close if @openmp
134
+ return self
143
135
  end
144
136
 
145
137
  end
@@ -28,7 +28,7 @@ EOF
28
28
  module Functor
29
29
 
30
30
  def self.extended(mod)
31
- BOAST::functorize(mod)
31
+ eval "#{mod.name.split('::')[-2]}::functorize(mod)"
32
32
  end
33
33
 
34
34
  end
@@ -36,7 +36,7 @@ EOF
36
36
  module VarFunctor
37
37
 
38
38
  def self.extended(mod)
39
- BOAST::var_functorize(mod)
39
+ eval "#{mod.name.split('::')[-2]}::var_functorize(mod)"
40
40
  end
41
41
 
42
42
  end
data/lib/BOAST/If.rb CHANGED
@@ -26,26 +26,22 @@ module BOAST
26
26
  end
27
27
  end
28
28
 
29
- @@c_strings = {
30
- :if => '"if (#{cond}) {"',
31
- :else_if => '"} else if (#{cond}) {"',
32
- :else => '"} else {"',
33
- :end => '"}"'
34
- }
29
+ def get_c_strings
30
+ return { :if => '"if (#{cond}) {"',
31
+ :else_if => '"} else if (#{cond}) {"',
32
+ :else => '"} else {"',
33
+ :end => '"}"' }
34
+ end
35
35
 
36
- @@f_strings = {
37
- :if => '"if (#{cond}) then"',
38
- :elsif => '"else if (#{cond}) then"',
39
- :else => '"else"',
40
- :end => '"end if"'
41
- }
36
+ def get_fortran_strings
37
+ return { :if => '"if (#{cond}) then"',
38
+ :elsif => '"else if (#{cond}) then"',
39
+ :else => '"else"',
40
+ :end => '"end if"' }
41
+ end
42
42
 
43
- @@strings = {
44
- C => @@c_strings,
45
- CL => @@c_strings,
46
- CUDA => @@c_strings,
47
- FORTRAN => @@f_strings
48
- }
43
+ alias get_cl_strings get_c_strings
44
+ alias get_cuda_strings get_c_strings
49
45
 
50
46
  eval token_string_generator( * %w{if cond} )
51
47
  eval token_string_generator( * %w{elsif cond} )
data/lib/BOAST/Index.rb CHANGED
@@ -23,11 +23,7 @@ module BOAST
23
23
  (0...dims.length).each { |indx|
24
24
  dim = dims[indx]
25
25
  s = "#{indxs[indx]}"
26
- if dim.val2 then
27
- s += " - (#{dim.val1})"
28
- elsif 0 != get_array_start then
29
- s += " - (#{get_array_start})"
30
- end
26
+ s += " - (#{dim.start})" unless 0.equal?(dim.start)
31
27
  ind = eval(s)
32
28
  ind = ind.to_i
33
29
  const = const[ind]
@@ -92,6 +88,18 @@ module BOAST
92
88
  return s
93
89
  end
94
90
 
91
+ def to_s_use_vla
92
+ indxs = @indexes.reverse
93
+ dims = @source.dimension.reverse
94
+ t = (0...dims.length).collect { |indx|
95
+ s = "#{indxs[indx]}"
96
+ dim = dims[indx]
97
+ s += " - (#{dim.start})" unless 0.equal?(dim.start)
98
+ s
99
+ }
100
+ return t.join("][")
101
+ end
102
+
95
103
  def to_s_c_reversed
96
104
  indxs = @indexes.reverse
97
105
  dims = @source.dimension.reverse
@@ -100,16 +108,10 @@ module BOAST
100
108
  s = ""
101
109
  dim = dims[indx]
102
110
  s += "#{indxs[indx]}"
103
- if dim.val2 then
104
- s += " - (#{dim.val1})"
105
- elsif 0 != get_array_start then
106
- s += " - (#{get_array_start})"
107
- end
111
+ s += " - (#{dim.start})" unless 0.equal?(dim.start)
108
112
  if ss then
109
113
  if dim.size then
110
114
  s += " + (#{dim.size}) * "
111
- elsif dim.val2 then
112
- s += " + (#{dim.val2} - (#{dim.val1}) + 1) * "
113
115
  else
114
116
  raise "Unkwown dimension size!"
115
117
  end
@@ -122,7 +124,11 @@ module BOAST
122
124
 
123
125
  def to_s_c
124
126
  return to_s_texture if @source.texture
125
- sub = to_s_c_reversed
127
+ if use_vla? then
128
+ sub = to_s_use_vla
129
+ else
130
+ sub = to_s_c_reversed
131
+ end
126
132
  s = "#{@source}[" + sub + "]"
127
133
  return s
128
134
  end
data/lib/BOAST/OpenMP.rb CHANGED
@@ -16,66 +16,101 @@ module BOAST
16
16
  return s
17
17
  end
18
18
 
19
- def openmp_clauses_to_s
19
+ # Registers an openmp clause, arg_type can be :none, :option, :option_list, :simple, :list, :multilist
20
+ def self.register_clause( name, arg_type )
21
+ s = <<EOF
22
+ def openmp_clause_#{name}(c)
23
+ EOF
24
+ case arg_type
25
+ when :none
26
+ s += <<EOF
27
+ return " #{name}"
28
+ EOF
29
+ when :option
30
+ s += <<EOF
31
+ return " \#{c}"
32
+ EOF
33
+ when :option_list
34
+ s += <<EOF
35
+ return " (\#{[c].flatten.join(", ")})"
36
+ EOF
37
+ when :simple
38
+ s += <<EOF
39
+ return " #{name}(\#{c})"
40
+ EOF
41
+ when :list
42
+ s += <<EOF
43
+ return " #{name}(\#{[c].flatten.join(", ")})"
44
+ EOF
45
+ when :multilist
46
+ s += <<EOF
20
47
  s = ""
21
- if @openmp_clauses[:if] then
22
- s += " if(#{@openmp_clauses[:if]})"
23
- end
24
- if @openmp_clauses[:num_threads] then
25
- s += " num_threads(#{@openmp_clauses[:num_threads]})"
26
- end
27
- if @openmp_clauses[:default] then
28
- s += " default(#{@openmp_clauses[:default]})"
29
- end
30
- if @openmp_clauses[:private] then
31
- s += " private(#{[@openmp_clauses[:private]].flatten.join(", ")})"
32
- end
33
- if @openmp_clauses[:firstprivate] then
34
- s += " firstprivate(#{[@openmp_clauses[:firstprivate]].flatten.join(", ")})"
35
- end
36
- if @openmp_clauses[:lastprivate] then
37
- s += " lastprivate(#{[@openmp_clauses[:lastprivate]].flatten.join(", ")})"
48
+ c.each { |id, list|
49
+ s += " #{name}(\#{id}: \#{[list].flatten.join(", ")})"
50
+ }
51
+ return s
52
+ EOF
53
+ else
54
+ raise "Unknown argument type!"
38
55
  end
56
+ s += <<EOF
57
+ end
58
+ EOF
59
+ eval s
60
+ end
61
+
62
+ register_clause(:nowait, :none)
63
+ register_clause(:ordered, :none)
64
+ register_clause(:untied, :none)
65
+ register_clause(:mergeable, :none)
66
+ register_clause(:inbranch, :none)
67
+ register_clause(:notinbranch, :none)
68
+ register_clause(:seq_cst, :none)
69
+ register_clause(:name, :option)
70
+ register_clause(:flush_list, :option_list)
71
+ register_clause(:threadprivate_list, :option_list)
72
+ register_clause(:if, :simple)
73
+ register_clause(:num_threads, :simple)
74
+ register_clause(:default, :simple)
75
+ register_clause(:collapse, :simple)
76
+ register_clause(:safelen, :simple)
77
+ register_clause(:simdlen, :simple)
78
+ register_clause(:device, :simple)
79
+ register_clause(:private, :list)
80
+ register_clause(:shared, :list)
81
+ register_clause(:firstprivate, :list)
82
+ register_clause(:lastprivate, :list)
83
+ register_clause(:copyprivate, :list)
84
+ register_clause(:copyin, :list)
85
+ register_clause(:schedule, :list)
86
+ register_clause(:linear, :list)
87
+ register_clause(:aligned, :list)
88
+ register_clause(:uniform, :list)
89
+ register_clause(:to, :list)
90
+ register_clause(:from, :list)
91
+ register_clause(:reduction, :multilist)
92
+ register_clause(:depend, :multilist)
93
+ register_clause(:map, :multilist)
94
+
95
+ def openmp_open_clauses_to_s
96
+ s = ""
97
+ get_open_clauses.each { |c|
98
+ s += self.send( "openmp_clause_#{c}", @openmp_clauses[c] ) if @openmp_clauses[c]
99
+ }
39
100
  if lang == C then
40
- if @openmp_clauses[:copyprivate] then
41
- s += " copyprivate(#{[@openmp_clauses[:copyprivate]].flatten.join(", ")})"
42
- end
43
- if @openmp_clauses[:nowait] then
44
- s += " nowait"
45
- end
46
- end
47
- if @openmp_clauses[:shared] then
48
- s += " shared(#{[@openmp_clauses[:shared]].flatten.join(", ")})"
49
- end
50
- if @openmp_clauses[:copyin] then
51
- s += " copyin(#{[@openmp_clauses[:copyin]].flatten.join(", ")})"
52
- end
53
- if @openmp_clauses[:reduction] then
54
- options[:reduction].each { |identifier, list|
55
- s += " reduction(#{identifier}: #{list.join(", ")})"
101
+ get_end_clauses.each { |c|
102
+ s += self.send( c, @openmp_clauses[c] ) if @openmp_clauses[c]
56
103
  }
57
104
  end
58
- if @openmp_clauses[:schedule] then
59
- s += " schedule(#{@openmp_clauses[:schedule].join(", ")})"
60
- end
61
- if @openmp_clauses[:collapse] then
62
- s += " collapse(#{@openmp_clauses[:collapse]})"
63
- end
64
- if @openmp_clauses[:ordered] then
65
- s += " ordered"
66
- end
67
105
  return s
68
106
  end
69
107
 
70
108
  def openmp_end_clauses_to_s
71
109
  s = ""
72
110
  if lang == FORTRAN then
73
- if @openmp_clauses[:copyprivate] then
74
- s += " copyprivate(#{[@openmp_clauses[:copyprivate]].flatten.join(", ")})"
75
- end
76
- if @openmp_clauses[:nowait] then
77
- s += " nowait"
78
- end
111
+ get_end_clauses.each { |c|
112
+ s += self.send( c, @openmp_clauses[c] ) if @openmp_clauses[c]
113
+ }
79
114
  end
80
115
  return s
81
116
  end
@@ -94,76 +129,30 @@ module BOAST
94
129
  EOF
95
130
  eval s
96
131
  end
97
-
98
- def var_functorize(klass)
99
- name = klass.name.split('::').last
100
- s = <<EOF
101
- def #{name}(*args,&block)
102
- Variable::new(args[0],#{name},*args[1..-1], &block)
103
- end
104
-
105
- module_function :#{name}
106
- EOF
107
- eval s
108
- end
109
-
110
- module Functor
111
-
112
- def self.extended(mod)
113
- BOAST::OpenMP::functorize(mod)
114
- end
115
-
116
- end
117
-
118
- class ControlStructure
119
- include PrivateStateAccessor
120
- include Inspectable
132
+
133
+ class OpenMPControlStructure < ControlStructure
121
134
  include OpenMP::Pragma
122
135
 
123
- def self.inherited(child)
124
- child.extend Functor
125
- end
126
-
127
- def self.token_string_generator(name, *args)
128
- s = <<EOF
129
- def #{name}_string(#{args.join(",")})
130
- return eval @@strings[get_lang][:#{name}]
131
- end
132
- EOF
136
+ def get_strings
137
+ return { C => get_c_strings,
138
+ FORTRAN => get_fortran_strings }
133
139
  end
134
140
 
135
- end
136
-
137
- class Parallel < ControlStructure
138
-
139
141
  def initialize(options = {}, &block)
140
142
  @openmp_clauses = options
141
143
  @block = block
142
144
  end
143
- @@c_strings = {
144
- :parallel => '"#pragma omp parallel #{c}\n{"',
145
- :end => '"}"',
146
- }
147
-
148
- @@f_strings = {
149
- :parallel => '"!$omp parallel #{c}"',
150
- :end => '"!$omp end parallel #{c}"',
151
- }
152
145
 
153
- @@strings = {
154
- C => @@c_strings,
155
- FORTRAN => @@f_strings
156
- }
157
-
158
- eval token_string_generator( * %w{parallel c})
146
+ eval token_string_generator( * %w{begin c})
159
147
  eval token_string_generator( * %w{end c})
160
148
 
161
149
  def to_s
162
- return parallel_string(openmp_clauses_to_s)
150
+ return begin_string(openmp_open_clauses_to_s)
163
151
  end
164
152
 
165
153
  def open
166
154
  output.puts to_s
155
+ return self
167
156
  end
168
157
 
169
158
  def pr(*args)
@@ -177,10 +166,285 @@ EOF
177
166
 
178
167
  def close
179
168
  output.puts end_string(openmp_end_clauses_to_s)
169
+ return self
170
+ end
171
+
172
+ end
173
+
174
+ def self.register_openmp_construct( name, c_name, open_clauses, end_clauses = [], options = {} )
175
+ fortran_name = c_name
176
+ fortran_name = options[:fortran_name] if options[:fortran_name]
177
+ s = <<EOF
178
+ class #{name} < OpenMPControlStructure
179
+
180
+ def self.name
181
+ return "#{name}"
182
+ end
183
+
184
+ def self.c_name
185
+ return "#{c_name}"
186
+ end
187
+
188
+ def self.fortran_name
189
+ return "#{fortran_name}"
190
+ end
191
+
192
+ def self.block
193
+ return #{options[:block] ? "true" : "false"}
194
+ end
195
+
196
+ def get_c_strings
197
+ return { :begin => '"#pragma omp #{c_name} #{ open_clauses.length + end_clauses.length > 0 ? "\#{c}" : "" }#{ options[:block] ? "\\n{" : "" }"',
198
+ EOF
199
+ if options[:c_end] then
200
+ s += <<EOF
201
+ :end => '"#pragma omp end #{c_name}"' }
202
+ EOF
203
+ else
204
+ s += <<EOF
205
+ :end => '"#{ options[:block] ? "}" : "" }"' }
206
+ EOF
180
207
  end
208
+ s += <<EOF
209
+ end
210
+
211
+ def get_fortran_strings
212
+ return { :begin => '"!$omp #{fortran_name}#{ open_clauses.length > 0 ? " \#{c}" : "" }#{ options[:fortran_block] ? "(" : "" }"',
213
+ EOF
214
+ if options[:fortran_no_end] then
215
+ s += <<EOF
216
+ :end => '"#{ options[:fortran_block] ? ")" : "" }"' }
217
+ EOF
218
+ else
219
+ s += <<EOF
220
+ :end => '"!$omp end #{fortran_name} #{ end_clauses.length > 0 ? "\#{c}" : "" }"' }
221
+ EOF
222
+ end
223
+ s += <<EOF
224
+ end
225
+
226
+ def self.get_open_clauses
227
+ return [ #{open_clauses.collect { |c| ":#{c}" }.join(",\n ")} ]
228
+ end
229
+
230
+ def self.get_end_clauses
231
+ return [ #{end_clauses.collect { |c| ":#{c}" }.join(",\n ")} ]
232
+ end
233
+
234
+ def get_open_clauses
235
+ return #{name}.get_open_clauses
236
+ end
237
+
238
+ def get_end_clauses
239
+ return #{name}.get_end_clauses
240
+ end
241
+
242
+ end
243
+ EOF
244
+ eval s
245
+ end
181
246
 
247
+ def self.register_openmp_compound_construct( c1, c2, options = {} )
248
+ register_openmp_construct( c1.name+c2.name, "#{c1.c_name} #{c2.c_name}",
249
+ (c1.get_open_clauses + c2.get_open_clauses).uniq,
250
+ options[:no_end_clauses] ? [] : (c1.get_end_clauses + c2.get_end_clauses).uniq,
251
+ :fortran_name => "#{c1.fortran_name} #{c2.fortran_name}",
252
+ :block => options[:block] )
182
253
  end
183
254
 
255
+ register_openmp_construct( :Parallel, "parallel",
256
+ [ :if,
257
+ :num_threads,
258
+ :default,
259
+ :private,
260
+ :firstprivate,
261
+ :shared,
262
+ :copyin,
263
+ :reduction,
264
+ :proc_bind ],
265
+ [],
266
+ :block => true )
267
+
268
+ register_openmp_construct( :For, "for",
269
+ [ :private,
270
+ :firstprivate,
271
+ :lastprivate,
272
+ :reduction,
273
+ :schedule,
274
+ :collapse,
275
+ :ordered ],
276
+ [ :nowait ],
277
+ :fortran_name => "do" )
278
+
279
+ register_openmp_construct( :Sections, "sections",
280
+ [ :private,
281
+ :firstprivate,
282
+ :lastprivate,
283
+ :reduction ],
284
+ [ :nowait ],
285
+ :block => true )
286
+
287
+ register_openmp_construct( :Section, "section", [], [],
288
+ :block => true,
289
+ :fortran_no_end => true )
290
+
291
+ register_openmp_construct( :Single, "single",
292
+ [ :private,
293
+ :firstprivate ],
294
+ [ :copyprivate,
295
+ :nowait ],
296
+ :block => true )
297
+
298
+ register_openmp_construct( :Simd, "simd",
299
+ [ :safelen,
300
+ :linear,
301
+ :aligned,
302
+ :private,
303
+ :lastprivate,
304
+ :reduction,
305
+ :collapse ] )
306
+
307
+ register_openmp_construct( :DeclareSimd, "declare simd",
308
+ [ :simdlen,
309
+ :linear,
310
+ :aligned,
311
+ :uniform,
312
+ :inbranch,
313
+ :notinbranch ] )
314
+
315
+ register_openmp_compound_construct( For, Simd )
316
+
317
+ register_openmp_construct( :TargetData, "target data",
318
+ [ :device,
319
+ :map,
320
+ :if ],
321
+ [],
322
+ :block => true )
323
+
324
+ register_openmp_construct( :Target, "target",
325
+ [ :device,
326
+ :map,
327
+ :if ],
328
+ [],
329
+ :block => true )
330
+
331
+ register_openmp_construct( :TargetUpdate, "target update",
332
+ [ :to,
333
+ :from,
334
+ :device,
335
+ :if ],
336
+ [],
337
+ :fortran_no_end => true )
338
+
339
+ register_openmp_construct( :DeclareTarget, "declare target",
340
+ [],
341
+ [],
342
+ :c_end => true,
343
+ :fortran_no_end => true,
344
+ :fortran_block => true )
345
+
346
+ register_openmp_construct( :Teams, "teams",
347
+ [ :num_teams,
348
+ :thread_limit,
349
+ :default,
350
+ :private,
351
+ :firstprivate,
352
+ :shared,
353
+ :reduction ],
354
+ [],
355
+ :block => true )
356
+
357
+ register_openmp_construct( :Distribute, "distribute",
358
+ [ :private,
359
+ :firstprivate,
360
+ :collapse,
361
+ :dist_schedule ] )
362
+
363
+ register_openmp_compound_construct( Distribute, Simd )
364
+
365
+ register_openmp_compound_construct( Parallel, For, :no_end_clauses => true )
366
+
367
+ register_openmp_compound_construct( Distribute, ParallelFor )
368
+
369
+ register_openmp_compound_construct( Parallel, ForSimd, :no_end_clauses => true )
370
+
371
+ register_openmp_compound_construct( Distribute, ParallelForSimd )
372
+
373
+ register_openmp_compound_construct( Parallel, Sections, :no_end_clauses => true, :block => true )
374
+
375
+ register_openmp_compound_construct( Target, Teams, :block => true )
376
+
377
+ register_openmp_compound_construct( Teams, Distribute )
378
+
379
+ register_openmp_compound_construct( Teams, DistributeSimd )
380
+
381
+ register_openmp_compound_construct( Target, TeamsDistribute )
382
+
383
+ register_openmp_compound_construct( Target, TeamsDistributeSimd )
384
+
385
+ register_openmp_compound_construct( Teams, DistributeParallelFor )
386
+
387
+ register_openmp_compound_construct( Target, TeamsDistributeParallelFor )
388
+
389
+ register_openmp_compound_construct( Teams, DistributeParallelForSimd )
390
+
391
+ register_openmp_compound_construct( Target, TeamsDistributeParallelForSimd )
392
+
393
+ register_openmp_construct( :Task, "task",
394
+ [ :if,
395
+ :final,
396
+ :untied,
397
+ :default,
398
+ :mergeable,
399
+ :private,
400
+ :firstprivate,
401
+ :shared,
402
+ :depend ],
403
+ [],
404
+ :block => true )
405
+
406
+ register_openmp_construct( :Taskyield, "taskyield", [], [], :fortran_no_end => true )
407
+
408
+ register_openmp_construct( :Master, "master", [], [], :block => true )
409
+
410
+ register_openmp_construct( :Critical, "critical", [:name], [:name], :block => true )
411
+
412
+ register_openmp_construct( :Barrier, "barrier", [], [], :fortran_no_end => true )
413
+
414
+ register_openmp_construct( :Taskwait, "taskwait", [], [], :fortran_no_end => true )
415
+
416
+ register_openmp_construct( :Taskgroup, "taskgroup", [], [], :block => true )
417
+
418
+ register_openmp_construct( :AtomicRead, "atomic read", [:seq_cst], [] )
419
+
420
+ register_openmp_construct( :AtomicWrite, "atomic write", [:seq_cst], [] )
421
+
422
+ register_openmp_construct( :AtomicUpdate, "atomic update", [:seq_cst], [] )
423
+
424
+ register_openmp_construct( :AtomicCapture, "atomic capture", [:seq_cst], [], :block => true )
425
+
426
+ register_openmp_construct( :Flush, "flush", [:flush_list], [], :fortran_no_end => true )
427
+
428
+ register_openmp_construct( :Ordered, "ordered", [], [], :block => true )
429
+
430
+ register_openmp_construct( :CancelParallel, "cancel parallel", [:if], [], :fortran_no_end => true )
431
+
432
+ register_openmp_construct( :CancelSections, "cancel sections", [:if], [], :fortran_no_end => true )
433
+
434
+ register_openmp_construct( :CancelFor, "cancel for", [:if], [], :fortran_no_end => true )
435
+
436
+ register_openmp_construct( :CancelTaskgroup, "cancel taskgroup", [:if], [], :fortran_no_end => true )
437
+
438
+ register_openmp_construct( :CancellationPointParallel, "cancellation point parallel", [], [], :fortran_no_end => true )
439
+
440
+ register_openmp_construct( :CancellationPointSections, "cancellation point sections", [], [], :fortran_no_end => true )
441
+
442
+ register_openmp_construct( :CancellationPointFor, "cancellation point for", [], [], :fortran_no_end => true )
443
+
444
+ register_openmp_construct( :CancellationPointTaskgroup, "cancellation point taskgroup", [], [], :fortran_no_end => true )
445
+
446
+ register_openmp_construct( :Threadprivate, "threadprivate", [:threadprivate_list], [], :fortran_no_end => true )
447
+
184
448
  end
185
449
 
186
450
  end
@@ -123,7 +123,9 @@ module BOAST
123
123
  s = ""
124
124
  if lang == CL then
125
125
  if @properties[:local] then
126
- s += "static "
126
+ s += "#if __OPENCL_C_VERSION__ && __OPENCL_C_VERSION__ >= 120\n"
127
+ s += "static\n"
128
+ s += "#endif\n"
127
129
  else
128
130
  s += "__kernel "
129
131
  wgs = @properties[:reqd_work_group_size]
@@ -0,0 +1,94 @@
1
+ module BOAST
2
+
3
+ class Slice
4
+ include PrivateStateAccessor
5
+ include Inspectable
6
+ attr_reader :source
7
+ attr_reader :slices
8
+
9
+ def initialize(source, *slices)
10
+ raise "Cannot slice a non array Variable!" if not source.dimension?
11
+ raise "Invalid slice!" if slices.length != source.dimension.length
12
+ @source = source
13
+ @slices = slices
14
+ end
15
+
16
+ def to_s_c
17
+ s = "#{@source}["
18
+ dims = @source.dimension.reverse
19
+ slices = @slices.reverse
20
+ slices_to_c = []
21
+ slices.each_index { |indx|
22
+ slice = slices[indx]
23
+ if slice.kind_of?(Array) then
24
+ if slice.length == 0 then
25
+ slices_to_c.push(":")
26
+ elsif slice.length == 1 then
27
+ slices_to_c.push("#{Expression::new(Substraction, slice[0], dims[indx].start)}")
28
+ else
29
+ start, finish, step = slice
30
+ start_c = Expression::new(Substraction, start, dims[indx].start)
31
+ length = Expression::new(Substraction, finish, start) + 1
32
+ slices_to_c.push("#{start_c}:#{length}")
33
+ end
34
+ elsif slice.kind_of?(Range) then
35
+ start = slice.first
36
+ finish = slice.last
37
+ start_c = Expression::new(Substraction, start, dims[indx].start)
38
+ length = Expression::new(Substraction, finish, start)
39
+ length = length + 1 unless slice.exclude_end?
40
+ slices_to_c.push("#{start_c}:#{length}")
41
+ elsif slice then
42
+ slices_to_c.push("#{Expression::new(Substraction, slice, dims[indx].start)}")
43
+ else
44
+ slices_to_c.push(":")
45
+ end
46
+ }
47
+ return s + slices_to_c.join("][") + "]"
48
+ end
49
+
50
+ def to_s_fortran
51
+ slices_to_fortran = @slices.collect { |slice|
52
+ if slice then
53
+ if slice.kind_of?(Range) then
54
+ "#{slice.first}:#{slice.last}#{slice.exclude_end? ? " - 1" : "" }"
55
+ else
56
+ sl = [slice].flatten
57
+ if sl.length > 0 then
58
+ sl.join(":")
59
+ else
60
+ ":"
61
+ end
62
+ end
63
+ else
64
+ ":"
65
+ end
66
+ }
67
+ return "#{source}(#{slices_to_fortran.join(",")})"
68
+ end
69
+
70
+ def to_s
71
+ return to_s_fortran if lang == FORTRAN
72
+ return to_s_c if [C, CL, CUDA].include?( lang )
73
+ end
74
+
75
+ def pr
76
+ s=""
77
+ s += indent
78
+ s += to_s
79
+ s += ";" if [C, CL, CUDA].include?( lang )
80
+ output.puts s
81
+ return self
82
+ end
83
+
84
+ end
85
+
86
+ class Variable
87
+
88
+ def slice(*slices)
89
+ Slice::new(self, *slices)
90
+ end
91
+
92
+ end
93
+
94
+ end
@@ -30,6 +30,33 @@ module BOAST
30
30
  return @size
31
31
  end
32
32
  end
33
+
34
+ def start
35
+ if @val2 then
36
+ return @val1
37
+ else
38
+ return get_array_start
39
+ end
40
+ end
41
+
42
+ def finish
43
+ if @val2 then
44
+ return @val2
45
+ elsif @size
46
+ if 0.equal?(get_array_start) then
47
+ if 1.equal?(get_array_start) then
48
+ return Expression::new(Addition, @size, get_array_start) - 1
49
+ else
50
+ return @size
51
+ end
52
+ else
53
+ return Expression::new(Substraction, @size, 1)
54
+ end
55
+ else
56
+ return nil
57
+ end
58
+ end
59
+
33
60
  end
34
61
 
35
62
  class ConstArray < Array
@@ -242,12 +269,24 @@ module BOAST
242
269
  s += "const " if constant? or @direction == :in
243
270
  s += @type.decl
244
271
  if dimension? then
245
- s += " *"
272
+ s += " *" unless use_vla?
246
273
  end
247
274
  if not dimension? and ( lang == FORTRAN or @direction == :out or @direction == :inout ) then
248
275
  s += " *"
249
276
  end
250
277
  s += " #{@name}"
278
+ if dimension? and use_vla? then
279
+ s += "["
280
+ s += @dimension.reverse.collect { |d|
281
+ dim = d.to_s
282
+ if dim then
283
+ dim.to_s
284
+ else
285
+ ""
286
+ end
287
+ }.join("][")
288
+ s += "]"
289
+ end
251
290
  return s
252
291
  end
253
292
 
@@ -264,28 +303,41 @@ module BOAST
264
303
  s += "__local " if local? and lang == CL
265
304
  s += "__shared__ " if local? and not device and lang == CUDA
266
305
  s += @type.decl
267
- if dimension? and not constant? and not allocate? and (not local? or (local? and device)) then
268
- s += " *"
269
- if restrict? then
270
- if lang == CL
271
- s += " restrict"
306
+ if use_vla? and dimension? and not decl_module? then
307
+ s += " #{@name}["
308
+ s += @dimension.reverse.collect { |d|
309
+ dim = d.to_s
310
+ if dim then
311
+ dim.to_s
272
312
  else
273
- s += " __restrict__"
313
+ ""
314
+ end
315
+ }.join("][")
316
+ s += "]"
317
+ else
318
+ if dimension? and not constant? and not allocate? and (not local? or (local? and device)) then
319
+ s += " *"
320
+ if restrict? and not decl_module? then
321
+ if lang == CL
322
+ s += " restrict"
323
+ else
324
+ s += " __restrict__" unless use_vla?
325
+ end
274
326
  end
275
327
  end
328
+ if not dimension? and ( @direction == :out or @direction == :inout ) then
329
+ s += " *"
330
+ end
331
+ s += " #{@name}"
332
+ if dimension? and constant? then
333
+ s += "[]"
334
+ end
335
+ if dimension? and ((local? and not device) or (allocate? and not constant?)) then
336
+ s +="[("
337
+ s += @dimension.collect{ |d| d.to_s }.reverse.join(")*(")
338
+ s +=")]"
339
+ end
276
340
  end
277
- if not dimension? and ( @direction == :out or @direction == :inout ) then
278
- s += " *"
279
- end
280
- s += " #{@name}"
281
- if dimension? and constant? then
282
- s += "[]"
283
- end
284
- if dimension? and ((local? and not device) or (allocate? and not constant?)) then
285
- s +="[("
286
- s += @dimension.collect{ |d| d.to_s }.reverse.join(")*(")
287
- s +=")]"
288
- end
289
341
  s += " = #{@constant}" if constant?
290
342
  return s
291
343
  end
data/lib/BOAST/While.rb CHANGED
@@ -9,22 +9,18 @@ module BOAST
9
9
  @block = block
10
10
  end
11
11
 
12
- @@c_strings = {
13
- :while => '"while (#{cond}) {"',
14
- :end => '"}"'
15
- }
12
+ def get_c_strings
13
+ return { :while => '"while (#{cond}) {"',
14
+ :end => '"}"' }
15
+ end
16
16
 
17
- @@f_strings = {
18
- :while => '"do while (#{cond})"',
19
- :end => '"end do"'
20
- }
17
+ def get_fortran_strings
18
+ return { :while => '"do while (#{cond})"',
19
+ :end => '"end do"' }
20
+ end
21
21
 
22
- @@strings = {
23
- C => @@c_strings,
24
- CL => @@c_strings,
25
- CUDA => @@c_strings,
26
- FORTRAN => @@f_strings
27
- }
22
+ alias get_cl_strings get_c_strings
23
+ alias get_cuda_strings get_c_strings
28
24
 
29
25
  eval token_string_generator( * %w{while cond} )
30
26
  eval token_string_generator( * %w{end} )
data/lib/BOAST.rb CHANGED
@@ -8,6 +8,7 @@ require 'BOAST/DataTypes.rb'
8
8
  require 'BOAST/Expression.rb'
9
9
  require 'BOAST/Index.rb'
10
10
  require 'BOAST/Variable.rb'
11
+ require 'BOAST/Slice.rb'
11
12
  require 'BOAST/FuncCall.rb'
12
13
  require 'BOAST/Procedure.rb'
13
14
  require 'BOAST/Algorithm.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: '0.99996'
4
+ version: '0.99997'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brice Videau
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-08 00:00:00.000000000 Z
11
+ date: 2015-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: narray
@@ -83,6 +83,7 @@ files:
83
83
  - lib/BOAST/Pragma.rb
84
84
  - lib/BOAST/Print.rb
85
85
  - lib/BOAST/Procedure.rb
86
+ - lib/BOAST/Slice.rb
86
87
  - lib/BOAST/State.rb
87
88
  - lib/BOAST/Transitions.rb
88
89
  - lib/BOAST/Variable.rb