Skip to content

Introduce dpctl/sycl.pxd #981

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Nov 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ per-file-ignores =
examples/cython/sycl_buffer/_buffer_example.pyx: E999, E225, E402
examples/cython/sycl_direct_linkage/_buffer_example.pyx: E999, E225, E402
examples/cython/usm_memory/blackscholes.pyx: E999, E225, E226, E402
examples/cython/use_dpctl_sycl/use_dpctl_sycl/_cython_api.pyx: E999, E225, E226, E402
7 changes: 6 additions & 1 deletion .github/workflows/conda-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,12 @@ jobs:
CC=dpcpp CXX=dpcpp LDSHARED="dpcpp -shared" \
python setup.py build_ext --inplace || exit 1
conda deactivate
LD_LIBRARY_PATH=${CONDA_PREFIX}/lib python run.py || exit 1
if [ -e tests ]
then
LD_LIBRARY_PATH=${CONDA_PREFIX}/lib python -m pytest tests || exit 1
else
LD_LIBRARY_PATH=${CONDA_PREFIX}/lib python run.py || exit 1
fi
popd
done
cd ../c
Expand Down
67 changes: 67 additions & 0 deletions dpctl/sycl.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Copyright 2022 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.

# distutils: language = c++
# cython: language_level=3

# SYCL static imports for Cython

from . cimport _backend as dpctl_backend


cdef extern from "CL/sycl.hpp" namespace "sycl":
cdef cppclass queue "sycl::queue":
pass

cdef cppclass device "sycl::device":
pass

cdef cppclass context "sycl::context":
pass

cdef cppclass event "sycl::event":
pass

cdef cppclass kernel "sycl::kernel":
pass

cdef cppclass executable_kernel_bundle \
"sycl::kernel_bundle<sycl::bundle_state::executable>":
pass

cdef extern from "syclinterface/dpctl_sycl_type_casters.hpp" \
namespace "dpctl::syclinterface":
# queue
cdef dpctl_backend.DPCTLSyclQueueRef wrap_queue \
"dpctl::syclinterface::wrap<sycl::queue>" (const queue *)
cdef queue * unwrap_queue "dpctl::syclinterface::unwrap<sycl::queue>" (
dpctl_backend.DPCTLSyclQueueRef)

# device
cdef dpctl_backend.DPCTLSyclDeviceRef wrap_device \
"dpctl::syclinterface::wrap<sycl::device>" (const device *)
cdef device * unwrap_device "dpctl::syclinterface::unwrap<sycl::device>" (
dpctl_backend.DPCTLSyclDeviceRef)

# context
cdef dpctl_backend.DPCTLSyclContextRef wrap_context \
"dpctl::syclinterface::wrap<sycl::context>" (const context *)
cdef context * unwrap_context "dpctl::syclinterface::unwrap<sycl::context>" (
dpctl_backend.DPCTLSyclContextRef)

# event
cdef dpctl_backend.DPCTLSyclEventRef wrap_event \
"dpctl::syclinterface::wrap<sycl::event>" (const event *)
cdef event * unwrap_event "dpctl::syclinterface::unwrap<sycl::event>" (
dpctl_backend.DPCTLSyclEventRef)
2 changes: 2 additions & 0 deletions examples/cython/use_dpctl_sycl/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
use_dpctl_sycl/_cython_api.cpp
*~
20 changes: 20 additions & 0 deletions examples/cython/use_dpctl_sycl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Example illustrating use of dpctl.sycl in Cython

Dpctl include `dpctl/sycl.pxd` file with incomplete definitions
of SYCL runtime classes and conversion routines from SYCLInterface
library opaque pointers to pointers to these SYCL classes.

This files simplifies usage of SYCL routines from Python extensions
written in Cython.

## Building

```bash
python setup.py develop
```

## Testing

```bash
python -m pytest tests
```
53 changes: 53 additions & 0 deletions examples/cython/use_dpctl_sycl/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Data Parallel Control (dpctl)
#
# Copyright 2020-2022 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 Cython.Build
import setuptools
from setuptools.command.build_ext import build_ext as build_ext_base

import dpctl


class custom_build_ext(build_ext_base):
def build_extensions(self):
self.compiler.set_executable("compiler_so", "icx -fsycl -fPIC")
self.compiler.set_executable("compiler_cxx", "icpx -fsycl -fPIC")
self.compiler.set_executable(
"linker_so",
"icpx -fsycl -shared -fpic -fsycl-device-code-split=per_kernel",
)
super().build_extensions()


ext = setuptools.Extension(
"use_dpctl_sycl._cython_api",
["./use_dpctl_sycl/_cython_api.pyx"],
include_dirs=[dpctl.get_include(), "./use_dpctl_sycl"],
language="c++",
)

(cythonized_ext,) = Cython.Build.cythonize(
[
ext,
]
)

setuptools.setup(
name="use_dpctl_sycl",
version="0.0.0",
ext_modules=[cythonized_ext],
cmdclass={"build_ext": custom_build_ext},
)
48 changes: 48 additions & 0 deletions examples/cython/use_dpctl_sycl/tests/test_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Data Parallel Control (dpctl)
#
# Copyright 2020-2022 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
import use_dpctl_sycl

import dpctl


def test_device_name():
try:
d = dpctl.SyclDevice()
except dpctl.SyclDeviceCreationError:
pytest.skip("Could not create default device. Nothing to do")
d_n = use_dpctl_sycl.device_name(d)
assert d_n.decode("utf-8") == d.name


def test_device_driver_version():
try:
d = dpctl.SyclDevice()
except dpctl.SyclDeviceCreationError:
pytest.skip("Could not create default device. Nothing to do")
d_dv = use_dpctl_sycl.device_driver_version(d)
assert d_dv.decode("utf-8") == d.driver_version


def test_device_copy():
try:
d = dpctl.SyclDevice()
except dpctl.SyclDeviceCreationError:
pytest.skip("Could not create default device. Nothing to do")
d_copy = use_dpctl_sycl.device_copy(d)
assert d_copy == d
assert d_copy.addressof_ref() != d.addressof_ref()
23 changes: 23 additions & 0 deletions examples/cython/use_dpctl_sycl/use_dpctl_sycl/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Data Parallel Control (dpctl)
#
# Copyright 2020-2022 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 ._cython_api import device_copy, device_driver_version, device_name

__all__ = [
"device_name",
"device_driver_version",
"device_copy",
]
53 changes: 53 additions & 0 deletions examples/cython/use_dpctl_sycl/use_dpctl_sycl/_cython_api.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Data Parallel Control (dpctl)
#
# Copyright 2020-2022 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.

# distutils: language = c++
# cython: language_level=3
# cython: linetrace=True

cimport libcpp.string

cimport dpctl
cimport dpctl.sycl


cdef extern from "utils.hpp":
cdef libcpp.string.string get_device_name(dpctl.sycl.device)
cdef libcpp.string.string get_device_driver_version(dpctl.sycl.device)
cdef dpctl.sycl.device *copy_device(dpctl.sycl.device)


def device_name(dpctl.SyclDevice dev):
cdef dpctl.DPCTLSyclDeviceRef d_ref = dev.get_device_ref()
cdef const dpctl.sycl.device *dpcpp_device = dpctl.sycl.unwrap_device(d_ref)

return get_device_name(dpcpp_device[0])


def device_driver_version(dpctl.SyclDevice dev):
cdef dpctl.DPCTLSyclDeviceRef d_ref = dev.get_device_ref()
cdef const dpctl.sycl.device *dpcpp_device = dpctl.sycl.unwrap_device(d_ref)

return get_device_driver_version(dpcpp_device[0])


cpdef dpctl.SyclDevice device_copy(dpctl.SyclDevice dev):
cdef dpctl.DPCTLSyclDeviceRef d_ref = dev.get_device_ref()
cdef const dpctl.sycl.device *dpcpp_device = dpctl.sycl.unwrap_device(d_ref)
cdef dpctl.sycl.device *copied_device = copy_device(dpcpp_device[0])
cdef dpctl.DPCTLSyclDeviceRef copied_d_ref = dpctl.sycl.wrap_device(copied_device)

return dpctl.SyclDevice._create(copied_d_ref)
20 changes: 20 additions & 0 deletions examples/cython/use_dpctl_sycl/use_dpctl_sycl/utils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

#include <CL/sycl.hpp>
#include <string>

std::string get_device_name(sycl::device d)
{
return d.get_info<sycl::info::device::name>();
}

std::string get_device_driver_version(sycl::device d)
{
return d.get_info<sycl::info::device::driver_version>();
}

sycl::device *copy_device(const sycl::device &d)
{
auto copy_ptr = new sycl::device(d);
return copy_ptr;
}