void update_sizes(graph &g) { // register sizes for (unsigned int i = 0; i != g.num_vertices(); i++) { register_type(g.info(i).t,g); switch (g.info(i).op) { case input: case temporary: { break; } case output: { register_type(g.info(g.inv_adj(i)[0]).t,g); merge_all_types(g.info(i).t, g.info(g.inv_adj(i)[0]).t, g); break; } case trans: { // size at all levels of inv_adj must equal size at all levels of current register_type(g.info(g.inv_adj(i)[0]).t,g); merge_all_types(g.info(i).t, g.info(g.inv_adj(i)[0]).t, g); break; } case squareroot: { register_type(g.info(g.inv_adj(i)[0]).t,g); merge_all_types(g.info(g.inv_adj(i)[0]).t, g.info(i).t, g); break; } case add: case subtract: { // size at all levels of both ops and result must be equal register_type(g.info(g.inv_adj(i)[0]).t,g); register_type(g.info(g.inv_adj(i)[1]).t,g); merge_all_types(g.info(g.inv_adj(i)[0]).t, g.info(g.inv_adj(i)[1]).t,g); merge_all_types(g.info(g.inv_adj(i)[0]).t, g.info(i).t, g); break; } case multiply: { register_type(g.info(g.inv_adj(i)[0]).t,g); register_type(g.info(g.inv_adj(i)[1]).t,g); register_type(g.info(i).t, g); mult_sizes(&g.info(i).t, &g.info(g.inv_adj(i)[0]).t, &g.info(g.inv_adj(i)[1]).t, g); break; } case divide: { register_type(g.info(g.inv_adj(i)[0]).t,g); register_type(g.info(g.inv_adj(i)[1]).t,g); merge_all_types(g.info(g.inv_adj(i)[0]).t,g.info(i).t,g); break; } default: { std::cout << "ERROR: build_graph.cpp: update_sizes(): unexpected type\n"; break; } } } for (unsigned int i = 0; i != g.num_vertices(); i++) { get_latest(g.info(i).t, g); } }
void topo_sort(graph& g, deque<vertex>& order) { vector<bool> visited(g.num_vertices(), false); for (vertex i = 0; i != g.num_vertices(); ++i) if (! visited[i]) topo_sort_r(i, g, order, visited); }
void create_from_graph(const graph<VertexData, EdgeData> &g, const std::vector<vertex_id_type> &partids) { clear(); size_t nv = g.num_vertices(); logger(LOG_WARNING, "storing vertices..."); #pragma omp parallel for for (int i = 0;i < (int)nv; ++i) { vertex_id_type vid = i; size_t hashloc = (vid) % atoms.size(); //place vertices sequentially uint16_t owner = partids[i] % atoms.size(); atoms[hashloc]->set_owner(vid, owner); atoms[owner]->add_vertex(vid, owner, g.vertex_data(i)); atoms[owner]->set_color(vid, g.color(vid)); } logger(LOG_WARNING, "storing edges..."); #pragma omp parallel for for (int i = 0;i < (int)(g.num_edges()); ++i) { vertex_id_type target = g.target(i); vertex_id_type source = g.source(i); uint16_t sourceowner = partids[source] % atoms.size(); uint16_t targetowner = partids[target] % atoms.size(); if (sourceowner != targetowner) atoms[sourceowner]->add_edge(source, sourceowner, target, targetowner); atoms[targetowner]->add_edge(source, sourceowner, target, targetowner, g.edge_data(i)); } numv.value = g.num_vertices(); nume.value = g.num_edges(); finalize(); }
void order_subgraphs_wrapper(vector<subgraph*> &sgorder, subgraph *sg, graph &g) { // simplify the call to the above order subgraphs deque<vertex> order; map<vertex,subgraph*> new_sub; map<vertex,vertex> new_old; if (sg == 0) { vector<vertex> verts; for (unsigned int i = 0; i != g.num_vertices(); ++i) if (g.find_parent(i) == 0 && (g.adj(i).size() > 0 || g.inv_adj(i).size() > 0)) verts.push_back(i); order_subgraphs(order, new_sub, new_old, 0, verts, g.subgraphs, g); } else { order_subgraphs(order, new_sub, new_old, sg, sg->vertices, sg->subs, g); } map<vertex,subgraph*>::iterator itr = new_sub.begin(); for (unsigned int i = 0; i < order.size(); i++) { map<vertex,subgraph*>::iterator iter = new_sub.find(order[i]); if (iter != new_sub.end()) { sgorder.push_back(iter->second); } } }
void program2graph(vector<stmt*> const& p, map<string,type*>& inputs, map<string,type*>& inouts, map<string,type*>& outputs, graph& g) { map<string, type*>::iterator i; for (i = inouts.begin(); i != inouts.end(); ++i) { inputs.insert(*i); outputs.insert(*i); } for (i = inputs.begin(); i != inputs.end(); i++) { set_container_size(i->first, *(i->second)); } for (i = outputs.begin(); i != outputs.end(); i++) { set_container_size(i->first, *(i->second)); } map<string, vertex> env; for (unsigned int i = 0; i != p.size(); ++i) { stmt* s = p[i]; vertex tmp = s->rhs->to_graph(env, inputs, outputs, g); env[s->lhs] = tmp; } ///// DEBUG #ifdef DEBUG std::ofstream out("lower0.dot"); print_graph(out, g); #endif for (map<string,type*>::iterator i = outputs.begin(); i != outputs.end(); ++i) { vertex def = env[i->first]; vertex_info vi; vi.t = *i->second; vi.op = output; vi.label = i->first; vi.eval = evaluate; vi.trivial = true; string name = i->first; set_container_size(name, vi.t); vertex v = g.add_vertex(vi); g.add_edge(def, v); } // push out types up to operation types for (vertex i = 0; i < g.num_vertices(); i++) { if (g.info(i).op == output) { std::vector<vertex> const& iav = g.inv_adj(i); for (vertex j = 0; j < iav.size(); j++) { if (g.info(iav[j]).t.k == unknown) { g.info(iav[j]).t = g.info(i).t; } } } } }
void update_iters(graph &g) { for (unsigned int i = 0; i < g.num_vertices(); ++i) { if (g.info(i).op == deleted) continue; get_latest(g.info(i).t, g); } for (unsigned int i = 0; i < g.subgraphs.size(); ++i) update_iters_sg(g, g.subgraphs[i]); }
void print_graph(std::ostream& out, graph const& g) { out << "digraph G {" << std::endl; for (unsigned int i = 0; i != g.num_vertices(); ++i) { if (g.adj(i).size() > 0 || g.inv_adj(i).size() > 0) { const vertex_info &lsd = g.info(i); string l = lsd.to_string(i); out << i << g.info(i).to_string(i) << std::endl; } for (unsigned int j = 0; j != g.adj(i).size(); ++j) { out << i << " -> " << g.adj(i)[j] << ";" << std::endl; } } for (unsigned int i = 0; i != g.subgraphs.size(); ++i) print_subgraph(out, g.subgraphs[i], g); out << "}" << std::endl; }
bool evalGraphTC(graph &g, int vid, string root, modelMsg &mMsg, versionData *verData) { // create the data structure modelData *newData = new modelData(); verData->add_model(tempCount,newData); unsigned int tds = 0; int tmpCnt = 0; for (;tds < g.num_vertices(); ++tds) { if (g.info(tds).op == temporary || (g.info(tds).op == sumto && g.info(tds).t.k != scalar)) tmpCnt++; } for (int start = mMsg.start; start <= mMsg.stop; start += mMsg.step) newData->add_data(start,(double)tmpCnt); return true; }
int find_or_add_op(op_code op, vector<vertex> const& rands, graph& g) { for (unsigned int i = 0; i != g.num_vertices(); ++i) { if (g.info(i).op == op) { if (rands.size() == g.inv_adj(i).size() && includes(rands.begin(), rands.end(), g.inv_adj(i).begin(), g.inv_adj(i).end())) return i; } } int n; if (op == trans && rands.size() > 0 && g.info(rands[0]).label.compare("") != 0) { vertex_info vi(op, g.info(rands[0]).label); n = g.add_vertex(vi); } else { vertex_info vi(op); n = g.add_vertex(vi); } for (unsigned int i = 0; i != rands.size(); ++i) g.add_edge(rands[i], n); return n; }
void update_dim_info(graph &g) { for (unsigned int i = 0; i != g.num_vertices(); i++) { dim_info &d = g.info(i).t.dim; if (g.info(i).t.height == 0) { d.base_rows = "1"; d.base_cols = "1"; d.step = "1"; d.lead_dim = "1"; } else if (g.info(i).t.height == 1) { // vector dim_info &dd = g.info(i).t.t->dim; d.step = "1"; d.lead_dim = "1"; dd.step = "1"; dd.lead_dim = "1"; if (g.info(i).t.k == row) { d.base_rows = "1"; d.base_cols = d.dim; dd.base_rows = "1"; dd.base_cols = d.dim; } else { d.base_rows = d.dim; d.base_cols = "1"; dd.base_rows = d.dim; dd.base_cols = "1"; } } else if (g.info(i).t.height == 2) { // matrix dim_info &d1 = g.info(i).t.t->dim; dim_info &d0 = g.info(i).t.t->t->dim; d.step = "1";//d1.dim; d1.step = "1"; d0.step = "1"; d0.lead_dim = "1"; d1.lead_dim = d1.dim; d.lead_dim = d1.dim; if (g.info(i).t.k == row) { d.base_rows = d1.dim; d.base_cols = d.dim; d1.base_rows = d1.dim; d1.base_cols = d.dim; d0.base_rows = d1.dim; d0.base_cols = d.dim; } else { d.base_rows = d.dim; d.base_cols = d1.dim; d1.base_rows = d.dim; d1.base_cols = d1.dim; d0.base_rows = d.dim; d0.base_cols = d1.dim; } } else { std::cout << "ERROR: build_graph.cpp: update_dim_info(): unexpected type\n"; } } }
void order_subgraphs(deque<vertex>& order, map<vertex,subgraph*>& new_sub, map<vertex,vertex>& new_old, subgraph* current, vector<vertex> const& vertices, vector<subgraph*> const& subgraphs, graph& g) { // create the graph to sort graph sg; map<vertex,vertex> old_new; //std::cerr << "starting graph creation " << vertices.size() << " " << subgraphs.size() << std::endl; { map<subgraph*,vertex> sub_new; // create the vertices for (unsigned int i = 0; i != vertices.size(); ++i) { vertex old = vertices[i]; vertex n = sg.add_vertex(g.info(old)); old_new[old] = n; new_old[n] = old; } for (unsigned int i = 0; i != subgraphs.size(); ++i) { vertex_info vi; vertex n = sg.add_vertex(vi); new_sub[n] = subgraphs[i]; sub_new[subgraphs[i]] = n; } // get all current level and verts of all children subgraphs // this is only needed when not at the top level. vector<vertex> childVerts; if (current) get_child_verts(current,childVerts); //std::cerr << sg.num_vertices() << " vertices added" << std::endl; // create the edges for (vertex u = 0; u != g.num_vertices(); ++u) { for (unsigned int i = 0; i != g.adj(u).size(); ++i) { vertex v = g.adj(u)[i]; // normal edges in this subgraph if (g.find_parent(u) == current && g.find_parent(v) == current) { if (old_new[u] != old_new[v]) sg.add_edge_no_dup(old_new[u],old_new[v]); } // edges from nested subgraph to this subgraph if (ancestor(current, g.find_parent(u)) && g.find_parent(v) == current) { if (sub_new[get_child_ancestor(current, g.find_parent(u))] != old_new[v]) sg.add_edge_no_dup(sub_new[get_child_ancestor(current, g.find_parent(u))], old_new[v]); } // edges from this subgraph to nested subgraph if (g.find_parent(u) == current && ancestor(current, g.find_parent(v))) { if (old_new[u] != sub_new[get_child_ancestor(current, g.find_parent(v))]) sg.add_edge_no_dup(old_new[u], sub_new[get_child_ancestor(current, g.find_parent(v))]); } // edges from one nested subgrpah to another if (g.find_parent(u) != g.find_parent(v) && ancestor(current, g.find_parent(u)) && ancestor(current, g.find_parent(v))) { if (sub_new[get_child_ancestor(current, g.find_parent(u))] != sub_new[get_child_ancestor(current, g.find_parent(v))]) sg.add_edge_no_dup(sub_new[get_child_ancestor(current, g.find_parent(u))], sub_new[get_child_ancestor(current, g.find_parent(v))]); } // there can be dependencies above this level of subgraph // that come back into this subgraph // so any vertex in a subgraph that is a parent level // is important // 1) from vertex inside this level -> outside if (g.find_parent(u) == current && !(g.find_parent(v) == current || ancestor(current, g.find_parent(v)))) { set<subgraph*> sgs; vector<vertex> verts; vector<vertex> lchild(childVerts); set<subgraph*> empty; while (1) { verts.clear(); int reachable = check_reachable_new_r(v,g,lchild,sgs,empty,true, verts); if (reachable < 0) break; lchild.erase(find(lchild.begin(),lchild.end(), reachable)); //cout << u << "->" << reachable << "\n"; if (find(vertices.begin(),vertices.end(),reachable) != vertices.end()) { // vertex to vertex vertex l = old_new[u]; vertex r = old_new[reachable]; if (l != r) sg.add_edge_no_dup(l,r); } else { // vertex to subgraph vertex l = old_new[u]; vertex r = sub_new[get_child_ancestor( current, g.find_parent(reachable))]; if (l != r) sg.add_edge_no_dup(l,r); } } } // 2) from nested subgraph inside this level -> outside if (ancestor(current, g.find_parent(u)) && !(g.find_parent(v) == current || ancestor(current, g.find_parent(v)))) { set<subgraph*> sgs; vector<vertex> verts; vector<vertex> lchild(childVerts); set<subgraph*> empty; while (1) { verts.clear(); int reachable = check_reachable_new_r(v,g, lchild,sgs,empty,true,verts); if (reachable < 0) break; lchild.erase(find(lchild.begin(),lchild.end(), reachable)); //cout << u << "->" << reachable << "\n"; if (find(vertices.begin(),vertices.end(),reachable) != vertices.end()) { // subgraph to vertex vertex l = sub_new[get_child_ancestor(current, g.find_parent(u))]; vertex r = old_new[reachable]; if (l != r) sg.add_edge_no_dup(l,r); } else { // subgraph to subgraph vertex l = sub_new[get_child_ancestor(current, g.find_parent(u))]; vertex r = sub_new[get_child_ancestor(current, g.find_parent(reachable))]; if (l != r) sg.add_edge_no_dup(l,r); } } } }//for }//for }//create graph //std::cerr << "finished graph creation" << std::endl; #if 0 { std::cout << toponum << "\n"; std::ofstream fout(string("topo" + boost::lexical_cast<string>(toponum++) + ".dot").c_str()); print_graph(fout, sg); } #endif // topologically sort the graph topo_sort(sg, order); //std::cerr << "finished topo sort" << std::endl; }
void translate_to_noPtr(ostream& out, string name, map<string,type*>const& inputs, map<string,type*>const& outputs, graph& g) { std::map<vertex, std::pair<string,string> > indexMap; // get all of the top level data into the map for (int i = 0; i < g.num_vertices(); ++i) { if (g.find_parent(i) == 0) { if (g.info(i).op == input || g.info(i).op == output) { indexMap[i] = make_pair("",g.info(i).label); } else if (g.info(i).op == temporary) { indexMap[i] = make_pair("","t"+boost::lexical_cast<string>(i)); } } } // change all vertex sizes from $$* to s* // have to touch all levels of a type because functions like get_next_element use // lower levels of a given type for (int i = 0; i != g.num_vertices(); i++) { type *t = &g.info(i).t; while (t) { string &s = t->dim.dim; if (s.find("$$") == 0) { s.erase(0,2); s = "__s" + s; } t = t->t; } } step_mp_noPtr.clear(); // for malloc out << "#include <stdlib.h>\n"; //dummy map for function map<string,pair<vertex,type> > data; out << make_function_signature(name,inputs,outputs,data,"",typeWithName,true); //out << "void " << name << function_args(inputs,outputs,data,"",typeWithName,true); //out << "{\n"; // string of pointers for scalar output string ptrOutputLcl; string ptrOutputEnd; for (map<string,type*>::const_iterator i = outputs.begin(); i != outputs.end(); ++i) { if (i->second->k == scalar) { // create local working scalar value ptrOutputLcl += type_to_noPtr(*i->second, i->first) + " = "; ptrOutputLcl += "*" + i->first + "_ptr;\n"; // create store back to argument ptrOutputEnd +="*" + i->first + "_ptr = " + i->first + ";\n"; } } // local copies of scalar outputs out << ptrOutputLcl; // declare iteration vars int maxd = 0; check_depth(1,maxd, g.subgraphs); if (maxd > 0) { out << "int ii"; for (int i = 1; i <= maxd; ++i) out << "," << var_name[i]; out << ";\n"; } else { out << "int ii;\n"; } init_partitions(g, g.subgraphs, out); for (unsigned int u = 0; u != g.num_vertices(); ++u) { if (g.find_parent(u) == 0 && (g.adj(u).size() > 0 || g.inv_adj(u).size() > 0)) { translate_tmp_noPtr(out, g, u, indexMap); } } for (int i = 0; i != g.subgraphs.size(); i++) { subgraph *sg = g.subgraphs[i]; translate_graph_noPtr(out, sg, sg->vertices, sg->subs, g, indexMap); } /* std::map<vertex, std::pair<string,string> >::iterator i; for (i=indexMap.begin(); i!=indexMap.end(); ++i) { std::cout << "map[" << i->first << "] = " << i->second.first << ", " << i->second.second << "\n"; } */ for (unsigned int i = 0; i != g.num_vertices(); ++i) { if (g.find_parent(i) != 0) continue; vertex u = i; if (g.info(u).op == output && g.info(u).t.k == scalar) { vertex pred = g.inv_adj(u)[0]; //string p_label = g.info(pred).label == "" ? "t" + boost::lexical_cast<string>(pred) //: g.info(pred).label; string p_label = "t" + boost::lexical_cast<string>(pred); out << g.info(u).label << " = " << p_label << ";" << std::endl; } } // handle any scalar outputs out << ptrOutputEnd; out << "}\n"; }