1 /*
2  *  cHardwareBase.h
3  *  Avida
4  *
5  *  Called "hardware_base.hh" prior to 11/17/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 #ifndef cHardwareBase_h
24 #define cHardwareBase_h
25 
26 #include "avida/core/Sequence.h"
27 
28 #include <cassert>
29 #include <climits>
30 #include <iostream>
31 
32 #ifndef cInstSet_h
33 #include "cInstSet.h"
34 #endif
35 #ifndef tBuffer_h
36 #include "tBuffer.h"
37 #endif
38 #ifndef tSmartArray_h
39 #include "tSmartArray.h"
40 #endif
41 
42 class cAvidaContext;
43 class cBioUnit;
44 class cCodeLabel;
45 class cCPUMemory;
46 class cHardwareTracer;
47 class cHeadCPU;
48 class cInstruction;
49 class cMutation;
50 class cOrganism;
51 class cString;
52 class cWorld;
53 
54 using namespace std;
55 using namespace Avida;
56 
57 
58 class cHardwareBase
59 {
60 protected:
61   cWorld* m_world;
62   cOrganism* m_organism;            // Organism using this hardware.
63   cInstSet* m_inst_set;             // Instruction set being used.
64   cHardwareTracer* m_tracer;        // Set this if you want execution traced.
65   cHardwareTracer* m_minitracer;    // Set this if you want execution traced in a condensed and tractable format.
66   cString& m_minitrace_file;
67   tSmartArray<char> m_microtracer;
68   tSmartArray<int> m_navtraceloc;
69   tSmartArray<int> m_navtracefacing;
70   tSmartArray<int> m_navtraceupdate;
71   bool m_microtrace;
72   bool m_topnavtrace;
73   bool m_reprotrace;
74 
75   // --------  Instruction Costs  ---------
76   int m_inst_cost;
77   int m_female_cost;
78   tArray<int> m_inst_ft_cost;
79   tArray<double> m_inst_energy_cost;
80   tArray<double> m_inst_res_cost;
81   tArray<double> m_inst_fem_res_cost;
82   tArray<int> m_thread_inst_cost;
83   tArray<int> m_thread_inst_post_cost;
84   tArray<int> m_active_thread_costs;
85   tArray<int> m_active_thread_post_costs;
86   bool m_has_any_costs;
87   bool m_has_costs;
88   bool m_has_ft_costs;
89   bool m_has_energy_costs;
90   bool m_has_res_costs;
91   bool m_has_fem_res_costs;
92   int m_task_switching_cost;
93   bool m_has_female_costs;
94   bool m_has_choosy_female_costs;
95   bool m_has_post_costs;
96 
97   // --------  Base Hardware Feature Support  ---------
98   tSmartArray<int> m_ext_mem;
99   bool m_implicit_repro_active;
100 
101 	// --------  Bit masks  ---------
102 	static const unsigned int MASK_SIGNBIT = 0x7FFFFFFF;
103 	static const unsigned int MASK24       = 0xFFFFFF;
104 
105 	static const unsigned int MASKOFF_LOWEST16       = 0xFFFF0000;
106 	static const unsigned int MASKOFF_LOWEST15       = 0xFFFF8000;
107 	static const unsigned int MASKOFF_LOWEST14       = 0xFFFFC000;
108 	static const unsigned int MASKOFF_LOWEST13       = 0xFFFFE000;
109 	static const unsigned int MASKOFF_LOWEST12       = 0xFFFFF000;
110 	static const unsigned int MASKOFF_LOWEST8        = 0xFFFFFF00;
111 	static const unsigned int MASKOFF_LOWEST4        = 0xFFFFFFF0;
112 
113   cHardwareBase(); // @not_implemented
114   cHardwareBase(const cHardwareBase&); // @not_implemented
115   cHardwareBase& operator=(const cHardwareBase&); // @not_implemented
116 
117 private:
118   cString null_str;
119 
120 public:
121   cHardwareBase(cWorld* world, cOrganism* in_organism, cInstSet* inst_set);
~cHardwareBase()122   virtual ~cHardwareBase() { ; }
123 
124   // interrupt types
125   enum interruptTypes {MSG_INTERRUPT = 0, MOVE_INTERRUPT};
126 
127   // --------  Organism  ---------
GetOrganism()128   cOrganism* GetOrganism() { return m_organism; }
GetInstSet()129   const cInstSet& GetInstSet() const { return *m_inst_set; }
130 
131 
132   // --------  Core Functionality  --------
133   void Reset(cAvidaContext& ctx);
134   virtual bool SingleProcess(cAvidaContext& ctx, bool speculative = false) = 0;
135   virtual void ProcessBonusInst(cAvidaContext& ctx, const cInstruction& inst) = 0;
136 
137   int Divide_DoMutations(cAvidaContext& ctx, double mut_multiplier = 1.0, const int maxmut = INT_MAX);
138   bool Divide_TestFitnessMeasures(cAvidaContext& ctx);
139 
140   // --------  Helper methods  --------
141   virtual int GetType() const = 0;
142   virtual bool SupportsSpeculative() const = 0;
143   virtual void PrintStatus(std::ostream& fp) = 0;
144   virtual void PrintMiniTraceStatus(cAvidaContext& ctx, std::ostream& fp, const cString& next_name) = 0;
145   virtual void PrintMiniTraceSuccess(std::ostream& fp, const int exec_success) = 0;
SetTrace(cHardwareTracer * tracer)146   void SetTrace(cHardwareTracer* tracer) { m_tracer = tracer; }
147   void SetMiniTrace(const cString& filename, const int gen_id, const cString& genotype);
SetMicroTrace()148   void SetMicroTrace() { m_microtrace = true; }
SetTopNavTrace(bool nav_trace)149   void SetTopNavTrace(bool nav_trace) { m_topnavtrace = nav_trace; }
IsTopNavTrace()150   bool IsTopNavTrace() { return m_topnavtrace; }
SetReproTrace(bool repro_trace)151   void SetReproTrace(bool repro_trace) { m_reprotrace = repro_trace; }
IsReproTrace()152   bool IsReproTrace() { return m_reprotrace; }
153   void RecordMicroTrace(const cInstruction& cur_inst);
154   void PrintMicroTrace(int gen_id);
155   void RecordNavTrace(bool use_avatar);
GetMicroTrace()156   tSmartArray<char>& GetMicroTrace() { return m_microtracer; }
GetNavTraceLoc()157   tSmartArray<int>& GetNavTraceLoc() { return m_navtraceloc; }
GetNavTraceFacing()158   tSmartArray<int>& GetNavTraceFacing() { return m_navtracefacing; }
GetNavTraceUpdate()159   tSmartArray<int>& GetNavTraceUpdate() { return m_navtraceupdate; }
160   void DeleteMiniTrace(bool print_reacs);
161   virtual void SetupMiniTraceFileHeader(const cString& filename, const int gen_id, const cString& genotype) = 0;
SetupExtendedMemory(const tArray<int> & ext_mem)162   void SetupExtendedMemory(const tArray<int>& ext_mem) { m_ext_mem = ext_mem; }
163   void PrintMiniTraceReactions();
164 
165   // --------  Stack Manipulation...  --------
166   virtual int GetStack(int depth = 0, int stack_id = -1, int in_thread = -1) const = 0;
167   virtual int GetNumStacks() const = 0;
168 
169 
170   // --------  Head Manipulation (including IP)  --------
171   virtual const cHeadCPU& GetHead(int head_id) const = 0;
172   virtual cHeadCPU& GetHead(int head_id) = 0;
173   virtual const cHeadCPU& GetHead(int head_id, int thread) const = 0;
174   virtual cHeadCPU& GetHead(int head_id, int thread) = 0;
175   virtual int GetNumHeads() const = 0;
176 
177   virtual const cHeadCPU& IP() const = 0;
178   virtual cHeadCPU& IP() = 0;
179   virtual const cHeadCPU& IP(int thread) const = 0;
180   virtual cHeadCPU& IP(int thread) = 0;
181 
182   cHeadCPU FindLabelFull(const cCodeLabel& label);
183 
184 
185   // --------  Memory Manipulation  --------
186   virtual const cCPUMemory& GetMemory() const = 0;
187   virtual cCPUMemory& GetMemory() = 0;
188   virtual int GetMemSize() const = 0;
189   virtual const cCPUMemory& GetMemory(int value) const = 0;
190   virtual cCPUMemory& GetMemory(int value) = 0;
191   virtual int GetMemSize(int value) const = 0;
192   virtual int GetNumMemSpaces() const = 0;
193 
GetExtendedMemory()194   const tSmartArray<int>& GetExtendedMemory() const { return m_ext_mem; }
195 
196 
197   // --------  Register Manipulation  --------
198   virtual int GetRegister(int reg_id) const = 0;
199   virtual int GetNumRegisters() const = 0;
200 
201 
202   // --------  Thread Manipulation  --------
203   virtual bool ThreadSelect(const int thread_id) = 0;
204   virtual bool ThreadSelect(const cCodeLabel& in_label) = 0;
205   virtual void ThreadNext() = 0;
206   virtual void ThreadPrev() = 0;
207   virtual cBioUnit* ThreadGetOwner() = 0;
208 
209   virtual int GetNumThreads() const = 0;
210   virtual int GetCurThread() const = 0;
211   virtual int GetCurThreadID() const = 0;
212 
213   // interrupt current thread
214   virtual bool InterruptThread(int interruptType) = 0; // only implemented in cHardwareCPU and cHardwareExperimental
215   virtual int GetThreadMessageTriggerType(int _index) = 0;
216 
217 
218   // --------  Parasite Stuff  --------
219   virtual bool ParasiteInfectHost(cBioUnit* bu) = 0;
220 
221 
222   // --------  Mutation  --------
223   virtual int PointMutate(cAvidaContext& ctx, double override_mut_rate = 0.0);
224 
225 
226   // --------  Input/Output Buffers  --------
227   virtual tBuffer<int>& GetInputBuf();
228   virtual tBuffer<int>& GetOutputBuf();
229 
230 
231   // --------  State Transfer  --------
InheritState(cHardwareBase & in_hardware)232   virtual void InheritState(cHardwareBase& in_hardware) { ; }
233 
234 
235   // --------  Alarm  --------
Jump_To_Alarm_Label(int jump_label)236   virtual bool Jump_To_Alarm_Label(int jump_label) { return false; }
237 
238 
239 	// -------- Synchronization --------
240   //! Called when the organism that owns this CPU has received a flash from a neighbor.
241   virtual void ReceiveFlash();
242 
243 	// -------- HGT --------
244 	//! Retrieve a genome fragment extending downstream from the read head.
245 	virtual Sequence GetGenomeFragment(unsigned int downstream);
246 	//! Insert a genome fragment at the current write head.
247 	virtual void InsertGenomeFragment(const Sequence& fragment);
248 
249 protected:
250   // --------  Core Execution Methods  --------
251   bool SingleProcess_PayPreCosts(cAvidaContext& ctx, const cInstruction& cur_inst, const int thread_id);
252   bool IsPayingActiveCost(cAvidaContext& ctx, const int thread_id);
253   void SingleProcess_PayPostResCosts(cAvidaContext& ctx, const cInstruction& cur_inst);
254   void SingleProcess_SetPostCPUCosts(cAvidaContext& ctx, const cInstruction& cur_inst, const int thread_id);
255   virtual void internalReset() = 0;
256 	virtual void internalResetOnFailedDivide() = 0;
257 
258 
259   // --------  No-Operation Instruction  --------
260   bool Inst_Nop(cAvidaContext& ctx);  // A no-operation instruction that does nothing!
261 
262 
263   // --------  Implicit Repro Check/Instruction  -------- @JEB
264   inline void CheckImplicitRepro(cAvidaContext& ctx, bool exec_last_inst = false)
265     { if (m_implicit_repro_active) checkImplicitRepro(ctx, exec_last_inst); }
266   virtual bool Inst_Repro(cAvidaContext& ctx);
267 
268 
269   // --------  Execution Speed Instruction  --------
270   bool Inst_DoubleEnergyUsage(cAvidaContext& ctx);
271   bool Inst_HalveEnergyUsage(cAvidaContext& ctx);
272   bool Inst_DefaultEnergyUsage(cAvidaContext& ctx);
273 
274 
275 
276   // --------  Mutation Helper Methods  --------
277   bool doUniformMutation(cAvidaContext& ctx, Sequence& genome);
278   void doUniformCopyMutation(cAvidaContext& ctx, cHeadCPU& head);
279   void doSlipMutation(cAvidaContext& ctx, Sequence& genome, int from = -1);
280   void doTransMutation(cAvidaContext& ctx, Sequence& genome, int from = -1);
281   void doLGTMutation(cAvidaContext& ctx, Sequence& genome);
282 
283 
284   // --------  Organism Execution Property Calculation  --------
285   virtual int calcExecutedSize(const int parent_size);
286   virtual int calcCopiedSize(const int parent_size, const int child_size) = 0;
287 
288 
289   // --------  Division Support Methods  --------
290   bool Divide_CheckViable(cAvidaContext& ctx, const int parent_size, const int child_size, bool using_repro = false);
291   unsigned Divide_DoExactMutations(cAvidaContext& ctx, double mut_multiplier = 1.0, const int pointmut = INT_MAX);
292   bool Divide_TestFitnessMeasures1(cAvidaContext& ctx);
293 
294 
295 private:
296   void checkImplicitRepro(cAvidaContext& ctx, bool exec_last_inst = false);
297 };
298 
299 
300 #endif
301