diff --git a/.github/workflows/conda-package.yml b/.github/workflows/conda-package.yml index f83de335bf..b0761ecace 100644 --- a/.github/workflows/conda-package.yml +++ b/.github/workflows/conda-package.yml @@ -207,7 +207,7 @@ jobs: run: | # echo "libintelocl.so" | tee /etc/OpenCL/vendors/intel-cpu.icd export OCL_ICD_FILENAMES=libintelocl.so - python -m pytest --pyargs $MODULE_NAME + python -m pytest -q -ra --disable-warnings --pyargs $MODULE_NAME -vv test_windows: needs: build_windows @@ -275,7 +275,7 @@ jobs: run: echo "NUMBA_DPPY_TESTING_SKIP_NO_DPNP=1" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - name: Run tests run: | - python -m pytest --pyargs ${{ env.MODULE_NAME }} + python -m pytest -q -ra --disable-warnings --pyargs ${{ env.MODULE_NAME }} -vv upload_linux: needs: test_linux diff --git a/MANIFEST.in b/MANIFEST.in index 4c02572c56..895fc6f2b4 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -6,3 +6,5 @@ recursive-include numba_dppy *.spir include versioneer.py include numba_dppy/_version.py + +recursive-include numba_dppy/examples * diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index a459037ab3..ca4ab7a300 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -37,6 +37,7 @@ test: requires: - pytest - {{ compiler('dpcpp') }} # [not osx] + - pexpect about: home: https://github.com/IntelPython/numba-dppy diff --git a/numba_dppy/examples/debug/side-by-side.py b/numba_dppy/examples/debug/side-by-side.py index 51468b7902..887b6cb389 100644 --- a/numba_dppy/examples/debug/side-by-side.py +++ b/numba_dppy/examples/debug/side-by-side.py @@ -22,7 +22,7 @@ def common_loop_body(param_a, param_b): - param_c = param_a + 10 # Set breakpoint + param_c = param_a + 10 # Set breakpoint here param_d = param_b * 0.5 result = param_c + param_d return result diff --git a/numba_dppy/examples/debug/simple_sum.py b/numba_dppy/examples/debug/simple_sum.py index a69f3cee04..a333c66855 100644 --- a/numba_dppy/examples/debug/simple_sum.py +++ b/numba_dppy/examples/debug/simple_sum.py @@ -21,7 +21,7 @@ @dppy.kernel(debug=True) def data_parallel_sum(a, b, c): i = dppy.get_global_id(0) - c[i] = a[i] + b[i] + c[i] = a[i] + b[i] # Condition breakpoint location global_size = 10 diff --git a/numba_dppy/tests/_helper.py b/numba_dppy/tests/_helper.py index 4c4ef91a76..93191c04b8 100644 --- a/numba_dppy/tests/_helper.py +++ b/numba_dppy/tests/_helper.py @@ -14,12 +14,14 @@ # limitations under the License. import contextlib +import shutil import dpctl import pytest from numba.tests.support import captured_stdout from numba_dppy import config +from numba_dppy.numba_support import numba_version def has_opencl_gpu(): @@ -113,6 +115,15 @@ def platform_not_supported(device_type): pytest.param("level_zero:gpu:0", marks=skip_no_level_zero_gpu), ] +skip_no_numba055 = pytest.mark.skipif( + numba_version < (0, 55), reason="Need Numba 0.55 or higher" +) + +skip_no_gdb = pytest.mark.skipif( + not shutil.which("gdb-oneapi"), + reason="IntelĀ® Distribution for GDB* is not available", +) + @contextlib.contextmanager def override_config(name, value, config=config): diff --git a/numba_dppy/tests/debugging/__init__.py b/numba_dppy/tests/debugging/__init__.py new file mode 100644 index 0000000000..e8ce169780 --- /dev/null +++ b/numba_dppy/tests/debugging/__init__.py @@ -0,0 +1,19 @@ +################################################################################ +# Numba-DPPY +# +# Copyright 2020-2021 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################ + +from . import * diff --git a/numba_dppy/tests/debugging/common.py b/numba_dppy/tests/debugging/common.py new file mode 100644 index 0000000000..91e3446549 --- /dev/null +++ b/numba_dppy/tests/debugging/common.py @@ -0,0 +1,73 @@ +#! /usr/bin/env python +# Copyright 2021 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Common tools for testing debugging""" + +import pathlib + +import numba_dppy + + +def script_path(script): + package_path = pathlib.Path(numba_dppy.__file__).parent + return str(package_path / "examples/debug" / script) + + +def line_number(file_path, text): + """Return line number of the text in the file""" + with open(file_path, "r") as lines: + for line_number, line in enumerate(lines): + if text in line: + return line_number + 1 + + raise RuntimeError(f"Can not find {text} in {file_path}") + + +def breakpoint_by_mark(script, mark, offset=0): + """Return breakpoint for the mark in the script + + Example: breakpoint_by_mark("script.py", "Set here") -> "script.py:25" + """ + return f"{script}:{line_number(script_path(script), mark) + offset}" + + +def breakpoint_by_function(script, function): + """Return breakpoint for the function in the script""" + return breakpoint_by_mark(script, f"def {function}", 1) + + +def setup_breakpoint( + app, + breakpoint: str, + script=None, + expected_location=None, + expected_line=None, +): + if not script: + script = breakpoint.split(" ")[0].split(":")[0] + + if not expected_location: + expected_location = breakpoint.split(" ")[0] + if not expected_location.split(":")[-1].isnumeric(): + expected_location = breakpoint_by_function( + script, expected_location.split(":")[-1] + ) + + app.breakpoint(breakpoint) + app.run(script) + + app.child.expect(fr"Thread .* hit Breakpoint .* at {expected_location}") + + if expected_line: + app.child.expect(expected_line) diff --git a/numba_dppy/tests/debugging/conftest.py b/numba_dppy/tests/debugging/conftest.py new file mode 100644 index 0000000000..e3c72e9204 --- /dev/null +++ b/numba_dppy/tests/debugging/conftest.py @@ -0,0 +1,23 @@ +#! /usr/bin/env python +# Copyright 2021 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest + + +@pytest.fixture +def app(): + from .gdb import gdb + + return gdb() diff --git a/numba_dppy/tests/debugging/gdb.py b/numba_dppy/tests/debugging/gdb.py new file mode 100644 index 0000000000..dee0b89b57 --- /dev/null +++ b/numba_dppy/tests/debugging/gdb.py @@ -0,0 +1,103 @@ +#! /usr/bin/env python +# Copyright 2021 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import os +import sys + +import pytest + +from numba_dppy import config + +from .common import script_path + +pexpect = pytest.importorskip("pexpect") + + +class gdb: + def __init__(self): + self.spawn() + self.setup_gdb() + + def __del__(self): + self.teardown_gdb() + + def spawn(self): + env = os.environ.copy() + env["NUMBA_OPT"] = "0" + env["NUMBA_EXTEND_VARIABLE_LIFETIMES"] = "1" + + self.child = pexpect.spawn( + "gdb-oneapi -q python", env=env, encoding="utf-8" + ) + if config.DEBUG: + self.child.logfile = sys.stdout + + def setup_gdb(self): + self.child.expect("(gdb)", timeout=5) + self.child.sendline("set breakpoint pending on") + self.child.expect("(gdb)", timeout=5) + self.child.sendline("set style enabled off") # disable colors symbols + + def teardown_gdb(self): + self.child.sendintr() + self.child.expect("(gdb)", timeout=5) + self.child.sendline("quit") + self.child.expect("Quit anyway?", timeout=5) + self.child.sendline("y") + + def _command(self, command): + self.child.expect("(gdb)", timeout=5) + self.child.sendline(command) + + def breakpoint(self, breakpoint): + self._command("break " + breakpoint) + + def run(self, script): + self._command("run " + self.script_path(script)) + + def backtrace(self): + self._command("backtrace") + + def print(self, var): + self._command("print " + var) + + def info_args(self): + self._command("info args") + + def info_functions(self, function): + self._command("info functions " + function) + + def info_locals(self): + self._command("info locals") + + def next(self): + self._command("next") + + def ptype(self, var): + self._command("ptype " + var) + + def whatis(self, var): + self._command("whatis " + var) + + def step(self): + self._command("step") + + def stepi(self): + self._command("stepi") + + @staticmethod + def script_path(script): + return script_path(script) diff --git a/numba_dppy/tests/debugging/test_backtraces.py b/numba_dppy/tests/debugging/test_backtraces.py new file mode 100644 index 0000000000..c812e9231e --- /dev/null +++ b/numba_dppy/tests/debugging/test_backtraces.py @@ -0,0 +1,41 @@ +#! /usr/bin/env python +# Copyright 2021 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for Backtraces + +https://www.sourceware.org/gdb/onlinedocs/gdb/Backtrace.html +""" + +from numba_dppy.tests._helper import skip_no_gdb + +from .common import setup_breakpoint + +pytestmark = skip_no_gdb + + +def test_backtrace(app): + """Simple test for backtrace. + + commands/backtrace + """ + setup_breakpoint( + app, + "simple_dppy_func.py:23", + expected_line=r"23\s+result = a_in_func \+ b_in_func", + ) + + app.backtrace() + + app.child.expect(r"#0.*__main__::func_sum .* at simple_dppy_func.py:23") + app.child.expect(r"#1.*__main__::kernel_sum .* at simple_dppy_func.py:30") diff --git a/numba_dppy/tests/debugging/test_breakpoints.py b/numba_dppy/tests/debugging/test_breakpoints.py new file mode 100644 index 0000000000..58ec8008ea --- /dev/null +++ b/numba_dppy/tests/debugging/test_breakpoints.py @@ -0,0 +1,119 @@ +#! /usr/bin/env python +# Copyright 2021 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for Setting Breakpoints + +https://www.sourceware.org/gdb/onlinedocs/gdb/Set-Breaks.html +""" + + +import pytest + +from numba_dppy.tests._helper import skip_no_gdb, skip_no_numba055 + +from .common import breakpoint_by_function, breakpoint_by_mark, setup_breakpoint + +pytestmark = skip_no_gdb + + +side_by_side_breakpoint = breakpoint_by_function( + "side-by-side.py", "common_loop_body" +) + +simple_sum_condition_breakpoint = breakpoint_by_mark( + "simple_sum.py", "Condition breakpoint location" +) + +common_loop_body_native_function_name = { + "numba": "common_loop_body_242", + "numba-dppy-kernel": "common_loop_body", +} + +breakpoint_api_cases = [ + (side_by_side_breakpoint, "numba"), + (side_by_side_breakpoint, "numba-dppy-kernel"), + *((fn, api) for api, fn in common_loop_body_native_function_name.items()), + *( + (f"side-by-side.py:{fn}", api) + for api, fn in common_loop_body_native_function_name.items() + ), +] + + +@skip_no_numba055 +@pytest.mark.parametrize("breakpoint, api", breakpoint_api_cases) +def test_breakpoint_with_condition_by_function_argument(app, breakpoint, api): + """Function breakpoints and argument initializing + + Test that it is possible to set conditional breakpoint at the beginning + of the function and use a function argument in the condition. + + Test for https://github.com/numba/numba/issues/7415 + SAT-4449 + """ + variable_name = "param_a" + variable_value = "3" + condition = f"{variable_name} == {variable_value}" + + app.breakpoint(f"{breakpoint} if {condition}") + app.run(f"side-by-side.py --api={api}") + + app.child.expect( + fr"Thread .* hit Breakpoint .* at {side_by_side_breakpoint}" + ) + + app.print(variable_name) + + app.child.expect(fr"\$1 = {variable_value}") + + +@pytest.mark.parametrize( + "breakpoint, script", + [ + # location specified by file name and function name + # commands/break_file_func + ("simple_sum.py:data_parallel_sum", None), + # location specified by function name + # commands/break_func + ("data_parallel_sum", "simple_sum.py"), + # location specified by file name and nested function name + # commands/break_nested_func + ("simple_dppy_func.py:func_sum", None), + ], +) +def test_breakpoint_common(app, breakpoint, script): + """Set a breakpoint in the given script.""" + setup_breakpoint(app, breakpoint, script=script) + + +@pytest.mark.parametrize( + "breakpoint, variable_name, variable_value", + [ + # commands/break_conditional + (f"{simple_sum_condition_breakpoint} if i == 1", "i", "1"), + ], +) +def test_breakpoint_with_condition_common( + app, + breakpoint, + variable_name, + variable_value, +): + """Set a breakpoint with condition and check value of variable.""" + + setup_breakpoint(app, breakpoint) + + app.print(variable_name) + + app.child.expect(fr"\$1 = {variable_value}") diff --git a/numba_dppy/tests/debugging/test_common.py b/numba_dppy/tests/debugging/test_common.py new file mode 100644 index 0000000000..601012c66d --- /dev/null +++ b/numba_dppy/tests/debugging/test_common.py @@ -0,0 +1,61 @@ +#! /usr/bin/env python +# Copyright 2021 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for common tools""" + +import pytest + +from numba_dppy.tests._helper import skip_no_gdb + +from .common import breakpoint_by_function, breakpoint_by_mark, setup_breakpoint + +pytestmark = skip_no_gdb + + +@pytest.mark.parametrize( + "file_name, mark, expected", + [("side-by-side.py", "Set breakpoint here", "side-by-side.py:25")], +) +def test_breakpoint_by_mark(file_name, mark, expected): + assert expected == breakpoint_by_mark(file_name, mark) + + +@pytest.mark.parametrize( + "file_name, function, expected", + [("side-by-side.py", "common_loop_body", "side-by-side.py:25")], +) +def test_breakpoint_by_function(file_name, function, expected): + assert expected == breakpoint_by_function(file_name, function) + + +@pytest.mark.parametrize( + "breakpoint, script, expected_location, expected_line", + [ + ( + "simple_sum.py:24", + "simple_sum.py", + "simple_sum.py:24", + r"24\s+c\[i\] = a\[i\] \+ b\[i\]", + ), + ("simple_sum.py:24", "simple_sum.py", "simple_sum.py:24", None), + ("simple_sum.py:24", "simple_sum.py", None, None), + ("simple_sum.py:24", None, None, None), + ("simple_sum.py:data_parallel_sum", None, None, None), + ("data_parallel_sum", "simple_sum.py", None, None), + ], +) +def test_setup_breakpoint( + app, breakpoint, script, expected_location, expected_line +): + setup_breakpoint(app, breakpoint, script, expected_location, expected_line) diff --git a/numba_dppy/tests/debugging/test_info.py b/numba_dppy/tests/debugging/test_info.py new file mode 100644 index 0000000000..51e1581493 --- /dev/null +++ b/numba_dppy/tests/debugging/test_info.py @@ -0,0 +1,97 @@ +#! /usr/bin/env python +# Copyright 2021 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for Information About a Frame + +https://www.sourceware.org/gdb/onlinedocs/gdb/Frame-Info.html +""" + +from numba_dppy.tests._helper import skip_no_gdb, skip_no_numba055 + +from .common import setup_breakpoint + +pytestmark = skip_no_gdb + + +@skip_no_numba055 +def test_info_args(app): + setup_breakpoint( + app, + "simple_dppy_func.py:29", + expected_line=r"29\s+i = dppy.get_global_id\(0\)", + ) + + app.info_args() + + app.child.expect(r"a_in_kernel = {meminfo = ") + app.child.expect(r"b_in_kernel = {meminfo = ") + app.child.expect(r"c_in_kernel = {meminfo = ") + + app.print("a_in_kernel") + app.child.expect(r"\$1 = {meminfo = ") + + app.ptype("a_in_kernel") + app.child.expect(r"type = struct array\(float32, 1d, C\).*}\)") + + app.whatis("a_in_kernel") + app.child.expect(r"type = array\(float32, 1d, C\) \({.*}\)") + + +# commands/info_func +@skip_no_numba055 +def test_info_functions(app): + setup_breakpoint( + app, + "simple_sum.py:23", + expected_line=r"23\s+i = dppy.get_global_id\(0\)", + ) + + app.info_functions("data_parallel_sum") + + app.child.expect(r"22:\s+.*__main__::data_parallel_sum\(.*\)") + + +# commands/local_variables_0 +@skip_no_numba055 +def test_local_variables(app): + setup_breakpoint( + app, "sum_local_vars.py:26", expected_line=r"26\s+c\[i\] = l1 \+ l2" + ) + + app.info_locals() + + app.child.expect(r"i = 0") + app.child.expect(r"l1 = [0-9]\.[0-9]{3}") + app.child.expect(r"l2 = [0-9]\.[0-9]{3}") + + app.print("a") + app.child.expect(r"\$1 = {meminfo = ") + + app.print("l1") + app.child.expect(r"\$2 = [0-9]\.[0-9]{3}") + + app.print("l2") + app.child.expect(r"\$3 = [0-9]\.[0-9]{3}") + + app.ptype("a") + app.child.expect(r"type = struct array\(float32, 1d, C\).*}\)") + + app.whatis("a") + app.child.expect(r"type = array\(float32, 1d, C\) \({.*}\)") + + app.ptype("l1") + app.child.expect(r"type = float64") + + app.whatis("l1") + app.child.expect(r"type = float64") diff --git a/numba_dppy/tests/debugging/test_side_by_side.py b/numba_dppy/tests/debugging/test_side_by_side.py new file mode 100644 index 0000000000..0a7ef4dfd4 --- /dev/null +++ b/numba_dppy/tests/debugging/test_side_by_side.py @@ -0,0 +1,33 @@ +#! /usr/bin/env python +# Copyright 2021 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for side-by-side.py script""" + + +import pytest + +from numba_dppy.tests._helper import skip_no_gdb + +pytestmark = skip_no_gdb + + +@pytest.mark.parametrize("api", ["numba", "numba-dppy-kernel"]) +def test_breakpoint_row_number(app, api): + """Test for checking numba and numba-dppy debugging side-by-side.""" + + app.breakpoint("side-by-side.py:25") + app.run("side-by-side.py --api={api}".format(api=api)) + + app.child.expect(r"Breakpoint .* at side-by-side.py:25") + app.child.expect(r"25\s+param_c = param_a \+ 10") diff --git a/numba_dppy/tests/debugging/test_stepping.py b/numba_dppy/tests/debugging/test_stepping.py new file mode 100644 index 0000000000..236184bf87 --- /dev/null +++ b/numba_dppy/tests/debugging/test_stepping.py @@ -0,0 +1,76 @@ +#! /usr/bin/env python +# Copyright 2021 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for Continuing and Stepping + +https://www.sourceware.org/gdb/onlinedocs/gdb/Continuing-and-Stepping.html +""" + +from numba_dppy.tests._helper import skip_no_gdb + +from .common import setup_breakpoint + +pytestmark = skip_no_gdb + + +# commands/next +def test_next(app): + setup_breakpoint( + app, + "simple_dppy_func.py:30", + expected_line=r"30\s+c_in_kernel\[i\] = func_sum\(a_in_kernel\[i\], b_in_kernel\[i\]\)", + ) + + app.next() + app.next() + + app.child.expect(r"Done\.\.\.") + + +# commands/step_dppy_func +def test_step(app): + setup_breakpoint( + app, + "simple_dppy_func.py:30", + expected_line=r"30\s+c_in_kernel\[i\] = func_sum\(a_in_kernel\[i\], b_in_kernel\[i\]\)", + ) + + app.step() + app.step() + + app.child.expect(r"__main__::func_sum \(.*\) at simple_dppy_func.py:23") + app.child.expect(r"23\s+result = a_in_func \+ b_in_func") + + +# commands/stepi +def test_stepi(app): + setup_breakpoint( + app, + "simple_dppy_func.py:30", + expected_line=r"30\s+c_in_kernel\[i\] = func_sum\(a_in_kernel\[i\], b_in_kernel\[i\]\)", + ) + + app.stepi() + + app.child.expect( + r"0x[0-f]+\s+30\s+c_in_kernel\[i\] = func_sum\(a_in_kernel\[i\], b_in_kernel\[i\]\)" + ) + + app.stepi() + + app.child.expect(r"Switching to Thread") + app.child.expect(r"Thread .* hit Breakpoint .* at simple_dppy_func.py:30") + app.child.expect( + r"30\s+c_in_kernel\[i\] = func_sum\(a_in_kernel\[i\], b_in_kernel\[i\]\)" + ) diff --git a/numba_dppy/tests/test_debug_dppy_numba.py b/numba_dppy/tests/test_debug_dppy_numba.py deleted file mode 100644 index 388a94b588..0000000000 --- a/numba_dppy/tests/test_debug_dppy_numba.py +++ /dev/null @@ -1,345 +0,0 @@ -#! /usr/bin/env python -# Copyright 2021 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -import pathlib -import shutil -import sys - -import pytest - -import numba_dppy -from numba_dppy import config -from numba_dppy.numba_support import numba_version - -pexpect = pytest.importorskip("pexpect") - -pytestmark = pytest.mark.skipif( - not shutil.which("gdb-oneapi"), - reason="IntelĀ® Distribution for GDB* is not available", -) - - -skip_no_numba055 = pytest.mark.skipif( - numba_version < (0, 55), reason="Need Numba 0.55 or higher" -) - - -# TODO: go to helper -class gdb: - def __init__(self): - self.spawn() - self.setup_gdb() - - def __del__(self): - self.teardown_gdb() - - def spawn(self): - env = os.environ.copy() - env["NUMBA_OPT"] = "0" - env["NUMBA_EXTEND_VARIABLE_LIFETIMES"] = "1" - - self.child = pexpect.spawn( - "gdb-oneapi -q python", env=env, encoding="utf-8" - ) - if config.DEBUG: - self.child.logfile = sys.stdout - - def setup_gdb(self): - self.child.expect("(gdb)", timeout=5) - self.child.sendline("set breakpoint pending on") - self.child.expect("(gdb)", timeout=5) - self.child.sendline("set style enabled off") # disable colors symbols - - def teardown_gdb(self): - self.child.sendintr() - self.child.expect("(gdb)", timeout=5) - self.child.sendline("quit") - self.child.expect("Quit anyway?", timeout=5) - self.child.sendline("y") - - def _command(self, command): - self.child.expect("(gdb)", timeout=5) - self.child.sendline(command) - - def breakpoint(self, breakpoint): - self._command("break " + breakpoint) - - def run(self, script): - self._command("run " + self.script_path(script)) - - def backtrace(self): - self._command("backtrace") - - def print(self, var): - self._command("print " + var) - - def info_args(self): - self._command("info args") - - def info_functions(self, function): - self._command("info functions " + function) - - def info_locals(self): - self._command("info locals") - - def next(self): - self._command("next") - - def ptype(self, var): - self._command("ptype " + var) - - def whatis(self, var): - self._command("whatis " + var) - - def step(self): - self._command("step") - - def stepi(self): - self._command("stepi") - - @staticmethod - def script_path(script): - package_path = pathlib.Path(numba_dppy.__file__).parent - return str(package_path / "examples/debug" / script) - - -@pytest.fixture -def app(): - return gdb() - - -@pytest.mark.parametrize("api", ["numba", "numba-dppy-kernel"]) -def test_breakpoint_row_number(app, api): - """Test for checking numba and numba-dppy debugging side-by-side.""" - - app.breakpoint("side-by-side.py:25") - app.run("side-by-side.py --api={api}".format(api=api)) - - app.child.expect(r"Breakpoint .* at side-by-side.py:25") - app.child.expect(r"25\s+param_c = param_a \+ 10") - - -# commands/backtrace -def test_backtrace(app): - app.breakpoint("simple_dppy_func.py:23") - app.run("simple_dppy_func.py") - - app.child.expect(r"Thread .* hit Breakpoint .* at simple_dppy_func.py:23") - app.child.expect(r"23\s+result = a_in_func \+ b_in_func") - - app.backtrace() - - app.child.expect(r"#0.*__main__::func_sum .* at simple_dppy_func.py:23") - app.child.expect(r"#1.*__main__::kernel_sum .* at simple_dppy_func.py:30") - - -# commands/break_conditional -def test_break_conditional(app): - app.breakpoint("simple_sum.py:24 if i == 1") - app.run("simple_sum.py") - - app.child.expect(r"Thread .* hit Breakpoint .* at simple_sum.py:24") - app.child.expect(r"24\s+c\[i\] = a\[i\] \+ b\[i\]") - - app.print("i") - - app.child.expect(r"\$1 = 1") - - -@skip_no_numba055 -def test_break_conditional_with_func_arg(app): - app.breakpoint("simple_dppy_func.py:23 if a_in_func == 3") - app.run("simple_dppy_func.py") - - app.child.expect(r"Thread .* hit Breakpoint .* at simple_dppy_func.py:23") - app.child.expect(r"23\s+result = a_in_func \+ b_in_func") - - app.print("a_in_func") - - app.child.expect(r"\$1 = 3") - - -@skip_no_numba055 -def test_break_conditional_by_func_name_with_func_arg(app): - app.breakpoint("func_sum if a_in_func == 3") - app.run("simple_dppy_func.py") - - app.child.expect(r"Thread .* hit Breakpoint .* at simple_dppy_func.py:23") - app.child.expect(r"23\s+result = a_in_func \+ b_in_func") - - app.print("a_in_func") - - app.child.expect(r"\$1 = 3") - - -# commands/break_file_func -def test_break_file_function(app): - app.breakpoint("simple_sum.py:data_parallel_sum") - app.run("simple_sum.py") - - app.child.expect(r"Thread .* hit Breakpoint .* at simple_sum.py:23") - app.child.expect(r"23\s+i = dppy.get_global_id\(0\)") - - -# commands/break_func -def test_break_function(app): - app.breakpoint("data_parallel_sum") - app.run("simple_sum.py") - - app.child.expect(r"Thread .* hit Breakpoint .* at simple_sum.py:23") - app.child.expect(r"23\s+i = dppy.get_global_id\(0\)") - - -# commands/break_nested_func -def test_break_nested_function(app): - app.breakpoint("simple_dppy_func.py:func_sum") - app.run("simple_dppy_func.py") - - app.child.expect(r"Thread .* hit Breakpoint .* at simple_dppy_func.py:23") - app.child.expect(r"23\s+result = a_in_func \+ b_in_func") - - -@skip_no_numba055 -def test_info_args(app): - app.breakpoint("simple_dppy_func.py:29") - app.run("simple_dppy_func.py") - - app.child.expect(r"Thread .* hit Breakpoint .* at simple_dppy_func.py:29") - app.child.expect(r"29\s+i = dppy.get_global_id\(0\)") - - app.info_args() - - app.child.expect(r"a_in_kernel = {meminfo = ") - app.child.expect(r"b_in_kernel = {meminfo = ") - app.child.expect(r"c_in_kernel = {meminfo = ") - - app.print("a_in_kernel") - app.child.expect(r"\$1 = {meminfo = ") - - app.ptype("a_in_kernel") - app.child.expect(r"type = struct array\(float32, 1d, C\).*}\)") - - app.whatis("a_in_kernel") - app.child.expect(r"type = array\(float32, 1d, C\) \({.*}\)") - - -# commands/info_func -@skip_no_numba055 -def test_info_functions(app): - app.breakpoint("simple_sum.py:23") - app.run("simple_sum.py") - - app.child.expect(r"Thread .* hit Breakpoint .* at simple_sum.py:23") - app.child.expect(r"23\s+i = dppy.get_global_id\(0\)") - - app.info_functions("data_parallel_sum") - - app.child.expect(r"22:\s+.*__main__::data_parallel_sum\(.*\)") - - -# commands/local_variables_0 -@skip_no_numba055 -def test_local_variables(app): - app.breakpoint("sum_local_vars.py:26") - app.run("sum_local_vars.py") - - app.child.expect(r"Thread .* hit Breakpoint .* at sum_local_vars.py:26") - app.child.expect(r"26\s+c\[i\] = l1 \+ l2") - - app.info_locals() - - app.child.expect(r"i = 0") - app.child.expect(r"l1 = [0-9]\.[0-9]{3}") - app.child.expect(r"l2 = [0-9]\.[0-9]{3}") - - app.print("a") - app.child.expect(r"\$1 = {meminfo = ") - - app.print("l1") - app.child.expect(r"\$2 = [0-9]\.[0-9]{3}") - - app.print("l2") - app.child.expect(r"\$3 = [0-9]\.[0-9]{3}") - - app.ptype("a") - app.child.expect(r"type = struct array\(float32, 1d, C\).*}\)") - - app.whatis("a") - app.child.expect(r"type = array\(float32, 1d, C\) \({.*}\)") - - app.ptype("l1") - app.child.expect(r"type = float64") - - app.whatis("l1") - app.child.expect(r"type = float64") - - -# commands/next -def test_next(app): - app.breakpoint("simple_dppy_func.py:30") - app.run("simple_dppy_func.py") - - app.child.expect(r"Thread .* hit Breakpoint .* at simple_dppy_func.py:30") - app.child.expect( - r"30\s+c_in_kernel\[i\] = func_sum\(a_in_kernel\[i\], b_in_kernel\[i\]\)" - ) - - app.next() - app.next() - - app.child.expect(r"Done\.\.\.") - - -# commands/step_dppy_func -def test_step(app): - app.breakpoint("simple_dppy_func.py:30") - app.run("simple_dppy_func.py") - - app.child.expect(r"Thread .* hit Breakpoint .* at simple_dppy_func.py:30") - app.child.expect( - r"30\s+c_in_kernel\[i\] = func_sum\(a_in_kernel\[i\], b_in_kernel\[i\]\)" - ) - - app.step() - app.step() - - app.child.expect(r"__main__::func_sum \(.*\) at simple_dppy_func.py:23") - app.child.expect(r"23\s+result = a_in_func \+ b_in_func") - - -# commands/stepi -def test_stepi(app): - app.breakpoint("simple_dppy_func.py:30") - app.run("simple_dppy_func.py") - - app.child.expect(r"Thread .* hit Breakpoint .* at simple_dppy_func.py:30") - app.child.expect( - r"30\s+c_in_kernel\[i\] = func_sum\(a_in_kernel\[i\], b_in_kernel\[i\]\)" - ) - - app.stepi() - - app.child.expect( - r"0x[0-f]+\s+30\s+c_in_kernel\[i\] = func_sum\(a_in_kernel\[i\], b_in_kernel\[i\]\)" - ) - - app.stepi() - - app.child.expect(r"Switching to Thread") - app.child.expect(r"Thread .* hit Breakpoint .* at simple_dppy_func.py:30") - app.child.expect( - r"30\s+c_in_kernel\[i\] = func_sum\(a_in_kernel\[i\], b_in_kernel\[i\]\)" - ) diff --git a/setup.py b/setup.py index 31d3026bee..894bf633e6 100644 --- a/setup.py +++ b/setup.py @@ -152,6 +152,7 @@ def spirv_compile(): setup_requires=build_requires, install_requires=install_requires, include_package_data=True, + zip_safe=False, ext_modules=get_ext_modules(), author="Intel Corporation", classifiers=[