trinitycrdriver 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -1
- data/VERSION +1 -1
- data/lib/trinitycrdriver.rb +14 -2
- data/lib/trinitycrdriver/optimisation.rb +316 -83
- data/lib/trinoptcrmod/trinopt.rb +227 -35
- data/trinitycrdriver.gemspec +10 -7
- metadata +19 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be3b3ef7a8135177b9176f17971baf754f62c114
|
4
|
+
data.tar.gz: 26d256bd34c004714b8ad5e0b7f035ef235110b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb01d0c800b4abaa758b6739012aa4d5d244fd9325b29ce540d972cb82302d14675f0114144657520737aae6153403d28e1923a07fc47993a614edc58e929fc3
|
7
|
+
data.tar.gz: 1bf6596bb2b92870736be15126f7cf1e1eda6d8dd8326b7185efe0baf576e22e648e670da8578be262b500e7fb2693f2b91d4da58e5b564da0bc237fb8dbb0c7
|
data/Gemfile
CHANGED
@@ -4,9 +4,10 @@ source "http://rubygems.org"
|
|
4
4
|
gem "coderunner", ">= 0.14.2"
|
5
5
|
gem "text-data-tools", ">= 1.1.3"
|
6
6
|
gem "gs2crmod", ">=0.11.33"
|
7
|
-
gem "trinitycrmod", ">= 0.
|
7
|
+
gem "trinitycrmod", ">= 0.7.11"
|
8
8
|
gem "ruby-mpi", ">=0.2.0"
|
9
9
|
gem "cheasecrmod", ">=0.1.0"
|
10
|
+
gem "tokfile", ">=0.0.3"
|
10
11
|
|
11
12
|
# Add dependencies to develop your gem here.
|
12
13
|
# Include everything needed to run rake, tests, features, etc.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.2
|
data/lib/trinitycrdriver.rb
CHANGED
@@ -4,12 +4,20 @@ class CodeRunner
|
|
4
4
|
module TrinityDriver
|
5
5
|
extend FFI::Library
|
6
6
|
ffi_lib ENV['TRINITY'] + '/libtrin.so'
|
7
|
-
attach_function :runtr, :run_trinity_c, [:string, :
|
7
|
+
attach_function :runtr, :run_trinity_c, [:string, :size_t], :void
|
8
|
+
attach_function :runtr2, :run_trinity_test, [], :void
|
8
9
|
end
|
9
10
|
def run_trin_actual2(input_file, mpicomm_int)
|
10
|
-
puts 'calling TrinityDriver.runtr'
|
11
|
+
puts ['calling TrinityDriver.runtr',mpicomm_int.class]
|
11
12
|
TrinityDriver.runtr(input_file, mpicomm_int)
|
12
13
|
end
|
14
|
+
def self.run_trin_standalone(input_file)
|
15
|
+
require 'mpi'
|
16
|
+
MPI.Init
|
17
|
+
obj = CodeRunner::Trinity.new
|
18
|
+
obj.run_trinity(input_file, MPI::Comm::WORLD)
|
19
|
+
MPI.Finalize
|
20
|
+
end
|
13
21
|
private :run_trin_actual2
|
14
22
|
end
|
15
23
|
end
|
@@ -21,8 +29,12 @@ class CodeRunner::Trinity
|
|
21
29
|
# Instead of running trinity via a bash command or a batch script,
|
22
30
|
# we run it directly via its API.
|
23
31
|
@delay_execution = false
|
32
|
+
def queue_status
|
33
|
+
""
|
34
|
+
end
|
24
35
|
def execute
|
25
36
|
if rcp.delay_execution
|
37
|
+
eputs 'Delaying execution...'
|
26
38
|
return
|
27
39
|
else
|
28
40
|
execute_actual
|
@@ -1,109 +1,342 @@
|
|
1
|
+
CodeRunner.setup_run_class('chease')
|
1
2
|
|
3
|
+
class CodeRunner::Chease
|
4
|
+
# We hotwire the execute command so that it just
|
5
|
+
# runs it instead of doing a batch submission
|
6
|
+
def execute
|
7
|
+
system "#{executable}"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
class CodeRunner::Ecom
|
11
|
+
# We hotwire the execute command so that it just
|
12
|
+
# runs it instead of doing a batch submission
|
13
|
+
def execute
|
14
|
+
system "#{executable}"
|
15
|
+
end
|
16
|
+
end
|
2
17
|
class CodeRunner::Trinity::Optimisation
|
3
18
|
include GSL::MultiMin
|
4
|
-
|
5
|
-
|
6
|
-
|
19
|
+
# optimisation_spec is a hash of {:code_name => {:variable => [initial_guess, dimension_scale_factor]}}
|
20
|
+
# dimension_scale_factor is just some estimate of the length scale in which the result
|
21
|
+
# varies significantly
|
7
22
|
# code_name is either trinity or chease (both can be used simultaneously)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
23
|
+
attr_reader :optimisation_spec
|
24
|
+
attr_reader :optimisation_variables
|
25
|
+
attr_accessor :trinity_runner
|
26
|
+
attr_accessor :gs_runner
|
27
|
+
attr_accessor :parameters_obj
|
28
|
+
attr_accessor :results_hash
|
29
|
+
def initialize(optimised_quantity, optimisation_spec)
|
30
|
+
#@folder = folder
|
31
|
+
@optimised_quantity = optimised_quantity
|
32
|
+
@optimisation_spec = optimisation_spec
|
33
|
+
@optimisation_variables = optimisation_spec.map{|code, hash| hash.map{|var, pars| [code, var]}}.flatten(1)
|
34
|
+
@optimisation_starts = optimisation_spec.map{|code, hash| hash.map{|var, pars| pars[0]}}.flatten(1)
|
35
|
+
@optimisation_steps = optimisation_spec.map{|code, hash| hash.map{|var, pars| pars[1]}}.flatten(1)
|
36
|
+
#@runner = CodeRunner.fetch_runner(
|
37
|
+
#p ['optimisation_variables', @optimisation_variables]
|
38
|
+
@results_hash = {}
|
39
|
+
@first_call = true
|
40
|
+
@ifspppl_converged = false
|
41
|
+
end
|
42
|
+
def dimension
|
43
|
+
@optimisation_variables.size
|
44
|
+
end
|
45
|
+
def serial_optimise(optimisation_method, parameters_obj)
|
46
|
+
optimisation_meth = case optimisation_method
|
47
|
+
when :simplex
|
48
|
+
FMinimizer::NMSIMPLEX
|
49
|
+
else
|
50
|
+
raise "Unknown optimisation_method"
|
51
|
+
end
|
52
|
+
@results_hash[:start_time] = Time.now.to_i
|
53
|
+
opt = FMinimizer.alloc(optimisation_meth, @optimisation_variables.size)
|
54
|
+
@parameters_obj = parameters_obj
|
55
|
+
catch(:out_of_time) do
|
33
56
|
func = Proc.new{|v, optimiser| optimiser.func(v)}
|
57
|
+
eputs 'Created func'
|
34
58
|
gsl_func = Function.alloc(func, dimension)
|
59
|
+
eputs 'Allocated gsl_func'
|
35
60
|
gsl_func.set_params(self)
|
61
|
+
eputs 'Set params'
|
36
62
|
opt.set(gsl_func, @optimisation_starts.to_gslv, @optimisation_steps.to_gslv)
|
63
|
+
eputs 'Set func and starting iteration'
|
37
64
|
parameters_obj.nit.times do |i|
|
38
65
|
opt.iterate
|
39
66
|
p ['status', opt.x, opt.minimum, i, parameters_obj.nit]
|
67
|
+
@results_hash[:iterations] ||= []
|
68
|
+
@results_hash[:iterations].push [opt.x.dup, opt.minimum]
|
69
|
+
@results_hash[:elapse_mins] = (Time.now.to_i - @results_hash[:start_time]).to_f/60
|
70
|
+
@results_hash[:current_time] = Time.now.to_i
|
71
|
+
File.open('results', 'w'){|f| f.puts @results_hash.pretty_inspect}
|
72
|
+
end
|
73
|
+
eputs 'Optimisation complete'
|
74
|
+
end
|
75
|
+
eputs 'Optimisation ended'
|
76
|
+
#MPI.Finalize
|
77
|
+
|
78
|
+
end
|
79
|
+
def func(v)
|
80
|
+
val = nil
|
81
|
+
count = 1
|
82
|
+
val_old, repeat = func_actual(v)
|
83
|
+
loop do
|
84
|
+
val, repeat, trinity_is_converged = func_actual(v)
|
85
|
+
if trinity_is_converged # This means that Trinity has reached steady state
|
86
|
+
|
87
|
+
# Now we check if the loop over recalculating the GS equation
|
88
|
+
# has converged
|
89
|
+
if ((val_old - val)/val).abs < @parameters_obj.convergence
|
90
|
+
if @parameters_obj.use_ifspppl_first and not @ifspppl_converged
|
91
|
+
@ifspppl_converged = true
|
92
|
+
else
|
93
|
+
break
|
94
|
+
end
|
95
|
+
end
|
96
|
+
break if count > @parameters_obj.max_func_evals
|
97
|
+
|
98
|
+
# If geometry is being evolved internally in Trinity, we don't
|
99
|
+
# need to run this loop
|
100
|
+
break if not repeat
|
101
|
+
val_old = val
|
102
|
+
#break if not repeat or (not @first_call and count > 1) or count > 4
|
103
|
+
count += 1 unless @parameters_obj.use_ifspppl_first and not @ifspppl_converged
|
40
104
|
end
|
105
|
+
end
|
106
|
+
@first_call = false
|
107
|
+
return val
|
108
|
+
end
|
109
|
+
def func_actual(v)
|
110
|
+
eputs 'Starting func'
|
111
|
+
@id||=1 # Id of the current trinity run which should always be equal to the number of func_actual calls
|
112
|
+
repeat = false
|
113
|
+
print_pars = {}
|
114
|
+
pars = {}
|
115
|
+
pars[:gs] = {}
|
116
|
+
pars[:trinity] = {}
|
117
|
+
pars[:trinity].absorb(@parameters_obj.trinity_pars) if @parameters_obj.trinity_pars
|
118
|
+
pars[:gs].absorb(@parameters_obj.gs_pars) if @parameters_obj.gs_pars
|
119
|
+
for i in 0...v.size
|
120
|
+
code, varname = @optimisation_variables[i]
|
121
|
+
val = v[i]
|
122
|
+
code = case code
|
123
|
+
when :chease, :ecom
|
124
|
+
:gs
|
125
|
+
else
|
126
|
+
:trinity
|
127
|
+
end
|
128
|
+
pars[code][varname] = val
|
129
|
+
print_pars[code] ||={}
|
130
|
+
print_pars[code][varname] = val
|
131
|
+
end
|
132
|
+
if not @first_run_done
|
133
|
+
pars[:trinity][:ntstep] = @parameters_obj.ntstep_first
|
134
|
+
#pars[:trinity][:nifspppl_initial] = -1
|
135
|
+
#pars[:trinity][:niter] = 2
|
136
|
+
|
137
|
+
# The line below assumes that the whole first run is done
|
138
|
+
# with ifspppl, in which case we don't want the timestep to get
|
139
|
+
# too large for the gryfx run afterwards.
|
140
|
+
#pars[:trinity][:ntdelt_max] = 0.05
|
141
|
+
#pars[:trinity][:convergetol] = -1.0
|
142
|
+
else
|
143
|
+
pars[:trinity][:ntstep] = @parameters_obj.ntstep
|
144
|
+
#pars[:trinity][:nifspppl_initial] = -1
|
145
|
+
#pars[:trinity][:niter] = 3
|
146
|
+
#pars[:trinity][:ntdelt_max] = 10.0
|
147
|
+
end
|
148
|
+
if @parameters_obj.use_ifspppl_first and not @ifspppl_converged
|
149
|
+
pars[:trinity][:nifspppl_initial] = pars[:trinity][:ntstep]
|
150
|
+
else
|
151
|
+
pars[:trinity][:nifspppl_initial] = -1
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
# Must fix this soon!
|
156
|
+
if @parameters_obj.gs_code == 'chease'
|
157
|
+
#pars[:gs][:ap] = [0.3,0.5,0.4,0.0,0.4,0.0,0.0]
|
158
|
+
#pars[:gs][:at] = [0.16,1.0,1.0,-1.1,-1.1]
|
159
|
+
end
|
41
160
|
|
42
|
-
|
43
|
-
|
44
|
-
|
161
|
+
trinity_runner.run_class.instance_variable_set(:@mpi_communicator, MPI::Comm::WORLD)
|
162
|
+
#if false and trinity_runner.run_list.size > 0
|
163
|
+
#else
|
164
|
+
if @first_run_done
|
165
|
+
#crun.nppfun=4
|
166
|
+
#crun.neqdsk=0
|
167
|
+
#crun.expeq_file = trinity_runner.run_list[@id]
|
45
168
|
end
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
169
|
+
if not @replay
|
170
|
+
if not @first_run_done and gs_runner.run_list.size > 0
|
171
|
+
#This means we are in a restart
|
172
|
+
@replay = true
|
173
|
+
@nrun = 1
|
174
|
+
if @parameters_obj.delete_final_run
|
175
|
+
eputs 'Removing final run: ' + trinity_runner.run_list.keys.max.to_s
|
176
|
+
trinity_runner.conditions = 'id==' + trinity_runner.run_list.keys.max.to_s
|
177
|
+
trinity_runner.destroy no_confirm: true
|
178
|
+
gs_runner.conditions = 'id==' + gs_runner.run_list.keys.max.to_s
|
179
|
+
gs_runner.destroy no_confirm: true
|
180
|
+
end
|
181
|
+
else
|
182
|
+
@nrun = nil
|
183
|
+
@replay = false
|
54
184
|
end
|
55
|
-
|
56
|
-
|
185
|
+
end
|
186
|
+
if @replay
|
187
|
+
eputs 'Replaying: ' + @nrun.to_s
|
188
|
+
run = trinity_runner.run_list[@nrun]
|
189
|
+
if not run
|
190
|
+
eputs 'Ending replay at ' + @nrun.to_s
|
191
|
+
@replay = false
|
192
|
+
@id = @gsid = @nrun-1
|
57
193
|
else
|
58
|
-
|
59
|
-
pars[:trinity][:ntstep] = 100
|
194
|
+
@id = @gsid = @nrun
|
60
195
|
end
|
196
|
+
@nrun += 1
|
197
|
+
end
|
198
|
+
Hash.phoenix('func_calls.rb') do |hash|
|
199
|
+
hash[@id+1] ||={}
|
200
|
+
hash[@id+1][:variables] = v.dup
|
201
|
+
hash[@id+1][:print_pars] = print_pars
|
202
|
+
hash
|
203
|
+
end
|
204
|
+
#raise "WORK!!"
|
205
|
+
eputs "Written parameters"
|
206
|
+
if not @replay
|
207
|
+
eputs "Not replaying... starting GS and Trinity runs"
|
208
|
+
remaining_wall_mins = (
|
209
|
+
@parameters_obj.wall_mins - @parameters_obj.wall_mins_margin -
|
210
|
+
(Time.now.to_i - @parameters_obj.start_time).to_f / 60.0
|
211
|
+
)
|
212
|
+
eputs "Remaining wall mins #{remaining_wall_mins}, wall mins #{@parameters_obj.wall_mins}, start time #{@parameters_obj.start_time}, time #{Time.now.to_i}, margin #{@parameters_obj.wall_mins_margin}"
|
213
|
+
if remaining_wall_mins < @parameters_obj.wall_mins_margin
|
214
|
+
eputs "Run out of time"
|
215
|
+
throw(:out_of_time)
|
216
|
+
end
|
217
|
+
eputs "Starting real run, @id = ",@id
|
218
|
+
# Create and initialize the gs run
|
219
|
+
gsrun = gs_runner.run_class.new(gs_runner)
|
220
|
+
raise "No gs_defaults strings" unless @parameters_obj.gs_defaults_strings.size > 0
|
221
|
+
@parameters_obj.gs_defaults_strings.each{|prc| gsrun.instance_eval(prc)}
|
222
|
+
if gs_runner.run_list.size > 0
|
223
|
+
#gsrun.restart_id = @gsid
|
224
|
+
if @parameters_obj.gs_code == 'chease'
|
225
|
+
last_converged = @id
|
226
|
+
#We need to find the last converged Trinity run to use as the pressure profile.
|
227
|
+
until last_converged == 0 or trinity_runner.combined_run_list[last_converged].is_converged?
|
228
|
+
eputs "Run #{last_converged} not converged"
|
229
|
+
last_converged -= 1
|
230
|
+
end
|
231
|
+
#unless (@parameters_obj.use_previous_pressure==0 and not @first_trinity_run_completed)
|
232
|
+
unless last_converged == 0
|
233
|
+
eputs "Using previous pressure profile"
|
234
|
+
# We give CHEASE the pressure profile from the previous run.
|
235
|
+
pars[:gs][:nppfun] = 4
|
236
|
+
pars[:gs][:nfunc] = 4
|
237
|
+
#if prid = @parameters_obj.use_previous_pressure and not @first_trinity_run_completed
|
238
|
+
# If the last trinity run did not converge we may want to run exactly
|
239
|
+
# the same case again, and in particular use the pressure profile from
|
240
|
+
# the previous Trinity run as input (as an unconverged pressure profile
|
241
|
+
# can lead to a wacky GS solution)
|
242
|
+
#gsrun.expeq_in=trinity_runner.combined_run_list[prid].directory + '/chease/EXPEQ.NOSURF'
|
243
|
+
#else
|
244
|
+
gsrun.expeq_in=trinity_runner.combined_run_list[last_converged].directory + '/chease/EXPEQ.NOSURF'
|
245
|
+
#end
|
246
|
+
# Don't optimise presssure profile.
|
247
|
+
pars[:gs][:nblopt] = 0
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
gsrun.update_submission_parameters(pars[:gs].inspect, false)
|
61
252
|
|
62
|
-
|
63
|
-
|
253
|
+
# Create and initialize the trinity run
|
254
|
+
run = trinity_runner.run_class.new(trinity_runner)
|
255
|
+
raise "No trinity_defaults_strings" unless @parameters_obj.trinity_defaults_strings.size > 0
|
256
|
+
run.instance_variable_set(:@set_flux_defaults_procs, []) unless run.instance_variable_get(:@set_flux_defaults_procs)
|
257
|
+
@parameters_obj.trinity_defaults_strings.each{|prc| run.instance_eval(prc)}
|
258
|
+
run.update_submission_parameters(pars[:trinity].inspect, false)
|
64
259
|
|
260
|
+
#if @parameters_obj.gs_code == 'chease' and (run.evolve_geometry and run.evolve_geometry.fortran_true?)
|
261
|
+
#pars[:gs][:nblopt] = 0
|
262
|
+
#end
|
263
|
+
gs_runner.submit(gsrun)
|
264
|
+
gsrun = gs_runner.run_list[@gsid = gs_runner.max_id]
|
265
|
+
gsrun.recheck
|
266
|
+
gs_runner.update
|
267
|
+
#gs_runner.print_out(0)
|
268
|
+
#FileUtils.cp(gsrun.directory + '/ogyropsi.dat', trinity_runner.root_folder + '/.')
|
65
269
|
|
66
|
-
|
67
|
-
|
270
|
+
run.gs_folder = gsrun.directory
|
271
|
+
while (
|
272
|
+
not FileTest.exist? run.gs_folder + '/ogyropsi.dat' or
|
273
|
+
File.read(run.gs_folder + '/ogyropsi.dat') =~ /nan/i
|
274
|
+
)
|
275
|
+
#eputs "GS solver failed: using previous solution"
|
276
|
+
|
277
|
+
gs_runner.conditions = 'id == ' + @gsid.to_s
|
278
|
+
gs_runner.destroy(no_confirm: true)
|
279
|
+
gs_runner.conditions = nil
|
280
|
+
eputs "GS solver failed for #{v.inspect}: returning 10000"
|
281
|
+
return [10000, false]
|
282
|
+
#run.gs_folder = gs_runner.run_list[@gsid -= 1].directory
|
283
|
+
end
|
284
|
+
#run.evolve_geometry = ".true."
|
285
|
+
eputs ['Set gs_folder', run.gs_folder]
|
286
|
+
trinity_runner.run_class.instance_variable_set(:@delay_execution, true)
|
287
|
+
if trinity_runner.run_list.size > 0
|
288
|
+
run.restart_id = @id
|
68
289
|
else
|
69
|
-
crun = chease_runner.run_class.new(chease_runner)
|
70
|
-
crun.update_submission_parameters(pars[:chease].inspect)
|
71
|
-
if @first_run_done
|
72
|
-
#crun.nppfun=4
|
73
|
-
#crun.neqdsk=0
|
74
|
-
#crun.expeq_file = trinity_runner.run_list[@id]
|
75
|
-
end
|
76
|
-
if chease_runner.run_list.size > 0
|
77
|
-
crun.restart_id = @cid
|
78
|
-
end
|
79
|
-
chease_runner.submit(crun)
|
80
|
-
crun = chease_runner.run_list[@cid = chease_runner.max_id]
|
81
|
-
crun.recheck
|
82
|
-
chease_runner.update
|
83
|
-
#chease_runner.print_out(0)
|
84
|
-
#FileUtils.cp(crun.directory + '/ogyropsi.dat', trinity_runner.root_folder + '/.')
|
85
|
-
|
86
|
-
run = trinity_runner.run_class.new(trinity_runner)
|
87
|
-
|
88
|
-
run.update_submission_parameters(pars[:trinity].inspect)
|
89
|
-
run.gs_folder = crun.directory
|
90
|
-
run.evolve_geometry = ".true."
|
91
|
-
#trinity_runner.run_class.instance_variable_set(:@delay_execution, true)
|
92
|
-
if trinity_runner.run_list.size > 0
|
93
|
-
run.restart_id = @id
|
94
|
-
end
|
95
|
-
trinity_runner.submit(run)
|
96
|
-
run = trinity_runner.run_list[@id = trinity_runner.max_id]
|
97
|
-
run.recheck
|
98
|
-
trinity_runner.update
|
99
|
-
#trinity_runner.print_out(0)
|
100
|
-
result = run.send(@optimised_quantity)
|
101
|
-
p ['result is ', result]
|
102
|
-
@first_run_done = true
|
103
|
-
return -result
|
104
290
|
end
|
291
|
+
eputs 'Submitting run'
|
292
|
+
run.wall_mins = remaining_wall_mins
|
293
|
+
trinity_runner.submit(run)
|
294
|
+
run = trinity_runner.run_list[@id = trinity_runner.max_id]
|
105
295
|
|
106
296
|
|
107
|
-
|
297
|
+
comm = MPI::Comm::WORLD
|
298
|
+
arr = NArray.int(1)
|
299
|
+
arr[0] = 1
|
300
|
+
eputs 'Sending message'
|
301
|
+
comm.Bcast(arr,0)
|
302
|
+
comm.Bcast_string(run.directory)
|
303
|
+
comm.Bcast_string(run.run_name)
|
304
|
+
eputs 'Running trinity'
|
305
|
+
Dir.chdir(run.directory){run.run_trinity(run.run_name+'.trin', comm)}
|
306
|
+
eputs 'Rechecking'
|
307
|
+
trinity_runner.update
|
308
|
+
eputs 'Queue', run.queue_status
|
309
|
+
|
310
|
+
trinity_runner.update
|
311
|
+
@first_trinity_run_completed
|
312
|
+
end # if not @replay
|
313
|
+
#trinity_runner.print_out(0)
|
314
|
+
Dir.chdir(run.directory) do
|
315
|
+
run.recheck
|
316
|
+
run.status = :Complete
|
317
|
+
run.get_global_results
|
318
|
+
if (run.evolve_geometry and run.evolve_geometry.fortran_true?)
|
319
|
+
repeat = false
|
320
|
+
else
|
321
|
+
repeat = true
|
322
|
+
end
|
323
|
+
end
|
324
|
+
result = run.instance_eval(@optimised_quantity)
|
325
|
+
p ['result is ', result, 'repeat: ', repeat]
|
326
|
+
@first_run_done = true
|
327
|
+
@results_hash[:func_calls] ||=[]
|
328
|
+
@results_hash[:func_calls].push [print_pars, result]
|
329
|
+
Hash.phoenix('func_calls.rb') do |hash|
|
330
|
+
hash[@id] ||={}
|
331
|
+
hash[@id][:result] = result
|
332
|
+
hash[@id][:repeat] = repeat
|
333
|
+
hash[@id][:is_converged] = run.is_converged?
|
334
|
+
hash
|
108
335
|
end
|
336
|
+
return [-result, repeat, run.is_converged?]
|
337
|
+
#end
|
338
|
+
|
339
|
+
|
340
|
+
#v.square.sum
|
341
|
+
end
|
109
342
|
end
|
data/lib/trinoptcrmod/trinopt.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
-
|
1
|
+
require 'mpi'
|
2
2
|
class CodeRunner
|
3
3
|
# This is a customised subclass of the CodeRunner::Run class which is designed to run the CodeRunner/Trinity optimisation framework
|
4
4
|
#
|
5
|
+
CodeRunner.setup_run_class('trinity')
|
6
|
+
CodeRunner.setup_run_class('chease')
|
5
7
|
class Trinopt < Run
|
6
8
|
|
9
|
+
|
7
10
|
# Where this file is
|
8
11
|
@code_module_folder = File.dirname(File.expand_path(__FILE__)) # i.e. the directory this file is in
|
9
12
|
|
@@ -18,16 +21,56 @@ class CodeRunner
|
|
18
21
|
|
19
22
|
@code_long="CodeRunner/Trinity Optimisation Framework"
|
20
23
|
|
21
|
-
@run_info=[:time, :is_a_restart, :restart_id, :restart_run_name, :completed_steps, :percent_complete]
|
24
|
+
@run_info=[:time, :is_a_restart, :restart_id, :restart_run_name, :completed_steps, :percent_complete, :start_time]
|
22
25
|
|
23
26
|
@variables = [
|
24
27
|
:chease_exec,
|
28
|
+
:ecom_exec,
|
25
29
|
:output,
|
26
30
|
:search,
|
27
31
|
:trinity_defaults,
|
32
|
+
:trinity_defaults_strings,
|
28
33
|
:gs_defaults,
|
29
|
-
:
|
34
|
+
:chease_defaults_strings,
|
35
|
+
:ecom_defaults_strings,
|
36
|
+
:nit,
|
37
|
+
:ntstep_first,
|
38
|
+
:ntstep,
|
39
|
+
:delete_final_run,
|
40
|
+
:trinity_pars,
|
41
|
+
:chease_pars,
|
42
|
+
:ecom_pars,
|
43
|
+
:gs_code,
|
44
|
+
:convergence,
|
45
|
+
:max_func_evals,
|
46
|
+
:use_previous_pressure,
|
47
|
+
:use_ifspppl_first,
|
48
|
+
:wall_mins_margin
|
30
49
|
]
|
50
|
+
def gs_defaults_strings
|
51
|
+
case @gs_code
|
52
|
+
when 'chease'
|
53
|
+
@chease_defaults_strings ||= @gs_defaults_strings # For backwards compatibility
|
54
|
+
else
|
55
|
+
@ecom_defaults_strings
|
56
|
+
end
|
57
|
+
end
|
58
|
+
def gs_defaults_strings=(strs)
|
59
|
+
@chease_defaults_strings = strs
|
60
|
+
end
|
61
|
+
def gs_pars
|
62
|
+
case @gs_code
|
63
|
+
when 'chease'
|
64
|
+
@chease_pars ||= @gs_pars
|
65
|
+
when 'ecom'
|
66
|
+
@gs_pars
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# For backwards compatibility
|
71
|
+
def gs_pars=(pars)
|
72
|
+
@chease_pars = pars
|
73
|
+
end
|
31
74
|
|
32
75
|
@uses_mpi = true
|
33
76
|
|
@@ -36,7 +79,32 @@ class CodeRunner
|
|
36
79
|
@naming_pars = []
|
37
80
|
|
38
81
|
# Any folders which are a number will contain the results from flux simulations.
|
39
|
-
@excluded_sub_folders = ['trinity_runs', '
|
82
|
+
@excluded_sub_folders = ['trinity_runs', 'gs_runs']
|
83
|
+
|
84
|
+
def initialize(*args)
|
85
|
+
@trinity_defaults_strings = []
|
86
|
+
@chease_defaults_strings = []
|
87
|
+
@ecom_defaults_strings = []
|
88
|
+
@convergence = 0.05
|
89
|
+
@max_func_evals = 4
|
90
|
+
@wall_mins_margin = 5.0
|
91
|
+
@wall_mins = 1.0e10
|
92
|
+
super(*args)
|
93
|
+
end
|
94
|
+
def evaluate_defaults_file(filename)
|
95
|
+
text = File.read(filename)
|
96
|
+
instance_eval(text)
|
97
|
+
text.scan(/^\s*@(\w+)/) do
|
98
|
+
var_name = $~[1].to_sym
|
99
|
+
next if var_name == :defaults_file_description
|
100
|
+
next if var_name == :code_run_environment
|
101
|
+
unless rcp.variables.include? var_name or (CodeRunner::Trinity.rcp.variables.include? var_name) or (CodeRunner::Chease.rcp.variables.include? var_name or CodeRunner::Gryfx.rcp.variables.include? var_name or CodeRunner::Gs2.rcp.variables.include? var_name or CodeRunner::Ecom.rcp.variables.include? var_name)
|
102
|
+
warning("---#{var_name}---, specified in #{File.expand_path(filename)}, is not a variable. This could be an error")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
eputs '@nstep_is', @nstep
|
106
|
+
eputs '@nstep_first', @nstep_first
|
107
|
+
end
|
40
108
|
|
41
109
|
# A hook which gets called when printing the standard run information to the screen using the status command.
|
42
110
|
def print_out_line
|
@@ -64,63 +132,133 @@ class CodeRunner
|
|
64
132
|
new_run.is_a_restart = true
|
65
133
|
new_run.restart_id = @id
|
66
134
|
new_run.restart_run_name = @run_name
|
67
|
-
new_run.nopt = -1
|
68
135
|
new_run.run_name = nil
|
69
136
|
new_run.naming_pars = @naming_pars
|
70
137
|
new_run.update_submission_parameters(new_run.parameter_hash.inspect, false) if new_run.parameter_hash
|
138
|
+
new_run.trinity_pars = @trinity_pars.absorb(new_run.trinity_pars) if @trinity_pars and new_run.trinity_pars
|
71
139
|
new_run.naming_pars.delete(:restart_id)
|
72
140
|
new_run.generate_run_name
|
73
|
-
raise "
|
141
|
+
raise "trinity_runs directory already exists" if FileTest.exist? new_run.directory + '/trinity_runs'
|
142
|
+
FileUtils.ln_s(@directory + '/trinity_runs', new_run.directory + '/trinity_runs')
|
143
|
+
FileUtils.ln_s(@directory + '/gs_runs', new_run.directory + '/gs_runs')
|
74
144
|
end
|
75
145
|
# This is a hook which gets called just before submitting a simulation. It sets up the folder and generates any necessary input files.
|
76
146
|
def generate_input_file
|
77
147
|
check_parameters
|
78
148
|
if @restart_id
|
79
149
|
@runner.run_list[@restart_id].restart(self)
|
150
|
+
else
|
151
|
+
FileUtils.makedirs('trinity_runs')
|
152
|
+
FileUtils.makedirs('gs_runs')
|
80
153
|
end
|
81
154
|
File.open("driver_script.rb", "w"){|f| f.puts optimisation_script}
|
82
|
-
FileUtils.
|
83
|
-
FileUtils.
|
84
|
-
FileUtils.ln_s("../../#{@trinity_defaults}_defaults.rb", "trinity_runs")
|
85
|
-
FileUtils.ln_s("../../#{@gs_defaults}_defaults.rb", "gs_runs")
|
155
|
+
#FileUtils.ln_s("../../#{@trinity_defaults}_defaults.rb", "trinity_runs")
|
156
|
+
#FileUtils.ln_s("../../#{@gs_defaults}_defaults.rb", "gs_runs")
|
86
157
|
save
|
87
158
|
end
|
88
159
|
|
89
160
|
def optimisation_script
|
90
161
|
return <<EOF
|
91
|
-
require '
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
162
|
+
require 'mpi'
|
163
|
+
class MPI::Comm
|
164
|
+
def Bcast_string(str)
|
165
|
+
@arr = NArray.int(1)
|
166
|
+
if rank==0
|
167
|
+
@arr[0] = str.length
|
168
|
+
Bcast(@arr, 0)
|
169
|
+
Bcast(str, 0)
|
170
|
+
else
|
171
|
+
Bcast(@arr,0)
|
172
|
+
str << " " while str.length < @arr[0]
|
173
|
+
Bcast(str,0)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
puts 'Initializing mpi'
|
178
|
+
MPI.Init
|
179
|
+
comm = MPI::Comm::WORLD
|
180
|
+
rank = comm.rank
|
181
|
+
puts ['Rank is: ', rank]
|
182
|
+
if rank==0
|
183
|
+
begin
|
184
|
+
require 'coderunner'
|
185
|
+
CodeRunner.setup_run_class('trinity')
|
186
|
+
CodeRunner.setup_run_class('trinopt')
|
187
|
+
require 'trinitycrdriver'
|
188
|
+
require 'trinitycrdriver/optimisation'
|
189
|
+
CodeRunner::Trinopt.run_optimisation(#@id)
|
190
|
+
rescue =>err
|
191
|
+
arr = NArray.int(1)
|
192
|
+
arr[0] = 0
|
193
|
+
comm.Bcast(arr,0)
|
194
|
+
raise err
|
195
|
+
end
|
196
|
+
arr = NArray.int(1)
|
197
|
+
arr[0] = 0
|
198
|
+
comm.Bcast(arr,0)
|
199
|
+
else
|
200
|
+
require 'trinitycrdriver'
|
201
|
+
arr = NArray.int(1)
|
202
|
+
puts "Proc \#{comm.rank} waiting for message"
|
203
|
+
loop do
|
204
|
+
comm.Bcast(arr, 0)
|
205
|
+
puts "Proc \#{comm.rank} received instructions: \#{arr[0]}"
|
206
|
+
dir = ""
|
207
|
+
run_name = ""
|
208
|
+
if arr[0] == 1
|
209
|
+
comm.Bcast_string(dir)
|
210
|
+
comm.Bcast_string(run_name)
|
211
|
+
puts "Proc \#{comm.rank} calling Trinity with run_name: \#{run_name}"
|
212
|
+
Dir.chdir(dir){CodeRunner::Trinity.new.run_trinity(run_name+'.trin', comm)}
|
213
|
+
else
|
214
|
+
break
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
MPI.Finalize
|
97
219
|
EOF
|
98
220
|
end
|
99
221
|
|
100
222
|
def check_parameters
|
223
|
+
if delete_final_run
|
224
|
+
raise CRFatal.new("Cancelled submission") unless Feedback.get_boolean("You have set delete_final_run which will cause the final run to be deleted. Is this correct?")
|
225
|
+
end
|
101
226
|
end
|
102
227
|
|
103
228
|
|
104
229
|
def self.run_optimisation(id = ARGV[-1])
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
230
|
+
eputs 'Fetching runner'
|
231
|
+
runner = CodeRunner.fetch_runner(Y: '../../', U: true)
|
232
|
+
eputs 'Got runner'
|
233
|
+
#@run = @runner.run_list[id.to_i]
|
234
|
+
#run = self.load(Dir.pwd, runner)
|
235
|
+
run = self.new(runner)
|
236
|
+
run.read_info
|
237
|
+
run.start_time = Time.now.to_i
|
238
|
+
eputs 'Loaded run'
|
239
|
+
#ep @run
|
240
|
+
#raise "Can't find run with id #{id}; #{@runner.run_list.keys}" unless @run
|
241
|
+
opt = CodeRunner::Trinity::Optimisation.new(
|
242
|
+
run.output, run.search
|
243
|
+
)
|
244
|
+
eputs 'Created opt'
|
245
|
+
trinity_runner = CodeRunner.fetch_runner(Y: 'trinity_runs', X: '/dev/null', C: 'trinity')
|
246
|
+
trinity_runner.nprocs = MPI::Comm::WORLD.size
|
247
|
+
eputs 'Got trinity runner'
|
248
|
+
case run.gs_code
|
249
|
+
when 'chease'
|
250
|
+
gs_runner = CodeRunner.fetch_runner(Y: 'gs_runs', X: run.chease_exec, C: 'chease')
|
251
|
+
gs_runner.nprocs = '1'
|
252
|
+
when 'ecom'
|
253
|
+
gs_runner = CodeRunner.fetch_runner(Y: 'gs_runs', X: run.ecom_exec, C: 'ecom')
|
254
|
+
gs_runner.nprocs = '1'
|
255
|
+
else
|
256
|
+
raise "Unknown gs_code #{run.gs_code.inspect}"
|
257
|
+
end
|
258
|
+
eputs 'Got gs runner'
|
259
|
+
opt.trinity_runner = trinity_runner
|
260
|
+
opt.gs_runner = gs_runner
|
261
|
+
opt.serial_optimise(:simplex, run)
|
124
262
|
end
|
125
263
|
|
126
264
|
|
@@ -169,6 +307,60 @@ EOF
|
|
169
307
|
''
|
170
308
|
end
|
171
309
|
|
310
|
+
def graphkit(name, options)
|
311
|
+
results = eval(File.read(@directory + '/results'))
|
312
|
+
case name
|
313
|
+
when 'evolution'
|
314
|
+
data = {}
|
315
|
+
pars_already_listed = []
|
316
|
+
results[:func_calls].reverse.each do |pars, res|
|
317
|
+
next if pars_already_listed.include? pars
|
318
|
+
pars_already_listed.push pars
|
319
|
+
pars.each do |code,cpars|
|
320
|
+
cpars.each do |vname, val|
|
321
|
+
label = "#{code}_#{vname}"
|
322
|
+
data[label] ||= []
|
323
|
+
data[label].push val
|
324
|
+
end
|
325
|
+
end
|
326
|
+
data['results']||=[]
|
327
|
+
data['results'].push res
|
328
|
+
end
|
329
|
+
kit = GraphKit.quick_create(data.values)
|
330
|
+
data.keys.zip(GraphKit::AXES).each{|lbl,ax| kit.set(ax + :label, lbl)}
|
331
|
+
kit
|
332
|
+
when 'iteration'
|
333
|
+
require 'tokfile/ogyropsi'
|
334
|
+
step = options[:step_index]
|
335
|
+
raise "Please specify step_index" unless step
|
336
|
+
iter, _trinstep = trinrunstep(step)[0]
|
337
|
+
kit = TokFile::Ogyropsi.new("#@directory/trinity_runs/v/id_#{iter}/chease/ogyropsi#{sprintf("%05d", step)}.dat").summary_graphkit
|
338
|
+
kit.gp.multiplot = " layout 3,3 title 'Iteration: #{iter}; Step: #{step}; Pars: #{results[:func_calls][iter-1][0]}; Result: #{results[:func_calls][iter-1][1].inspect}'"
|
339
|
+
kit[-1].gp.size = "ratio 1"
|
340
|
+
#pp 'kit', kit
|
341
|
+
return kit
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
def trinstep_mappings
|
346
|
+
@trinstep_mappings = (
|
347
|
+
trinity_runner = CodeRunner.fetch_runner(Y: @directory + '/trinity_runs')
|
348
|
+
sizes = trinity_runner.run_list.values.sort_by{|r| r.id}.map{|r| r.get_completed_timesteps; r.completed_timesteps}
|
349
|
+
i = 0; cs = 0
|
350
|
+
sizes.inject({}){|h,sz| cs+=sz; h[i+=1]=cs; h}
|
351
|
+
)
|
352
|
+
end
|
353
|
+
|
354
|
+
def trinrunstep(overall_step)
|
355
|
+
p 'trinstep_mappings', trinstep_mappings
|
356
|
+
trinrun, cusum = trinstep_mappings.to_a.find{|t, c| c>=overall_step}
|
357
|
+
[trinrun, cusum-overall_step + 1]
|
358
|
+
end
|
359
|
+
|
360
|
+
def max_step
|
361
|
+
trinstep_mappings[-1][1]
|
362
|
+
end
|
363
|
+
|
172
364
|
end
|
173
365
|
end
|
174
366
|
|
data/trinitycrdriver.gemspec
CHANGED
@@ -2,17 +2,17 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: trinitycrdriver 0.1.
|
5
|
+
# stub: trinitycrdriver 0.1.2 ruby lib
|
6
6
|
# stub: ext/trinitycrdriver/extconf.rb
|
7
7
|
|
8
8
|
Gem::Specification.new do |s|
|
9
9
|
s.name = "trinitycrdriver"
|
10
|
-
s.version = "0.1.
|
10
|
+
s.version = "0.1.2"
|
11
11
|
|
12
12
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
13
13
|
s.require_paths = ["lib"]
|
14
14
|
s.authors = ["Edmund Highcock"]
|
15
|
-
s.date = "
|
15
|
+
s.date = "2016-06-06"
|
16
16
|
s.description = "A gem to allow coderunner to run the trinity code directly."
|
17
17
|
s.email = "edmundhighcock@users.sourceforge.net"
|
18
18
|
s.extensions = ["ext/trinitycrdriver/extconf.rb"]
|
@@ -38,7 +38,7 @@ Gem::Specification.new do |s|
|
|
38
38
|
]
|
39
39
|
s.homepage = "http://github.com/edmundhighcock/trinitycrdriver"
|
40
40
|
s.licenses = ["GPLv3"]
|
41
|
-
s.rubygems_version = "2.
|
41
|
+
s.rubygems_version = "2.2.0"
|
42
42
|
s.summary = "A gem to allow coderunner to run the trinity code directly via a C interface."
|
43
43
|
|
44
44
|
if s.respond_to? :specification_version then
|
@@ -48,9 +48,10 @@ Gem::Specification.new do |s|
|
|
48
48
|
s.add_runtime_dependency(%q<coderunner>, [">= 0.14.2"])
|
49
49
|
s.add_runtime_dependency(%q<text-data-tools>, [">= 1.1.3"])
|
50
50
|
s.add_runtime_dependency(%q<gs2crmod>, [">= 0.11.33"])
|
51
|
-
s.add_runtime_dependency(%q<trinitycrmod>, [">= 0.
|
51
|
+
s.add_runtime_dependency(%q<trinitycrmod>, [">= 0.7.11"])
|
52
52
|
s.add_runtime_dependency(%q<ruby-mpi>, [">= 0.2.0"])
|
53
53
|
s.add_runtime_dependency(%q<cheasecrmod>, [">= 0.1.0"])
|
54
|
+
s.add_runtime_dependency(%q<tokfile>, [">= 0.0.3"])
|
54
55
|
s.add_development_dependency(%q<shoulda>, ["= 3.0.1"])
|
55
56
|
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
56
57
|
s.add_development_dependency(%q<bundler>, ["> 1.0.0"])
|
@@ -62,9 +63,10 @@ Gem::Specification.new do |s|
|
|
62
63
|
s.add_dependency(%q<coderunner>, [">= 0.14.2"])
|
63
64
|
s.add_dependency(%q<text-data-tools>, [">= 1.1.3"])
|
64
65
|
s.add_dependency(%q<gs2crmod>, [">= 0.11.33"])
|
65
|
-
s.add_dependency(%q<trinitycrmod>, [">= 0.
|
66
|
+
s.add_dependency(%q<trinitycrmod>, [">= 0.7.11"])
|
66
67
|
s.add_dependency(%q<ruby-mpi>, [">= 0.2.0"])
|
67
68
|
s.add_dependency(%q<cheasecrmod>, [">= 0.1.0"])
|
69
|
+
s.add_dependency(%q<tokfile>, [">= 0.0.3"])
|
68
70
|
s.add_dependency(%q<shoulda>, ["= 3.0.1"])
|
69
71
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
70
72
|
s.add_dependency(%q<bundler>, ["> 1.0.0"])
|
@@ -77,9 +79,10 @@ Gem::Specification.new do |s|
|
|
77
79
|
s.add_dependency(%q<coderunner>, [">= 0.14.2"])
|
78
80
|
s.add_dependency(%q<text-data-tools>, [">= 1.1.3"])
|
79
81
|
s.add_dependency(%q<gs2crmod>, [">= 0.11.33"])
|
80
|
-
s.add_dependency(%q<trinitycrmod>, [">= 0.
|
82
|
+
s.add_dependency(%q<trinitycrmod>, [">= 0.7.11"])
|
81
83
|
s.add_dependency(%q<ruby-mpi>, [">= 0.2.0"])
|
82
84
|
s.add_dependency(%q<cheasecrmod>, [">= 0.1.0"])
|
85
|
+
s.add_dependency(%q<tokfile>, [">= 0.0.3"])
|
83
86
|
s.add_dependency(%q<shoulda>, ["= 3.0.1"])
|
84
87
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
85
88
|
s.add_dependency(%q<bundler>, ["> 1.0.0"])
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trinitycrdriver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Edmund Highcock
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-06-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: coderunner
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.
|
61
|
+
version: 0.7.11
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.
|
68
|
+
version: 0.7.11
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: ruby-mpi
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: 0.1.0
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: tokfile
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.0.3
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.0.3
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: shoulda
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -235,7 +249,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
235
249
|
version: '0'
|
236
250
|
requirements: []
|
237
251
|
rubyforge_project:
|
238
|
-
rubygems_version: 2.
|
252
|
+
rubygems_version: 2.2.0
|
239
253
|
signing_key:
|
240
254
|
specification_version: 4
|
241
255
|
summary: A gem to allow coderunner to run the trinity code directly via a C interface.
|