trinitycrdriver 0.1.1 → 0.1.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 99d128788dbcf852da53d869d20f874b57cdb6b4
4
- data.tar.gz: eca654dc62344fc0f941784cb60c3c65b6779ea5
3
+ metadata.gz: be3b3ef7a8135177b9176f17971baf754f62c114
4
+ data.tar.gz: 26d256bd34c004714b8ad5e0b7f035ef235110b3
5
5
  SHA512:
6
- metadata.gz: 9098ed22b3dd3371c01c81728d3d83d8c6b11b3f51d0058c4dab0bc2926e2a8e0e9f4e1135b5f6e71fb9d5408cf86f8c2d5b63a37a06a891a4a9e70dce5c0523
7
- data.tar.gz: 1a726053cdedf417eefa3b2634536592bdd5089c7781b5cbd125bb88af2e093aee0ef16582e4498cd8945c6bf0e550d0e56a895d31fe45f4573044432a44f0b0
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.4.7"
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
1
+ 0.1.2
@@ -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, :int], :void
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
- # optimisation_spec is a hash of {:code_name => {:variable => [initial_guess, dimension_scale_factor]}}
5
- # dimension_scale_factor is just some estimate of the length scale in which the result
6
- # varies significantly
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
- attr_reader :optimisation_spec
9
- attr_reader :optimisation_variables
10
- attr_accessor :trinity_runner
11
- attr_accessor :chease_runner
12
- def initialize(optimised_quantity, optimisation_spec)
13
- #@folder = folder
14
- @optimised_quantity = optimised_quantity
15
- @optimisation_spec = optimisation_spec
16
- @optimisation_variables = optimisation_spec.map{|code, hash| hash.map{|var, pars| [code, var]}}.flatten(1)
17
- @optimisation_starts = optimisation_spec.map{|code, hash| hash.map{|var, pars| pars[0]}}.flatten(1)
18
- @optimisation_steps = optimisation_spec.map{|code, hash| hash.map{|var, pars| pars[1]}}.flatten(1)
19
- #@runner = CodeRunner.fetch_runner(
20
- #p ['optimisation_variables', @optimisation_variables]
21
- end
22
- def dimension
23
- @optimisation_variables.size
24
- end
25
- def serial_optimise(optimisation_method, parameters_obj)
26
- optimisation_meth = case optimisation_method
27
- when :simplex
28
- FMinimizer::NMSIMPLEX
29
- else
30
- raise "Unknown optimisation_method"
31
- end
32
- opt = FMinimizer.alloc(optimisation_meth, @optimisation_variables.size)
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
- p 'heellllllo'
43
- MPI.Finalize
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
- def func(v)
47
- pars = {}
48
- pars[:chease] = {}
49
- pars[:trinity] = {}
50
- for i in 0...v.size
51
- code, varname = @optimisation_variables[i]
52
- val = v[i]
53
- pars[code][varname] = val
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
- if not @first_run_done
56
- pars[:trinity][:ntstep] = 300
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
- #pars[:trinity].delete(:ntstep)
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
- pars[:chease][:ap] = [0.3,0.5,0.4,0.0,0.4,0.0,0.0]
63
- pars[:chease][:at] = [0.16,1.0,1.0,-1.1,-1.1]
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
- trinity_runner.run_class.instance_variable_set(:@mpi_communicator, MPI::Comm::WORLD)
67
- if false and trinity_runner.run_list.size > 0
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
- #v.square.sum
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
@@ -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
- :nit
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', 'chease_runs', 'ecom_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 "This function is not complete"
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.makedirs('trinity_runs')
83
- FileUtils.makedirs('gs_runs')
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 'coderunner'
92
- CodeRunner.setup_run_class('trinity')
93
- CodeRunner.setup_run_class('trinopt')
94
- require 'trinitycrdriver'
95
- require 'trinitycrdriver/optimisation'
96
- CodeRunner::Trinopt.run_optimisation(#@id)
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
- MPI.Init
106
- @runner = CodeRunner.fetch_runner(Y: '../../', U: true)
107
- #@run = @runner.run_list[id.to_i]
108
- @run = self.load(Dir.pwd, @runner)
109
- #raise "Can't find run with id #{id}; #{@runner.run_list.keys}" unless @run
110
- opt = CodeRunner::Trinity::Optimisation.new(
111
- @run.output, @run.search
112
- )
113
- @trinity_runner = CodeRunner.fetch_runner(Y: 'trinity_runs', X: '/dev/null', C: 'trinity', D: @run.trinity_defaults)
114
- @trinity_runner.nprocs = MPI::Comm::WORLD.size
115
- @chease_runner = CodeRunner.fetch_runner(Y: 'gs_runs', X: @run.chease_exec, C: 'chease', D: @run.gs_defaults)
116
- @chease_runner.nprocs = '1'
117
- #Dir.chdir('trinity_runs'){@trinity_runner.run_class.use_new_defaults_file('rake_test_opt', 'ifspppl_chease_input.trin')}
118
- #Dir.chdir(tfolderchease){@chease_runner.run_class.use_new_defaults_file('rake_test_opt_chease', 'chease_example.in')}
119
- #assert_equal([:trinity, :powerin], opt.optimisation_variables[0])
120
- opt.trinity_runner = @trinity_runner
121
- opt.chease_runner = @chease_runner
122
- opt.serial_optimise(:simplex, @run)
123
- MPI.Finalize
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
 
@@ -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.1 ruby lib
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.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 = "2015-07-28"
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.4.8"
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.4.7"])
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.4.7"])
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.4.7"])
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.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: 2015-07-28 00:00:00.000000000 Z
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.4.7
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.4.7
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.4.8
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.