def gen_for(self, node, target, local_iter, local_iter_decl, loop_body): """ Create For representation on iterator for Cxx generation. Examples -------- >> "omp parallel for" >> for i in xrange(10): >> ... do things ... Becomes >> "omp parallel for shared(__iterX)" >> for(decltype(__iterX)::iterator __targetX = __iterX.begin(); __targetX < __iterX.end(); ++__targetX) >> typename decltype(__targetX)::reference i = *__targetX; >> ... do things ... It the case of not local variable, typing for `i` disappear and typing is removed for iterator in case of yields statement in function. """ # Choose target variable for iterator (which is iterator type) local_target = "__target{0}".format(len(self.break_handlers)) local_target_decl = NamedType( "typename decltype({0})::iterator".format(local_iter)) # For yield function, all variables are globals. if self.yields: self.extra_declarations.append(( local_target, local_target_decl, )) local_target_decl = "" # If variable is local to the for body it's a ref to the iterator value # type if node.target.id in self.scope[node] and not self.yields: self.ldecls = {d for d in self.ldecls if d.id != node.target.id} local_type = "typename decltype({})::reference ".format( local_target) else: local_type = "" # Assign iterable value loop_body_prelude = Statement("{} {}= *{}".format( local_type, target, local_target)) # Create the loop loop = For( "{0} {1} = {2}.begin()".format(local_target_decl, local_target, local_iter), "{0} < {1}.end()".format(local_target, local_iter), "++{0}".format(local_target), Block([loop_body_prelude, loop_body])) return [self.process_omp_attachements(node, loop)]
def gen_for(self, node, target, local_iter, local_iter_decl, loop_body): """ Create For representation on iterator for Cxx generation. Examples -------- >> "omp parallel for" >> for i in range(10): >> ... do things ... Becomes >> "omp parallel for shared(__iterX)" >> for(decltype(__iterX)::iterator __targetX = __iterX.begin(); __targetX < __iterX.end(); ++__targetX) >> auto&& i = *__targetX; >> ... do things ... It the case of not local variable, typing for `i` disappear and typing is removed for iterator in case of yields statement in function. """ # Choose target variable for iterator (which is iterator type) local_target = "__target{0}".format(id(node)) local_target_decl = self.types.builder.IteratorOfType(local_iter_decl) islocal = (node.target.id not in self.openmp_deps and node.target.id in self.scope[node] and not hasattr(self, 'yields')) # If variable is local to the for body it's a ref to the iterator value # type if islocal: local_type = "auto&&" self.ldecls.remove(node.target.id) else: local_type = "" # Assign iterable value loop_body_prelude = Statement("{} {}= *{}".format(local_type, target, local_target)) # Create the loop assign = self.make_assign(local_target_decl, local_target, local_iter) loop = For("{}.begin()".format(assign), "{0} < {1}.end()".format(local_target, local_iter), "++{0}".format(local_target), Block([loop_body_prelude, loop_body])) return [self.process_omp_attachements(node, loop)]
def gen_c_for(self, node, local_iter, loop_body): """ Create C For representation for Cxx generation. Examples -------- >> for i in xrange(10): >> ... do things ... Becomes >> for(long i = 0, __targetX = 10; i < __targetX; i += 1) >> ... do things ... Or >> for i in xrange(10, 0, -1): >> ... do things ... Becomes >> for(long i = 10, __targetX = 0; i > __targetX; i += -1) >> ... do things ... It the case of not local variable, typing for `i` disappear """ args = node.iter.args step = "1L" if len(args) <= 2 else self.visit(args[2]) if len(args) == 1: lower_bound = "0L" upper_value = self.visit(args[0]) else: lower_bound = self.visit(args[0]) upper_value = self.visit(args[1]) upper_bound = "__target{0}".format(id(node)) upper_type = iter_type = "long " # If variable is local to the for body keep it local... if node.target.id in self.scope[node] and not hasattr(self, 'yields'): self.ldecls.remove(node.target.id) loop = list() else: # For yield function, upper_bound is globals. iter_type = "" # Back one step to keep Python behavior (except for break) loop = [ If("{} == {}".format(local_iter, upper_bound), Statement("{} -= {}".format(local_iter, step))) ] comparison = self.handle_real_loop_comparison(args, loop, local_iter, upper_bound, step) forloop = For("{0} {1}={2}".format(iter_type, local_iter, lower_bound), comparison, "{0} += {1}".format(local_iter, step), loop_body) loop.insert(0, self.process_omp_attachements(node, forloop)) # Store upper bound value assgnt = self.make_assign(upper_type, upper_bound, upper_value) header = [Statement(assgnt)] return header, loop
def gen_c_for(self, node, local_iter, loop_body): """ Create C For representation for Cxx generation. Examples -------- >> for i in xrange(10): >> ... do things ... Becomes >> for(long i = 0, __targetX = 10; i < __targetX; i += 1) >> ... do things ... Or >> for i in xrange(10, 0, -1): >> ... do things ... Becomes >> for(long i = 10, __targetX = 0; i > __targetX; i += -1) >> ... do things ... Or >> for i in xrange(a, b, c): >> ... do things ... Becomes >> std::function<bool(int, int)> __cmpX = std::less<long>(); >> if(c < 0) >> __cmpX = std::greater<long>(); >> for(long i = a, __targetX = b; __cmpX(i, __targetX); i += c) >> ... do things ... It the case of not local variable, typing for `i` disappear """ args = node.iter.args step = "1L" if len(args) <= 2 else self.visit(args[2]) if len(args) == 1: lower_bound = "0L" upper_value = self.visit(args[0]) else: lower_bound = self.visit(args[0]) upper_value = self.visit(args[1]) upper_bound = "__target{0}".format(len(self.break_handlers)) upper_type = iter_type = "long " # If variable is local to the for body keep it local... if node.target.id in self.scope[node] and not self.yields: self.ldecls = {d for d in self.ldecls if d.id != node.target.id} loop = list() else: # For yield function, upper_bound is globals. if self.yields: self.extra_declarations.append((upper_bound, upper_type)) upper_type = "" iter_type = "" # Back one step to keep Python behavior (except for break) loop = [ If("{} == {}".format(local_iter, upper_bound), Statement("{} -= {}".format(local_iter, step))) ] comparison, for_pos = self.handle_real_loop_comparison( args, loop, local_iter, upper_bound, step) forloop = For( "{0} {1} = {2}".format(iter_type, local_iter, lower_bound), comparison, "{0} += {1}".format(local_iter, step), loop_body) loop.insert(for_pos, self.process_omp_attachements(node, forloop)) # Store upper bound value header = [ Statement("{0} {1} = {2}".format(upper_type, upper_bound, upper_value)) ] return header, loop