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