diff --git a/source/EngineGpuKernels/GenomeDecoder.cuh b/source/EngineGpuKernels/GenomeDecoder.cuh index bfed8b0eb..d06394db9 100644 --- a/source/EngineGpuKernels/GenomeDecoder.cuh +++ b/source/EngineGpuKernels/GenomeDecoder.cuh @@ -64,7 +64,7 @@ public: __inline__ __device__ static void setNextConstructorSeparation(uint8_t* genome, int nodeAddress, bool separation); __inline__ __device__ static void setNextConstructorNumBranches(uint8_t* genome, int nodeAddress, int numBranches); __inline__ __device__ static bool containsSectionSelfReplication(uint8_t* genome, int genomeSize); - __inline__ __device__ static int getNodeAddressForSelfReplication(uint8_t* genome, int genomeSize); //-1 = no node for self-replication found + __inline__ __device__ static int getNodeAddressForSelfReplication(uint8_t* genome, int genomeSize, bool& containsSelfReplicator); __inline__ __device__ static void setRandomCellFunctionData(SimulationData& data, uint8_t* genome, int nodeAddress, CellFunction const& cellFunction, bool makeSelfCopy, int subGenomeSize); __inline__ __device__ static int getCellFunctionDataSize( CellFunction cellFunction, @@ -740,15 +740,16 @@ __inline__ __device__ bool GenomeDecoder::containsSectionSelfReplication(uint8_t return false; } -__inline__ __device__ int GenomeDecoder::getNodeAddressForSelfReplication(uint8_t* genome, int genomeSize) +__inline__ __device__ int GenomeDecoder::getNodeAddressForSelfReplication(uint8_t* genome, int genomeSize, bool& containsSelfReplicator) { int nodeAddress = 0; for (; nodeAddress < genomeSize;) { if (isNextCellSelfReplication(genome, nodeAddress)) { + containsSelfReplicator = true; return nodeAddress; } nodeAddress += Const::CellBasicBytes + getNextCellFunctionDataSize(genome, genomeSize, nodeAddress); } - - return -1; + containsSelfReplicator = false; + return 0; } diff --git a/source/EngineGpuKernels/MutationProcessor.cuh b/source/EngineGpuKernels/MutationProcessor.cuh index 691513b46..0d8cfdc77 100644 --- a/source/EngineGpuKernels/MutationProcessor.cuh +++ b/source/EngineGpuKernels/MutationProcessor.cuh @@ -739,10 +739,11 @@ __inline__ __device__ void MutationProcessor::duplicateMutation(SimulationData& } auto sizeDelta = endSourceIndex - startSourceIndex; auto nodeAddressForSelfReplication = -1; + auto duplicatedSegmentContainsSelfReplicator = false; if (!cudaSimulationParameters.cellFunctionConstructorMutationSelfReplication) { - nodeAddressForSelfReplication = GenomeDecoder::getNodeAddressForSelfReplication(genome + startSourceIndex, sizeDelta); - if (nodeAddressForSelfReplication != -1 ) { - nodeAddressForSelfReplication += startSourceIndex; + nodeAddressForSelfReplication = + GenomeDecoder::getNodeAddressForSelfReplication(genome + startSourceIndex, sizeDelta, duplicatedSegmentContainsSelfReplicator) + startSourceIndex; + if (duplicatedSegmentContainsSelfReplicator) { sizeDelta += 2 + Const::GenomeHeaderSize; //additional size for empty subgenome } } @@ -802,7 +803,7 @@ __inline__ __device__ void MutationProcessor::duplicateMutation(SimulationData& } //copy duplicated part - if (nodeAddressForSelfReplication == -1) { + if (!duplicatedSegmentContainsSelfReplicator) { for (int i = 0; i < sizeDelta; ++i) { targetGenome[startTargetIndex + i] = genome[startSourceIndex + i]; }