diff options
author | Josh Morman <mormjb@gmail.com> | 2020-04-23 09:58:59 -0400 |
---|---|---|
committer | Josh Morman <mormjb@gmail.com> | 2020-06-04 10:05:47 -0400 |
commit | 0249f7ce0cf5173b946b936c5cd66380afc8bf92 (patch) | |
tree | 587f3da2a664c9589fdc7a1d0533a8b76af0c3ec /gnuradio-runtime/lib | |
parent | 5322a1ff0066bee025b2ea9af550aad4b461d5e0 (diff) |
runtime: replace py gateway with pybind11 support, remove feval
Diffstat (limited to 'gnuradio-runtime/lib')
-rw-r--r-- | gnuradio-runtime/lib/CMakeLists.txt | 5 | ||||
-rw-r--r-- | gnuradio-runtime/lib/block_gateway_impl.cc | 137 | ||||
-rw-r--r-- | gnuradio-runtime/lib/block_gateway_impl.h | 56 | ||||
-rw-r--r-- | gnuradio-runtime/lib/feval.cc | 74 |
4 files changed, 70 insertions, 202 deletions
diff --git a/gnuradio-runtime/lib/CMakeLists.txt b/gnuradio-runtime/lib/CMakeLists.txt index ee89f363ce..65673ad699 100644 --- a/gnuradio-runtime/lib/CMakeLists.txt +++ b/gnuradio-runtime/lib/CMakeLists.txt @@ -47,7 +47,6 @@ add_library(gnuradio-runtime block_gateway_impl.cc block_registry.cc buffer.cc - feval.cc flat_flowgraph.cc flowgraph.cc hier_block2.cc @@ -196,10 +195,14 @@ target_link_libraries(gnuradio-runtime PUBLIC Boost::thread Log4Cpp::log4cpp MPLib::mplib + ${PYTHON_LIBRARIES} ) target_include_directories(gnuradio-runtime PUBLIC + ${PYTHON_INCLUDE_DIR} + ${PYTHON_NUMPY_INCLUDE_DIR} + ${pybind11_INCLUDE_DIR} $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include> $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/../include> diff --git a/gnuradio-runtime/lib/block_gateway_impl.cc b/gnuradio-runtime/lib/block_gateway_impl.cc index 4acb464511..ced8edd1f5 100644 --- a/gnuradio-runtime/lib/block_gateway_impl.cc +++ b/gnuradio-runtime/lib/block_gateway_impl.cc @@ -1,93 +1,45 @@ +/* -*- c++ -*- */ /* - * Copyright 2011-2013 Free Software Foundation, Inc. + * Copyright 2013,2020 Free Software Foundation, Inc. * * This file is part of GNU Radio * * SPDX-License-Identifier: GPL-3.0-or-later * */ - #include "block_gateway_impl.h" +#include <pybind11/embed.h> + #include <gnuradio/io_signature.h> -#include <boost/bind.hpp> #include <iostream> namespace gr { -/*********************************************************************** - * Helper routines - **********************************************************************/ -template <typename OutType, typename InType> -void copy_pointers(OutType& out, const InType& in) -{ - out.resize(in.size()); - for (size_t i = 0; i < in.size(); i++) { - out[i] = (void*)(in[i]); - } -} - - -block_gateway::sptr block_gateway::make(feval_ll* handler, +block_gateway::sptr block_gateway::make(const py::object& p, const std::string& name, gr::io_signature::sptr in_sig, - gr::io_signature::sptr out_sig, - const block_gw_work_type work_type, - const unsigned factor) + gr::io_signature::sptr out_sig) { return block_gateway::sptr( - new block_gateway_impl(handler, name, in_sig, out_sig, work_type, factor)); + new block_gateway_impl(p, name, in_sig, out_sig)); } -block_gateway_impl::block_gateway_impl(feval_ll* handler, +block_gateway_impl::block_gateway_impl(const py::handle& p, const std::string& name, gr::io_signature::sptr in_sig, - gr::io_signature::sptr out_sig, - const block_gw_work_type work_type, - const unsigned factor) - : block(name, in_sig, out_sig), _handler(handler), _work_type(work_type) + gr::io_signature::sptr out_sig) + : block(name, in_sig, out_sig) { - switch (_work_type) { - case GR_BLOCK_GW_WORK_GENERAL: - _decim = 1; // not relevant, but set anyway - _interp = 1; // not relevant, but set anyway - break; - - case GR_BLOCK_GW_WORK_SYNC: - _decim = 1; - _interp = 1; - this->set_fixed_rate(true); - break; - - case GR_BLOCK_GW_WORK_DECIM: - _decim = factor; - _interp = 1; - break; - - case GR_BLOCK_GW_WORK_INTERP: - _decim = 1; - _interp = factor; - this->set_output_multiple(_interp); - break; - } + _py_handle = p; } void block_gateway_impl::forecast(int noutput_items, gr_vector_int& ninput_items_required) { - switch (_work_type) { - case GR_BLOCK_GW_WORK_GENERAL: - _message.action = block_gw_message_type::ACTION_FORECAST; - _message.forecast_args_noutput_items = noutput_items; - _message.forecast_args_ninput_items_required = ninput_items_required; - _handler->calleval(0); - ninput_items_required = _message.forecast_args_ninput_items_required; - return; + py::gil_scoped_acquire acquire; + + py::object ret_ninput_items_required = _py_handle.attr("handle_forecast")(noutput_items, ninput_items_required.size()); + ninput_items_required = ret_ninput_items_required.cast<std::vector<int>>(); - default: - unsigned ninputs = ninput_items_required.size(); - for (unsigned i = 0; i < ninputs; i++) - ninput_items_required[i] = fixed_rate_noutput_to_ninput(noutput_items); - return; - } } int block_gateway_impl::general_work(int noutput_items, @@ -95,63 +47,28 @@ int block_gateway_impl::general_work(int noutput_items, gr_vector_const_void_star& input_items, gr_vector_void_star& output_items) { - switch (_work_type) { - case GR_BLOCK_GW_WORK_GENERAL: - _message.action = block_gw_message_type::ACTION_GENERAL_WORK; - _message.general_work_args_noutput_items = noutput_items; - _message.general_work_args_ninput_items = ninput_items; - copy_pointers(_message.general_work_args_input_items, input_items); - _message.general_work_args_output_items = output_items; - _handler->calleval(0); - return _message.general_work_args_return_value; + py::gil_scoped_acquire acquire; - default: - int r = work(noutput_items, input_items, output_items); - if (r > 0) - consume_each(r * _decim / _interp); - return r; - } + py::object ret = _py_handle.attr("handle_general_work")(noutput_items, ninput_items, input_items, output_items); + + return ret.cast<int>();; } -int block_gateway_impl::work(int noutput_items, - gr_vector_const_void_star& input_items, - gr_vector_void_star& output_items) +bool block_gateway_impl::start(void) { - _message.action = block_gw_message_type::ACTION_WORK; - _message.work_args_ninput_items = fixed_rate_noutput_to_ninput(noutput_items); - if (_message.work_args_ninput_items == 0) - return -1; - _message.work_args_noutput_items = noutput_items; - copy_pointers(_message.work_args_input_items, input_items); - _message.work_args_output_items = output_items; - _handler->calleval(0); - return _message.work_args_return_value; -} + py::gil_scoped_acquire acquire; -int block_gateway_impl::fixed_rate_noutput_to_ninput(int noutput_items) -{ - return (noutput_items * _decim / _interp) + history() - 1; + py::object ret = _py_handle.attr("start")(); + return ret.cast<bool>(); } -int block_gateway_impl::fixed_rate_ninput_to_noutput(int ninput_items) +bool block_gateway_impl::stop(void) { - return std::max(0, ninput_items - (int)history() + 1) * _interp / _decim; -} + py::gil_scoped_acquire acquire; -bool block_gateway_impl::start(void) -{ - _message.action = block_gw_message_type::ACTION_START; - _handler->calleval(0); - return _message.start_args_return_value; -} + py::object ret = _py_handle.attr("stop")(); + return ret.cast<bool>(); -bool block_gateway_impl::stop(void) -{ - _message.action = block_gw_message_type::ACTION_STOP; - _handler->calleval(0); - return _message.stop_args_return_value; } -block_gw_message_type& block_gateway_impl::block_message(void) { return _message; } - } /* namespace gr */ diff --git a/gnuradio-runtime/lib/block_gateway_impl.h b/gnuradio-runtime/lib/block_gateway_impl.h index a87f0ec1e5..168a78650e 100644 --- a/gnuradio-runtime/lib/block_gateway_impl.h +++ b/gnuradio-runtime/lib/block_gateway_impl.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2013 Free Software Foundation, Inc. + * Copyright 2013,2020 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -21,12 +21,10 @@ namespace gr { class block_gateway_impl : public block_gateway { public: - block_gateway_impl(feval_ll* handler, + block_gateway_impl(const py::handle& p, const std::string& name, gr::io_signature::sptr in_sig, - gr::io_signature::sptr out_sig, - const block_gw_work_type work_type, - const unsigned factor); + gr::io_signature::sptr out_sig); /******************************************************************* * Overloads for various scheduler-called functions @@ -38,23 +36,47 @@ public: gr_vector_const_void_star& input_items, gr_vector_void_star& output_items); - int work(int noutput_items, - gr_vector_const_void_star& input_items, - gr_vector_void_star& output_items); - - int fixed_rate_noutput_to_ninput(int noutput_items); - int fixed_rate_ninput_to_noutput(int ninput_items); - bool start(void); bool stop(void); + void set_msg_handler_pybind(pmt::pmt_t which_port, std::string& handler_name) + { + if (msg_queue.find(which_port) == msg_queue.end()) { + throw std::runtime_error( + "attempt to set_msg_handler_pybind() on invalid input message port!"); + } + d_msg_handlers_pybind[which_port] = handler_name; + } + +protected: + // Message handlers back into python using pybind API + typedef std::map<pmt::pmt_t, std::string, pmt::comparator> msg_handlers_pybind_t; + msg_handlers_pybind_t d_msg_handlers_pybind; + + bool has_msg_handler(pmt::pmt_t which_port) + { + if (d_msg_handlers_pybind.find(which_port) != d_msg_handlers_pybind.end()) { + return true; + } else { + return gr::basic_block::has_msg_handler(which_port); + } + } - block_gw_message_type& block_message(void); + void dispatch_msg(pmt::pmt_t which_port, pmt::pmt_t msg) + { + // Is there a handler? + if (d_msg_handlers_pybind.find(which_port) != d_msg_handlers_pybind.end()) { + // d_msg_handlers_pybind[which_port]->calleval(msg); // Yes, invoke it. + py::gil_scoped_acquire acquire; + // std::string handler_name(d_msg_handlers_pybind[which_port]); + py::object ret = _py_handle.attr(d_msg_handlers_pybind[which_port].c_str())(msg); + } else { + // Pass to generic dispatcher if not found + gr::basic_block::dispatch_msg(which_port, msg); + } + } private: - feval_ll* _handler; - block_gw_message_type _message; - const block_gw_work_type _work_type; - unsigned _decim, _interp; + py::handle _py_handle; }; } /* namespace gr */ diff --git a/gnuradio-runtime/lib/feval.cc b/gnuradio-runtime/lib/feval.cc deleted file mode 100644 index 63e3fa419d..0000000000 --- a/gnuradio-runtime/lib/feval.cc +++ /dev/null @@ -1,74 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006,2013 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gnuradio/feval.h> - -namespace gr { - -feval_dd::~feval_dd() {} - -double feval_dd::eval(double x) { return 0; } - -double feval_dd::calleval(double x) { return eval(x); } - -// ---------------------------------------------------------------- - -feval_cc::~feval_cc() {} - -gr_complex feval_cc::eval(gr_complex x) { return 0; } - -gr_complex feval_cc::calleval(gr_complex x) { return eval(x); } - -// ---------------------------------------------------------------- - -feval_ll::~feval_ll() {} - -long feval_ll::eval(long x) { return 0; } - -long feval_ll::calleval(long x) { return eval(x); } - -// ---------------------------------------------------------------- - -feval::~feval() {} - -void feval::eval(void) -{ - // nop -} - -void feval::calleval(void) { eval(); } - -// ---------------------------------------------------------------- - -feval_p::~feval_p() {} - -void feval_p::eval(pmt::pmt_t x) -{ - // nop -} - -void feval_p::calleval(pmt::pmt_t x) { eval(x); } - -/* - * Trivial examples showing C++ (transparently) calling Python - */ -double feval_dd_example(feval_dd* f, double x) { return f->calleval(x); } - -gr_complex feval_cc_example(feval_cc* f, gr_complex x) { return f->calleval(x); } - -long feval_ll_example(feval_ll* f, long x) { return f->calleval(x); } - -void feval_example(feval* f) { f->calleval(); } - -} /* namespace gr */ |