Skip to content

Commit 7219c50

Browse files
authored
Merge pull request #277 from diptorupd/feature/device_manager
Feature/device manager
2 parents a0495d4 + a8e49c5 commit 7219c50

23 files changed

+1163
-224
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ __pycache__/
88
*.so
99
*.exe
1010
*.lib
11+
*.dll
1112

1213
# CMake build and local install directory
1314
build

conda-recipe/bld.bat

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
call "%ONEAPI_ROOT%\compiler\latest\env\vars.bat"
2-
IF %ERRORLEVEL% NEQ 0 (
3-
echo "oneAPI compiler activation failed"
4-
exit /b 1
2+
if errorlevel 1 (
3+
echo "oneAPI compiler activation failed"
4+
exit /b 1
55
)
66

77
"%PYTHON%" setup.py clean --all
88
"%PYTHON%" setup.py install
9-
IF %ERRORLEVEL% NEQ 0 exit /b 1
9+
if errorlevel 1 exit 1
1010

1111
rem Build wheel package
1212
if NOT "%WHEELS_OUTPUT_FOLDER%"=="" (

conda-recipe/run_test.bat

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
call "%ONEAPI_ROOT%\compiler\latest\env\vars.bat"
2-
IF %ERRORLEVEL% NEQ 0 (
2+
if errorlevel 1 (
33
echo "oneAPI compiler activation failed%"
44
exit /b 1
55
)
@@ -9,7 +9,7 @@ set ERRORLEVEL=
99
@echo on
1010

1111
"%PYTHON%" -c "import dpctl"
12-
IF %ERRORLEVEL% NEQ 0 exit /b 1
12+
if errorlevel 1 exit 1
1313

1414
pytest -q -ra --disable-warnings --pyargs dpctl -vv
15-
IF %ERRORLEVEL% NEQ 0 exit /b 1
15+
if errorlevel 1 exit 1

dpctl-capi/CMakeLists.txt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ if(WIN32)
4141
set(CMAKE_LINKER:PATH "${DPCPP_ROOT}/bin/lld-link")
4242
message(STATUS "Resetting CXX compiler to: " ${CMAKE_CXX_COMPILER})
4343
message(STATUS "Resetting C compiler to: " ${CMAKE_C_COMPILER})
44-
message(STATUS "Resetting Linker to: " ${CMAKE_LINK})
44+
message(STATUS "Resetting Linker to: " ${CMAKE_LINKER})
4545
set(WARNING_FLAGS "-Wall -Wextra -Winit-self -Wunused-function -Wuninitialized -Wmissing-declarations")
4646
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS}")
4747
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS} -Qstd=c++17")
@@ -108,10 +108,8 @@ if(DPCTL_ENABLE_LO_PROGRAM_CREATION)
108108
endif()
109109

110110
install(
111-
TARGETS
112-
DPCTLSyclInterface
113-
LIBRARY DESTINATION
114-
"${CMAKE_INSTALL_PREFIX}/lib/"
111+
TARGETS DPCTLSyclInterface
112+
LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/
115113
)
116114

117115
# Install all headers

dpctl-capi/cmake/modules/FindDPCPP.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,14 @@ if(${dpcpp_result} MATCHES "0")
100100
set(DPCPP_SYCL_LIBRARY ${DPCPP_INSTALL_DIR}/lib/libsycl.so)
101101
set(DPCPP_OPENCL_LIBRARY ${DPCPP_INSTALL_DIR}/lib/libOpenCL.so)
102102
endif()
103+
set(DPCPP_FOUND TRUE)
103104
else()
104105
message(STATUS "DPCPP needed to build dpctl_sycl_interface")
105106
return()
106107
endif()
107108

108109
find_package_handle_standard_args(DPCPP DEFAULT_MSG
110+
DPCPP_FOUND
109111
DPCPP_VERSION
110112
DPCPP_INCLUDE_DIR
111113
DPCPP_SYCL_INCLUDE_DIR

dpctl-capi/include/dpctl_sycl_device_interface.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,6 @@ DPCTL_API
6969
__dpctl_give DPCTLSyclDeviceRef DPCTLDevice_CreateFromSelector(
7070
__dpctl_keep const DPCTLSyclDeviceSelectorRef DSRef);
7171

72-
/*!
73-
* @brief Prints out some of the info::deivice attributes for the device.
74-
*
75-
* @param DRef A DPCTLSyclDeviceRef pointer.
76-
*/
77-
DPCTL_API
78-
void DPCTLDevice_DumpInfo(__dpctl_keep const DPCTLSyclDeviceRef DRef);
79-
8072
/*!
8173
* @brief Deletes a DPCTLSyclDeviceRef pointer after casting to to sycl::device.
8274
*
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
//===-- dpctl_sycl_device_manager.h - A manager for sycl devices -*-C++-*- ===//
2+
//
3+
// Data Parallel Control (dpCtl)
4+
//
5+
// Copyright 2020-2021 Intel Corporation
6+
//
7+
// Licensed under the Apache License, Version 2.0 (the "License");
8+
// you may not use this file except in compliance with the License.
9+
// You may obtain a copy of the License at
10+
//
11+
// http://www.apache.org/licenses/LICENSE-2.0
12+
//
13+
// Unless required by applicable law or agreed to in writing, software
14+
// distributed under the License is distributed on an "AS IS" BASIS,
15+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
// See the License for the specific language governing permissions and
17+
// limitations under the License.
18+
//
19+
//===----------------------------------------------------------------------===//
20+
///
21+
/// \file
22+
/// This file declares a set of helper functions to query about the available
23+
/// SYCL devices and backends on the system.
24+
///
25+
//===----------------------------------------------------------------------===//
26+
27+
#pragma once
28+
29+
#include "Support/DllExport.h"
30+
#include "Support/ExternC.h"
31+
#include "Support/MemOwnershipAttrs.h"
32+
#include "dpctl_data_types.h"
33+
#include "dpctl_sycl_types.h"
34+
#include "dpctl_vector.h"
35+
36+
DPCTL_C_EXTERN_C_BEGIN
37+
38+
/**
39+
* @defgroup DeviceManager Device management helper functions
40+
*/
41+
42+
/*!
43+
* @brief Contains a #DPCTLSyclDeviceRef and #DPCTLSyclContextRef 2-tuple that
44+
* contains a sycl::device and a sycl::context associated with that device.
45+
*/
46+
typedef struct DeviceAndContextPair
47+
{
48+
DPCTLSyclDeviceRef DRef;
49+
DPCTLSyclContextRef CRef;
50+
} DPCTL_DeviceAndContextPair;
51+
52+
// Declares a set of types abd functions to deal with vectors of
53+
// DPCTLSyclDeviceRef. Refer dpctl_vector_macros.h
54+
DPCTL_DECLARE_VECTOR(Device)
55+
56+
/*!
57+
* @brief Checks if two ::DPCTLSyclDeviceRef objects point to the same
58+
* sycl::device.
59+
*
60+
* DPC++ 2021.1.2 has some bugs that prevent the equality of sycl::device
61+
* objects to work correctly. The DPCTLDeviceMgr_AreEq implements a workaround
62+
* to check if two sycl::device pointers are equivalent. Since, DPC++ uses
63+
* std::shared_pointer wrappers for sycl::device objects we check if the raw
64+
* pointer (shared_pointer.get()) for each device are the same. One caveat is
65+
* that the trick works only for non-host devices. The function evaluates host
66+
* devices separately and always assumes that all host devices are equivalent,
67+
* while checking for the raw pointer equivalent for all other types of devices.
68+
* The workaround will be removed once DPC++ is fixed to correctly check device
69+
* equivalence.
70+
*
71+
* @param DRef1 First opaque pointer to a sycl device.
72+
* @param DRef2 Second opaque pointer to a sycl device.
73+
* @return True if the underlying sycl::device are same, false otherwise.
74+
* @ingroup DeviceManager
75+
*/
76+
bool DPCTLDeviceMgr_AreEq(__dpctl_keep const DPCTLSyclDeviceRef DRef1,
77+
__dpctl_keep const DPCTLSyclDeviceRef DRef2);
78+
79+
/*!
80+
* @brief Returns a pointer to a std::vector<sycl::DPCTLSyclDeviceRef>
81+
* containing the set of ::DPCTLSyclDeviceRef pointers matching the passed in
82+
* device_identifier bit flag.
83+
*
84+
* The device_identifier can be a combination of #DPCTLSyclBackendType and
85+
* #DPCTLSyclDeviceType bit flags. The function returns all devices that
86+
* match the specified bit flags. For example,
87+
*
88+
* @code
89+
* // Returns all opencl devices
90+
* DPCTLDeviceMgr_GetDevices(DPCTLSyclBackendType::DPCTL_OPENCL);
91+
*
92+
* // Returns all opencl gpu devices
93+
* DPCTLDeviceMgr_GetDevices(
94+
* DPCTLSyclBackendType::DPCTL_OPENCL|DPCTLSyclDeviceType::DPCTL_GPU);
95+
*
96+
* // Returns all gpu devices
97+
* DPCTLDeviceMgr_GetDevices(DPCTLSyclDeviceType::DPCTL_GPU);
98+
* @endcode
99+
*
100+
* @param device_identifier A bitflag that can be any combination of
101+
* #DPCTLSyclBackendType and #DPCTLSyclDeviceType
102+
* enum values.
103+
* @return A #DPCTLDeviceVectorRef containing #DPCTLSyclDeviceRef objects
104+
* that match the device identifier bit flags.
105+
* @ingroup DeviceManager
106+
*/
107+
DPCTL_API
108+
__dpctl_give DPCTLDeviceVectorRef
109+
DPCTLDeviceMgr_GetDevices(int device_identifier);
110+
111+
/*!
112+
* @brief Returns the default sycl context inside an opaque DPCTLSyclContextRef
113+
* pointer for the DPCTLSyclDeviceRef input argument.
114+
*
115+
* @param DRef A pointer to a sycl::device that will be used to
116+
* search an internal map containing a cached "default"
117+
* sycl::context for the device.
118+
* @return A #DPCTL_DeviceAndContextPair struct containing the cached
119+
* #DPCTLSyclContextRef associated with the #DPCTLSyclDeviceRef argument passed
120+
* to the function. The DPCTL_DeviceAndContextPair also contains a
121+
* #DPCTLSyclDeviceRef pointer pointing to the same device as the input
122+
* #DPCTLSyclDeviceRef. The returned #DPCTLSyclDeviceRef was cached along with
123+
* the #DPCTLSyclContextRef. This is a workaround till device equality is
124+
* properly fixed in DPC++. If the #DPCTLSyclDeviceRef is not found in the cache
125+
* then DPCTL_DeviceAndContextPair contains a pair of nullptr.
126+
* @ingroup DeviceManager
127+
*/
128+
DPCTL_API
129+
DPCTL_DeviceAndContextPair DPCTLDeviceMgr_GetDeviceAndContextPair(
130+
__dpctl_keep const DPCTLSyclDeviceRef DRef);
131+
132+
/*!
133+
* @brief Get the number of available devices for given backend and device type
134+
* combination.
135+
*
136+
* @param device_identifier Identifies a device using a combination of
137+
* #DPCTLSyclBackendType and #DPCTLSyclDeviceType
138+
* enum values. The argument can be either one of
139+
* the enum values or a bitwise OR-ed combination.
140+
* @return The number of available devices satisfying the condition specified
141+
* by the device_identifier bit flag.
142+
* @ingroup DeviceManager
143+
*/
144+
DPCTL_API
145+
size_t DPCTLDeviceMgr_GetNumDevices(int device_identifier);
146+
147+
/*!
148+
* @brief Prints out the info::deivice attributes for the device that are
149+
* currently supported by dpCtl.
150+
*
151+
* @param DRef A #DPCTLSyclDeviceRef opaque pointer.
152+
* @ingroup DeviceManager
153+
*/
154+
DPCTL_API
155+
void DPCTLDeviceMgr_PrintDeviceInfo(__dpctl_keep const DPCTLSyclDeviceRef DRef);
156+
157+
DPCTL_C_EXTERN_C_END

dpctl-capi/source/dpctl_sycl_device_interface.cpp

Lines changed: 7 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,9 @@
2727
#include "dpctl_sycl_device_interface.h"
2828
#include "../helper/include/dpctl_utils_helper.h"
2929
#include "Support/CBindingWrapping.h"
30+
#include "dpctl_sycl_device_manager.h"
3031
#include <CL/sycl.hpp> /* SYCL headers */
3132
#include <cstring>
32-
#include <iomanip>
33-
#include <iostream>
3433

3534
using namespace cl::sycl;
3635

@@ -41,31 +40,6 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(device, DPCTLSyclDeviceRef)
4140
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(device_selector, DPCTLSyclDeviceSelectorRef)
4241
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(platform, DPCTLSyclPlatformRef)
4342

44-
/*!
45-
* @brief Helper function to print the metadata for a sycl::device.
46-
*
47-
* @param Device My Param doc
48-
*/
49-
void dump_device_info(const device &Device)
50-
{
51-
std::stringstream ss;
52-
53-
ss << std::setw(4) << " " << std::left << std::setw(16) << "Name"
54-
<< Device.get_info<info::device::name>() << '\n';
55-
ss << std::setw(4) << " " << std::left << std::setw(16) << "Driver version"
56-
<< Device.get_info<info::device::driver_version>() << '\n';
57-
ss << std::setw(4) << " " << std::left << std::setw(16) << "Vendor"
58-
<< Device.get_info<info::device::vendor>() << '\n';
59-
ss << std::setw(4) << " " << std::left << std::setw(16) << "Profile"
60-
<< Device.get_info<info::device::profile>() << '\n';
61-
ss << std::setw(4) << " " << std::left << std::setw(16) << "Device type";
62-
63-
auto devTy = Device.get_info<info::device::device_type>();
64-
ss << DPCTL_DeviceTypeToStr(devTy);
65-
66-
std::cout << ss.str();
67-
}
68-
6943
} /* end of anonymous namespace */
7044

7145
__dpctl_give DPCTLSyclDeviceRef
@@ -123,18 +97,6 @@ __dpctl_give DPCTLSyclDeviceRef DPCTLDevice_CreateFromSelector(
12397
}
12498
}
12599

126-
/*!
127-
* Prints some of the device info metadata for the device corresponding to the
128-
* specified sycl::queue. Currently, device name, driver version, device
129-
* vendor, and device profile are printed out. More attributed may be added
130-
* later.
131-
*/
132-
void DPCTLDevice_DumpInfo(__dpctl_keep const DPCTLSyclDeviceRef DRef)
133-
{
134-
auto Device = unwrap(DRef);
135-
dump_device_info(*Device);
136-
}
137-
138100
void DPCTLDevice_Delete(__dpctl_take DPCTLSyclDeviceRef DRef)
139101
{
140102
delete unwrap(DRef);
@@ -432,11 +394,11 @@ bool DPCTLDevice_IsHostUnifiedMemory(__dpctl_keep const DPCTLSyclDeviceRef DRef)
432394
return ret;
433395
}
434396

435-
bool DPCTLDevice_AreEq(__dpctl_keep const DPCTLSyclDeviceRef DevRef1,
436-
__dpctl_keep const DPCTLSyclDeviceRef DevRef2)
397+
bool DPCTLDevice_AreEq(__dpctl_keep const DPCTLSyclDeviceRef DRef1,
398+
__dpctl_keep const DPCTLSyclDeviceRef DRef2)
437399
{
438-
if (!(DevRef1 && DevRef2))
439-
// \todo handle error
440-
return false;
441-
return (*unwrap(DevRef1) == *unwrap(DevRef2));
400+
// Note: DPCPP does not yet support device equality of the form:
401+
// *unwrap(DevRef1) == *unwrap(DevRef2). Till DPCPP is fixed we use the
402+
// custom equality checker implemented inside DPCTLDeviceMgr.
403+
return DPCTLDeviceMgr_AreEq(DRef1, DRef2);
442404
}

0 commit comments

Comments
 (0)