Example #1
0
	def calc_output(self,mapir):
		#input bounds calculated based on full iteration space and the specified iter_seed_space_relation
		input_bounds=mapir.full_iter_space.apply(self.iter_sub_space_relation)

		#output is a tile number, therefore the bounds are from 0 to the number of tiles
		output_bounds=Set('{[tile]: 0<=tile and tile<%s}'%(self.num_tile_name,),symbolics=[mapir.symbolics[self.num_tile_name]])

		#the relation takes the input loop position and iterator and yields a tile number
		input_tuple_vars=[]
		for i in xrange(input_bounds.arity()):
			input_tuple_vars.append('%s_in%d'%(self.grouping_name,i))
		input_tuple=','.join(input_tuple_vars)
		relation=Relation('{[%s]->[t]: t=%s(%s)}'%(input_tuple,self.grouping_name,input_tuple))
		relation=relation.restrict_domain(input_bounds)
		relation=relation.restrict_range(output_bounds)

		#Create a static description of the tiling function (theta) that is the output of the tiling routine
		self.outputs.append(ERSpec(
		    name=self.grouping_name,
		    input_bounds=input_bounds,
		    output_bounds=output_bounds,
		    relation=relation,
		    is_function=True,
		    is_permutation=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])
Example #2
0
	def testSymbolics(self):
		from iegen import Relation,Symbolic

		rel=Relation('{[a,b]->[ap,bp]: a=f(n) and b=foo(a)}',[Symbolic('n')])
		res=['n']

		self.failUnless(res==rel.symbolics(),'%s!=%s'%(res,rel.symbolics()))
Example #3
0
	def testUnionRename(self):
		from iegen import Relation
		from iegen.parser import PresParser

		prelation1=PresParser.parse_relation('{[a]->[ap]:a>10 and ap>20}')
		prelation2=PresParser.parse_relation('{[a]->[ap]:a<5 and ap<10}')
		prelation3=PresParser.parse_relation('{[a]->[ap]:a=7 and ap=14}')
		relation1=Relation('{[a]->[ap]:a>10 and ap>20}')
		relation2=Relation('{[b]->[bp]:b<5 and bp<10}')
		relation3=Relation('{[c]->[cp]:c=7 and cp=14}')
		unioned=relation1.union(relation2).union(relation3)
		unioned_res=Relation(relations=[prelation1,prelation2,prelation3])

		self.failUnless(unioned==unioned_res,'%s!=%s'%(unioned,unioned_res))

		prelation1=PresParser.parse_relation('{[a]->[ap]:a>10 and ap>20}')
		prelation2=PresParser.parse_relation('{[a]->[ap]:a<5 and ap<10}')
		prelation3=PresParser.parse_relation('{[a]->[ap]:a=7 and ap=14}')
		relation1=Relation('{[a]->[ap]:a>10 and ap>20}')
		relation2=Relation('{[b]->[bp]:b<5 and bp<10}')
		relation3=Relation('{[c]->[cp]:c=7 and cp=14}')
		unioned=unioned.union(relation1)
		unioned_res=Relation(relations=[prelation1,prelation2,prelation3])

		self.failUnless(unioned==unioned_res,'%s!=%s'%(unioned,unioned_res))
Example #4
0
	def testVariables(self):
		from iegen import Relation

		rel=Relation('{[a,b]->[ap,bp]: a=ap and b=bp}')
		res=['a','ap','b','bp']

		self.failUnless(res==rel.variables(),'%s!=%s'%(res,rel.variables()))
Example #5
0
	def testFunctions(self):
		from iegen import Relation

		rel=Relation('{[a,b]->[ap,bp]: a=f(b) and b=foo(a)}')
		res=['f','foo']

		self.failUnless(res==rel.functions(),'%s!=%s'%(res,rel.functions()))
Example #6
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
Example #7
0
	def testComposeNonDestructive(self):
		from iegen import Relation

		relation1=Relation('{[a]->[a]}')
		relation2=Relation('{[b]->[b]}')
		composed=relation1.compose(relation2)

		self.failIf(composed is relation1,'%s is %s'%(composed,relation1))
		self.failIf(composed is relation2,'%s is %s'%(composed,relation2))
Example #8
0
	def testUnionNonDestructive(self):
		from iegen import Relation

		relation1=Relation('{[a]->[a]}')
		relation2=Relation('{[b]->[b]}')
		unioned=relation1.union(relation2)

		self.failIf(unioned is relation1,'%s is %s'%(unioned,relation1))
		self.failIf(unioned is relation2,'%s is %s'%(unioned,relation2))
Example #9
0
	def testGetFormulaRenameDict(self):
		from iegen import Relation

		relation1=Relation('{[a_1,b_1]->[ap_1,bp_1]:1<=a_1 and a_1<=10}')
		relation2=Relation('{[b,c]->[bp,cp]}')
		rename=relation1._get_formula_rename_dict(relation1.relations[0],relation2.relations[0])
		rename_res={'a_1':'b','b_1':'c','ap_1':'bp','bp_1':'cp'}

		self.failUnless(rename==rename_res,'%s!=%s'%(rename,rename_res))
Example #10
0
	def testComposeSameObject(self):
		from iegen import Relation

		rel=Relation('{[a]->[a]}')
		composed=rel.compose(rel)

		composed_res=Relation('{[a2]->[a01]: a2=a01}')

		self.failUnless(composed==composed_res,'%s!=%s'%(composed,composed_res))
Example #11
0
	def testGetPrefixUnrenameDict(self):
		from iegen import Relation

		relation=Relation('{[a,b]->[c,d,e]:1<=a and a<=10}')

		unrename=relation._get_prefix_unrename_dict(relation.relations[0],'pre')
		unrename_res={'pre_in_a':'a','pre_in_b':'b','pre_out_c':'c','pre_out_d':'d','pre_out_e':'e'}

		self.failUnless(unrename==unrename_res,'%s!=%s'%(unrename,unrename_res))
Example #12
0
	def testInverseConstraints(self):
		from iegen import Relation
		from iegen.parser import PresParser

		relation=Relation('{[a,b]->[c,d]:a>=n && b<5 and c+d=15}')
		prelation=PresParser.parse_relation('{[c,d]->[a,b]:b<5 and a>=n && c+d=15}')

		inverse=relation.inverse()
		inverse_res=Relation(relations=[prelation])

		self.failUnless(inverse==inverse_res,'%s!=%s'%(inverse,inverse_res))
Example #13
0
	def testInverse(self):
		from iegen import Relation
		from iegen.parser import PresParser

		relation=Relation('{[a,b]->[c,d]}')
		prelation=PresParser.parse_relation('{[c,d]->[a,b]}')

		inverse=relation.inverse()
		inverse_res=Relation(relations=[prelation])

		self.failUnless(inverse==inverse_res,'%s!=%s'%(inverse,inverse_res))
Example #14
0
	def testComposeEquality(self):
		from iegen import Relation

		relation1=Relation('{[a,b]->[c]:c=a}')
		relation2=Relation('{[d]->[e,f]:e=d and f=d}')

		composed=relation1.compose(relation2)

		composed_res=Relation('{[d]->[c]: d=c}')

		self.failUnless(composed==composed_res,'%s!=%s'%(composed,composed_res))
Example #15
0
	def testCompose(self):
		from iegen import Relation

		relation1=Relation('{[a,b]->[c]:1<=a and a<=10 and 1<=b and b<=10}')
		relation2=Relation('{[d]->[e,f]:-10<=d and d<=0}')

		composed=relation1.compose(relation2)

		composed_res=Relation('{[d]->[c]: -10<=d and d<=0}')

		self.failUnless(composed==composed_res,'%s!=%s'%(composed,composed_res))
Example #16
0
	def testComposeRenameBack(self):
		from iegen import Relation

		relation1=Relation('{[a]->[b,c]: a=6 and b=7 and c>10}')
		relation2=Relation('{[i,j]->[k]: i>0 and j<-5 and k>3}')

		composed=relation1.compose(relation2)

		composed_res=Relation('{[i,j]->[b,c]: i>0 and j<-5 and b=7 and c>10}')

		self.failUnless(composed==composed_res,'%s!=%s'%(composed,composed_res))
Example #17
0
	def testComposeNoRenameBack(self):
		from iegen import Relation

		relation1=Relation('{[a]->[b,c]: a=b and b=7 and c>10}')
		relation2=Relation('{[b,i]->[k]: i>0 and b<-5 and k>3 and b=k}')

		composed=relation1.compose(relation2)

		composed_res=Relation('{[b2,i2]->[b1,c1]: i2>0 and b2<-5 and b2>=4 and b1=7 and c1>10 and b2=b1}')

		self.failUnless(composed==composed_res,'%s!=%s'%(composed,composed_res))
Example #18
0
	def testInOutMapping(self):
		from iegen import Relation

		relation1=Relation('{[i]->[j]: j=f(i)}')
		relation2=Relation('{[a]->[a]}')

		composed=relation1.compose(relation2)

		composed_res=Relation('{[a]->[j]: j=f(a)}')

		self.failUnless(composed==composed_res,'%s!=%s'%(composed,composed_res))
Example #19
0
	def testComposeRename1(self):
		from iegen import Relation

		relation1=Relation('{[a,b]->[c]:1<=a and a<=10 and 1<=b and b<=10}')
		relation2=Relation('{[a]->[b,c]:-10<=a and a<=0}')

		composed=relation1.compose(relation2)

		composed_res=Relation('{[a2]->[c1]: -1a2>=0 and a2+10>=0}')

		self.failUnless(composed==composed_res,'%s!=%s'%(composed,composed_res))
Example #20
0
	def testComposeRealUnion(self):
		from iegen import Relation

		ar=Relation('{[ii,s]->[ar_out]:s=1 and ar_out=inter(ii)}').union(Relation('{[ii,s]->[ar_out]:s=2 and ar_out=inter(ii)}')).union(Relation('{[ii,s]->[ar_out]:s=3 and ar_out=inter(ii)}'))
		data_reordering=Relation('{[k]->[dr_out]:dr_out=sigma(k)}')

		ar_composed=data_reordering.compose(ar)

		ar_res=Relation('{[ii,s]->[dr_out]:s=1 and dr_out=sigma(inter(ii))}').union(Relation('{[ii,s]->[dr_out]:s=2 and dr_out=sigma(inter(ii))}')).union(Relation('{[ii,s]->[dr_out]:s=3 and dr_out=sigma(inter(ii))}'))

		self.failUnless(ar_composed==ar_res,'%s!=%s'%(ar_composed,ar_res))
Example #21
0
	def testComposeRename3(self):
		from iegen import Relation

		relation1=Relation('{[a,b]->[a]:1<=a and a<=10 and 1<=b and b<=10}')
		relation2=Relation('{[a]->[a,b]:-10<=a and a<=0 and b=5}')

		composed=relation1.compose(relation2)

		composed_res=Relation('{[a2]->[a01]: a2<=10 and a2<=0 and a2>=1 and a2>=-10 and a2=a01}')

		self.failUnless(composed==composed_res,'%s!=%s'%(composed,composed_res))
Example #22
0
	def testComposeRename2(self):
		from iegen import Relation

		relation1=Relation('{[a,b]->[b]:1<=a and a<=11 and 1<=b and b<=10}')
		relation2=Relation('{[a]->[a,b]:-10<=a and a<=0 and b=5}')

		composed=relation1.compose(relation2)

		composed_res=Relation('{[a2]->[b01]: a2+-1>=0 and -1a2>=0 and a2+10>=0 and -1a2+11>=0 and -1b01+5=0}')

		self.failUnless(composed==composed_res,'%s!=%s'%(composed,composed_res))
Example #23
0
	def testArity(self):
		from iegen import Relation
		from iegen.util import lower_gen
		from string import lowercase

		for size_in in xrange(10):
			for size_out in xrange(10):
				var_tuple_in=lowercase[:size_in]
				var_tuple_in='['+','.join(var_tuple_in)+']'
				var_tuple_out=[var+'p' for var in lowercase[:size_out]]
				var_tuple_out='['+','.join(var_tuple_out)+']'
				relation=Relation('{'+var_tuple_in+'->'+var_tuple_out+'}')
				self.failUnless(relation.arity_in()==size_in,"Input arity of '%s'!=%d"%(relation,size_in))
				self.failUnless(relation.arity_out()==size_out,"Output arity of '%s'!=%d"%(relation,size_out))
				self.failUnless(relation.arity()==(size_in,size_out),"Inpyut/Output arity of '%s'!=%s"%(relation,(size_in,size_out)))
Example #24
0
	def testUnion(self):
		from iegen import Relation
		from iegen.parser import PresParser

		prelation1=PresParser.parse_relation('{[a]->[a]:a>10}')
		prelation2=PresParser.parse_relation('{[b]->[b]:b>11}')
		relation1=Relation('{[a]->[a]:a>10}')
		relation2=Relation('{[b]->[b]:b>11}')
		unioned=relation1.union(relation2)
		unioned_res=Relation(relations=[prelation1,prelation2])

		self.failUnless(unioned==unioned_res,'%s!=%s'%(unioned,unioned_res))

		prelation1=PresParser.parse_relation('{[a]->[a]:a>10}')
		prelation2=PresParser.parse_relation('{[b]->[b]:b>11}')
		prelation3=PresParser.parse_relation('{[b]->[b]:b>11}')
		relation1=Relation('{[a]->[a]:a>10}')
		relation2=Relation('{[b]->[b]:b>11}')
		unioned=unioned.union(relation1)
		unioned_res=Relation(relations=[prelation1,prelation2,prelation3])

		self.failUnless(unioned==unioned_res,'%s!=%s'%(unioned,unioned_res))
Example #25
0
	def __init__(self,name,reordering_name,data_arrays,iter_sub_space_relation,target_data_arrays,erg_func_name):
		Transformation.__init__(self,name)
		self.reordering_name=reordering_name
		self.data_arrays=data_arrays
		self.iter_sub_space_relation=iter_sub_space_relation
		self.target_data_arrays=target_data_arrays
		self.erg_func_name=erg_func_name

		#Calculate the data reordering relation
		self._data_reordering=Relation('{[%s_in]->[%s_out]: %s_out=%s(%s_in)}'%(5*(self.reordering_name,)))

		#Make sure the target data arrays all have the same bounds
		#We do this by unioning all bounds and simply checking that there is a single conjunction in the disjunction
		target_bounds=[data_array.bounds for data_array in self.target_data_arrays]
		unioned_bounds=reduce(lambda da1,da2: da1.union(da2),target_bounds)
		if len(unioned_bounds)!=1:
			raise ValueError('All target data arrays must have the same bounds')
Example #26
0
def ar_testing():
	a4_0=Relation('{[s_out1,j]->[k]: k+-1inter1(j)=0}')

	#### DataPermuteTrans
	R_x0_x1 = Relation("{[sigma_in] -> [sigma_out] : sigma_out = sigma(sigma_in)}")

	a4_1 =  R_x0_x1.compose(a4_0)

	#### Loop Alignment
	T_I0_to_I1 = Relation('{[s,i] -> [s,j]: j=sigma(i)}')

	a4_2 =  a4_1.compose( T_I0_to_I1.inverse() )

	#### IterPermuteTrans
	T_I1_to_I2 = Relation("{[s,ii]->[s,j]: j = delta(ii) }")

	a4_3 =  a4_2.compose( T_I1_to_I2.inverse() )

	print a4_3
Example #27
0
def ar_working():
	a4_0=Relation('{[c0,s_out1,c1,j,c2]->[k]: c0=0 and c2=0 and k+-1inter1(j)=0 and -1c1+1=0}')

	#### DataPermuteTrans
	R_x0_x1 = Relation("{[sigma_in] -> [sigma_out] : sigma_out = sigma(sigma_in)}")

	a4_1 =  R_x0_x1.compose(a4_0)

	#### Loop Alignment
	T_I0_to_I1 = Relation('{[c0, s, c0, i, c0] -> [c0, s, c0, j, c0] : c0=0 && j=sigma(i)}').union( Relation('{[c0, s, c1, ii, x] -> [c0, s, c1, ii, x] : c0=0 && c1=1}') )

	a4_2 =  a4_1.compose( T_I0_to_I1.inverse() )

	#### IterPermuteTrans
	T_I1_to_I2 = Relation("{[c0,s1,c1,i,c2] -> [c3,s2,c4,j,c5] : s1=s2 && c0=0 && c1=0 && c2=0 && c3=0 && c4=0 && c5=0 && i=j}").union( Relation("{[c6,s3,c7,ii,x] -> [c8,s4,c9,j,y] : s3=s4 && j = delta(ii) && c6=0 && c8=0 && c7=1 && c9=1 && x=y }"))

	a4_3 =  a4_2.compose( T_I1_to_I2.inverse() )

	print a4_3
Example #28
0
class DataPermuteTrans(Transformation):
	__slots__=('reordering_name','_data_reordering','data_arrays','iter_sub_space_relation','target_data_arrays','erg_func_name')
	_relation_fields=('iter_sub_space_relation',)
	_data_arrays_fields=('data_arrays','target_data_arrays')

	def __init__(self,name,reordering_name,data_arrays,iter_sub_space_relation,target_data_arrays,erg_func_name):
		Transformation.__init__(self,name)
		self.reordering_name=reordering_name
		self.data_arrays=data_arrays
		self.iter_sub_space_relation=iter_sub_space_relation
		self.target_data_arrays=target_data_arrays
		self.erg_func_name=erg_func_name

		#Calculate the data reordering relation
		self._data_reordering=Relation('{[%s_in]->[%s_out]: %s_out=%s(%s_in)}'%(5*(self.reordering_name,)))

		#Make sure the target data arrays all have the same bounds
		#We do this by unioning all bounds and simply checking that there is a single conjunction in the disjunction
		target_bounds=[data_array.bounds for data_array in self.target_data_arrays]
		unioned_bounds=reduce(lambda da1,da2: da1.union(da2),target_bounds)
		if len(unioned_bounds)!=1:
			raise ValueError('All target data arrays must have the same bounds')

	def __repr__(self):
		return 'DataPermuteTrans(%s,%s,%s,%s,%s)'%(self.data_reordering,self.data_arrays,self.iter_sub_space_relation,self.target_data_arrays,self.erg_func_name)

	def __str__(self):
		return self._get_string(0)

	def _get_string(self,indent):
		if indent>0: indent+=1
		spaces=' '*indent

		inputs_string=StringIO()
		if len(self.inputs)>0:
			for input in self.inputs:
				print >>inputs_string,input._get_string(indent+5)
		inputs_string=inputs_string.getvalue()[:-1]
		if len(inputs_string)>0: inputs_string='\n'+inputs_string

		outputs_string=StringIO()
		if len(self.outputs)>0:
			for output in self.outputs:
				print >>outputs_string,output._get_string(indent+5)
		outputs_string=outputs_string.getvalue()[:-1]
		if len(outputs_string)>0: outputs_string='\n'+outputs_string

		data_arrays_string=StringIO()
		if len(self.data_arrays)>0:
			for data_array in self.data_arrays:
				print >>data_arrays_string,data_array._get_string(indent+13)
		data_arrays_string=data_arrays_string.getvalue()[:-1]
		if len(data_arrays_string)>0: data_arrays_string='\n'+data_arrays_string

		target_data_arrays_string=StringIO()
		if len(self.target_data_arrays)>0:
			for data_array in self.target_data_arrays:
				print >>target_data_arrays_string,data_array._get_string(indent+13)
		target_data_arrays_string=target_data_arrays_string.getvalue()[:-1]
		if len(target_data_arrays_string)>0: target_data_arrays_string='\n'+target_data_arrays_string

		return '''%sDataPermuteTrans:
%s|-name: %s
%s|-inputs: %s
%s|-outputs: %s
%s|-reordering_name: %s
%s|-_data_reordering: %s
%s|-data_arrays: %s
%s|-iter_sub_space_relation: %s
%s|-target_data_arrays:
%s
%s|-erg_func_name: %s'''%(spaces,spaces,self.name,
    spaces,inputs_string,
    spaces,outputs_string,
    spaces,self.reordering_name,
    spaces,self._data_reordering,
    spaces,data_arrays_string,
    spaces,self.iter_sub_space_relation,
    spaces,target_data_arrays_string,
    spaces,self.erg_func_name)

	#Calculate a specification for the explicit relation that is input to
	# the data reordering algorithm.
	#This input is a relation from the iteration sub space to the
	# the target data space.
	def calc_input(self,mapir):
		#Iteration Sub Space Relation
		issr=self.iter_sub_space_relation

		#Calculate the full iteration space to data space relation
		#Collect all iter_to_data relations in all access relations
		access_relations=[ar.iter_to_data for stmt in mapir.get_statements() for ar in stmt.get_access_relations() if set()!=set([ar.data_array]).intersection(set(self.target_data_arrays))]

		#Union all the relations that were collected into a single relation
		iter_to_data=reduce(lambda form1,form2: form1.union(form2),access_relations)

		#Compose the unioned access relation with the iteration subspace
		# relation to remove conjunctions we are not interested in
		iter_to_data=self.iter_sub_space_relation.compose(iter_to_data.inverse()).inverse()

		#Create the ERSpec for the relation that is input to the reordering
		self.inputs.append(ERSpec(
		    name='%s_input'%(self.name),
		    input_bounds=mapir.full_iter_space.apply(self.iter_sub_space_relation),
		    output_bounds=self.target_data_arrays[0].bounds.copy(),
		    relation=iter_to_data,
		    is_function=True,
		    er_type='er_u1d'))

		print 'In DataPermuteTrans, input type %s.is_er_u1d()=%s'%(self.inputs[-1].get_var_name(),self.inputs[-1].is_er_u1d())

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

		self.print_progress("Calculated input ERSpec '%s' for transformation '%s'..."%(self.inputs[0].name,self.name))

		self.print_detail(self.inputs[0])

	#Calculate a specification for the explicit relation that is the
	# output of this data reordering.
	#This relation is a permutation of the original data space, permuted
	# based on the heuristics of the reordering algorithm.
	def calc_output(self,mapir):

		#Need to create a static description of the output of the reordering
		self.outputs.append(ERSpec(
		    name=self.reordering_name,
		    input_bounds=self.target_data_arrays[0].bounds.copy(),
		    output_bounds=self.target_data_arrays[0].bounds.copy(),
		    relation=self._data_reordering.copy(),
		    is_permutation=True))

		#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])

	#Update the MapIR based on this transformation
	def update_mapir(self,mapir):
		#Data spaces are not changed
		#Scattering functions are not changed

		#Update the access relations of all statements that access
		# the reordered data array(s)
		self.print_progress('Updating access relations...')
		for statement in mapir.get_statements():
			for access_relation in statement.get_access_relations():
				if access_relation.data_array in self.data_arrays:
					access_relation.iter_to_data=self._data_reordering.compose(access_relation.iter_to_data)

	#Update the idg based on this transformation
	def update_idg(self,mapir):
		#Add the ERG call node to the IDG
		erg_call_node=mapir.idg.get_node(IDGCall,calc_erg_call(self.name,self.erg_func_name,self.inputs,self.outputs))

		#Collection of reorder call nodes
		reorder_call_nodes=[]

		#Add the input ERSpecs to the IDG
		for input_er_spec in self.inputs:
			#Get a node for the ERSpec
			input_er_spec_node=mapir.idg.get_node(IDGERSpec,input_er_spec)

			#Get a gen node for the ERSpec
			gen_input_er_spec_node=mapir.idg.get_node(IDGGenERSpec,input_er_spec)

			#Add dependence of the GenERSpec node to ERSpec node
			input_er_spec_node.add_dep(gen_input_er_spec_node)

			#Add dependence of the call to the input
			erg_call_node.add_dep(input_er_spec_node)

			#Add reorder call nodes for each data array to be reordered
			for data_array in self.data_arrays:
				#Build the list of arguments to the function call
				#Add the reorder call node for this data array to the IDG
				reorder_call_node=mapir.idg.get_node(IDGCall,calc_reorder_call(self.name,data_array,self.reordering_name,mapir))

				#Add the reorder call node to the collection of reorder call nodes
				reorder_call_nodes.append(reorder_call_node)

				#Get the data array node before the reordering
				before_data_array_node=mapir.idg.get_node(IDGDataArray,VersionedDataArray(data_array))

				#Add the dependence of the reorder call on the before data array
				reorder_call_node.add_dep(before_data_array_node)

				#Get the data array node after the reordering
				after_data_array_node=mapir.idg.get_node(IDGDataArray,VersionedDataArray(data_array))

				#Add the dependence of the after data array node on the reorder call
				after_data_array_node.add_dep(reorder_call_node)

		#Add the output ERSpecs to the IDG
		for output_er_spec in self.outputs:
			#Get a node for the ERSpec
			output_er_spec_node=mapir.idg.get_node(IDGOutputERSpec,output_er_spec)

			#Add dependence of the output on the call
			output_er_spec_node.add_dep(erg_call_node)

			#Add dependences of the reorder calls on the output
			for reorder_call_node in reorder_call_nodes:
				reorder_call_node.add_dep(output_er_spec_node)
Example #29
0
#from iegen import IEGenObject
## None corresponds to stdout
#IEGenObject.settings.outputs['debug'].append(None)

##### Compose scheduling/scattering function for each statement
##### with the statement's original iteration space.
#iegen.simplify.registerInversePairs()

syms = [Symbolic("N"),Symbolic("T"), Symbolic("n_inter")]

# S1
print "==== S1"
S1_I = Set("{[s,i]: 0<=s && s<T && 0<=i && i<N}", syms)
print S1_I

S1_sched = Relation("{[s,i]->[c0,s,c1,j,c2]: c0=0 && c1=0 && c2=0 && i=j}")
#print S1_sched
#PrettyPrintVisitor().visit(S1_sched)


S1_full_I = S1_I.apply(S1_sched)
print S1_full_I

# S2
print "==== S2"
S2_I = Set("{[s,i]: 0<=s && s<T && 0<=i && i<n_inter}", syms)
print S2_I

S2_sched = Relation("{[s,i]->[c0,s,c1,j,c2]: c0=0 && c1=1 && c2=0 && i=j}")
#print S2_sched
#PrettyPrintVisitor().visit(S2_sched)
Example #30
0
#
# Turned out this was another un-renaming bug.  Issue #124 is now fixed.

import iegen
from iegen import Set
from iegen import Relation
from iegen import Symbolic

import iegen.simplify
iegen.simplify.register_inverse_pair('delta','delta_inv')

from iegen.ast.visitor import PrettyPrintVisitor



D_1_2 = Relation("{[c0,s,c1,i,c2] -> [c0,s,c3,ii,c2] : i = inter1(ii) && c1=0 && c2=0 && c0=0 && c3=1}")
D_1_2 = D_1_2.union(Relation("{[c0,s,c1,i,c2] -> [c0,s,c3,ii,c2] : i = inter2(ii) && c1=0 && c2=0 && c0=0 && c3=1}"))
print
print "D_1_2 = ", D_1_2
PrettyPrintVisitor().visit(D_1_2)
D_1_3 = D_1_2


print
T_I0_to_I1 = Relation('{[c0, s, c0, i, c0] -> [c0, s, c0, j, c0] : c0=0 && j=sigma(i)}')
T_I0_to_I1 = T_I0_to_I1.union( Relation('{[c0, s, c1, ii, x] -> [c0, s, c1, ii, x] : c0=0 && c1=1}') )
print "\tT_I0_to_I1 = "
PrettyPrintVisitor().visit(T_I0_to_I1)
print
T_I1_to_I2 = Relation("{[c0,s,c0,i,c0] -> [c0,s,c0,i,c0] : c0=0 }")
T_I1_to_I2 = T_I1_to_I2.union( Relation("{[c0,s,c1,ii,x] -> [c7,s,c8,j,x] : j = delta(ii) && c0=0  && c1=1 }"))