sim_db for C++

Minimal Example using C++

A parameter file called params_mininal_cpp_example.txt is located in the sim_db/examples/ directory in the source code. The file contains the following:

name (string): minimal_cpp_example

{cmake_config} (alias): cmake -Hroot/ -Broot/examples/build
{cmake_build} (alias): {cmake_config}; cmake --build root/examples/build --target

run_command (string): {cmake_build} minimal_cpp_example; root/examples/build/minimal_cpp_example

param1 (string): "Minimal C++ example is running."

param2 (int): 42

A C++ file called minimal_example.cpp and is found in the same directory:

#include "sim_db.hpp"  // Parts from the standard library is also included.

int main(int argc, char** argv) {
    // Open database and write some initial metadata to database.
    sim_db::Connection sim_db(argc, argv);

    // Read parameters from database.
    auto param1 = sim_db.read<std::string>("param1");
    auto param2 = sim_db.read<int>("param2");

    // Demonstrate that the simulation is running.
    std::cout << param1 << std::endl;
}

Add the those simulations parameters to the sim_db database and run the simulation from within the sim_db/examples directory with:

$ sim_db add_and_run -f params_minimal_cpp_example.txt

Notice that when it is run, it first call two cmake commands to compile the code if needed. What cmake does is equvalient to the following command called from sim_db/examples/ (given that the static C library are compiled and located in sim_db/build):

$ c++ -o build/minimal_cpp_example minimal_example.cpp -I../include -L../build -lsimdbcpp -lpthread -ldl -m

The example is not really a minimal one. If you already have compiled your program into a executable called program located in the current directory, the lines starting with {...} (alias): can be removed and the run_command can be replaced with simpy run_command (string): ./program.

Extensive Example using C++

A parameter file called params_extensive_cpp_example.txt is found in the sim_db/examples/ directory in the source code. This parameter file contains all the possible types available in addition to some comments:

This is a comment, as any line without a colon is a comment.
# Adding a hashtag to the start of a comment line, make the comment easier to recognize.

# The name parameter is highly recommended to include.
name (string): extensive_c++_example

# It is also recommended to include a description to further explain the intention of 
# the simulation.
description (string): Extensive C++ example to demonstrate most features in sim_db.

# Aliases for cmake commands for compiling the example. 
{cmake_config} (alias): cmake -Hroot/ -Broot/examples/build
{cmake_build} (alias): {cmake_config}; cmake --build root/examples/build --target

# This 'run_command' starts with an alias that is replaced with the above two cmake 
# commands that compile the extensitve example if needed. The last part of the 
# 'run_command' then run the compiled example. Each command is seperated by a 
# semicolon, but they all need to be on the same line.
run_command (string): {cmake_build} extensive_cpp_example; root/examples/build/extensive_cpp_example

# A parameter is added for each of the avaiable types.
param1_extensive (int): 3
param2_extensive (float): -0.5e10
param3_extensive (string): "Extensive C++ example is running."
param4_extensive (bool): True
param5_extensive (int array): [1, 2, 3]
param6_extensive (float array): [1.5, 2.5, 3.5]
param7_extensive (string array): ["a", "b", "c"]
param8_extensive (bool array): [True, False, True]

# Include parameters from another parameter file.
include_parameter_file: root/examples/extra_params_example.txt

# Change a parameter value from the included parameter file to demonstrate that
# it is the last parameter value that count for a given parameter name. 
extra_param1 (int): 9

The line in the parameter file starting with include_parameter_file: will be substituted with the contain of the specified extra_params_example.txt file, found in the same directory:

# Extra parameters included in the extensive examples.

extra_param1 (int): 7
extra_param2 (string): "Extra params added."
extra_param3 (bool): False

extensive_example.py is also found in the same directory:

#include "sim_db.hpp"  // Parts from the standard library is also included.

int main(int argc, char** argv) {
    // Open database and write some initial metadata to database.
    sim_db::Connection sim_db(argc, argv);

    // Read parameters from database.
    auto param1 = sim_db.read<int>("param1_extensive");
    auto param2 = sim_db.read<double>("param2_extensive");
    auto param3 = sim_db.read<std::string>("param3_extensive");
    auto param4 = sim_db.read<bool>("param4_extensive");
    auto param5 = sim_db.read<std::vector<int> >("param5_extensive");
    auto param6 = sim_db.read<std::vector<double> >("param6_extensive");
    auto param7 = sim_db.read<std::vector<std::string> >("param7_extensive");
    auto param8 = sim_db.read<std::vector<bool> >("param8_extensive");

    // Demonstrate that the simulation is running.
    std::cout << param3 << std::endl;

    // Write all the possible types to database.
    // Only these types are can be written to the database.
    sim_db.write("example_result_1", param1);
    sim_db.write("example_result_2", param2);
    sim_db.write("example_result_3", param3);
    sim_db.write("example_result_4", param4);
    sim_db.write("example_result_5", param5);
    sim_db.write("example_result_6", param6);
    sim_db.write("example_result_7", param7);
    sim_db.write("example_result_8", param8);

    // Make unique subdirectory for storing results and write its name to
    // database. Large results are recommended to be saved in this subdirectory.
    std::string name_results_dir =
            sim_db.unique_results_dir("root/examples/results");

    // Write some results to a file in the newly create subdirectory.
    std::ofstream results_file;
    results_file.open(name_results_dir + "/results.txt");
    for (auto i : param6) {
        results_file << i << std::endl;
    }

    // Check if column exists in database.
    bool is_column_in_database = sim_db.column_exists("column_not_in_database");

    // Check if column is empty and then set it to empty.
    bool is_empty = sim_db.is_empty("example_result_1");
    sim_db.set_empty("example_result_1");

    // Get the 'ID' of the connected simulation an the path to the project's
    // root directory.
    int id = sim_db.get_id();
    std::string path_proj_root = sim_db.get_path_proj_root();

    // Add an empty simulation to the database, open connection and write to it.
    sim_db::Connection sim_db_2 = sim_db::add_empty_sim(path_proj_root, false);
    sim_db_2.write<int>("param1_extensive", 7);

    // Delete simulation from database.
    sim_db_2.delete_from_database();
}

Add the those simulations parameters to the sim_db database and run the simulation from within the sim_db/examples directory with:

$ sdb add_and_run -f params_extensive_cpp_example.txt

Notice that when it is run, it first call cmake to compile the code if needed. What cmake does is equvalient to the following command called from sim_db/examples/ (given that the static C library are compiled and located in sim_db/build/):

$ cc -o build/extensive_cpp_example extensive_example.cpp -I../include -L../build -lsimdbcpp -lpthread -ldl -m

C++ API Referance

class Connection

To interact with the sim_db database.

For an actuall simulation it should be initialised at the very start of the simulation (with ‘store_metadata’ set to True) in a scope that last the entirety of the simulation. This must be done to add the corrrect metadata.

For multithreading/multiprocessing each thread/process MUST have its own connection (instance of this class).

Warning

doxygenfunction: Unable to resolve multiple matches for function “sim_db::Connection::Connection” with arguments (int, char**, bool) in doxygen xml output for project “sim_db” from directory: /home/docs/checkouts/readthedocs.org/user_builds/sim-db/checkouts/latest/docs/xml/. Potential matches:

- sim_db::Connection::Connection(int argc, char **argv, bool store_metadata = true)
- sim_db::Connection::Connection(int id, bool store_metadata = true)
- sim_db::Connection::Connection(std::string path_proj_root, int id, bool store_metadata = true)

Warning

doxygenfunction: Unable to resolve multiple matches for function “sim_db::Connection::Connection” with arguments (std::string, int, bool) in doxygen xml output for project “sim_db” from directory: /home/docs/checkouts/readthedocs.org/user_builds/sim-db/checkouts/latest/docs/xml/. Potential matches:

- sim_db::Connection::Connection(int argc, char **argv, bool store_metadata = true)
- sim_db::Connection::Connection(int id, bool store_metadata = true)
- sim_db::Connection::Connection(std::string path_proj_root, int id, bool store_metadata = true)
template<typename T>
T sim_db::Connection::read(std::string column)

Read parameter from database.

Return

Parameter read from database.

Parameters
  • column: Name of the parameter and column in the database.

Exceptions
  • std::invalid_argument: column not a column in the database.

  • sim_db::TimeoutError: Waited more than 5 seconds to read from the database, because other threads/processes are busy writing to it. Way too much concurrent writing is done and it indicates an design error in the user program.

template<typename T>
void sim_db::Connection::write(std::string column, T value, bool only_if_empty = false)

Write value to database.

Parameters
  • column: Name of the parameter and column in the database.

  • value: To be written to database.

  • only_if_empty: If True, it will only write to the database if the simulation’s entry under ‘column’ is empty. Will avoid potential timeouts for concurrect applications.

Exceptions
  • sim_db::TimeoutError: Waited more than 5 seconds to write to the database because other threads/processes are busy writing to it. Way too much concurrent writing is done and indicates an design error in the user program.

std::string sim_db::Connection::unique_results_dir(std::string path_directory)

Get path to subdirectory in path_directory unique to simulation.

The subdirectory will be named ‘date_time_name_id’ and is intended to store results in. If ‘results_dir’ in the database is empty, a new and unique directory is created and the path stored in ‘results_dir’. Otherwise the path in ‘results_dir’ is just returned.

Return

Path to new subdirectory.

Parameters
  • path_directory: Path to where the new directory is created. If it starts with ‘root/’, that part will be replaced with the full path to the root directory of the project.

bool sim_db::Connection::column_exists(std::string column)

Return true if column is a column in the database.

Exceptions
  • sim_db::TimeoutError: Waited more than 5 seconds to write to the database because other threads/processes are busy writing to it. Way too much concurrent writing is done and indicates an design error

int sim_db::Connection::get_id()

Return ID number of simulation in the database that is connected.

std::string sim_db::Connection::get_path_proj_root()

Return path to root directory of the project, where *.sim_db/* is located.

void sim_db::Connection::update_sha1_executables(std::vector<std::string> paths_executables, bool only_if_empty = false)

Save the sha1 hash of the file paths_executables to the database.

Parameters
  • paths_executables: Paths to executable files.

  • only_if_empty: If True, it will only write to the database if the simulation’s entry under ‘column’ is empty. Will avoid potential timeouts for concurrect applications.

Exceptions
  • sim_db::TimeoutError: Waited more than 5 seconds to write to the database because other threads/processes are busy writing to it. Way too much concurrent writing is done and indicates an design error in the user program.

void sim_db::Connection::delete_from_database()

Delete simulation from database.

Warning

doxygenfunction: Unable to resolve multiple matches for function “sim_db::add_empty_sim” with arguments (bool) in doxygen xml output for project “sim_db” from directory: /home/docs/checkouts/readthedocs.org/user_builds/sim-db/checkouts/latest/docs/xml/. Potential matches:

- Connection sim_db::add_empty_sim(bool store_metadata = false)
- Connection sim_db::add_empty_sim(std::string path_proj_root, bool store_metadata = false)

Warning

doxygenfunction: Unable to resolve multiple matches for function “sim_db::add_empty_sim” with arguments (std::string, bool) in doxygen xml output for project “sim_db” from directory: /home/docs/checkouts/readthedocs.org/user_builds/sim-db/checkouts/latest/docs/xml/. Potential matches:

- Connection sim_db::add_empty_sim(bool store_metadata = false)
- Connection sim_db::add_empty_sim(std::string path_proj_root, bool store_metadata = false)