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 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 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; }
string container_size(vertex v, graph const& g) { // strip the const qualifier from graph const& type &t = *(type*)(void*)&g.info(v).t; return container_size_type(t); }
string expr_of_noPtr(vertex u, graph& g, subgraph* cur, std::map<unsigned int, std::pair<string, string> > &indexMap) { switch (g.info(u).op) { case trans: assert(g.inv_adj(u).size() == 1); return expr_of_noPtr(g.inv_adj(u)[0], g, cur, indexMap); case negate_op: assert(g.inv_adj(u).size() == 1); return "(-" + expr_of_noPtr(g.inv_adj(u)[0], g, cur, indexMap) + ")"; case squareroot: assert(g.inv_adj(u).size() == 1); return "sqrt(" + expr_of_noPtr(g.inv_adj(u)[0], g, cur, indexMap) + ")"; case add: assert(g.inv_adj(u).size() == 2); return "(" + expr_of_noPtr(g.inv_adj(u)[0], g, cur, indexMap) + "+" + expr_of_noPtr(g.inv_adj(u)[1], g, cur, indexMap) + ")"; case subtract: assert(g.inv_adj(u).size() == 2); return "(" + expr_of_noPtr(g.inv_adj(u)[0], g, cur, indexMap) + "-" + expr_of_noPtr(g.inv_adj(u)[1], g, cur, indexMap) + ")"; case multiply: assert(g.inv_adj(u).size() == 2); return "(" + expr_of_noPtr(g.inv_adj(u)[0], g, cur, indexMap) + "*" + expr_of_noPtr(g.inv_adj(u)[1], g, cur, indexMap) + ")"; case divide: assert(g.inv_adj(u).size() == 2); return "(" + expr_of_noPtr(g.inv_adj(u)[0], g, cur, indexMap) + "/" + expr_of_noPtr(g.inv_adj(u)[1], g, cur, indexMap) + ")"; case get_element: { char itr = var_name[depth(g.find_parent(u))]; map<vertex,pair<string,string> >::iterator index_found = indexMap.find(g.inv_adj(u)[0]); if (index_found != indexMap.end()) { return indexMap[g.inv_adj(u)[0]].second + indexMap[g.inv_adj(u)[0]].first + "[" + itr +"]"; } else if (g.info(g.inv_adj(u)[0]).label.compare("") == 0) { std::cerr << "bad index in expr_of" << endl; } else { return g.info(g.inv_adj(u)[0]).label + "[" + itr + "]"; } } case store_element: case store_add_element: { char itr = var_name[depth(g.find_parent(u))]; vertex succ = g.adj(u)[0]; for (unsigned int i = 0; i != g.adj(u).size(); ++i) { if (g.info(g.adj(u)[i]).op == output) { succ = g.adj(u)[i]; break; } } return indexMap[succ].second + indexMap[succ].first + "[" + itr +"]"; } case get_row: case get_column: case get_row_from_column: case get_column_from_row: case store_row: case store_column: case store_add_row: case store_add_column: case temporary: return "t" + boost::lexical_cast<string>(u); case input: case output: return g.info(u).label; case sumto: return "t" + boost::lexical_cast<string>(u); default: return "?"; } }
string expr_of(vertex u, graph& g, subgraph* cur) { switch (g.info(u).op) { case trans: assert(g.inv_adj(u).size() == 1); return expr_of(g.inv_adj(u)[0], g, cur); case negate_op: assert(g.inv_adj(u).size() == 1); return "(-" + expr_of(g.inv_adj(u)[0], g, cur) + ")"; case squareroot: assert(g.inv_adj(u).size() == 1); return "(" + expr_of(g.inv_adj(u)[0], g, cur) + ")"; case add: assert(g.inv_adj(u).size() == 2); return "(" + expr_of(g.inv_adj(u)[0], g, cur) + "+" + expr_of(g.inv_adj(u)[1], g, cur) + ")"; case subtract: assert(g.inv_adj(u).size() == 2); return "(" + expr_of(g.inv_adj(u)[0], g, cur) + "-" + expr_of(g.inv_adj(u)[1], g, cur) + ")"; case multiply: assert(g.inv_adj(u).size() == 2); return "(" + expr_of(g.inv_adj(u)[0], g, cur) + "*" + expr_of(g.inv_adj(u)[1], g, cur) + ")"; case divide: assert(g.inv_adj(u).size() == 2); return "(" + expr_of(g.inv_adj(u)[0], g, cur) + "/" + expr_of(g.inv_adj(u)[1], g, cur) + ")"; case get_element: { string indx; indx.assign(var_name,depth(g.find_parent(u)),1); if (g.info(g.inv_adj(u)[0]).op == get_row_from_column || g.info(g.inv_adj(u)[0]).op == get_column_from_row) indx += "*"+g.info(g.inv_adj(u)[0]).t.dim.step; if (g.info(g.inv_adj(u)[0]).op == output || g.info(g.inv_adj(u)[0]).op == input) return g.info(g.inv_adj(u)[0]).label + "[" + indx +"]"; vertex pred = g.inv_adj(u)[0]; while (g.info(pred).op == partition_cast) { pred = g.inv_adj(pred)[0]; } if (g.info(pred).t.k == scalar && g.adj(pred).size() > 1) { for (unsigned int i = 0; i < g.adj(pred).size(); ++i) { vertex s = g.adj(pred)[i]; if (s == u) continue; if (g.info(s).op == input || g.info(s).op == output) return g.info(s).label + "[" + indx + "]"; } } return "t" + boost::lexical_cast<string>(pred) + "[" + indx + "]"; } case store_element: case store_add_element: { char itr = var_name[depth(g.find_parent(u))]; for (unsigned int i = 0; i != g.adj(u).size(); ++i) { if (g.info(g.adj(u)[i]).op == output) { return g.info(g.adj(u)[i]).label + "[" + itr + "]"; } } return "t" + boost::lexical_cast<string>(g.adj(u)[0]) + "[" + itr + "]"; //return "t" + boost::lexical_cast<string>(u); } case get_row: case get_column: case get_row_from_column: case get_column_from_row: case store_row: case store_column: case store_add_row: case store_add_column: case temporary: return "t" + boost::lexical_cast<string>(u); case input: case output: return g.info(u).label; case sumto: return "t" + boost::lexical_cast<string>(u); default: return "?"; } }
void translate_declareVariables_noPtr(ostream& out, graph &g, vertex u, bool parallel, map<vertex, pair<string, string> > &indexMap) { string iter = string(1,var_name[depth(g.find_parent(u))]); string topName = ""; bool need_iter = true; switch (g.info(u).op) { case get_row_from_column: case get_column_from_row: { vertex pred = g.inv_adj(u)[0]; if (g.info(pred).op == input) topName = g.info(pred).label; else topName = indexMap[pred].second; break; } case get_row: case get_element: case get_column: { vertex pred = g.inv_adj(u)[0]; if (g.info(pred).op == input) { topName = g.info(pred).label; } else { topName = indexMap[pred].second; } break; } case store_row: case store_element: case store_add_element: case store_add_column: case store_column: { vertex succ = g.adj(u)[0]; if (g.info(succ).op == output) topName = g.info(succ).label; else topName = indexMap[succ].second; break; } case temporary: topName = "t"+boost::lexical_cast<string>(u); need_iter = false; if (parallel) break; switch (g.info(u).t.k) { case row: case column: out << type_to_noPtr(g.info(u).t, "t"+boost::lexical_cast<string>(u), false) << ";\n"; break; case scalar: out << precision_type << " t" << u << ";\n"; break; default: break; }//switch inside temporary case break; case sumto: { vertex succ = g.adj(u)[0]; string scl = "t" + boost::lexical_cast<string>(succ); //new stuff //code coverage: /* I think the point here is that the output of the sumto node * may or may not be an output in the total graph. * If it isn't, we need to create a temporary for it. * My question: why don't we have the same situation for the other nodes? */ if (g.info(succ).op == output) { topName = g.info(succ).label; scl = g.info(succ).label; } else { topName = scl; } // What does this mean? Why do we care about the height difference of the two nodes? if (g.info(u).t.height < g.info(succ).t.height) { if (g.info(u).t.k == scalar) { out << precision_type << " t" << u << " = " << scl; if (g.info(succ).t.k != scalar) { out << "[" << iter << "]"; } out << ";\n"; } /*else { out << precision_type << "* t" << u << " = " << scl << " + " << iter << get_next_elem(g.info(succ).t) << ";\n"; }*/ } else { if (g.info(u).t.k == scalar) { if (depth(g.find_parent(u)) > depth(g.find_parent(succ))) { out << precision_type << " *t" << u << " = " << scl; } else { out << precision_type << " t" << u; } out << ";\n"; } else { if (depth(g.find_parent(u)) > depth(g.find_parent(succ))) { if (parallel) { out << precision_type << " *t" << u << " = " << scl << "+disp*" << container_size(u,g) << ";\n"; } else { out << precision_type << " *t" << u << " = " << scl << ";\n"; } } else { out << type_to_noPtr(g.info(u).t, "t"+boost::lexical_cast<string>(u), false) << ";\n"; } } } if (!been_cleared(u,g,0)) { if (g.info(u).t.k == scalar) { need_iter = false; //scalar, so we don't need iter out << "t" + boost::lexical_cast<string>(u) << " = 0.0;\n"; } else { need_iter = true; string cs = container_size(u,g); size_t pos = cs.find("__s",0); while (pos != string::npos) { cs.replace(pos,3,"__m"); pos = cs.find("__s",0); } out << "for (ii = 0; ii < " << cs << "; ++ii)\n"; //out << "t" + boost::lexical_cast<string>(u) << "[ii] = 0.0;\n"; if (topName != "") { out << topName << "[" << iter << "][ii] = 0.0;\n"; } else { out << indexMap[succ].second << "[" << iter << "][ii] = 0.0;\n"; } } } break; } default: break; } if (topName != "") { if (need_iter) { indexMap[u] = make_pair(indexMap[u].first + "[" + iter + "]", topName); } else { indexMap[u] = make_pair(indexMap[u].first, topName); } } }
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"; }
void translate_graph_noPtr(ostream& out, subgraph* current, vector<vertex> const& vertices, vector<subgraph*> const& subgraphs, graph& g, std::map<vertex,std::pair<string,string> > &indexMap) { // get correct loop based on subgraph iterator details out << current->sg_iterator.getSerialCLoop(current); //std::cerr << "starting graph translation" << std::endl; // topologically sort the subgraphs deque<vertex> order; map<vertex,subgraph*> new_sub; map<vertex,vertex> new_old; order_subgraphs(order, new_sub, new_old, current, vertices, subgraphs, g); //std::cerr << "declaring variables" << std::endl; // Declare variables for (unsigned int i = 0; i != order.size(); ++i) { map<vertex,vertex>::iterator iter = new_old.find(order[i]); if (iter != new_old.end()) { vertex u = iter->second; translate_declareVariables_noPtr(out, g, u, false, indexMap); }//if }//for //std::cerr << "finished declaring variables" << std::endl; // Do computations and store the results for (unsigned int i = 0; i != order.size(); ++i) { map<vertex,subgraph*>::iterator iter = new_sub.find(order[i]); if (iter != new_sub.end()) { subgraph* sg = iter->second; translate_graph_noPtr(out, sg, sg->vertices, sg->subs, g, indexMap); } else { map<vertex,vertex>::iterator iter = new_old.find(order[i]); if (iter != new_old.end()) { vertex u = iter->second; switch (g.info(u).op) { case store_element: if (g.inv_adj(u).size() == 1) { string target; char itr = var_name[depth(g.find_parent(u))]; vertex succ = g.adj(u)[0]; if (g.info(succ).op != output) target = "t" + boost::lexical_cast<string>(succ); else target = g.info(succ).label; map<vertex,pair<string,string> >::iterator index_found = indexMap.find(succ); if (index_found != indexMap.end()) { out << indexMap[succ].second << indexMap[succ].first + "[" + itr << "] = " << expr_of_noPtr(g.inv_adj(u)[0], g, current, indexMap) << "; //accessing indexMap[" << succ << "]\n"; } else { if (g.info(succ).label.compare("") == 0) { std::cerr << "Failing to find in indexMap, unexpected case" << endl; } else { out << g.info(succ).label << "[" << itr << "] = " << expr_of_noPtr(g.inv_adj(u)[0], g, current, indexMap) << "; //accessing indexMap[" << succ << "]\n"; } } //out << "*t" << u << " = " << expr_of_noPtr(g.inv_adj(u)[0], g, current) << ";\n"; } break; case store_add_element: if (g.inv_adj(u).size() == 1) { string target; char itr = var_name[depth(g.find_parent(u))]; vertex succ = g.adj(u)[0]; if (g.info(succ).op != output) target = "t" + boost::lexical_cast<string>(succ); else target = g.info(succ).label; map<vertex,pair<string,string> >::iterator index_found = indexMap.find(succ); if (index_found != indexMap.end()) { out << indexMap[succ].second << indexMap[succ].first + "[" + itr << "] += " << expr_of_noPtr(g.inv_adj(u)[0], g, current, indexMap) << "; //accessing indexMap[" << succ << "]\n"; } else { if (g.info(succ).label.compare("") == 0) { std::cerr << "Failing to find in indexMap, unexpected case" << endl; } else if (g.info(succ).label.compare(0, 3,"tmp") == 0) { out << "t" + boost::lexical_cast<string>(succ) << "[" << itr << "] += " << expr_of_noPtr(g.inv_adj(u)[0], g, current, indexMap) << "; //accessing indexMap[" << succ << "]\n"; } else { out << g.info(succ).label << "[" << itr << "] += " << expr_of_noPtr(g.inv_adj(u)[0], g, current, indexMap) << "; //accessing indexMap[" << succ << "]\n"; } } //out << "*t" << u << " += " << expr_of_noPtr(g.inv_adj(u)[0], g, current) << ";\n"; } break; case sumto: break; if (g.info(u).t.k == scalar) { if (been_cleared(u, g, 0)) { out << "*t" << u << " += t" << g.inv_adj(u)[0] << ";\n"; } else { out << "*t" << u << " = t" << g.inv_adj(u)[0] << ";\n"; } } break; case multiply: if (g.adj(u).size() > 0) { vertex adj = g.adj(u)[0]; while (g.info(adj).op == partition_cast) { adj = g.adj(adj)[0]; } if (g.info(adj).op == sumto) { out << "t" << adj << " += " << expr_of_noPtr(u, g, current, indexMap) << ";\n"; } } default: // old summation code, sumto should eliminate the need for this //out << "t" << g.adj(u)[0] << " += " << expr_of_noPtr(u, g, current, indexMap) << ";\n"; break; } } } } // Sumto cleanup for (unsigned int i = 0; i != order.size(); ++i) { map<vertex,vertex>::iterator iter = new_old.find(order[i]); if (iter != new_old.end()) { vertex u = iter->second; if (g.adj(u).size() > 0) { char iter = var_name[depth(g.find_parent(u))]; switch (g.info(u).op) { case sumto: { vertex succ = g.adj(u)[0]; string scl = "t" + boost::lexical_cast<string>(succ); if (g.info(succ).op == output) scl = g.info(succ).label; if (g.info(u).t.height < g.info(succ).t.height) { // store if (g.info(u).t.k == scalar) { out << scl; if (g.info(succ).t.k != scalar) out << "[" << iter << "]"; out << " = t" << u << ";\n"; } } break; } default: { break; } } } } } /* for (unsigned int i = 0; i != vertices.size(); ++i) { vertex u = vertices[i]; if (g.info(u).op == output && g.info(u).t.k == scalar) { vertex pred = g.inv_adj(u)[0]; // in the single core case if pred is a sumto it is pointing to the output node // any way so this should be skipped if (g.info(pred).op == sumto) continue; string p_label = g.info(pred).label == "" ? "t" + boost::lexical_cast<string>(pred) : g.info(pred).label; out << g.info(u).label << " = " << p_label << ";" << std::endl; } } */ out << "}\n"; //std::cerr << "finished translating graph" << std::endl; }
void translate_tmp_noPtr(ostream& out, graph &g, vertex u, map<vertex, pair<string,string> > &indexMap) { string iter = string(1,var_name[depth(g.find_parent(u))]); string topname = ""; // create temporary space switch (g.info(u).op) { case temporary: topname = "t"+boost::lexical_cast<string>(u); switch (g.info(u).t.k) { case row: case column: out << type_to_noPtr(g.info(u).t, "t"+boost::lexical_cast<string>(u), false) << ";\n"; break; case scalar: //out << precision_type << " t" << u << "[1];\n"; out << precision_type << " t" << u << ";\n"; break; default: break; }//switch inside temporary case break; case sumto: { topname = "t"+boost::lexical_cast<string>(u); vertex succ = g.adj(u)[0]; string scl = "t" + boost::lexical_cast<string>(succ); if (g.info(succ).op == output) scl = g.info(succ).label; int d = (depth(g.find_parent(u)) - depth(g.find_parent(succ))); if (d == 0) { // just point to if (g.info(u).t.k == scalar) out << precision_type << " t" << u << " = " << scl << ";\n"; else out << precision_type << " *t" << u << " = " << scl << ";\n"; } else if (d < 0) { // treat as temporary if (g.info(u).t.k == scalar) { //out << precision_type << " t" << u << "[1];\n"; out << precision_type << " t" << u << ";\n"; } else { out << type_to_noPtr(g.info(u).t, "t"+boost::lexical_cast<string>(u), false) << ";\n"; } } else { // if the adjacent node is an output, we can use the output space that exists // aready so do nothing.Pointing to another sumto should have the space // already allocated, but this check may need to be improved. // For other ops // parallel has shown other cases in the dispatch loops that are working // correctly for now.In these cases, it may be correct to allocate // this space here.Need to find a case for this. //} } if (g.info(u).t.k == scalar) { out << "t" + boost::lexical_cast<string>(u) << " = 0.0;\n"; } else { out << "for (ii = 0; ii < " << container_size(u, g) << "; ++ii)\n"; out << "t" + boost::lexical_cast<string>(u) << "[ii] = 0.0; //in translate_tmp\n"; } //indexMap[u] = make_pair("t"+ boost::lexical_cast<string>(u), itr); break; } case input: case output: break; default: { break; } } if (topname != "") { indexMap[u] = make_pair(indexMap[u].first, topname); } }