1 /*
2 * cDefaultRunDriver.cc
3 * Avida
4 *
5 * Created by David on 12/11/05.
6 * Copyright 1999-2011 Michigan State University. All rights reserved.
7 *
8 *
9 * This file is part of Avida.
10 *
11 * Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
12 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
13 *
14 * Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License along with Avida.
18 * If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22 #include "cDefaultRunDriver.h"
23
24 #include "cAvidaContext.h"
25 #include "cBGGenotype.h"
26 #include "cClassificationManager.h"
27 #include "cHardwareBase.h"
28 #include "cHardwareManager.h"
29 #include "cOrganism.h"
30 #include "cPopulation.h"
31 #include "cPopulationCell.h"
32 #include "cStats.h"
33 #include "cString.h"
34 #include "cWorld.h"
35
36 #include <cstdlib>
37 #include <ctime>
38 #include <iostream>
39 #include <iomanip>
40
41 using namespace std;
42
43
cDefaultRunDriver(cWorld * world)44 cDefaultRunDriver::cDefaultRunDriver(cWorld* world) : m_world(world), m_done(false),
45 m_fastforward(false),m_last_generation(0), m_generation_same_update_count(0)
46 {
47 GlobalObjectManager::Register(this);
48 world->SetDriver(this);
49
50 // Save this config variable
51 m_generation_update_fastforward_threshold = m_world->GetConfig().FASTFORWARD_UPDATES.Get();
52 m_population_fastforward_threshold = m_world->GetConfig().FASTFORWARD_NUM_ORGS.Get();
53 }
54
~cDefaultRunDriver()55 cDefaultRunDriver::~cDefaultRunDriver()
56 {
57 GlobalObjectManager::Unregister(this);
58 delete m_world;
59 }
60
61
Run()62 void cDefaultRunDriver::Run()
63 {
64 cPopulation& population = m_world->GetPopulation();
65 cStats& stats = m_world->GetStats();
66
67 const double point_mut_prob = m_world->GetConfig().POINT_MUT_PROB.Get() +
68 m_world->GetConfig().POINT_INS_PROB.Get() +
69 m_world->GetConfig().POINT_DEL_PROB.Get() +
70 m_world->GetConfig().DIV_LGT_PROB.Get();
71
72 void (cPopulation::*ActiveProcessStep)(cAvidaContext& ctx, double step_size, int cell_id) = &cPopulation::ProcessStep;
73 if (m_world->GetConfig().SPECULATIVE.Get() &&
74 m_world->GetConfig().THREAD_SLICING_METHOD.Get() != 1 && !m_world->GetConfig().IMPLICIT_REPRO_END.Get() && point_mut_prob == 0.0) {
75 ActiveProcessStep = &cPopulation::ProcessStepSpeculative;
76 }
77
78 cAvidaContext& ctx = m_world->GetDefaultContext();
79
80 while (!m_done) {
81 m_world->GetEvents(ctx);
82 if(m_done == true) break;
83
84 // Increment the Update.
85 stats.IncCurrentUpdate();
86
87 population.ProcessPreUpdate();
88
89 // Handle all data collection for previous update.
90 if (stats.GetUpdate() > 0) {
91 // Tell the stats object to do update calculations and printing.
92 stats.ProcessUpdate();
93 }
94
95 // don't process organisms if we are in fast-forward mode. -- @JEB
96 if (!GetFastForward()) {
97 // Process the update.
98 // query the world to calculate the exact size of this update:
99 const int UD_size = m_world->CalculateUpdateSize();
100 const double step_size = 1.0 / (double) UD_size;
101
102 for (int i = 0; i < UD_size; i++) {
103 if(population.GetNumOrganisms() == 0) {
104 break;
105 }
106 (population.*ActiveProcessStep)(ctx, step_size, population.ScheduleOrganism());
107 }
108 }
109
110 // end of update stats...
111 population.ProcessPostUpdate(ctx);
112
113 m_world->ProcessPostUpdate(ctx);
114
115 // No viewer; print out status for this update....
116 if (m_world->GetVerbosity() > VERBOSE_SILENT) {
117 cout.setf(ios::left);
118 cout.setf(ios::showpoint);
119 cout << "UD: " << setw(6) << stats.GetUpdate() << " ";
120 cout << "Gen: " << setw(9) << setprecision(7) << stats.SumGeneration().Average() << " ";
121 cout << "Fit: " << setw(9) << setprecision(7) << stats.GetAveFitness() << " ";
122 cout << "Orgs: " << setw(6) << population.GetNumOrganisms() << " ";
123 if (m_world->GetPopulation().GetNumDemes() > 1) cout << "Demes: " << setw(4) << stats.GetNumOccupiedDemes() << " ";
124 if (m_world->GetVerbosity() == VERBOSE_ON || m_world->GetVerbosity() == VERBOSE_DETAILS) {
125 cout << "Merit: " << setw(9) << setprecision(7) << stats.GetAveMerit() << " ";
126 cout << "Thrd: " << setw(6) << stats.GetNumThreads() << " ";
127 cout << "Para: " << stats.GetNumParasites() << " ";
128 cout << "GenEntr: " << stats.GetEntropy() << " ";
129 }
130 if (m_world->GetVerbosity() >= VERBOSE_DEBUG) {
131 cout << "Spec: " << setw(6) << setprecision(4) << stats.GetAveSpeculative() << " ";
132 cout << "SWst: " << setw(6) << setprecision(4) << (((double)stats.GetSpeculativeWaste() / (double)m_world->CalculateUpdateSize()) * 100.0) << "% ";
133 cout << "GSz: " << setw(4) << setprecision(3) << (double)((stats.GetNumGenotypes() + stats.GetNumGenotypesHistoric()) * sizeof(cBGGenotype)) / 1048576.0 << "m";
134 }
135
136 cout << endl;
137 }
138
139
140 // Do Point Mutations
141 if (point_mut_prob > 0 ) {
142 for (int i = 0; i < population.GetSize(); i++) {
143 if (population.GetCell(i).IsOccupied()) {
144 int num_mut = population.GetCell(i).GetOrganism()->GetHardware().PointMutate(ctx);
145 population.GetCell(i).GetOrganism()->IncPointMutations(num_mut);
146 }
147 }
148 }
149
150 // Keep track of changes in generation for fast-forward purposes
151 UpdateFastForward(stats.GetGeneration(),stats.GetNumCreatures());
152
153 // Exit conditons...
154 if((population.GetNumOrganisms()==0) && m_world->AllowsEarlyExit()) {
155 m_done = true;
156 }
157 }
158 }
159
RaiseException(const cString & in_string)160 void cDefaultRunDriver::RaiseException(const cString& in_string)
161 {
162 cerr << "Error: " << in_string << endl;
163 }
164
RaiseFatalException(int exit_code,const cString & in_string)165 void cDefaultRunDriver::RaiseFatalException(int exit_code, const cString& in_string)
166 {
167 cerr << "Error: " << in_string << " Exiting..." << endl;
168 exit(exit_code);
169 }
170
NotifyComment(const cString & in_string)171 void cDefaultRunDriver::NotifyComment(const cString& in_string)
172 {
173 cout << in_string << endl;
174 }
175
NotifyWarning(const cString & in_string)176 void cDefaultRunDriver::NotifyWarning(const cString& in_string)
177 {
178 cout << "Warning: " << in_string << endl;
179 }
180
UpdateFastForward(double inGeneration,int population)181 void cDefaultRunDriver::UpdateFastForward (double inGeneration, int population)
182 {
183 if (bool(m_population_fastforward_threshold))
184 {
185 if (population >= m_population_fastforward_threshold) m_fastforward = true;
186 else m_fastforward = false;
187 }
188 if (!m_generation_update_fastforward_threshold) return;
189
190 if (inGeneration == m_last_generation)
191 {
192 m_generation_same_update_count++;
193 if (m_generation_same_update_count >= m_generation_update_fastforward_threshold) m_fastforward = true;
194 }
195 else
196 {
197 m_generation_same_update_count = 0;
198 m_last_generation = inGeneration;
199 }
200 }
201