Пример #1
0
def gen_output_er_1dto1d(output_er_spec,is_call_input,mapir):
	import iegen.pycloog
	from iegen.pycloog import codegen
	from iegen.codegen import Statement,Comment

	iegen.print_progress("Generating code for output ERSpec '%s'..."%(output_er_spec.name))
	iegen.print_detail(str(output_er_spec))

	print 'Abstract relation: %s'%(output_er_spec.relation)
	print 'Input bounds for abstract relation: %s'%(output_er_spec.input_bounds)
	print 'Output bounds for abstract relation: %s'%(output_er_spec.output_bounds)

	#Calculate the necessary information before generating code
	output_bounds_var_name=output_er_spec.output_bounds.tuple_set[0]
	output_lower_bound=str(list(output_er_spec.output_bounds.lower_bounds(output_bounds_var_name)[0])[0])
	output_upper_bound=str(list(output_er_spec.output_bounds.upper_bounds(output_bounds_var_name)[0])[0])

	input_bounds_var_name=output_er_spec.input_bounds.tuple_set[0]
	input_lower_bound=str(list(output_er_spec.input_bounds.lower_bounds(input_bounds_var_name)[0])[0])
	input_upper_bound=str(list(output_er_spec.input_bounds.upper_bounds(input_bounds_var_name)[0])[0])

	num_entries=calc_size_string(list(output_er_spec.output_bounds)[0],output_bounds_var_name)

	input_equal_value=calc_equality_value(input_bounds_var_name,list(output_er_spec.relation)[0],mapir)

	input_var_name=output_er_spec.relation.tuple_in[0]
	output_var_name=output_er_spec.relation.tuple_out[0]

	stmts=[]
	stmts.append(Comment('Creation of ER_1Dto1D for abstract relation:'))
	stmts.append(Comment(str(output_er_spec.relation)))
	stmts.append(Comment('Bounds for output domain: '+str(output_er_spec.output_bounds)))

	#Generate the call to the constructor
	stmts.append(Statement('%s=%s(%s,%s,%s,%s,%s);'%(output_er_spec.get_var_name(),output_er_spec.get_ctor_str(),input_lower_bound,input_upper_bound,output_lower_bound,output_upper_bound,num_entries)))

	#Generate the count loop
	stmts.append(Statement('#define S0(%s) %s(%s,%s)'%(output_var_name,output_er_spec.get_count_name(),output_er_spec.get_var_name(),input_equal_value)))
	loop_stmts=codegen([iegen.pycloog.Statement(output_er_spec.output_bounds)]).split('\n')
	for loop_stmt in loop_stmts:
		stmts.append(Statement(loop_stmt))
	stmts.append(Statement('#undef S0'))

	#Generate the finalize count call
	stmts.append(Statement('%s(%s)'%(output_er_spec.get_count_finalize_name(),output_er_spec.get_var_name())))

	#Generate the insert loop
	stmts.append(Statement('#define S0(%s) %s(%s,%s,%s)'%(output_var_name,output_er_spec.get_setter_str(),output_er_spec.get_var_name(),input_equal_value,output_var_name)))
	loop_stmts=codegen([iegen.pycloog.Statement(output_er_spec.output_bounds)]).split('\n')
	for loop_stmt in loop_stmts:
		stmts.append(Statement(loop_stmt))
	stmts.append(Statement('#undef S0'))

	stmts.append(Statement('*%s=%s;'%(output_er_spec.get_param_name(),output_er_spec.get_var_name())))
	stmts.append(Statement())

	return stmts
Пример #2
0
	def calc_input(self,mapir):
		#This transformation requires the ER for the given sparse tiling
		self.inputs.append(mapir.er_specs[self.tiling_name])

		#and the constant for the specific loop nest
		statement=mapir.statements[self.statement_name]
		loop_pos=calc_equality_value(statement.scatter.tuple_vars[-3],list(statement.scatter)[0],mapir)
		#TODO: The loop constants don't match exactly, they are off by one.
		loop_pos=str(int(loop_pos)+1)
		self.inputs.append(Constant(loop_pos))
Пример #3
0
	def calc_input(self,mapir):
		#The tiling routine takes the dependences into and out of the iteration seed space
		#These dependences are given by the user currently, so we do not need to calculate them
		#Create a DataDependence instance for the dependences
		target=calc_equality_value(self.to_deps.tuple_out[0],list(self.to_deps)[0],mapir)
		self.to_deps=DataDependence('%s_to_deps'%(self.grouping_name,),self.to_deps,target)
		self.from_deps=DataDependence('%s_from_deps'%(self.grouping_name,),self.from_deps,target)

		#Create a new Symbolic for the number of tiles
		#TODO: The type is constant here, it would be better if this were defined somewhere else
		mapir.add_symbolic(name=self.num_tile_name,type='int %s',lower_bound=1)

		self.inputs.append(self.to_deps)
		self.inputs.append(self.from_deps)
		self.inputs.append(mapir.symbolics[self.num_tile_name])
Пример #4
0
def gen_explicit_er_spec(er_spec,mapir):
	import iegen.pycloog
	from iegen.pycloog import codegen
	from iegen.codegen import Statement,Comment

	if 0==len(er_spec.relation): raise ValueError("ESpec's relation has no terms in the disjunction")
	if (1,1)!=er_spec.relation.arity(): raise ValueError("ESpec's relation must have arity (1,1)")

	iegen.print_progress("Generating code for ERSpec '%s'..."%(er_spec.name))
	iegen.print_detail(er_spec)

	var_in_name=er_spec.relation.tuple_in[0]
	var_out_name=er_spec.relation.tuple_out[0]

	#Generate the define/undefine statements
	cloog_stmts=[]
	define_stmts=[]
	undefine_stmts=[]
	for relation_index,relation in enumerate(er_spec.relation):
		#Get the value to insert
		value=calc_equality_value(var_out_name,relation,mapir)

		define_stmts.append(Statement('#define S%d(%s) ER_in_ordered_insert(%s_ER,Tuple_make(%s),Tuple_make(%s));'%(relation_index,var_in_name,er_spec.name,var_in_name,value)))

		cloog_stmts.append(iegen.pycloog.Statement(er_spec.input_bounds))
		undefine_stmts.append(Statement('#undef S%d'%(relation_index,)))

	#Generate the whole set of statements
	stmts=[]
	in_domain_name='in_domain_%s'%(er_spec.name)
	stmts.extend(gen_domain(in_domain_name,er_spec.input_bounds))
	stmts.append(Statement())
	stmts.append(Comment('Creation of ExplicitRelation'))
	stmts.append(Comment(str(er_spec.relation)))
	stmts.append(Statement('%s_ER = %s(%d,%d,%s,%s,%s);'%(er_spec.name,er_spec.get_ctor_str(),er_spec.relation.arity_in(),er_spec.relation.arity_out(),in_domain_name,str(er_spec.is_function).lower(),str(er_spec.is_permutation).lower())))
	stmts.append(Statement())
	stmts.append(Comment('Define loop body statements'))
	stmts.extend(define_stmts)
	stmts.append(Statement())
	loop_stmts=codegen(cloog_stmts).split('\n')
	for loop_stmt in loop_stmts:
		stmts.append(Statement(loop_stmt))
	stmts.append(Statement())
	stmts.append(Comment('Undefine loop body statements'))
	stmts.extend(undefine_stmts)
	return stmts
Пример #5
0
	def calc_output(self,mapir):
		#Create the name of the sparse schedule
		sparse_sched_name='%s_sched'%(self.statement_name)

		#Get the ERSpec for the specified tiling function
		tiling_er_spec=mapir.er_specs[self.tiling_name]

		statement=mapir.statements[self.statement_name]
		sparse_loop_iter=statement.iter_space.tuple_vars[-2]

		#Extract the sparse loop bounds from the statement's iteration space
		output_bounds=statement.iter_space.bounds(sparse_loop_iter)
		lower_bounds=' and '.join(list('%s<=%s'%(str(bound),sparse_loop_iter) for bound in list(output_bounds[0])[0]))
		upper_bounds=' and '.join(list('%s<=%s'%(sparse_loop_iter,str(bound)) for bound in list(output_bounds[0])[1]))
		output_bounds=Set('{[%s]: %s and %s}'%(sparse_loop_iter,lower_bounds,upper_bounds),symbolics=statement.iter_space.symbolics)

		#Get the constant for the position of the sparse loop within the tile loop
		loop_pos=calc_equality_value(statement.scatter.tuple_vars[-3],list(statement.scatter)[0],mapir)
		#TODO: The loop constants don't match exactly, they are off by one.
		loop_pos=str(int(loop_pos)+1)

		relation=Relation('{[tile]->[iter]: tile=theta(%s,iter)}'%(loop_pos))

		#Create a new ERSpec that represents the specified statement's sparse schedule
		self.outputs.append(ERSpec(
		    name=sparse_sched_name,
		    input_bounds=tiling_er_spec.output_bounds.copy(),
		    output_bounds=output_bounds,
		    relation=relation,
		    is_function=False,
		    is_permutation=False,
		    is_gen_output=False))

		#Add the ERSpec to the MapIR
		mapir.add_er_spec(self.outputs[0])

		self.print_progress("Calculated output ERSpec '%s' for transformation '%s'..."%(self.outputs[0].name,self.name))
		self.print_detail(self.outputs[0])
Пример #6
0
def gen_executor_loop_stmts(mapir):
	from iegen.codegen import Statement,Comment
	from iegen.util import trans_equals

	stmts=[]
	stmts.append(Comment('Define the executor main loop body statments'))
	statement_names=mapir.statements.keys()
	statement_names.sort()
	for i,statement_name in enumerate(statement_names):
		statement=mapir.statements[statement_name]
		for comment_line in statement.text.split('\n'):
			stmts.append(Comment(comment_line))
		ar_dict={}
		for access_relation in statement.get_access_relations():
			iegen.print_detail('Generating code for access relation %s'%(access_relation.name))
			stmts.append(Comment('%s: %s'%(access_relation.name,access_relation.iter_to_data)))
			ar_string_list=[]
			for out_var_name in access_relation.iter_to_data.tuple_out:
				ar_string_list.append(calc_equality_value(out_var_name,access_relation.iter_to_data,mapir))
			ar_dict[access_relation.name]=']['.join(ar_string_list)

		#Gather the loop iterators
		if statement.sparse_sched is None:
			iterators=','.join(statement.iter_space.tuple_set)
		else:
			iterators=','.join(statement.iter_space.tuple_set[:-1])

		#If there are any UFS constraints, wrap the statement text in a guard
		statement_text=statement.text
		ufs_constraints=statement.iter_space.ufs_constraints()

		#Make sure there is only a single conjunction in the iteration space
		if len(ufs_constraints)!=1:
			raise ValueError('Iteration space has multiple conjunctions')

		#Check if we need to generate a sparse loop
		if statement.sparse_sched is not None:
			sparse_sched_name=statement.sparse_sched
			sparse_sched_er=mapir.er_specs[sparse_sched_name]

			iter_name=statement.iter_space.tuple_set[-1]
			outer_iter_name=statement.iter_space.tuple_set[-2]

			sparse_loop='''for(%s=%s(*%s,%s);\
    %s!=%s(*%s,%s);\
    %s=%s(*%s,%s))'''%(iter_name,sparse_sched_er.get_begin_iter(),sparse_sched_name,outer_iter_name,iter_name,sparse_sched_er.get_end_iter(),sparse_sched_name,outer_iter_name,iter_name,sparse_sched_er.get_next_iter(),sparse_sched_name,outer_iter_name)

			statement_text='''%s{\
%s\
}'''%(sparse_loop,statement_text)

		#Check if there are any UFS constraints that we need to generate guards for
		elif len(ufs_constraints[0])>0:
			ufs_constraints_strs=[trans_equals(str(constraint.value_string(function_name_map=mapir.ufs_name_map()))) for constraint in ufs_constraints[0]]
			statement_text='if(%s){%s}'%(' && '.join(ufs_constraints_strs),statement_text)

		stmt_string='#define S%d(%s) %s'%(i,iterators,statement_text)
		stmt_string=stmt_string.replace('\n','\\\n')
		stmts.append(Statement(stmt_string%ar_dict))

		stmts.append(Statement())

	return stmts
Пример #7
0
def gen_data_dep(data_dep,mapir):
	from iegen.pycloog import codegen

	#Get the dependence relation from the data dependence object
	dep_rel=data_dep.dep_rel

	#Ensure the data dep is 2d -> 2d
	if (2,2)!=dep_rel.arity():
		raise ValueError('Code generation for data dependences that are not 2d -> 2d is not supported')

	stmts=[]

	#Input constant value (from loop)
	in_const=calc_equality_value(dep_rel.tuple_in[0],list(dep_rel)[0],mapir)

	#Determine if the target loop is the input or output of the relation
	if in_const==data_dep.target:
		bounds_var=dep_rel.tuple_in[1]
	else:
		bounds_var=dep_rel.tuple_out[1]

	#Get the lower and upper bounds for the bounds variable
	lbs=calc_single_bounds_from_bounds(dep_rel.lower_bounds(bounds_var))
	ubs=calc_single_bounds_from_bounds(dep_rel.upper_bounds(bounds_var))

	stmts.append(Comment('Dependences for %s'%(data_dep.name)))
	stmts.append(Comment(str(dep_rel)))

	#Declare the explicit dependence variable
	const_in=calc_equality_value(dep_rel.tuple_in[0],list(dep_rel)[0],mapir)
	input_size_string=calc_size_string(list(dep_rel)[0],dep_rel.tuple_in[1])
	const_out=calc_equality_value(dep_rel.tuple_out[0],list(dep_rel)[0],mapir)
	output_size_string=calc_size_string(list(dep_rel)[0],dep_rel.tuple_out[1])
	stmts.append(Statement('%s %s=%s(%s,%s,%s,%s,%s);'%(data_dep.get_type(),data_dep.get_var_name(),data_dep.get_ctor_str(),const_in,const_out,input_size_string,output_size_string,len(dep_rel))))

	#Generate the define/undefine statements
	cloog_stmts=[]
	define_stmts=[]
	undefine_stmts=[]

	var_in_name=dep_rel.tuple_in[1]
	var_out_name=dep_rel.tuple_out[1]

	for conjunction_index,single_relation in enumerate(dep_rel):
		bounds_set=Set('{[%s]: %s<=%s and %s<=%s}'%(bounds_var,lbs[conjunction_index],bounds_var,bounds_var,ubs[conjunction_index]),mapir.get_symbolics())

		#Get the value to insert
		if in_const==data_dep.target:
			value=calc_equality_value(var_out_name,single_relation,mapir,only_eqs=True)
			define_stmts.append(Statement('#define S%d(%s) %s(%s,%s,%s);'%(conjunction_index,bounds_var,data_dep.get_setter_str(),data_dep.get_var_name(),bounds_var,value)))
		else:
			value=calc_equality_value(var_in_name,single_relation,mapir,only_eqs=True)
			define_stmts.append(Statement('#define S%d(%s) %s(%s,%s,%s);'%(conjunction_index,bounds_var,data_dep.get_setter_str(),data_dep.get_var_name(),value,bounds_var)))

		cloog_stmts.append(iegen.pycloog.Statement(bounds_set))

		undefine_stmts.append(Statement('#undef S%d'%(conjunction_index,)))

	#Generate the whole set of statements
	stmts.append(Comment('Define loop body statements'))
	stmts.extend(define_stmts)
	stmts.append(Statement())
	loop_stmts=codegen(cloog_stmts).split('\n')
	for loop_stmt in loop_stmts:
		stmts.append(Statement(loop_stmt))
	stmts.append(Statement())
	stmts.append(Comment('Undefine loop body statements'))
	stmts.extend(undefine_stmts)
	stmts.append(Statement())

	return stmts
Пример #8
0
def gen_output_er_u1d(output_er_spec,is_call_input,mapir):
	import iegen.pycloog
	from iegen.pycloog import codegen
	from iegen.codegen import Statement,Comment

	iegen.print_progress("Generating code for output ERSpec '%s'..."%(output_er_spec.name))
	iegen.print_detail(str(output_er_spec))

	stmts=[]

	#TODO: Make this routine more general so it can handle generation for
	# general relations in addition to functions
	# Currently it just generates code for explicit functions
	#TODO: Generalize the bounds expression calculations to handle
	# more than a single expression (with min/max)
	input_var_name=output_er_spec.input_bounds.tuple_set[0]
	input_lower_bound=str(list(output_er_spec.input_bounds.lower_bounds(input_var_name)[0])[0])
	input_upper_bound=str(list(output_er_spec.input_bounds.upper_bounds(input_var_name)[0])[0])
	output_var_name=output_er_spec.output_bounds.tuple_set[0]
	output_lower_bound=str(list(output_er_spec.output_bounds.lower_bounds(output_var_name)[0])[0])
	output_upper_bound=str(list(output_er_spec.output_bounds.upper_bounds(output_var_name)[0])[0])
	stmts.append(Comment('Creation of ExplicitFunction for abstract relation:'))
	stmts.append(Comment(str(output_er_spec.relation)))
	stmts.append(Comment('Input bounds for abstract relation: %s'%(output_er_spec.input_bounds)))
	stmts.append(Comment('Output bounds for abstract relation: %s'%(output_er_spec.output_bounds)))
	stmts.append(Statement('*%s=%s(%s,%s,%s,%s,%s);'%(output_er_spec.get_param_name(),output_er_spec.get_ctor_str(),input_lower_bound,input_upper_bound,output_lower_bound,output_upper_bound,str(output_er_spec.is_permutation).lower())))
	stmts.append(Statement('%s=*%s;'%(output_er_spec.get_var_name(),output_er_spec.get_param_name())))
	stmts.append(Statement())

	if not is_call_input:
		#Generate the define/undefine statements
		cloog_stmts=[]
		define_stmts=[]
		undefine_stmts=[]

		var_in_name=output_er_spec.relation.tuple_in[0]
		var_out_name=output_er_spec.relation.tuple_out[0]

		for relation_index,single_relation in enumerate(output_er_spec.relation):
			#Get the value to insert
			value=calc_equality_value(var_out_name,single_relation,mapir)

			define_stmts.append(Statement('#define S%d(%s) %s(%s,%s,%s);'%(relation_index,var_in_name,output_er_spec.get_setter_str(),output_er_spec.get_var_name(),var_in_name,value)))

			cloog_stmts.append(iegen.pycloog.Statement(output_er_spec.input_bounds))
			undefine_stmts.append(Statement('#undef S%d'%(relation_index,)))

		#Generate the whole set of statements
		stmts.append(Comment('Define loop body statements'))
		stmts.extend(define_stmts)
		stmts.append(Statement())
		loop_stmts=codegen(cloog_stmts).split('\n')
		for loop_stmt in loop_stmts:
			stmts.append(Statement(loop_stmt))
		stmts.append(Statement())
		stmts.append(Comment('Undefine loop body statements'))
		stmts.extend(undefine_stmts)
		stmts.append(Statement())

	#TODO: This is the old code that generates an ER rather than an EF
	##Create a domain for the ERSpec
	#in_domain_name='in_domain_%s'%(output_er_spec.name)
	#stmts.extend(gen_domain(in_domain_name,output_er_spec.input_bounds))
	#stmts.append(Statement('*%s=ER_ctor(%d,%d,%s,%s,%s);'%(output_er_spec.name,output_er_spec.input_bounds.arity(),output_er_spec.output_bounds.arity(),in_domain_name,str(output_er_spec.is_function).lower(),str(output_er_spec.is_permutation).lower())))
	#stmts.append(Statement('%s_ER=*%s;'%(output_er_spec.name,output_er_spec.name)))

	return stmts