| 1155 | |
| 1156 | |
| 1157 | bool cHardwareTransSMT::Divide_Main(cAvidaContext& ctx, double mut_multiplier) |
| 1158 | { |
| 1159 | const int mem_space_used = GetHead(nHardware::HEAD_WRITE).GetMemSpace(); |
| 1160 | const int write_head_pos = GetHead(nHardware::HEAD_WRITE).GetPosition(); |
| 1161 | |
| 1162 | // Make sure the memory space we're using exists |
| 1163 | // Make sure the offpsring memory space isn't the parental space //LZ ?? |
| 1164 | if (m_mem_array.GetSize() <= mem_space_used || mem_space_used == 0) return false; |
| 1165 | |
| 1166 | // Make sure this divide will produce a viable offspring. |
| 1167 | m_cur_child = mem_space_used; // save current child memory space for use by dependent functions (e.g. calcCopiedSize()) |
| 1168 | |
| 1169 | //Genome size gets a + 1 to handle heads, so we have to adjust size when it's sent to CheckViable |
| 1170 | if (!Divide_CheckViable(ctx, m_mem_array[0].GetSize() - 1, write_head_pos)) return false; |
| 1171 | |
| 1172 | // Since the divide will now succeed, set up the information to be sent to the new organism |
| 1173 | m_mem_array[mem_space_used].Resize(write_head_pos); |
| 1174 | |
| 1175 | InstructionSequencePtr offspring_seq(new InstructionSequence(m_mem_array[mem_space_used])); |
| 1176 | HashPropertyMap props; |
| 1177 | cHardwareManager::SetupPropertyMap(props, (const char*)m_inst_set->GetInstSetName()); |
| 1178 | Genome offspring(GetType(), props, offspring_seq); |
| 1179 | |
| 1180 | m_organism->OffspringGenome() = offspring; |
| 1181 | |
| 1182 | // Handle Divide Mutations... |
| 1183 | Divide_DoMutations(ctx, mut_multiplier); |
| 1184 | |
| 1185 | // Many tests will require us to run the offspring through a test CPU; |
| 1186 | // this is, for example, to see if mutations need to be reverted or if |
| 1187 | // lineages need to be updated. |
| 1188 | Divide_TestFitnessMeasures(ctx); |
| 1189 | |
| 1190 | // reset first time instruction costs |
| 1191 | for (int i = 0; i < m_inst_ft_cost.GetSize(); i++) { |
| 1192 | m_inst_ft_cost[i] = m_inst_set->GetFTCost(Instruction(i)); |
| 1193 | } |
| 1194 | |
| 1195 | bool parent_alive = m_organism->ActivateDivide(ctx, &m_threads[m_cur_thread].context_phenotype); |
| 1196 | //reset the memory of the memory space that has been divided off |
| 1197 | m_mem_array[mem_space_used] = InstructionSequence("a"); |
| 1198 | |
| 1199 | // Division Methods: |
| 1200 | // 0 - DIVIDE_METHOD_OFFSPRING - Create a child, leave parent state untouched. |
| 1201 | // 1 - DIVIDE_METHOD_SPLIT - Create a child, completely reset state of parent. |
| 1202 | // 2 - DIVIDE_METHOD_BIRTH - Create a child, reset state of parent's current thread. |
| 1203 | |
| 1204 | if (parent_alive) { // If the parent is no longer alive, all of this is moot |
| 1205 | switch (m_world->GetConfig().DIVIDE_METHOD.Get()) { |
| 1206 | case DIVIDE_METHOD_SPLIT: |
| 1207 | Reset(ctx); // This will wipe out all parasites on a divide. |
| 1208 | break; |
| 1209 | |
| 1210 | case DIVIDE_METHOD_BIRTH: |
| 1211 | // Reset only the calling thread's state |
| 1212 | for(int x = 0; x < nHardware::NUM_HEADS; x++) GetHead(x).Reset(this, 0); |
| 1213 | for(int x = 0; x < NUM_LOCAL_STACKS; x++) Stack(x).Clear(); |
| 1214 | if(m_world->GetConfig().INHERIT_MERIT.Get() == 0) { |
nothing calls this directly
no test coverage detected