Skip to content

Commit 851628b

Browse files
Move usm_ndarray into dpctl_ext.tensor (#2807)
This PR proposes to migrate the tensor interface (`usm_ndarray, dlpack, flags`) into `dpctl_ext/tensor` making `dpnp` independent of `dpctl's` tensor module. Updates: > - Introduce `dpctl_ext_capi.h` > - Implement a clean CMake interface library `DpctlExtCAPI` to properly propagate generated headers to consumers > - Update remaining imports from `dpctl.tensor` to `dpctl_ext.tensor` > - Link all backend extensions against `DpctlExtCAPI` to ensure consistent access to the C-API
1 parent 8d1c75b commit 851628b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+7532
-658
lines changed

.github/workflows/build-sphinx.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
name: Build and Deploy Docs
2727

2828
runs-on: ubuntu-22.04
29-
timeout-minutes: 60
29+
timeout-minutes: 90
3030

3131
permissions:
3232
# Needed to cancel any previous runs that are not completed for a given workflow

.github/workflows/generate_coverage.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
name: Generate coverage and push to Coveralls.io
1212

1313
runs-on: ubuntu-latest
14-
timeout-minutes: 120
14+
timeout-minutes: 150
1515

1616
permissions:
1717
# Needed to cancel any previous runs that are not completed for a given workflow
@@ -122,7 +122,7 @@ jobs:
122122
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
123123
with:
124124
shell: bash
125-
timeout_minutes: 60
125+
timeout_minutes: 120
126126
max_attempts: 5
127127
retry_on: error
128128
command: |

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,4 @@ core
3636
# TODO: revert to `dpctl/`
3737
# when dpnp fully migrates dpctl/tensor
3838
dpctl_ext/**/*.cpython*.so
39+
dpctl_ext/include/

CMakeLists.txt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,5 +344,16 @@ if(DEFINED SKBUILD)
344344
set(_ignore_me ${SKBUILD})
345345
endif()
346346

347-
add_subdirectory(dpnp)
347+
# DpctlExtCAPI: Interface library for dpctl_ext C-API
348+
# Provides access to:
349+
# 1. Public C-API headers from dpctl_ext/apis/include
350+
# 2. Generated Cython headers via per-target header interface libraries
351+
352+
add_library(DpctlExtCAPI INTERFACE)
353+
target_include_directories(
354+
DpctlExtCAPI
355+
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/dpctl_ext/apis/include
356+
)
357+
348358
add_subdirectory(dpctl_ext)
359+
add_subdirectory(dpnp)

dpctl_ext/CMakeLists.txt

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,99 @@ else()
112112
endif()
113113

114114
# at build time create include/ directory and copy header files over
115-
# set(DPCTL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
115+
set(DPCTL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
116116

117117
set(CMAKE_INSTALL_RPATH "$ORIGIN")
118118

119+
function(build_dpctl_ext _trgt _src _dest)
120+
set(options SYCL)
121+
cmake_parse_arguments(BUILD_DPCTL_EXT "${options}" "RELATIVE_PATH" "" ${ARGN})
122+
add_cython_target(${_trgt} ${_src} CXX OUTPUT_VAR _generated_src)
123+
set(_cythonize_trgt "${_trgt}_cythonize_pyx")
124+
python_add_library(${_trgt} MODULE WITH_SOABI ${_generated_src})
125+
if(BUILD_DPCTL_EXT_SYCL)
126+
add_sycl_to_target(TARGET ${_trgt} SOURCES ${_generated_src})
127+
target_compile_options(${_trgt} PRIVATE -fno-sycl-id-queries-fit-in-int)
128+
target_link_options(${_trgt} PRIVATE -fsycl-device-code-split=per_kernel)
129+
if(DPCTL_OFFLOAD_COMPRESS)
130+
target_link_options(${_trgt} PRIVATE --offload-compress)
131+
endif()
132+
if(_dpctl_sycl_targets)
133+
# make fat binary
134+
target_compile_options(
135+
${_trgt}
136+
PRIVATE ${_dpctl_sycl_target_compile_options}
137+
)
138+
target_link_options(${_trgt} PRIVATE ${_dpctl_sycl_target_link_options})
139+
endif()
140+
endif()
141+
target_link_libraries(${_trgt} PRIVATE Python::NumPy)
142+
if(DPCTL_GENERATE_COVERAGE)
143+
target_compile_definitions(${_trgt} PRIVATE CYTHON_TRACE=1 CYTHON_TRACE_NOGIL=1)
144+
if(BUILD_DPCTL_EXT_SYCL)
145+
target_compile_options(${_trgt} PRIVATE -fno-sycl-use-footer)
146+
endif()
147+
endif()
148+
# Dpctl
149+
target_include_directories(${_trgt} PRIVATE ${Dpctl_INCLUDE_DIR})
150+
target_link_directories(${_trgt} PRIVATE ${Dpctl_INCLUDE_DIR}/..)
151+
target_link_libraries(${_trgt} PRIVATE DPCTLSyclInterface)
152+
set(_linker_options "LINKER:${DPCTL_LDFLAGS}")
153+
target_link_options(${_trgt} PRIVATE ${_linker_options})
154+
get_filename_component(_name_wle ${_generated_src} NAME_WLE)
155+
get_filename_component(_generated_src_dir ${_generated_src} DIRECTORY)
156+
set(_generated_public_h "${_generated_src_dir}/${_name_wle}.h")
157+
set(_generated_api_h "${_generated_src_dir}/${_name_wle}_api.h")
158+
159+
# TODO: create separate folder inside build folder that contains only
160+
# headers related to this target and appropriate folder structure to
161+
# eliminate shadow dependencies
162+
# Go up two levels to build root for "dpctl_ext/tensor/_usmarray.h" resolution
163+
get_filename_component(_parent_dir ${_generated_src_dir} DIRECTORY)
164+
get_filename_component(_build_root ${_parent_dir} DIRECTORY)
165+
# TODO: do not set directory if we did not generate header
166+
target_include_directories(${_trgt} INTERFACE ${_build_root})
167+
set(_rpath_value "$ORIGIN")
168+
if(BUILD_DPCTL_EXT_RELATIVE_PATH)
169+
set(_rpath_value "${_rpath_value}/${BUILD_DPCTL_EXT_RELATIVE_PATH}")
170+
endif()
171+
if(DPCTL_WITH_REDIST)
172+
set(_rpath_value "${_rpath_value}:${_rpath_value}/../../..")
173+
endif()
174+
set_target_properties(${_trgt} PROPERTIES INSTALL_RPATH ${_rpath_value})
175+
176+
install(TARGETS ${_trgt} LIBRARY DESTINATION ${_dest})
177+
install(
178+
FILES ${_generated_api_h}
179+
DESTINATION ${CMAKE_INSTALL_PREFIX}/dpctl_ext/include/${_dest}
180+
OPTIONAL
181+
)
182+
install(
183+
FILES ${_generated_public_h}
184+
DESTINATION ${CMAKE_INSTALL_PREFIX}/dpctl_ext/include/${_dest}
185+
OPTIONAL
186+
)
187+
if(DPCTL_GENERATE_COVERAGE)
188+
get_filename_component(_original_src_dir ${_src} DIRECTORY)
189+
file(RELATIVE_PATH _rel_dir ${CMAKE_SOURCE_DIR} ${_original_src_dir})
190+
install(FILES ${_generated_src} DESTINATION ${CMAKE_INSTALL_PREFIX}/${_rel_dir})
191+
endif()
192+
193+
# Create target with headers only, because python is managing all the
194+
# library imports at runtime
195+
set(_trgt_headers ${_trgt}_headers)
196+
add_library(${_trgt_headers} INTERFACE)
197+
add_dependencies(${_trgt_headers} ${_trgt})
198+
get_target_property(_trgt_headers_dir ${_trgt} INTERFACE_INCLUDE_DIRECTORIES)
199+
target_include_directories(${_trgt_headers} INTERFACE ${_trgt_headers_dir})
200+
endfunction()
201+
202+
# Install dpctl_ext C-API headers (similar to dpctl's C-API installation)
203+
install(
204+
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/apis/include/
205+
DESTINATION ${CMAKE_INSTALL_PREFIX}/dpctl_ext/include
206+
FILES_MATCHING
207+
REGEX "\\.h(pp)?$"
208+
)
209+
119210
add_subdirectory(tensor)
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
//*****************************************************************************
2+
// Copyright (c) 2026, Intel Corporation
3+
// All rights reserved.
4+
//
5+
// Redistribution and use in source and binary forms, with or without
6+
// modification, are permitted provided that the following conditions are met:
7+
// - Redistributions of source code must retain the above copyright notice,
8+
// this list of conditions and the following disclaimer.
9+
// - Redistributions in binary form must reproduce the above copyright notice,
10+
// this list of conditions and the following disclaimer in the documentation
11+
// and/or other materials provided with the distribution.
12+
// - Neither the name of the copyright holder nor the names of its contributors
13+
// may be used to endorse or promote products derived from this software
14+
// without specific prior written permission.
15+
//
16+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20+
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26+
// THE POSSIBILITY OF SUCH DAMAGE.
27+
//*****************************************************************************
28+
//
29+
//===---------------------------------------------------------------------===//
30+
///
31+
/// \file
32+
/// This file provides access to dpctl_ext's C-API, including:
33+
/// - dpctl C-API (from external dpctl package - SYCL interface)
34+
/// - dpctl_ext tensor C-API (usm_ndarray)
35+
//===---------------------------------------------------------------------===//
36+
37+
#pragma once
38+
39+
// Include dpctl C-API headers explicitly from external dpctl package (SYCL
40+
// interface)
41+
// TODO: Once dpctl removes its tensor module and stabilizes dpctl_capi.h,
42+
// we can simplify to just: #include "dpctl_capi.h"
43+
// For now, explicit includes ensure we only get SYCL interface without tensor.
44+
45+
#include "syclinterface/dpctl_sycl_extension_interface.h"
46+
#include "syclinterface/dpctl_sycl_types.h"
47+
48+
#ifdef __cplusplus
49+
#define CYTHON_EXTERN_C extern "C"
50+
#else
51+
#define CYTHON_EXTERN_C
52+
#endif
53+
54+
#include "dpctl/_sycl_context.h"
55+
#include "dpctl/_sycl_context_api.h"
56+
#include "dpctl/_sycl_device.h"
57+
#include "dpctl/_sycl_device_api.h"
58+
#include "dpctl/_sycl_event.h"
59+
#include "dpctl/_sycl_event_api.h"
60+
#include "dpctl/_sycl_queue.h"
61+
#include "dpctl/_sycl_queue_api.h"
62+
#include "dpctl/memory/_memory.h"
63+
#include "dpctl/memory/_memory_api.h"
64+
#include "dpctl/program/_program.h"
65+
#include "dpctl/program/_program_api.h"
66+
67+
// Include the generated Cython C-API headers for usm_ndarray
68+
// These headers are generated during build and placed in the build directory
69+
#include "dpctl_ext/tensor/_usmarray.h"
70+
#include "dpctl_ext/tensor/_usmarray_api.h"
71+
72+
/*
73+
* Function to import dpctl_ext C-API and make it available.
74+
* This imports both:
75+
* - dpctl C-API (from external dpctl package - SYCL interface)
76+
* - dpctl_ext C-API (tensor interface - usm_ndarray)
77+
*
78+
* C functions can use dpctl_ext's C-API functions without linking to
79+
* shared objects defining these symbols, if they call `import_dpctl_ext()`
80+
* prior to using those symbols.
81+
*
82+
* It is declared inline to allow multiple definitions in
83+
* different translation units.
84+
*
85+
* TODO: When dpctl_ext is renamed to dpctl.tensor:
86+
* - Rename this file: dpctl_ext_capi.h → dpctl/tensor/tensor_capi.h
87+
* (Use tensor_capi.h, NOT dpctl_capi.h, to avoid conflict with external
88+
* dpctl)
89+
* - Rename this function: import_dpctl_ext() → import_dpctl_tensor()
90+
* - Include external dpctl_capi.h and simplify imports to use import_dpctl()
91+
*/
92+
static inline void import_dpctl_ext(void)
93+
{
94+
// Import dpctl SYCL interface
95+
// TODO: Once dpctl removes its tensor module and stabilizes dpctl_capi.h,
96+
// we can simplify to just: import_dpctl()
97+
import_dpctl___sycl_device();
98+
import_dpctl___sycl_context();
99+
import_dpctl___sycl_event();
100+
import_dpctl___sycl_queue();
101+
import_dpctl__memory___memory();
102+
import_dpctl__program___program();
103+
// Import dpctl_ext tensor interface
104+
import_dpctl_ext__tensor___usmarray();
105+
return;
106+
}

dpctl_ext/tensor/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@
2929

3030
find_package(Python COMPONENTS Development.Module)
3131

32+
file(GLOB _cython_sources *.pyx)
33+
foreach(_cy_file ${_cython_sources})
34+
get_filename_component(_trgt ${_cy_file} NAME_WLE)
35+
build_dpctl_ext(${_trgt} ${_cy_file} "dpctl_ext/tensor" RELATIVE_PATH "..")
36+
target_include_directories(${_trgt} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
37+
# target_link_libraries(DpctlCAPI INTERFACE ${_trgt}_headers)
38+
target_link_libraries(DpctlExtCAPI INTERFACE ${_trgt}_headers)
39+
endforeach()
40+
3241
if(WIN32)
3342
if(${CMAKE_VERSION} VERSION_LESS "3.27")
3443
# this is a work-around for target_link_options inserting option after -link option, cause
@@ -338,6 +347,7 @@ foreach(python_module_name ${_py_trgts})
338347
# dpctl4pybind11.hpp. It will allow to simplify dependency tree
339348
# NOTE: dpctl C-API is resolved at runtime via Python
340349
# target_link_libraries(${python_module_name} PRIVATE DpctlCAPI)
350+
target_link_libraries(${python_module_name} PRIVATE DpctlExtCAPI)
341351
if(DPNP_WITH_REDIST)
342352
set_target_properties(
343353
${python_module_name}

dpctl_ext/tensor/__init__.pxd

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# *****************************************************************************
2+
# Copyright (c) 2026, Intel Corporation
3+
# All rights reserved.
4+
#
5+
# Redistribution and use in source and binary forms, with or without
6+
# modification, are permitted provided that the following conditions are met:
7+
# - Redistributions of source code must retain the above copyright notice,
8+
# this list of conditions and the following disclaimer.
9+
# - Redistributions in binary form must reproduce the above copyright notice,
10+
# this list of conditions and the following disclaimer in the documentation
11+
# and/or other materials provided with the distribution.
12+
# - Neither the name of the copyright holder nor the names of its contributors
13+
# may be used to endorse or promote products derived from this software
14+
# without specific prior written permission.
15+
#
16+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26+
# THE POSSIBILITY OF SUCH DAMAGE.
27+
# *****************************************************************************
28+
29+
""" This file declares the extension types and functions for the Cython API
30+
implemented in _usmarray.pyx file.
31+
"""
32+
33+
# distutils: language = c++
34+
# cython: language_level=3
35+
36+
from ._usmarray cimport *

0 commit comments

Comments
 (0)