BOAST 0.1
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.
- data/BOAST.gemspec +16 -0
- data/LICENSE +22 -0
- data/lib/BOAST.rb +3 -0
- data/lib/BOAST/Algorithm.rb +1759 -0
- data/lib/BOAST/BOAST_OpenCL.rb +104 -0
- data/lib/BOAST/CKernel.rb +545 -0
- metadata +100 -0
data/BOAST.gemspec
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'BOAST'
|
3
|
+
s.version = "0.1"
|
4
|
+
s.author = "Brice Videau"
|
5
|
+
s.email = "brice.videau@imag.fr"
|
6
|
+
s.homepage = "https://forge.imag.fr/projects/boast/"
|
7
|
+
s.summary = "BOAST is a computing kernel metaprogramming tool."
|
8
|
+
s.description = "BOAST aims at providing a framework to metaprogram, benchmark and validate computing kernels"
|
9
|
+
s.files = %w( BOAST.gemspec LICENSE lib/BOAST.rb lib/BOAST/Algorithm.rb lib/BOAST/CKernel.rb lib/BOAST/BOAST_OpenCL.rb )
|
10
|
+
s.has_rdoc = true
|
11
|
+
s.license = 'BSD'
|
12
|
+
s.required_ruby_version = '>= 1.9.3'
|
13
|
+
s.add_dependency 'narray', '>=0.6.0.8'
|
14
|
+
s.add_dependency 'opencl_ruby_ffi', '>=0.4'
|
15
|
+
s.add_dependency 'systemu', '>=2.2.0'
|
16
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012, Brice Videau <brice.videau@imag.fr>
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
8
|
+
list of conditions and the following disclaimer.
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
10
|
+
this list of conditions and the following disclaimer in the documentation
|
11
|
+
and/or other materials provided with the distribution.
|
12
|
+
|
13
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
14
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
15
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
16
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
17
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
18
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
19
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
20
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
21
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
22
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/lib/BOAST.rb
ADDED
@@ -0,0 +1,1759 @@
|
|
1
|
+
class Object
|
2
|
+
alias_method :orig_method_missing, :method_missing
|
3
|
+
|
4
|
+
def method_missing(m, *a, &b)
|
5
|
+
s=nil
|
6
|
+
klass = begin
|
7
|
+
s = (self.is_a?(Module) ? self : self.class)
|
8
|
+
s.const_get(m)
|
9
|
+
rescue NameError
|
10
|
+
end
|
11
|
+
|
12
|
+
return klass.send(:parens, *a, &b) if klass.respond_to? :parens
|
13
|
+
|
14
|
+
return BOAST::FuncCall::new(m,*a,&b) if s == BOAST
|
15
|
+
|
16
|
+
orig_method_missing m, *a, &b
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module BOAST
|
21
|
+
|
22
|
+
FORTRAN = 1
|
23
|
+
C = 2
|
24
|
+
CL = 3
|
25
|
+
CUDA = 4
|
26
|
+
@@output = STDOUT
|
27
|
+
@@lang = FORTRAN
|
28
|
+
@@replace_constants = true
|
29
|
+
@@default_int_size = 4
|
30
|
+
@@default_int_signed = true
|
31
|
+
@@default_real_size = 8
|
32
|
+
@@indent_level = 0
|
33
|
+
@@indent_increment = 2
|
34
|
+
@@array_start = 1
|
35
|
+
@@chain_code = false
|
36
|
+
|
37
|
+
@@env = Hash.new{|h, k| h[k] = []}
|
38
|
+
|
39
|
+
|
40
|
+
def BOAST::push_env(vars = {})
|
41
|
+
vars.each { |key,value|
|
42
|
+
var = nil
|
43
|
+
begin
|
44
|
+
var = BOAST::class_variable_get("@@"+key.to_s)
|
45
|
+
rescue
|
46
|
+
raise "Unknown module variable #{key}!"
|
47
|
+
end
|
48
|
+
@@env[key].push(var)
|
49
|
+
BOAST::class_variable_set("@@"+key.to_s, value)
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def BOAST::pop_env(*vars)
|
54
|
+
vars.each { |key|
|
55
|
+
raise "Unknown module variable #{key}!" unless @@env.has_key?(key)
|
56
|
+
ret = @@env[key].pop
|
57
|
+
raise "No stored value for #{key}!" if ret.nil?
|
58
|
+
BOAST::class_variable_set("@@"+key.to_s, ret)
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
def BOAST::print(a)
|
63
|
+
a.print
|
64
|
+
end
|
65
|
+
|
66
|
+
def BOAST::decl(*a)
|
67
|
+
a.each { |d|
|
68
|
+
d.decl
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def BOAST::close(a)
|
73
|
+
a.close
|
74
|
+
end
|
75
|
+
|
76
|
+
def BOAST::set_indent_level(level)
|
77
|
+
@@indent_level = level
|
78
|
+
end
|
79
|
+
|
80
|
+
def BOAST::get_indent_level
|
81
|
+
return @@indent_level
|
82
|
+
end
|
83
|
+
|
84
|
+
def BOAST::get_indent_increment
|
85
|
+
return @@indent_increment
|
86
|
+
end
|
87
|
+
|
88
|
+
def BOAST::increment_indent_level(increment = @@indent_increment)
|
89
|
+
@@indent_level += increment
|
90
|
+
end
|
91
|
+
|
92
|
+
def BOAST::decrement_indent_level(increment = @@indent_increment)
|
93
|
+
@@indent_level -= increment
|
94
|
+
end
|
95
|
+
|
96
|
+
def BOAST::set_replace_constants(replace_constants)
|
97
|
+
@@replace_constants = replace_constants
|
98
|
+
end
|
99
|
+
|
100
|
+
def BOAST::get_replace_constants
|
101
|
+
return @@replace_constants
|
102
|
+
end
|
103
|
+
|
104
|
+
def BOAST::set_default_int_signed(signed)
|
105
|
+
@@default_int_signed = signed
|
106
|
+
end
|
107
|
+
|
108
|
+
def BOAST::get_default_int_signed
|
109
|
+
return @@default_int_signed
|
110
|
+
end
|
111
|
+
|
112
|
+
def BOAST::set_default_int_size(size)
|
113
|
+
@@default_int_size = size
|
114
|
+
end
|
115
|
+
|
116
|
+
def BOAST::get_default_int_size
|
117
|
+
return @@default_int_size
|
118
|
+
end
|
119
|
+
|
120
|
+
def BOAST::set_default_real_size(size)
|
121
|
+
@@default_real_size = size
|
122
|
+
end
|
123
|
+
|
124
|
+
def BOAST::get_default_real_size
|
125
|
+
return @@default_real_size
|
126
|
+
end
|
127
|
+
|
128
|
+
def BOAST::set_lang(lang)
|
129
|
+
@@lang = lang
|
130
|
+
end
|
131
|
+
|
132
|
+
def BOAST::get_lang
|
133
|
+
return @@lang
|
134
|
+
end
|
135
|
+
|
136
|
+
def BOAST::set_output(output)
|
137
|
+
@@output = output
|
138
|
+
end
|
139
|
+
|
140
|
+
def BOAST::get_output
|
141
|
+
return @@output
|
142
|
+
end
|
143
|
+
|
144
|
+
def BOAST::set_chain_code(chain_code)
|
145
|
+
@@chain_code = chain_code
|
146
|
+
end
|
147
|
+
|
148
|
+
def BOAST::get_chain_code
|
149
|
+
return @@chain_code
|
150
|
+
end
|
151
|
+
|
152
|
+
def BOAST::set_array_start(array_start)
|
153
|
+
@@array_start = array_start
|
154
|
+
end
|
155
|
+
|
156
|
+
def BOAST::get_array_start
|
157
|
+
return @@array_start
|
158
|
+
end
|
159
|
+
|
160
|
+
class Pragma
|
161
|
+
def self.parens(*args,&block)
|
162
|
+
return self::new(*args,&block)
|
163
|
+
end
|
164
|
+
|
165
|
+
attr_reader :name
|
166
|
+
attr_reader :options
|
167
|
+
|
168
|
+
def initialize(name, options)
|
169
|
+
@name = name
|
170
|
+
@options = options
|
171
|
+
end
|
172
|
+
|
173
|
+
def to_s
|
174
|
+
self.to_str
|
175
|
+
end
|
176
|
+
|
177
|
+
def to_str
|
178
|
+
s = ""
|
179
|
+
if BOAST::get_lang == FORTRAN then
|
180
|
+
s += "$!"
|
181
|
+
else
|
182
|
+
s += "#pragma"
|
183
|
+
end
|
184
|
+
@options.each{ |opt|
|
185
|
+
s += " #{opt}"
|
186
|
+
}
|
187
|
+
return s
|
188
|
+
end
|
189
|
+
|
190
|
+
def print(final = true)
|
191
|
+
s=""
|
192
|
+
s += self.to_str
|
193
|
+
BOAST::get_output.puts s if final
|
194
|
+
return s
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def BOAST::Return(value)
|
199
|
+
return Expression("return",nil, value)
|
200
|
+
end
|
201
|
+
|
202
|
+
class Expression
|
203
|
+
def self.parens(*args,&block)
|
204
|
+
return self::new(*args,&block)
|
205
|
+
end
|
206
|
+
|
207
|
+
attr_reader :operator
|
208
|
+
attr_reader :operand1
|
209
|
+
attr_reader :operand2
|
210
|
+
def initialize(operator, operand1, operand2)
|
211
|
+
@operator = operator
|
212
|
+
@operand1 = operand1
|
213
|
+
@operand2 = operand2
|
214
|
+
end
|
215
|
+
def to_s
|
216
|
+
self.to_str
|
217
|
+
end
|
218
|
+
|
219
|
+
def ===(x)
|
220
|
+
return Expression::new("=",self,x)
|
221
|
+
end
|
222
|
+
|
223
|
+
def ==(x)
|
224
|
+
return Expression::new("==",self,x)
|
225
|
+
end
|
226
|
+
|
227
|
+
def +(x)
|
228
|
+
return Expression::new("+",self,x)
|
229
|
+
end
|
230
|
+
|
231
|
+
def >(x)
|
232
|
+
return Expression::new(">",self,x)
|
233
|
+
end
|
234
|
+
|
235
|
+
def <(x)
|
236
|
+
return Expression::new("<",self,x)
|
237
|
+
end
|
238
|
+
|
239
|
+
def >=(x)
|
240
|
+
return Expression::new(">=",self,x)
|
241
|
+
end
|
242
|
+
|
243
|
+
def *(x)
|
244
|
+
return Expression::new("*",self,x)
|
245
|
+
end
|
246
|
+
|
247
|
+
def /(x)
|
248
|
+
return Expression::new("/",self,x)
|
249
|
+
end
|
250
|
+
|
251
|
+
def dereference
|
252
|
+
return Expression::new("*",nil,self)
|
253
|
+
end
|
254
|
+
|
255
|
+
def struct_reference(x)
|
256
|
+
return Expression::new(".",self,x)
|
257
|
+
end
|
258
|
+
|
259
|
+
def -(x)
|
260
|
+
return Expression::new("-",self,x)
|
261
|
+
end
|
262
|
+
|
263
|
+
def !
|
264
|
+
return Expression::new("!",nil,self)
|
265
|
+
end
|
266
|
+
|
267
|
+
def -@
|
268
|
+
return Expression::new("-",nil,self)
|
269
|
+
end
|
270
|
+
|
271
|
+
def to_str
|
272
|
+
s = ""
|
273
|
+
if @operand1 then
|
274
|
+
s += "(" if (@operator == "*" or @operator == "/")
|
275
|
+
s += @operand1.to_s
|
276
|
+
s += ")" if (@operator == "*" or @operator == "/")
|
277
|
+
end
|
278
|
+
s += " " unless @operator.to_s == "++" or @operator.to_s == "."
|
279
|
+
s += @operator.to_s
|
280
|
+
s += " " unless @operator.to_s == "." or @operator.to_s == "&" or ( @operator.to_s == "*" and @operand1.nil? )
|
281
|
+
if @operand2 then
|
282
|
+
s += "(" if (@operator == "*" or @operator == "/" or @operator == "-")
|
283
|
+
s += @operand2.to_s
|
284
|
+
s += ")" if (@operator == "*" or @operator == "/" or @operator == "-")
|
285
|
+
end
|
286
|
+
return s
|
287
|
+
end
|
288
|
+
def print(final=true)
|
289
|
+
s=""
|
290
|
+
s += " "*BOAST::get_indent_level if final
|
291
|
+
s += self.to_str
|
292
|
+
s += ";" if final and [C, CL, CUDA].include?( BOAST::get_lang )
|
293
|
+
BOAST::get_output.puts s if final
|
294
|
+
return s
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
class Mult < Expression
|
299
|
+
def initialize(operand1, operand2)
|
300
|
+
super("*", operand1, operand2)
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
class Add < Expression
|
305
|
+
def initialize(operand1, operand2)
|
306
|
+
super("+", operand1, operand2)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
class Affect < Expression
|
311
|
+
def initialize(operand1, operand2)
|
312
|
+
super("=", operand1, operand2)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
class Index < Expression
|
317
|
+
attr_reader :source
|
318
|
+
attr_reader :indexes
|
319
|
+
def initialize(source, indexes)
|
320
|
+
@source = source
|
321
|
+
@indexes = indexes
|
322
|
+
end
|
323
|
+
def to_s
|
324
|
+
self.to_str
|
325
|
+
end
|
326
|
+
def to_str
|
327
|
+
return self.to_str_fortran if BOAST::get_lang == FORTRAN
|
328
|
+
return self.to_str_c if [C, CL, CUDA].include?( BOAST::get_lang )
|
329
|
+
end
|
330
|
+
def to_str_fortran
|
331
|
+
s = ""
|
332
|
+
s += "#{@source}(#{@indexes.join(", ")})"
|
333
|
+
return s
|
334
|
+
end
|
335
|
+
def to_str_texture
|
336
|
+
raise "Unsupported language #{BOAST::get_lang} for texture!" if not [CL, CUDA].include?( BOAST::get_lang )
|
337
|
+
raise "Write is unsupported for textures!" if not ( @source.constant or @source.direction == :in )
|
338
|
+
dim_number = 1
|
339
|
+
if @source.dimension then
|
340
|
+
dim_number == @source.dimension.size
|
341
|
+
end
|
342
|
+
raise "Unsupported number of dimension: #{dim_number}!" if dim_number > 3
|
343
|
+
s = ""
|
344
|
+
if BOAST::get_lang == CL then
|
345
|
+
s += "as_#{@source.type.decl}("
|
346
|
+
s += "read_imageui(#{@source}, #{@source.sampler}, "
|
347
|
+
if dim_number == 1 then
|
348
|
+
s += "int2(#{@indexes[0]},0)"
|
349
|
+
else
|
350
|
+
if dim_number == 2 then
|
351
|
+
s += "int2("
|
352
|
+
else
|
353
|
+
s += "int3("
|
354
|
+
end
|
355
|
+
s += "#{@indexes.join(", ")})"
|
356
|
+
end
|
357
|
+
s += ")"
|
358
|
+
if @source.type.size == 4 then
|
359
|
+
s += ".x"
|
360
|
+
elsif @source.type.size == 8 then
|
361
|
+
s += ".xy"
|
362
|
+
end
|
363
|
+
s += ")"
|
364
|
+
else
|
365
|
+
s += "tex#{dim_number}Dfetch(#{@source},"
|
366
|
+
if dim_number == 1 then
|
367
|
+
s += "#{@indexes[0]}"
|
368
|
+
else
|
369
|
+
if dim_number == 2 then
|
370
|
+
s += "int2("
|
371
|
+
else
|
372
|
+
s += "int3("
|
373
|
+
end
|
374
|
+
s += "#{@indexes.join(", ")})"
|
375
|
+
end
|
376
|
+
s += ")"
|
377
|
+
end
|
378
|
+
return s
|
379
|
+
end
|
380
|
+
def to_str_c
|
381
|
+
return to_str_texture if @source.texture
|
382
|
+
dim = @source.dimension.first
|
383
|
+
if dim.val2 then
|
384
|
+
start = dim.val1
|
385
|
+
else
|
386
|
+
start = BOAST::get_array_start
|
387
|
+
end
|
388
|
+
sub = "#{@indexes.first} - #{start}"
|
389
|
+
i=1
|
390
|
+
ss = ""
|
391
|
+
@source.dimension[0..-2].each{ |d|
|
392
|
+
if d.size then
|
393
|
+
ss += " * (#{d.size})"
|
394
|
+
elsif d.val2 then
|
395
|
+
ss += " * (#{d.val2} - (#{d.val1}) + 1)"
|
396
|
+
else
|
397
|
+
raise "Unkwown dimension size!"
|
398
|
+
end
|
399
|
+
dim = @source.dimension[i]
|
400
|
+
if dim.val2 then
|
401
|
+
start = dim.val1
|
402
|
+
else
|
403
|
+
start = BOAST::get_array_start
|
404
|
+
end
|
405
|
+
sub += " + (#{@indexes[i]} - (#{start}))"+ss
|
406
|
+
i+=1
|
407
|
+
}
|
408
|
+
if BOAST::get_replace_constants then
|
409
|
+
begin
|
410
|
+
# puts sub
|
411
|
+
indx = eval(sub)
|
412
|
+
indx = indx.to_i
|
413
|
+
# puts indx
|
414
|
+
return "#{@source.constant[indx]}"
|
415
|
+
rescue Exception => e
|
416
|
+
end
|
417
|
+
end
|
418
|
+
s = "#{@source}[" + sub + "]"
|
419
|
+
return s
|
420
|
+
end
|
421
|
+
def print(final=true)
|
422
|
+
s=""
|
423
|
+
s += " "*BOAST::get_indent_level if final
|
424
|
+
s += self.to_str
|
425
|
+
s += ";" if final and [C, CL, CUDA].include?( BOAST::get_lang )
|
426
|
+
BOAST::get_output.puts s if final
|
427
|
+
return s
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
class CStruct
|
432
|
+
attr_reader :name, :members, :members_array
|
433
|
+
def self.parens(*args,&block)
|
434
|
+
return Variable::new(args[0], self, *args[1..-1], &block)
|
435
|
+
end
|
436
|
+
|
437
|
+
def initialize(hash={})
|
438
|
+
@name = hash[:type_name]
|
439
|
+
@members = {}
|
440
|
+
@members_array = []
|
441
|
+
hash[:members].each { |m|
|
442
|
+
mc = m.copy
|
443
|
+
@members_array.push(mc)
|
444
|
+
@members[mc.name] = mc
|
445
|
+
}
|
446
|
+
end
|
447
|
+
|
448
|
+
def decl
|
449
|
+
return "struct #{@name}" if [C, CL, CUDA].include?( BOAST::get_lang )
|
450
|
+
return "TYPE(#{@name})" if BOAST::get_lang == FORTRAN
|
451
|
+
end
|
452
|
+
|
453
|
+
def finalize
|
454
|
+
s = ""
|
455
|
+
s += ";" if [C, CL, CUDA].include?( BOAST::get_lang )
|
456
|
+
s+="\n"
|
457
|
+
return s
|
458
|
+
end
|
459
|
+
|
460
|
+
def indent
|
461
|
+
return " "*BOAST::get_indent_level
|
462
|
+
end
|
463
|
+
|
464
|
+
def header
|
465
|
+
return header_c if [C, CL, CUDA].include?( BOAST::get_lang )
|
466
|
+
return header_fortran if BOAST::get_lang == FORTRAN
|
467
|
+
raise "Unsupported language!"
|
468
|
+
end
|
469
|
+
|
470
|
+
def header_c(final = true)
|
471
|
+
s = ""
|
472
|
+
s += self.indent if final
|
473
|
+
s += self.decl + " {\n"
|
474
|
+
@members_array.each { |value|
|
475
|
+
s+= self.indent if final
|
476
|
+
s+= " "*BOAST::get_indent_increment + value.decl(false)+";\n"
|
477
|
+
}
|
478
|
+
s += self.indent if final
|
479
|
+
s += "}"
|
480
|
+
s += self.finalize if final
|
481
|
+
BOAST::get_output.print s if final
|
482
|
+
return s
|
483
|
+
end
|
484
|
+
|
485
|
+
def header_fortran(final = true)
|
486
|
+
s = ""
|
487
|
+
s += self.indent if final
|
488
|
+
s += "TYPE :: #{@name}\n"
|
489
|
+
members_array.each { |value|
|
490
|
+
s+= self.indent if final
|
491
|
+
s+= " "*BOAST::get_indent_increment + value.decl(false)+"\n"
|
492
|
+
}
|
493
|
+
s += self.indent if final
|
494
|
+
s += "END TYPE #{@name}"
|
495
|
+
s += self.finalize if final
|
496
|
+
BOAST::get_output.print s if final
|
497
|
+
return s
|
498
|
+
end
|
499
|
+
|
500
|
+
end
|
501
|
+
class CustomType
|
502
|
+
attr_reader :size, :name, :vector_length
|
503
|
+
def initialize(hash={})
|
504
|
+
@name = hash[:type_name]
|
505
|
+
@size = hash[:size]
|
506
|
+
@vector_length = hash[:vector_length]
|
507
|
+
end
|
508
|
+
def decl
|
509
|
+
return "#{@name}" if [C, CL, CUDA].include?( BOAST::get_lang )
|
510
|
+
end
|
511
|
+
end
|
512
|
+
|
513
|
+
|
514
|
+
class Variable
|
515
|
+
alias_method :orig_method_missing, :method_missing
|
516
|
+
|
517
|
+
def method_missing(m, *a, &b)
|
518
|
+
return self.struct_reference(type.members[m.to_s]) if type.members[m.to_s]
|
519
|
+
return self.orig_method_missing(m, *a, &b)
|
520
|
+
end
|
521
|
+
|
522
|
+
def self.parens(*args,&block)
|
523
|
+
return self::new(*args,&block)
|
524
|
+
end
|
525
|
+
|
526
|
+
attr_reader :name
|
527
|
+
attr_accessor :direction
|
528
|
+
attr_accessor :constant
|
529
|
+
attr_reader :allocate
|
530
|
+
attr_reader :type
|
531
|
+
attr_reader :dimension
|
532
|
+
attr_reader :local
|
533
|
+
attr_reader :texture
|
534
|
+
attr_reader :sampler
|
535
|
+
attr_reader :replace_constant
|
536
|
+
attr_accessor :force_replace_constant
|
537
|
+
|
538
|
+
def initialize(name,type,hash={})
|
539
|
+
@name = name
|
540
|
+
@direction = hash[:direction] ? hash[:direction] : hash[:dir]
|
541
|
+
@constant = hash[:constant] ? hash[:constant] : hash[:const]
|
542
|
+
@dimension = hash[:dimension] ? hash[:dimension] : hash[:dim]
|
543
|
+
@local = hash[:local] ? hash[:local] : hash[:shared]
|
544
|
+
@texture = hash[:texture]
|
545
|
+
@allocate = hash[:allocate]
|
546
|
+
@force_replace_constant = false
|
547
|
+
if not hash[:replace_constant].nil? then
|
548
|
+
@replace_constant = hash[:replace_constant]
|
549
|
+
else
|
550
|
+
@replace_constant = true
|
551
|
+
end
|
552
|
+
if @texture and BOAST::get_lang == CL then
|
553
|
+
@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")
|
554
|
+
else
|
555
|
+
@sampler = nil
|
556
|
+
end
|
557
|
+
@type = type::new(hash)
|
558
|
+
@hash = hash
|
559
|
+
end
|
560
|
+
|
561
|
+
def copy(name=@name)
|
562
|
+
return Variable::new(name, @type.class, @hash)
|
563
|
+
end
|
564
|
+
|
565
|
+
def to_s
|
566
|
+
self.to_str
|
567
|
+
end
|
568
|
+
|
569
|
+
def to_str
|
570
|
+
if @force_replace_constant or ( @replace_constant and @constant and BOAST::get_replace_constants and not @dimension ) then
|
571
|
+
s = @constant.to_s
|
572
|
+
s += "_wp" if BOAST::get_lang == FORTRAN and @type and @type.size == 8
|
573
|
+
return s
|
574
|
+
end
|
575
|
+
return @name.to_str
|
576
|
+
end
|
577
|
+
|
578
|
+
def ===(x)
|
579
|
+
return Expression::new("=",self,x)
|
580
|
+
end
|
581
|
+
|
582
|
+
def ==(x)
|
583
|
+
return Expression::new("==",self,x)
|
584
|
+
end
|
585
|
+
|
586
|
+
def >(x)
|
587
|
+
return Expression::new(">",self,x)
|
588
|
+
end
|
589
|
+
|
590
|
+
def <(x)
|
591
|
+
return Expression::new("<",self,x)
|
592
|
+
end
|
593
|
+
|
594
|
+
def >=(x)
|
595
|
+
return Expression::new(">=",self,x)
|
596
|
+
end
|
597
|
+
|
598
|
+
def +(x)
|
599
|
+
return Expression::new("+",self,x)
|
600
|
+
end
|
601
|
+
|
602
|
+
def *(x)
|
603
|
+
return Expression::new("*",self,x)
|
604
|
+
end
|
605
|
+
|
606
|
+
def /(x)
|
607
|
+
return Expression::new("/",self,x)
|
608
|
+
end
|
609
|
+
|
610
|
+
def -(x)
|
611
|
+
return Expression::new("-",self,x)
|
612
|
+
end
|
613
|
+
|
614
|
+
def !
|
615
|
+
return Expression::new("!",nil,self)
|
616
|
+
end
|
617
|
+
|
618
|
+
def -@
|
619
|
+
return Expression::new("-",nil,self)
|
620
|
+
end
|
621
|
+
|
622
|
+
def address
|
623
|
+
return Expression::new("&",nil,self)
|
624
|
+
end
|
625
|
+
|
626
|
+
def dereference
|
627
|
+
return Expression::new("*",nil,self)
|
628
|
+
end
|
629
|
+
|
630
|
+
def struct_reference(x)
|
631
|
+
return x.copy(self.name+"."+x.name) if [C, CL, CUDA].include?( BOAST::get_lang )
|
632
|
+
return x.copy(self.name+"%"+x.name) if BOAST::get_lang == FORTRAN
|
633
|
+
end
|
634
|
+
|
635
|
+
def inc
|
636
|
+
return Expression::new("++",self,nil)
|
637
|
+
end
|
638
|
+
|
639
|
+
def [](*args)
|
640
|
+
return Index::new(self,args)
|
641
|
+
end
|
642
|
+
|
643
|
+
def indent
|
644
|
+
return " "*BOAST::get_indent_level
|
645
|
+
end
|
646
|
+
|
647
|
+
def finalize
|
648
|
+
s = ""
|
649
|
+
s += ";" if [C, CL, CUDA].include?( BOAST::get_lang )
|
650
|
+
s+="\n"
|
651
|
+
return s
|
652
|
+
end
|
653
|
+
|
654
|
+
def decl_c(final=true, device=false)
|
655
|
+
return decl_texture(final) if @texture
|
656
|
+
s = ""
|
657
|
+
s += self.indent if final
|
658
|
+
s += "const " if @constant or @direction == :in
|
659
|
+
s += "__global " if @direction and @dimension and not (@hash[:register] or @hash[:private] or @local) and BOAST::get_lang == CL
|
660
|
+
s += "__local " if @local and BOAST::get_lang == CL
|
661
|
+
s += "__shared__ " if @local and not device and BOAST::get_lang == CUDA
|
662
|
+
s += @type.decl
|
663
|
+
if(@dimension and not @constant and not @allocate and (not @local or (@local and device))) then
|
664
|
+
s += " *"
|
665
|
+
end
|
666
|
+
s += " #{@name}"
|
667
|
+
if @dimension and @constant then
|
668
|
+
s += "[]"
|
669
|
+
end
|
670
|
+
if @dimension and ((@local and not device) or (@allocate and not @constant)) then
|
671
|
+
s +="["
|
672
|
+
s += @dimension.reverse.join("*")
|
673
|
+
s +="]"
|
674
|
+
end
|
675
|
+
s += " = #{@constant}" if @constant
|
676
|
+
s += self.finalize if final
|
677
|
+
BOAST::get_output.print s if final
|
678
|
+
return s
|
679
|
+
end
|
680
|
+
|
681
|
+
def header(lang=C,final=true)
|
682
|
+
return decl_texture(final) if @texture
|
683
|
+
s = ""
|
684
|
+
s += self.indent if final
|
685
|
+
s += "const " if @constant or @direction == :in
|
686
|
+
s += "__global " if @direction and @dimension and BOAST::get_lang == CL
|
687
|
+
s += "__local " if @local and BOAST::get_lang == CL
|
688
|
+
s += "__shared__ " if @local and BOAST::get_lang == CUDA
|
689
|
+
s += @type.decl
|
690
|
+
if(@dimension and not @constant and not @local) then
|
691
|
+
s += " *"
|
692
|
+
end
|
693
|
+
if not @dimension and lang == FORTRAN then
|
694
|
+
s += " *"
|
695
|
+
end
|
696
|
+
s += " #{@name}"
|
697
|
+
if(@dimension and @constant) then
|
698
|
+
s += "[]"
|
699
|
+
end
|
700
|
+
if(@dimension and @local) then
|
701
|
+
s +="["
|
702
|
+
s += @dimension.reverse.join("*")
|
703
|
+
s +="]"
|
704
|
+
end
|
705
|
+
s += " = #{@constant}" if @constant
|
706
|
+
s += self.finalize if final
|
707
|
+
BOAST::get_output.print s if final
|
708
|
+
return s
|
709
|
+
end
|
710
|
+
|
711
|
+
def decl(final=true,device=false)
|
712
|
+
return self.decl_fortran(final) if BOAST::get_lang == FORTRAN
|
713
|
+
return self.decl_c(final, device) if [C, CL, CUDA].include?( BOAST::get_lang )
|
714
|
+
end
|
715
|
+
|
716
|
+
def decl_texture(final=true)
|
717
|
+
raise "Unsupported language #{BOAST::get_lang} for texture!" if not [CL, CUDA].include?( BOAST::get_lang )
|
718
|
+
raise "Write is unsupported for textures!" if not (@constant or @direction == :in)
|
719
|
+
dim_number = 1
|
720
|
+
if @dimension then
|
721
|
+
dim_number == @dimension.size
|
722
|
+
end
|
723
|
+
raise "Unsupported number of dimension: #{dim_number}!" if dim_number > 3
|
724
|
+
s = ""
|
725
|
+
s += self.indent if final
|
726
|
+
if BOAST::get_lang == CL then
|
727
|
+
s += "__read_only "
|
728
|
+
if dim_number < 3 then
|
729
|
+
s += "image2d_t " #from OCL 1.2+ image1d_t is defined
|
730
|
+
else
|
731
|
+
s += "image3d_t "
|
732
|
+
end
|
733
|
+
else
|
734
|
+
s += "texture<#{@type.decl}, cudaTextureType#{dim_number}D, cudaReadModeElementType> "
|
735
|
+
end
|
736
|
+
s += @name
|
737
|
+
s += self.finalize if final
|
738
|
+
BOAST::get_output.print s if final
|
739
|
+
return s
|
740
|
+
end
|
741
|
+
|
742
|
+
|
743
|
+
def decl_fortran(final=true)
|
744
|
+
s = ""
|
745
|
+
s += self.indent if final
|
746
|
+
s += @type.decl
|
747
|
+
s += ", intent(#{@direction})" if @direction
|
748
|
+
s += ", parameter" if @constant
|
749
|
+
if(@dimension) then
|
750
|
+
s += ", dimension("
|
751
|
+
dim = @dimension[0].to_str
|
752
|
+
if dim then
|
753
|
+
s += dim
|
754
|
+
@dimension[1..-1].each { |d|
|
755
|
+
s += ", "
|
756
|
+
s += d
|
757
|
+
}
|
758
|
+
else
|
759
|
+
s += ":"
|
760
|
+
end
|
761
|
+
s += ")"
|
762
|
+
end
|
763
|
+
s += " :: #{@name}"
|
764
|
+
if @constant
|
765
|
+
s += " = #{@constant}"
|
766
|
+
s += "_wp" if not @dimension and @type and @type.size == 8
|
767
|
+
end
|
768
|
+
s += self.finalize if final
|
769
|
+
BOAST::get_output.print s if final
|
770
|
+
return s
|
771
|
+
end
|
772
|
+
|
773
|
+
end
|
774
|
+
|
775
|
+
|
776
|
+
|
777
|
+
class Real
|
778
|
+
def self.parens(*args,&block)
|
779
|
+
return Variable::new(args[0], self, *args[1..-1], &block)
|
780
|
+
end
|
781
|
+
|
782
|
+
attr_reader :size
|
783
|
+
def initialize(hash={})
|
784
|
+
if hash[:size] then
|
785
|
+
@size = hash[:size]
|
786
|
+
else
|
787
|
+
@size = BOAST::get_default_real_size
|
788
|
+
end
|
789
|
+
if hash[:vector_length] and hash[:vector_length] > 1 then
|
790
|
+
@vector_length = hash[:vector_length]
|
791
|
+
else
|
792
|
+
@vector_length = 1
|
793
|
+
end
|
794
|
+
end
|
795
|
+
def decl
|
796
|
+
return "real(kind=#{@size})" if BOAST::get_lang == FORTRAN
|
797
|
+
if [C, CL, CUDA].include?( BOAST::get_lang ) and @vector_length == 1 then
|
798
|
+
return "float" if @size == 4
|
799
|
+
return "double" if @size == 8
|
800
|
+
elsif [CL, CUDA].include?(BOAST::get_lang) and @vector_length > 1 then
|
801
|
+
return "float#{@vector_length}" if @size == 4
|
802
|
+
return "double#{@vector_length}" if @size == 8
|
803
|
+
end
|
804
|
+
end
|
805
|
+
end
|
806
|
+
|
807
|
+
class CodeBlock
|
808
|
+
def initialize(&block)
|
809
|
+
@block = block
|
810
|
+
end
|
811
|
+
|
812
|
+
def print(final=true)
|
813
|
+
s=""
|
814
|
+
s += " "*BOAST::get_indent_level if final
|
815
|
+
BOAST::increment_indent_level
|
816
|
+
BOAST::get_output.puts s if final
|
817
|
+
if @block then
|
818
|
+
s += "\n"
|
819
|
+
@block.call
|
820
|
+
end
|
821
|
+
return s
|
822
|
+
end
|
823
|
+
end
|
824
|
+
|
825
|
+
class Procedure
|
826
|
+
def self.parens(*args,&block)
|
827
|
+
return self::new(*args,&block)
|
828
|
+
end
|
829
|
+
|
830
|
+
attr_reader :name
|
831
|
+
attr_reader :parameters
|
832
|
+
attr_reader :constants
|
833
|
+
attr_reader :properties
|
834
|
+
attr_reader :headers
|
835
|
+
def initialize(name, parameters=[], constants=[], properties={}, &block)
|
836
|
+
@name = name
|
837
|
+
@parameters = parameters
|
838
|
+
@constants = constants
|
839
|
+
@block = block
|
840
|
+
@properties = properties
|
841
|
+
@headers = properties[:headers]
|
842
|
+
@headers = [] if not @headers
|
843
|
+
end
|
844
|
+
|
845
|
+
def header(lang=C,final=true)
|
846
|
+
s = ""
|
847
|
+
headers.each { |h|
|
848
|
+
s += "#include <#{h}>\n"
|
849
|
+
}
|
850
|
+
if BOAST::get_lang == CL then
|
851
|
+
s += "__kernel "
|
852
|
+
wgs = @properties[:reqd_work_group_size]
|
853
|
+
if wgs then
|
854
|
+
s += "__attribute__((reqd_work_group_size(#{wgs[0]},#{wgs[1]},#{wgs[2]}))) "
|
855
|
+
end
|
856
|
+
end
|
857
|
+
trailer = ""
|
858
|
+
trailer += "_" if lang == FORTRAN
|
859
|
+
trailer += "_wrapper" if lang == CUDA
|
860
|
+
if @properties[:return] then
|
861
|
+
s += "#{@properties[:return].type.decl} "
|
862
|
+
elsif lang == CUDA
|
863
|
+
s += "unsigned long long int "
|
864
|
+
else
|
865
|
+
s += "void "
|
866
|
+
end
|
867
|
+
s += "#{@name}#{trailer}("
|
868
|
+
if parameters.first then
|
869
|
+
s += parameters.first.header(lang,false)
|
870
|
+
parameters[1..-1].each { |p|
|
871
|
+
s += ", "
|
872
|
+
s += p.header(lang,false)
|
873
|
+
}
|
874
|
+
end
|
875
|
+
if lang == CUDA then
|
876
|
+
s += ", " if parameters.first
|
877
|
+
s += "size_t *block_number, size_t *block_size"
|
878
|
+
end
|
879
|
+
s += ")"
|
880
|
+
s += ";\n" if final
|
881
|
+
BOAST::get_output.print s if final
|
882
|
+
return s
|
883
|
+
end
|
884
|
+
|
885
|
+
def call(*parameters)
|
886
|
+
prefix = ""
|
887
|
+
prefix += "call " if BOAST::get_lang==FORTRAN
|
888
|
+
f = FuncCall::new(@name, *parameters)
|
889
|
+
f.prefix = prefix
|
890
|
+
return f
|
891
|
+
end
|
892
|
+
def decl(final=true)
|
893
|
+
return self.decl_fortran(final) if BOAST::get_lang==FORTRAN
|
894
|
+
return self.decl_c(final) if [C, CL, CUDA].include?( BOAST::get_lang )
|
895
|
+
end
|
896
|
+
def close(final=true)
|
897
|
+
return self.close_fortran(final) if BOAST::get_lang==FORTRAN
|
898
|
+
return self.close_c(final) if [C, CL, CUDA].include?( BOAST::get_lang )
|
899
|
+
end
|
900
|
+
def close_c(final=true)
|
901
|
+
BOAST::decrement_indent_level
|
902
|
+
s = ""
|
903
|
+
s += " return #{@properties[:return]};\n" if @properties[:return]
|
904
|
+
s += "}"
|
905
|
+
BOAST::get_output.puts s if final
|
906
|
+
return s
|
907
|
+
end
|
908
|
+
def close_fortran(final=true)
|
909
|
+
BOAST::decrement_indent_level
|
910
|
+
s = ""
|
911
|
+
if @properties[:return] then
|
912
|
+
s += " #{@name} = #{@properties[:return]}\n"
|
913
|
+
s += "END FUNCTION #{@name}"
|
914
|
+
else
|
915
|
+
s += "END SUBROUTINE #{@name}"
|
916
|
+
end
|
917
|
+
BOAST::get_output.puts s if final
|
918
|
+
return s
|
919
|
+
end
|
920
|
+
|
921
|
+
def print(final=true)
|
922
|
+
s = self.decl
|
923
|
+
if @block then
|
924
|
+
@block.call
|
925
|
+
s += self.close
|
926
|
+
end
|
927
|
+
return s
|
928
|
+
end
|
929
|
+
|
930
|
+
def decl_c(final=true)
|
931
|
+
s = ""
|
932
|
+
# s += self.header(BOAST::get_lang,false)
|
933
|
+
# s += ";\n"
|
934
|
+
if BOAST::get_lang == CL then
|
935
|
+
if not @properties[:local] then
|
936
|
+
s += "__kernel "
|
937
|
+
end
|
938
|
+
wgs = @properties[:reqd_work_group_size]
|
939
|
+
if wgs then
|
940
|
+
s += "__attribute__((reqd_work_group_size(#{wgs[0]},#{wgs[1]},#{wgs[2]}))) "
|
941
|
+
end
|
942
|
+
elsif BOAST::get_lang == CUDA then
|
943
|
+
if @properties[:local] then
|
944
|
+
s += "__device__ "
|
945
|
+
else
|
946
|
+
s += "__global__ "
|
947
|
+
end
|
948
|
+
end
|
949
|
+
if @properties[:return] then
|
950
|
+
s += "#{@properties[:return].type.decl} "
|
951
|
+
else
|
952
|
+
s += "void "
|
953
|
+
end
|
954
|
+
s += "#{@name}("
|
955
|
+
if parameters.first then
|
956
|
+
s += parameters.first.decl(false, @properties[:local])
|
957
|
+
parameters[1..-1].each { |p|
|
958
|
+
s += ", "+p.decl(false, @properties[:local])
|
959
|
+
}
|
960
|
+
end
|
961
|
+
s += "){\n"
|
962
|
+
BOAST::increment_indent_level
|
963
|
+
constants.each { |c|
|
964
|
+
s += " "*BOAST::get_indent_level
|
965
|
+
s += c.decl(false)
|
966
|
+
s += ";\n"
|
967
|
+
}
|
968
|
+
BOAST::get_output.print s if final
|
969
|
+
return s
|
970
|
+
end
|
971
|
+
def decl_fortran(final=true)
|
972
|
+
s = ""
|
973
|
+
if @properties[:return] then
|
974
|
+
s += "#{@properties[:return].type.decl} FUNCTION "
|
975
|
+
else
|
976
|
+
s += "SUBROUTINE "
|
977
|
+
end
|
978
|
+
s += "#{@name}("
|
979
|
+
if parameters.first then
|
980
|
+
s += parameters.first
|
981
|
+
parameters[1..-1].each { |p|
|
982
|
+
s += ", "+p
|
983
|
+
}
|
984
|
+
end
|
985
|
+
s += ")\n"
|
986
|
+
BOAST::increment_indent_level
|
987
|
+
s += " "*BOAST::get_indent_level + "integer, parameter :: wp=kind(1.0d0)\n"
|
988
|
+
constants.each { |c|
|
989
|
+
s += " "*BOAST::get_indent_level
|
990
|
+
s += c.decl(false)
|
991
|
+
s += "\n"
|
992
|
+
}
|
993
|
+
parameters.each { |p|
|
994
|
+
s += " "*BOAST::get_indent_level
|
995
|
+
s += p.decl(false)
|
996
|
+
s += "\n"
|
997
|
+
}
|
998
|
+
BOAST::get_output.print s if final
|
999
|
+
return s
|
1000
|
+
end
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
class Dimension
|
1004
|
+
def self.parens(*args,&block)
|
1005
|
+
return self::new(*args,&block)
|
1006
|
+
end
|
1007
|
+
|
1008
|
+
attr_reader :val1
|
1009
|
+
attr_reader :val2
|
1010
|
+
attr_reader :size
|
1011
|
+
def initialize(v1=nil,v2=nil)
|
1012
|
+
@size = nil
|
1013
|
+
@val1 = nil
|
1014
|
+
@val2 = nil
|
1015
|
+
if v2.nil? and v1 then
|
1016
|
+
@val1 = BOAST::get_array_start
|
1017
|
+
@val2 = v1 + BOAST::get_array_start - 1
|
1018
|
+
@size = v1
|
1019
|
+
else
|
1020
|
+
@val1 = v1
|
1021
|
+
@val2 = v2
|
1022
|
+
end
|
1023
|
+
end
|
1024
|
+
def to_str
|
1025
|
+
s = ""
|
1026
|
+
if @val2 then
|
1027
|
+
if BOAST::get_lang == FORTRAN then
|
1028
|
+
s += @val1.to_s
|
1029
|
+
s += ":"
|
1030
|
+
s += @val2.to_s
|
1031
|
+
elsif [C, CL, CUDA].include?( BOAST::get_lang ) then
|
1032
|
+
s += (@val2 - @val1 + 1).to_s
|
1033
|
+
end
|
1034
|
+
elsif @val1.nil? then
|
1035
|
+
return nil
|
1036
|
+
else
|
1037
|
+
s += @val1.to_s
|
1038
|
+
end
|
1039
|
+
return s
|
1040
|
+
end
|
1041
|
+
def to_s
|
1042
|
+
self.to_str
|
1043
|
+
end
|
1044
|
+
end
|
1045
|
+
|
1046
|
+
class Sizet
|
1047
|
+
def self.parens(*args,&block)
|
1048
|
+
return Variable::new(args[0], self, *args[1..-1], &block)
|
1049
|
+
end
|
1050
|
+
|
1051
|
+
attr_reader :signed
|
1052
|
+
def initialize(hash={})
|
1053
|
+
if hash[:signed] != nil then
|
1054
|
+
@signed = hash[:signed]
|
1055
|
+
end
|
1056
|
+
end
|
1057
|
+
def decl
|
1058
|
+
return "integer(kind=#{BOAST::get_default_int_signed})" if BOAST::get_lang == FORTRAN
|
1059
|
+
if not @signed then
|
1060
|
+
return "size_t" if [C, CL, CUDA].include?( BOAST::get_lang )
|
1061
|
+
else
|
1062
|
+
return "ptrdiff_t" if [C, CL, CUDA].include?( BOAST::get_lang )
|
1063
|
+
end
|
1064
|
+
end
|
1065
|
+
end
|
1066
|
+
|
1067
|
+
class Int
|
1068
|
+
def self.parens(*args,&block)
|
1069
|
+
return Variable::new(args[0], self, *args[1..-1], &block)
|
1070
|
+
end
|
1071
|
+
|
1072
|
+
attr_reader :size
|
1073
|
+
attr_reader :signed
|
1074
|
+
def initialize(hash={})
|
1075
|
+
if hash[:size] then
|
1076
|
+
@size = hash[:size]
|
1077
|
+
else
|
1078
|
+
@size = BOAST::get_default_int_size
|
1079
|
+
end
|
1080
|
+
if hash[:signed] != nil then
|
1081
|
+
@signed = hash[:signed]
|
1082
|
+
else
|
1083
|
+
@signed = BOAST::get_default_int_signed
|
1084
|
+
end
|
1085
|
+
end
|
1086
|
+
def decl
|
1087
|
+
return "integer(kind=#{@size})" if BOAST::get_lang == FORTRAN
|
1088
|
+
return "int#{8*@size}_t" if BOAST::get_lang == C
|
1089
|
+
if BOAST::get_lang == CL then
|
1090
|
+
#char="cl_"
|
1091
|
+
char=""
|
1092
|
+
char += "u" if not @signed
|
1093
|
+
return char += "char" if @size==1
|
1094
|
+
return char += "short" if @size==2
|
1095
|
+
return char += "int" if @size==4
|
1096
|
+
return char += "long" if @size==8
|
1097
|
+
elsif BOAST::get_lang == CUDA then
|
1098
|
+
char = ""
|
1099
|
+
char += "unsigned " if not @signed
|
1100
|
+
return char += "char" if @size==1
|
1101
|
+
return char += "short" if @size==2
|
1102
|
+
return char += "int" if @size==4
|
1103
|
+
return char += "long long" if @size==8
|
1104
|
+
end
|
1105
|
+
end
|
1106
|
+
end
|
1107
|
+
|
1108
|
+
class ConstArray < Array
|
1109
|
+
def initialize(array,type = nil)
|
1110
|
+
super(array)
|
1111
|
+
@type = type::new if type
|
1112
|
+
end
|
1113
|
+
def to_s
|
1114
|
+
self.to_str
|
1115
|
+
end
|
1116
|
+
def to_str
|
1117
|
+
return self.to_str_fortran if BOAST::get_lang == FORTRAN
|
1118
|
+
return self.to_str_c if [C, CL, CUDA].include?( BOAST::get_lang )
|
1119
|
+
end
|
1120
|
+
def to_str_fortran
|
1121
|
+
s = ""
|
1122
|
+
return s if self.first.nil?
|
1123
|
+
s += "(/ &\n"
|
1124
|
+
s += self.first
|
1125
|
+
s += "_wp" if @type and @type.size == 8
|
1126
|
+
self[1..-1].each { |v|
|
1127
|
+
s += ", &\n"+v
|
1128
|
+
s += "_wp" if @type and @type.size == 8
|
1129
|
+
}
|
1130
|
+
s += " /)"
|
1131
|
+
end
|
1132
|
+
def to_str_c
|
1133
|
+
s = ""
|
1134
|
+
return s if self.first.nil?
|
1135
|
+
s += "{\n"
|
1136
|
+
s += self.first
|
1137
|
+
self[1..-1].each { |v|
|
1138
|
+
s += ",\n"+v
|
1139
|
+
}
|
1140
|
+
s += "}"
|
1141
|
+
end
|
1142
|
+
end
|
1143
|
+
|
1144
|
+
class Ternary
|
1145
|
+
|
1146
|
+
def self.parens(*args,&block)
|
1147
|
+
return self::new(*args,&block)
|
1148
|
+
end
|
1149
|
+
|
1150
|
+
attr_reader :operand1
|
1151
|
+
attr_reader :operand2
|
1152
|
+
attr_reader :operand3
|
1153
|
+
|
1154
|
+
def initialize(x,y,z)
|
1155
|
+
@operand1 = x
|
1156
|
+
@operand2 = y
|
1157
|
+
@operand3 = z
|
1158
|
+
end
|
1159
|
+
|
1160
|
+
def ==(x)
|
1161
|
+
return Expression::new("==",self,x)
|
1162
|
+
end
|
1163
|
+
|
1164
|
+
def +(x)
|
1165
|
+
return Expression::new("+",self,x)
|
1166
|
+
end
|
1167
|
+
|
1168
|
+
def <(x)
|
1169
|
+
return Expression::new("<",self,x)
|
1170
|
+
end
|
1171
|
+
|
1172
|
+
def >=(x)
|
1173
|
+
return Expression::new(">=",self,x)
|
1174
|
+
end
|
1175
|
+
|
1176
|
+
def *(x)
|
1177
|
+
return Expression::new("*",self,x)
|
1178
|
+
end
|
1179
|
+
|
1180
|
+
def -(x)
|
1181
|
+
return Expression::new("-",self,x)
|
1182
|
+
end
|
1183
|
+
|
1184
|
+
def -@
|
1185
|
+
return Expression::new("-",nil,self)
|
1186
|
+
end
|
1187
|
+
|
1188
|
+
def [](*args)
|
1189
|
+
return Index::new(self,args)
|
1190
|
+
end
|
1191
|
+
|
1192
|
+
def to_s
|
1193
|
+
self.to_str
|
1194
|
+
end
|
1195
|
+
|
1196
|
+
def to_str
|
1197
|
+
raise "Ternary operator unsupported in FORTRAN!" if BOAST::get_lang == FORTRAN
|
1198
|
+
return self.to_str_c if [C, CL, CUDA].include?( BOAST::get_lang )
|
1199
|
+
end
|
1200
|
+
def to_str_c
|
1201
|
+
s = ""
|
1202
|
+
s += "(#{@operand1} ? #{@operand2} : #{@operand3})"
|
1203
|
+
end
|
1204
|
+
def print(final=true)
|
1205
|
+
s=""
|
1206
|
+
s += " "*BOAST::get_indent_level if final
|
1207
|
+
s += self.to_str
|
1208
|
+
s += ";" if final and [C, CL, CUDA].include?( BOAST::get_lang )
|
1209
|
+
BOAST::get_output.puts s if final
|
1210
|
+
return s
|
1211
|
+
end
|
1212
|
+
|
1213
|
+
end
|
1214
|
+
|
1215
|
+
class FuncCall
|
1216
|
+
def self.parens(*args,&block)
|
1217
|
+
return self::new(*args,&block)
|
1218
|
+
end
|
1219
|
+
|
1220
|
+
attr_reader :func_name
|
1221
|
+
attr_reader :args
|
1222
|
+
attr_accessor :prefix
|
1223
|
+
|
1224
|
+
def initialize(func_name, *args)
|
1225
|
+
@func_name = func_name
|
1226
|
+
@args = args
|
1227
|
+
end
|
1228
|
+
|
1229
|
+
def to_s
|
1230
|
+
self.to_str
|
1231
|
+
end
|
1232
|
+
|
1233
|
+
def ==(x)
|
1234
|
+
return Expression::new("==",self,x)
|
1235
|
+
end
|
1236
|
+
|
1237
|
+
def +(x)
|
1238
|
+
return Expression::new("+",self,x)
|
1239
|
+
end
|
1240
|
+
|
1241
|
+
def *(x)
|
1242
|
+
return Expression::new("*",self,x)
|
1243
|
+
end
|
1244
|
+
|
1245
|
+
def /(x)
|
1246
|
+
return Expression::new("/",self,x)
|
1247
|
+
end
|
1248
|
+
|
1249
|
+
def -(x)
|
1250
|
+
return Expression::new("-",self,x)
|
1251
|
+
end
|
1252
|
+
|
1253
|
+
def -@
|
1254
|
+
return Expression::new("-",nil,self)
|
1255
|
+
end
|
1256
|
+
|
1257
|
+
def [](*args)
|
1258
|
+
return Index::new(self,args)
|
1259
|
+
end
|
1260
|
+
|
1261
|
+
|
1262
|
+
def to_str
|
1263
|
+
return self.to_str_fortran if BOAST::get_lang == FORTRAN
|
1264
|
+
return self.to_str_c if [C, CL, CUDA].include?( BOAST::get_lang )
|
1265
|
+
end
|
1266
|
+
def to_str_fortran
|
1267
|
+
s = ""
|
1268
|
+
s += @prefix if @prefix
|
1269
|
+
s += "#{func_name}(#{@args.join(", ")})"
|
1270
|
+
end
|
1271
|
+
def to_str_c
|
1272
|
+
s = ""
|
1273
|
+
s += @prefix if @prefix
|
1274
|
+
s += "#{func_name}(#{@args.join(", ")})"
|
1275
|
+
end
|
1276
|
+
def print(final=true)
|
1277
|
+
s=""
|
1278
|
+
s += " "*BOAST::get_indent_level if final
|
1279
|
+
s += self.to_str
|
1280
|
+
s += ";" if final and [C, CL, CUDA].include?( BOAST::get_lang )
|
1281
|
+
BOAST::get_output.puts s if final
|
1282
|
+
return s
|
1283
|
+
end
|
1284
|
+
end
|
1285
|
+
|
1286
|
+
class While
|
1287
|
+
def self.parens(*args,&block)
|
1288
|
+
return self::new(*args,&block)
|
1289
|
+
end
|
1290
|
+
|
1291
|
+
attr_reader :condition
|
1292
|
+
def initialize(condition, &block)
|
1293
|
+
@condition = condition
|
1294
|
+
@block = block
|
1295
|
+
end
|
1296
|
+
def to_s
|
1297
|
+
self.to_str
|
1298
|
+
end
|
1299
|
+
def to_str
|
1300
|
+
return self.to_str_fortran if BOAST::get_lang == FORTRAN
|
1301
|
+
return self.to_str_c if [C, CL, CUDA].include?( BOAST::get_lang )
|
1302
|
+
end
|
1303
|
+
def to_str_fortran
|
1304
|
+
s = ""
|
1305
|
+
s += "do while( #{@condition} )"
|
1306
|
+
return s
|
1307
|
+
end
|
1308
|
+
def to_str_c
|
1309
|
+
s = ""
|
1310
|
+
s += "while(#{@condition}){"
|
1311
|
+
return s
|
1312
|
+
end
|
1313
|
+
def print(*args)
|
1314
|
+
final = true
|
1315
|
+
s=""
|
1316
|
+
s += " "*BOAST::get_indent_level if final
|
1317
|
+
s += self.to_str
|
1318
|
+
BOAST::increment_indent_level
|
1319
|
+
BOAST::get_output.puts s if final
|
1320
|
+
if @block then
|
1321
|
+
s += "\n"
|
1322
|
+
@block.call(*args)
|
1323
|
+
s += self.close
|
1324
|
+
end
|
1325
|
+
return s
|
1326
|
+
end
|
1327
|
+
def close(final=true)
|
1328
|
+
return self.close_fortran(final) if BOAST::get_lang == FORTRAN
|
1329
|
+
return self.close_c(final) if [C, CL, CUDA].include?( BOAST::get_lang )
|
1330
|
+
end
|
1331
|
+
def close_c(final=true)
|
1332
|
+
s = ""
|
1333
|
+
BOAST::decrement_indent_level
|
1334
|
+
s += " "*BOAST::get_indent_level if final
|
1335
|
+
s += "}"
|
1336
|
+
BOAST::get_output.puts s if final
|
1337
|
+
return s
|
1338
|
+
end
|
1339
|
+
def close_fortran(final=true)
|
1340
|
+
s = ""
|
1341
|
+
BOAST::decrement_indent_level
|
1342
|
+
s += " "*BOAST::get_indent_level if final
|
1343
|
+
s += "end do"
|
1344
|
+
BOAST::get_output.puts s if final
|
1345
|
+
return s
|
1346
|
+
end
|
1347
|
+
|
1348
|
+
end
|
1349
|
+
|
1350
|
+
class Else
|
1351
|
+
def self.parens(*args,&block)
|
1352
|
+
return self::new(*args,&block)
|
1353
|
+
end
|
1354
|
+
|
1355
|
+
attr_reader :condition
|
1356
|
+
def initialize(condition=nil, &block)
|
1357
|
+
@condition = condition
|
1358
|
+
@block = block
|
1359
|
+
end
|
1360
|
+
def to_s
|
1361
|
+
self.to_str
|
1362
|
+
end
|
1363
|
+
def to_str
|
1364
|
+
return self.to_str_fortran if BOAST::get_lang == FORTRAN
|
1365
|
+
return self.to_str_c if [C, CL, CUDA].include?( BOAST::get_lang )
|
1366
|
+
end
|
1367
|
+
def to_str_fortran
|
1368
|
+
s = ""
|
1369
|
+
if @condition then
|
1370
|
+
s += "else if #{@condition} then"
|
1371
|
+
else
|
1372
|
+
s += "else"
|
1373
|
+
end
|
1374
|
+
return s
|
1375
|
+
end
|
1376
|
+
def to_str_c
|
1377
|
+
s = ""
|
1378
|
+
if @condition then
|
1379
|
+
s += "else if(#{@condition}){"
|
1380
|
+
else
|
1381
|
+
s += "else {"
|
1382
|
+
end
|
1383
|
+
return s
|
1384
|
+
end
|
1385
|
+
def print(*args)
|
1386
|
+
final = true
|
1387
|
+
s=""
|
1388
|
+
s += " "*BOAST::get_indent_level if final
|
1389
|
+
s += self.to_str
|
1390
|
+
BOAST::increment_indent_level
|
1391
|
+
BOAST::get_output.puts s if final
|
1392
|
+
if @block then
|
1393
|
+
s += "\n"
|
1394
|
+
@block.call(*args)
|
1395
|
+
s += self.close
|
1396
|
+
end
|
1397
|
+
return s
|
1398
|
+
end
|
1399
|
+
def close(final=true)
|
1400
|
+
return self.close_fortran(final) if BOAST::get_lang == FORTRAN
|
1401
|
+
return self.close_c(final) if [C, CL, CUDA].include?( BOAST::get_lang )
|
1402
|
+
end
|
1403
|
+
def close_c(final=true)
|
1404
|
+
s = ""
|
1405
|
+
BOAST::decrement_indent_level
|
1406
|
+
s += " "*BOAST::get_indent_level if final
|
1407
|
+
s += "}"
|
1408
|
+
BOAST::get_output.puts s if final
|
1409
|
+
return s
|
1410
|
+
end
|
1411
|
+
def close_fortran(final=true)
|
1412
|
+
s = ""
|
1413
|
+
BOAST::decrement_indent_level
|
1414
|
+
s += " "*BOAST::get_indent_level if final
|
1415
|
+
s += "end if"
|
1416
|
+
BOAST::get_output.puts s if final
|
1417
|
+
return s
|
1418
|
+
end
|
1419
|
+
|
1420
|
+
end
|
1421
|
+
|
1422
|
+
class Case
|
1423
|
+
def self.parens(*args,&block)
|
1424
|
+
return self::new(*args,&block)
|
1425
|
+
end
|
1426
|
+
|
1427
|
+
attr_reader :expression
|
1428
|
+
attr_reader :constants_list
|
1429
|
+
|
1430
|
+
def initialize(expression, *control)
|
1431
|
+
@expression = expression
|
1432
|
+
@constants_list = []
|
1433
|
+
@blocks = []
|
1434
|
+
if control.size < 1 then
|
1435
|
+
raise "No block given!"
|
1436
|
+
elsif control.size.even? then
|
1437
|
+
(0..control.size-1).step(2) { |i|
|
1438
|
+
@constants_list[i/2] = [control[i]].flatten
|
1439
|
+
@blocks[i/2] = control[i+1]
|
1440
|
+
}
|
1441
|
+
else
|
1442
|
+
(0..control.size-2).step(2) { |i|
|
1443
|
+
@constants_list[i/2] = [control[i]].flatten
|
1444
|
+
@blocks[i/2] = control[i+1]
|
1445
|
+
}
|
1446
|
+
@blocks.push(control.last)
|
1447
|
+
end
|
1448
|
+
end
|
1449
|
+
|
1450
|
+
def to_s(*args)
|
1451
|
+
self.to_str(*args)
|
1452
|
+
end
|
1453
|
+
|
1454
|
+
def to_str(constants, first= true)
|
1455
|
+
return self.to_str_fortran(constants, first) if BOAST::get_lang == FORTRAN
|
1456
|
+
return self.to_str_c(constants, first) if [C, CL, CUDA].include?( BOAST::get_lang )
|
1457
|
+
end
|
1458
|
+
|
1459
|
+
def to_str_fortran(constants, first)
|
1460
|
+
s = ""
|
1461
|
+
if first then
|
1462
|
+
s += "select case #{@expression}\n"
|
1463
|
+
BOAST::increment_indent_level
|
1464
|
+
else
|
1465
|
+
BOAST::decrement_indent_level
|
1466
|
+
end
|
1467
|
+
s += " "*BOAST::get_indent_level
|
1468
|
+
if constants and constants.size>0 then
|
1469
|
+
s += "case #{constants.join(" : ")}"
|
1470
|
+
else
|
1471
|
+
s += "case default"
|
1472
|
+
end
|
1473
|
+
BOAST::increment_indent_level
|
1474
|
+
return s
|
1475
|
+
end
|
1476
|
+
|
1477
|
+
def to_str_c(constants, first)
|
1478
|
+
s = ""
|
1479
|
+
if first then
|
1480
|
+
s += " "*BOAST::get_indent_level
|
1481
|
+
s += "switch(#{@expression}){\n"
|
1482
|
+
BOAST::increment_indent_level
|
1483
|
+
else
|
1484
|
+
s += " "*BOAST::get_indent_level + "break;\n"
|
1485
|
+
BOAST::decrement_indent_level
|
1486
|
+
end
|
1487
|
+
s += " "*BOAST::get_indent_level
|
1488
|
+
if constants and constants.size>0 then
|
1489
|
+
s += "case #{constants.join(" : case")} :"
|
1490
|
+
else
|
1491
|
+
s += "default :"
|
1492
|
+
end
|
1493
|
+
BOAST::increment_indent_level
|
1494
|
+
return s
|
1495
|
+
end
|
1496
|
+
|
1497
|
+
def print(*args)
|
1498
|
+
first = true
|
1499
|
+
@blocks.each_index { |indx|
|
1500
|
+
s = self.to_str(@constants_list[indx],first)
|
1501
|
+
BOAST::get_output.puts s
|
1502
|
+
@blocks[indx].call(*args)
|
1503
|
+
first = false
|
1504
|
+
}
|
1505
|
+
self.close
|
1506
|
+
return self
|
1507
|
+
end
|
1508
|
+
def close(final=true)
|
1509
|
+
return self.close_fortran(final) if BOAST::get_lang == FORTRAN
|
1510
|
+
return self.close_c(final) if [C, CL, CUDA].include?( BOAST::get_lang )
|
1511
|
+
end
|
1512
|
+
def close_c(final=true)
|
1513
|
+
s = ""
|
1514
|
+
s += " "*BOAST::get_indent_level if final
|
1515
|
+
s += "break;\n"
|
1516
|
+
BOAST::decrement_indent_level
|
1517
|
+
s += " "*BOAST::get_indent_level if final
|
1518
|
+
s += "}"
|
1519
|
+
BOAST::decrement_indent_level
|
1520
|
+
BOAST::get_output.puts s if final
|
1521
|
+
return s
|
1522
|
+
end
|
1523
|
+
def close_fortran(final=true)
|
1524
|
+
s = ""
|
1525
|
+
BOAST::decrement_indent_level
|
1526
|
+
s += " "*BOAST::get_indent_level if final
|
1527
|
+
s += "end select"
|
1528
|
+
BOAST::decrement_indent_level
|
1529
|
+
BOAST::get_output.puts s if final
|
1530
|
+
return s
|
1531
|
+
end
|
1532
|
+
|
1533
|
+
end
|
1534
|
+
class If
|
1535
|
+
def self.parens(*args,&block)
|
1536
|
+
return self::new(*args,&block)
|
1537
|
+
end
|
1538
|
+
|
1539
|
+
attr_reader :conditions
|
1540
|
+
def initialize(*conditions, &block)
|
1541
|
+
@conditions = []
|
1542
|
+
@blocks = []
|
1543
|
+
if conditions.size == 0 then
|
1544
|
+
raise "Illegal if construct!"
|
1545
|
+
elsif conditions.size == 1 then
|
1546
|
+
@conditions.push(conditions[0])
|
1547
|
+
@blocks.push(block)
|
1548
|
+
elsif conditions.size.even? then
|
1549
|
+
(0..conditions.size-1).step(2) { |i|
|
1550
|
+
@conditions[i/2] = conditions[i]
|
1551
|
+
@blocks[i/2] = conditions[i+1]
|
1552
|
+
}
|
1553
|
+
else
|
1554
|
+
(0..conditions.size-2).step(2) { |i|
|
1555
|
+
@conditions[i/2] = conditions[i]
|
1556
|
+
@blocks[i/2] = conditions[i+1]
|
1557
|
+
}
|
1558
|
+
@blocks.push(conditions.last)
|
1559
|
+
end
|
1560
|
+
end
|
1561
|
+
def to_s(*args)
|
1562
|
+
self.to_str(*args)
|
1563
|
+
end
|
1564
|
+
def to_str(condition, first= true)
|
1565
|
+
return self.to_str_fortran(condition, first) if BOAST::get_lang == FORTRAN
|
1566
|
+
return self.to_str_c(condition, first) if [C, CL, CUDA].include?( BOAST::get_lang )
|
1567
|
+
end
|
1568
|
+
def to_str_fortran(condition, first)
|
1569
|
+
s = ""
|
1570
|
+
if first then
|
1571
|
+
s += "if #{condition} then"
|
1572
|
+
else
|
1573
|
+
if condition then
|
1574
|
+
s += "else if #{condition} then"
|
1575
|
+
else
|
1576
|
+
s += "else"
|
1577
|
+
end
|
1578
|
+
end
|
1579
|
+
return s
|
1580
|
+
end
|
1581
|
+
def to_str_c(condition, first)
|
1582
|
+
s = ""
|
1583
|
+
if first then
|
1584
|
+
s += "if(#{condition}){"
|
1585
|
+
else
|
1586
|
+
if condition then
|
1587
|
+
s += "} else if(#{condition}){"
|
1588
|
+
else
|
1589
|
+
s += "} else {"
|
1590
|
+
end
|
1591
|
+
end
|
1592
|
+
return s
|
1593
|
+
end
|
1594
|
+
def print(*args)
|
1595
|
+
s=""
|
1596
|
+
s += " "*BOAST::get_indent_level
|
1597
|
+
s += self.to_str(@conditions.first)
|
1598
|
+
BOAST::increment_indent_level
|
1599
|
+
BOAST::get_output.puts s
|
1600
|
+
if @blocks.size > 0 then
|
1601
|
+
if @blocks[0] then
|
1602
|
+
@blocks[0].call(*args)
|
1603
|
+
end
|
1604
|
+
@blocks[1..-1].each_index { |indx|
|
1605
|
+
BOAST::decrement_indent_level
|
1606
|
+
s=""
|
1607
|
+
s += " "*BOAST::get_indent_level
|
1608
|
+
s += self.to_str(@conditions[1..-1][indx],false)
|
1609
|
+
BOAST::increment_indent_level
|
1610
|
+
BOAST::get_output.puts s
|
1611
|
+
@blocks[1..-1][indx].call(*args)
|
1612
|
+
}
|
1613
|
+
self.close
|
1614
|
+
end
|
1615
|
+
return self
|
1616
|
+
end
|
1617
|
+
def close(final=true)
|
1618
|
+
return self.close_fortran(final) if BOAST::get_lang == FORTRAN
|
1619
|
+
return self.close_c(final) if [C, CL, CUDA].include?( BOAST::get_lang )
|
1620
|
+
end
|
1621
|
+
def close_c(final=true)
|
1622
|
+
s = ""
|
1623
|
+
BOAST::decrement_indent_level
|
1624
|
+
s += " "*BOAST::get_indent_level if final
|
1625
|
+
s += "}"
|
1626
|
+
BOAST::get_output.puts s if final
|
1627
|
+
return s
|
1628
|
+
end
|
1629
|
+
def close_fortran(final=true)
|
1630
|
+
s = ""
|
1631
|
+
BOAST::decrement_indent_level
|
1632
|
+
s += " "*BOAST::get_indent_level if final
|
1633
|
+
s += "end if"
|
1634
|
+
BOAST::get_output.puts s if final
|
1635
|
+
return s
|
1636
|
+
end
|
1637
|
+
|
1638
|
+
end
|
1639
|
+
|
1640
|
+
class For
|
1641
|
+
attr_reader :iterator
|
1642
|
+
attr_reader :begin
|
1643
|
+
attr_reader :end
|
1644
|
+
attr_reader :step
|
1645
|
+
|
1646
|
+
def self.parens(*args,&block)
|
1647
|
+
return self::new(*args,&block)
|
1648
|
+
end
|
1649
|
+
|
1650
|
+
def initialize(i, b, e, s=1, &block)
|
1651
|
+
@iterator = i
|
1652
|
+
@begin = b
|
1653
|
+
@end = e
|
1654
|
+
@step = s
|
1655
|
+
@block = block
|
1656
|
+
end
|
1657
|
+
def to_s
|
1658
|
+
self.to_str
|
1659
|
+
end
|
1660
|
+
def to_str
|
1661
|
+
return self.to_str_fortran if BOAST::get_lang == FORTRAN
|
1662
|
+
return self.to_str_c if [C, CL, CUDA].include?( BOAST::get_lang )
|
1663
|
+
end
|
1664
|
+
def to_str_fortran
|
1665
|
+
s = ""
|
1666
|
+
s += "do #{@iterator}=#{@begin}, #{@end}"
|
1667
|
+
s += ", #{@step}" if @step != 1
|
1668
|
+
return s
|
1669
|
+
end
|
1670
|
+
def to_str_c
|
1671
|
+
s = ""
|
1672
|
+
s += "for(#{@iterator}=#{@begin}; #{@iterator}<=#{@end}; #{@iterator}+=#{@step}){"
|
1673
|
+
return s
|
1674
|
+
end
|
1675
|
+
|
1676
|
+
def unroll(*args)
|
1677
|
+
raise "Block not given!" if not @block
|
1678
|
+
BOAST::push_env( :replace_constants => true )
|
1679
|
+
begin
|
1680
|
+
if @begin.kind_of?(Variable) then
|
1681
|
+
start = @begin.constant
|
1682
|
+
elsif @begin.kind_of?(Expression) then
|
1683
|
+
start = eval "#{@begin}"
|
1684
|
+
else
|
1685
|
+
start = @begin.to_i
|
1686
|
+
end
|
1687
|
+
if @end.kind_of?(Variable) then
|
1688
|
+
e = @end.constant
|
1689
|
+
elsif @end.kind_of?(Expression) then
|
1690
|
+
e = eval "#{@end}"
|
1691
|
+
else
|
1692
|
+
e = @end.to_i
|
1693
|
+
end
|
1694
|
+
if @step.kind_of?(Variable) then
|
1695
|
+
step = @step.constant
|
1696
|
+
elsif @step.kind_of?(Expression) then
|
1697
|
+
step = eval "#{@step}"
|
1698
|
+
else
|
1699
|
+
step = @step.to_i
|
1700
|
+
end
|
1701
|
+
raise "Invalid bounds (not constants)!" if not ( start and e and step )
|
1702
|
+
rescue Exception => ex
|
1703
|
+
if not ( start and e and step ) then
|
1704
|
+
BOAST::pop_env( :replace_constants )
|
1705
|
+
return self.print(*args) if not ( start and e and step )
|
1706
|
+
end
|
1707
|
+
end
|
1708
|
+
BOAST::pop_env( :replace_constants )
|
1709
|
+
range = start..e
|
1710
|
+
@iterator.force_replace_constant = true
|
1711
|
+
range.step(step) { |i|
|
1712
|
+
@iterator.constant = i
|
1713
|
+
@block.call(*args)
|
1714
|
+
}
|
1715
|
+
@iterator.force_replace_constant = false
|
1716
|
+
@iterator.constant = nil
|
1717
|
+
end
|
1718
|
+
|
1719
|
+
def print(*args)
|
1720
|
+
final = true
|
1721
|
+
s=""
|
1722
|
+
s += " "*BOAST::get_indent_level if final
|
1723
|
+
s += self.to_str
|
1724
|
+
BOAST::increment_indent_level
|
1725
|
+
BOAST::get_output.puts s if final
|
1726
|
+
if @block then
|
1727
|
+
s += "\n"
|
1728
|
+
@block.call(*args)
|
1729
|
+
s += self.close
|
1730
|
+
end
|
1731
|
+
return s
|
1732
|
+
end
|
1733
|
+
|
1734
|
+
def close(final=true)
|
1735
|
+
return self.close_fortran(final) if BOAST::get_lang == FORTRAN
|
1736
|
+
return self.close_c(final) if [C, CL, CUDA].include?( BOAST::get_lang )
|
1737
|
+
end
|
1738
|
+
def close_c(final=true)
|
1739
|
+
s = ""
|
1740
|
+
BOAST::decrement_indent_level
|
1741
|
+
s += " "*BOAST::get_indent_level if final
|
1742
|
+
s += "}"
|
1743
|
+
BOAST::get_output.puts s if final
|
1744
|
+
return s
|
1745
|
+
end
|
1746
|
+
def close_fortran(final=true)
|
1747
|
+
s = ""
|
1748
|
+
BOAST::decrement_indent_level
|
1749
|
+
s += " "*BOAST::get_indent_level if final
|
1750
|
+
s += "enddo"
|
1751
|
+
BOAST::get_output.puts s if final
|
1752
|
+
return s
|
1753
|
+
end
|
1754
|
+
end
|
1755
|
+
Var = Variable
|
1756
|
+
Dim = Dimension
|
1757
|
+
Call = FuncCall
|
1758
|
+
end
|
1759
|
+
ConvolutionGenerator = BOAST
|