def get_parfor_array_accesses(parfor, func_ir, typemap, accesses=None): if accesses is None: accesses = set() blocks = wrap_parfor_blocks(parfor) accesses = _get_array_accesses(blocks, func_ir, typemap, accesses) unwrap_parfor_blocks(parfor) return accesses
def update_node_definitions(nodes, definitions): for inst in nodes: if isinstance(inst, ir.Assign): definitions[inst.target.name].append(inst.value) if isinstance(inst, numba.parfor.Parfor): parfor_blocks = wrap_parfor_blocks(inst) get_definitions(parfor_blocks, definitions) unwrap_parfor_blocks(inst)
def _analyze_parfor(self, parfor, array_dists, parfor_dists): if parfor.id not in parfor_dists: parfor_dists[parfor.id] = Distribution.OneD # analyze init block first to see array definitions self._analyze_block(parfor.init_block, array_dists, parfor_dists) out_dist = Distribution.OneD if self.in_parallel_parfor != -1: out_dist = Distribution.REP parfor_arrs = set() # arrays this parfor accesses in parallel array_accesses = ir_utils.get_array_accesses(parfor.loop_body) par_index_var = parfor.loop_nests[0].index_variable.name #stencil_accesses, _ = get_stencil_accesses(parfor, self.typemap) for (arr, index) in array_accesses: if index == par_index_var: #or index in stencil_accesses: parfor_arrs.add(arr) self._parallel_accesses.add((arr, index)) # multi-dim case tup_list = guard(find_build_tuple, self.func_ir, index) if tup_list is not None: index_tuple = [var.name for var in tup_list] if index_tuple[0] == par_index_var: parfor_arrs.add(arr) self._parallel_accesses.add((arr, index)) if par_index_var in index_tuple[1:]: out_dist = Distribution.REP # TODO: check for index dependency for arr in parfor_arrs: if arr in array_dists: out_dist = Distribution( min(out_dist.value, array_dists[arr].value)) parfor_dists[parfor.id] = out_dist for arr in parfor_arrs: if arr in array_dists: array_dists[arr] = out_dist # TODO: find prange actually coming from user # for pattern in parfor.patterns: # if pattern[0] == 'prange' and not self.in_parallel_parfor: # parfor_dists[parfor.id] = Distribution.OneD # run analysis recursively on parfor body if self.second_pass and out_dist in [ Distribution.OneD, Distribution.OneD_Var ]: self.in_parallel_parfor = parfor.id blocks = wrap_parfor_blocks(parfor) for b in blocks.values(): self._analyze_block(b, array_dists, parfor_dists) unwrap_parfor_blocks(parfor) if self.in_parallel_parfor == parfor.id: self.in_parallel_parfor = -1 return
def get_definitions(blocks, definitions=None): if definitions is None: definitions = collections.defaultdict(list) for block in blocks.values(): for inst in block.body: if isinstance(inst, ir.Assign): definitions[inst.target.name].append(inst.value) if isinstance(inst, numba.parfor.Parfor): parfor_blocks = wrap_parfor_blocks(inst) get_definitions(parfor_blocks, definitions) unwrap_parfor_blocks(inst) return definitions
def _analyze_parfor(self, parfor, array_dists, parfor_dists): if parfor.id not in parfor_dists: parfor_dists[parfor.id] = Distribution.OneD # analyze init block first to see array definitions self._analyze_block(parfor.init_block, array_dists, parfor_dists) out_dist = Distribution.OneD if self.in_parallel_parfor: out_dist = Distribution.REP parfor_arrs = set() # arrays this parfor accesses in parallel array_accesses = ir_utils.get_array_accesses(parfor.loop_body) par_index_var = parfor.loop_nests[0].index_variable.name stencil_accesses, _ = get_stencil_accesses(parfor, self.typemap) for (arr, index) in array_accesses: if index == par_index_var or index in stencil_accesses: parfor_arrs.add(arr) self._parallel_accesses.add((arr, index)) if index in self._tuple_table: index_tuple = [(var.name if isinstance(var, ir.Var) else var) for var in self._tuple_table[index]] if index_tuple[0] == par_index_var: parfor_arrs.add(arr) self._parallel_accesses.add((arr, index)) if par_index_var in index_tuple[1:]: out_dist = Distribution.REP # TODO: check for index dependency for arr in parfor_arrs: if arr in array_dists: out_dist = Distribution( min(out_dist.value, array_dists[arr].value)) parfor_dists[parfor.id] = out_dist for arr in parfor_arrs: if arr in array_dists: array_dists[arr] = out_dist # TODO: find prange actually coming from user # for pattern in parfor.patterns: # if pattern[0] == 'prange' and not self.in_parallel_parfor: # parfor_dists[parfor.id] = Distribution.OneD # run analysis recursively on parfor body if self.second_pass and out_dist == Distribution.OneD: self.in_parallel_parfor = True blocks = wrap_parfor_blocks(parfor) for b in blocks.values(): self._analyze_block(b, array_dists, parfor_dists) unwrap_parfor_blocks(parfor) self.in_parallel_parfor = False return
def _analyze_parfor(self, parfor, array_dists, parfor_dists): if parfor.id not in parfor_dists: parfor_dists[parfor.id] = Distribution.OneD # analyze init block first to see array definitions self._analyze_block(parfor.init_block, array_dists, parfor_dists) out_dist = Distribution.OneD parfor_arrs = set() # arrays this parfor accesses in parallel array_accesses = ir_utils.get_array_accesses(parfor.loop_body) par_index_var = parfor.loop_nests[0].index_variable.name stencil_accesses, _ = get_stencil_accesses(parfor.loop_body, par_index_var) for (arr, index) in array_accesses: if index == par_index_var or index in stencil_accesses: parfor_arrs.add(arr) self._parallel_accesses.add((arr, index)) if index in self._tuple_table: index_tuple = [(var.name if isinstance(var, ir.Var) else var) for var in self._tuple_table[index]] if index_tuple[0] == par_index_var: parfor_arrs.add(arr) self._parallel_accesses.add((arr, index)) if par_index_var in index_tuple[1:]: out_dist = Distribution.REP # TODO: check for index dependency for arr in parfor_arrs: if arr in array_dists: out_dist = Distribution( min(out_dist.value, array_dists[arr].value)) parfor_dists[parfor.id] = out_dist for arr in parfor_arrs: if arr in array_dists: array_dists[arr] = out_dist # run analysis recursively on parfor body blocks = wrap_parfor_blocks(parfor) for b in blocks.values(): self._analyze_block(b, array_dists, parfor_dists) unwrap_parfor_blocks(parfor) return