Exemplo n.º 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
Exemplo n.º 2
0
	def testPYCLooGScatter(self):
		from iegen.pycloog import Statement,codegen
		from iegen import Set,Relation,Symbolic

		code='''for (s=0;s<=T;s++) {
  for (i=0;i<=N;i++) {
    S0(s,i);
  }
  for (i=0;i<=n_inter;i++) {
    S1(s,i);
    S2(s,i);
  }
}'''

		dom0=Set('{[s,i]: 0<=s && s<=T && 0<=i && i<=N}',[Symbolic('T',lower_bound=0),Symbolic('N',lower_bound=0)])
		scat0=Relation('{[s,i]->[c0,s,c1,i,c2]: c0=0 && c1=0 && c2=0}')

		dom1=Set('{[s,i]: 0<=s && s<=T && 0<=i && i<=n_inter}',[Symbolic('T',lower_bound=0),Symbolic('n_inter',lower_bound=0)])
		scat1=Relation('{[s,i]->[c0,s,c1,i,c2]: c0=0 && c1=1 && c2=0}')

		dom2=Set('{[s,i]: 0<=s && s<=T && 0<=i && i<=n_inter}',[Symbolic('T',lower_bound=0),Symbolic('n_inter',lower_bound=0)])
		scat2=Relation('{[s,i]->[c0,s,c1,i,c2]: c0=0 && c1=1 && c2=1}')

		stmt0=Statement(dom0,scat0)
		stmt1=Statement(dom1,scat1)
		stmt2=Statement(dom2,scat2)
		stmts=(stmt0,stmt1,stmt2)

		res=codegen(stmts)
		self.failUnless(code==res,'PYCLooG generated:\n\n%s\n\nbut test expected:\n\n%s'%(res,code))
Exemplo n.º 3
0
def gen_executor_loop(mapir):
	from iegen import Set,Relation
	from iegen.codegen import Statement,Comment
	import iegen.pycloog as pycloog
	from iegen.pycloog import codegen

	stmts=[]
	stmts.append(Comment('The executor main loop'))

	statement_names=mapir.statements.keys()
	statement_names.sort()

	#True if any statement has a sparse schedule
	sparse_loop=any((mapir.statements[statement_name].sparse_sched is not None for statement_name in statement_names))

	cloog_stmts=[]
	for statement_name in statement_names:
		statement=mapir.statements[statement_name]

		#Approximate any iterators that are equal to a UFS using know range bounds
		cloog_iter_space=statement.iter_space.approximate(mapir.ufs_range_dict())

		#Use approximate with empty sets to remove any UFS equalities in the scattering function
		scatter_fnames=statement.scatter.function_names
		empty_sets=[Set('{[a]}')]*len(scatter_fnames)
		empty_sets_ufs_map=dict(zip(scatter_fnames,empty_sets))
		cloog_scatter=statement.scatter.approximate(empty_sets_ufs_map)

		#Calculate iteration space reduction relations
		orig_iters=','.join(cloog_iter_space.tuple_set)
		reduce_iters=','.join(cloog_iter_space.tuple_set[:-1])
		reduce_iter_space=Relation('{[%s]->[%s]}'%(reduce_iters,orig_iters)).inverse()

		orig_full_iters=','.join(cloog_scatter.tuple_out)
		reduce_full_iters=','.join(cloog_scatter.tuple_out[:-2])
		reduce_full_iter_space=Relation('{[%s]->[%s]}'%(reduce_full_iters,orig_full_iters)).inverse()

		#If the statement has a sparse schedule, reduce the dimensionality of the iteration space and scattering function
		if statement.sparse_sched is not None:
			cloog_iter_space=cloog_iter_space.apply(reduce_iter_space)
			cloog_scatter=reduce_full_iter_space.compose(cloog_scatter)
			cloog_scatter=reduce_iter_space.compose(cloog_scatter.inverse()).inverse()
		elif statement.sparse_sched is None and sparse_loop:
			cloog_scatter=reduce_full_iter_space.compose(cloog_scatter)

		#Create the statement to pass to CLooG using the modified iteration space and scattering function
		cloog_stmts.append(pycloog.Statement(cloog_iter_space,cloog_scatter))

	#Run CLooG, get the result string from CLooG's codegen
	cloog_gen_str=codegen(cloog_stmts)

	#Split the generated code at newlines
	cloog_stmts=cloog_gen_str.split('\n')

	#Create Statement objects for each line of the code generated by CLooG
	for cloog_stmt in cloog_stmts:
		stmts.append(Statement(cloog_stmt))

	return stmts
Exemplo n.º 4
0
	def testPYCLooGSimple(self):
		from iegen.pycloog import Statement,codegen
		from iegen import Set,Relation,Symbolic

		code='''for (i=0;i<=n;i++) {
  for (j=0;j<=m;j++) {
    S1(i,j);
  }
}
for (i=0;i<=n;i++) {
  for (j=0;j<=m;j++) {
    S0(i,j);
  }
}'''

		old_code='''if ((m >= 1) && (n >= 1)) {
  for (i=1;i<=n;i++) {
    for (j=1;j<=m;j++) {
      S1 ;
    }
  }
  for (i=1;i<=n;i++) {
    for (j=1;j<=m;j++) {
      S0 ;
    }
  }
}'''

		old_old_code='''if (m >= 1) {
  for (i=1;i<=n;i++) {
    for (j=1;j<=m;j++) {
      S2 ;
    }
  }
}
if (m >= 1) {
  for (i=1;i<=n;i++) {
    for (j=1;j<=m;j++) {
      S1 ;
    }
  }
}'''

		dom1=Set('{[i,j]:0<=i and i<=n and 0<=j and j<=m}',[Symbolic('n',lower_bound=0),Symbolic('m',lower_bound=0)])
		scat1=Relation('{[i,j]->[p0,i,p1,j,p2]: p0=1 and p1=0 and p2=0}')

		dom2=Set('{[i,j]:0<=i and i<=n and 0<=j and j<=m}',[Symbolic('n',lower_bound=0),Symbolic('m',lower_bound=0)])
		scat2=Relation('{[i,j]->[p0,i,p1,j,p2]: p0=0 and p1=0 and p2=0}')

		stmt1=Statement(dom1,scat1)
		stmt2=Statement(dom2,scat2)
		stmts=(stmt1,stmt2)

		res=codegen(stmts)
		self.failUnless(code==res,'PYCLooG generated:\n\n%s\n\nbut test expected:\n\n%s'%(res,code))
Exemplo n.º 5
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
Exemplo n.º 6
0
	def testPYCLooGNoScattering(self):
		from iegen.pycloog import Statement,codegen
		from iegen import Set,Symbolic

		code='''if (n >= 1) {
  for (i=1;i<=n;i++) {
    for (j=1;j<=n;j++) {
      S0(i,j);
      S1(i,j);
    }
  }
}'''

		old_code='''if (n >= 1) {
  for (i=1;i<=n;i++) {
    for (j=1;j<=n;j++) {
      S0 ;
      S1 ;
    }
  }
}'''

		old_old_code='''for (i=1;i<=n;i++) {
  for (j=1;j<=n;j++) {
    S1 ;
    S2 ;
  }
}'''

		dom1=Set('{[i,j]:1<=i and i<=n and 1<=j and j<=n}',[Symbolic('n',lower_bound=0)])
		dom2=Set('{[i,j]:1<=i and i<=n and 1<=j and j<=n}',[Symbolic('n',lower_bound=0)])

		stmt1=Statement(dom1)
		stmt2=Statement(dom2)
		stmts=(stmt1,stmt2)

		res=codegen(stmts)
		self.failUnless(code==res,'PYCLooG generated:\n\n%s\n\nbut test expected:\n\n%s'%(res,code))
Exemplo n.º 7
0
#!/usr/bin/env python

from iegen import Set,Symbolic
from iegen.pycloog import Statement,codegen

s1_domain=Set('{[k,i,j]: 0<=k and k<=L and 0<=i and i<=M and 0<=j and j<=N}',[Symbolic('L'),Symbolic('M'),Symbolic('N')])
s2_domain=Set('{[k,i,j]: 0<=k and k<=L and 0<=i and i<=M and 0<=j and j<=N}',[Symbolic('L'),Symbolic('M'),Symbolic('N')])

s1=Statement(s1_domain)
s2=Statement(s2_domain)

print codegen([s1,s2])
Exemplo n.º 8
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
Exemplo n.º 9
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