Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
chrxh committed Nov 25, 2023
2 parents 0382e11 + 5feb9a3 commit e35176c
Show file tree
Hide file tree
Showing 18 changed files with 213 additions and 128 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Further information and artwork:
An Nvidia graphics card with compute capability 6.0 or higher is needed. Please check [https://en.wikipedia.org/wiki/CUDA#GPUs_supported](https://en.wikipedia.org/wiki/CUDA#GPUs_supported).

# 💽 Installer
Installer for Windows: [alien-installer.msi](https://alien-project.org/media/files/alien-installer.msi) (Updated: 2023-11-08)
Installer for Windows: [alien-installer.msi](https://alien-project.org/media/files/alien-installer.msi) (Updated: 2023-11-25)

In the case that the program crashes for an unknown reason, please refer to the troubleshooting section in [alien-project.org/downloads.html](https://alien-project.org/downloads.html).

Expand Down
7 changes: 7 additions & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Release notes

## [4.4.2] - 2023-11-25
### Added
- external energy source, which is controllable by two new parameters

### Removed
- parameter `unlimited energy for constructors` removed

## [4.4.1] - 2023-11-15
### Added
- allow deletion of selection via DEL key
Expand Down
2 changes: 1 addition & 1 deletion source/Base/Resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Const
{
std::string const ProgramVersion = "4.4.1";
std::string const ProgramVersion = "4.4.2";
std::string const DiscordLink = "https://discord.gg/7bjyZdXXQ2";

std::string const BasePath = "resources/";
Expand Down
4 changes: 2 additions & 2 deletions source/EngineGpuKernels/CellConnectionProcessor.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ __inline__ __device__ bool CellConnectionProcessor::tryAddConnectionOneWay(
if (angleDiff < 0) {
angleDiff += 360.0;
}
angleDiff = Math::avoidAngleBoundaries(angleDiff, 360.0f, angleAlignment);
angleDiff = Math::alignAngleOnBoundaries(angleDiff, 360.0f, angleAlignment);
if (abs(angleDiff) < NEAR_ZERO || abs(angleDiff - 360.0f) < NEAR_ZERO || abs(angleDiff + 360.0f) < NEAR_ZERO) {
return false;
}
Expand Down Expand Up @@ -358,7 +358,7 @@ __inline__ __device__ bool CellConnectionProcessor::tryAddConnectionOneWay(
angleFromPrevious = min(angleFromPrevious, refAngle);

angleFromPrevious = Math::alignAngle(angleFromPrevious, angleAlignment);
angleFromPrevious = Math::avoidAngleBoundaries(angleFromPrevious, refAngle, angleAlignment);
angleFromPrevious = Math::alignAngleOnBoundaries(angleFromPrevious, refAngle, angleAlignment);
}
if (angleFromPrevious < NEAR_ZERO) {
return false;
Expand Down
49 changes: 33 additions & 16 deletions source/EngineGpuKernels/ConstructorProcessor.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -718,26 +718,43 @@ ConstructorProcessor::constructCellIntern(

__inline__ __device__ bool ConstructorProcessor::checkAndReduceHostEnergy(SimulationData& data, Cell* hostCell, ConstructionData const& constructionData)
{
if (!cudaSimulationParameters.cellFunctionConstructionUnlimitedEnergy) {
auto cellFunctionConstructorPumpEnergyFactor = cudaSimulationParameters.cellFunctionConstructorPumpEnergyFactor[hostCell->color];
if (hostCell->energy < constructionData.energy + cudaSimulationParameters.cellNormalEnergy[hostCell->color]
&& cudaSimulationParameters.cellFunctionConstructorExternalEnergySupplyRate[hostCell->color] > 0) {
auto externalEnergyPortion = constructionData.energy * cudaSimulationParameters.cellFunctionConstructorExternalEnergySupplyRate[hostCell->color];

auto externalEnergyPtr = &((*data.externalEnergy)[hostCell->color]);
auto origExternalEnergy = alienAtomicRead(externalEnergyPtr);
if (origExternalEnergy == Infinity<float>::value) {
hostCell->energy += externalEnergyPortion;
} else {
externalEnergyPortion = max(0.0f, min(origExternalEnergy, externalEnergyPortion));
auto origExternalEnergy_tickLater = atomicAdd(externalEnergyPtr, -externalEnergyPortion);
if (origExternalEnergy_tickLater >= externalEnergyPortion) {
hostCell->energy += externalEnergyPortion;
} else {
atomicAdd(externalEnergyPtr, externalEnergyPortion);
}
}
}

auto cellFunctionConstructorPumpEnergyFactor = cudaSimulationParameters.cellFunctionConstructorPumpEnergyFactor[hostCell->color];

auto energyNeededFromHost = max(0.0f, constructionData.energy - cudaSimulationParameters.cellNormalEnergy[hostCell->color])
+ min(constructionData.energy, cudaSimulationParameters.cellNormalEnergy[hostCell->color]) * (1.0f - cellFunctionConstructorPumpEnergyFactor);
auto energyNeededFromHost = max(0.0f, constructionData.energy - cudaSimulationParameters.cellNormalEnergy[hostCell->color])
+ min(constructionData.energy, cudaSimulationParameters.cellNormalEnergy[hostCell->color]) * (1.0f - cellFunctionConstructorPumpEnergyFactor);

if (cellFunctionConstructorPumpEnergyFactor < 1.0f && hostCell->energy < cudaSimulationParameters.cellNormalEnergy[hostCell->color] + energyNeededFromHost) {
if (cellFunctionConstructorPumpEnergyFactor < 1.0f && hostCell->energy < cudaSimulationParameters.cellNormalEnergy[hostCell->color] + energyNeededFromHost) {
return false;
}
auto energyNeededFromRadiation = constructionData.energy - energyNeededFromHost;
auto orig = atomicAdd(data.residualEnergy, -energyNeededFromRadiation);
if (orig < energyNeededFromRadiation) {
atomicAdd(data.residualEnergy, energyNeededFromRadiation);
if (hostCell->energy < cudaSimulationParameters.cellNormalEnergy[hostCell->color] + constructionData.energy) {
return false;
}
auto energyNeededFromRadiation = constructionData.energy - energyNeededFromHost;
auto orig = atomicAdd(data.residualEnergy, -energyNeededFromRadiation);
if (orig < energyNeededFromRadiation) {
atomicAdd(data.residualEnergy, energyNeededFromRadiation);
if (hostCell->energy < cudaSimulationParameters.cellNormalEnergy[hostCell->color] + constructionData.energy) {
return false;
}
hostCell->energy -= constructionData.energy;
} else {
hostCell->energy -= energyNeededFromHost;
}
hostCell->energy -= constructionData.energy;
} else {
hostCell->energy -= energyNeededFromHost;
}
return true;
}
Expand Down
25 changes: 13 additions & 12 deletions source/EngineGpuKernels/CudaSimulationFacade.cu
Original file line number Diff line number Diff line change
Expand Up @@ -113,22 +113,23 @@ void _CudaSimulationFacade::calcTimestep()
{
checkAndProcessSimulationParameterChanges();

Settings settings = [this] {
std::lock_guard lock(_mutexForSimulationParameters);
if (_simulationKernels->calcSimulationParametersForNextTimestep(_settings)) {
CHECK_FOR_CUDA_ERROR(
cudaMemcpyToSymbol(cudaSimulationParameters, &_settings.simulationParameters, sizeof(SimulationParameters), 0, cudaMemcpyHostToDevice));
}
return _settings;
}();

_simulationKernels->calcTimestep(settings, getSimulationDataIntern(), *_simulationStatistics);
auto simulationData = getSimulationDataIntern();
_simulationKernels->calcTimestep(_settings, simulationData, *_simulationStatistics);
syncAndCheck();

automaticResizeArrays();

std::lock_guard lock(_mutexForSimulationData);
++_cudaSimulationData->timestep;
{
std::lock_guard lock(_mutexForSimulationData);
++_cudaSimulationData->timestep;
}
{
std::lock_guard lock(_mutexForSimulationParameters);
if (_simulationKernels->updateSimulationParametersAfterTimestep(_settings, simulationData)) {
CHECK_FOR_CUDA_ERROR(
cudaMemcpyToSymbol(cudaSimulationParameters, &_settings.simulationParameters, sizeof(SimulationParameters), 0, cudaMemcpyHostToDevice));
}
}
}

void _CudaSimulationFacade::applyCataclysm(int power)
Expand Down
4 changes: 2 additions & 2 deletions source/EngineGpuKernels/Math.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public:
__inline__ __device__ static float subtractAngle(float angleMinuend, float angleSubtrahend);
__inline__ __device__ static float calcDistanceToLineSegment(float2 const& startSegment, float2 const& endSegment, float2 const& pos, float boundary = 0);
__inline__ __device__ static float alignAngle(float angle, ConstructorAngleAlignment alignment);
__inline__ __device__ static float avoidAngleBoundaries(float angle, float maxAngle, ConstructorAngleAlignment alignment);
__inline__ __device__ static float alignAngleOnBoundaries(float angle, float maxAngle, ConstructorAngleAlignment alignment);
__inline__ __device__ static bool
crossing(float2 const& segmentStart, float2 const& segmentEnd, float2 const& otherSegmentStart, float2 const& otherSegmentEnd);
};
Expand Down Expand Up @@ -310,7 +310,7 @@ __inline__ __device__ float Math::alignAngle(float angle, ConstructorAngleAlignm
return factor * unitAngle;
}

__inline__ __device__ float Math::avoidAngleBoundaries(float angle, float maxAngle, ConstructorAngleAlignment alignment)
__inline__ __device__ float Math::alignAngleOnBoundaries(float angle, float maxAngle, ConstructorAngleAlignment alignment)
{
if (alignment != ConstructorAngleAlignment_None) {
auto angleUnit = 360.0f / (alignment + 1);
Expand Down
2 changes: 1 addition & 1 deletion source/EngineGpuKernels/MutationProcessor.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ __inline__ __device__ void MutationProcessor::insertMutation(SimulationData& dat
int numSubGenomesSizeIndices;

int nodeAddress = 0;
if (data.numberGen1.randomBool() && data.numberGen1.randomBool() && genomeSize > Const::GenomeHeaderSize) {
if (data.numberGen1.randomBool() && genomeSize > Const::GenomeHeaderSize) {

//choose a random node position to a constructor with a subgenome
int numConstructorsWithSubgenome = 0;
Expand Down
6 changes: 6 additions & 0 deletions source/EngineGpuKernels/SimulationData.cu
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "SimulationData.cuh"

#include "ConstantMemory.cuh"
#include "GarbageCollectorKernels.cuh"

void SimulationData::init(int2 const& worldSize_, uint64_t timestep_)
Expand All @@ -13,6 +14,7 @@ void SimulationData::init(int2 const& worldSize_, uint64_t timestep_)
cellMap.init(worldSize);
particleMap.init(worldSize);

CudaMemoryManager::getInstance().acquireMemory<ColorVector<float>>(1, externalEnergy);
CudaMemoryManager::getInstance().acquireMemory<double>(1, residualEnergy);
CHECK_FOR_CUDA_ERROR(cudaMemset(residualEnergy, 0, sizeof(double)));

Expand Down Expand Up @@ -40,6 +42,9 @@ __device__ void SimulationData::prepareForNextTimestep()
for (int i = 0; i < CellFunction_WithoutNone_Count; ++i) {
cellFunctionOperations[i].setMemory(processMemory.getTypedSubArray<CellFunctionOperation>(maxCellFunctionOperations), maxCellFunctionOperations);
}
for (int i = 0; i < MAX_COLORS; ++i) {
(*externalEnergy)[i] = cudaSimulationParameters.cellFunctionConstructorExternalEnergy[i];
}

objects.saveNumEntries();
}
Expand Down Expand Up @@ -97,6 +102,7 @@ void SimulationData::free()
numberGen1.free();
numberGen2.free();
processMemory.free();
CudaMemoryManager::getInstance().freeMemory(externalEnergy);
CudaMemoryManager::getInstance().freeMemory(residualEnergy);

structuralOperations.free();
Expand Down
2 changes: 2 additions & 0 deletions source/EngineGpuKernels/SimulationData.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "EngineInterface/CellFunctionConstants.h"
#include "EngineInterface/GpuSettings.h"
#include "EngineInterface/Colors.h"

#include "Base.cuh"
#include "CudaNumberGenerator.cuh"
Expand All @@ -26,6 +27,7 @@ struct SimulationData
Objects tempObjects;

//additional data for cell functions
ColorVector<float>* externalEnergy;
double* residualEnergy;
RawMemory processMemory;
PreprocessedCellFunctionData preprocessedCellFunctionData;
Expand Down
87 changes: 50 additions & 37 deletions source/EngineGpuKernels/SimulationKernelsLauncher.cu
Original file line number Diff line number Diff line change
Expand Up @@ -13,43 +13,6 @@ _SimulationKernelsLauncher::_SimulationKernelsLauncher()
_garbageCollector = std::make_shared<_GarbageCollectorKernelsLauncher>();
}

bool _SimulationKernelsLauncher::calcSimulationParametersForNextTimestep(Settings& settings)
{
auto changesMade = false;
auto const& worldSizeX = settings.generalSettings.worldSizeX;
auto const& worldSizeY = settings.generalSettings.worldSizeY;
SpaceCalculator space({worldSizeX, worldSizeY});
for (int i = 0; i < settings.simulationParameters.numParticleSources; ++i) {
auto& source = settings.simulationParameters.particleSources[i];
if (source.velX != 0) {
source.posX += source.velX * settings.simulationParameters.timestepSize;
changesMade = true;
}
if (source.velY != 0) {
source.posY += source.velY * settings.simulationParameters.timestepSize;
changesMade = true;
}
auto correctedPosition = space.getCorrectedPosition({source.posX, source.posY});
source.posX = correctedPosition.x;
source.posY = correctedPosition.y;
}
for (int i = 0; i < settings.simulationParameters.numSpots; ++i) {
auto& spot = settings.simulationParameters.spots[i];
if (spot.velX != 0) {
spot.posX += spot.velX * settings.simulationParameters.timestepSize;
changesMade = true;
}
if (spot.velY != 0) {
spot.posY += spot.velY * settings.simulationParameters.timestepSize;
changesMade = true;
}
auto correctedPosition = space.getCorrectedPosition({spot.posX, spot.posY});
spot.posX = correctedPosition.x;
spot.posY = correctedPosition.y;
}
return changesMade;
}

namespace
{
int calcOptimalThreadsForFluidKernel(SimulationParameters const& parameters)
Expand Down Expand Up @@ -127,6 +90,56 @@ void _SimulationKernelsLauncher::calcTimestep(Settings const& settings, Simulati
_garbageCollector->cleanupAfterTimestep(settings.gpuSettings, data);
}

bool _SimulationKernelsLauncher::updateSimulationParametersAfterTimestep(Settings& settings, SimulationData const& simulationData)
{
auto changesMade = false;
auto const& worldSizeX = settings.generalSettings.worldSizeX;
auto const& worldSizeY = settings.generalSettings.worldSizeY;
SpaceCalculator space({worldSizeX, worldSizeY});
for (int i = 0; i < settings.simulationParameters.numParticleSources; ++i) {
auto& source = settings.simulationParameters.particleSources[i];
if (source.velX != 0) {
source.posX += source.velX * settings.simulationParameters.timestepSize;
changesMade = true;
}
if (source.velY != 0) {
source.posY += source.velY * settings.simulationParameters.timestepSize;
changesMade = true;
}
auto correctedPosition = space.getCorrectedPosition({source.posX, source.posY});
source.posX = correctedPosition.x;
source.posY = correctedPosition.y;
}
for (int i = 0; i < settings.simulationParameters.numSpots; ++i) {
auto& spot = settings.simulationParameters.spots[i];
if (spot.velX != 0) {
spot.posX += spot.velX * settings.simulationParameters.timestepSize;
changesMade = true;
}
if (spot.velY != 0) {
spot.posY += spot.velY * settings.simulationParameters.timestepSize;
changesMade = true;
}
auto correctedPosition = space.getCorrectedPosition({spot.posX, spot.posY});
spot.posX = correctedPosition.x;
spot.posY = correctedPosition.y;
}

auto externalEnergyPresent = false;
for (int i = 0; i < MAX_COLORS; ++i) {
externalEnergyPresent |= settings.simulationParameters.cellFunctionConstructorExternalEnergy[i] > 0;
}
if (externalEnergyPresent) {
CHECK_FOR_CUDA_ERROR(cudaMemcpy(
&settings.simulationParameters.cellFunctionConstructorExternalEnergy,
simulationData.externalEnergy,
sizeof(ColorVector<float>),
cudaMemcpyDeviceToHost));
changesMade = true;
}
return changesMade;
}

void _SimulationKernelsLauncher::prepareForSimulationParametersChanges(Settings const& settings, SimulationData const& data)
{
auto const gpuSettings = settings.gpuSettings;
Expand Down
2 changes: 1 addition & 1 deletion source/EngineGpuKernels/SimulationKernelsLauncher.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ class _SimulationKernelsLauncher
public:
_SimulationKernelsLauncher();

bool calcSimulationParametersForNextTimestep(Settings& settings);
void calcTimestep(Settings const& settings, SimulationData const& simulationData, SimulationStatistics const& statistics);
bool updateSimulationParametersAfterTimestep(Settings& settings, SimulationData const& simulationData);
void prepareForSimulationParametersChanges(Settings const& settings, SimulationData const& simulationData);

private:
Expand Down
12 changes: 9 additions & 3 deletions source/EngineInterface/AuxiliaryDataParserService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,9 +390,15 @@ namespace
parserTask);
encodeDecodeProperty(
tree,
parameters.cellFunctionConstructionUnlimitedEnergy,
defaultParameters.cellFunctionConstructionUnlimitedEnergy,
"simulation parameters.cell.function.constructor.unlimited energy",
parameters.cellFunctionConstructorExternalEnergy,
defaultParameters.cellFunctionConstructorExternalEnergy,
"simulation parameters.cell.function.constructor.external energy",
parserTask);
encodeDecodeProperty(
tree,
parameters.cellFunctionConstructorExternalEnergySupplyRate,
defaultParameters.cellFunctionConstructorExternalEnergySupplyRate,
"simulation parameters.cell.function.constructor.external energy supply rate",
parserTask);

encodeDecodeProperty(
Expand Down
10 changes: 8 additions & 2 deletions source/EngineInterface/SimulationParameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ struct SimulationParameters
bool particleTransformationRandomCellFunction = false;
int particleTransformationMaxGenomeSize = 300;

bool cellFunctionConstructionUnlimitedEnergy = false;
ColorVector<float> cellFunctionConstructorOffspringDistance = {2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f};
ColorVector<float> cellFunctionConstructorConnectingCellMaxDistance = {1.8f, 1.8f, 1.8f, 1.8f, 1.8f, 1.8f, 1.8f};
ColorVector<float> cellFunctionConstructorActivityThreshold = {0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f};
Expand All @@ -82,6 +81,8 @@ struct SimulationParameters
{true, true, true, true, true, true, true}};
bool cellFunctionConstructorMutationPreventDepthIncrease = false;
bool cellFunctionConstructorMutationSelfReplication = false;
ColorVector<float> cellFunctionConstructorExternalEnergy = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
ColorVector<float> cellFunctionConstructorExternalEnergySupplyRate = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};

ColorVector<float> cellFunctionInjectorRadius = {3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f};
ColorMatrix<int> cellFunctionInjectorDurationColorMatrix = {
Expand Down Expand Up @@ -271,6 +272,12 @@ struct SimulationParameters
if (cellFunctionDetonatorChainExplosionProbability[i] != other.cellFunctionDetonatorChainExplosionProbability[i]) {
return false;
}
if (cellFunctionConstructorExternalEnergy[i] != other.cellFunctionConstructorExternalEnergy[i]) {
return false;
}
if (cellFunctionConstructorExternalEnergySupplyRate[i] != other.cellFunctionConstructorExternalEnergySupplyRate[i]) {
return false;
}
}
if (numParticleSources != other.numParticleSources) {
return false;
Expand Down Expand Up @@ -322,7 +329,6 @@ struct SimulationParameters
&& particleTransformationMaxGenomeSize == other.particleTransformationMaxGenomeSize
&& clusterDecay == other.clusterDecay
&& cellFunctionSensorActivityThreshold == other.cellFunctionSensorActivityThreshold
&& cellFunctionConstructionUnlimitedEnergy == other.cellFunctionConstructionUnlimitedEnergy
&& cellFunctionMuscleBendingAccelerationThreshold == other.cellFunctionMuscleBendingAccelerationThreshold
&& cellFunctionConstructorMutationSelfReplication == other.cellFunctionConstructorMutationSelfReplication
&& cellMaxAgeBalancer == other.cellMaxAgeBalancer && cellMaxAgeBalancerInterval == other.cellMaxAgeBalancerInterval
Expand Down
4 changes: 2 additions & 2 deletions source/Gui/GenomeEditorWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -902,8 +902,8 @@ void _GenomeEditorWindow::onCreateSpore()
auto genome = GenomeDescriptionService::convertDescriptionToBytes(genomeDesc);

auto parameter = _simController->getSimulationParameters();
auto energy = parameter.cellNormalEnergy[_editorModel->getDefaultColorCode()]
* toFloat(toInt(genomeDesc.cells.size()) * std::min(1000, genomeDesc.header.numRepetitions) * 2 + 1);
auto numNodes = GenomeDescriptionService::getNumNodesRecursively(genome, true);
auto energy = parameter.cellNormalEnergy[_editorModel->getDefaultColorCode()] * toFloat(numNodes * 2 + 1);
auto cell = CellDescription()
.setPos(pos)
.setEnergy(energy)
Expand Down
Loading

0 comments on commit e35176c

Please sign in to comment.