Skip to content

Commit

Permalink
Merge pull request #265 from northwesternfintech/local-cpp
Browse files Browse the repository at this point in the history
Add cpp support to local dev algos
  • Loading branch information
stevenewald authored Sep 20, 2024
2 parents 4eb0ce7 + 05e4302 commit 10a3815
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 53 deletions.
20 changes: 2 additions & 18 deletions .github/workflows/exchange-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ jobs:
CLANG_DIR: '/usr/lib/llvm-18/lib/cmake/clang'
LLVM_DIR: '/usr/lib/llvm-18/lib/cmake/llvm'
NUTC_WRAPPER_BINARY_PATH: ${{ github.workspace }}/exchange/build/WRAPPER
NUTC_CPP_TEMPLATE_PATH: ${{ github.workspace }}/exchange/template.cpp

steps:
- uses: actions/checkout@v3
Expand Down Expand Up @@ -332,7 +333,7 @@ jobs:
run: |
pip3 install conan numpy
sudo apt install libssl-dev rabbitmq-server -y
sudo apt install libssl-dev -y
bash < ../.github/scripts/conan-profile.sh
conan install . -s build_type=Release -b missing
Expand All @@ -359,23 +360,6 @@ jobs:
- name: Move test algo files
run: cp -r -L test/src/integration/test_algos build/test/test_algos

# TODO: use secrets
- name: Configure RabbitMQ
run: |
sudo rabbitmqctl add_user NUFT ADMIN
sudo rabbitmqctl set_permissions -p / NUFT ".*" ".*" ".*"
sudo rabbitmqctl set_user_tags NUFT administrator
- name: Start RabbitMQ
run: |
sudo systemctl start rabbitmq-server
sudo rabbitmqctl status
- name: Configure RabbitMQ Port
run: |
echo "listeners.tcp.default = 5672" | sudo tee -a /etc/rabbitmq/rabbitmq.conf
sudo systemctl restart rabbitmq-server
- name: Test exchange
working-directory: exchange/build
run: ctest --output-on-failure --no-tests=error --timeout 10 -C Release -R "Integration*"
2 changes: 2 additions & 0 deletions exchange/Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ tasks:

run:
env:
NUTC_CPP_TEMPLATE_PATH: 'template.cpp'
NUTC_WRAPPER_BINARY_PATH: '{{if eq .RELEASE_BUILD "true"}}./build/WRAPPER{{else}}./build/dev/WRAPPER{{end}}'
NUTC_EXPOSE_METRICS: 1
vars:
Expand Down Expand Up @@ -131,6 +132,7 @@ tasks:
RELEASE_TEST_FLAGS: '--output-on-failure --no-tests=error --timeout 10 -C Release'
TEST_FLAGS: '{{if eq .RELEASE_BUILD "true"}}{{.RELEASE_TEST_FLAGS}}{{else}}{{.DEV_TEST_FLAGS}}{{end}}'
env:
NUTC_CPP_TEMPLATE_PATH: 'test_algos/cpp/template.cpp'
NUTC_WRAPPER_BINARY_PATH: '{{.PWD}}/{{.WRAPPER_RELATIVE_PATH}}'
cmds:
- ctest -j 4 {{.TEST_FLAGS}} -R "Integration*"
44 changes: 20 additions & 24 deletions exchange/src/common/types/algorithm/local_algorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,44 @@
#include <cassert>

#include <filesystem>
#include <optional>

namespace nutc::common {
namespace {
std::string
LocalAlgorithm::compile_cpp_() const
get_cpp_template_path()
{
static const char* template_path_env = std::getenv("NUTC_CPP_TEMPLATE_PATH");
if (template_path_env == nullptr)
throw std::runtime_error("Template.cpp path not set, unable to compile cpp");
return template_path_env;
}
} // namespace

std::string
LocalAlgorithm::compile_cpp(const std::filesystem::path& filepath)
{
assert(get_language() == AlgoLanguage::cpp);
static constexpr std::string_view TEMPLATE_PATH = "test_algos/cpp/template.cpp";
std::string binary_output = (boost::filesystem::temp_directory_path()
/ boost::filesystem::unique_path("%%%%-%%%%-%%%%.tmp"))
.string();

std::string command = fmt::format(
"g++ -std=c++20 -fPIC -shared -o {} -include {} {}", binary_output,
filepath_.string(), TEMPLATE_PATH
filepath.string(), get_cpp_template_path()
);

int result = system(command.c_str());

if (result != 0) {
throw std::runtime_error(
fmt::format("Compilation of {} failed", filepath_.string())
fmt::format("Compilation of {} failed", filepath.string())
);
}
return binary_output;
}

LocalAlgorithm::LocalAlgorithm(AlgoLanguage language, std::filesystem::path filepath) :
BaseAlgorithm{language}, filepath_{std::move(filepath)}
{
if (!std::filesystem::exists(filepath_)) [[unlikely]] {
throw std::runtime_error(
fmt::format("Local algorithm file not found: {}", filepath_.string())
);
}
}
{}

const std::filesystem::path&
LocalAlgorithm::get_path() const
Expand All @@ -53,21 +56,14 @@ LocalAlgorithm::get_path() const
std::string
LocalAlgorithm::get_algo_string() const
{
std::optional<std::string> algorithm;
if (get_language() == AlgoLanguage::cpp) {
algorithm = common::read_file_content(compile_cpp_());
}
else {
algorithm = common::read_file_content(filepath_);
return common::read_file_content(compile_cpp(filepath_));
}

if (!algorithm) {
throw std::runtime_error(
fmt::format("Unable to find algorithm at {}", filepath_.string())
);
if (get_language() == AlgoLanguage::python) {
return common::read_file_content(filepath_);
}

return algorithm.value();
throw std::runtime_error("Unknown algo language");
}

std::string
Expand Down
2 changes: 1 addition & 1 deletion exchange/src/common/types/algorithm/local_algorithm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ class LocalAlgorithm : public BaseAlgorithm {
std::string get_id() const;

private:
std::string compile_cpp_() const;
static std::string compile_cpp(const std::filesystem::path& filepath);
};
} // namespace nutc::common
20 changes: 12 additions & 8 deletions exchange/src/exchange/algos/dev_mode/dev_mode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include "exchange/traders/trader_types/algo_trader.hpp"
#include "exchange/wrappers/creation/rmq_wrapper_init.hpp"

#include <iostream>
#include <stdexcept>

namespace nutc::exchange {
Expand All @@ -28,15 +27,15 @@ DevModeAlgoInitializer::initialize_trader_container(
void
DevModeAlgoInitializer::initialize_files()
{
if (!algorithms_.empty())
return;

for (size_t i = 0; i < NUM_ALGOS; i++) {
auto relative_path = fmt::format("{}/algo_{}.py", ALGO_DIR, i);
algorithms_.emplace_back(common::AlgoLanguage::python, relative_path);
auto relative_py_path = fmt::format("{}/algo_{}.py", ALGO_DIR, i);
auto relative_cpp_path = fmt::format("{}/algo_{}.hpp", ALGO_DIR, i);
algorithms_.emplace_back(common::AlgoLanguage::python, relative_py_path);
algorithms_.emplace_back(common::AlgoLanguage::cpp, relative_cpp_path);
}

std::string content = common::read_file_content("template.py");
std::string py_content = common::read_file_content("template.py");
std::string cpp_content = common::read_file_content("template.hpp");

if (!common::create_directory(ALGO_DIR))
throw std::runtime_error("Failed to create directory");
Expand All @@ -50,7 +49,12 @@ DevModeAlgoInitializer::initialize_files()
if (!file)
throw std::runtime_error("Failed to create local algo");

file << content;
if (algo.get_language() == common::AlgoLanguage::python) {
file << py_content;
}
else {
file << cpp_content;
}
file.close();
}
}
Expand Down
2 changes: 1 addition & 1 deletion exchange/src/exchange/algos/dev_mode/dev_mode.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include "common/types/algorithm/algorithm.hpp"
#include "common/types/algorithm/local_algorithm.hpp"
#include "common/types/decimal.hpp"
#include "exchange/algos/algo_manager.hpp"
#include "exchange/traders/trader_container.hpp"
Expand Down
1 change: 0 additions & 1 deletion exchange/src/exchange/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ create_cycle(TraderContainer& traders, const auto& mode)
double order_fee = Config::get().constants().ORDER_FEE;
auto tickers = TickerContainer(ticker_config, traders);

return std::make_unique<BaseMatchingCycle>(tickers, traders, order_fee);
switch (mode) {
case Mode::normal:
return std::make_unique<BaseMatchingCycle>(tickers, traders, order_fee);
Expand Down

0 comments on commit 10a3815

Please sign in to comment.