/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /*! * \file stecilReduceOCL.hpp * \ingroup high_level_patterns * * \brief OpenCL map and non-iterative data-parallel patterns * */ /* *************************************************************************** * * FastFlow is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 3 as * published by the Free Software Foundation. * Starting from version 3.0.1 FastFlow is dual licensed under the GNU LGPLv3 * or MIT License (https://github.com/ParaGroup/WindFlow/blob/vers3.x/LICENSE.MIT) * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * **************************************************************************** */ /* * Authors: * Massimo Torquati (August 2015) * * */ #ifndef FF_NODE_SELECTOR_HPP #define FF_NODE_SELECTOR_HPP #include #include #include namespace ff { template class ff_nodeSelector: public ff_node_t { protected: static bool ff_send_out_selector(void * task,int id, unsigned long retry, unsigned long ticks, void *obj) { return reinterpret_cast(obj)->ff_send_out(task, id, retry, ticks); } inline void add2selector(ff_node &node) { ff_nodeSelector::addNode(node); } inline void add2selector(ff_node *node) { cleanup_devices.push_back(node); ff_nodeSelector::addNode(*node); } void add2selectorall(const IN_t &task){ setTask(task); } void add2selectorall(IN_t &task){ setTask(task); } void add2selectorall(){} template void add2selectorall(FIRST &stage,ARGS&...args){ add2selector(stage); add2selectorall(args...); } template void add2selectorall(std::unique_ptr & stage,ARGS&...args){ add2selector(stage.release()); add2selectorall(args...); } public: typedef IN_t in_type; typedef OUT_t out_type; ff_nodeSelector():selected(0) {} //ff_nodeSelector(const IN_t &task):selected(0), inTask(const_cast(&task)) {} template ff_nodeSelector(NODES &&...nodes):selected(0) { this->add2selectorall(nodes...); } // used to set tasks when running in a passive mode void setTask(const IN_t &task) { inTask = const_cast(&task); } void selectNode(size_t id) { selected = id; } int svc_init() { return nodeInit(); } OUT_t* svc(IN_t *in) { if (in == nullptr) { devices[selected]->svc(inTask); return ff_node_t::EOS; } OUT_t* out = (OUT_t*)(devices[selected]->svc(in)); return out; } void svc_end() { nodeEnd(); } ff_node *getNode(size_t id) { if (id >= devices.size()) return nullptr; return devices[id]; } int nodeInit() { if (devices.size() == 0) return -1; for(size_t i=0;inodeInit()<0) return -1; devices[i]->set_id(ff_node::get_my_id()); } return 0; } void nodeEnd() { for(size_t i=0;inodeEnd(); } size_t addNode(ff_node &node) { devices.push_back(&node); node.registerCallback(ff_send_out_selector, this); return devices.size()-1; } size_t addNode(std::unique_ptr node) { ff_node *n = node.get(); n->registerCallback(ff_send_out_selector, this); devices.push_back(n); node.release(); cleanup_devices.push_back(n); return devices.size()-1; } size_t numNodes() const { return devices.size(); } int run(bool = false) { return ff_node::run(); } int wait() { return ff_node::wait(); } int run_and_wait_end() { if (nodeInit() < 0) return -1; svc(nullptr); nodeEnd(); return 0; } #if defined(FF_REPARA) bool rpr_get_measure_energy() const { return false; } void rpr_set_measure_energy(bool v) { for(size_t i=0;irpr_set_measure_energy(v); } #endif protected: size_t selected; IN_t *inTask; std::vector devices; std::vector cleanup_devices; }; } // namespace #endif /* FF_NODE_SELECTOR_HPP */