예제 #1
0
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);
        }
    }
}
예제 #2
0
	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;
				}
			}
		}
	}
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
void print_subgraph(std::ostream& out, subgraph* sg, graph const& g) {
	out << "subgraph cluster" << subgraph_num++ << " {\n" << std::endl;

	out << "label = \"conditions:" << sg->sg_iterator.printConditions()
		<< "\\nupdates: "
		<< sg->sg_iterator.printUpdates() 
		<< "\\n" << format_to_name(sg->sg_iterator.format)
		<< attribute_to_string(&sg->sg_iterator)
		<< "\\n id:" << sg->str_id << "\";" << std::endl;
	out << "style = solid;\n";

	for (unsigned int j = 0; j != sg->vertices.size(); ++j) {
		vertex u = sg->vertices[j];
		if (g.adj(u).size() > 0 || g.inv_adj(u).size() > 0)
			out << u << ";\n";
	}
	for (unsigned int j = 0; j != sg->subs.size(); ++j)
		print_subgraph(out, sg->subs[j], g);
	out << "}" << std::endl;
}
예제 #6
0
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);
	}
}
예제 #7
0
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 "?";
	}
}
예제 #8
0
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 "?";
	}
}
예제 #9
0
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);
		}
	}
}
예제 #10
0
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";

}
예제 #11
0
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;
}