BOAST 0.99996 → 0.99997

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