Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
chrxh committed Sep 21, 2023
2 parents 58fe14c + 1b039d0 commit f99e00e
Show file tree
Hide file tree
Showing 39 changed files with 376 additions and 152 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ add_compile_options($<$<COMPILE_LANGUAGE:CUDA>:--Werror=all-warnings>)

add_executable(alien)
add_executable(tests)
add_executable(cli)

find_package(CUDAToolkit)
find_package(Boost REQUIRED)
Expand All @@ -57,6 +58,7 @@ find_package(glad CONFIG REQUIRED)
find_package(GTest REQUIRED)
find_package(ZLIB REQUIRED)
find_package(OpenSSL REQUIRED)
find_package(CLI11 CONFIG REQUIRED)

add_subdirectory(external/ImFileDialog)
add_subdirectory(source/Base)
Expand All @@ -65,6 +67,7 @@ add_subdirectory(source/EngineImpl)
add_subdirectory(source/EngineInterface)
add_subdirectory(source/EngineTests)
add_subdirectory(source/Gui)
add_subdirectory(source/Cli)

# Copy resources to the build location
add_custom_command(
Expand Down
8 changes: 8 additions & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Release notes

## [4.2.0] - 2023-09-21
### Added
- command-line interface for running simulation files for a specified number of time steps
- statistics can be exported with CLI

### Fixed
- csv-file in statistics export corrected

## [4.1.1] - 2023-09-16
### Added
- show confirmation dialog for deleting a simulation
Expand Down
4 changes: 3 additions & 1 deletion source/Base/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ add_library(alien_base_lib
StringHelper.cpp
StringHelper.h
Vector2D.cpp
Vector2D.h)
Vector2D.h
VersionChecker.cpp
VersionChecker.h)

target_link_libraries(alien_base_lib Boost::boost)

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.1.1";
std::string const ProgramVersion = "4.2.0";

std::string const BasePath = "resources/";

Expand Down
File renamed without changes.
File renamed without changes.
24 changes: 24 additions & 0 deletions source/Cli/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
target_sources(cli
PUBLIC
Main.cpp)

target_link_libraries(cli alien_base_lib)
target_link_libraries(cli alien_engine_gpu_kernels_lib)
target_link_libraries(cli alien_engine_impl_lib)
target_link_libraries(cli alien_engine_interface_lib)

target_link_libraries(cli CUDA::cudart_static)
target_link_libraries(cli CUDA::cuda_driver)
target_link_libraries(cli Boost::boost)
target_link_libraries(cli OpenGL::GL OpenGL::GLU)
target_link_libraries(cli GLEW::GLEW)
target_link_libraries(cli glfw)
target_link_libraries(cli glad::glad)
target_link_libraries(cli GTest::GTest GTest::Main)
target_link_libraries(cli glad::glad)
target_link_libraries(cli CLI11::CLI11)
target_link_libraries(cli ZLIB::ZLIB)

if (MSVC)
target_compile_options(cli PRIVATE "/MP")
endif()
164 changes: 164 additions & 0 deletions source/Cli/Main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
#include <algorithm>
#include <iostream>

#include "CLI/CLI.hpp"

#include "Base/GlobalSettings.h"
#include "Base/LoggingService.h"
#include "Base/Resources.h"
#include "Base/StringHelper.h"
#include "EngineImpl/SimulationControllerImpl.h"
#include "EngineInterface/Serializer.h"

namespace
{

bool writeStatistics(SimulationController const& simController, std::string const& statisticsFilename)
{
auto statistics = simController->getStatistics();
std::ofstream file;
file.open(statisticsFilename, std::ios_base::out);
if (!file) {
return false;
}

auto writeLabelAllColors = [&file](auto const& name) {
for (int i = 0; i < MAX_COLORS; ++i) {
file << ", " << name << " (color " << i << ")";
}
};
file << "Time step";
writeLabelAllColors("Cells");
writeLabelAllColors("Self-replicators");
writeLabelAllColors("Viruses");
writeLabelAllColors("Cell connections");
writeLabelAllColors("Energy particles");
writeLabelAllColors("Total energy");
writeLabelAllColors("Total genome cells");
writeLabelAllColors("Created cells");
writeLabelAllColors("Attacks");
writeLabelAllColors("Muscle activities");
writeLabelAllColors("Transmitter activities");
writeLabelAllColors("Defender activities");
writeLabelAllColors("Injection activities");
writeLabelAllColors("Completed injections");
writeLabelAllColors("Nerve pulses");
writeLabelAllColors("Neuron activities");
writeLabelAllColors("Sensor activities");
writeLabelAllColors("Sensor matches");
file << std::endl;

auto writeIntValueAllColors = [&file](ColorVector<int> const& values) {
for (int i = 0; i < MAX_COLORS; ++i) {
file << ", " << static_cast<uint64_t>(values[i]);
}
};
auto writeInt64ValueAllColors = [&file](ColorVector<uint64_t> const& values) {
for (int i = 0; i < MAX_COLORS; ++i) {
file << ", " << values[i];
}
};
auto writeFloatValueAllColors = [&file](ColorVector<float> const& values) {
for (int i = 0; i < MAX_COLORS; ++i) {
file << ", " << values[i];
}
};
file << simController->getCurrentTimestep();
writeIntValueAllColors(statistics.timeline.timestep.numCells);
writeIntValueAllColors(statistics.timeline.timestep.numSelfReplicators);
writeIntValueAllColors(statistics.timeline.timestep.numViruses);
writeIntValueAllColors(statistics.timeline.timestep.numConnections);
writeIntValueAllColors(statistics.timeline.timestep.numParticles);
writeFloatValueAllColors(statistics.timeline.timestep.totalEnergy);
writeInt64ValueAllColors(statistics.timeline.timestep.numGenomeCells);
writeInt64ValueAllColors(statistics.timeline.accumulated.numCreatedCells);
writeInt64ValueAllColors(statistics.timeline.accumulated.numAttacks);
writeInt64ValueAllColors(statistics.timeline.accumulated.numMuscleActivities);
writeInt64ValueAllColors(statistics.timeline.accumulated.numTransmitterActivities);
writeInt64ValueAllColors(statistics.timeline.accumulated.numDefenderActivities);
writeInt64ValueAllColors(statistics.timeline.accumulated.numInjectionActivities);
writeInt64ValueAllColors(statistics.timeline.accumulated.numCompletedInjections);
writeInt64ValueAllColors(statistics.timeline.accumulated.numNervePulses);
writeInt64ValueAllColors(statistics.timeline.accumulated.numNeuronActivities);
writeInt64ValueAllColors(statistics.timeline.accumulated.numSensorActivities);
writeInt64ValueAllColors(statistics.timeline.accumulated.numSensorMatches);
file << std::endl;
file.close();
return true;
}
}

int main(int argc, char** argv)
{
try {
CLI::App app{"Command-line interface for ALIEN v" + Const::ProgramVersion};

//parse command line arguments
std::string inputFilename;
std::string outputFilename;
std::string statisticsFilename;
int timesteps = 0;
app.add_option(
"-i", inputFilename, "Specifies the name of the input file for the simulation to run. The corresponding .settings.json should also be available.");
app.add_option("-o", outputFilename, "Specifies the name of the output file for the simulation.");
app.add_option("-t", timesteps, "The number of time steps to be calculated.");
app.add_option("-s", statisticsFilename, "Specifies the name of the csv-file containing the statistics.");
CLI11_PARSE(app, argc, argv);

//read input
std::cout << "Reading input" << std::endl;
if (inputFilename.empty()) {
std::cout << "No input file given." << std::endl;
return 1;
}
DeserializedSimulation simData;
if (!Serializer::deserializeSimulationFromFiles(simData, inputFilename)) {
std::cout << "Could not read from input files." << std::endl;
return 1;
}

//run simulation
auto startTimepoint = std::chrono::steady_clock::now();

auto simController = std::make_shared<_SimulationControllerImpl>();
simController->newSimulation(simData.auxiliaryData.timestep, simData.auxiliaryData.generalSettings, simData.auxiliaryData.simulationParameters);
simController->setClusteredSimulationData(simData.mainData);

std::cout << "Device: " << simController->getGpuName() << std::endl;
std::cout << "Start simulation" << std::endl;
simController->calcTimesteps(timesteps);
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - startTimepoint).count();
auto tps = ms != 0 ? 1000.0f * toFloat(timesteps) / toFloat(ms) : 0.0f;
std::cout << "Simulation finished: " << StringHelper::format(timesteps) << " time steps, " << StringHelper::format(ms) << " ms, "
<< StringHelper::format(tps, 1) << " TPS" << std::endl;


//write output simulation file
std::cout << "Writing output" << std::endl;
simData.auxiliaryData.timestep = static_cast<uint32_t>(simController->getCurrentTimestep());
simData.mainData = simController->getClusteredSimulationData();
if (outputFilename.empty()) {
std::cout << "No output file given." << std::endl;
return 1;
}
if (!Serializer::serializeSimulationToFiles(outputFilename, simData)) {
std::cout << "Could not write to output files." << std::endl;
return 1;
}

//write output statistics file
if (!statisticsFilename.empty()) {
if (!writeStatistics(simController, statisticsFilename)) {
std::cout << "Could not write to statistics file." << std::endl;
return 1;
}
}

std::cout << "Finished" << std::endl;
} catch (std::exception const& e) {
std::cerr << "An uncaught exception occurred: " << e.what() << std::endl;
} catch (...) {
std::cerr << "An unknown exception occurred." << std::endl;
}
return 0;
}
1 change: 1 addition & 0 deletions source/EngineGpuKernels/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ add_library(alien_engine_gpu_kernels_lib
TOs.cuh)

target_link_libraries(alien_engine_gpu_kernels_lib alien_base_lib)
target_link_libraries(alien_engine_gpu_kernels_lib alien_engine_interface_lib)

# See https://gitlab.kitware.com/cmake/cmake/-/issues/17520
set_property(TARGET alien_engine_gpu_kernels_lib PROPERTY CUDA_RESOLVE_DEVICE_SYMBOLS ON)
7 changes: 4 additions & 3 deletions source/EngineGpuKernels/CudaSimulationFacade.cu
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,10 @@ void _CudaSimulationFacade::calcTimestep()

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

Expand Down
24 changes: 19 additions & 5 deletions source/EngineGpuKernels/SimulationKernelsLauncher.cu
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,41 @@ _SimulationKernelsLauncher::_SimulationKernelsLauncher()
_garbageCollector = std::make_shared<_GarbageCollectorKernelsLauncher>();
}

void _SimulationKernelsLauncher::calcSimulationParametersForNextTimestep(Settings& settings)
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];
source.posX += source.velX * settings.simulationParameters.timestepSize;
source.posY += source.velY * settings.simulationParameters.timestepSize;
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];
spot.posX += spot.velX * settings.simulationParameters.timestepSize;
spot.posY += spot.velY * settings.simulationParameters.timestepSize;
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
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,7 +10,7 @@ class _SimulationKernelsLauncher
public:
_SimulationKernelsLauncher();

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

Expand Down
2 changes: 1 addition & 1 deletion source/EngineGpuKernels/SimulationStatistics.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public:
__inline__ __device__ void addEnergy(int color, float valueToAdd) { atomicAdd(&_data->timeline.timestep.totalEnergy[color], valueToAdd); }
__inline__ __device__ void addNumGenomeNodes(int color, uint64_t valueToAdd)
{
alienAtomicAdd64(&_data->timeline.timestep.numGenomeNodes[color], valueToAdd);
alienAtomicAdd64(&_data->timeline.timestep.numGenomeCells[color], valueToAdd);
}
__inline__ __device__ void halveNumConnections()
{
Expand Down
8 changes: 5 additions & 3 deletions source/EngineImpl/EngineWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,11 +315,13 @@ void EngineWorker::changeParticle(ParticleDescription const& changedParticle)
_cudaSimulation->changeInspectedSimulationData(dataTO);
}

void EngineWorker::calcSingleTimestep()
void EngineWorker::calcTimesteps(uint64_t timesteps)
{
EngineWorkerGuard access(this);

_cudaSimulation->calcTimestep();
for (uint64_t i = 0; i < timesteps; ++i) {
_cudaSimulation->calcTimestep();
}
updateStatistics();
}

Expand Down Expand Up @@ -562,7 +564,7 @@ void EngineWorker::syncSimulationWithRenderingIfDesired()
{
if (_syncSimulationWithRendering && _isSimulationRunning) {
for (int i = 0; i < _syncSimulationWithRenderingRatio; ++i) {
calcSingleTimestep();
calcTimesteps(1);
measureTPS();
slowdownTPS();
}
Expand Down
2 changes: 1 addition & 1 deletion source/EngineImpl/EngineWorker.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class EngineWorker
void changeCell(CellDescription const& changedCell);
void changeParticle(ParticleDescription const& changedParticle);

void calcSingleTimestep();
void calcTimesteps(uint64_t timesteps);
void applyCataclysm(int power);

void beginShutdown(); //caller should wait for termination of thread
Expand Down
4 changes: 2 additions & 2 deletions source/EngineImpl/SimulationControllerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,9 @@ void _SimulationControllerImpl::changeParticle(ParticleDescription const& change
_worker.changeParticle(changedParticle);
}

void _SimulationControllerImpl::calcSingleTimestep()
void _SimulationControllerImpl::calcTimesteps(uint64_t timesteps)
{
_worker.calcSingleTimestep();
_worker.calcTimesteps(timesteps);
_selectionNeedsUpdate = true;
}

Expand Down
2 changes: 1 addition & 1 deletion source/EngineImpl/SimulationControllerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class _SimulationControllerImpl : public _SimulationController
void changeCell(CellDescription const& changedCell) override;
void changeParticle(ParticleDescription const& changedParticle) override;

void calcSingleTimestep() override;
void calcTimesteps(uint64_t timesteps) override;
void runSimulation() override;
void pauseSimulation() override;
void applyCataclysm(int power) override;
Expand Down
Loading

0 comments on commit f99e00e

Please sign in to comment.