Skip to content

Commit

Permalink
duplication mutation extended: allow copying segments containing self…
Browse files Browse the repository at this point in the history
…-replicating parts
  • Loading branch information
chrxh committed Sep 28, 2024
1 parent 2831766 commit 72b6eff
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 7 deletions.
44 changes: 42 additions & 2 deletions source/EngineGpuKernels/GenomeDecoder.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public:
__inline__ __device__ static int getNextExecutionNumber(uint8_t* genome, int nodeAddress);
__inline__ __device__ static int getNextInputExecutionNumber(uint8_t* genome, int nodeAddress);
__inline__ __device__ static void setNextCellFunctionType(uint8_t* genome, int nodeAddress, CellFunction cellFunction);
__inline__ __device__ static void setNextCellSelfReplication(uint8_t* genome, int nodeAddress, bool value);
__inline__ __device__ static void setNextCellSubgenomeSize(uint8_t* genome, int nodeAddress, int size);
__inline__ __device__ static void setNextCellColor(uint8_t* genome, int nodeAddress, int color);
__inline__ __device__ static void setNextInputExecutionNumber(uint8_t* genome, int nodeAddress, int value);
__inline__ __device__ static void setNextOutputBlocked(uint8_t* genome, int nodeAddress, bool value);
Expand All @@ -62,8 +64,8 @@ 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 void
setRandomCellFunctionData(SimulationData& data, uint8_t* genome, int nodeAddress, CellFunction const& cellFunction, bool makeSelfCopy, int subGenomeSize);
__inline__ __device__ static int getNodeAddressForSelfReplication(uint8_t* genome, int genomeSize); //-1 = no node for self-replication found
__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,
bool makeSelfCopy,
Expand Down Expand Up @@ -615,6 +617,31 @@ __inline__ __device__ void GenomeDecoder::setNextCellFunctionType(uint8_t* genom
genome[nodeAddress] = static_cast<uint8_t>(cellFunction);
}

__inline__ __device__ void GenomeDecoder::setNextCellSelfReplication(uint8_t* genome, int nodeAddress, bool value)
{
switch (getNextCellFunctionType(genome, nodeAddress)) {
case CellFunction_Constructor: {
genome[nodeAddress + Const::CellBasicBytes + Const::ConstructorFixedBytes] = GenomeDecoder::convertBoolToByte(value);
} break;
case CellFunction_Injector: {
genome[nodeAddress + Const::CellBasicBytes + Const::InjectorFixedBytes] = GenomeDecoder::convertBoolToByte(value);
} break;
}
}

__inline__ __device__ void GenomeDecoder::setNextCellSubgenomeSize(uint8_t* genome, int nodeAddress, int size)
{

switch (getNextCellFunctionType(genome, nodeAddress)) {
case CellFunction_Constructor: {
GenomeDecoder::writeWord(genome, nodeAddress + Const::CellBasicBytes + Const::ConstructorFixedBytes + 1, size);
} break;
case CellFunction_Injector: {
GenomeDecoder::writeWord(genome, nodeAddress + Const::CellBasicBytes + Const::InjectorFixedBytes + 1, size);
} break;
}
}

__inline__ __device__ void GenomeDecoder::setNextCellColor(uint8_t* genome, int nodeAddress, int color)
{
genome[nodeAddress + Const::CellColorPos] = color;
Expand Down Expand Up @@ -712,3 +739,16 @@ __inline__ __device__ bool GenomeDecoder::containsSectionSelfReplication(uint8_t

return false;
}

__inline__ __device__ int GenomeDecoder::getNodeAddressForSelfReplication(uint8_t* genome, int genomeSize)
{
int nodeAddress = 0;
for (; nodeAddress < genomeSize;) {
if (isNextCellSelfReplication(genome, nodeAddress)) {
return nodeAddress;
}
nodeAddress += Const::CellBasicBytes + getNextCellFunctionDataSize(genome, genomeSize, nodeAddress);
}

return -1;
}
62 changes: 57 additions & 5 deletions source/EngineGpuKernels/MutationProcessor.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -738,15 +738,45 @@ __inline__ __device__ void MutationProcessor::duplicateMutation(SimulationData&
}
}
auto sizeDelta = endSourceIndex - startSourceIndex;
auto nodeAddressForSelfReplication = -1;
if (!cudaSimulationParameters.cellFunctionConstructorMutationSelfReplication) {
if (GenomeDecoder::containsSectionSelfReplication(genome + startSourceIndex, sizeDelta)) {
return;
nodeAddressForSelfReplication = GenomeDecoder::getNodeAddressForSelfReplication(genome + startSourceIndex, sizeDelta);
if (nodeAddressForSelfReplication != -1 ) {
nodeAddressForSelfReplication += startSourceIndex;
sizeDelta += 2 + Const::GenomeHeaderSize; //additional size for empty subgenome
}
}

//calculate target addess where the new node should be inserted
int startTargetIndex = 0;
int subGenomesSizeIndices[GenomeDecoder::MAX_SUBGENOME_RECURSION_DEPTH + 1];
int numSubGenomesSizeIndices;
auto startTargetIndex = GenomeDecoder::getRandomGenomeNodeAddress(data, genome, genomeSize, true, subGenomesSizeIndices, &numSubGenomesSizeIndices);
if (data.numberGen1.randomBool() && genomeSize > Const::GenomeHeaderSize) {

//choose a random node position to a constructor with a subgenome
int numConstructorsWithSubgenome = 0;
GenomeDecoder::executeForEachNodeRecursively(genome, genomeSize, true, false, [&](int depth, int nodeAddressIntern, int repetition) {
auto cellFunctionType = GenomeDecoder::getNextCellFunctionType(genome, nodeAddressIntern);
if (cellFunctionType == CellFunction_Constructor && !GenomeDecoder::isNextCellSelfReplication(genome, nodeAddressIntern)) {
++numConstructorsWithSubgenome;
}
});
if (numConstructorsWithSubgenome > 0) {
auto randomIndex = data.numberGen1.random(numConstructorsWithSubgenome - 1);
auto counter = 0;
GenomeDecoder::executeForEachNodeRecursively(genome, genomeSize, true, false, [&](int depth, int nodeAddressIntern, int repetition) {
auto cellFunctionType = GenomeDecoder::getNextCellFunctionType(genome, nodeAddressIntern);
if (cellFunctionType == CellFunction_Constructor && !GenomeDecoder::isNextCellSelfReplication(genome, nodeAddressIntern)) {
if (randomIndex == counter) {
startTargetIndex = nodeAddressIntern + Const::CellBasicBytes + Const::ConstructorFixedBytes + 3 + 1;
}
++counter;
}
});
}
}
startTargetIndex =
GenomeDecoder::getRandomGenomeNodeAddress(data, genome, genomeSize, true, subGenomesSizeIndices, &numSubGenomesSizeIndices, startTargetIndex);

auto targetGenomeSize = genomeSize + sizeDelta;
if (targetGenomeSize > MAX_GENOME_BYTES) {
Expand All @@ -765,12 +795,34 @@ __inline__ __device__ void MutationProcessor::duplicateMutation(SimulationData&
}

auto targetGenome = data.objects.auxiliaryData.getAlignedSubArray(targetGenomeSize);

//copy segment before duplication
for (int i = 0; i < startTargetIndex; ++i) {
targetGenome[i] = genome[i];
}
for (int i = 0; i < sizeDelta; ++i) {
targetGenome[startTargetIndex + i] = genome[startSourceIndex + i];

//copy duplicated part
if (nodeAddressForSelfReplication == -1) {
for (int i = 0; i < sizeDelta; ++i) {
targetGenome[startTargetIndex + i] = genome[startSourceIndex + i];
}
} else {
auto nodeSize = Const::CellBasicBytes + GenomeDecoder::getNextCellFunctionDataSize(genome, genomeSize, nodeAddressForSelfReplication);
for (int i = 0; i < nodeAddressForSelfReplication - startSourceIndex + nodeSize; ++i) {
targetGenome[startTargetIndex + i] = genome[startSourceIndex + i];
}

//make construction non-self-replicating + insert empty subgenome
GenomeDecoder::setNextCellSelfReplication(targetGenome, startTargetIndex + nodeAddressForSelfReplication - startSourceIndex, false);
GenomeDecoder::setNextCellSubgenomeSize(targetGenome, startTargetIndex + nodeAddressForSelfReplication - startSourceIndex, Const::GenomeHeaderSize);

auto const emptySubgenomeSize = 2 + Const::GenomeHeaderSize;
for (int i = nodeAddressForSelfReplication - startSourceIndex + nodeSize; i < sizeDelta; ++i) {
targetGenome[startTargetIndex + i + emptySubgenomeSize] = genome[startSourceIndex + i];
}
}

//copy segment after duplication
for (int i = 0; i < genomeSize - startTargetIndex; ++i) {
targetGenome[startTargetIndex + sizeDelta + i] = genome[startTargetIndex + i];
}
Expand Down

0 comments on commit 72b6eff

Please sign in to comment.