1 /*
2 * cTestCPU.cc
3 * Avida
4 *
5 * Called "test_cpu.cc" prior to 11/30/05.
6 * Copyright 1999-2011 Michigan State University. All rights reserved.
7 * Copyright 1999-2003 California Institute of Technology.
8 *
9 *
10 * This file is part of Avida.
11 *
12 * Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
14 *
15 * Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License along with Avida.
19 * If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23 #include "cTestCPU.h"
24
25 #include "cAvidaContext.h"
26 #include "cBioGroup.h"
27 #include "cCPUTestInfo.h"
28 #include "cEnvironment.h"
29 #include "cHardwareBase.h"
30 #include "cHardwareManager.h"
31 #include "cHardwareStatusPrinter.h"
32 #include "cInstSet.h"
33 #include "cOrganism.h"
34 #include "cPhenotype.h"
35 #include "cResource.h"
36 #include "cResourceCount.h"
37 #include "cResourceHistory.h"
38 #include "cResourceLib.h"
39 #include "cStringUtil.h"
40 #include "cTestCPUInterface.h"
41 #include "cWorld.h"
42 #include "tMatrix.h"
43
44 #include <iomanip>
45
46 using namespace std;
47 using namespace AvidaTools;
48
49
cTestCPU(cAvidaContext & ctx,cWorld * world)50 cTestCPU::cTestCPU(cAvidaContext& ctx, cWorld* world)
51 {
52 m_world = world;
53 m_use_manual_inputs = false;
54 InitResources(ctx);
55 }
56
57
InitResources(cAvidaContext & ctx,int res_method,cResourceHistory * res,int update,int cpu_cycle_offset)58 void cTestCPU::InitResources(cAvidaContext& ctx, int res_method, cResourceHistory* res, int update, int cpu_cycle_offset)
59 {
60 //FOR DEMES
61 m_deme_resource_count.SetSize(0);
62
63 m_res_method = (eTestCPUResourceMethod)res_method;
64 // Make sure it's valid
65 if (res_method < 0 || res_method >= RES_LAST) m_res_method = RES_INITIAL;
66
67 // Setup the resources...
68 m_res = res;
69 m_res_cpu_cycle_offset = cpu_cycle_offset;
70 m_res_update = update;
71
72 // Adjust updates if time_spent_offset is greater than a time slice
73 int ave_time_slice = m_world->GetConfig().AVE_TIME_SLICE.Get();
74 m_res_update += m_res_cpu_cycle_offset / ave_time_slice;
75 m_res_cpu_cycle_offset %= ave_time_slice;
76 assert(m_res_cpu_cycle_offset >= 0);
77
78 // If they didn't send anything (usually during an avida run as opposed to analyze mode),
79 // then we set up a static variable (or just point to it) that reflects the initial conditions of the run
80 // from the environment file. (JEB -- This code moved from cAnalyze::cAnalyze).
81 if (m_res_method == RES_INITIAL)
82 {
83 // Initialize the time oriented resource list to be just the initial
84 // concentrations of the resources in the environment. This will only
85 // be changed if LOAD_RESOURCES analyze command is called. If there are
86 // no resources in the environment or there is no environment, the list
87 // is empty then the all resources will default to 0.0
88 m_res = &m_world->GetEnvironment().GetResourceLib().GetInitialResourceLevels();
89 }
90
91 const cResourceLib& resource_lib = m_world->GetEnvironment().GetResourceLib();
92 assert(resource_lib.GetSize() >= 0);
93
94 // Set the resource count to zero by default
95 m_resource_count.SetSize(resource_lib.GetSize());
96 m_faced_cell_resource_count.SetSize(resource_lib.GetSize());
97 m_cell_resource_count.SetSize(resource_lib.GetSize());
98 for (int i = 0; i < resource_lib.GetSize(); i++) {
99 m_resource_count.Set(ctx, i, 0.0);
100 m_faced_cell_resource_count.Set(ctx, i, 0.0);
101 m_cell_resource_count.Set(ctx, i, 0.0);
102 }
103
104 SetResourceUpdate(ctx, m_res_update, false);
105 // Round down to the closest update to choose how to initialize resources
106 }
107
UpdateResources(cAvidaContext & ctx,int cpu_cycles_used)108 void cTestCPU::UpdateResources(cAvidaContext& ctx, int cpu_cycles_used)
109 {
110 int ave_time_slice = m_world->GetConfig().AVE_TIME_SLICE.Get();
111 if ((m_res_method >= RES_UPDATED_DEPLETABLE) && (cpu_cycles_used % ave_time_slice == 0))
112 SetResourceUpdate(ctx, m_res_update + 1, true);
113 }
114
SetResourceUpdate(cAvidaContext & ctx,int update,bool round_to_closest)115 inline void cTestCPU::SetResourceUpdate(cAvidaContext& ctx, int update, bool round_to_closest)
116 {
117 // No resources defined? -- you can't do this!
118 if (!m_res) return;
119
120 m_res_update = update;
121
122 m_res->GetResourceCountForUpdate(ctx, update, m_resource_count, !round_to_closest);
123 }
124
ModifyResources(cAvidaContext & ctx,const tArray<double> & res_change)125 void cTestCPU::ModifyResources(cAvidaContext& ctx, const tArray<double>& res_change)
126 {
127 //We only let the testCPU modify the resources if we are using a DEPLETABLE option. @JEB
128 if (m_res_method >= RES_UPDATED_DEPLETABLE) m_resource_count.Modify(ctx, res_change);
129 }
130
131
132 // NOTE: This method assumes that the organism is a fresh creation.
ProcessGestation(cAvidaContext & ctx,cCPUTestInfo & test_info,int cur_depth)133 bool cTestCPU::ProcessGestation(cAvidaContext& ctx, cCPUTestInfo& test_info, int cur_depth)
134 {
135 assert(test_info.org_array[cur_depth] != NULL);
136
137 cOrganism & organism = *( test_info.org_array[cur_depth] );
138
139 // Determine how long this organism should be tested for...
140 int time_allocated = m_world->GetConfig().TEST_CPU_TIME_MOD.Get() * organism.GetGenome().GetSize();
141 time_allocated += m_res_cpu_cycle_offset; // If the resource offset has us starting at a different time, adjust @JEB
142
143 // Prepare the inputs...
144 cur_input = 0;
145 cur_receive = 0;
146
147 // Prepare the resources
148 InitResources(ctx, test_info.m_res_method, test_info.m_res, test_info.m_res_update, test_info.m_res_cpu_cycle_offset);
149
150
151 // Determine if we're tracing and what we need to print.
152 cHardwareTracer* tracer = test_info.GetTraceExecution() ? (test_info.GetTracer()) : NULL;
153 std::ostream * tracerStream = NULL;
154 if (tracer != NULL) tracerStream = tracer->GetStream();
155
156 // This way of keeping track of time is only used to update resources...
157 int time_used = m_res_cpu_cycle_offset; // Note: the offset is zero by default if no resources being used @JEB
158
159 organism.GetHardware().SetTrace(tracer);
160 while (time_used < time_allocated && organism.GetPhenotype().GetNumDivides() == 0 && !organism.IsDead())
161 {
162 time_used++;
163
164 // @CAO Need to watch out for parasites.
165
166 // Resources will be updated as if each update takes a number of cpu cycles equal to the average time slice
167 UpdateResources(ctx, time_used);
168
169 // Add extra info to trace files so that we can watch resource changes.
170 // This is a clumsy way to insert it in the trace file, but works for my purposes @JEB
171 if ( (m_res_method >= RES_UPDATED_DEPLETABLE) && (tracerStream != NULL) )
172 {
173 const cResourceLib& resource_lib = m_world->GetEnvironment().GetResourceLib();
174 assert(resource_lib.GetSize() >= 0);
175 *tracerStream << "Resources:";
176 // Print out resources
177 for(int i=0; i<resource_lib.GetSize(); i++)
178 {
179 *tracerStream << " " << m_resource_count.Get(ctx, i);
180 }
181 *tracerStream << endl;
182 }
183
184 organism.GetHardware().SingleProcess(ctx);
185 }
186
187
188 // Output final resource information @JEB
189 if ( (m_res_method >= RES_UPDATED_DEPLETABLE) && (tracerStream != NULL) )
190 {
191 const cResourceLib& resource_lib = m_world->GetEnvironment().GetResourceLib();
192 assert(resource_lib.GetSize() >= 0);
193 *tracerStream << "Resources:";
194 // Print out resources
195 for(int i=0; i<resource_lib.GetSize(); i++)
196 {
197 *tracerStream << " " << m_resource_count.Get(ctx, i);
198 }
199 *tracerStream << endl;
200 }
201
202
203 organism.GetHardware().SetTrace(NULL);
204
205 // Print out some final info in trace...
206 if (tracer != NULL) tracer->TraceTestCPU(time_used, time_allocated, organism);
207
208 // For now, always return true.
209 return true;
210 }
211
212
TestGenome(cAvidaContext & ctx,cCPUTestInfo & test_info,const Genome & genome)213 bool cTestCPU::TestGenome(cAvidaContext& ctx, cCPUTestInfo& test_info, const Genome& genome)
214 {
215 ctx.SetTestMode();
216 test_info.Clear();
217 TestGenome_Body(ctx, test_info, genome, 0);
218 ctx.ClearTestMode();
219
220 return test_info.is_viable;
221 }
222
TestGenome(cAvidaContext & ctx,cCPUTestInfo & test_info,const Genome & genome,ofstream & out_fp)223 bool cTestCPU::TestGenome(cAvidaContext& ctx, cCPUTestInfo& test_info, const Genome& genome, ofstream& out_fp)
224 {
225 ctx.SetTestMode();
226 test_info.Clear();
227 TestGenome_Body(ctx, test_info, genome, 0);
228
229 ////////////////////////////////////////////////////////////////
230 // IsViable() == false
231 // max_depth == 0 : (0) Parent doesn't divide
232 // max_depth == 1 : (2) Parent does divide, but child does not.
233 // max_depth >= 2 : (3) Parent and child do divide, but neither true.
234 // ------------------------------------------------------------
235 // IsViable() == true
236 // max_depth == 0 : (4) Parent Breed True
237 // max_depth == 1 : (5) Parent NOT Breed True, but Child Does
238 // max_depth >= 2 : (6) Multiple levels of non-breed true.
239 ////////////////////////////////////////////////////////////////
240
241
242 const int depth_comp = Min(test_info.max_depth, 2);
243 int repro_type = ((int) test_info.is_viable) * 3 + 1 + depth_comp;
244 if (test_info.is_viable == false && depth_comp == 0) repro_type = 0;
245
246 out_fp << test_info.is_viable << " "
247 << test_info.max_depth << " "
248 << test_info.depth_found << " "
249 << test_info.max_cycle << " "
250 << repro_type << endl;
251
252 ctx.ClearTestMode();
253 return test_info.is_viable;
254 }
255
TestGenome_Body(cAvidaContext & ctx,cCPUTestInfo & test_info,const Genome & genome,int cur_depth)256 bool cTestCPU::TestGenome_Body(cAvidaContext& ctx, cCPUTestInfo& test_info, const Genome& genome, int cur_depth)
257 {
258 assert(cur_depth < test_info.generation_tests);
259
260 // Input sizes can vary based on environment settings, must at least initialize
261 m_use_random_inputs = test_info.GetUseRandomInputs(); // save this value in case ResetInputs is used.
262 if (!test_info.GetUseManualInputs())
263 m_world->GetEnvironment().SetupInputs(ctx, input_array, m_use_random_inputs);
264 else
265 input_array = test_info.manual_inputs;
266
267 receive_array.Resize(3);
268 if (test_info.GetUseRandomInputs()) {
269 receive_array[0] = (15 << 24) + ctx.GetRandom().GetUInt(1 << 24); // 00001111
270 receive_array[1] = (51 << 24) + ctx.GetRandom().GetUInt(1 << 24); // 00110011
271 receive_array[2] = (85 << 24) + ctx.GetRandom().GetUInt(1 << 24); // 01010101
272 } else {
273 receive_array[0] = 0x0f139f14; // 00001111 00010011 10011111 00010100
274 receive_array[1] = 0x33083ee5; // 00110011 00001000 00111110 11100101
275 receive_array[2] = 0x5562eb41; // 01010101 01100010 11101011 01000001
276 }
277
278 if (cur_depth == 0) test_info.used_inputs = input_array;
279
280 if (cur_depth > test_info.max_depth) test_info.max_depth = cur_depth;
281
282 // Setup the organism we're working with now.
283 if (test_info.org_array[cur_depth] != NULL) {
284 delete test_info.org_array[cur_depth];
285 }
286 cOrganism* organism = new cOrganism(m_world, ctx, genome, -1, SRC_TEST_CPU);
287
288 // Copy the test mutation rates
289 organism->MutationRates().Copy(test_info.MutationRates());
290
291 test_info.org_array[cur_depth] = organism;
292 organism->SetOrgInterface(ctx, new cTestCPUInterface(this, test_info, cur_depth));
293 organism->GetPhenotype().SetupInject(genome.GetSequence());
294
295 // Run the current organism.
296 ProcessGestation(ctx, test_info, cur_depth);
297
298
299 // Notify the organism that it has died to allow for various cleanup methods to run
300 organism->NotifyDeath(ctx);
301
302
303 // Must be able to divide twice in order to form a successful colony,
304 // assuming the CPU doesn't get reset on divides.
305 //
306 // The possibilities after this gestation cycle are:
307 // 1: It did not copy at all => Exit this level.
308 // 2: It copied true => Check next gestation cycle, or set is_viable.
309 // 3: Its copy looks like an ancestor => copy true.
310 // 4: It copied false => we must check the child.
311
312 // Case 1: ////////////////////////////////////
313 if (organism->GetPhenotype().GetNumDivides() == 0) return false;
314
315 // Case 2: ////////////////////////////////////
316 if (organism->GetPhenotype().CopyTrue() == true) {
317 test_info.depth_found = cur_depth;
318 test_info.is_viable = true;
319 return true;
320 }
321
322 // Case 3: ////////////////////////////////////
323 bool is_ancestor = false;
324 for (int anc_depth = 0; anc_depth < cur_depth; anc_depth++) {
325 if (organism->OffspringGenome() == test_info.org_array[anc_depth]->GetGenome()){
326 is_ancestor = true;
327 const int cur_cycle = cur_depth - anc_depth;
328 if (test_info.max_cycle < cur_cycle) test_info.max_cycle = cur_cycle;
329 test_info.cycle_to = anc_depth;
330 }
331 }
332 if (is_ancestor) {
333 test_info.depth_found = cur_depth;
334 test_info.is_viable = true;
335 return true;
336 }
337
338 // Case 4: ////////////////////////////////////
339 // If we haven't reached maximum depth yet, check out the child.
340 if (cur_depth + 1 < test_info.generation_tests) {
341 // Run the offspring's genome.
342 return TestGenome_Body(ctx, test_info, organism->OffspringGenome(), cur_depth + 1);
343 }
344
345 // All options have failed; just return false.
346 return false;
347 }
348
349
PrintGenome(cAvidaContext & ctx,const Genome & genome,cString filename,int update,bool for_groups,int last_birth_cell,int last_group_id,int last_forager_type)350 void cTestCPU::PrintGenome(cAvidaContext& ctx, const Genome& genome, cString filename, int update, bool for_groups, int last_birth_cell, int last_group_id, int last_forager_type)
351 {
352 if (filename == "") filename.Set("archive/%03d-unnamed.org", genome.GetSize());
353
354 cCPUTestInfo test_info;
355 TestGenome(ctx, test_info, genome);
356
357 // Open the file...
358 cDataFile& df = m_world->GetDataFile(filename);
359
360 // Print the useful info at the top...
361 df.WriteTimeStamp();
362 cString c("");
363
364 df.WriteComment(c.Set("Filename........: %s", static_cast<const char*>(filename)));
365
366 if (update >= 0) df.WriteComment(c.Set("Update Output...: %d", update));
367 else df.WriteComment("Update Output...: N/A");
368
369 df.WriteComment(c.Set("Is Viable.......: %d", test_info.IsViable()));
370 df.WriteComment(c.Set("Repro Cycle Size: %d", test_info.GetMaxCycle()));
371 df.WriteComment(c.Set("Depth to Viable.: %d", test_info.GetDepthFound()));
372
373 df.WriteComment("");
374
375 const int num_levels = test_info.GetMaxDepth() + 1;
376 for (int j = 0; j < num_levels; j++) {
377 df.WriteComment(c.Set("Generation: %d", j));
378
379 cOrganism* organism = test_info.GetTestOrganism(j);
380 assert(organism != NULL);
381 cPhenotype& phenotype = organism->GetPhenotype();
382
383 df.WriteComment(c.Set("Merit...........: %f", phenotype.GetMerit().GetDouble()));
384 df.WriteComment(c.Set("Gestation Time..: %d", phenotype.GetGestationTime()));
385 df.WriteComment(c.Set("Fitness.........: %f", phenotype.GetFitness()));
386 df.WriteComment(c.Set("Errors..........: %d", phenotype.GetLastNumErrors()));
387 df.WriteComment(c.Set("Genome Size.....: %d", organism->GetGenome().GetSize()));
388 df.WriteComment(c.Set("Copied Size.....: %d", phenotype.GetCopiedSize()));
389 df.WriteComment(c.Set("Executed Size...: %d", phenotype.GetExecutedSize()));
390
391 if (for_groups) {
392 df.WriteComment(c.Set("Last Birth Group ID........: %d", last_group_id));
393 df.WriteComment(c.Set("Last Birth Forager Type....: %d", last_forager_type));
394 df.WriteComment(c.Set("Last Birth Cell............: %d", last_birth_cell));
395 }
396
397 if (phenotype.GetNumDivides() == 0)
398 df.WriteComment("Offspring.......: NONE");
399 else if (phenotype.CopyTrue())
400 df.WriteComment("Offspring.......: SELF");
401 else if (test_info.GetCycleTo() != -1)
402 df.WriteComment(c.Set("Offspring.......: %d", test_info.GetCycleTo()));
403 else
404 df.WriteComment(c.Set("Offspring.......: %d", j + 1));
405
406 df.WriteComment("");
407 }
408
409 df.WriteComment("Tasks Performed:");
410
411 const cEnvironment& env = m_world->GetEnvironment();
412 const tArray<int>& task_count = test_info.GetTestPhenotype().GetLastTaskCount();
413 const tArray<double>& task_qual = test_info.GetTestPhenotype().GetLastTaskQuality();
414 for (int i = 0; i < task_count.GetSize(); i++) {
415 df.WriteComment(c.Set("%s %d (%f)", static_cast<const char*>(env.GetTask(i).GetName()),
416 task_count[i], task_qual[i]));
417 }
418
419 // if resource bins are being used, print relevant information
420 if(m_world->GetConfig().USE_RESOURCE_BINS.Get()) {
421 df.WriteComment("Tasks Performed Using Internal Resources:");
422
423 const tArray<int>& internal_task_count = test_info.GetTestPhenotype().GetLastInternalTaskCount();
424 const tArray<double>& internal_task_qual = test_info.GetTestPhenotype().GetLastInternalTaskQuality();
425
426 for (int i = 0; i < task_count.GetSize(); i++) {
427 df.WriteComment(c.Set("%s %d (%f)", static_cast<const char*>(env.GetTask(i).GetName()),
428 internal_task_count[i], internal_task_qual[i]));
429 }
430
431 const tArray<double>& rbins_total = test_info.GetTestPhenotype().GetLastRBinsTotal();
432 const tArray<double>& rbins_avail = test_info.GetTestPhenotype().GetLastRBinsAvail();
433
434 df.WriteComment( "Resources Collected: Name\t\tTotal\t\tAvailable");
435 for (int i = 0; i < rbins_total.GetSize(); i++) {
436 df.WriteComment(c.Set(" %d : %s\t\t%f\t\t%f\t\t", i,
437 static_cast<const char*>(env.GetResourceLib().GetResource(i)->GetName()),
438 rbins_total[i], rbins_avail[i]));
439 }
440 }
441
442 df.Endl();
443
444 // Display the genome
445 genome.GetSequence().SaveInstructions(df.GetOFStream(), test_info.GetTestOrganism()->GetHardware().GetInstSet());
446
447 m_world->GetDataFileManager().Remove(filename);
448 }
449
450
PrintBioGroup(cAvidaContext & ctx,cBioGroup * bg,cString filename,int update)451 void cTestCPU::PrintBioGroup(cAvidaContext& ctx, cBioGroup* bg, cString filename, int update)
452 {
453 if (!bg->HasProperty("genome")) return;
454
455 Genome mg(bg->GetProperty("genome").AsString());
456
457 if (filename == "") filename.Set("archive/%03d-unnamed.org", mg.GetSequence().GetSize());
458
459 cCPUTestInfo test_info;
460 TestGenome(ctx, test_info, mg);
461
462 // Open the file...
463 cDataFile& df = m_world->GetDataFile(filename);
464
465 // Print the useful info at the top...
466 df.WriteTimeStamp();
467 cString c("");
468
469 df.WriteComment(c.Set("Filename........: %s", static_cast<const char*>(filename)));
470
471 if (update >= 0) df.WriteComment(c.Set("Update Output...: %d", update));
472 else df.WriteComment("Update Output...: N/A");
473
474 df.WriteComment(c.Set("Is Viable.......: %d", test_info.IsViable()));
475 df.WriteComment(c.Set("Repro Cycle Size: %d", test_info.GetMaxCycle()));
476 df.WriteComment(c.Set("Depth to Viable.: %d", test_info.GetDepthFound()));
477
478 df.WriteComment(c.Set("Genotype ID.....: %d", bg->GetID()));
479 df.WriteComment(c.Set("Tree Depth......: %d", bg->GetDepth()));
480
481 if (bg->HasProperty("update_born")) df.WriteComment(c.Set("Update Born.....: %d", bg->GetProperty("update_born").AsInt()));
482 if (bg->HasProperty("parents")) df.WriteComment(c.Set("Parent(s).......: %s", (const char*)bg->GetProperty("parents").AsString()));
483
484 df.WriteComment("");
485
486 const int num_levels = test_info.GetMaxDepth() + 1;
487 for (int j = 0; j < num_levels; j++) {
488 df.WriteComment(c.Set("Generation: %d", j));
489
490 cOrganism* organism = test_info.GetTestOrganism(j);
491 assert(organism != NULL);
492 cPhenotype& phenotype = organism->GetPhenotype();
493
494 df.WriteComment(c.Set("Merit...........: %f", phenotype.GetMerit().GetDouble()));
495 df.WriteComment(c.Set("Gestation Time..: %d", phenotype.GetGestationTime()));
496 df.WriteComment(c.Set("Fitness.........: %f", phenotype.GetFitness()));
497 df.WriteComment(c.Set("Errors..........: %d", phenotype.GetLastNumErrors()));
498 df.WriteComment(c.Set("Genome Size.....: %d", organism->GetGenome().GetSize()));
499 df.WriteComment(c.Set("Copied Size.....: %d", phenotype.GetCopiedSize()));
500 df.WriteComment(c.Set("Executed Size...: %d", phenotype.GetExecutedSize()));
501
502 if (phenotype.GetNumDivides() == 0)
503 df.WriteComment("Offspring.......: NONE");
504 else if (phenotype.CopyTrue())
505 df.WriteComment("Offspring.......: SELF");
506 else if (test_info.GetCycleTo() != -1)
507 df.WriteComment(c.Set("Offspring.......: %d", test_info.GetCycleTo()));
508 else
509 df.WriteComment(c.Set("Offspring.......: %d", j + 1));
510
511 df.WriteComment("");
512 }
513
514 df.WriteComment("Tasks Performed:");
515
516 const cEnvironment& env = m_world->GetEnvironment();
517 const tArray<int>& task_count = test_info.GetTestPhenotype().GetLastTaskCount();
518 const tArray<double>& task_qual = test_info.GetTestPhenotype().GetLastTaskQuality();
519 for (int i = 0; i < task_count.GetSize(); i++) {
520 df.WriteComment(c.Set("%s %d (%f)", static_cast<const char*>(env.GetTask(i).GetName()),
521 task_count[i], task_qual[i]));
522 }
523
524 // if resource bins are being used, print relevant information
525 if(m_world->GetConfig().USE_RESOURCE_BINS.Get()) {
526 df.WriteComment("Tasks Performed Using Internal Resources:");
527
528 const tArray<int>& internal_task_count = test_info.GetTestPhenotype().GetLastInternalTaskCount();
529 const tArray<double>& internal_task_qual = test_info.GetTestPhenotype().GetLastInternalTaskQuality();
530
531 for (int i = 0; i < task_count.GetSize(); i++) {
532 df.WriteComment(c.Set("%s %d (%f)", static_cast<const char*>(env.GetTask(i).GetName()),
533 internal_task_count[i], internal_task_qual[i]));
534 }
535
536 const tArray<double>& rbins_total = test_info.GetTestPhenotype().GetLastRBinsTotal();
537 const tArray<double>& rbins_avail = test_info.GetTestPhenotype().GetLastRBinsAvail();
538
539 df.WriteComment( "Resources Collected: Name\t\tTotal\t\tAvailable");
540 for (int i = 0; i < rbins_total.GetSize(); i++) {
541 df.WriteComment(c.Set(" %d : %s\t\t%f\t\t%f\t\t", i,
542 static_cast<const char*>(env.GetResourceLib().GetResource(i)->GetName()),
543 rbins_total[i], rbins_avail[i]));
544 }
545 }
546
547 df.Endl();
548
549 // Display the genome
550 mg.GetSequence().SaveInstructions(df.GetOFStream(), test_info.GetTestOrganism()->GetHardware().GetInstSet());
551
552 m_world->GetDataFileManager().Remove(filename);
553 }
554
555
ResetInputs(cAvidaContext & ctx)556 void cTestCPU::ResetInputs(cAvidaContext& ctx)
557 {
558 if (!m_use_manual_inputs)
559 m_world->GetEnvironment().SetupInputs(ctx, input_array, m_use_random_inputs);
560 }
561
562