BOAST 0.995 → 0.996

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,187 @@
1
+ module BOAST
2
+ class Procedure
3
+ def self.parens(*args,&block)
4
+ return self::new(*args,&block)
5
+ end
6
+
7
+ attr_reader :name
8
+ attr_reader :parameters
9
+ attr_reader :constants
10
+ attr_reader :properties
11
+ attr_reader :headers
12
+ def initialize(name, parameters=[], constants=[], properties={}, &block)
13
+ @name = name
14
+ @parameters = parameters
15
+ @constants = constants
16
+ @block = block
17
+ @properties = properties
18
+ @headers = properties[:headers]
19
+ @headers = [] if not @headers
20
+ end
21
+
22
+ def header(lang=C,final=true)
23
+ s = ""
24
+ headers.each { |h|
25
+ s += "#include <#{h}>\n"
26
+ }
27
+ if BOAST::get_lang == CL then
28
+ s += "__kernel "
29
+ wgs = @properties[:reqd_work_group_size]
30
+ if wgs then
31
+ s += "__attribute__((reqd_work_group_size(#{wgs[0]},#{wgs[1]},#{wgs[2]}))) "
32
+ end
33
+ end
34
+ trailer = ""
35
+ trailer += "_" if lang == FORTRAN
36
+ trailer += "_wrapper" if lang == CUDA
37
+ if @properties[:return] then
38
+ s += "#{@properties[:return].type.decl} "
39
+ elsif lang == CUDA
40
+ s += "unsigned long long int "
41
+ else
42
+ s += "void "
43
+ end
44
+ s += "#{@name}#{trailer}("
45
+ if parameters.first then
46
+ s += parameters.first.header(lang,false)
47
+ parameters[1..-1].each { |p|
48
+ s += ", "
49
+ s += p.header(lang,false)
50
+ }
51
+ end
52
+ if lang == CUDA then
53
+ s += ", " if parameters.first
54
+ s += "size_t *block_number, size_t *block_size"
55
+ end
56
+ s += ")"
57
+ s += ";\n" if final
58
+ BOAST::get_output.print s if final
59
+ return s
60
+ end
61
+
62
+ def call(*parameters)
63
+ prefix = ""
64
+ prefix += "call " if BOAST::get_lang==FORTRAN
65
+ f = FuncCall::new(@name, *parameters)
66
+ f.prefix = prefix
67
+ return f
68
+ end
69
+ def decl(final=true)
70
+ return self.decl_fortran(final) if BOAST::get_lang==FORTRAN
71
+ return self.decl_c(final) if [C, CL, CUDA].include?( BOAST::get_lang )
72
+ end
73
+ def close(final=true)
74
+ return self.close_fortran(final) if BOAST::get_lang==FORTRAN
75
+ return self.close_c(final) if [C, CL, CUDA].include?( BOAST::get_lang )
76
+ end
77
+ def close_c(final=true)
78
+ BOAST::decrement_indent_level
79
+ s = ""
80
+ s += " return #{@properties[:return]};\n" if @properties[:return]
81
+ s += "}"
82
+ BOAST::get_output.puts s if final
83
+ return s
84
+ end
85
+ def close_fortran(final=true)
86
+ BOAST::decrement_indent_level
87
+ s = ""
88
+ if @properties[:return] then
89
+ s += " #{@name} = #{@properties[:return]}\n"
90
+ s += "END FUNCTION #{@name}"
91
+ else
92
+ s += "END SUBROUTINE #{@name}"
93
+ end
94
+ BOAST::get_output.puts s if final
95
+ return s
96
+ end
97
+
98
+ def print(final=true)
99
+ s = self.decl
100
+ if @block then
101
+ @block.call
102
+ s += self.close
103
+ end
104
+ return s
105
+ end
106
+
107
+ def decl_c(final=true)
108
+ s = ""
109
+ # s += self.header(BOAST::get_lang,false)
110
+ # s += ";\n"
111
+ if BOAST::get_lang == CL then
112
+ if not @properties[:local] then
113
+ s += "__kernel "
114
+ wgs = @properties[:reqd_work_group_size]
115
+ if wgs then
116
+ s += "__attribute__((reqd_work_group_size(#{wgs[0]},#{wgs[1]},#{wgs[2]}))) "
117
+ end
118
+ end
119
+ elsif BOAST::get_lang == CUDA then
120
+ if @properties[:local] then
121
+ s += "static __device__ "
122
+ else
123
+ s += "__global__ "
124
+ wgs = @properties[:reqd_work_group_size]
125
+ if wgs then
126
+ s += "__launch_bounds__(#{wgs[0]}*#{wgs[1]}*#{wgs[2]}) "
127
+ end
128
+ end
129
+ end
130
+ if @properties[:qualifiers] then
131
+ s += "#{@properties[:qualifiers]} "
132
+ end
133
+ if @properties[:return] then
134
+ s += "#{@properties[:return].type.decl} "
135
+ else
136
+ s += "void "
137
+ end
138
+ s += "#{@name}("
139
+ if parameters.first then
140
+ s += parameters.first.decl(false, @properties[:local])
141
+ parameters[1..-1].each { |p|
142
+ s += ", "+p.decl(false, @properties[:local])
143
+ }
144
+ end
145
+ s += "){\n"
146
+ BOAST::increment_indent_level
147
+ constants.each { |c|
148
+ s += " "*BOAST::get_indent_level
149
+ s += c.decl(false)
150
+ s += ";\n"
151
+ }
152
+ BOAST::get_output.print s if final
153
+ return s
154
+ end
155
+ def decl_fortran(final=true)
156
+ s = ""
157
+ if @properties[:return] then
158
+ s += "#{@properties[:return].type.decl} FUNCTION "
159
+ else
160
+ s += "SUBROUTINE "
161
+ end
162
+ s += "#{@name}("
163
+ if parameters.first then
164
+ s += parameters.first
165
+ parameters[1..-1].each { |p|
166
+ s += ", "+p
167
+ }
168
+ end
169
+ s += ")\n"
170
+ BOAST::increment_indent_level
171
+ s += " "*BOAST::get_indent_level + "integer, parameter :: wp=kind(1.0d0)\n"
172
+ constants.each { |c|
173
+ s += " "*BOAST::get_indent_level
174
+ s += c.decl(false)
175
+ s += "\n"
176
+ }
177
+ parameters.each { |p|
178
+ s += " "*BOAST::get_indent_level
179
+ s += p.decl(false)
180
+ s += "\n"
181
+ }
182
+ BOAST::get_output.print s if final
183
+ return s
184
+ end
185
+ end
186
+
187
+ end
@@ -0,0 +1,345 @@
1
+ module BOAST
2
+
3
+ class Dimension
4
+ def self.parens(*args,&block)
5
+ return self::new(*args,&block)
6
+ end
7
+
8
+ attr_reader :val1
9
+ attr_reader :val2
10
+ attr_reader :size
11
+ def initialize(v1=nil,v2=nil)
12
+ @size = nil
13
+ @val1 = nil
14
+ @val2 = nil
15
+ if v2.nil? and v1 then
16
+ @val1 = BOAST::get_array_start
17
+ @val2 = v1 + BOAST::get_array_start - 1
18
+ @size = v1
19
+ else
20
+ @val1 = v1
21
+ @val2 = v2
22
+ end
23
+ end
24
+
25
+ def to_str
26
+ s = ""
27
+ if @val2 then
28
+ if BOAST::get_lang == BOAST::FORTRAN then
29
+ s += @val1.to_s
30
+ s += ":"
31
+ s += @val2.to_s
32
+ elsif [BOAST::C, BOAST::CL, BOAST::CUDA].include?( BOAST::get_lang ) then
33
+ s += (@val2 - @val1 + 1).to_s
34
+ end
35
+ elsif @val1.nil? then
36
+ return nil
37
+ else
38
+ s += @val1.to_s
39
+ end
40
+ return s
41
+ end
42
+ def to_s
43
+ self.to_str
44
+ end
45
+ end
46
+
47
+ class ConstArray < Array
48
+ def initialize(array,type = nil)
49
+ super(array)
50
+ @type = type::new if type
51
+ end
52
+ def to_s
53
+ self.to_str
54
+ end
55
+ def to_str
56
+ return self.to_str_fortran if BOAST::get_lang == BOAST::FORTRAN
57
+ return self.to_str_c if [BOAST::C, BOAST::CL, BOAST::CUDA].include?( BOAST::get_lang )
58
+ end
59
+ def to_str_fortran
60
+ s = ""
61
+ return s if self.first.nil?
62
+ s += "(/ &\n"
63
+ s += self.first.to_s
64
+ s += "_wp" if @type and @type.size == 8
65
+ self[1..-1].each { |v|
66
+ s += ", &\n"+v.to_s
67
+ s += "_wp" if @type and @type.size == 8
68
+ }
69
+ s += " /)"
70
+ end
71
+ def to_str_c
72
+ s = ""
73
+ return s if self.first.nil?
74
+ s += "{\n"
75
+ s += self.first.to_s
76
+ self[1..-1].each { |v|
77
+ s += ",\n"+v.to_s
78
+ }
79
+ s += "}"
80
+ end
81
+ end
82
+
83
+ class Variable
84
+ include BOAST::Arithmetic
85
+
86
+ alias_method :orig_method_missing, :method_missing
87
+
88
+ def method_missing(m, *a, &b)
89
+ return self.struct_reference(type.members[m.to_s]) if type.members[m.to_s]
90
+ # return self.get_element(m.to_s) if type.getters[m.to_s]
91
+ # return self.set_element(m.to_s) if type.setters[m.to_s]
92
+ return self.orig_method_missing(m, *a, &b)
93
+ end
94
+
95
+ def self.parens(*args,&block)
96
+ return self::new(*args,&block)
97
+ end
98
+
99
+ attr_reader :name
100
+ attr_accessor :direction
101
+ attr_accessor :constant
102
+ attr_reader :allocate
103
+ attr_reader :type
104
+ attr_reader :dimension
105
+ attr_reader :local
106
+ attr_reader :texture
107
+ attr_reader :sampler
108
+ attr_reader :restrict
109
+ attr_accessor :replace_constant
110
+ attr_accessor :force_replace_constant
111
+
112
+ def initialize(name,type,hash={})
113
+ @name = name.to_s
114
+ @direction = hash[:direction] ? hash[:direction] : hash[:dir]
115
+ @constant = hash[:constant] ? hash[:constant] : hash[:const]
116
+ @dimension = hash[:dimension] ? hash[:dimension] : hash[:dim]
117
+ @local = hash[:local] ? hash[:local] : hash[:shared]
118
+ @texture = hash[:texture]
119
+ @allocate = hash[:allocate]
120
+ @restrict = hash[:restrict]
121
+ @force_replace_constant = false
122
+ if not hash[:replace_constant].nil? then
123
+ @replace_constant = hash[:replace_constant]
124
+ else
125
+ @replace_constant = true
126
+ end
127
+ if @texture and BOAST::get_lang == BOAST::CL then
128
+ @sampler = Variable::new("sampler_#{name}", BOAST::CustomType,:type_name => "sampler_t" ,:replace_constant => false, :constant => "CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_NONE | CLK_FILTER_NEAREST")
129
+ else
130
+ @sampler = nil
131
+ end
132
+ @type = type::new(hash)
133
+ @hash = hash
134
+ if (@direction == :out or @direction == :inout) and not @dimension then
135
+ @scalar_output = true
136
+ else
137
+ @scalar_output = false
138
+ end
139
+ end
140
+
141
+ def copy(name=nil,options={})
142
+ name = @name if not name
143
+ h = @hash.clone
144
+ options.each { |k,v|
145
+ h[k] = v
146
+ }
147
+ return Variable::new(name, @type.class, h)
148
+ end
149
+
150
+ def Variable.from_type(name, type, options={})
151
+ hash = type.to_hash
152
+ options.each { |k,v|
153
+ hash[k] = v
154
+ }
155
+ hash[:direction] = nil
156
+ hash[:dir] = nil
157
+ return Variable::new(name, type.class, hash)
158
+ end
159
+
160
+ def to_s
161
+ self.to_str
162
+ end
163
+
164
+ def to_str
165
+ if @force_replace_constant or ( @replace_constant and @constant and BOAST::get_replace_constants and not @dimension ) then
166
+ s = @constant.to_s
167
+ s += "_wp" if BOAST::get_lang == BOAST::FORTRAN and @type and @type.size == 8
168
+ return s
169
+ end
170
+ if @scalar_output then
171
+ return "(*#{self.name})"
172
+ end
173
+ return @name
174
+ end
175
+
176
+ def to_var
177
+ return self
178
+ end
179
+
180
+ def set(x)
181
+ return Expression::new(BOAST::Set, self, x)
182
+ end
183
+
184
+ def dereference
185
+ return self.copy("*(#{self.name})", :dimension => nil, :dim => nil, :direction => nil, :dir => nil) if [BOAST::C, BOAST::CL, BOAST::CUDA].include?( BOAST::get_lang )
186
+ return self if BOAST::get_lang == BOAST::FORTRAN
187
+ #return Expression::new("*",nil,self)
188
+ end
189
+
190
+ def struct_reference(x)
191
+ return x.copy(self.name+"."+x.name) if [BOAST::C, BOAST::CL, BOAST::CUDA].include?( BOAST::get_lang )
192
+ return x.copy(self.name+"%"+x.name) if BOAST::get_lang == BOAST::FORTRAN
193
+ end
194
+
195
+ def inc
196
+ return Expression::new("++",self,nil)
197
+ end
198
+
199
+ def [](*args)
200
+ return Index::new(self,args)
201
+ end
202
+
203
+ def indent
204
+ return " "*BOAST::get_indent_level
205
+ end
206
+
207
+ def finalize
208
+ s = ""
209
+ s += ";" if [BOAST::C, BOAST::CL, BOAST::CUDA].include?( BOAST::get_lang )
210
+ s+="\n"
211
+ return s
212
+ end
213
+
214
+ def decl_c(final=true, device=false)
215
+ return decl_texture(final) if @texture
216
+ s = ""
217
+ s += self.indent if final
218
+ s += "const " if @constant or @direction == :in
219
+ s += "__global " if @direction and @dimension and not (@hash[:register] or @hash[:private] or @local) and BOAST::get_lang == BOAST::CL
220
+ s += "__local " if @local and BOAST::get_lang == BOAST::CL
221
+ s += "__shared__ " if @local and not device and BOAST::get_lang == BOAST::CUDA
222
+ s += @type.decl
223
+ if(@dimension and not @constant and not @allocate and (not @local or (@local and device))) then
224
+ s += " *"
225
+ if @restrict then
226
+ if BOAST::get_lang == BOAST::CL
227
+ s += " restrict"
228
+ else
229
+ s += " __restrict__"
230
+ end
231
+ end
232
+ end
233
+ if not @dimension and ( @direction == :out or @direction == :inout ) then
234
+ s += " *"
235
+ end
236
+ s += " #{@name}"
237
+ if @dimension and @constant then
238
+ s += "[]"
239
+ end
240
+ if @dimension and ((@local and not device) or (@allocate and not @constant)) then
241
+ s +="["
242
+ s += @dimension.reverse.join("*")
243
+ s +="]"
244
+ end
245
+ s += " = #{@constant}" if @constant
246
+ s += self.finalize if final
247
+ BOAST::get_output.print s if final
248
+ return s
249
+ end
250
+
251
+ def header(lang=C,final=true)
252
+ return decl_texture(final) if @texture
253
+ s = ""
254
+ s += self.indent if final
255
+ s += "const " if @constant or @direction == :in
256
+ s += "__global " if @direction and @dimension and BOAST::get_lang == BOAST::CL
257
+ s += "__local " if @local and BOAST::get_lang == BOAST::CL
258
+ s += "__shared__ " if @local and BOAST::get_lang == BOAST::CUDA
259
+ s += @type.decl
260
+ if(@dimension and not @constant and not @local) then
261
+ s += " *"
262
+ end
263
+ if not @dimension and ( lang == BOAST::FORTRAN or @direction == :out or @direction == :inout ) then
264
+ s += " *"
265
+ end
266
+ s += " #{@name}"
267
+ if(@dimension and @constant) then
268
+ s += "[]"
269
+ end
270
+ if(@dimension and @local) then
271
+ s +="["
272
+ s += @dimension.reverse.join("*")
273
+ s +="]"
274
+ end
275
+ s += " = #{@constant}" if @constant
276
+ s += self.finalize if final
277
+ BOAST::get_output.print s if final
278
+ return s
279
+ end
280
+
281
+ def decl(final=true,device=false)
282
+ return self.decl_fortran(final) if BOAST::get_lang == BOAST::FORTRAN
283
+ return self.decl_c(final, device) if [BOAST::C, BOAST::CL, BOAST::CUDA].include?( BOAST::get_lang )
284
+ end
285
+
286
+ def decl_texture(final=true)
287
+ raise "Unsupported language #{BOAST::get_lang} for texture!" if not [BOAST::CL, BOAST::CUDA].include?( BOAST::get_lang )
288
+ raise "Write is unsupported for textures!" if not (@constant or @direction == :in)
289
+ dim_number = 1
290
+ if @dimension then
291
+ dim_number == @dimension.size
292
+ end
293
+ raise "Unsupported number of dimension: #{dim_number}!" if dim_number > 3
294
+ s = ""
295
+ s += self.indent if final
296
+ if BOAST::get_lang == BOAST::CL then
297
+ s += "__read_only "
298
+ if dim_number < 3 then
299
+ s += "image2d_t " #from OCL 1.2+ image1d_t is defined
300
+ else
301
+ s += "image3d_t "
302
+ end
303
+ else
304
+ s += "texture<#{@type.decl}, cudaTextureType#{dim_number}D, cudaReadModeElementType> "
305
+ end
306
+ s += @name
307
+ s += self.finalize if final
308
+ BOAST::get_output.print s if final
309
+ return s
310
+ end
311
+
312
+
313
+ def decl_fortran(final=true)
314
+ s = ""
315
+ s += self.indent if final
316
+ s += @type.decl
317
+ s += ", intent(#{@direction})" if @direction
318
+ s += ", parameter" if @constant
319
+ if(@dimension) then
320
+ s += ", dimension("
321
+ dim = @dimension[0].to_str
322
+ if dim then
323
+ s += dim
324
+ @dimension[1..-1].each { |d|
325
+ s += ", "
326
+ s += d
327
+ }
328
+ else
329
+ s += "*"
330
+ end
331
+ s += ")"
332
+ end
333
+ s += " :: #{@name}"
334
+ if @constant
335
+ s += " = #{@constant}"
336
+ s += "_wp" if not @dimension and @type and @type.size == 8
337
+ end
338
+ s += self.finalize if final
339
+ BOAST::get_output.print s if final
340
+ return s
341
+ end
342
+
343
+ end
344
+
345
+ end
@@ -0,0 +1,67 @@
1
+ module BOAST
2
+
3
+ class While
4
+ def self.parens(*args,&block)
5
+ return self::new(*args,&block)
6
+ end
7
+
8
+ attr_reader :condition
9
+ def initialize(condition, &block)
10
+ @condition = condition
11
+ @block = block
12
+ end
13
+ def to_s
14
+ self.to_str
15
+ end
16
+ def to_str
17
+ return self.to_str_fortran if BOAST::get_lang == FORTRAN
18
+ return self.to_str_c if [C, CL, CUDA].include?( BOAST::get_lang )
19
+ end
20
+ def to_str_fortran
21
+ s = ""
22
+ s += "do while( #{@condition} )"
23
+ return s
24
+ end
25
+ def to_str_c
26
+ s = ""
27
+ s += "while(#{@condition}){"
28
+ return s
29
+ end
30
+ def print(*args)
31
+ final = true
32
+ s=""
33
+ s += " "*BOAST::get_indent_level if final
34
+ s += self.to_str
35
+ BOAST::increment_indent_level
36
+ BOAST::get_output.puts s if final
37
+ if @block then
38
+ s += "\n"
39
+ @block.call(*args)
40
+ s += self.close
41
+ end
42
+ return s
43
+ end
44
+ def close(final=true)
45
+ return self.close_fortran(final) if BOAST::get_lang == FORTRAN
46
+ return self.close_c(final) if [C, CL, CUDA].include?( BOAST::get_lang )
47
+ end
48
+ def close_c(final=true)
49
+ s = ""
50
+ BOAST::decrement_indent_level
51
+ s += " "*BOAST::get_indent_level if final
52
+ s += "}"
53
+ BOAST::get_output.puts s if final
54
+ return s
55
+ end
56
+ def close_fortran(final=true)
57
+ s = ""
58
+ BOAST::decrement_indent_level
59
+ s += " "*BOAST::get_indent_level if final
60
+ s += "end do"
61
+ BOAST::get_output.puts s if final
62
+ return s
63
+ end
64
+
65
+ end
66
+
67
+ end
data/lib/BOAST.rb CHANGED
@@ -1,6 +1,17 @@
1
1
  require 'BOAST/Transitions.rb'
2
+ require 'BOAST/Arithmetic.rb'
2
3
  require 'BOAST/Operators.rb'
3
4
  require 'BOAST/DataTypes.rb'
5
+ require 'BOAST/Expression.rb'
6
+ require 'BOAST/Index.rb'
7
+ require 'BOAST/Variable.rb'
8
+ require 'BOAST/FuncCall.rb'
9
+ require 'BOAST/Procedure.rb'
10
+ require 'BOAST/If.rb'
11
+ require 'BOAST/For.rb'
12
+ require 'BOAST/Case.rb'
13
+ require 'BOAST/While.rb'
14
+ require 'BOAST/Pragma.rb'
4
15
  require 'BOAST/Algorithm.rb'
5
16
  require 'BOAST/CKernel.rb'
6
17
  require 'BOAST/Parens.rb'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: BOAST
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.995'
4
+ version: '0.996'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-06-30 00:00:00.000000000 Z
12
+ date: 2014-07-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: narray
@@ -76,6 +76,17 @@ files:
76
76
  - lib/BOAST/Parens.rb
77
77
  - lib/BOAST/Operators.rb
78
78
  - lib/BOAST/DataTypes.rb
79
+ - lib/BOAST/Arithmetic.rb
80
+ - lib/BOAST/Expression.rb
81
+ - lib/BOAST/Index.rb
82
+ - lib/BOAST/Variable.rb
83
+ - lib/BOAST/Procedure.rb
84
+ - lib/BOAST/If.rb
85
+ - lib/BOAST/For.rb
86
+ - lib/BOAST/Case.rb
87
+ - lib/BOAST/While.rb
88
+ - lib/BOAST/FuncCall.rb
89
+ - lib/BOAST/Pragma.rb
79
90
  homepage: https://forge.imag.fr/projects/boast/
80
91
  licenses:
81
92
  - BSD