From cd0d7c7d3a3def9f99bc1b37834ad9df56c4d8c4 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Sun, 12 Dec 2021 07:29:36 -0600 Subject: [PATCH 1/7] A step added to build/run examples Adjust triggers to avoid duplicate jobs on push to branches with a PR Activate and stack activate in shell session where examples are built Only activate build_env for building packages, deactivate it before running example Make sure to set OCL_ICD_FILENAMES before running examples --- .github/workflows/conda-package.yml | 116 +++++++++++++++++++++++++++- 1 file changed, 115 insertions(+), 1 deletion(-) diff --git a/.github/workflows/conda-package.yml b/.github/workflows/conda-package.yml index 86d9a025ed..f4c15abfb2 100644 --- a/.github/workflows/conda-package.yml +++ b/.github/workflows/conda-package.yml @@ -1,6 +1,10 @@ name: Conda package -on: [push, pull_request] +on: + push: + branches: + - master + pull_request: env: PACKAGE_NAME: dpctl @@ -115,6 +119,7 @@ jobs: - name: Add conda to system path run: echo $CONDA/bin >> $GITHUB_PATH - name: Install conda-build + # Needed to be able to run conda index run: conda install conda-build - name: Create conda channel run: | @@ -178,6 +183,7 @@ jobs: auto-activate-base: true activate-environment: "" - name: Install conda-build + # Needed to be able to run conda index run: conda install conda-build - name: Create conda channel run: | @@ -263,3 +269,111 @@ jobs: run: | conda install anaconda-client anaconda --token ${{ env.ANACONDA_TOKEN }} upload --user dppy --label dev ${{ env.PACKAGE_NAME }}-*.tar.bz2 + + test_examples_linux: + needs: build_linux + runs-on: ${{ matrix.runner }} + strategy: + matrix: + python: [3.8] + experimental: [false] + runner: [ubuntu-latest] + continue-on-error: ${{ matrix.experimental }} + env: + CHANNELS: -c intel -c defaults --override-channels + + steps: + - name: Install conda-build + # Needed to be able to run conda index + run: conda install conda-build python=${{ matrix.python }} + - name: Checkout dpctl repo + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Download artifact + uses: actions/download-artifact@v2 + with: + name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} + - name: Add conda to system path + run: echo $CONDA/bin >> $GITHUB_PATH + - name: Create conda channel + run: | + mkdir -p $GITHUB_WORKSPACE/channel/linux-64 + mv ${PACKAGE_NAME}-*.tar.bz2 $GITHUB_WORKSPACE/channel/linux-64 + conda index $GITHUB_WORKSPACE/channel + # Test channel + conda search $PACKAGE_NAME -c $GITHUB_WORKSPACE/channel --override-channels + - name: Collect dependencies + run: | + CHANNELS="-c $GITHUB_WORKSPACE/channel ${{ env.CHANNELS }}" + conda install $PACKAGE_NAME python=${{ matrix.python }} $CHANNELS --only-deps --dry-run > lockfile + - name: Set pkgs_dirs + run: | + echo "pkgs_dirs: [~/.conda/pkgs]" >> ~/.condarc + - name: Cache conda packages + uses: actions/cache@v2 + env: + CACHE_NUMBER: 0 # Increase to reset cache + with: + path: ~/.conda/pkgs + key: + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-python-${{ matrix.python }}-${{hashFiles('lockfile') }} + restore-keys: | + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-python-${{ matrix.python }}- + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}- + - name: Install dpctl + shell: bash -l {0} + run: | + source $CONDA/etc/profile.d/conda.sh + conda activate + CHANNELS="-c $GITHUB_WORKSPACE/channel ${{ env.CHANNELS }}" + conda install -y $PACKAGE_NAME pytest python=${{ matrix.python }} $CHANNELS + # Test installed packages + conda list + - name: Install example requirements + shell: bash -l {0} + run: | + source $CONDA/etc/profile.d/conda.sh + conda install -y pybind11 cython + conda install -y -c intel mkl-dpcpp mkl-devel-dpcpp numba-dppy + conda create -y -n build_env -c intel dpcpp_linux-64 + - name: Build and run examples with native extensions + shell: bash -l {0} + run: | + source $CONDA/etc/profile.d/conda.sh + export OCL_ICD_FILENAMES=libintelocl.so + export SYCL_ENABLE_HOST_DEVICE=1 + conda activate + cd examples/pybind11 + export CC=dpcpp + export CXX=dpcpp + for d in $(ls) + do + pushd $d + conda activate --stack build_env + python setup.py build_ext --inplace || exit 1 + conda deactivate + python example.py + popd + done + cd ../cython + for d in $(ls) + do + pushd $d + conda activate --stack build_env + python setup.py build_ext --inplace || exit 1 + conda deactivate + python run.py + popd + done + - name: Run Python examples + shell: bash -l {0} + run: | + cd examples/python + export OCL_ICD_FILENAMES=libintelocl.so + export SYCL_ENABLE_HOST_DEVICE=1 + for script in $(find . \( -not -name "_*" -and -name "*.py" \)) + do + echo "Executing ${script}" + python ${script} || exit 1 + done From a1a93af3ef8ddf615e83ebd21bce755c436ba66e Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Mon, 13 Dec 2021 18:01:56 -0600 Subject: [PATCH 2/7] Use default selected queue, rather than gpu selected queue --- examples/pybind11/external_usm_allocation/example.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/pybind11/external_usm_allocation/example.py b/examples/pybind11/external_usm_allocation/example.py index 522f822a36..4455616146 100644 --- a/examples/pybind11/external_usm_allocation/example.py +++ b/examples/pybind11/external_usm_allocation/example.py @@ -22,7 +22,7 @@ import dpctl import dpctl.memory as dpm -q = dpctl.SyclQueue("gpu") +q = dpctl.SyclQueue() matr = eua.DMatrix(q, 5, 5) print(matr) From 7342189d73e5c1ecfaae31f776c2c693bc9add32 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Mon, 13 Dec 2021 18:15:05 -0600 Subject: [PATCH 3/7] Added C++ and language level directive to .pyx files Added $CONDA_PREFIX/include to include dirs in Extensions using MKL --- examples/cython/sycl_buffer/_buffer_example.pyx | 3 +++ examples/cython/sycl_buffer/setup.py | 10 +++++++++- .../cython/sycl_direct_linkage/_buffer_example.pyx | 3 +++ examples/cython/sycl_direct_linkage/setup.py | 10 +++++++++- examples/cython/usm_memory/setup.py | 10 +++++++++- 5 files changed, 33 insertions(+), 3 deletions(-) diff --git a/examples/cython/sycl_buffer/_buffer_example.pyx b/examples/cython/sycl_buffer/_buffer_example.pyx index 2737dbcc72..2f442d9388 100644 --- a/examples/cython/sycl_buffer/_buffer_example.pyx +++ b/examples/cython/sycl_buffer/_buffer_example.pyx @@ -14,6 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +# distutils: language = c++ +# cython: language_level=3 + cimport numpy as cnp import numpy as np diff --git a/examples/cython/sycl_buffer/setup.py b/examples/cython/sycl_buffer/setup.py index 8efce46d7a..3e2d98390f 100644 --- a/examples/cython/sycl_buffer/setup.py +++ b/examples/cython/sycl_buffer/setup.py @@ -14,6 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os.path +import sysconfig + import numpy as np from setuptools import Extension, setup @@ -39,7 +42,12 @@ "_buffer_example.pyx", "use_sycl_buffer.cpp", ], - include_dirs=[".", np.get_include(), dpctl.get_include()], + include_dirs=[ + ".", + np.get_include(), + dpctl.get_include(), + os.path.join(sysconfig.get_paths()["include"], ".."), + ], libraries=["sycl"] + [ "mkl_sycl", diff --git a/examples/cython/sycl_direct_linkage/_buffer_example.pyx b/examples/cython/sycl_direct_linkage/_buffer_example.pyx index 49d6cbd95e..effff5117c 100644 --- a/examples/cython/sycl_direct_linkage/_buffer_example.pyx +++ b/examples/cython/sycl_direct_linkage/_buffer_example.pyx @@ -14,6 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +# distutils: language = c++ +# cython: language_level=3 + cimport numpy as cnp import numpy as np diff --git a/examples/cython/sycl_direct_linkage/setup.py b/examples/cython/sycl_direct_linkage/setup.py index 31c1e92162..b60e358afa 100644 --- a/examples/cython/sycl_direct_linkage/setup.py +++ b/examples/cython/sycl_direct_linkage/setup.py @@ -14,6 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os.path +import sysconfig + import numpy as np from setuptools import Extension, setup @@ -43,7 +46,12 @@ "_buffer_example.pyx", "sycl_function.cpp", ], - include_dirs=[".", np.get_include(), dpctl.get_include()], + include_dirs=[ + ".", + np.get_include(), + dpctl.get_include(), + os.path.join(sysconfig.get_paths()["include"], ".."), + ], libraries=["sycl"] + [ "mkl_sycl", diff --git a/examples/cython/usm_memory/setup.py b/examples/cython/usm_memory/setup.py index 008370fd62..cf5e4ed122 100644 --- a/examples/cython/usm_memory/setup.py +++ b/examples/cython/usm_memory/setup.py @@ -14,6 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os.path +import sysconfig + import numpy as np from setuptools import Extension, setup @@ -38,7 +41,12 @@ "blackscholes.pyx", "sycl_blackscholes.cpp", ], - include_dirs=[".", np.get_include(), dpctl.get_include()], + include_dirs=[ + ".", + np.get_include(), + dpctl.get_include(), + os.path.join(sysconfig.get_paths()["include"], ".."), + ], libraries=["sycl"] + [ "mkl_sycl", From 4d92808afea7505693bcce52f136202681cd3a52 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Mon, 13 Dec 2021 19:23:55 -0600 Subject: [PATCH 4/7] Use try/catch to handle failure to create a queue --- examples/python/dppy_kernel.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/examples/python/dppy_kernel.py b/examples/python/dppy_kernel.py index cfbbc947f6..05e7dd6cfc 100644 --- a/examples/python/dppy_kernel.py +++ b/examples/python/dppy_kernel.py @@ -44,7 +44,14 @@ def dppy_gemm(a, b, c): b = np.array(np.random.random(X * X), dtype=np.float32).reshape(X, X) c = np.ones_like(a).reshape(X, X) -q = dpctl.SyclQueue("opencl:gpu", property="enable_profiling") +try: + q = dpctl.SyclQueue("opencl:gpu", property="enable_profiling") +except dpctl.SyclQueueCreationError: + print( + "Skipping the example, as dpctl.SyclQueue targeting " + "opencl:gpu device could not be created" + ) + exit(0) timer = SyclTimer(time_scale=1) with dpctl.device_context(q): with timer(q): From 9842e3c9702dffc522530c7b007188447393dbff Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Mon, 13 Dec 2021 19:25:32 -0600 Subject: [PATCH 5/7] Use try/except to handle failure to create SyclQueue --- examples/cython/sycl_buffer/run.py | 31 +++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/examples/cython/sycl_buffer/run.py b/examples/cython/sycl_buffer/run.py index a82a6671a0..a66ae60dea 100644 --- a/examples/cython/sycl_buffer/run.py +++ b/examples/cython/sycl_buffer/run.py @@ -23,18 +23,31 @@ print("Result computed by NumPy") print(X.sum(axis=0)) -print("Result computed by SYCL extension using default offloading target") -print(sb.columnwise_total(X)) +try: + res = sb.columnwise_total(X) + print("Result computed by SYCL extension using default offloading target") + print(res) +except dpctl.SyclQueueCreationError: + print( + "Could not create SyclQueue for default selected device. Nothing to do." + ) + exit(0) print("") # controlling where to offload -q = dpctl.SyclQueue("opencl:gpu") -print("Running on: ", q.sycl_device.name) -print(sb.columnwise_total(X, queue=q)) - -q = dpctl.SyclQueue("opencl:cpu") -print("Running on: ", q.sycl_device.name) -print(sb.columnwise_total(X, queue=q)) +try: + q = dpctl.SyclQueue("opencl:gpu") + print("Running on: ", q.sycl_device.name) + print(sb.columnwise_total(X, queue=q)) +except dpctl.SyclQueueCreationError: + print("Not running onf opencl:gpu, queue could not be created") + +try: + q = dpctl.SyclQueue("opencl:cpu") + print("Running on: ", q.sycl_device.name) + print(sb.columnwise_total(X, queue=q)) +except dpctl.SyclQueueCreationError: + print("Not running onf opencl:cpu, queue could not be created") From db23331b86df856864aa74cffbf85f8d228ef101 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Mon, 13 Dec 2021 19:36:01 -0600 Subject: [PATCH 6/7] Make example capable of running for different SYCL platform configurations --- examples/cython/usm_memory/run.py | 99 ++++++++++++++----------------- 1 file changed, 44 insertions(+), 55 deletions(-) diff --git a/examples/cython/usm_memory/run.py b/examples/cython/usm_memory/run.py index 2b676288dd..720c580250 100644 --- a/examples/cython/usm_memory/run.py +++ b/examples/cython/usm_memory/run.py @@ -64,59 +64,48 @@ def gen_option_params( n_opts = 3 * 10 ** 6 # compute on CPU sycl device -cpu_q = dpctl.SyclQueue("opencl:cpu:0") -opts1 = gen_option_params( - n_opts, - 20.0, - 30.0, - 22.0, - 29.0, - 18.0, - 24.0, - 0.01, - 0.05, - 0.01, - 0.05, - "d", - queue=cpu_q, -) - -gpu_q = dpctl.SyclQueue("level_zero:gpu:0") -opts2 = gen_option_params( - n_opts, - 20.0, - 30.0, - 22.0, - 29.0, - 18.0, - 24.0, - 0.01, - 0.05, - 0.01, - 0.05, - "d", - queue=gpu_q, -) - -cpu_times = [] -gpu_times = [] -for _ in range(5): - - t0 = timeit.default_timer() - X1 = bs.black_scholes_price(opts1, queue=cpu_q) - t1 = timeit.default_timer() - cpu_times.append(t1 - t0) - - # compute on GPU sycl device - - t0 = timeit.default_timer() - X2 = bs.black_scholes_price(opts2, queue=gpu_q) - t1 = timeit.default_timer() - gpu_times.append(t1 - t0) - -print("Using : {}".format(cpu_q.sycl_device.name)) -print("Wall times : {}".format(cpu_times)) - -print("Using : {}".format(gpu_q.sycl_device.name)) -print("Wall times : {}".format(gpu_times)) +queues = [] +for filter_str in ["cpu", "gpu"]: + try: + q = dpctl.SyclQueue(filter_str) + queues.append(q) + except dpctl.SyclQueueCreationError: + continue + +if not queues: + print("No queues could not created, nothing to do.") + exit(0) + +opt_params_list = [] +for q in queues: + opt_params = gen_option_params( + n_opts, + 20.0, + 30.0, + 22.0, + 29.0, + 18.0, + 24.0, + 0.01, + 0.05, + 0.01, + 0.05, + "d", + queue=q, + ) + opt_params_list.append(opt_params) + +times_dict = dict() +for q, params in zip(queues, opt_params_list): + times_list = [] + for _ in range(5): + t0 = timeit.default_timer() + X1 = bs.black_scholes_price(params, queue=q) + t1 = timeit.default_timer() + times_list.append(t1 - t0) + times_dict[q.name] = times_list + +for dev_name, wall_times in times_dict.items(): + print("Using : {}".format(dev_name)) + print("Wall times : {}".format(wall_times)) From 3e1dc2cba8442bb049988e6e15f01e81aea0df3a Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Wed, 15 Dec 2021 09:28:29 -0600 Subject: [PATCH 7/7] In example select device with aspects do not insists on GPU to enable it running in cloud --- examples/python/device_selection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/python/device_selection.py b/examples/python/device_selection.py index 55b65b9ea5..373b9e401a 100644 --- a/examples/python/device_selection.py +++ b/examples/python/device_selection.py @@ -98,7 +98,7 @@ def create_device_with_aspects(): Demonstrate the usage of :func:`dpctl.select_device_with_aspects()`. """ dev = dpctl.select_device_with_aspects( - required_aspects=["fp64", "gpu", "usm_shared_allocations"] + required_aspects=["fp64", "usm_shared_allocations"] ) dev.print_device_info()