Skip to content

Commit

Permalink
Adds more custom exception classes to numba_dpex.
Browse files Browse the repository at this point in the history
  • Loading branch information
Diptorup Deb committed Oct 15, 2022
1 parent 192ef38 commit 06d2951
Showing 1 changed file with 165 additions and 3 deletions.
168 changes: 165 additions & 3 deletions numba_dpex/core/dpex_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
#
# SPDX-License-Identifier: Apache-2.0

"""The module stores a set of exception classes specific to numba_dpex compiler
pipeline.
"""The module defines the custom exception classes used in numba_dpex.
"""

from warnings import warn


class KernelHasReturnValueError(Exception):
"""Exception raised when a kernel function is defined with a return
Expand All @@ -17,9 +18,9 @@ class KernelHasReturnValueError(Exception):
CUDA, and SYCL.
Args:
kernel_name: Name of the kernel function that caused the error.
return_type: Numba type representing the return value specified for
the kernel function.
"""

def __init__(self, kernel_name, return_type) -> None:
Expand All @@ -32,3 +33,164 @@ def __init__(self, kernel_name, return_type) -> None:
)

super().__init__(self.message)


class InvalidKernelLaunchArgsError(Exception):
"""Raised when a kernel is dispatched with insufficient or incorrect launch
arguments.
A global range value is needed to submit a kernel to an execution queue. The
global range provides the number of work items that the SYCL runtime should
create to execute the kernel. The exception is raised if a kernel is
dispatched without specifying a valid global range.
Args:
kernel_name (str): The kernel function name.
"""

def __init__(self, kernel_name, *args):

if not args:
self.message = (
f"No global range specified for launching the Kernel "
f"{kernel_name}. "
f"A valid global range tuple is needed to launch a kernel."
)
else:
self.message = (
f"Invalid launch arguments specified for launching the Kernel "
f"{kernel_name}. Launch arguments can only be a tuple "
f"specifying the global range or a tuple of tuples specifying "
f"global and local ranges."
)

super().__init__(self.message)


class ComputeFollowsDataInferenceError(Exception):
"""Raised when an execution queue for a given array expression or a kernel
function could not be inferred using the compute-follows-data logic.
Compute-follows-data is a programming model that determines the execution
device or queue of an array expression or kernel based on the arrays that
are on the right hand side of the expression or are the arguments to the
kernel function. The execution queue is derived based on the device on
which the array operands were allocated. Computation is required to occur
on the same device where the arrays currently reside.
A ComputeFollowsDataInferenceError is raised when the execution queue using
compute-follows-data rules could not be derived. It may happen when arrays
that have a device attribute such as ``dpctl.tensor.usm_ndarray`` are mixed
with host arrays such as ``numpy.ndarray``. The error may also be raised if
the array operands are allocated on different devices.
Args:
kernel_name : Name of the kernel function for which the error occurred.
ndarray_argnum_list: The list of ``numpy.ndarray`` arguments identified
by the argument position that caused the error.
usmarray_argnum_list: The list of ``dpctl.tensor.usm_ndarray`` arguments
identified by the argument position that caused the error.
"""

def __init__(
self, kernel_name, ndarray_argnum_list=None, usmarray_argnum_list=None
) -> None:
if ndarray_argnum_list and usmarray_argnum_list:
self.message = (
f"Kernel {kernel_name} has arguments of both usm_ndarray and "
f"non-usm_ndarray types. Mixing of arguments of different "
f" array types is disallowed. "
f"Arguments {ndarray_argnum_list.join()} are non-usm arrays, "
f"and arguments {usmarray_argnum_list.join()} are usm arrays."
)
elif usmarray_argnum_list:
self.message = (
f"Execution queue for kernel {kernel_name} could "
f"be inferred using compute follows data rules. The usm array "
f"arguments {usmarray_argnum_list.join()} were not allocated "
f"on the same queue."
)
super().__init__(self.message)


class ExecutionQueueInferenceError(Exception):
"""Raised when an execution queue could not be inferred for NumPy ndarray
kernel arguments.
Args:
kernel_name (str): Name of kernel where the error was raised.
.. deprecated:: 0.19
"""

def __init__(self, kernel_name) -> None:
warn(
"The ExecutionQueueInferenceError class is deprecated, and will "
+ "be removed once support for NumPy ndarrays as kernel arguments "
+ "is removed.",
DeprecationWarning,
stacklevel=2,
)
self.message = (
f"Kernel {kernel_name} was called with NumPy ndarray arguments "
f"outside a dpctl.device_context. The execution queue to be used "
f"could not be determined."
)
super().__init__(self.message)


class UnsupportedBackendError(Exception):
"""Raised when the target device is not supported by dpex.
Presently only L0 and OpenCL devices are supported by numba_dpex. If the
provided execution queue is for any other SYCL platform (e.g., Cuda) then
it results in an UnsupportedBackendError.
Args:
kernel_name (str): Name of kernel where the error was raised.
backend (str): name of the unsupported backend.
supported_backends (List): The list of supported backends.
"""

def __init__(self, kernel_name, backend, supported_backends) -> None:
self.message = (
f"Kernel {kernel_name} cannot be compiled for {backend}. "
f"Only {supported_backends} are supported."
)
super().__init__(self.message)


class UncompiledKernelError(Exception):
"""Raised when an attribute of a KernelInterface object is accessed before
the object is compiled.
Args:
kernel_name (str): Name of kernel where the error was raised.
"""

def __init__(self, kernel_name) -> None:
self.message = (
f"No LLVM module for kernel {kernel_name}. "
f"Kernel might not be compiled."
)
super().__init__(self.message)


class UnreachableError(Exception):
"""Internal compiler error when an unreachable branch is taken somewhere in
the compiler code.
"""

def __init__(self) -> None:
import sys
import traceback

_, _, tb = sys.exc_info()
traceback.print_tb(tb) # Fixed format
tb_info = traceback.extract_tb(tb)
filename, line, func, text = tb_info[-1]
self.message = (
f"Attempt to execute a unreachable code section on line {line} in "
f"statement {text} in function {func} in the module {filename}."
)
super().__init__(self.message)

0 comments on commit 06d2951

Please sign in to comment.