From 94ff6818baa5f6e6d12468b80a85e7c6a93b9e15 Mon Sep 17 00:00:00 2001 From: Andrew Loeliger Date: Fri, 10 Feb 2023 15:05:12 -0600 Subject: [PATCH] Change major symbols to be created on load, and return model smart pointer --- include/hls4ml/emulator.h | 6 ++---- src/hls4ml/emulator.cc | 41 +++++++++++++++++++++++---------------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/include/hls4ml/emulator.h b/include/hls4ml/emulator.h index 4c3bdff..6d7e9cb 100644 --- a/include/hls4ml/emulator.h +++ b/include/hls4ml/emulator.h @@ -5,6 +5,7 @@ #include #include #include +#include namespace hls4mlEmulator { @@ -23,11 +24,9 @@ namespace hls4mlEmulator private: std::string model_name_; void* model_lib_; - Model* model_ = nullptr; public: ModelLoader(std::string model_name); - //prevent copying ModelLoader(ModelLoader const&) = delete; ModelLoader& operator=(ModelLoader const&) = delete; //prevent move constructor/assignment @@ -36,8 +35,7 @@ namespace hls4mlEmulator ~ModelLoader(); - Model* load_model(); - void destroy_model(); + std::shared_ptr load_model(); }; } diff --git a/src/hls4ml/emulator.cc b/src/hls4ml/emulator.cc index a00d533..e199a84 100644 --- a/src/hls4ml/emulator.cc +++ b/src/hls4ml/emulator.cc @@ -12,35 +12,42 @@ ModelLoader::~ModelLoader(){ dlclose(model_lib_); } -Model* ModelLoader::load_model() + +std::shared_ptr ModelLoader::load_model() { + //Open the model .so model_lib_ = dlopen(model_name_.c_str(), RTLD_LAZY | RTLD_LOCAL); if (!model_lib_) { std::cerr << "Cannot load library: " << dlerror() << std::endl; - throw "hls4ml emulator load_model() failure!"; + throw std::runtime_error("hls4ml emulator model library dlopen failure!"); } + //bind the model .so's "create_model" function to "create_model" so we can make a model later create_model_cls* create_model = (create_model_cls*) dlsym(model_lib_, "create_model"); const char* dlsym_error = dlerror(); if (dlsym_error) { - std::cerr << "Cannot load symbol 'create_model': " << dlsym_error << std::endl; - throw "hls4ml emulator create_model() failure!"; + throw std::runtime_error("hls4ml emulator failed to load 'create_model' symbol!"); } - - model_ = create_model(); - - return model_; -} -void ModelLoader::destroy_model() -{ + //bind the model .so's "destroy_model" function to "destroy" so the model can also be destroyed later destroy_model_cls* destroy = (destroy_model_cls*) dlsym(model_lib_, "destroy_model"); - const char* dlsym_error = dlerror(); + dlsym_error = dlerror(); if (dlsym_error) { - std::cerr << "Cannot load symbol destroy_model: " << dlsym_error << std::endl; - throw "hls4ml emulator destroy_model() failure!"; - } - if (model_ != nullptr) { - destroy(model_); + throw std::runtime_error("hls4ml emulator failed to load 'destroy_model' symbol!"); } + + //Create a/the model from our specific implementation in the loaded .so + Model* model = create_model(); + //Hand over a shared pointer to the model + //Also hand over it's destructor, which is, in essence, the "destroy" function/symbol we created earlier + return std::shared_ptr( + model, + [destroy](Model* m) + { + if (m != nullptr) + { + destroy(m); + } + } + ); } \ No newline at end of file