diff --git a/template/py_aff3ct_template.cpp b/template/py_aff3ct_template.cpp index 49689b1..c118f6c 100644 --- a/template/py_aff3ct_template.cpp +++ b/template/py_aff3ct_template.cpp @@ -90,6 +90,7 @@ R"pbdoc( monitor switcher interleaver + source )pbdoc"; std::unique_ptr wrapper_socket (new wrapper::Wrapper_Socket (m1)); wrappers.push_back(wrapper_socket.get()); @@ -136,7 +137,22 @@ R"pbdoc( wrappers.push_back(wrapper_interleaver_float .get()); wrappers.push_back(wrapper_interleaver_double.get()); + py::module_ mod_tunnel = m1.def_submodule("tunnel"); + std::unique_ptr wrapper_tunnel_numpy_int8(new aff3ct::wrapper::Wrapper_Tunnel_numpy(mod_tunnel, "int8")); + std::unique_ptr wrapper_tunnel_numpy_int16(new aff3ct::wrapper::Wrapper_Tunnel_numpy(mod_tunnel, "int16")); + std::unique_ptr wrapper_tunnel_numpy_int32(new aff3ct::wrapper::Wrapper_Tunnel_numpy(mod_tunnel, "int32")); + std::unique_ptr wrapper_tunnel_numpy_int64(new aff3ct::wrapper::Wrapper_Tunnel_numpy(mod_tunnel, "int64")); + std::unique_ptr wrapper_tunnel_numpy_float(new aff3ct::wrapper::Wrapper_Tunnel_numpy(mod_tunnel, "float")); + std::unique_ptr wrapper_tunnel_numpy_double(new aff3ct::wrapper::Wrapper_Tunnel_numpy(mod_tunnel, "double")); + wrappers.push_back(wrapper_tunnel_numpy_int8.get()); + wrappers.push_back(wrapper_tunnel_numpy_int16.get()); + wrappers.push_back(wrapper_tunnel_numpy_int32.get()); + wrappers.push_back(wrapper_tunnel_numpy_int64.get()); + wrappers.push_back(wrapper_tunnel_numpy_float.get()); + wrappers.push_back(wrapper_tunnel_numpy_double.get()); + {other_module_wrappers} + m1.doc() = doc_m1.c_str(); for (size_t i = 0; i < wrappers.size(); i++) wrappers[i]->definitions(); diff --git a/template/py_aff3ct_template.hpp b/template/py_aff3ct_template.hpp index ba38ce6..451a740 100644 --- a/template/py_aff3ct_template.hpp +++ b/template/py_aff3ct_template.hpp @@ -30,6 +30,7 @@ #include "Wrapper_py/Module/Monitor/Monitor_MI/Monitor_MI.hpp" #include "Wrapper_py/Module/Switcher/Switcher.hpp" #include "Wrapper_py/Module/Interleaver/Interleaver.hpp" +#include "Wrapper_py/Module/Tunnel/Tunnel_numpy.hpp" {other_includes} diff --git a/template/src/Module/Tunnel/Tunnel_numpy.cpp b/template/src/Module/Tunnel/Tunnel_numpy.cpp new file mode 100644 index 0000000..f920f83 --- /dev/null +++ b/template/src/Module/Tunnel/Tunnel_numpy.cpp @@ -0,0 +1,193 @@ +/** + * @file Tunnel_numpy.cpp + * @author Sciroccogti (scirocco_gti@yeah.net) + * @brief + * @date 2024-03-13 18:00:38 + * @modified: 2024-03-15 20:14:20 + */ + +#include "Module/Tunnel/Tunnel_numpy.hpp" + +using namespace aff3ct; +using namespace aff3ct::module; + +template +Task& Tunnel_numpy::operator[](const ftr::tsk t) +{ + switch (t) { + case ftr::tsk::append: + return Module::operator[](static_cast(ftr::tsk::append)); + default: + break; + } + + std::stringstream message; + message << "Unknown task"; + throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str()); +} + +template +Socket& Tunnel_numpy::operator[](const ftr::sck::append s) +{ + return Module::operator[]((size_t)ftr::tsk::append)[(size_t)s]; +} + +template +Socket& Tunnel_numpy::operator[](const ftr::sck::get s) +{ + return Module::operator[]((size_t)ftr::tsk::get)[(size_t)s]; +} + +template +Tunnel_numpy::Tunnel_numpy(const int K, const int N, const bool is_out) + : Module() + , K(K) + , N(N) + , is_out(is_out) +{ + const std::string name = "Tunnel_numpy"; + this->set_name(name); + + this->append_done = false; + this->get_done = false; + this->counter = 0; + + if (K <= 0 || N <= 0) { + std::stringstream message; + message << "'K', and 'N' have to be greater than 0 ('K' = " << K + << ", 'N' = " << N << ")."; + throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str()); + } + + auto& p1 = this->create_task("append"); + auto p1s_U = this->template create_socket_in(p1, "U_K", this->K); + // auto p1s_data = this->template create_socket_out(p1, "data", this->K * this->N); + this->create_codelet(p1, [p1s_U](Module& m, Task& t, const size_t frame_id) -> int { + auto& ftr = static_cast&>(m); + + ftr._append(static_cast(t[p1s_U].get_dataptr())); + + return status_t::SUCCESS; + }); + + auto& p2 = this->create_task("get"); + auto p2s_U = this->template create_socket_out(p2, "U_K", this->K); + this->create_codelet(p2, [p2s_U](Module& m, Task& t, const size_t frame_id) -> int { + auto& ftr = static_cast&>(m); + + ftr._get(static_cast(t[p2s_U].get_dataptr())); + + return status_t::SUCCESS; + }); +} + +template +Tunnel_numpy* Tunnel_numpy::clone() const +{ + auto m = new Tunnel_numpy(*this); + m->deep_copy(*this); + return m; +} + +template +int Tunnel_numpy::get_K() const +{ + return this->K; +} + +template +int Tunnel_numpy::get_N() const +{ + return this->N; +} + +template +void Tunnel_numpy::append(std::vector& U_K) +{ + if (this->is_out) { + std::stringstream message; + message << "The tunnel is an output tunnel, you can't append data to it."; + throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str()); + } + (*this)[ftr::sck::append::U_K].bind(U_K.data()); + (*this)[ftr::tsk::append].exec(); +} + +template +void Tunnel_numpy::get(std::vector& U_K) +{ + if (!this->is_out) { + std::stringstream message; + message << "The tunnel is an input tunnel, you can't get data from it."; + throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str()); + } + (*this)[ftr::sck::get::U_K].bind(U_K.data()); + (*this)[ftr::tsk::get].exec(); +} + +template +void Tunnel_numpy::set_data(const std::vector>& data) +{ + this->data = data; +} + +template +std::vector> Tunnel_numpy::get_data() const +{ + return this->data; +} + +template +void Tunnel_numpy::set_N(const int N) +{ + this->N = (size_t)N; +} + +template +void Tunnel_numpy::_append(B* U_K) +{ + std::vector U_K_vec(U_K, U_K + this->K); + this->data.push_back(U_K_vec); + if (this->data.size() == this->N) { + this->append_done = true; + } +} + +template +void Tunnel_numpy::_get(B* U_K) +{ + std::copy(this->data[this->counter].begin(), this->data[this->counter].end(), U_K); + this->counter++; + + if (this->counter == this->data.size()) { + this->counter = 0; + this->get_done = true; + } +} + +template +bool Tunnel_numpy::is_done() const +{ + if (this->is_out) { + return this->get_done; + } else { + return this->append_done; + } +} + +template +void Tunnel_numpy::reset() +{ + this->data.clear(); + this->get_done = false; + this->append_done = false; + this->counter = 0; +} + +#include "Tools/types.h" +template class aff3ct::module::Tunnel_numpy; +template class aff3ct::module::Tunnel_numpy; +template class aff3ct::module::Tunnel_numpy; +template class aff3ct::module::Tunnel_numpy; +template class aff3ct::module::Tunnel_numpy; +template class aff3ct::module::Tunnel_numpy; diff --git a/template/src/Module/Tunnel/Tunnel_numpy.hpp b/template/src/Module/Tunnel/Tunnel_numpy.hpp new file mode 100644 index 0000000..64f346e --- /dev/null +++ b/template/src/Module/Tunnel/Tunnel_numpy.hpp @@ -0,0 +1,91 @@ +/** + * @file Tunnel_numpy.hpp + * @author Sciroccogti (scirocco_gti@yeah.net) + * @brief + * @date 2024-03-13 18:00:30 + * @modified: 2024-03-15 20:14:08 + */ + +#ifndef TUNNEL_NUMPY_HPP_ +#define TUNNEL_NUMPY_HPP_ + +#include "Module/Module.hpp" +#include "Module/Socket.hpp" +#include "Module/Task.hpp" +#include "Tools/Interface/Interface_is_done.hpp" +#include "Tools/Interface/Interface_reset.hpp" + +namespace aff3ct { +namespace module { + namespace ftr { + enum class tsk : size_t { + append, + get, + SIZE + }; + namespace sck { + enum class append : size_t { + U_K, + data, + SIZE + }; + enum class get : size_t { + U_K, + data, + SIZE + }; + } + } + + template + class Tunnel_numpy : public Module, + public tools::Interface_is_done, + public tools::Interface_reset { + public: + inline Task& operator[](const ftr::tsk t); + inline Socket& operator[](const ftr::sck::append s); + inline Socket& operator[](const ftr::sck::get s); + + protected: + std::vector> data; + const size_t K; /*!< Number of information bits in one frame */ + size_t N; /*!< Number of frames */ + size_t counter; + bool is_out; + bool append_done; + bool get_done; + + public: + Tunnel_numpy(const int K, const int N, const bool is_out); + + ~Tunnel_numpy() = default; + + Tunnel_numpy* clone() const; + + void append(std::vector& U_K); + + void get(std::vector& U_K); + + void set_data(const std::vector>& data); + + std::vector> get_data() const; + + void set_N(const int N); + + int get_K() const; + + int get_N() const; + + bool is_done() const; + + void reset(); + + private: + void _append(B* U_K); + + void _get(B* U_K); + }; +} +} + +#endif /* TUNNEL_NUMPY_HPP_ */ diff --git a/template/src/Wrapper_py/Module/Tunnel/Tunnel_numpy.cpp b/template/src/Wrapper_py/Module/Tunnel/Tunnel_numpy.cpp new file mode 100644 index 0000000..bada2c6 --- /dev/null +++ b/template/src/Wrapper_py/Module/Tunnel/Tunnel_numpy.cpp @@ -0,0 +1,61 @@ +/** + * @file Tunnel_numpy.cpp + * @author Sciroccogti (scirocco_gti@yeah.net) + * @brief + * @date 2024-03-14 14:58:53 + * @modified: 2024-03-15 20:13:41 + */ + +#include "Wrapper_py/Module/Tunnel/Tunnel_numpy.hpp" + +namespace py = pybind11; +using namespace py::literals; +using namespace aff3ct; +using namespace aff3ct::module; +using namespace aff3ct::tools; +using namespace aff3ct::wrapper; + +template +Wrapper_Tunnel_numpy +::Wrapper_Tunnel_numpy(py::handle scope, const std::string& type) +: Wrapper_py(), + py::class_,aff3ct::module::Module>(scope, std::string("Tunnel_numpy_" + type).c_str()) +{ +} + +template +void Wrapper_Tunnel_numpy +::definitions() +{ + this->def(py::init(),"K"_a, "N"_a, "is_out"_a, R"pbdoc()pbdoc", py::return_value_policy::take_ownership); + this->def("get_K", &aff3ct::module::Tunnel_numpy::get_K, R"pbdoc()pbdoc"); + this->def("get_N", &aff3ct::module::Tunnel_numpy::get_N, R"pbdoc()pbdoc"); + this->def("append", &aff3ct::module::Tunnel_numpy::append, R"pbdoc()pbdoc"); + this->def("get", &aff3ct::module::Tunnel_numpy::get, R"pbdoc()pbdoc"); + this->def("set_data", &aff3ct::module::Tunnel_numpy::set_data, R"pbdoc()pbdoc"); + this->def("get_data", &aff3ct::module::Tunnel_numpy::get_data, R"pbdoc()pbdoc"); + this->def("set_N", &aff3ct::module::Tunnel_numpy::set_N, R"pbdoc()pbdoc"); + this->def("is_done", &aff3ct::module::Tunnel_numpy::is_done, R"pbdoc()pbdoc"); + this->def("reset", &aff3ct::module::Tunnel_numpy::reset, R"pbdoc()pbdoc"); + this->def_property_readonly("tasks", [](Tunnel_numpy& self)-> std::vector> { return self.tasks; },R"pbdoc(List of tasks: +* **append**: Task method method appends a vector to the buffer. +* **get**: Task method method gets a vector from the buffer. + + * U_K: a vector of bits to append. +)pbdoc"); + this->doc() = R"pbdoc(Fetches a message. + +Parameters: + + * B: type of the bits in the Tunnel. +)pbdoc"; +}; + +#include "Tools/types.h" + +template class aff3ct::wrapper::Wrapper_Tunnel_numpy; +template class aff3ct::wrapper::Wrapper_Tunnel_numpy; +template class aff3ct::wrapper::Wrapper_Tunnel_numpy; +template class aff3ct::wrapper::Wrapper_Tunnel_numpy; +template class aff3ct::wrapper::Wrapper_Tunnel_numpy; +template class aff3ct::wrapper::Wrapper_Tunnel_numpy; diff --git a/template/src/Wrapper_py/Module/Tunnel/Tunnel_numpy.hpp b/template/src/Wrapper_py/Module/Tunnel/Tunnel_numpy.hpp new file mode 100644 index 0000000..8366d03 --- /dev/null +++ b/template/src/Wrapper_py/Module/Tunnel/Tunnel_numpy.hpp @@ -0,0 +1,40 @@ +/** + * @file Tunnel_numpy.hpp + * @author Sciroccogti (scirocco_gti@yeah.net) + * @brief + * @date 2024-03-14 14:59:01 + * @modified: 2024-03-15 15:55:05 + */ + +#ifndef WRAPPER_TUNNEL_NUMPY_HPP_ +#define WRAPPER_TUNNEL_NUMPY_HPP_ + +#include +#include +#include + +#include "Module/Tunnel/Tunnel_numpy.hpp" + +#include "Wrapper_py/Wrapper_py.hpp" + +namespace py = pybind11; +using namespace aff3ct; +using namespace aff3ct::module; +using namespace aff3ct::tools; + +namespace aff3ct +{ +namespace wrapper +{ +template +class Wrapper_Tunnel_numpy : public Wrapper_py, + public py::class_, aff3ct::module::Module> +{ + public: + Wrapper_Tunnel_numpy(py::handle scope, const std::string& type); + virtual void definitions(); + virtual ~Wrapper_Tunnel_numpy() = default; +}; +} +} +#endif //WRAPPER_TUNNEL_NUMPY_HPP_