Skip to content

Commit

Permalink
integration test for genome with infinite repetitions added
Browse files Browse the repository at this point in the history
  • Loading branch information
chrxh committed Oct 16, 2023
1 parent 1f944ec commit 8181069
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 18 deletions.
2 changes: 1 addition & 1 deletion source/EngineGpuKernels/CellProcessor.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ __inline__ __device__ void CellProcessor::livingStateTransition(SimulationData&
auto& constructor = connectedCell->cellFunctionData.constructor;
if (!(connectedCell->cellFunction == CellFunction_Constructor
&& GenomeDecoder::containsSelfReplication(constructor)
&& !GenomeDecoder::isSeparating(constructor))) {
&& !GenomeDecoder::isSeparating(constructor.genome))) {
atomicExch(&connectedCell->livingState, LivingState_Dying);
} else {
constructor.genomeCurrentNodeIndex = 0;
Expand Down
40 changes: 23 additions & 17 deletions source/EngineGpuKernels/GenomeDecoder.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ public:
__inline__ __device__
static bool hasEmptyGenome(ConstructorFunction const& constructor);
__inline__ __device__ static bool isFinished(ConstructorFunction const& constructor);
__inline__ __device__ static bool isSeparating(ConstructorFunction const& constructor);
__inline__ __device__ static int getNumRepetitions(ConstructorFunction const& constructor);
__inline__ __device__ static bool isSingleConstruction(ConstructorFunction const& constructor);
template <typename ConstructorOrInjector>
__inline__ __device__ static bool containsSelfReplication(ConstructorOrInjector const& cellFunction);
template <typename CellFunctionSource, typename CellFunctionTarget>
__inline__ __device__ static void copyGenome(SimulationData& data, CellFunctionSource& source, int genomeBytePosition, CellFunctionTarget& target);
__inline__ __device__ static bool isSeparating(uint8_t* genome);
__inline__ __device__ static int getNumRepetitions(uint8_t* genome, bool countInfinityAsOne = false);
__inline__ __device__ static bool isSingleConstruction(uint8_t* genome);

//node-wide methods
__inline__ __device__ static int getNextCellFunctionDataSize(uint8_t* genome, int genomeSize, int nodeAddress, bool withSubgenomes = true);
Expand Down Expand Up @@ -112,7 +112,7 @@ __inline__ __device__ void GenomeDecoder::executeForEachNodeRecursively(uint8_t*
int subGenomeEndAddresses[MAX_SUBGENOME_RECURSION_DEPTH];
int subGenomeNumRepetitions[MAX_SUBGENOME_RECURSION_DEPTH + 1];
int depth = 0;
subGenomeNumRepetitions[0] = genome[Const::GenomeHeaderNumRepetitionsPos];
subGenomeNumRepetitions[0] = getNumRepetitions(genome, true);
for (auto nodeAddress = Const::GenomeHeaderSize; nodeAddress < genomeSize;) {
auto cellFunction = GenomeDecoder::getNextCellFunctionType(genome, nodeAddress);
func(depth, nodeAddress, subGenomeNumRepetitions[depth]);
Expand All @@ -125,7 +125,9 @@ __inline__ __device__ void GenomeDecoder::executeForEachNodeRecursively(uint8_t*
auto subGenomeSize = GenomeDecoder::getNextSubGenomeSize(genome, genomeSize, nodeAddress);
nodeAddress += Const::CellBasicBytes + cellFunctionFixedBytes + 3;
subGenomeEndAddresses[depth++] = nodeAddress + subGenomeSize;
subGenomeNumRepetitions[depth] = subGenomeNumRepetitions[depth - 1] * genome[nodeAddress + Const::GenomeHeaderNumRepetitionsPos];

auto repetitions = getNumRepetitions(genome + nodeAddress, true);
subGenomeNumRepetitions[depth] = subGenomeNumRepetitions[depth - 1] * repetitions;
nodeAddress += Const::GenomeHeaderSize;
goToNextSibling = false;
}
Expand Down Expand Up @@ -292,7 +294,7 @@ __inline__ __device__ bool GenomeDecoder::isLastNode(ConstructorFunction const&

__inline__ __device__ bool GenomeDecoder::isLastRepetition(ConstructorFunction const& constructor)
{
return getNumRepetitions(constructor) - 1 == constructor.genomeCurrentRepetition;
return getNumRepetitions(constructor.genome) - 1 == constructor.genomeCurrentRepetition;
}

__inline__ __device__ bool GenomeDecoder::hasEmptyGenome(ConstructorFunction const& constructor)
Expand All @@ -310,7 +312,7 @@ __inline__ __device__ bool GenomeDecoder::isFinished(ConstructorFunction const&
if (hasEmptyGenome(constructor)) {
return true;
}
if (isSingleConstruction(constructor)) {
if (isSingleConstruction(constructor.genome)) {
return constructor.isConstructionBuilt;
}
return false;
Expand Down Expand Up @@ -339,20 +341,24 @@ __inline__ __device__ void GenomeDecoder::copyGenome(SimulationData& data, CellF
}
}

__inline__ __device__ bool GenomeDecoder::isSeparating(ConstructorFunction const& constructor)
__inline__ __device__ bool GenomeDecoder::isSeparating(uint8_t* genome)
{
return GenomeDecoder::convertByteToBool(constructor.genome[Const::GenomeHeaderSeparationPos]);
return GenomeDecoder::convertByteToBool(genome[Const::GenomeHeaderSeparationPos]);
}

__inline__ __device__ bool GenomeDecoder::isSingleConstruction(ConstructorFunction const& constructor)
__inline__ __device__ bool GenomeDecoder::isSingleConstruction(uint8_t* genome)
{
return GenomeDecoder::convertByteToBool(constructor.genome[Const::GenomeHeaderSingleConstruction]);
return GenomeDecoder::convertByteToBool(genome[Const::GenomeHeaderSingleConstruction]);
}

__inline__ __device__ int GenomeDecoder::getNumRepetitions(ConstructorFunction const& constructor)
__inline__ __device__ int GenomeDecoder::getNumRepetitions(uint8_t* genome, bool countInfinityAsOne)
{
int result = max(1, toInt(constructor.genome[Const::GenomeHeaderNumRepetitionsPos]));
return result == 255 ? NPP_MAX_32S : result;
int result = max(1, toInt(genome[Const::GenomeHeaderNumRepetitionsPos]));
if (!countInfinityAsOne) {
return result == 255 ? NPP_MAX_32S : result;
} else {
return result == 255 ? 1 : result;
}
}

template <typename ConstructorOrInjector>
Expand All @@ -374,12 +380,12 @@ __inline__ __device__ GenomeHeader GenomeDecoder::readGenomeHeader(ConstructorFu

GenomeHeader result;
result.shape = constructor.genome[Const::GenomeHeaderShapePos] % ConstructionShape_Count;
result.singleConstruction = isSingleConstruction(constructor);
result.separateConstruction = isSeparating(constructor);
result.singleConstruction = isSingleConstruction(constructor.genome);
result.separateConstruction = isSeparating(constructor.genome);
result.angleAlignment = constructor.genome[Const::GenomeHeaderAlignmentPos] % ConstructorAngleAlignment_Count;
result.stiffness = toFloat(constructor.genome[Const::GenomeHeaderStiffnessPos]) / 255;
result.connectionDistance = toFloat(constructor.genome[Const::GenomeHeaderConstructionDistancePos]) / 255 + 0.5f;
result.numRepetitions = getNumRepetitions(constructor);
result.numRepetitions = getNumRepetitions(constructor.genome);
result.concatenationAngle1 = convertByteToAngle(constructor.genome[Const::GenomeHeaderConcatenationAngle1Pos]);
result.concatenationAngle2 = convertByteToAngle(constructor.genome[Const::GenomeHeaderConcatenationAngle2Pos]);
return result;
Expand Down
5 changes: 5 additions & 0 deletions source/EngineInterface/GenomeDescriptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,11 @@ struct GenomeHeaderDescription
numRepetitions = value;
return *this;
}
GenomeHeaderDescription& setInfiniteRepetitions()
{
numRepetitions = std::numeric_limits<int>::max();

Check failure on line 428 in source/EngineInterface/GenomeDescriptions.h

View workflow job for this annotation

GitHub Actions / build

incomplete type ‘std::numeric_limits<int>’ used in nested name specifier
return *this;
}
};

struct GenomeDescription
Expand Down
25 changes: 25 additions & 0 deletions source/EngineTests/StatisticsTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,31 @@ TEST_F(StatisticsTests, selfReplicatorWithRepetitionsInGenome)
EXPECT_EQ(10, statistics.timeline.timestep.numGenomeCells[0]);
}

TEST_F(StatisticsTests, selfReplicatorWithInfiniteRepetitionsInGenome)
{
auto subGenome = GenomeDescriptionConverter::convertDescriptionToBytes(
GenomeDescription().setHeader(GenomeHeaderDescription().setInfiniteRepetitions()).setCells({CellGenomeDescription()}));
auto mainGenome = GenomeDescriptionConverter::convertDescriptionToBytes(
GenomeDescription()
.setHeader(GenomeHeaderDescription().setNumRepetitions(2))
.setCells({
CellGenomeDescription().setCellFunction(ConstructorGenomeDescription().setGenome(subGenome)),
CellGenomeDescription().setCellFunction(ConstructorGenomeDescription().setMakeGenomeCopy()),
}));

DataDescription data;
data.addCells({
CellDescription().setId(1).setCellFunction(ConstructorDescription().setGenome(mainGenome)),
});

_simController->setSimulationData(data);
auto statistics = _simController->getStatistics();

EXPECT_EQ(1, statistics.timeline.timestep.numCells[0]);
EXPECT_EQ(1, statistics.timeline.timestep.numSelfReplicators[0]);
EXPECT_EQ(6, statistics.timeline.timestep.numGenomeCells[0]);
}

TEST_F(StatisticsTests, nonSelfReplicatorWithRepetitionsInGenome)
{
auto subGenome = GenomeDescriptionConverter::convertDescriptionToBytes(
Expand Down

0 comments on commit 8181069

Please sign in to comment.