inline factory_t make_factory() { factory_t f; f.add ( hopp::is_integer, [](std::string const & string) -> expression_t { return constant_t(std::stoi(string)); } ); f.add ( [](std::string const & string) -> bool { return std::find_if(string.begin(), string.end(), [](char const c) { return std::isalpha(c) == false; }) == string.end(); }, [](std::string const & string) -> expression_t { return variable_t(string, 0); } ); f.add ( [](std::string const & string) -> bool { return (string == "+" || string == "-" || string == "*" || string == "/" || string == "="); }, [](std::string const & string, std::vector<expression_t> & expressions) -> expression_t { if (expressions.size() < 2) { std::cerr << "ERROR: make_factory: operator_t needs two expressions" << std::endl; exit(1); // or throw } auto r = operator_t ( string[0], expressions[expressions.size() - 2].release(), expressions[expressions.size() - 1].release() ); expressions.resize(expressions.size() - 2); return std::move(r); } ); return f; }
void AssignThreadsAlgorithm::apply(Stream& stream) { const std::vector<Operator*> & operators = stream.initializedOperators(); if (operators.size() == 0) return; // create the graph Graph graph; std::map<const Operator*, Graph::vertex_descriptor> op2VertexMap; // fill the maps for(std::vector<Operator*>::const_iterator op = operators.begin(); op != operators.end(); ++op) { Graph::vertex_descriptor v = boost::add_vertex(graph); boost::put(operator_t(), graph, v, *op); op2VertexMap[*op] = v; } // iterate over each operator for(std::vector<Operator*>::const_iterator op = operators.begin(); op != operators.end(); ++op) { const std::vector<const Description*> & inputs = (*op)->info().inputs(); for(std::vector<const Description*>::const_iterator input = inputs.begin(); input != inputs.end(); ++input) { Output connector = stream.connectionSource(*op, (*input)->id()); if(connector.valid()) { const Operator* source = connector.op(); const Operator* target = *op; const Description& output = source->info().output(connector.id()); Graph::edge_descriptor e = boost::add_edge(op2VertexMap[source], op2VertexMap[target], graph).first; std::map<Graph::vertex_descriptor, int> operatorThreads; operatorThreads[op2VertexMap[source]] = output.operatorThread(); operatorThreads[op2VertexMap[target]] = (*input)->operatorThread(); boost::put(operator_thread_t(), graph, e, operatorThreads); boost::put(thread_t(), graph, e, NO_THREAD); boost::put(connector_id_t(), graph, e, (*input)->id()); } } } int numThreads = 0; Visitor v(numThreads); boost::undirected_dfs<>(graph, root_vertex(Graph::vertex_descriptor(0)).visitor(v) .edge_color_map(get(edge_color, graph))); // delete all threads while(stream.threads().size()) stream.removeThread(stream.threads().front()); // create threads for (int i = 0; i < numThreads; ++i) stream.addThread(); // add the inputs to the threads graph_traits<Graph>::edge_iterator ei, ei_end; for (boost::tie(ei, ei_end) = edges(graph); ei != ei_end; ++ei) { int thread = boost::get(thread_t(), graph, *ei); if (thread == NO_THREAD) continue; unsigned int id = boost::get(connector_id_t(), graph, *ei); Graph::vertex_descriptor v = boost::target(*ei, graph); Operator* op = boost::get(operator_t(), graph, v); stream.threads()[thread]->addInput(op, id); } }