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