BOAST 1.0.9 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/BOAST.gemspec +1 -1
- data/lib/BOAST.rb +5 -1
- data/lib/BOAST/Language/Algorithm.rb +104 -22
- data/lib/BOAST/Language/Annotation.rb +55 -0
- data/lib/BOAST/Language/Arithmetic.rb +44 -10
- data/lib/BOAST/Language/Case.rb +89 -52
- data/lib/BOAST/Language/CodeBlock.rb +17 -0
- data/lib/BOAST/Language/Comment.rb +38 -0
- data/lib/BOAST/Language/ControlStructure.rb +7 -0
- data/lib/BOAST/Language/Error.rb +7 -0
- data/lib/BOAST/Language/Expression.rb +4 -5
- data/lib/BOAST/Language/For.rb +59 -27
- data/lib/BOAST/Language/If.rb +12 -17
- data/lib/BOAST/Language/Index.rb +5 -5
- data/lib/BOAST/Language/Intrinsics.rb +38 -32
- data/lib/BOAST/Language/OpenMP.rb +1 -1
- data/lib/BOAST/Language/Operators.rb +208 -53
- data/lib/BOAST/Language/Pragma.rb +3 -3
- data/lib/BOAST/Language/Print.rb +3 -3
- data/lib/BOAST/Language/Procedure.rb +15 -8
- data/lib/BOAST/Language/Variable.rb +45 -87
- data/lib/BOAST/Language/While.rb +3 -0
- data/lib/BOAST/Optimization/Optimization.rb +241 -0
- metadata +7 -4
- data/lib/BOAST/Language/Optimization.rb +0 -74
- data/lib/BOAST/Language/Vector.rb +0 -6
@@ -4,6 +4,8 @@ module BOAST
|
|
4
4
|
include PrivateStateAccessor
|
5
5
|
include Inspectable
|
6
6
|
extend Functor
|
7
|
+
include Annotation
|
8
|
+
ANNOTATIONS = [ :name, :parameters, :constants ]
|
7
9
|
|
8
10
|
attr_reader :name
|
9
11
|
attr_reader :parameters
|
@@ -214,21 +216,22 @@ module BOAST
|
|
214
216
|
s += ")"
|
215
217
|
end
|
216
218
|
|
217
|
-
def pr_align
|
218
|
-
end
|
219
|
-
|
220
219
|
def open_c
|
221
220
|
s = indent + decl_c_s + "{"
|
222
221
|
output.puts s
|
223
222
|
increment_indent_level
|
224
223
|
constants.each { |c|
|
225
|
-
c
|
224
|
+
BOAST::decl c
|
226
225
|
}
|
227
226
|
if lang == C then
|
228
227
|
parameters.each { |p|
|
229
|
-
p.
|
228
|
+
align = p.align
|
229
|
+
BOAST::pr align if align
|
230
230
|
}
|
231
231
|
end
|
232
|
+
if @properties[:return] then
|
233
|
+
BOAST::decl @properties[:return]
|
234
|
+
end
|
232
235
|
return self
|
233
236
|
end
|
234
237
|
|
@@ -239,12 +242,16 @@ module BOAST
|
|
239
242
|
s += indent + "integer, parameter :: wp=kind(1.0d0)"
|
240
243
|
output.puts s
|
241
244
|
constants.each { |c|
|
242
|
-
c
|
245
|
+
BOAST::decl c
|
243
246
|
}
|
244
247
|
parameters.each { |p|
|
245
|
-
p
|
246
|
-
p.
|
248
|
+
BOAST::decl p
|
249
|
+
align = p.align
|
250
|
+
BOAST::pr align if align
|
247
251
|
}
|
252
|
+
if @properties[:return] then
|
253
|
+
BOAST::decl @properties[:return]
|
254
|
+
end
|
248
255
|
return self
|
249
256
|
end
|
250
257
|
|
@@ -13,7 +13,11 @@ module BOAST
|
|
13
13
|
if v1 then
|
14
14
|
if v2 then
|
15
15
|
#@size = Expression::new(Substraction, v2, v1) + 1
|
16
|
-
|
16
|
+
begin
|
17
|
+
@size = v2-v1+1
|
18
|
+
rescue
|
19
|
+
@size = Expression::new(Substraction, v2, v1) + 1
|
20
|
+
end
|
17
21
|
else
|
18
22
|
@size = v1
|
19
23
|
end
|
@@ -29,8 +33,10 @@ module BOAST
|
|
29
33
|
return "#{@val1}:#{@val2}"
|
30
34
|
elsif lang == FORTRAN and get_array_start != 1 then
|
31
35
|
return "#{get_array_start}:#{@size-(1+get_array_start)}"
|
36
|
+
elsif lang == FORTRAN and size.nil?
|
37
|
+
return "*"
|
32
38
|
else
|
33
|
-
return @size
|
39
|
+
return @size.to_s
|
34
40
|
end
|
35
41
|
end
|
36
42
|
|
@@ -47,13 +53,17 @@ module BOAST
|
|
47
53
|
return @val2
|
48
54
|
elsif @size
|
49
55
|
if 0.equal?(get_array_start) then
|
56
|
+
return @size - 1
|
57
|
+
else
|
50
58
|
if 1.equal?(get_array_start) then
|
51
|
-
return Expression::new(Addition, @size, get_array_start) - 1
|
52
|
-
else
|
53
59
|
return @size
|
60
|
+
else
|
61
|
+
begin
|
62
|
+
return @size + get_array_start - 1
|
63
|
+
rescue
|
64
|
+
return Expression::new(Addition, @size, get_array_start) - 1
|
65
|
+
end
|
54
66
|
end
|
55
|
-
else
|
56
|
-
return Expression::new(Substraction, @size, 1)
|
57
67
|
end
|
58
68
|
else
|
59
69
|
return nil
|
@@ -115,6 +125,8 @@ module BOAST
|
|
115
125
|
include Arithmetic
|
116
126
|
include Inspectable
|
117
127
|
extend Functor
|
128
|
+
include Annotation
|
129
|
+
ANNOTATIONS = [ :name, :type, :dimension ]
|
118
130
|
|
119
131
|
alias_method :orig_method_missing, :method_missing
|
120
132
|
|
@@ -146,7 +158,7 @@ module BOAST
|
|
146
158
|
attr_reader :restrict
|
147
159
|
attr_reader :deferred_shape
|
148
160
|
attr_reader :optional
|
149
|
-
attr_accessor :
|
161
|
+
attr_accessor :alignment
|
150
162
|
attr_accessor :replace_constant
|
151
163
|
attr_accessor :force_replace_constant
|
152
164
|
|
@@ -191,7 +203,7 @@ module BOAST
|
|
191
203
|
end
|
192
204
|
|
193
205
|
def align?
|
194
|
-
!!@
|
206
|
+
!!@alignment
|
195
207
|
end
|
196
208
|
|
197
209
|
def deferred_shape?
|
@@ -207,7 +219,7 @@ module BOAST
|
|
207
219
|
@texture = hash[:texture]
|
208
220
|
@allocate = hash[:allocate]
|
209
221
|
@restrict = hash[:restrict]
|
210
|
-
@
|
222
|
+
@alignment = hash[:align]
|
211
223
|
@deferred_shape = hash[:deferred_shape]
|
212
224
|
@optional = hash[:optional]
|
213
225
|
@force_replace_constant = false
|
@@ -271,8 +283,7 @@ module BOAST
|
|
271
283
|
|
272
284
|
def dereference
|
273
285
|
return copy("*(#{name})", :dimension => nil, :dim => nil, :direction => nil, :dir => nil) if [C, CL, CUDA].include?( lang )
|
274
|
-
return self if lang == FORTRAN
|
275
|
-
#return Expression::new("*",nil,self)
|
286
|
+
return Index::new(self, *(@dimension.collect { |d| d.start } ) ) if lang == FORTRAN
|
276
287
|
end
|
277
288
|
|
278
289
|
def struct_reference(x)
|
@@ -285,7 +296,7 @@ module BOAST
|
|
285
296
|
end
|
286
297
|
|
287
298
|
def [](*args)
|
288
|
-
return Index::new(self
|
299
|
+
return Index::new(self,*args)
|
289
300
|
end
|
290
301
|
|
291
302
|
def finalize
|
@@ -310,12 +321,7 @@ module BOAST
|
|
310
321
|
if dimension? and use_vla? and lang != FORTRAN then
|
311
322
|
s += "["
|
312
323
|
s += @dimension.reverse.collect { |d|
|
313
|
-
|
314
|
-
if dim then
|
315
|
-
dim.to_s
|
316
|
-
else
|
317
|
-
""
|
318
|
-
end
|
324
|
+
d.to_s
|
319
325
|
}.join("][")
|
320
326
|
s += "]"
|
321
327
|
end
|
@@ -386,12 +392,7 @@ module BOAST
|
|
386
392
|
s += " #{@name}["
|
387
393
|
s += "__restrict__ " if __restrict?
|
388
394
|
s += @dimension.reverse.collect { |d|
|
389
|
-
|
390
|
-
if dim then
|
391
|
-
dim.to_s
|
392
|
-
else
|
393
|
-
""
|
394
|
-
end
|
395
|
+
d.to_s
|
395
396
|
}.join("][")
|
396
397
|
s += "]"
|
397
398
|
else
|
@@ -413,8 +414,8 @@ module BOAST
|
|
413
414
|
s +=")]"
|
414
415
|
end
|
415
416
|
end
|
416
|
-
if __align? then
|
417
|
-
a = ( align? ?
|
417
|
+
if __align? and lang != CUDA then
|
418
|
+
a = ( align? ? alignment : 1 )
|
418
419
|
a = ( a >= default_align ? a : default_align )
|
419
420
|
s+= " __attribute((aligned(#{a})))"
|
420
421
|
end
|
@@ -423,7 +424,7 @@ module BOAST
|
|
423
424
|
end
|
424
425
|
|
425
426
|
def decl_texture_s
|
426
|
-
raise "Unsupported language #{lang} for texture!" if not [CL, CUDA].include?( lang )
|
427
|
+
raise LanguageError, "Unsupported language #{lang} for texture!" if not [CL, CUDA].include?( lang )
|
427
428
|
raise "Write is unsupported for textures!" if not (constant? or @direction == :in)
|
428
429
|
dim_number = 1
|
429
430
|
if dimension? then
|
@@ -454,69 +455,39 @@ module BOAST
|
|
454
455
|
return self
|
455
456
|
end
|
456
457
|
|
457
|
-
def
|
458
|
-
return "__assume_aligned
|
459
|
-
end
|
460
|
-
|
461
|
-
def pr_align_c(a)
|
462
|
-
s = ""
|
463
|
-
s += indent
|
464
|
-
s += pr_align_c_s(a)
|
465
|
-
s += finalize
|
466
|
-
output.print s
|
467
|
-
return self
|
458
|
+
def align_c(a)
|
459
|
+
return FuncCall::new("__assume_aligned", @name, a)
|
468
460
|
end
|
469
461
|
|
470
|
-
def
|
471
|
-
return "
|
462
|
+
def align_fortran(a)
|
463
|
+
return Pragma::new("DIR", "ASSUME_ALIGNED", "#{@name}: #{a}")
|
472
464
|
end
|
473
465
|
|
474
|
-
def
|
475
|
-
s = ""
|
476
|
-
s += indent
|
477
|
-
s += pr_align_fortran_s(a)
|
478
|
-
s += finalize
|
479
|
-
output.print s
|
480
|
-
return self
|
481
|
-
end
|
482
|
-
|
483
|
-
def pr_align
|
466
|
+
def align
|
484
467
|
if dimension? then
|
485
468
|
if align? or default_align > 1 then
|
486
|
-
a = ( align? ?
|
469
|
+
a = ( align? ? alignment : 1 )
|
487
470
|
a = ( a >= default_align ? a : default_align )
|
488
|
-
return
|
489
|
-
return
|
471
|
+
return align_c(a) if lang == C
|
472
|
+
return align_fortran(a) if lang == FORTRAN
|
490
473
|
end
|
491
474
|
end
|
475
|
+
return nil
|
492
476
|
end
|
493
477
|
|
494
478
|
def alloc_fortran( dims = nil )
|
495
|
-
|
496
|
-
s += indent
|
497
|
-
s += "allocate( #{name}("
|
498
|
-
s += dims.collect { |d| d.to_s }.join(", ")
|
499
|
-
s += ") )"
|
500
|
-
s += finalize
|
501
|
-
output.print s
|
502
|
-
return self
|
479
|
+
return FuncCall::new(:allocate, FuncCall(name, * dims ) )
|
503
480
|
end
|
504
481
|
|
505
482
|
def alloc_c( dims = nil, align = get_address_size)
|
506
|
-
|
507
|
-
s += indent
|
483
|
+
d = dims.collect { |d| d.to_s }.reverse.join(")*(")
|
508
484
|
if align > (OS.bits/8) then
|
509
485
|
# check alignment is a power of 2
|
510
486
|
raise "Invalid alignment #{align}!" if align & (align - 1) != 0
|
511
|
-
|
487
|
+
return FuncCall::new(:posix_memalign, self.address, align, FuncCall::new(:sizeof, @type.decl) * d)
|
512
488
|
else
|
513
|
-
|
489
|
+
return self === FuncCall::new(:malloc, FuncCall::new(:sizeof, @type.decl) * d).cast(self)
|
514
490
|
end
|
515
|
-
s += dims.collect { |d| d.to_s }.reverse.join(")*(")
|
516
|
-
s += ") )"
|
517
|
-
s += finalize
|
518
|
-
output.print s
|
519
|
-
return self
|
520
491
|
end
|
521
492
|
|
522
493
|
def alloc( dims = nil, align = get_address_size )
|
@@ -528,21 +499,11 @@ module BOAST
|
|
528
499
|
end
|
529
500
|
|
530
501
|
def dealloc_fortran
|
531
|
-
|
532
|
-
s += indent
|
533
|
-
s += "deallocate( #{name} )"
|
534
|
-
s += finalize
|
535
|
-
output.print s
|
536
|
-
return self
|
502
|
+
return FuncCall::new(:deallocate, self)
|
537
503
|
end
|
538
504
|
|
539
505
|
def dealloc_c
|
540
|
-
|
541
|
-
s += indent
|
542
|
-
s += "free( #{name} )"
|
543
|
-
s += finalize
|
544
|
-
output.print s
|
545
|
-
return self
|
506
|
+
return FuncCall::new(:free, self)
|
546
507
|
end
|
547
508
|
|
548
509
|
def dealloc
|
@@ -561,13 +522,10 @@ module BOAST
|
|
561
522
|
if dimension? then
|
562
523
|
s += ", dimension("
|
563
524
|
s += @dimension.collect { |d|
|
564
|
-
dim = d.to_s
|
565
525
|
if deferred_shape? or ( allocate? and @allocate == :heap )
|
566
526
|
":"
|
567
|
-
elsif dim then
|
568
|
-
dim.to_s
|
569
527
|
else
|
570
|
-
|
528
|
+
d.to_s
|
571
529
|
end
|
572
530
|
}.join(", ")
|
573
531
|
s += ")"
|
@@ -581,7 +539,7 @@ module BOAST
|
|
581
539
|
s += finalize
|
582
540
|
output.print s
|
583
541
|
if dimension? and (align? or default_align > 1) and (constant? or ( allocate? and @allocate != :heap ) ) then
|
584
|
-
a = ( align? ?
|
542
|
+
a = ( align? ? alignment : 1 )
|
585
543
|
a = ( a >= default_align ? a : default_align )
|
586
544
|
s = ""
|
587
545
|
s += indent
|
data/lib/BOAST/Language/While.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module BOAST
|
2
2
|
|
3
3
|
class While < ControlStructure
|
4
|
+
include Annotation
|
5
|
+
ANNOTATIONS = [ :condition ]
|
4
6
|
|
5
7
|
attr_reader :condition
|
6
8
|
|
@@ -39,6 +41,7 @@ module BOAST
|
|
39
41
|
end
|
40
42
|
|
41
43
|
def pr(*args)
|
44
|
+
args = @args if args.length == 0 and @args
|
42
45
|
open
|
43
46
|
if @block then
|
44
47
|
@block.call(*args)
|
@@ -0,0 +1,241 @@
|
|
1
|
+
module BOAST
|
2
|
+
|
3
|
+
class OptimizationParameter
|
4
|
+
attr_reader :name
|
5
|
+
attr_reader :values
|
6
|
+
def initialize( name, values )
|
7
|
+
@name = name
|
8
|
+
@values = values
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class BooleanParameter < OptimizationParameter
|
13
|
+
def initialize( name )
|
14
|
+
super( name, [false, true] )
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
OP = OptimizationParameter
|
19
|
+
BP = BooleanParameter
|
20
|
+
|
21
|
+
class OptimizationSpace
|
22
|
+
attr_reader :parameters
|
23
|
+
|
24
|
+
def initialize( *parameters )
|
25
|
+
if parameters.length == 1 and parameters[0].is_a?(Hash) then
|
26
|
+
@parameters = []
|
27
|
+
parameters[0].each { |key, value|
|
28
|
+
@parameters.push( OptimizationParameter::new(key, value) )
|
29
|
+
}
|
30
|
+
else
|
31
|
+
@parameters = parameters
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_h
|
36
|
+
h = {}
|
37
|
+
@parameters.each { |p|
|
38
|
+
h[p.name] = p.values
|
39
|
+
}
|
40
|
+
return h
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
class Optimizer
|
46
|
+
include PrivateStateAccessor
|
47
|
+
attr_reader :experiments
|
48
|
+
attr_reader :search_space
|
49
|
+
attr_reader :log
|
50
|
+
|
51
|
+
def initialize(search_space, options = {} )
|
52
|
+
@search_space = search_space
|
53
|
+
@experiments = 0
|
54
|
+
@log = {}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class GeneticOptimizer < Optimizer
|
59
|
+
|
60
|
+
def initialize(search_space, options = {} )
|
61
|
+
super
|
62
|
+
require 'darwinning'
|
63
|
+
s = <<EOF
|
64
|
+
@organism = Class::new(Darwinning::Organism) do
|
65
|
+
@@block = nil
|
66
|
+
def self.block
|
67
|
+
return @@block
|
68
|
+
end
|
69
|
+
def self.block=(block)
|
70
|
+
@@block = block
|
71
|
+
end
|
72
|
+
@@experiments = 0
|
73
|
+
def self.experiments
|
74
|
+
return @@experiments
|
75
|
+
end
|
76
|
+
def self.experiments=(experiments)
|
77
|
+
@@experiments = experiments
|
78
|
+
end
|
79
|
+
EOF
|
80
|
+
@search_space.parameters.each { |param|
|
81
|
+
s += <<EOF
|
82
|
+
@genes.push( Darwinning::Gene.new(name: #{param.name.inspect}, value_range: #{param.values.inspect}) )
|
83
|
+
EOF
|
84
|
+
}
|
85
|
+
s += <<EOF
|
86
|
+
def initialize(*args)
|
87
|
+
super
|
88
|
+
end
|
89
|
+
|
90
|
+
def fitness
|
91
|
+
return @fitness if @fitness
|
92
|
+
opts = {}
|
93
|
+
genes.each { |gene|
|
94
|
+
opts[gene.name] = genotypes[gene]
|
95
|
+
}
|
96
|
+
@fitness = @@block.call(opts)
|
97
|
+
@@experiments = @@experiments + 1
|
98
|
+
return fitness
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_a
|
102
|
+
opts = {}
|
103
|
+
genes.each { |gene|
|
104
|
+
opts[gene.name] = genotypes[gene]
|
105
|
+
}
|
106
|
+
return [opts, fitness]
|
107
|
+
end
|
108
|
+
|
109
|
+
def to_s
|
110
|
+
return [opts, fitness].to_s
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
EOF
|
115
|
+
eval s
|
116
|
+
end
|
117
|
+
|
118
|
+
def optimize(options={}, &block)
|
119
|
+
opts = { :population_size => 20,
|
120
|
+
:fitness_goal => 0,
|
121
|
+
:generations_limit => 100 }
|
122
|
+
opts.update(options)
|
123
|
+
opts[:organism] = @organism
|
124
|
+
@organism.block = block
|
125
|
+
@organism.experiments = 0
|
126
|
+
population = Darwinning::Population.new(opts)
|
127
|
+
population.evolve!
|
128
|
+
@experiments = @organism.experiments
|
129
|
+
return population.best_member.to_a
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
class BruteForceOptimizer < Optimizer
|
135
|
+
|
136
|
+
def initialize(search_space, options = {} )
|
137
|
+
super
|
138
|
+
@randomize = options[:randomize]
|
139
|
+
end
|
140
|
+
|
141
|
+
def points
|
142
|
+
params2 = @search_space.parameters.dup
|
143
|
+
param = params2.shift
|
144
|
+
pts = param.values.collect { |val| {param.name => val} }
|
145
|
+
if params2.size == 0 then
|
146
|
+
return pts
|
147
|
+
else
|
148
|
+
optim2 = BruteForceOptimizer::new(OptimizationSpace::new(*params2))
|
149
|
+
pts3=[]
|
150
|
+
pts.each{ |p1|
|
151
|
+
optim2.each { |p2|
|
152
|
+
pts3.push(p1.dup.update(p2))
|
153
|
+
}
|
154
|
+
}
|
155
|
+
return pts3
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def each(&block)
|
160
|
+
return self.points.each(&block)
|
161
|
+
end
|
162
|
+
|
163
|
+
def each_random(&block)
|
164
|
+
return self.points.shuffle.each(&block)
|
165
|
+
end
|
166
|
+
|
167
|
+
def optimize(&block)
|
168
|
+
@experiments = 0
|
169
|
+
@log = {}
|
170
|
+
best = [nil, Float::INFINITY]
|
171
|
+
pts = points
|
172
|
+
pts.shuffle! if @randomize
|
173
|
+
pts.each { |config|
|
174
|
+
@experiments += 1
|
175
|
+
metric = block.call(config)
|
176
|
+
@log[config] = metric if optimizer_log
|
177
|
+
best = [config, metric] if metric < best[1]
|
178
|
+
}
|
179
|
+
if optimizer_log_file then
|
180
|
+
File::open(File::basename(optimizer_log_file,".yaml")+".yaml", "w") { |f|
|
181
|
+
f.print YAML::dump(@log)
|
182
|
+
}
|
183
|
+
File::open(File::basename(optimizer_log_file,".yaml")+"_parameters.yaml", "w") { |f|
|
184
|
+
f.print YAML::dump(@search_space.to_h)
|
185
|
+
}
|
186
|
+
end
|
187
|
+
return best
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
class GenericOptimization
|
193
|
+
|
194
|
+
attr_accessor :repeat
|
195
|
+
attr_reader :parameters
|
196
|
+
|
197
|
+
def size
|
198
|
+
return @parameters.size
|
199
|
+
end
|
200
|
+
|
201
|
+
def points
|
202
|
+
params2 = @parameters.dup
|
203
|
+
param = params2.shift
|
204
|
+
pts = param.values.collect { |val| {param.name => val} }
|
205
|
+
if params2.size == 0 then
|
206
|
+
return pts
|
207
|
+
else
|
208
|
+
optim2 = GenericOptimization::new(*params2)
|
209
|
+
pts3=[]
|
210
|
+
pts.each{ |p1|
|
211
|
+
optim2.each { |p2|
|
212
|
+
pts3.push(p1.dup.update(p2))
|
213
|
+
}
|
214
|
+
}
|
215
|
+
return pts3
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def each(&block)
|
220
|
+
return self.points.each(&block)
|
221
|
+
end
|
222
|
+
|
223
|
+
def each_random(&block)
|
224
|
+
return self.points.shuffle.each(&block)
|
225
|
+
end
|
226
|
+
|
227
|
+
def initialize( *parameters )
|
228
|
+
if parameters.length == 1 and parameters[0].is_a?(Hash) then
|
229
|
+
@parameters = []
|
230
|
+
parameters[0].each { |key, value|
|
231
|
+
@parameters.push( OptimizationParameter::new(key, value) )
|
232
|
+
}
|
233
|
+
else
|
234
|
+
@parameters = parameters
|
235
|
+
end
|
236
|
+
@repeat = 3
|
237
|
+
end
|
238
|
+
|
239
|
+
end
|
240
|
+
|
241
|
+
end
|