Skip to content

Commit

Permalink
allow sensors to scan for less complex mutants
Browse files Browse the repository at this point in the history
  • Loading branch information
chrxh committed Jul 5, 2024
1 parent 56da8b4 commit 23c379f
Show file tree
Hide file tree
Showing 10 changed files with 228 additions and 12 deletions.
6 changes: 3 additions & 3 deletions source/EngineGpuKernels/ConstructorProcessor.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ private:
__inline__ __device__ static bool checkAndReduceHostEnergy(SimulationData& data, Cell* hostCell, ConstructionData const& constructionData);

__inline__ __device__ static bool isSelfReplicator(Cell* cell);
__inline__ __device__ static int calcGenomeComplexity(int color, uint8_t* genome, uint16_t genomeSize);
__inline__ __device__ static uint32_t calcGenomeComplexity(int color, uint8_t* genome, uint16_t genomeSize);
};

/************************************************************************/
Expand Down Expand Up @@ -778,7 +778,7 @@ __inline__ __device__ bool ConstructorProcessor::isSelfReplicator(Cell* cell)
return GenomeDecoder::containsSelfReplication(cell->cellFunctionData.constructor);
}

__inline__ __device__ int ConstructorProcessor::calcGenomeComplexity(int color, uint8_t* genome, uint16_t genomeSize)
__inline__ __device__ uint32_t ConstructorProcessor::calcGenomeComplexity(int color, uint8_t* genome, uint16_t genomeSize)
{
int lastDepth = 0;
auto result = 0.0f;
Expand All @@ -794,5 +794,5 @@ __inline__ __device__ int ConstructorProcessor::calcGenomeComplexity(int color,
lastDepth = depth;
++acceleration;
});
return toInt(result);
return static_cast<uint32_t>(result);
}
39 changes: 39 additions & 0 deletions source/EngineGpuKernels/DensityMap.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public:
CudaMemoryManager::getInstance().acquireMemory<uint64_t>(_densityMapSize.x * _densityMapSize.y, _sameMutantDensityMap1);
CudaMemoryManager::getInstance().acquireMemory<uint64_t>(_densityMapSize.x * _densityMapSize.y, _sameMutantDensityMap2);
CudaMemoryManager::getInstance().acquireMemory<uint32_t>(_densityMapSize.x * _densityMapSize.y, _specificMutantDensityMap);
CudaMemoryManager::getInstance().acquireMemory<uint64_t>(_densityMapSize.x * _densityMapSize.y, _lessGenomeComplexityDensityMap1);
CudaMemoryManager::getInstance().acquireMemory<uint64_t>(_densityMapSize.x * _densityMapSize.y, _lessGenomeComplexityDensityMap2);
_slotSize = slotSize;
}

Expand All @@ -26,6 +28,8 @@ public:
CudaMemoryManager::getInstance().freeMemory(_sameMutantDensityMap1);
CudaMemoryManager::getInstance().freeMemory(_sameMutantDensityMap2);
CudaMemoryManager::getInstance().freeMemory(_specificMutantDensityMap);
CudaMemoryManager::getInstance().freeMemory(_lessGenomeComplexityDensityMap1);
CudaMemoryManager::getInstance().freeMemory(_lessGenomeComplexityDensityMap2);
}

__device__ __inline__ void clear()
Expand All @@ -37,6 +41,8 @@ public:
_sameMutantDensityMap1[index] = 0;
_sameMutantDensityMap2[index] = 0;
_specificMutantDensityMap[index] = 0;
_lessGenomeComplexityDensityMap1[index] = 0;
_lessGenomeComplexityDensityMap2[index] = 0;
}
}

Expand Down Expand Up @@ -102,6 +108,20 @@ public:
return 0ul;
}

__device__ __inline__ uint32_t getLowerComplexMutantDensity(float2 const& pos, uint32_t genomeComplexity) const
{
auto index = toInt(pos.x) / _slotSize + toInt(pos.y) / _slotSize * _densityMapSize.x;
if (index >= 0 && index < _densityMapSize.x * _densityMapSize.y) {
auto bucket = min(16, max(0, 31 - __clz(genomeComplexity)));
if (bucket < 8) {
return (_lessGenomeComplexityDensityMap1[index] >> (bucket * 8)) & 0xff;
} else {
return (_lessGenomeComplexityDensityMap2[index] >> ((bucket - 8) * 8)) & 0xff;
}
}
return 0ul;
}

__device__ __inline__ void addCell(uint64_t const& timestep, Cell* cell)
{
auto index = toInt(cell->pos.x) / _slotSize + toInt(cell->pos.y) / _slotSize * _densityMapSize.x;
Expand All @@ -125,6 +145,23 @@ public:
alienAtomicAdd64(&_sameMutantDensityMap1[index], static_cast<uint64_t>((1ull << (bucket1 * 8)) | (1ull << ((bucket2 + 3) * 8))));
alienAtomicAdd64(&_sameMutantDensityMap2[index], static_cast<uint64_t>(1ull << (bucket3 * 8)));
}
{
auto bucket = 32 - __clz(cell->genomeComplexity);
if (bucket < 8) {
auto bitset = static_cast<uint64_t>(1ull << bucket * 8);
for (int i = 0; i < 7; ++i) {
bitset |= (bitset << 8);
}
alienAtomicAdd64(&_lessGenomeComplexityDensityMap1[index], bitset);
alienAtomicAdd64(&_lessGenomeComplexityDensityMap2[index], 0x0101010101010101ull);
} else if (bucket < 16) {
auto bitset = static_cast<uint64_t>(1ull << ((bucket - 8) * 8));
for (int i = 0; i < 7; ++i) {
bitset |= (bitset << 8);
}
alienAtomicAdd64(&_lessGenomeComplexityDensityMap2[index], bitset);
}
}
}
}
}
Expand All @@ -144,5 +181,7 @@ private:
uint64_t* _sameMutantDensityMap2;
uint32_t* _respawnedMutantDensityMap;
uint32_t* _specificMutantDensityMap;
uint64_t* _lessGenomeComplexityDensityMap1;
uint64_t* _lessGenomeComplexityDensityMap2;
};

19 changes: 13 additions & 6 deletions source/EngineGpuKernels/SensorProcessor.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ private:
__inline__ __device__ static void processCell(SimulationData& data, SimulationStatistics& statistics, Cell* cell);
__inline__ __device__ static uint32_t getCellDensity(
uint64_t const& timestep,
uint32_t const& mutationId,
Cell* const& cell,
uint8_t const& restrictToColor,
SensorRestrictToMutants const& restrictToMutants,
DensityMap const& densityMap,
Expand Down Expand Up @@ -73,7 +73,7 @@ __inline__ __device__ void SensorProcessor::processCell(SimulationData& data, Si

__inline__ __device__ uint32_t SensorProcessor::getCellDensity(
uint64_t const& timestep,
uint32_t const& mutationId,
Cell* const& cell,
uint8_t const& restrictToColor,
SensorRestrictToMutants const& restrictToMutants,
DensityMap const& densityMap,
Expand All @@ -89,17 +89,20 @@ __inline__ __device__ uint32_t SensorProcessor::getCellDensity(
}
} else {
if (restrictToMutants == SensorRestrictToMutants_RestrictToSameMutants) {
result = densityMap.getSameMutantDensity(scanPos, mutationId);
result = densityMap.getSameMutantDensity(scanPos, cell->mutationId);
}
if (restrictToMutants == SensorRestrictToMutants_RestrictToOtherMutants) {
result = densityMap.getOtherMutantDensity(timestep, scanPos, mutationId);
result = densityMap.getOtherMutantDensity(timestep, scanPos, cell->mutationId);
}
if (restrictToMutants == SensorRestrictToMutants_RestrictToRespawnedMutants) {
result = densityMap.getRespawnedMutantDensity(scanPos);
}
if (restrictToMutants == SensorRestrictToMutants_RestrictToZeroMutants) {
result = densityMap.getZeroMutantDensity(scanPos);
}
if (restrictToMutants == SensorRestrictToMutants_RestrictToLessComplexMutants) {
result = densityMap.getLowerComplexMutantDensity(scanPos, cell->genomeComplexity);
}
if (restrictToColor != 255) {
result = min(result, densityMap.getColorDensity(scanPos, restrictToColor));
}
Expand Down Expand Up @@ -136,7 +139,7 @@ SensorProcessor::searchNeighborhood(SimulationData& data, SimulationStatistics&
auto scanPos = cell->pos + delta;
data.cellMap.correctPosition(scanPos);

uint32_t density = getCellDensity(data.timestep, cell->mutationId, restrictToColor, restrictToMutants, densityMap, scanPos);
uint32_t density = getCellDensity(data.timestep, cell, restrictToColor, restrictToMutants, densityMap, scanPos);
if (density < minDensity) {
continue;
}
Expand Down Expand Up @@ -206,7 +209,7 @@ SensorProcessor::searchByAngle(SimulationData& data, SimulationStatistics& stati
auto scanPos = cell->pos + searchDelta * distance;
data.cellMap.correctPosition(scanPos);

uint32_t density = getCellDensity(data.timestep, cell->mutationId, restrictToColor, restrictToMutants, densityMap, scanPos);
uint32_t density = getCellDensity(data.timestep, cell, restrictToColor, restrictToMutants, densityMap, scanPos);

if (density < minDensity) {
continue;
Expand Down Expand Up @@ -266,6 +269,10 @@ __inline__ __device__ void SensorProcessor::flagDetectedCells(SimulationData& da
if (restrictToMutants == SensorRestrictToMutants_RestrictToZeroMutants && otherCell->mutationId != 0) {
continue;
}
if (restrictToMutants == SensorRestrictToMutants_RestrictToLessComplexMutants
&& (otherCell->genomeComplexity >= cell->genomeComplexity || otherCell->mutationId == 0 && otherCell->mutationId == 1)) {
continue;
}
//if (restrictToOtherMutants && otherCell->mutationId != 0
// && ((cell->mutationId <= otherCell->mutationId && cell->genomeComplexity <= otherCell->genomeComplexity)
// || static_cast<uint8_t>(cell->mutationId & 0xff) == otherCell->ancestorMutationId)) {
Expand Down
1 change: 1 addition & 0 deletions source/EngineInterface/CellFunctionConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ enum SensorRestrictToMutants_
SensorRestrictToMutants_RestrictToOtherMutants,
SensorRestrictToMutants_RestrictToRespawnedMutants,
SensorRestrictToMutants_RestrictToZeroMutants,
SensorRestrictToMutants_RestrictToLessComplexMutants,
SensorRestrictToMutants_Count
};

Expand Down
3 changes: 2 additions & 1 deletion source/EngineInterface/DescriptionEditService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ DataDescription DescriptionEditService::createRect(CreateRectParameters const& p
.setColor(parameters._color)
.setBarrier(parameters._barrier)
.setCreatureId(creatureId)
.setMutationId(parameters._mutationId));
.setMutationId(parameters._mutationId)
.setGenomeComplexity(parameters._genomeComplexity));
}
}
reconnectCells(result, parameters._cellDistance * 1.1f);
Expand Down
1 change: 1 addition & 0 deletions source/EngineInterface/DescriptionEditService.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class DescriptionEditService
MEMBER_DECLARATION(CreateRectParameters, bool, barrier, false);
MEMBER_DECLARATION(CreateRectParameters, bool, randomCreatureId, true);
MEMBER_DECLARATION(CreateRectParameters, int, mutationId, 0);
MEMBER_DECLARATION(CreateRectParameters, int, genomeComplexity, 0);
};
static DataDescription createRect(CreateRectParameters const& parameters);

Expand Down
5 changes: 5 additions & 0 deletions source/EngineInterface/Descriptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,11 @@ struct CellDescription
mutationId = value;
return *this;
}
CellDescription& setGenomeComplexity(int value)
{
genomeComplexity = value;
return *this;
}

bool hasGenome() const;
std::vector<uint8_t>& getGenomeRef();
Expand Down
162 changes: 162 additions & 0 deletions source/EngineTests/SensorTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -686,3 +686,165 @@ TEST_F(SensorTests, scanNeighborhood_targetedCreature_respawnedMutant_notFound)

EXPECT_TRUE(approxCompare(0.0f, actualSensorCell.activity.channels[0]));
}

TEST_F(SensorTests, scanNeighborhood_targetedCreature_lessComplexMutant_found)
{
_parameters.cellFunctionAttackerSensorDetectionFactor[0] = 1.0f;
_simController->setSimulationParameters(_parameters);

for (int otherGenomeComplexity = 0; otherGenomeComplexity < 500; ++otherGenomeComplexity) {
DataDescription data;
data.addCells(
{CellDescription()
.setId(1)
.setMutationId(5)
.setPos({100.0f, 100.0f})
.setMaxConnections(2)
.setGenomeComplexity(1000)
.setExecutionOrderNumber(0)
.setInputExecutionOrderNumber(5)
.setCellFunction(SensorDescription().setRestrictToMutants(SensorRestrictToMutants_RestrictToLessComplexMutants)),
CellDescription()
.setId(2)
.setPos({101.0f, 100.0f})
.setMaxConnections(1)
.setExecutionOrderNumber(5)
.setCellFunction(NerveDescription())
.setActivity({1, 0, 0, 0, 0, 0, 0, 0})});
data.addConnection(1, 2);

data.add(DescriptionEditService::createRect(DescriptionEditService::CreateRectParameters()
.center({10.0f, 100.0f})
.width(16)
.height(16)
.cellDistance(0.5f)
.mutationId(6)
.genomeComplexity(otherGenomeComplexity)));

_simController->clear();
_simController->setCurrentTimestep(0ull);
_simController->setSimulationData(data);
_simController->calcTimesteps(1);

auto actualData = _simController->getSimulationData();
auto actualSensorCell = getCell(actualData, 1);

EXPECT_TRUE(approxCompare(1.0f, actualSensorCell.activity.channels[0]));
}
}

TEST_F(SensorTests, scanNeighborhood_targetedCreature_lessComplexMutant_notFound_otherMutant)
{
_parameters.cellFunctionAttackerSensorDetectionFactor[0] = 1.0f;
_simController->setSimulationParameters(_parameters);

for (int otherGenomeComplexity = 1000; otherGenomeComplexity < 2001; ++otherGenomeComplexity) {
DataDescription data;
data.addCells(
{CellDescription()
.setId(1)
.setMutationId(5)
.setPos({100.0f, 100.0f})
.setMaxConnections(2)
.setGenomeComplexity(1000)
.setExecutionOrderNumber(0)
.setInputExecutionOrderNumber(5)
.setCellFunction(SensorDescription().setRestrictToMutants(SensorRestrictToMutants_RestrictToLessComplexMutants)),
CellDescription()
.setId(2)
.setPos({101.0f, 100.0f})
.setMaxConnections(1)
.setExecutionOrderNumber(5)
.setCellFunction(NerveDescription())
.setActivity({1, 0, 0, 0, 0, 0, 0, 0})});
data.addConnection(1, 2);

data.add(DescriptionEditService::createRect(DescriptionEditService::CreateRectParameters()
.center({10.0f, 100.0f})
.width(16)
.height(16)
.cellDistance(0.5f)
.mutationId(6)
.genomeComplexity(otherGenomeComplexity)));

_simController->clear();
_simController->setCurrentTimestep(0ull);
_simController->setSimulationData(data);
_simController->calcTimesteps(1);

auto actualData = _simController->getSimulationData();
auto actualSensorCell = getCell(actualData, 1);

EXPECT_TRUE(approxCompare(0.0f, actualSensorCell.activity.channels[0]));
}
}

TEST_F(SensorTests, scanNeighborhood_targetedCreature_lessComplexMutant_notFound_zeroMutant)
{
_parameters.cellFunctionAttackerSensorDetectionFactor[0] = 1.0f;
_simController->setSimulationParameters(_parameters);
DataDescription data;
data.addCells(
{CellDescription()
.setId(1)
.setMutationId(100)
.setPos({100.0f, 100.0f})
.setMaxConnections(2)
.setExecutionOrderNumber(0)
.setInputExecutionOrderNumber(5)
.setCellFunction(SensorDescription().setRestrictToMutants(SensorRestrictToMutants_RestrictToLessComplexMutants)),
CellDescription()
.setId(2)
.setPos({101.0f, 100.0f})
.setMaxConnections(1)
.setExecutionOrderNumber(5)
.setCellFunction(NerveDescription())
.setActivity({1, 0, 0, 0, 0, 0, 0, 0})});
data.addConnection(1, 2);

data.add(DescriptionEditService::createRect(
DescriptionEditService::CreateRectParameters().center({10.0f, 100.0f}).width(16).height(16).cellDistance(0.5f).mutationId(0)));

_simController->setSimulationData(data);
_simController->calcTimesteps(1);

auto actualData = _simController->getSimulationData();
auto actualSensorCell = getCell(actualData, 1);

EXPECT_TRUE(approxCompare(0.0f, actualSensorCell.activity.channels[0]));
}

TEST_F(SensorTests, scanNeighborhood_targetedCreature_lessComplexMutant_notFound_respawnedCell)
{
_parameters.cellFunctionAttackerSensorDetectionFactor[0] = 1.0f;
_simController->setSimulationParameters(_parameters);
DataDescription data;
data.addCells(
{CellDescription()
.setId(1)
.setMutationId(100)
.setPos({100.0f, 100.0f})
.setMaxConnections(2)
.setExecutionOrderNumber(0)
.setInputExecutionOrderNumber(5)
.setCellFunction(SensorDescription().setRestrictToMutants(SensorRestrictToMutants_RestrictToLessComplexMutants)),
CellDescription()
.setId(2)
.setPos({101.0f, 100.0f})
.setMaxConnections(1)
.setExecutionOrderNumber(5)
.setCellFunction(NerveDescription())
.setActivity({1, 0, 0, 0, 0, 0, 0, 0})});
data.addConnection(1, 2);

data.add(DescriptionEditService::createRect(
DescriptionEditService::CreateRectParameters().center({10.0f, 100.0f}).width(16).height(16).cellDistance(0.5f).mutationId(1)));

_simController->setSimulationData(data);
_simController->calcTimesteps(1);

auto actualData = _simController->getSimulationData();
auto actualSensorCell = getCell(actualData, 1);

EXPECT_TRUE(approxCompare(0.0f, actualSensorCell.activity.channels[0]));
}
2 changes: 1 addition & 1 deletion source/Gui/GenomeEditorWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,7 @@ void _GenomeEditorWindow::processNode(
AlienImGui::Combo(
AlienImGui::ComboParameters()
.name("Scan mutants")
.values({"None", "Same mutants", "Other mutants", "Respawned", "Artificial"})
.values({"None", "Same mutants", "Other mutants", "Respawned", "Artificial", "Less complex mutants"})
.textWidth(ContentTextWidth)
.tooltip(Const::GenomeSensorRestrictToOtherMutantsTooltip),
sensor.restrictToMutants);
Expand Down
2 changes: 1 addition & 1 deletion source/Gui/InspectorWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ void _InspectorWindow::processSensorContent(SensorDescription& sensor)
AlienImGui::Combo(
AlienImGui::ComboParameters()
.name("Scan mutants")
.values({"None", "Same mutants", "Other mutants", "Respawned", "Artificial"})
.values({"None", "Same mutants", "Other mutants", "Respawned", "Artificial", "Less complex mutants"})
.textWidth(CellFunctionTextWidth)
.tooltip(Const::GenomeSensorRestrictToOtherMutantsTooltip),
sensor.restrictToMutants);
Expand Down

0 comments on commit 23c379f

Please sign in to comment.