Skip to content

Commit

Permalink
Updates
Browse files Browse the repository at this point in the history
  • Loading branch information
SergioMartin86 committed Aug 4, 2024
1 parent fe95ad8 commit 59b8c93
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 32 deletions.
7 changes: 7 additions & 0 deletions emulators/quickerGPGX/quickerGPGX.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ class QuickerGPGX final : public Emulator
const auto disabledStateProperties = jaffarCommon::json::getArray<std::string>(config, "Disabled State Properties");
for (const auto &property : disabledStateProperties) _disabledStateProperties.push_back(property);

// Getting work ram serialization size
_workRamSerializationSize = jaffarCommon::json::getNumber<size_t>(config, "Work RAM Serialization Size");

// Creating internal emulator instance
_quickerGPGX = std::make_unique<gpgx::EmuInstance>(config);
};
Expand Down Expand Up @@ -133,10 +136,12 @@ class QuickerGPGX final : public Emulator
__INLINE__ void disableStateProperties()
{
for (const auto &property : _disabledStateProperties) disableStateProperty(property);
setWorkRamSerializationSize(_workRamSerializationSize);
}
__INLINE__ void enableStateProperties()
{
for (const auto &property : _disabledStateProperties) enableStateProperty(property);
setWorkRamSerializationSize(0x10000);
}

// This function opens the video output (e.g., window)
Expand Down Expand Up @@ -179,6 +184,8 @@ class QuickerGPGX final : public Emulator

// Collection of state blocks to disable during engine run
std::vector<std::string> _disabledStateProperties;

size_t _workRamSerializationSize;
};

} // namespace emulator
Expand Down
34 changes: 31 additions & 3 deletions source/driver.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <limits>
#include <chrono>
#include <cstdlib>
#include "engine.hpp"
#include "game.hpp"
Expand All @@ -27,8 +28,13 @@ class Driver final
};

// Base constructor
Driver(const nlohmann::json &config)
Driver(const std::string& configFilePath, const nlohmann::json &config) :
_configFilePath(configFilePath)
{
// Getting job identifier from the system timer
auto currentTime = std::chrono::system_clock::now();
_jobId = std::chrono::duration_cast<std::chrono::seconds>(currentTime.time_since_epoch()).count();

// Getting driver configuration
const auto &driverConfig = jaffarCommon::json::getObject(config, "Driver Configuration");

Expand Down Expand Up @@ -180,9 +186,16 @@ class Driver final
_updateIntermediateResultMutex.lock();

// Saving best solution and state
std::string timeSuffix = std::string(".") + std::to_string(_jobId);

// Saving files with standard name
jaffarCommon::file::saveStringToFile(_bestSolutionStorage, _saveIntermediateBestSolutionPath);
jaffarCommon::file::saveStringToFile(_bestStateStorage, _saveIntermediateBestStatePath);

// Saving files with a time suffix
jaffarCommon::file::saveStringToFile(_bestSolutionStorage, _saveIntermediateBestSolutionPath + timeSuffix);
jaffarCommon::file::saveStringToFile(_bestStateStorage, _saveIntermediateBestStatePath + timeSuffix);

// Making sure the main thread is not currently writing
_updateIntermediateResultMutex.unlock();
}
Expand All @@ -192,10 +205,17 @@ class Driver final
// Making sure the main thread is not currently writing
_updateIntermediateResultMutex.lock();

// Saving best solution and state
std::string timeSuffix = std::string(".") + std::to_string(_jobId);

// Saving best solution and state
jaffarCommon::file::saveStringToFile(_worstSolutionStorage, _saveIntermediateWorstSolutionPath);
jaffarCommon::file::saveStringToFile(_worstStateStorage, _saveIntermediateWorstStatePath);

// Saving best solution and state
jaffarCommon::file::saveStringToFile(_worstSolutionStorage, _saveIntermediateWorstSolutionPath + timeSuffix);
jaffarCommon::file::saveStringToFile(_worstStateStorage, _saveIntermediateWorstStatePath + timeSuffix);

// Making sure the main thread is not currently writing
_updateIntermediateResultMutex.unlock();
}
Expand Down Expand Up @@ -310,6 +330,8 @@ class Driver final
jaffarCommon::logger::clearTerminal();

// Printing information
jaffarCommon::logger::log("[J+] Job Id: %lu\n", _jobId);
jaffarCommon::logger::log("[J+] Script File: '%s'\n", _configFilePath.c_str());
jaffarCommon::logger::log("[J+] Emulator Name: '%s'\n", _runner->getGame()->getEmulator()->getName().c_str());
jaffarCommon::logger::log("[J+] Game Name: '%s'\n", _runner->getGame()->getName().c_str());
jaffarCommon::logger::log("[J+] Current Step #: %lu (Max: %lu)\n", _currentStep, _maxSteps);
Expand Down Expand Up @@ -343,10 +365,10 @@ class Driver final
}

// Function to obtain driver based on configuration
static std::unique_ptr<Driver> getDriver(const nlohmann::json &config)
static std::unique_ptr<Driver> getDriver(const std::string& configFilePath, const nlohmann::json &config)
{
// Creating new engine
auto d = std::make_unique<Driver>(config);
auto d = std::make_unique<Driver>(configFilePath, config);

// Returning engine
return d;
Expand All @@ -357,12 +379,18 @@ class Driver final

private:

// Remember path to config file for reference
const std::string _configFilePath;

// Pointer to the internal Jaffar engine
std::unique_ptr<Engine> _engine;

// Pointer to runner to use for printing information and saving partial results
std::unique_ptr<Runner> _runner;

// Job identifier -- to have a way for distinguishing intermediate values between different jobs
size_t _jobId;

// Getting maximum number of steps (zero = not established)
size_t _maxSteps;

Expand Down
2 changes: 1 addition & 1 deletion source/game.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ class Game
virtual jaffarCommon::hash::hash_t getStateInputHash() = 0;

// Function to enable a game code to provide additional allowed inputs based on complex decisions
virtual __INLINE__ void getAdditionalAllowedInputs(std::set<InputSet::inputIndex_t> &allowedInputSet) {}
virtual __INLINE__ void getAdditionalAllowedInputs(std::unordered_set<InputSet::inputIndex_t> &allowedInputSet) {}

protected:

Expand Down
2 changes: 1 addition & 1 deletion source/jaffar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ int main(int argc, char *argv[])
}

// Creating driver to run the Jaffar engine
auto d = jaffarPlus::Driver::getDriver(config);
auto d = jaffarPlus::Driver::getDriver(configFile, config);

// Initializing driver
d->initialize();
Expand Down
7 changes: 4 additions & 3 deletions source/runner.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#include <memory>
#include <set>
#include <unordered_set>
#include <vector>
#include <cstdint>
#include <jaffarCommon/bitwise.hpp>
Expand Down Expand Up @@ -137,10 +137,10 @@ class Runner final
return inputIdx;
}

std::set<InputSet::inputIndex_t> getInputsFromInputSets(const std::vector<std::unique_ptr<InputSet>> &inputSets) const
std::unordered_set<InputSet::inputIndex_t> getInputsFromInputSets(const std::vector<std::unique_ptr<InputSet>> &inputSets) const
{
// Storage for the possible input set
std::set<InputSet::inputIndex_t> possibleInputs;
std::unordered_set<InputSet::inputIndex_t> possibleInputs;

// For all registered input sets, see which ones satisfy their conditions and add them
for (const auto &inputSet : inputSets)
Expand Down Expand Up @@ -361,6 +361,7 @@ class Runner final
jaffarCommon::logger::log("[J+] + '%s'\n", _inputStringMap.at(inputIdx).c_str());
currentInputIdx++;
}

if (_showEmptyInputSlots)
for (; currentInputIdx < _largestInputSetSize; currentInputIdx++) jaffarCommon::logger::log("[J+] + ----- \n");
}
Expand Down
95 changes: 73 additions & 22 deletions source/stateDb/numa.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class Numa : public stateDb::Base
if (_maxSizePerNumaMb.size() < (size_t)_numaCount)
JAFFAR_THROW_LOGIC("System has %d NUMA domains but only sizes for %lu of them provided.", _numaCount, _maxSizePerNumaMb.size());

// Getting scavenge depth
// Getting scavenge depth for stae databases
_scavengerQueuesSize = jaffarCommon::json::getNumber<size_t>(config, "Scavenger Queues Size");
_scavengingDepth = jaffarCommon::json::getNumber<size_t>(config, "Scavenging Depth");
}
Expand All @@ -50,10 +50,16 @@ class Numa : public stateDb::Base

void initializeImpl() override
{
// Setting counters
// Setting counters for database state popping
_numaNonLocalDatabaseStateCount = 0;
_numaLocalDatabaseStateCount = 0;
_numaDatabaseStateNotFoundCount = 0;

// Setting counters for free state getting
_numaNonLocalFreeStateCount = 0;
_numaLocalFreeStateCount = 0;
_numaFreeStateNotFoundCount = 0;
_numaStealingFreeStateCount = 0;

// Creating scavenger queues
for (int i = 0; i < _numaCount; i++) _scavengerQueues.push_back(std::make_unique<jaffarCommon::concurrent::atomicQueue_t<void *>>(_scavengerQueuesSize));
Expand Down Expand Up @@ -142,12 +148,25 @@ class Numa : public stateDb::Base
(double)_maxSizePerNuma[i] / (1024.0 * 1024.0),
(double)_maxSizePerNuma[i] / (1024.0 * 1024.0 * 1024.0));

size_t totalFreeStatesRequested = _numaNonLocalFreeStateCount + _numaLocalFreeStateCount + _numaFreeStateNotFoundCount;
jaffarCommon::logger::log("[J+] + Numa Locality Success Rate: %5.3f%%\n",

size_t totalDatabaseStatesRequested = _numaNonLocalDatabaseStateCount + _numaLocalDatabaseStateCount + _numaDatabaseStateNotFoundCount;
jaffarCommon::logger::log("[J+] + Database Popping State Rates:\n");
jaffarCommon::logger::log("[J+] + Numa Locality Success Rate: %5.3f%%\n",
100.0 * (double)_numaLocalDatabaseStateCount.load() / (double)totalDatabaseStatesRequested);
jaffarCommon::logger::log("[J+] + Numa Locality Fail Rate: %5.3f%%\n",
100.0 * (double)_numaNonLocalDatabaseStateCount.load() / (double)totalDatabaseStatesRequested);
jaffarCommon::logger::log("[J+] + Numa No DB State Found Rate: %5.3f%%\n",
100.0 * (double)_numaDatabaseStateNotFoundCount.load() / (double)totalDatabaseStatesRequested);

size_t totalFreeStatesRequested = _numaNonLocalFreeStateCount + _numaLocalFreeStateCount + _numaFreeStateNotFoundCount + _numaStealingFreeStateCount;
jaffarCommon::logger::log("[J+] + Get Free State Rates:\n");
jaffarCommon::logger::log("[J+] + Numa Locality Success Rate: %5.3f%%\n",
100.0 * (double)_numaLocalFreeStateCount.load() / (double)totalFreeStatesRequested);
jaffarCommon::logger::log("[J+] + Numa Locality Fail Rate: %5.3f%%\n",
jaffarCommon::logger::log("[J+] + Numa Locality Fail Rate: %5.3f%%\n",
100.0 * (double)_numaNonLocalFreeStateCount.load() / (double)totalFreeStatesRequested);
jaffarCommon::logger::log("[J+] + Numa No Free State Found Rate: %5.3f%%\n",
jaffarCommon::logger::log("[J+] + State DB Stealing Rate: %5.3f%%\n",
100.0 * (double)_numaStealingFreeStateCount.load() / (double)totalFreeStatesRequested);
jaffarCommon::logger::log("[J+] + Numa No Free State Found Rate: %5.3f%%\n",
100.0 * (double)_numaFreeStateNotFoundCount.load() / (double)totalFreeStatesRequested);
}

Expand All @@ -160,7 +179,11 @@ class Numa : public stateDb::Base
bool success = _freeStateQueues[preferredNumaDomain]->try_pop(stateSpace);

// If successful, return the pointer immediately
if (success == true) return stateSpace;
if (success == true)
{
_numaLocalFreeStateCount++;
return stateSpace;
}

// Trying all other free state queues now
for (int i = 0; (size_t)i < _freeStateQueues.size(); i++)
Expand All @@ -170,16 +193,25 @@ class Numa : public stateDb::Base
bool success = _freeStateQueues[i]->try_pop(stateSpace);

// If successful, return the pointer immediately
if (success == true) return stateSpace;
if (success == true)
{
_numaNonLocalFreeStateCount++;
return stateSpace;
}
}

// If failed, then try to get it from the back of the current state database
success = _currentStateDb.pop_back_get(stateSpace);

// If successful, return the pointer immediately
if (success == true) return stateSpace;
if (success == true)
{
_numaStealingFreeStateCount++;
return stateSpace;
}

// Otherwise, return a null pointer. The state will be discarded
_numaFreeStateNotFoundCount++;
return nullptr;
}

Expand Down Expand Up @@ -237,7 +269,7 @@ class Numa : public stateDb::Base
// If its my preferred numa, return it immediately
if (isPreferredNuma == true)
{
_numaLocalFreeStateCount++;
_numaLocalDatabaseStateCount++;
return statePtr;
}

Expand All @@ -251,8 +283,12 @@ class Numa : public stateDb::Base
auto success = _scavengerQueues[numaIdx]->try_push(statePtr);

// If the queue was full, then go ahead and run the state
if (success == false) return statePtr;
}
if (success == false)
{
_numaNonLocalDatabaseStateCount++;
return statePtr;
}
}
}

// If still no success, check the other scavenger queues
Expand All @@ -262,18 +298,13 @@ class Numa : public stateDb::Base
bool success = _scavengerQueues[i]->try_pop(statePtr);
if (success == true)
{
// For statistics, get numa domain of state
const auto numaIdx = getStateNumaDomain(statePtr);

if (numaIdx == preferredNumaDomain) _numaLocalFreeStateCount++;
if (numaIdx != preferredNumaDomain) _numaNonLocalFreeStateCount++;

_numaNonLocalDatabaseStateCount++;
return statePtr;
}
}
}
}

// If no success at all, just return a nullptr
_numaFreeStateNotFoundCount++;
_numaDatabaseStateNotFoundCount++;
return nullptr;
}

Expand All @@ -289,6 +320,21 @@ class Numa : public stateDb::Base
*/
int _numaCount;

/**
* Count of local database states retrieved
*/
std::atomic<size_t> _numaLocalDatabaseStateCount;

/**
* Count of non-local database states retrieved
*/
std::atomic<size_t> _numaNonLocalDatabaseStateCount;

/**
* Count of non-local database states retrieved
*/
std::atomic<size_t> _numaDatabaseStateNotFoundCount;

/**
* Count of local free states retrieved
*/
Expand All @@ -300,7 +346,12 @@ class Numa : public stateDb::Base
std::atomic<size_t> _numaNonLocalFreeStateCount;

/**
* Count of non-local free states retrieved
* Count of free states stolen from the back of the state databse
*/
std::atomic<size_t> _numaStealingFreeStateCount;

/**
* Count of free states failed to be retrieved
*/
std::atomic<size_t> _numaFreeStateNotFoundCount;

Expand Down

0 comments on commit 59b8c93

Please sign in to comment.