131
131
<tr class="marked">
132
<td><pre><a name="line13">13</a> public </pre></td>
137
<tr class="inferred">
138
<td><pre><a name="line14">14</a> </pre></td>
144
<td><pre><a name="line15">15</a> def neptune_ssa_run_job(nodes, job_data, secret)</pre></td>
149
<tr class="uncovered">
150
<td><pre><a name="line16">16</a> return BAD_SECRET_MSG unless valid_secret?(secret)</pre></td>
155
<tr class="uncovered">
156
<td><pre><a name="line17">17</a> Djinn.log_debug("ssa - run")</pre></td>
161
<tr class="uncovered">
162
<td><pre><a name="line18">18</a> </pre></td>
167
<tr class="uncovered">
168
<td><pre><a name="line19">19</a> Thread.new {</pre></td>
173
<tr class="uncovered">
174
<td><pre><a name="line20">20</a> start_time = Time.now</pre></td>
179
<tr class="uncovered">
180
<td><pre><a name="line21">21</a> total_compute_time = 0</pre></td>
185
<tr class="uncovered">
186
<td><pre><a name="line22">22</a> total_storage_time = 0</pre></td>
191
<tr class="uncovered">
192
<td><pre><a name="line23">23</a> total_slowest_path = 0</pre></td>
197
<tr class="uncovered">
198
<td><pre><a name="line24">24</a> c_times = []</pre></td>
203
<tr class="uncovered">
204
<td><pre><a name="line25">25</a> s_times = []</pre></td>
209
<tr class="uncovered">
210
<td><pre><a name="line26">26</a> </pre></td>
215
<tr class="uncovered">
216
<td><pre><a name="line27">27</a> Djinn.log_debug("job data is #{job_data.inspect}")</pre></td>
221
<tr class="uncovered">
222
<td><pre><a name="line28">28</a> keyname = @creds['keyname']</pre></td>
227
<tr class="uncovered">
228
<td><pre><a name="line29">29</a> </pre></td>
233
<tr class="uncovered">
234
<td><pre><a name="line30">30</a> nodes = Djinn.convert_location_array_to_class(nodes, keyname)</pre></td>
239
<tr class="uncovered">
240
<td><pre><a name="line31">31</a> </pre></td>
245
<tr class="uncovered">
246
<td><pre><a name="line32">32</a> sims = neptune_get_ssa_num_simulations(nodes, job_data)</pre></td>
251
<tr class="uncovered">
252
<td><pre><a name="line33">33</a> </pre></td>
257
<tr class="uncovered">
258
<td><pre><a name="line34">34</a> working_dir = "/tmp/ssa-#{rand(10000)}"</pre></td>
263
<tr class="uncovered">
264
<td><pre><a name="line35">35</a> FileUtils.mkdir_p(working_dir)</pre></td>
269
<tr class="uncovered">
270
<td><pre><a name="line36">36</a> </pre></td>
275
<tr class="uncovered">
276
<td><pre><a name="line37">37</a> tar = working_dir + "/" + File.basename(job_data['@tar'])</pre></td>
132
<td><pre><a name="line13">13</a> MULTICORE = true</pre></td>
138
<td><pre><a name="line14">14</a> SSA_HOME = "/usr/local/StochKit2.0/"</pre></td>
143
<tr class="inferred">
144
<td><pre><a name="line15">15</a> </pre></td>
149
<tr class="inferred">
150
<td><pre><a name="line16">16</a> </pre></td>
156
<td><pre><a name="line17">17</a> IS_FILE = true</pre></td>
162
<td><pre><a name="line18">18</a> NOT_A_FILE = false</pre></td>
167
<tr class="inferred">
168
<td><pre><a name="line19">19</a> </pre></td>
173
<tr class="inferred">
174
<td><pre><a name="line20">20</a> </pre></td>
180
<td><pre><a name="line21">21</a> public </pre></td>
185
<tr class="inferred">
186
<td><pre><a name="line22">22</a> </pre></td>
191
<tr class="inferred">
192
<td><pre><a name="line23">23</a> </pre></td>
198
<td><pre><a name="line24">24</a> def neptune_ssa_run_job(nodes, job_data, secret)</pre></td>
203
<tr class="uncovered">
204
<td><pre><a name="line25">25</a> return BAD_SECRET_MSG unless valid_secret?(secret)</pre></td>
209
<tr class="uncovered">
210
<td><pre><a name="line26">26</a> Djinn.log_debug("ssa - run")</pre></td>
215
<tr class="uncovered">
216
<td><pre><a name="line27">27</a> </pre></td>
221
<tr class="uncovered">
222
<td><pre><a name="line28">28</a> Thread.new {</pre></td>
227
<tr class="uncovered">
228
<td><pre><a name="line29">29</a> start_time = Time.now</pre></td>
233
<tr class="uncovered">
234
<td><pre><a name="line30">30</a> total_compute_time = 0</pre></td>
239
<tr class="uncovered">
240
<td><pre><a name="line31">31</a> total_storage_time = 0</pre></td>
245
<tr class="uncovered">
246
<td><pre><a name="line32">32</a> total_slowest_path = 0</pre></td>
251
<tr class="uncovered">
252
<td><pre><a name="line33">33</a> c_times = []</pre></td>
257
<tr class="uncovered">
258
<td><pre><a name="line34">34</a> s_times = []</pre></td>
263
<tr class="uncovered">
264
<td><pre><a name="line35">35</a> </pre></td>
269
<tr class="uncovered">
270
<td><pre><a name="line36">36</a> Djinn.log_debug("job data is #{job_data.inspect}")</pre></td>
275
<tr class="uncovered">
276
<td><pre><a name="line37">37</a> keyname = @creds['keyname']</pre></td>
329
329
<tr class="uncovered">
330
<td><pre><a name="line46">46</a> Repo.get_output(remote, storage, creds, tar)</pre></td>
335
<tr class="uncovered">
336
<td><pre><a name="line47">47</a> neptune_uncompress_file(tar)</pre></td>
341
<tr class="uncovered">
342
<td><pre><a name="line48">48</a> </pre></td>
347
<tr class="uncovered">
348
<td><pre><a name="line49">49</a> num_sims = job_data["@trajectories"] || job_data["@simulations"]</pre></td>
353
<tr class="uncovered">
354
<td><pre><a name="line50">50</a> #seeds = neptune_get_ssa_seed_vals(num_sims)</pre></td>
359
<tr class="uncovered">
360
<td><pre><a name="line51">51</a> #Djinn.log_debug("seeds are #{seeds.join(', ')}")</pre></td>
365
<tr class="uncovered">
366
<td><pre><a name="line52">52</a> </pre></td>
371
<tr class="uncovered">
372
<td><pre><a name="line53">53</a> param_num = job_data['@param_num']</pre></td>
377
<tr class="uncovered">
378
<td><pre><a name="line54">54</a> </pre></td>
383
<tr class="uncovered">
384
<td><pre><a name="line55">55</a> threads = []</pre></td>
389
<tr class="uncovered">
390
<td><pre><a name="line56">56</a> node_times = []</pre></td>
395
<tr class="uncovered">
396
<td><pre><a name="line57">57</a> at = 0 </pre></td>
401
<tr class="uncovered">
402
<td><pre><a name="line58">58</a> nodes.each_with_index { |node, i|</pre></td>
407
<tr class="uncovered">
408
<td><pre><a name="line59">59</a> threads << Thread.new {</pre></td>
413
<tr class="uncovered">
414
<td><pre><a name="line60">60</a> node_times[i] = 0</pre></td>
419
<tr class="uncovered">
420
<td><pre><a name="line61">61</a> </pre></td>
425
<tr class="uncovered">
426
<td><pre><a name="line62">62</a> ip = node.private_ip</pre></td>
431
<tr class="uncovered">
432
<td><pre><a name="line63">63</a> ssh_key = node.ssh_key</pre></td>
437
<tr class="uncovered">
438
<td><pre><a name="line64">64</a> start = at</pre></td>
443
<tr class="uncovered">
444
<td><pre><a name="line65">65</a> fin = at + sims[i]</pre></td>
449
<tr class="uncovered">
450
<td><pre><a name="line66">66</a> at = fin</pre></td>
455
<tr class="uncovered">
456
<td><pre><a name="line67">67</a> fin -= 1 </pre></td>
461
<tr class="uncovered">
462
<td><pre><a name="line68">68</a> Djinn.log_debug("This node will run trajectories #{start} to #{fin}")</pre></td>
330
<td><pre><a name="line46">46</a> tar = working_dir + "/" + File.basename(job_data['@tar'])</pre></td>
335
<tr class="uncovered">
336
<td><pre><a name="line47">47</a> </pre></td>
341
<tr class="uncovered">
342
<td><pre><a name="line48">48</a> Djinn.log_debug("tar is #{job_data['@tar']}")</pre></td>
347
<tr class="uncovered">
348
<td><pre><a name="line49">49</a> Djinn.log_debug("working dir is #{working_dir}")</pre></td>
353
<tr class="uncovered">
354
<td><pre><a name="line50">50</a> </pre></td>
359
<tr class="uncovered">
360
<td><pre><a name="line51">51</a> remote = job_data['@tar']</pre></td>
365
<tr class="uncovered">
366
<td><pre><a name="line52">52</a> storage = job_data['@storage']</pre></td>
371
<tr class="uncovered">
372
<td><pre><a name="line53">53</a> </pre></td>
377
<tr class="uncovered">
378
<td><pre><a name="line54">54</a> datastore = DatastoreFactory.get_datastore(storage, job_data)</pre></td>
383
<tr class="uncovered">
384
<td><pre><a name="line55">55</a> datastore.get_output_and_save_to_fs(remote, tar)</pre></td>
389
<tr class="uncovered">
390
<td><pre><a name="line56">56</a> </pre></td>
395
<tr class="uncovered">
396
<td><pre><a name="line57">57</a> neptune_uncompress_file(tar)</pre></td>
401
<tr class="uncovered">
402
<td><pre><a name="line58">58</a> </pre></td>
407
<tr class="uncovered">
408
<td><pre><a name="line59">59</a> num_sims = job_data["@trajectories"] || job_data["@simulations"]</pre></td>
413
<tr class="uncovered">
414
<td><pre><a name="line60">60</a> </pre></td>
419
<tr class="uncovered">
420
<td><pre><a name="line61">61</a> param_num = job_data['@param_num']</pre></td>
425
<tr class="uncovered">
426
<td><pre><a name="line62">62</a> </pre></td>
431
<tr class="uncovered">
432
<td><pre><a name="line63">63</a> threads = []</pre></td>
437
<tr class="uncovered">
438
<td><pre><a name="line64">64</a> node_times = []</pre></td>
443
<tr class="uncovered">
444
<td><pre><a name="line65">65</a> at = 0 </pre></td>
449
<tr class="uncovered">
450
<td><pre><a name="line66">66</a> nodes.each_with_index { |node, i|</pre></td>
455
<tr class="uncovered">
456
<td><pre><a name="line67">67</a> threads << Thread.new {</pre></td>
461
<tr class="uncovered">
462
<td><pre><a name="line68">68</a> node_times[i] = 0</pre></td>
473
473
<tr class="uncovered">
474
<td><pre><a name="line70">70</a> code_path = "#{working_dir}/code/run.sh"</pre></td>
479
<tr class="uncovered">
480
<td><pre><a name="line71">71</a> Djinn.log_run("chmod +x #{code_path}")</pre></td>
485
<tr class="uncovered">
486
<td><pre><a name="line72">72</a> exec = "bash #{code_path}"</pre></td>
491
<tr class="uncovered">
492
<td><pre><a name="line73">73</a> </pre></td>
497
<tr class="uncovered">
498
<td><pre><a name="line74">74</a> input = "#{working_dir}/code/#{job_data['@input']}"</pre></td>
503
<tr class="uncovered">
504
<td><pre><a name="line75">75</a> </pre></td>
509
<tr class="uncovered">
510
<td><pre><a name="line76">76</a> unless ip == HelperFunctions.local_ip</pre></td>
515
<tr class="uncovered">
516
<td><pre><a name="line77">77</a> Djinn.log_run("scp -r -i #{ssh_key} -o StrictHostkeyChecking=no #{working_dir} root@#{ip}:#{working_dir}")</pre></td>
521
<tr class="uncovered">
522
<td><pre><a name="line78">78</a> end</pre></td>
527
<tr class="uncovered">
528
<td><pre><a name="line79">79</a> </pre></td>
533
<tr class="uncovered">
534
<td><pre><a name="line80">80</a> trajectories = fin - start + 1 </pre></td>
474
<td><pre><a name="line70">70</a> ip = node.private_ip</pre></td>
479
<tr class="uncovered">
480
<td><pre><a name="line71">71</a> ssh_key = node.ssh_key</pre></td>
485
<tr class="uncovered">
486
<td><pre><a name="line72">72</a> start = at</pre></td>
491
<tr class="uncovered">
492
<td><pre><a name="line73">73</a> fin = at + sims[i]</pre></td>
497
<tr class="uncovered">
498
<td><pre><a name="line74">74</a> at = fin</pre></td>
503
<tr class="uncovered">
504
<td><pre><a name="line75">75</a> fin -= 1 </pre></td>
509
<tr class="uncovered">
510
<td><pre><a name="line76">76</a> Djinn.log_debug("This node will run trajectories #{start} to #{fin}")</pre></td>
515
<tr class="uncovered">
516
<td><pre><a name="line77">77</a> </pre></td>
521
<tr class="uncovered">
522
<td><pre><a name="line78">78</a> code_path = "#{working_dir}/code/run.sh"</pre></td>
527
<tr class="uncovered">
528
<td><pre><a name="line79">79</a> Djinn.log_run("chmod +x #{code_path}")</pre></td>
533
<tr class="uncovered">
534
<td><pre><a name="line80">80</a> exec = "bash #{code_path}"</pre></td>
581
581
<tr class="uncovered">
582
<td><pre><a name="line88">88</a> done = 0</pre></td>
587
<tr class="uncovered">
588
<td><pre><a name="line89">89</a> loop {</pre></td>
593
<tr class="uncovered">
594
<td><pre><a name="line90">90</a> trajectories_left = trajectories - done</pre></td>
599
<tr class="uncovered">
600
<td><pre><a name="line91">91</a> Djinn.log_debug("Need to run #{trajectories_left} more trajectories on #{cores} cores")</pre></td>
605
<tr class="uncovered">
606
<td><pre><a name="line92">92</a> break if trajectories_left.zero?</pre></td>
611
<tr class="uncovered">
612
<td><pre><a name="line93">93</a> need_to_run = [trajectories_left, cores].min</pre></td>
617
<tr class="uncovered">
618
<td><pre><a name="line94">94</a> </pre></td>
623
<tr class="uncovered">
624
<td><pre><a name="line95">95</a> Djinn.log_debug("Running #{need_to_run} trajectories")</pre></td>
629
<tr class="uncovered">
630
<td><pre><a name="line96">96</a> core_threads = []</pre></td>
635
<tr class="uncovered">
636
<td><pre><a name="line97">97</a> current_times = []</pre></td>
641
<tr class="uncovered">
642
<td><pre><a name="line98">98</a> need_to_run.times { |j|</pre></td>
647
<tr class="uncovered">
648
<td><pre><a name="line99">99</a> core_threads << Thread.new {</pre></td>
653
<tr class="uncovered">
654
<td><pre><a name="line100">100</a> my_trajectory = start+done+j</pre></td>
659
<tr class="uncovered">
660
<td><pre><a name="line101">101</a> Djinn.log_debug("Thread #{j} is running trajectory #{my_trajectory}")</pre></td>
665
<tr class="uncovered">
666
<td><pre><a name="line102">102</a> output = File.expand_path("#{working_dir}/output-#{my_trajectory}")</pre></td>
671
<tr class="uncovered">
672
<td><pre><a name="line103">103</a> </pre></td>
677
<tr class="uncovered">
678
<td><pre><a name="line104">104</a> # run the computation, remembering to place StochKit in the user's PATH</pre></td>
683
<tr class="uncovered">
684
<td><pre><a name="line105">105</a> path = "PATH=$PATH:#{SSA_HOME}"</pre></td>
689
<tr class="uncovered">
690
<td><pre><a name="line106">106</a> run_command = "#{path} #{exec} #{input} #{output} #{my_trajectory} #{param_num}"</pre></td>
695
<tr class="uncovered">
696
<td><pre><a name="line107">107</a> </pre></td>
701
<tr class="uncovered">
702
<td><pre><a name="line108">108</a> start_compute = Time.now</pre></td>
707
<tr class="uncovered">
708
<td><pre><a name="line109">109</a> Djinn.log_run("ssh -i #{ssh_key} -o StrictHostkeyChecking=no root@#{ip} '#{run_command}'")</pre></td>
713
<tr class="uncovered">
714
<td><pre><a name="line110">110</a> end_compute = Time.now</pre></td>
719
<tr class="uncovered">
720
<td><pre><a name="line111">111</a> c_time = end_compute - start_compute</pre></td>
725
<tr class="uncovered">
726
<td><pre><a name="line112">112</a> total_compute_time += c_time</pre></td>
731
<tr class="uncovered">
732
<td><pre><a name="line113">113</a> c_times << c_time</pre></td>
737
<tr class="uncovered">
738
<td><pre><a name="line114">114</a> </pre></td>
743
<tr class="uncovered">
744
<td><pre><a name="line115">115</a> # copy the output back to this box - in the future we can do merges here</pre></td>
749
<tr class="uncovered">
750
<td><pre><a name="line116">116</a> # or in the future we can just have the node upload to s3</pre></td>
755
<tr class="uncovered">
756
<td><pre><a name="line117">117</a> start_storage = Time.now</pre></td>
761
<tr class="uncovered">
762
<td><pre><a name="line118">118</a> unless HelperFunctions.local_ip == ip</pre></td>
767
<tr class="uncovered">
768
<td><pre><a name="line119">119</a> remote_cp_command = "scp -r -i #{ssh_key} -o StrictHostkeyChecking=no root@#{ip}:#{output} #{output}"</pre></td>
773
<tr class="uncovered">
774
<td><pre><a name="line120">120</a> Djinn.log_run(remote_cp_command)</pre></td>
779
<tr class="uncovered">
780
<td><pre><a name="line121">121</a> </pre></td>
785
<tr class="uncovered">
786
<td><pre><a name="line122">122</a> end</pre></td>
791
<tr class="uncovered">
792
<td><pre><a name="line123">123</a> </pre></td>
797
<tr class="uncovered">
798
<td><pre><a name="line124">124</a> remote_location = "#{job_data['@output']}/output-#{my_trajectory}"</pre></td>
803
<tr class="uncovered">
804
<td><pre><a name="line125">125</a> Repo.set_output(remote_location, output, storage, creds, IS_FILE)</pre></td>
809
<tr class="uncovered">
810
<td><pre><a name="line126">126</a> end_storage = Time.now</pre></td>
815
<tr class="uncovered">
816
<td><pre><a name="line127">127</a> s_time = end_storage - start_storage</pre></td>
821
<tr class="uncovered">
822
<td><pre><a name="line128">128</a> total_storage_time += s_time</pre></td>
827
<tr class="uncovered">
828
<td><pre><a name="line129">129</a> s_times << s_time</pre></td>
833
<tr class="uncovered">
834
<td><pre><a name="line130">130</a> </pre></td>
839
<tr class="uncovered">
840
<td><pre><a name="line131">131</a> node_times[i] += (c_time + s_time)</pre></td>
845
<tr class="uncovered">
846
<td><pre><a name="line132">132</a> </pre></td>
851
<tr class="uncovered">
852
<td><pre><a name="line133">133</a> # remove our output - we can't want the disk to fill up</pre></td>
857
<tr class="uncovered">
858
<td><pre><a name="line134">134</a> remove_cmd = "rm -rf #{output}"</pre></td>
863
<tr class="uncovered">
864
<td><pre><a name="line135">135</a> Djinn.log_run("ssh -i #{ssh_key} -o StrictHostkeyChecking=no root@#{ip} '#{remove_cmd}'")</pre></td>
869
<tr class="uncovered">
870
<td><pre><a name="line136">136</a> Djinn.log_run(remove_cmd)</pre></td>
875
<tr class="uncovered">
876
<td><pre><a name="line137">137</a> }</pre></td>
881
<tr class="uncovered">
882
<td><pre><a name="line138">138</a> }</pre></td>
887
<tr class="uncovered">
888
<td><pre><a name="line139">139</a> </pre></td>
893
<tr class="uncovered">
894
<td><pre><a name="line140">140</a> core_threads.each { |c| c.join }</pre></td>
899
<tr class="uncovered">
900
<td><pre><a name="line141">141</a> </pre></td>
905
<tr class="uncovered">
906
<td><pre><a name="line142">142</a> done += need_to_run</pre></td>
911
<tr class="uncovered">
912
<td><pre><a name="line143">143</a> Djinn.log_debug("Done running #{need_to_run} trajectories, #{trajectories - done} to go")</pre></td>
917
<tr class="uncovered">
918
<td><pre><a name="line144">144</a> }</pre></td>
923
<tr class="uncovered">
924
<td><pre><a name="line145">145</a> }</pre></td>
929
<tr class="uncovered">
930
<td><pre><a name="line146">146</a> }</pre></td>
582
<td><pre><a name="line88">88</a> trajectories = fin - start + 1 </pre></td>
587
<tr class="uncovered">
588
<td><pre><a name="line89">89</a> </pre></td>
593
<tr class="uncovered">
594
<td><pre><a name="line90">90</a> if MULTICORE</pre></td>
599
<tr class="uncovered">
600
<td><pre><a name="line91">91</a> cores = HelperFunctions.get_num_cpus()</pre></td>
605
<tr class="uncovered">
606
<td><pre><a name="line92">92</a> else</pre></td>
611
<tr class="uncovered">
612
<td><pre><a name="line93">93</a> cores = 1</pre></td>
617
<tr class="uncovered">
618
<td><pre><a name="line94">94</a> end</pre></td>
623
<tr class="uncovered">
624
<td><pre><a name="line95">95</a> </pre></td>
629
<tr class="uncovered">
630
<td><pre><a name="line96">96</a> done = 0</pre></td>
635
<tr class="uncovered">
636
<td><pre><a name="line97">97</a> loop {</pre></td>
641
<tr class="uncovered">
642
<td><pre><a name="line98">98</a> trajectories_left = trajectories - done</pre></td>
647
<tr class="uncovered">
648
<td><pre><a name="line99">99</a> Djinn.log_debug("Need to run #{trajectories_left} more trajectories on #{cores} cores")</pre></td>
653
<tr class="uncovered">
654
<td><pre><a name="line100">100</a> break if trajectories_left.zero?</pre></td>
659
<tr class="uncovered">
660
<td><pre><a name="line101">101</a> need_to_run = [trajectories_left, cores].min</pre></td>
665
<tr class="uncovered">
666
<td><pre><a name="line102">102</a> </pre></td>
671
<tr class="uncovered">
672
<td><pre><a name="line103">103</a> Djinn.log_debug("Running #{need_to_run} trajectories")</pre></td>
677
<tr class="uncovered">
678
<td><pre><a name="line104">104</a> core_threads = []</pre></td>
683
<tr class="uncovered">
684
<td><pre><a name="line105">105</a> current_times = []</pre></td>
689
<tr class="uncovered">
690
<td><pre><a name="line106">106</a> need_to_run.times { |j|</pre></td>
695
<tr class="uncovered">
696
<td><pre><a name="line107">107</a> core_threads << Thread.new {</pre></td>
701
<tr class="uncovered">
702
<td><pre><a name="line108">108</a> my_trajectory = start+done+j</pre></td>
707
<tr class="uncovered">
708
<td><pre><a name="line109">109</a> Djinn.log_debug("Thread #{j} is running trajectory #{my_trajectory}")</pre></td>
713
<tr class="uncovered">
714
<td><pre><a name="line110">110</a> output = File.expand_path("#{working_dir}/output-#{my_trajectory}")</pre></td>
719
<tr class="uncovered">
720
<td><pre><a name="line111">111</a> </pre></td>
725
<tr class="uncovered">
726
<td><pre><a name="line112">112</a> # run the computation, remembering to place StochKit in the user's PATH</pre></td>
731
<tr class="uncovered">
732
<td><pre><a name="line113">113</a> path = "PATH=$PATH:#{SSA_HOME}"</pre></td>
737
<tr class="uncovered">
738
<td><pre><a name="line114">114</a> run_command = "#{path} #{exec} #{input} #{output} #{my_trajectory} #{param_num}"</pre></td>
743
<tr class="uncovered">
744
<td><pre><a name="line115">115</a> </pre></td>
749
<tr class="uncovered">
750
<td><pre><a name="line116">116</a> start_compute = Time.now</pre></td>
755
<tr class="uncovered">
756
<td><pre><a name="line117">117</a> Djinn.log_run("ssh -i #{ssh_key} -o StrictHostkeyChecking=no root@#{ip} '#{run_command}'")</pre></td>
761
<tr class="uncovered">
762
<td><pre><a name="line118">118</a> end_compute = Time.now</pre></td>
767
<tr class="uncovered">
768
<td><pre><a name="line119">119</a> c_time = end_compute - start_compute</pre></td>
773
<tr class="uncovered">
774
<td><pre><a name="line120">120</a> total_compute_time += c_time</pre></td>
779
<tr class="uncovered">
780
<td><pre><a name="line121">121</a> c_times << c_time</pre></td>
785
<tr class="uncovered">
786
<td><pre><a name="line122">122</a> </pre></td>
791
<tr class="uncovered">
792
<td><pre><a name="line123">123</a> # copy the output back to this box - in the future we can do merges here</pre></td>
797
<tr class="uncovered">
798
<td><pre><a name="line124">124</a> # or in the future we can just have the node upload to s3</pre></td>
803
<tr class="uncovered">
804
<td><pre><a name="line125">125</a> start_storage = Time.now</pre></td>
809
<tr class="uncovered">
810
<td><pre><a name="line126">126</a> unless HelperFunctions.local_ip == ip</pre></td>
815
<tr class="uncovered">
816
<td><pre><a name="line127">127</a> remote_cp_command = "scp -r -i #{ssh_key} -o StrictHostkeyChecking=no root@#{ip}:#{output} #{output}"</pre></td>
821
<tr class="uncovered">
822
<td><pre><a name="line128">128</a> Djinn.log_run(remote_cp_command)</pre></td>
827
<tr class="uncovered">
828
<td><pre><a name="line129">129</a> </pre></td>
833
<tr class="uncovered">
834
<td><pre><a name="line130">130</a> end</pre></td>
839
<tr class="uncovered">
840
<td><pre><a name="line131">131</a> </pre></td>
845
<tr class="uncovered">
846
<td><pre><a name="line132">132</a> remote_location = "#{job_data['@output']}/output-#{my_trajectory}"</pre></td>
851
<tr class="uncovered">
852
<td><pre><a name="line133">133</a> datastore.write_remote_file_from_local_file(remote_location, output)</pre></td>
857
<tr class="uncovered">
858
<td><pre><a name="line134">134</a> end_storage = Time.now</pre></td>
863
<tr class="uncovered">
864
<td><pre><a name="line135">135</a> s_time = end_storage - start_storage</pre></td>
869
<tr class="uncovered">
870
<td><pre><a name="line136">136</a> total_storage_time += s_time</pre></td>
875
<tr class="uncovered">
876
<td><pre><a name="line137">137</a> s_times << s_time</pre></td>
881
<tr class="uncovered">
882
<td><pre><a name="line138">138</a> </pre></td>
887
<tr class="uncovered">
888
<td><pre><a name="line139">139</a> node_times[i] += (c_time + s_time)</pre></td>
893
<tr class="uncovered">
894
<td><pre><a name="line140">140</a> </pre></td>
899
<tr class="uncovered">
900
<td><pre><a name="line141">141</a> # remove our output - we can't want the disk to fill up</pre></td>
905
<tr class="uncovered">
906
<td><pre><a name="line142">142</a> remove_cmd = "rm -rf #{output}"</pre></td>
911
<tr class="uncovered">
912
<td><pre><a name="line143">143</a> Djinn.log_run("ssh -i #{ssh_key} -o StrictHostkeyChecking=no root@#{ip} '#{remove_cmd}'")</pre></td>
917
<tr class="uncovered">
918
<td><pre><a name="line144">144</a> Djinn.log_run(remove_cmd)</pre></td>
923
<tr class="uncovered">
924
<td><pre><a name="line145">145</a> }</pre></td>
929
<tr class="uncovered">
930
<td><pre><a name="line146">146</a> }</pre></td>
1013
1013
<tr class="uncovered">
1014
<td><pre><a name="line160">160</a> timing_info = <<BAZ</pre></td>
1019
<tr class="uncovered">
1020
<td><pre><a name="line161">161</a> TIMING: total execution time is #{total} seconds.</pre></td>
1025
<tr class="uncovered">
1026
<td><pre><a name="line162">162</a> TIMING: total compute time is #{total_compute_time} seconds.</pre></td>
1031
<tr class="uncovered">
1032
<td><pre><a name="line163">163</a> TIMING: total storage time is #{total_storage_time} seconds.</pre></td>
1037
<tr class="uncovered">
1038
<td><pre><a name="line164">164</a> TIMING: slowest path time is #{total_slowest_path} seconds.</pre></td>
1043
<tr class="uncovered">
1044
<td><pre><a name="line165">165</a> TIMING: overhead time is #{total_overhead_time} seconds.</pre></td>
1049
<tr class="uncovered">
1050
<td><pre><a name="line166">166</a> TIMING: average compute time is #{average(c_times)} seconds.</pre></td>
1055
<tr class="uncovered">
1056
<td><pre><a name="line167">167</a> TIMING: stddev compute time is #{standard_deviation(c_times)} seconds.</pre></td>
1061
<tr class="uncovered">
1062
<td><pre><a name="line168">168</a> TIMING: average storage time is #{average(s_times)} seconds.</pre></td>
1067
<tr class="uncovered">
1068
<td><pre><a name="line169">169</a> TIMING: stddev storage time is #{standard_deviation(s_times)} seconds.</pre></td>
1073
<tr class="uncovered">
1074
<td><pre><a name="line170">170</a> RAW_DATA: node times are: [#{node_times.join(', ')}]</pre></td>
1079
<tr class="uncovered">
1080
<td><pre><a name="line171">171</a> RAW_DATA: compute times are: [#{c_times.join(', ')}]</pre></td>
1085
<tr class="uncovered">
1086
<td><pre><a name="line172">172</a> RAW_DATA: storage times are: [#{s_times.join(', ')}]</pre></td>
1091
<tr class="uncovered">
1092
<td><pre><a name="line173">173</a> BAZ</pre></td>
1097
<tr class="uncovered">
1098
<td><pre><a name="line174">174</a> </pre></td>
1103
<tr class="uncovered">
1104
<td><pre><a name="line175">175</a> Djinn.log_debug(timing_info)</pre></td>
1109
<tr class="uncovered">
1110
<td><pre><a name="line176">176</a> </pre></td>
1115
<tr class="uncovered">
1116
<td><pre><a name="line177">177</a> remote_location = "#{job_data['@output']}/timing_info.txt"</pre></td>
1121
<tr class="uncovered">
1122
<td><pre><a name="line178">178</a> Repo.set_output(remote_location, timing_info, storage, creds, NOT_A_FILE)</pre></td>
1127
<tr class="uncovered">
1128
<td><pre><a name="line179">179</a> </pre></td>
1133
<tr class="uncovered">
1134
<td><pre><a name="line180">180</a> remove_lock_file(job_data)</pre></td>
1139
<tr class="uncovered">
1140
<td><pre><a name="line181">181</a> }</pre></td>
1014
<td><pre><a name="line160">160</a> # clean up after ourselves</pre></td>
1019
<tr class="uncovered">
1020
<td><pre><a name="line161">161</a> Djinn.log_run("rm -rf #{working_dir}")</pre></td>
1025
<tr class="uncovered">
1026
<td><pre><a name="line162">162</a> </pre></td>
1031
<tr class="uncovered">
1032
<td><pre><a name="line163">163</a> fin_time = Time.now</pre></td>
1037
<tr class="uncovered">
1038
<td><pre><a name="line164">164</a> total = fin_time - start_time</pre></td>
1043
<tr class="uncovered">
1044
<td><pre><a name="line165">165</a> total_slowest_path = node_times.max</pre></td>
1049
<tr class="uncovered">
1050
<td><pre><a name="line166">166</a> total_overhead_time = total - total_slowest_path</pre></td>
1055
<tr class="uncovered">
1056
<td><pre><a name="line167">167</a> </pre></td>
1061
<tr class="uncovered">
1062
<td><pre><a name="line168">168</a> timing_info = <<BAZ</pre></td>
1067
<tr class="uncovered">
1068
<td><pre><a name="line169">169</a> TIMING: total execution time is #{total} seconds.</pre></td>
1073
<tr class="uncovered">
1074
<td><pre><a name="line170">170</a> TIMING: total compute time is #{total_compute_time} seconds.</pre></td>
1079
<tr class="uncovered">
1080
<td><pre><a name="line171">171</a> TIMING: total storage time is #{total_storage_time} seconds.</pre></td>
1085
<tr class="uncovered">
1086
<td><pre><a name="line172">172</a> TIMING: slowest path time is #{total_slowest_path} seconds.</pre></td>
1091
<tr class="uncovered">
1092
<td><pre><a name="line173">173</a> TIMING: overhead time is #{total_overhead_time} seconds.</pre></td>
1097
<tr class="uncovered">
1098
<td><pre><a name="line174">174</a> TIMING: average compute time is #{average(c_times)} seconds.</pre></td>
1103
<tr class="uncovered">
1104
<td><pre><a name="line175">175</a> TIMING: stddev compute time is #{standard_deviation(c_times)} seconds.</pre></td>
1109
<tr class="uncovered">
1110
<td><pre><a name="line176">176</a> TIMING: average storage time is #{average(s_times)} seconds.</pre></td>
1115
<tr class="uncovered">
1116
<td><pre><a name="line177">177</a> TIMING: stddev storage time is #{standard_deviation(s_times)} seconds.</pre></td>
1121
<tr class="uncovered">
1122
<td><pre><a name="line178">178</a> RAW_DATA: node times are: [#{node_times.join(', ')}]</pre></td>
1127
<tr class="uncovered">
1128
<td><pre><a name="line179">179</a> RAW_DATA: compute times are: [#{c_times.join(', ')}]</pre></td>
1133
<tr class="uncovered">
1134
<td><pre><a name="line180">180</a> RAW_DATA: storage times are: [#{s_times.join(', ')}]</pre></td>
1139
<tr class="uncovered">
1140
<td><pre><a name="line181">181</a> BAZ</pre></td>
1151
1151
<tr class="uncovered">
1152
<td><pre><a name="line183">183</a> return "OK"</pre></td>
1157
<tr class="uncovered">
1158
<td><pre><a name="line184">184</a> end</pre></td>
1163
<tr class="inferred">
1164
<td><pre><a name="line185">185</a> </pre></td>
1170
<td><pre><a name="line186">186</a> private</pre></td>
1175
<tr class="inferred">
1152
<td><pre><a name="line183">183</a> Djinn.log_debug(timing_info)</pre></td>
1157
<tr class="uncovered">
1158
<td><pre><a name="line184">184</a> </pre></td>
1163
<tr class="uncovered">
1164
<td><pre><a name="line185">185</a> remote_location = "#{job_data['@output']}/timing_info.txt"</pre></td>
1169
<tr class="uncovered">
1170
<td><pre><a name="line186">186</a> datastore.write_remote_file_from_string(remote_location, timing_info)</pre></td>
1175
<tr class="uncovered">
1176
1176
<td><pre><a name="line187">187</a> </pre></td>
1182
<td><pre><a name="line188">188</a> def neptune_ssa_get_output(job_data)</pre></td>
1187
<tr class="uncovered">
1188
<td><pre><a name="line189">189</a> return SSA_HOME</pre></td>
1193
<tr class="uncovered">
1194
<td><pre><a name="line190">190</a> end</pre></td>
1181
<tr class="uncovered">
1182
<td><pre><a name="line188">188</a> remove_lock_file(job_data)</pre></td>
1187
<tr class="uncovered">
1188
<td><pre><a name="line189">189</a> }</pre></td>
1193
<tr class="uncovered">
1194
<td><pre><a name="line190">190</a> </pre></td>
1199
<tr class="uncovered">
1200
<td><pre><a name="line191">191</a> return "OK"</pre></td>
1205
<tr class="uncovered">
1206
<td><pre><a name="line192">192</a> end</pre></td>
1199
1211
<tr class="inferred">
1200
<td><pre><a name="line191">191</a> </pre></td>
1212
<td><pre><a name="line193">193</a> </pre></td>
1205
1217
<tr class="marked">
1206
<td><pre><a name="line192">192</a> def start_ssa_master()</pre></td>
1211
<tr class="uncovered">
1212
<td><pre><a name="line193">193</a> Djinn.log_debug("#{my_node.private_ip} is starting ssa master")</pre></td>
1217
<tr class="uncovered">
1218
<td><pre><a name="line194">194</a> end</pre></td>
1218
<td><pre><a name="line194">194</a> private</pre></td>
1301
1301
<tr class="marked">
1302
<td><pre><a name="line208">208</a> def neptune_get_ssa_seed_vals(num_vals)</pre></td>
1307
<tr class="uncovered">
1308
<td><pre><a name="line209">209</a> random_numbers = []</pre></td>
1313
<tr class="uncovered">
1314
<td><pre><a name="line210">210</a> loop {</pre></td>
1319
<tr class="uncovered">
1320
<td><pre><a name="line211">211</a> possible_rand = rand(32000)</pre></td>
1325
<tr class="uncovered">
1326
<td><pre><a name="line212">212</a> unless random_numbers.include?(possible_rand)</pre></td>
1331
<tr class="uncovered">
1332
<td><pre><a name="line213">213</a> random_numbers << possible_rand</pre></td>
1337
<tr class="uncovered">
1338
<td><pre><a name="line214">214</a> end</pre></td>
1343
<tr class="uncovered">
1344
<td><pre><a name="line215">215</a> break if num_vals == random_numbers.length</pre></td>
1349
<tr class="uncovered">
1350
<td><pre><a name="line216">216</a> }</pre></td>
1355
<tr class="uncovered">
1356
<td><pre><a name="line217">217</a> </pre></td>
1361
<tr class="uncovered">
1362
<td><pre><a name="line218">218</a> return random_numbers</pre></td>
1367
<tr class="uncovered">
1368
<td><pre><a name="line219">219</a> end</pre></td>
1373
<tr class="inferred">
1374
<td><pre><a name="line220">220</a> </pre></td>
1380
<td><pre><a name="line221">221</a> def neptune_get_ssa_num_simulations(nodes, job_data)</pre></td>
1385
<tr class="uncovered">
1386
<td><pre><a name="line222">222</a> num_nodes = nodes.length</pre></td>
1391
<tr class="uncovered">
1392
<td><pre><a name="line223">223</a> num_sims = job_data["@trajectories"] || job_data["@simulations"]</pre></td>
1397
<tr class="uncovered">
1398
<td><pre><a name="line224">224</a> sims_per_node = num_sims / num_nodes</pre></td>
1302
<td><pre><a name="line208">208</a> def stop_ssa_master()</pre></td>
1307
<tr class="uncovered">
1308
<td><pre><a name="line209">209</a> Djinn.log_debug("#{my_node.private_ip} is stopping ssa master")</pre></td>
1313
<tr class="uncovered">
1314
<td><pre><a name="line210">210</a> end</pre></td>
1319
<tr class="inferred">
1320
<td><pre><a name="line211">211</a> </pre></td>
1326
<td><pre><a name="line212">212</a> def stop_ssa_slave()</pre></td>
1331
<tr class="uncovered">
1332
<td><pre><a name="line213">213</a> Djinn.log_debug("#{my_node.private_ip} is stopping ssa slave")</pre></td>
1337
<tr class="uncovered">
1338
<td><pre><a name="line214">214</a> end</pre></td>
1343
<tr class="inferred">
1344
<td><pre><a name="line215">215</a> </pre></td>
1350
<td><pre><a name="line216">216</a> def neptune_get_ssa_seed_vals(num_vals)</pre></td>
1355
<tr class="uncovered">
1356
<td><pre><a name="line217">217</a> random_numbers = []</pre></td>
1361
<tr class="uncovered">
1362
<td><pre><a name="line218">218</a> loop {</pre></td>
1367
<tr class="uncovered">
1368
<td><pre><a name="line219">219</a> possible_rand = rand(32000)</pre></td>
1373
<tr class="uncovered">
1374
<td><pre><a name="line220">220</a> unless random_numbers.include?(possible_rand)</pre></td>
1379
<tr class="uncovered">
1380
<td><pre><a name="line221">221</a> random_numbers << possible_rand</pre></td>
1385
<tr class="uncovered">
1386
<td><pre><a name="line222">222</a> end</pre></td>
1391
<tr class="uncovered">
1392
<td><pre><a name="line223">223</a> break if num_vals == random_numbers.length</pre></td>
1397
<tr class="uncovered">
1398
<td><pre><a name="line224">224</a> }</pre></td>
1409
1409
<tr class="uncovered">
1410
<td><pre><a name="line226">226</a> Djinn.log_debug("num nodes = #{num_nodes}")</pre></td>
1415
<tr class="uncovered">
1416
<td><pre><a name="line227">227</a> Djinn.log_debug("num_sims = #{num_sims}")</pre></td>
1421
<tr class="uncovered">
1422
<td><pre><a name="line228">228</a> Djinn.log_debug("sims_per_node = #{sims_per_node}")</pre></td>
1427
<tr class="uncovered">
1428
<td><pre><a name="line229">229</a> </pre></td>
1433
<tr class="uncovered">
1434
<td><pre><a name="line230">230</a> # set up how many simulations each node</pre></td>
1439
<tr class="uncovered">
1440
<td><pre><a name="line231">231</a> # should run by divying it up equally</pre></td>
1445
<tr class="uncovered">
1446
<td><pre><a name="line232">232</a> # any remainder can be assigned to an</pre></td>
1451
<tr class="uncovered">
1452
<td><pre><a name="line233">233</a> # arbitrary node</pre></td>
1457
<tr class="uncovered">
1458
<td><pre><a name="line234">234</a> </pre></td>
1463
<tr class="uncovered">
1464
<td><pre><a name="line235">235</a> sims = [sims_per_node] * num_nodes</pre></td>
1469
<tr class="uncovered">
1470
<td><pre><a name="line236">236</a> remainder = num_sims % num_nodes</pre></td>
1475
<tr class="uncovered">
1476
<td><pre><a name="line237">237</a> sims[-1] += remainder</pre></td>
1481
<tr class="uncovered">
1482
<td><pre><a name="line238">238</a> </pre></td>
1487
<tr class="uncovered">
1488
<td><pre><a name="line239">239</a> Djinn.log_debug("sims = #{sims.join(', ')}")</pre></td>
1493
<tr class="uncovered">
1494
<td><pre><a name="line240">240</a> Djinn.log_debug("remainder = #{remainder}")</pre></td>
1499
<tr class="uncovered">
1500
<td><pre><a name="line241">241</a> </pre></td>
1505
<tr class="uncovered">
1506
<td><pre><a name="line242">242</a> return sims</pre></td>
1511
<tr class="uncovered">
1512
<td><pre><a name="line243">243</a> end</pre></td>
1517
<tr class="inferred">
1518
<td><pre><a name="line244">244</a> </pre></td>
1524
<td><pre><a name="line245">245</a> def average(population)</pre></td>
1529
<tr class="uncovered">
1530
<td><pre><a name="line246">246</a> total = 0.0</pre></td>
1535
<tr class="uncovered">
1536
<td><pre><a name="line247">247</a> n = 0</pre></td>
1541
<tr class="uncovered">
1542
<td><pre><a name="line248">248</a> </pre></td>
1547
<tr class="uncovered">
1548
<td><pre><a name="line249">249</a> population.each { |val|</pre></td>
1553
<tr class="uncovered">
1554
<td><pre><a name="line250">250</a> total += val</pre></td>
1559
<tr class="uncovered">
1560
<td><pre><a name="line251">251</a> n += 1</pre></td>
1565
<tr class="uncovered">
1566
<td><pre><a name="line252">252</a> }</pre></td>
1571
<tr class="uncovered">
1572
<td><pre><a name="line253">253</a> </pre></td>
1577
<tr class="uncovered">
1578
<td><pre><a name="line254">254</a> return total / n</pre></td>
1583
<tr class="uncovered">
1584
<td><pre><a name="line255">255</a> end</pre></td>
1589
<tr class="inferred">
1410
<td><pre><a name="line226">226</a> return random_numbers</pre></td>
1415
<tr class="uncovered">
1416
<td><pre><a name="line227">227</a> end</pre></td>
1421
<tr class="inferred">
1422
<td><pre><a name="line228">228</a> </pre></td>
1428
<td><pre><a name="line229">229</a> def neptune_get_ssa_num_simulations(nodes, job_data)</pre></td>
1433
<tr class="uncovered">
1434
<td><pre><a name="line230">230</a> num_nodes = nodes.length</pre></td>
1439
<tr class="uncovered">
1440
<td><pre><a name="line231">231</a> num_sims = job_data["@trajectories"] || job_data["@simulations"]</pre></td>
1445
<tr class="uncovered">
1446
<td><pre><a name="line232">232</a> sims_per_node = num_sims / num_nodes</pre></td>
1451
<tr class="uncovered">
1452
<td><pre><a name="line233">233</a> </pre></td>
1457
<tr class="uncovered">
1458
<td><pre><a name="line234">234</a> Djinn.log_debug("num nodes = #{num_nodes}")</pre></td>
1463
<tr class="uncovered">
1464
<td><pre><a name="line235">235</a> Djinn.log_debug("num_sims = #{num_sims}")</pre></td>
1469
<tr class="uncovered">
1470
<td><pre><a name="line236">236</a> Djinn.log_debug("sims_per_node = #{sims_per_node}")</pre></td>
1475
<tr class="uncovered">
1476
<td><pre><a name="line237">237</a> </pre></td>
1481
<tr class="uncovered">
1482
<td><pre><a name="line238">238</a> # set up how many simulations each node</pre></td>
1487
<tr class="uncovered">
1488
<td><pre><a name="line239">239</a> # should run by divying it up equally</pre></td>
1493
<tr class="uncovered">
1494
<td><pre><a name="line240">240</a> # any remainder can be assigned to an</pre></td>
1499
<tr class="uncovered">
1500
<td><pre><a name="line241">241</a> # arbitrary node</pre></td>
1505
<tr class="uncovered">
1506
<td><pre><a name="line242">242</a> </pre></td>
1511
<tr class="uncovered">
1512
<td><pre><a name="line243">243</a> sims = [sims_per_node] * num_nodes</pre></td>
1517
<tr class="uncovered">
1518
<td><pre><a name="line244">244</a> remainder = num_sims % num_nodes</pre></td>
1523
<tr class="uncovered">
1524
<td><pre><a name="line245">245</a> sims[-1] += remainder</pre></td>
1529
<tr class="uncovered">
1530
<td><pre><a name="line246">246</a> </pre></td>
1535
<tr class="uncovered">
1536
<td><pre><a name="line247">247</a> Djinn.log_debug("sims = #{sims.join(', ')}")</pre></td>
1541
<tr class="uncovered">
1542
<td><pre><a name="line248">248</a> Djinn.log_debug("remainder = #{remainder}")</pre></td>
1547
<tr class="uncovered">
1548
<td><pre><a name="line249">249</a> </pre></td>
1553
<tr class="uncovered">
1554
<td><pre><a name="line250">250</a> return sims</pre></td>
1559
<tr class="uncovered">
1560
<td><pre><a name="line251">251</a> end</pre></td>
1565
<tr class="inferred">
1566
<td><pre><a name="line252">252</a> </pre></td>
1572
<td><pre><a name="line253">253</a> def average(population)</pre></td>
1577
<tr class="uncovered">
1578
<td><pre><a name="line254">254</a> total = 0.0</pre></td>
1583
<tr class="uncovered">
1584
<td><pre><a name="line255">255</a> n = 0</pre></td>
1589
<tr class="uncovered">
1590
1590
<td><pre><a name="line256">256</a> </pre></td>
1595
<tr class="uncovered">
1596
<td><pre><a name="line257">257</a> population.each { |val|</pre></td>
1601
<tr class="uncovered">
1602
<td><pre><a name="line258">258</a> total += val</pre></td>
1607
<tr class="uncovered">
1608
<td><pre><a name="line259">259</a> n += 1</pre></td>
1613
<tr class="uncovered">
1614
<td><pre><a name="line260">260</a> }</pre></td>
1619
<tr class="uncovered">
1620
<td><pre><a name="line261">261</a> </pre></td>
1625
<tr class="uncovered">
1626
<td><pre><a name="line262">262</a> return total / n</pre></td>
1631
<tr class="uncovered">
1632
<td><pre><a name="line263">263</a> end</pre></td>
1637
<tr class="inferred">
1638
<td><pre><a name="line264">264</a> </pre></td>
1595
1643
<tr class="marked">
1596
<td><pre><a name="line257">257</a> def variance(population)</pre></td>
1601
<tr class="uncovered">
1602
<td><pre><a name="line258">258</a> n = 0</pre></td>
1607
<tr class="uncovered">
1608
<td><pre><a name="line259">259</a> mean = 0.0</pre></td>
1613
<tr class="uncovered">
1614
<td><pre><a name="line260">260</a> </pre></td>
1619
<tr class="uncovered">
1620
<td><pre><a name="line261">261</a> sum = population.reduce(0.0) do |sum, x|</pre></td>
1625
<tr class="uncovered">
1626
<td><pre><a name="line262">262</a> n += 1</pre></td>
1631
<tr class="uncovered">
1632
<td><pre><a name="line263">263</a> delta = x - mean</pre></td>
1637
<tr class="uncovered">
1638
<td><pre><a name="line264">264</a> mean += delta / n</pre></td>
1643
<tr class="uncovered">
1644
<td><pre><a name="line265">265</a> </pre></td>
1649
<tr class="uncovered">
1650
<td><pre><a name="line266">266</a> sum + delta * (x - mean)</pre></td>
1655
<tr class="uncovered">
1656
<td><pre><a name="line267">267</a> end</pre></td>
1644
<td><pre><a name="line265">265</a> def variance(population)</pre></td>
1649
<tr class="uncovered">
1650
<td><pre><a name="line266">266</a> n = 0</pre></td>
1655
<tr class="uncovered">
1656
<td><pre><a name="line267">267</a> mean = 0.0</pre></td>