def run(self, state): """ Run the defined pipelines on the state. """ from numba.core.compiler import _EarlyPipelineCompletion if not self.finalized: raise RuntimeError("Cannot run non-finalised pipeline") # walk the passes and run them for idx, (pss, pass_desc) in enumerate(self.passes): try: event("-- %s" % pass_desc) pass_inst = _pass_registry.get(pss).pass_inst if isinstance(pass_inst, CompilerPass): self._runPass(idx, pass_inst, state) else: raise BaseException("Legacy pass in use") except _EarlyPipelineCompletion as e: raise e except Exception as e: if (utils.use_new_style_errors() and not isinstance(e, errors.NumbaError)): raise e msg = "Failed in %s mode pipeline (step: %s)" % \ (self.pipeline_name, pass_desc) patched_exception = self._patch_error(msg, e) raise patched_exception
def get_call_type(self, context, args, kws): prefer_lit = [True, False] # old behavior preferring literal prefer_not = [False, True] # new behavior preferring non-literal failures = _ResolutionFailures(context, self, args, kws, depth=self._depth) # get the order in which to try templates from numba.core.target_extension import get_local_target # circular target_hw = get_local_target(context) order = utils.order_by_target_specificity(target_hw, self.templates, fnkey=self.key[0]) self._depth += 1 for temp_cls in order: temp = temp_cls(context) # The template can override the default and prefer literal args choice = prefer_lit if temp.prefer_literal else prefer_not for uselit in choice: try: if uselit: sig = temp.apply(args, kws) else: nolitargs = tuple([_unlit_non_poison(a) for a in args]) nolitkws = { k: _unlit_non_poison(v) for k, v in kws.items() } sig = temp.apply(nolitargs, nolitkws) except Exception as e: if (utils.use_new_style_errors() and not isinstance(e, errors.NumbaError)): raise e else: sig = None failures.add_error(temp, False, e, uselit) else: if sig is not None: self._impl_keys[sig.args] = temp.get_impl_key(sig) self._depth -= 1 return sig else: registered_sigs = getattr(temp, 'cases', None) if registered_sigs is not None: msg = "No match for registered cases:\n%s" msg = msg % '\n'.join(" * {}".format(x) for x in registered_sigs) else: msg = 'No match.' failures.add_error(temp, True, msg, uselit) failures.raise_error()
def _compile_core(self): """ Populate and run compiler pipeline """ with ConfigStack().enter(self.state.flags.copy()): pms = self.define_pipelines() for pm in pms: pipeline_name = pm.pipeline_name func_name = "%s.%s" % (self.state.func_id.modname, self.state.func_id.func_qualname) event("Pipeline: %s for %s" % (pipeline_name, func_name)) self.state.metadata['pipeline_times'] = { pipeline_name: pm.exec_times } is_final_pipeline = pm == pms[-1] res = None try: pm.run(self.state) if self.state.cr is not None: break except _EarlyPipelineCompletion as e: res = e.result break except Exception as e: if (utils.use_new_style_errors() and not isinstance(e, errors.NumbaError)): raise e self.state.status.fail_reason = e if is_final_pipeline: raise e else: raise CompilerError("All available pipelines exhausted") # Pipeline is done, remove self reference to release refs to user # code self.state.pipeline = None # organise a return if res is not None: # Early pipeline completion return res else: assert self.state.cr is not None return self.state.cr
def new_error_context(fmt_, *args, **kwargs): """ A contextmanager that prepend contextual information to any exception raised within. If the exception type is not an instance of NumbaError, it will be wrapped into a InternalError. The exception class can be changed by providing a "errcls_" keyword argument with the exception constructor. The first argument is a message that describes the context. It can be a format string. If there are additional arguments, it will be used as ``fmt_.format(*args, **kwargs)`` to produce the final message string. """ errcls = kwargs.pop('errcls_', InternalError) loc = kwargs.get('loc', None) if loc is not None and not loc.filename.startswith(_numba_path): loc_info.update(kwargs) try: yield except NumbaError as e: e.add_context(_format_msg(fmt_, args, kwargs)) raise except AssertionError: # Let assertion error pass through for shorter traceback in debugging raise except Exception as e: if use_old_style_errors(): newerr = errcls(e).add_context(_format_msg(fmt_, args, kwargs)) if numba.core.config.FULL_TRACEBACKS: tb = sys.exc_info()[2] else: tb = None raise newerr.with_traceback(tb) elif use_new_style_errors(): raise e else: msg = ("Unknown CAPTURED_ERRORS style: " f"'{numba.core.config.CAPTURED_ERRORS}'.") assert 0, msg
def get_call_type(self, context, args, kws): template = self.template(context) literal_e = None nonliteral_e = None out = None choice = [True, False] if template.prefer_literal else [False, True] for uselit in choice: if uselit: # Try with Literal try: out = template.apply(args, kws) except Exception as exc: if (utils.use_new_style_errors() and not isinstance(exc, errors.NumbaError)): raise exc if isinstance(exc, errors.ForceLiteralArg): raise exc literal_e = exc out = None else: break else: # if the unliteral_args and unliteral_kws are the same as the # literal ones, set up to not bother retrying unliteral_args = tuple([_unlit_non_poison(a) for a in args]) unliteral_kws = { k: _unlit_non_poison(v) for k, v in kws.items() } skip = unliteral_args == args and kws == unliteral_kws # If the above template application failed and the non-literal # args are different to the literal ones, try again with # literals rewritten as non-literals if not skip and out is None: try: out = template.apply(unliteral_args, unliteral_kws) except Exception as exc: if isinstance(exc, errors.ForceLiteralArg): if template.prefer_literal: # For template that prefers literal types, # reaching here means that the literal types # have failed typing as well. raise exc nonliteral_e = exc else: break if out is None and (nonliteral_e is not None or literal_e is not None): header = "- Resolution failure for {} arguments:\n{}\n" tmplt = _termcolor.highlight(header) if config.DEVELOPER_MODE: indent = ' ' * 4 def add_bt(error): if isinstance(error, BaseException): # if the error is an actual exception instance, trace it bt = traceback.format_exception( type(error), error, error.__traceback__) else: bt = [""] nd2indent = '\n{}'.format(2 * indent) errstr = _termcolor.reset(nd2indent + nd2indent.join(_bt_as_lines(bt))) return _termcolor.reset(errstr) else: add_bt = lambda X: '' def nested_msg(literalness, e): estr = str(e) estr = estr if estr else (str(repr(e)) + add_bt(e)) new_e = errors.TypingError(textwrap.dedent(estr)) return tmplt.format(literalness, str(new_e)) raise errors.TypingError( nested_msg('literal', literal_e) + nested_msg('non-literal', nonliteral_e)) return out