From fdb48499e80bd2f2144a1d9cdacdcc89d8aeb81c Mon Sep 17 00:00:00 2001 From: Martin Morrison-Grant Date: Mon, 6 Nov 2023 12:05:19 +0000 Subject: [PATCH] [NATIVECPU] Move Native CPU adapter to UR. --- .github/CODEOWNERS | 3 + CMakeLists.txt | 1 + README.md | 1 + source/adapters/CMakeLists.txt | 5 + source/adapters/native_cpu/.clang-format | 4 + source/adapters/native_cpu/CMakeLists.txt | 58 ++ source/adapters/native_cpu/adapter.cpp | 73 +++ source/adapters/native_cpu/command_buffer.cpp | 133 +++++ source/adapters/native_cpu/common.cpp | 34 ++ source/adapters/native_cpu/common.hpp | 70 +++ source/adapters/native_cpu/context.cpp | 103 ++++ source/adapters/native_cpu/context.hpp | 21 + source/adapters/native_cpu/device.cpp | 400 +++++++++++++ source/adapters/native_cpu/device.hpp | 19 + source/adapters/native_cpu/enqueue.cpp | 533 ++++++++++++++++++ source/adapters/native_cpu/event.cpp | 89 +++ source/adapters/native_cpu/image.cpp | 175 ++++++ source/adapters/native_cpu/kernel.cpp | 284 ++++++++++ source/adapters/native_cpu/kernel.hpp | 90 +++ source/adapters/native_cpu/memory.cpp | 172 ++++++ source/adapters/native_cpu/memory.hpp | 75 +++ .../adapters/native_cpu/nativecpu_state.hpp | 57 ++ source/adapters/native_cpu/platform.cpp | 117 ++++ source/adapters/native_cpu/platform.hpp | 20 + source/adapters/native_cpu/program.cpp | 188 ++++++ source/adapters/native_cpu/program.hpp | 42 ++ source/adapters/native_cpu/queue.cpp | 88 +++ source/adapters/native_cpu/queue.hpp | 12 + source/adapters/native_cpu/sampler.cpp | 69 +++ .../native_cpu/ur_interface_loader.cpp | 280 +++++++++ source/adapters/native_cpu/usm.cpp | 141 +++++ source/adapters/native_cpu/usm_p2p.cpp | 27 + test/conformance/CMakeLists.txt | 6 +- 33 files changed, 3389 insertions(+), 1 deletion(-) create mode 100644 source/adapters/native_cpu/.clang-format create mode 100644 source/adapters/native_cpu/CMakeLists.txt create mode 100644 source/adapters/native_cpu/adapter.cpp create mode 100644 source/adapters/native_cpu/command_buffer.cpp create mode 100644 source/adapters/native_cpu/common.cpp create mode 100644 source/adapters/native_cpu/common.hpp create mode 100644 source/adapters/native_cpu/context.cpp create mode 100644 source/adapters/native_cpu/context.hpp create mode 100644 source/adapters/native_cpu/device.cpp create mode 100644 source/adapters/native_cpu/device.hpp create mode 100644 source/adapters/native_cpu/enqueue.cpp create mode 100644 source/adapters/native_cpu/event.cpp create mode 100644 source/adapters/native_cpu/image.cpp create mode 100644 source/adapters/native_cpu/kernel.cpp create mode 100644 source/adapters/native_cpu/kernel.hpp create mode 100644 source/adapters/native_cpu/memory.cpp create mode 100644 source/adapters/native_cpu/memory.hpp create mode 100644 source/adapters/native_cpu/nativecpu_state.hpp create mode 100644 source/adapters/native_cpu/platform.cpp create mode 100644 source/adapters/native_cpu/platform.hpp create mode 100644 source/adapters/native_cpu/program.cpp create mode 100644 source/adapters/native_cpu/program.hpp create mode 100644 source/adapters/native_cpu/queue.cpp create mode 100644 source/adapters/native_cpu/queue.hpp create mode 100644 source/adapters/native_cpu/sampler.cpp create mode 100644 source/adapters/native_cpu/ur_interface_loader.cpp create mode 100644 source/adapters/native_cpu/usm.cpp create mode 100644 source/adapters/native_cpu/usm_p2p.cpp diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 4643296368..39e77dccd9 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -10,6 +10,9 @@ source/adapters/hip @oneapi-src/unified-runtime-hip-write # OpenCL adapter source/adapters/opencl @oneapi-src/unified-runtime-opencl-write +# SYCL Native CPU adapter +source/adapters/native_cpu @oneapi-src/unified-runtime-native-cpu-write + # Command-buffer experimental feature source/adapters/**/command_buffer.* @oneapi-src/unified-runtime-command-buffer-write scripts/core/EXP-COMMAND-BUFFER.rst @oneapi-src/unified-runtime-command-buffer-write diff --git a/CMakeLists.txt b/CMakeLists.txt index 1210375dd8..189a03a9cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ option(UR_BUILD_ADAPTER_L0 "build level 0 adapter from SYCL" OFF) option(UR_BUILD_ADAPTER_OPENCL "build opencl adapter from SYCL" OFF) option(UR_BUILD_ADAPTER_CUDA "build cuda adapter from SYCL" OFF) option(UR_BUILD_ADAPTER_HIP "build hip adapter from SYCL" OFF) +option(UR_BUILD_ADAPTER_NATIVE_CPU "build native_cpu adapter from SYCL" OFF) option(UR_BUILD_EXAMPLE_CODEGEN "Build the codegen example." OFF) option(VAL_USE_LIBBACKTRACE_BACKTRACE "enable libbacktrace validation backtrace for linux" OFF) diff --git a/README.md b/README.md index 4917add660..f8da59198b 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,7 @@ List of options provided by CMake: | UR_BUILD_ADAPTER_OPENCL | Fetch and use opencl adapter from SYCL | ON/OFF | OFF | | UR_BUILD_ADAPTER_CUDA | Fetch and use cuda adapter from SYCL | ON/OFF | OFF | | UR_BUILD_ADAPTER_HIP | Fetch and use hip adapter from SYCL | ON/OFF | OFF | +| UR_BUILD_ADAPTER_NATIVE_CPU | Fetch and use native-cpu adapter from SYCL | ON/OFF | OFF | | UR_HIP_PLATFORM | Build hip adapter for AMD or NVIDIA platform | AMD/NVIDIA | AMD | | UR_ENABLE_COMGR | Enable comgr lib usage | AMD/NVIDIA | AMD | diff --git a/source/adapters/CMakeLists.txt b/source/adapters/CMakeLists.txt index 14b6130efa..d2b5ac0294 100644 --- a/source/adapters/CMakeLists.txt +++ b/source/adapters/CMakeLists.txt @@ -47,3 +47,8 @@ endif() if(UR_BUILD_ADAPTER_OPENCL) add_subdirectory(opencl) endif() + +if(UR_BUILD_ADAPTER_NATIVE_CPU) + add_subdirectory(native_cpu) +endif() + diff --git a/source/adapters/native_cpu/.clang-format b/source/adapters/native_cpu/.clang-format new file mode 100644 index 0000000000..c8daebc205 --- /dev/null +++ b/source/adapters/native_cpu/.clang-format @@ -0,0 +1,4 @@ +--- +Language: Cpp +BasedOnStyle: LLVM +... diff --git a/source/adapters/native_cpu/CMakeLists.txt b/source/adapters/native_cpu/CMakeLists.txt new file mode 100644 index 0000000000..a15e7aac84 --- /dev/null +++ b/source/adapters/native_cpu/CMakeLists.txt @@ -0,0 +1,58 @@ +# Copyright (C) 2023 Intel Corporation +# Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions. +# See LICENSE.TXT +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +set(NATIVE_CPU_DIR "${CMAKE_CURRENT_SOURCE_DIR}" CACHE PATH "Native CPU adapter directory") + +set(TARGET_NAME ur_adapter_native_cpu) + +add_ur_adapter(${TARGET_NAME} + SHARED + ${CMAKE_CURRENT_SOURCE_DIR}/adapter.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/command_buffer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/common.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/common.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/context.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/context.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/device.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/device.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/enqueue.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/event.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/image.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/kernel.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/kernel.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/memory.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/memory.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/nativecpu_state.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/platform.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/platform.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/program.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/program.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/queue.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/queue.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/sampler.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ur_interface_loader.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/usm_p2p.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/usm.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/../../ur/ur.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/../../ur/ur.hpp +) + +set_target_properties(${TARGET_NAME} PROPERTIES + VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}" + SOVERSION "${PROJECT_VERSION_MAJOR}" +) + +find_package(Threads REQUIRED) + +target_link_libraries(${TARGET_NAME} PRIVATE + ${PROJECT_NAME}::headers + ${PROJECT_NAME}::common + ${PROJECT_NAME}::unified_malloc_framework + Threads::Threads +) + +target_include_directories(${TARGET_NAME} PRIVATE + "${CMAKE_CURRENT_SOURCE_DIR}/../../" +) diff --git a/source/adapters/native_cpu/adapter.cpp b/source/adapters/native_cpu/adapter.cpp new file mode 100644 index 0000000000..082653b7be --- /dev/null +++ b/source/adapters/native_cpu/adapter.cpp @@ -0,0 +1,73 @@ +//===--------- adapter.cpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "common.hpp" +#include "ur_api.h" + +struct ur_adapter_handle_t_ { + std::atomic RefCount = 0; +} Adapter; + +UR_APIEXPORT ur_result_t UR_APICALL urInit(ur_device_init_flags_t, + ur_loader_config_handle_t) { + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urTearDown(void *) { + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urAdapterGet( + uint32_t, ur_adapter_handle_t *phAdapters, uint32_t *pNumAdapters) { + if (phAdapters) { + Adapter.RefCount++; + *phAdapters = &Adapter; + } + if (pNumAdapters) { + *pNumAdapters = 1; + } + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urAdapterRelease(ur_adapter_handle_t) { + Adapter.RefCount--; + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urAdapterRetain(ur_adapter_handle_t) { + Adapter.RefCount++; + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urAdapterGetLastError( + ur_adapter_handle_t, const char **ppMessage, int32_t *pError) { + *ppMessage = ErrorMessage; + *pError = ErrorMessageCode; + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urAdapterGetInfo(ur_adapter_handle_t, + ur_adapter_info_t propName, + size_t propSize, + void *pPropValue, + size_t *pPropSizeRet) { + UrReturnHelper ReturnValue(propSize, pPropValue, pPropSizeRet); + + switch (propName) { + case UR_ADAPTER_INFO_BACKEND: + return ReturnValue(UR_ADAPTER_BACKEND_NATIVE_CPU); + case UR_ADAPTER_INFO_REFERENCE_COUNT: + return ReturnValue(Adapter.RefCount.load()); + default: + return UR_RESULT_ERROR_INVALID_ENUMERATION; + } + + return UR_RESULT_SUCCESS; +} diff --git a/source/adapters/native_cpu/command_buffer.cpp b/source/adapters/native_cpu/command_buffer.cpp new file mode 100644 index 0000000000..e26b6db730 --- /dev/null +++ b/source/adapters/native_cpu/command_buffer.cpp @@ -0,0 +1,133 @@ +//===--------- command_buffer.cpp - Native CPU Adapter --------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "common.hpp" + +/// Stub implementations of UR experimental feature command-buffers +/// Taken almost unchanged from another adapter. Perhaps going forward +/// these stubs could be defined in core UR as the default which would +/// reduce code duplication. Adapters could then "override" these defaults. + +UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferCreateExp( + ur_context_handle_t, ur_device_handle_t, + const ur_exp_command_buffer_desc_t *, ur_exp_command_buffer_handle_t *) { + detail::ur::die("Experimental Command-buffer feature is not " + "implemented for the NativeCPU adapter."); + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urCommandBufferRetainExp(ur_exp_command_buffer_handle_t) { + detail::ur::die("Experimental Command-buffer feature is not " + "implemented for the NativeCPU adapter."); + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urCommandBufferReleaseExp(ur_exp_command_buffer_handle_t) { + detail::ur::die("Experimental Command-buffer feature is not " + "implemented for the NativeCPU adapter."); + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urCommandBufferFinalizeExp(ur_exp_command_buffer_handle_t) { + detail::ur::die("Experimental Command-buffer feature is not " + "implemented for the NativeCPU adapter."); + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferAppendKernelLaunchExp( + ur_exp_command_buffer_handle_t, ur_kernel_handle_t, uint32_t, + const size_t *, const size_t *, const size_t *, uint32_t, + const ur_exp_command_buffer_sync_point_t *, + ur_exp_command_buffer_sync_point_t *) { + detail::ur::die("Experimental Command-buffer feature is not " + "implemented for the NativeCPU adapter."); + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferAppendMemcpyUSMExp( + ur_exp_command_buffer_handle_t, void *, const void *, size_t, uint32_t, + const ur_exp_command_buffer_sync_point_t *, + ur_exp_command_buffer_sync_point_t *) { + detail::ur::die("Experimental Command-buffer feature is not " + "implemented for the NativeCPU adapter."); + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferAppendMembufferCopyExp( + ur_exp_command_buffer_handle_t, ur_mem_handle_t, ur_mem_handle_t, size_t, + size_t, size_t, uint32_t, const ur_exp_command_buffer_sync_point_t *, + ur_exp_command_buffer_sync_point_t *) { + detail::ur::die("Experimental Command-buffer feature is not " + "implemented for the NativeCPU adapter."); + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferAppendMembufferCopyRectExp( + ur_exp_command_buffer_handle_t, ur_mem_handle_t, ur_mem_handle_t, + ur_rect_offset_t, ur_rect_offset_t, ur_rect_region_t, size_t, size_t, + size_t, size_t, uint32_t, const ur_exp_command_buffer_sync_point_t *, + ur_exp_command_buffer_sync_point_t *) { + detail::ur::die("Experimental Command-buffer feature is not " + "implemented for the NativeCPU adapter."); + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT +ur_result_t UR_APICALL urCommandBufferAppendMembufferWriteExp( + ur_exp_command_buffer_handle_t, ur_mem_handle_t, size_t, size_t, + const void *, uint32_t, const ur_exp_command_buffer_sync_point_t *, + ur_exp_command_buffer_sync_point_t *) { + detail::ur::die("Experimental Command-buffer feature is not " + "implemented for the NativeCPU adapter."); + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT +ur_result_t UR_APICALL urCommandBufferAppendMembufferReadExp( + ur_exp_command_buffer_handle_t, ur_mem_handle_t, size_t, size_t, void *, + uint32_t, const ur_exp_command_buffer_sync_point_t *, + ur_exp_command_buffer_sync_point_t *) { + detail::ur::die("Experimental Command-buffer feature is not " + "implemented for the NativeCPU adapter."); + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT +ur_result_t UR_APICALL urCommandBufferAppendMembufferWriteRectExp( + ur_exp_command_buffer_handle_t, ur_mem_handle_t, ur_rect_offset_t, + ur_rect_offset_t, ur_rect_region_t, size_t, size_t, size_t, size_t, void *, + uint32_t, const ur_exp_command_buffer_sync_point_t *, + ur_exp_command_buffer_sync_point_t *) { + detail::ur::die("Experimental Command-buffer feature is not " + "implemented for the NativeCPU adapter."); + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT +ur_result_t UR_APICALL urCommandBufferAppendMembufferReadRectExp( + ur_exp_command_buffer_handle_t, ur_mem_handle_t, ur_rect_offset_t, + ur_rect_offset_t, ur_rect_region_t, size_t, size_t, size_t, size_t, void *, + uint32_t, const ur_exp_command_buffer_sync_point_t *, + ur_exp_command_buffer_sync_point_t *) { + detail::ur::die("Experimental Command-buffer feature is not " + "implemented for the NativeCPU adapter."); + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferEnqueueExp( + ur_exp_command_buffer_handle_t, ur_queue_handle_t, uint32_t, + const ur_event_handle_t *, ur_event_handle_t *) { + detail::ur::die("Experimental Command-buffer feature is not " + "implemented for the NativeCPU adapter."); + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} diff --git a/source/adapters/native_cpu/common.cpp b/source/adapters/native_cpu/common.cpp new file mode 100644 index 0000000000..bbf85a9884 --- /dev/null +++ b/source/adapters/native_cpu/common.cpp @@ -0,0 +1,34 @@ +//===--------- common.cpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "common.hpp" + +// Global variables for UR_RESULT_ADAPTER_SPECIFIC_ERROR +// See urGetLastResult +thread_local ur_result_t ErrorMessageCode = UR_RESULT_SUCCESS; +thread_local char ErrorMessage[MaxMessageSize]; + +// Utility function for setting a message and warning +[[maybe_unused]] void setErrorMessage(const char *pMessage, + ur_result_t ErrorCode) { + assert(strlen(pMessage) <= MaxMessageSize); + strcpy(ErrorMessage, pMessage); + ErrorMessageCode = ErrorCode; +} + +ur_result_t urGetLastResult(ur_platform_handle_t, const char **ppMessage) { + *ppMessage = &ErrorMessage[0]; + return ErrorMessageCode; +} + +void detail::ur::die(const char *pMessage) { + std::cerr << "ur_die: " << pMessage << '\n'; + std::terminate(); +} diff --git a/source/adapters/native_cpu/common.hpp b/source/adapters/native_cpu/common.hpp new file mode 100644 index 0000000000..018509f189 --- /dev/null +++ b/source/adapters/native_cpu/common.hpp @@ -0,0 +1,70 @@ +//===--------- common.hpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "ur/ur.hpp" + +constexpr size_t MaxMessageSize = 256; + +extern thread_local ur_result_t ErrorMessageCode; +extern thread_local char ErrorMessage[MaxMessageSize]; + +#define DIE_NO_IMPLEMENTATION \ + if (PrintTrace) { \ + std::cerr << "Not Implemented : " << __FUNCTION__ \ + << " - File : " << __FILE__; \ + std::cerr << " / Line : " << __LINE__ << std::endl; \ + } \ + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + +#define CONTINUE_NO_IMPLEMENTATION \ + if (PrintTrace) { \ + std::cerr << "Warning : Not Implemented : " << __FUNCTION__ \ + << " - File : " << __FILE__; \ + std::cerr << " / Line : " << __LINE__ << std::endl; \ + } \ + return UR_RESULT_SUCCESS; + +#define CASE_UR_UNSUPPORTED(not_supported) \ + case not_supported: \ + if (PrintTrace) { \ + std::cerr << std::endl \ + << "Unsupported UR case : " << #not_supported << " in " \ + << __FUNCTION__ << ":" << __LINE__ << "(" << __FILE__ << ")" \ + << std::endl; \ + } \ + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + +/// ------ Error handling, matching OpenCL plugin semantics. +/// Taken from other adapter +namespace detail { +namespace ur { + +// Report error and no return (keeps compiler from printing warnings). +// TODO: Probably change that to throw a catchable exception, +// but for now it is useful to see every failure. +// +[[noreturn]] void die(const char *pMessage); +} // namespace ur +} // namespace detail + +// Base class to store common data +struct _ur_object { + ur_shared_mutex Mutex; +}; + +struct RefCounted { + std::atomic_uint32_t _refCount; + void incrementReferenceCount() { _refCount++; } + void decrementReferenceCount() { _refCount--; } + RefCounted() : _refCount{1} {} + uint32_t getReferenceCount() const { return _refCount; } +}; diff --git a/source/adapters/native_cpu/context.cpp b/source/adapters/native_cpu/context.cpp new file mode 100644 index 0000000000..e8732646f5 --- /dev/null +++ b/source/adapters/native_cpu/context.cpp @@ -0,0 +1,103 @@ +//===--------- context.cpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include + +#include "ur/ur.hpp" +#include "ur_api.h" + +#include "common.hpp" +#include "context.hpp" + +UR_APIEXPORT ur_result_t UR_APICALL +urContextCreate(uint32_t DeviceCount, const ur_device_handle_t *phDevices, + const ur_context_properties_t *pProperties, + ur_context_handle_t *phContext) { + std::ignore = pProperties; + assert(DeviceCount == 1); + + // TODO: Proper error checking. + auto ctx = new ur_context_handle_t_(*phDevices); + *phContext = ctx; + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urContextRetain(ur_context_handle_t hContext) { + std::ignore = hContext; + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL +urContextRelease(ur_context_handle_t hContext) { + delete hContext; + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urContextGetInfo(ur_context_handle_t hContext, ur_context_info_t propName, + size_t propSize, void *pPropValue, size_t *pPropSizeRet) { + UrReturnHelper returnValue(propSize, pPropValue, pPropSizeRet); + + switch (propName) { + case UR_CONTEXT_INFO_NUM_DEVICES: + return returnValue(1); + case UR_CONTEXT_INFO_DEVICES: + return returnValue(hContext->_device); + case UR_CONTEXT_INFO_REFERENCE_COUNT: + return returnValue(nullptr); + case UR_CONTEXT_INFO_USM_MEMCPY2D_SUPPORT: + return returnValue(true); + case UR_CONTEXT_INFO_USM_FILL2D_SUPPORT: + // case UR_CONTEXT_INFO_USM_MEMSET2D_SUPPORT: + // 2D USM operations currently not supported. + return returnValue(false); + case UR_CONTEXT_INFO_ATOMIC_MEMORY_ORDER_CAPABILITIES: + case UR_CONTEXT_INFO_ATOMIC_MEMORY_SCOPE_CAPABILITIES: + case UR_CONTEXT_INFO_ATOMIC_FENCE_ORDER_CAPABILITIES: + case UR_CONTEXT_INFO_ATOMIC_FENCE_SCOPE_CAPABILITIES: { + return UR_RESULT_ERROR_ADAPTER_SPECIFIC; + } + default: + return UR_RESULT_ERROR_INVALID_ENUMERATION; + } +} + +UR_APIEXPORT ur_result_t UR_APICALL urContextGetNativeHandle( + ur_context_handle_t hContext, ur_native_handle_t *phNativeContext) { + std::ignore = hContext; + std::ignore = phNativeContext; + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL urContextCreateWithNativeHandle( + ur_native_handle_t hNativeContext, uint32_t numDevices, + const ur_device_handle_t *phDevices, + const ur_context_native_properties_t *pProperties, + ur_context_handle_t *phContext) { + std::ignore = hNativeContext; + std::ignore = numDevices; + std::ignore = phDevices; + std::ignore = pProperties; + std::ignore = phContext; + + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL urContextSetExtendedDeleter( + ur_context_handle_t hContext, ur_context_extended_deleter_t pfnDeleter, + void *pUserData) { + std::ignore = hContext; + std::ignore = pfnDeleter; + std::ignore = pUserData; + + DIE_NO_IMPLEMENTATION +} diff --git a/source/adapters/native_cpu/context.hpp b/source/adapters/native_cpu/context.hpp new file mode 100644 index 0000000000..04404d7988 --- /dev/null +++ b/source/adapters/native_cpu/context.hpp @@ -0,0 +1,21 @@ +//===--------- context.hpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include + +#include "device.hpp" + +struct ur_context_handle_t_ { + ur_context_handle_t_(ur_device_handle_t_ *phDevices) : _device{phDevices} {} + + ur_device_handle_t _device; +}; diff --git a/source/adapters/native_cpu/device.cpp b/source/adapters/native_cpu/device.cpp new file mode 100644 index 0000000000..4df06cc596 --- /dev/null +++ b/source/adapters/native_cpu/device.cpp @@ -0,0 +1,400 @@ +//===--------- device.cpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include + +#include "platform.hpp" + +UR_APIEXPORT ur_result_t UR_APICALL urDeviceGet(ur_platform_handle_t hPlatform, + ur_device_type_t DeviceType, + uint32_t NumEntries, + ur_device_handle_t *phDevices, + uint32_t *pNumDevices) { + UR_ASSERT(hPlatform, UR_RESULT_ERROR_INVALID_NULL_HANDLE); + + const bool AskingForAll = DeviceType == UR_DEVICE_TYPE_ALL; + const bool AskingForDefault = DeviceType == UR_DEVICE_TYPE_DEFAULT; + const bool AskingForCPU = DeviceType == UR_DEVICE_TYPE_CPU; + const bool ValidDeviceType = AskingForDefault || AskingForAll || AskingForCPU; + uint32_t DeviceCount = ValidDeviceType ? 1 : 0; + + if (pNumDevices) { + *pNumDevices = DeviceCount; + } + + if (NumEntries == 0) { + /// Runtime queries number of devices + if (phDevices != nullptr) { + if (PrintTrace) { + std::cerr << "Invalid Arguments for urDevicesGet\n"; + } + return UR_RESULT_ERROR_INVALID_VALUE; + } + return UR_RESULT_SUCCESS; + } + + if (DeviceCount == 0) { + /// No CPU entry to fill 'Device' array + return UR_RESULT_SUCCESS; + } + + if (phDevices) { + phDevices[0] = &hPlatform->TheDevice; + } + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice, + ur_device_info_t propName, + size_t propSize, + void *pPropValue, + size_t *pPropSizeRet) { + UR_ASSERT(hDevice, UR_RESULT_ERROR_INVALID_NULL_HANDLE); + UrReturnHelper ReturnValue(propSize, pPropValue, pPropSizeRet); + + switch (propName) { + case UR_DEVICE_INFO_TYPE: + return ReturnValue(UR_DEVICE_TYPE_CPU); + case UR_DEVICE_INFO_PARENT_DEVICE: + return ReturnValue(nullptr); + case UR_DEVICE_INFO_PLATFORM: + return ReturnValue(hDevice->Platform); + case UR_DEVICE_INFO_NAME: + return ReturnValue("SYCL Native CPU"); + case UR_DEVICE_INFO_IMAGE_SUPPORTED: + return ReturnValue(bool{false}); + case UR_DEVICE_INFO_DRIVER_VERSION: + return ReturnValue("0.0.0"); + case UR_DEVICE_INFO_VENDOR: + return ReturnValue("Intel(R) Corporation"); + case UR_DEVICE_INFO_BACKEND_RUNTIME_VERSION: + // TODO : CHECK + return ReturnValue("0.0.0"); + case UR_DEVICE_INFO_IMAGE2D_MAX_WIDTH: + return ReturnValue(size_t{8192}); + case UR_DEVICE_INFO_IMAGE2D_MAX_HEIGHT: + return ReturnValue(size_t{8192}); + case UR_DEVICE_INFO_IMAGE_MAX_BUFFER_SIZE: + return ReturnValue(size_t(65536 /*todo: min if aspect::image*/)); + case UR_DEVICE_INFO_MAX_SAMPLERS: + return ReturnValue(uint32_t{16 /*todo: min if aspect::image*/}); + case UR_DEVICE_INFO_HOST_UNIFIED_MEMORY: + return ReturnValue(bool{1}); + case UR_DEVICE_INFO_EXTENSIONS: + // TODO : Populate return string accordingly - e.g. cl_khr_fp16, + // cl_khr_fp64, cl_khr_int64_base_atomics, + // cl_khr_int64_extended_atomics + return ReturnValue("cl_khr_fp64 "); + case UR_DEVICE_INFO_VERSION: + return ReturnValue("0.1"); + case UR_DEVICE_INFO_COMPILER_AVAILABLE: + return ReturnValue(bool{false}); + case UR_DEVICE_INFO_LINKER_AVAILABLE: + return ReturnValue(bool{false}); + case UR_DEVICE_INFO_MAX_COMPUTE_UNITS: + return ReturnValue(uint32_t{256}); + case UR_DEVICE_INFO_PARTITION_MAX_SUB_DEVICES: + return ReturnValue(uint32_t{0}); + case UR_DEVICE_INFO_SUPPORTED_PARTITIONS: + // TODO: Ensure this property is tested correctly + // Taken from CUDA ur adapter + if (pPropSizeRet) { + *pPropSizeRet = 0; + } + return UR_RESULT_SUCCESS; + case UR_DEVICE_INFO_VENDOR_ID: + // '0x8086' : 'Intel HD graphics vendor ID' + return ReturnValue(uint32_t{0x8086}); + case UR_DEVICE_INFO_MAX_WORK_GROUP_SIZE: + return ReturnValue(size_t{256}); + case UR_DEVICE_INFO_MEM_BASE_ADDR_ALIGN: + // Imported from level_zero + return ReturnValue(uint32_t{8}); + case UR_DEVICE_INFO_IMAGE3D_MAX_WIDTH: + case UR_DEVICE_INFO_IMAGE3D_MAX_HEIGHT: + case UR_DEVICE_INFO_IMAGE3D_MAX_DEPTH: + // Default minimum values required by the SYCL specification. + return ReturnValue(size_t{2048}); + case UR_DEVICE_INFO_HALF_FP_CONFIG: { + // todo: + ur_device_fp_capability_flags_t HalfFPValue = 0; + return ReturnValue(HalfFPValue); + } + case UR_DEVICE_INFO_SINGLE_FP_CONFIG: { + // todo + ur_device_fp_capability_flags_t SingleFPValue = 0; + return ReturnValue(SingleFPValue); + } + case UR_DEVICE_INFO_DOUBLE_FP_CONFIG: { + ur_device_fp_capability_flags_t DoubleFPValue = 0; + return ReturnValue(DoubleFPValue); + } + case UR_DEVICE_INFO_MAX_WORK_ITEM_DIMENSIONS: + return ReturnValue(uint32_t{3}); + case UR_DEVICE_INFO_PARTITION_TYPE: + return ReturnValue(ur_device_partition_property_t{}); + case UR_EXT_DEVICE_INFO_OPENCL_C_VERSION: + return ReturnValue(""); + case UR_DEVICE_INFO_QUEUE_PROPERTIES: + return ReturnValue( + ur_queue_flag_t(UR_QUEUE_FLAG_OUT_OF_ORDER_EXEC_MODE_ENABLE | + UR_QUEUE_FLAG_PROFILING_ENABLE)); + case UR_DEVICE_INFO_MAX_WORK_ITEM_SIZES: { + struct { + size_t Arr[3]; + } MaxGroupSize = {{256, 256, 1}}; + return ReturnValue(MaxGroupSize); + } + case UR_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_CHAR: + case UR_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_SHORT: + case UR_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_INT: + case UR_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_LONG: + case UR_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_FLOAT: + case UR_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_DOUBLE: + case UR_DEVICE_INFO_PREFERRED_VECTOR_WIDTH_HALF: + case UR_DEVICE_INFO_NATIVE_VECTOR_WIDTH_CHAR: + case UR_DEVICE_INFO_NATIVE_VECTOR_WIDTH_SHORT: + case UR_DEVICE_INFO_NATIVE_VECTOR_WIDTH_INT: + case UR_DEVICE_INFO_NATIVE_VECTOR_WIDTH_LONG: + case UR_DEVICE_INFO_NATIVE_VECTOR_WIDTH_FLOAT: + case UR_DEVICE_INFO_NATIVE_VECTOR_WIDTH_DOUBLE: + case UR_DEVICE_INFO_NATIVE_VECTOR_WIDTH_HALF: + return ReturnValue(uint32_t{1}); + + // Imported from level_zero + case UR_DEVICE_INFO_USM_HOST_SUPPORT: + case UR_DEVICE_INFO_USM_DEVICE_SUPPORT: + case UR_DEVICE_INFO_USM_SINGLE_SHARED_SUPPORT: + case UR_DEVICE_INFO_USM_CROSS_SHARED_SUPPORT: + case UR_DEVICE_INFO_USM_SYSTEM_SHARED_SUPPORT: { + uint64_t Supported = 0; + // TODO[1.0]: how to query for USM support now? + if (true) { + // TODO: Use ze_memory_access_capabilities_t + Supported = UR_DEVICE_USM_ACCESS_CAPABILITY_FLAG_ACCESS | + UR_DEVICE_USM_ACCESS_CAPABILITY_FLAG_ATOMIC_ACCESS | + UR_DEVICE_USM_ACCESS_CAPABILITY_FLAG_CONCURRENT_ACCESS | + UR_DEVICE_USM_ACCESS_CAPABILITY_FLAG_ATOMIC_CONCURRENT_ACCESS; + } + return ReturnValue(Supported); + } + case UR_DEVICE_INFO_ADDRESS_BITS: + return ReturnValue( + uint32_t{sizeof(void *) * std::numeric_limits::digits}); + case UR_DEVICE_INFO_MAX_CLOCK_FREQUENCY: + return ReturnValue(uint32_t{1000}); + case UR_DEVICE_INFO_ENDIAN_LITTLE: + return ReturnValue(bool{true}); + case UR_DEVICE_INFO_AVAILABLE: + return ReturnValue(bool{true}); + case UR_DEVICE_INFO_MAX_READ_IMAGE_ARGS: + case UR_DEVICE_INFO_MAX_WRITE_IMAGE_ARGS: + /// TODO : Check + return ReturnValue(uint32_t{0}); + case UR_DEVICE_INFO_IMAGE_MAX_ARRAY_SIZE: + /// TODO : Check + return ReturnValue(size_t{0}); + case UR_DEVICE_INFO_MAX_PARAMETER_SIZE: + /// TODO : Check + return ReturnValue(size_t{32}); + case UR_DEVICE_INFO_GLOBAL_MEM_CACHE_TYPE: + return ReturnValue(UR_DEVICE_MEM_CACHE_TYPE_READ_WRITE_CACHE); + case UR_DEVICE_INFO_GLOBAL_MEM_CACHELINE_SIZE: + // TODO : CHECK + return ReturnValue(uint32_t{64}); + case UR_DEVICE_INFO_GLOBAL_MEM_CACHE_SIZE: + // TODO : CHECK + return ReturnValue(uint64_t{0}); + case UR_DEVICE_INFO_GLOBAL_MEM_SIZE: + // TODO : CHECK + return ReturnValue(uint64_t{0}); + case UR_DEVICE_INFO_LOCAL_MEM_SIZE: + // TODO : CHECK + return ReturnValue(uint64_t{0}); + case UR_DEVICE_INFO_MAX_CONSTANT_BUFFER_SIZE: + // TODO : CHECK + return ReturnValue(uint64_t{0}); + case UR_DEVICE_INFO_MAX_CONSTANT_ARGS: + // TODO : CHECK + return ReturnValue(uint32_t{64}); + case UR_DEVICE_INFO_LOCAL_MEM_TYPE: + // TODO : CHECK + return ReturnValue(UR_DEVICE_LOCAL_MEM_TYPE_LOCAL); + case UR_DEVICE_INFO_ERROR_CORRECTION_SUPPORT: + return ReturnValue(bool{false}); + case UR_DEVICE_INFO_PROFILING_TIMER_RESOLUTION: + // TODO : CHECK + return ReturnValue(size_t{0}); + case UR_DEVICE_INFO_BUILT_IN_KERNELS: + // TODO : CHECK + return ReturnValue(""); + case UR_DEVICE_INFO_PRINTF_BUFFER_SIZE: + // TODO : CHECK + return ReturnValue(size_t{1024}); + case UR_DEVICE_INFO_PREFERRED_INTEROP_USER_SYNC: + return ReturnValue(bool{false}); + case UR_DEVICE_INFO_PARTITION_AFFINITY_DOMAIN: + return ReturnValue(ur_device_affinity_domain_flags_t{0}); + case UR_DEVICE_INFO_MAX_MEM_ALLOC_SIZE: + // TODO : CHECK + return ReturnValue(uint64_t{0}); + case UR_DEVICE_INFO_EXECUTION_CAPABILITIES: + // TODO : CHECK + return ReturnValue(ur_device_exec_capability_flags_t{ + UR_DEVICE_EXEC_CAPABILITY_FLAG_KERNEL}); + case UR_DEVICE_INFO_PROFILE: + return ReturnValue("FULL_PROFILE"); + case UR_DEVICE_INFO_REFERENCE_COUNT: + // TODO : CHECK + return ReturnValue(uint32_t{0}); + case UR_DEVICE_INFO_BUILD_ON_SUBDEVICE: + return ReturnValue(bool{0}); + case UR_DEVICE_INFO_ATOMIC_64: + return ReturnValue(bool{0}); + case UR_DEVICE_INFO_BFLOAT16: + return ReturnValue(bool{0}); + case UR_DEVICE_INFO_MEM_CHANNEL_SUPPORT: + return ReturnValue(bool{0}); + case UR_DEVICE_INFO_IMAGE_SRGB: + return ReturnValue(bool{0}); + case UR_DEVICE_INFO_SUB_GROUP_SIZES_INTEL: + return ReturnValue(uint32_t{1}); + case UR_DEVICE_INFO_GPU_EU_COUNT: + case UR_DEVICE_INFO_PCI_ADDRESS: + case UR_DEVICE_INFO_GPU_EU_SLICES: + case UR_DEVICE_INFO_GPU_EU_COUNT_PER_SUBSLICE: + case UR_DEVICE_INFO_GPU_SUBSLICES_PER_SLICE: + case UR_DEVICE_INFO_GPU_EU_SIMD_WIDTH: + case UR_DEVICE_INFO_GPU_HW_THREADS_PER_EU: + case UR_DEVICE_INFO_UUID: + case UR_DEVICE_INFO_DEVICE_ID: + case UR_DEVICE_INFO_MAX_NUM_SUB_GROUPS: + case UR_DEVICE_INFO_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS: + case UR_DEVICE_INFO_IL_VERSION: + case UR_DEVICE_INFO_MAX_WORK_GROUPS_3D: + case UR_DEVICE_INFO_MEMORY_CLOCK_RATE: + case UR_DEVICE_INFO_MEMORY_BUS_WIDTH: + return UR_RESULT_ERROR_INVALID_VALUE; + case UR_DEVICE_INFO_ATOMIC_MEMORY_ORDER_CAPABILITIES: { + ur_memory_order_capability_flags_t Capabilities = + UR_MEMORY_ORDER_CAPABILITY_FLAG_RELAXED | + UR_MEMORY_ORDER_CAPABILITY_FLAG_ACQUIRE | + UR_MEMORY_ORDER_CAPABILITY_FLAG_RELEASE | + UR_MEMORY_ORDER_CAPABILITY_FLAG_ACQ_REL; + return ReturnValue(Capabilities); + } + case UR_DEVICE_INFO_ATOMIC_MEMORY_SCOPE_CAPABILITIES: { + uint64_t Capabilities = UR_MEMORY_SCOPE_CAPABILITY_FLAG_WORK_ITEM | + UR_MEMORY_SCOPE_CAPABILITY_FLAG_SUB_GROUP | + UR_MEMORY_SCOPE_CAPABILITY_FLAG_WORK_GROUP | + UR_MEMORY_SCOPE_CAPABILITY_FLAG_DEVICE; + return ReturnValue(Capabilities); + } + case UR_DEVICE_INFO_ESIMD_SUPPORT: + return ReturnValue(false); + + CASE_UR_UNSUPPORTED(UR_DEVICE_INFO_MAX_MEMORY_BANDWIDTH); + + default: + DIE_NO_IMPLEMENTATION; + } + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urDeviceRetain(ur_device_handle_t hDevice) { + UR_ASSERT(hDevice, UR_RESULT_ERROR_INVALID_NULL_HANDLE) + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urDeviceRelease(ur_device_handle_t hDevice) { + UR_ASSERT(hDevice, UR_RESULT_ERROR_INVALID_NULL_HANDLE) + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urDevicePartition( + ur_device_handle_t hDevice, + const ur_device_partition_properties_t *pProperties, uint32_t NumDevices, + ur_device_handle_t *phSubDevices, uint32_t *pNumDevicesRet) { + std::ignore = hDevice; + std::ignore = NumDevices; + std::ignore = pProperties; + std::ignore = phSubDevices; + std::ignore = pNumDevicesRet; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetNativeHandle( + ur_device_handle_t hDevice, ur_native_handle_t *phNativeDevice) { + std::ignore = hDevice; + std::ignore = phNativeDevice; + + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL urDeviceCreateWithNativeHandle( + ur_native_handle_t hNativeDevice, ur_platform_handle_t hPlatform, + const ur_device_native_properties_t *pProperties, + ur_device_handle_t *phDevice) { + std::ignore = hNativeDevice; + std::ignore = hPlatform; + std::ignore = pProperties; + std::ignore = phDevice; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetGlobalTimestamps( + ur_device_handle_t hDevice, uint64_t *pDeviceTimestamp, + uint64_t *pHostTimestamp) { + std::ignore = hDevice; // todo + if (pHostTimestamp) { + using namespace std::chrono; + *pHostTimestamp = + duration_cast(steady_clock::now().time_since_epoch()) + .count(); + } + if (pDeviceTimestamp) { + // todo: calculate elapsed time properly + using namespace std::chrono; + *pDeviceTimestamp = + duration_cast(steady_clock::now().time_since_epoch()) + .count(); + } + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urDeviceSelectBinary( + ur_device_handle_t hDevice, const ur_device_binary_t *pBinaries, + uint32_t NumBinaries, uint32_t *pSelectedBinary) { + std::ignore = hDevice; + std::ignore = pBinaries; + std::ignore = NumBinaries; + std::ignore = pSelectedBinary; + +#define UR_DEVICE_BINARY_TARGET_NATIVE_CPU "native_cpu" + // look for a binary with type "native_cpu" + // Todo: error checking + // Todo: define UR_DEVICE_BINARY_TARGET_NATIVE_CPU in upstream + const char *image_target = UR_DEVICE_BINARY_TARGET_NATIVE_CPU; + for (uint32_t i = 0; i < NumBinaries; ++i) { + if (strcmp(pBinaries[i].pDeviceTargetSpec, image_target) == 0) { + *pSelectedBinary = i; + return UR_RESULT_SUCCESS; + } + } + + // No image can be loaded for the given device + return UR_RESULT_ERROR_INVALID_BINARY; +} diff --git a/source/adapters/native_cpu/device.hpp b/source/adapters/native_cpu/device.hpp new file mode 100644 index 0000000000..b726e26794 --- /dev/null +++ b/source/adapters/native_cpu/device.hpp @@ -0,0 +1,19 @@ +//===--------- device.hpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include + +struct ur_device_handle_t_ { + ur_device_handle_t_(ur_platform_handle_t ArgPlt) : Platform(ArgPlt) {} + + ur_platform_handle_t Platform; +}; diff --git a/source/adapters/native_cpu/enqueue.cpp b/source/adapters/native_cpu/enqueue.cpp new file mode 100644 index 0000000000..8b21ed39eb --- /dev/null +++ b/source/adapters/native_cpu/enqueue.cpp @@ -0,0 +1,533 @@ +//===--------- enqueue.cpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include + +#include "ur_api.h" + +#include "common.hpp" +#include "kernel.hpp" +#include "memory.hpp" + +namespace native_cpu { +struct NDRDescT { + using RangeT = std::array; + uint32_t WorkDim; + RangeT GlobalOffset; + RangeT GlobalSize; + RangeT LocalSize; + NDRDescT(uint32_t WorkDim, const size_t *GlobalWorkOffset, + const size_t *GlobalWorkSize, const size_t *LocalWorkSize) { + for (uint32_t I = 0; I < WorkDim; I++) { + GlobalOffset[I] = GlobalWorkOffset[I]; + GlobalSize[I] = GlobalWorkSize[I]; + LocalSize[I] = LocalWorkSize[I]; + } + for (uint32_t I = WorkDim; I < 3; I++) { + GlobalSize[I] = 1; + LocalSize[I] = LocalSize[0] ? 1 : 0; + GlobalOffset[I] = 0; + } + } +}; +} // namespace native_cpu + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueKernelLaunch( + ur_queue_handle_t hQueue, ur_kernel_handle_t hKernel, uint32_t workDim, + const size_t *pGlobalWorkOffset, const size_t *pGlobalWorkSize, + const size_t *pLocalWorkSize, uint32_t numEventsInWaitList, + const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) { + std::ignore = numEventsInWaitList; + std::ignore = phEventWaitList; + std::ignore = phEvent; + + UR_ASSERT(hQueue, UR_RESULT_ERROR_INVALID_NULL_HANDLE); + UR_ASSERT(hKernel, UR_RESULT_ERROR_INVALID_NULL_HANDLE); + UR_ASSERT(pGlobalWorkOffset, UR_RESULT_ERROR_INVALID_NULL_POINTER); + UR_ASSERT(workDim > 0, UR_RESULT_ERROR_INVALID_WORK_DIMENSION); + UR_ASSERT(workDim < 4, UR_RESULT_ERROR_INVALID_WORK_DIMENSION); + + if (*pGlobalWorkSize == 0) { + DIE_NO_IMPLEMENTATION; + } + + // TODO: add proper error checking + // TODO: add proper event dep management + native_cpu::NDRDescT ndr(workDim, pGlobalWorkOffset, pGlobalWorkSize, + pLocalWorkSize); + hKernel->handleLocalArgs(); + + native_cpu::state state(ndr.GlobalSize[0], ndr.GlobalSize[1], + ndr.GlobalSize[2], ndr.LocalSize[0], ndr.LocalSize[1], + ndr.LocalSize[2], ndr.GlobalOffset[0], + ndr.GlobalOffset[1], ndr.GlobalOffset[2]); + + auto numWG0 = ndr.GlobalSize[0] / ndr.LocalSize[0]; + auto numWG1 = ndr.GlobalSize[1] / ndr.LocalSize[1]; + auto numWG2 = ndr.GlobalSize[2] / ndr.LocalSize[2]; + for (unsigned g2 = 0; g2 < numWG2; g2++) { + for (unsigned g1 = 0; g1 < numWG1; g1++) { + for (unsigned g0 = 0; g0 < numWG0; g0++) { + for (unsigned local2 = 0; local2 < ndr.LocalSize[2]; local2++) { + for (unsigned local1 = 0; local1 < ndr.LocalSize[1]; local1++) { + for (unsigned local0 = 0; local0 < ndr.LocalSize[0]; local0++) { + state.update(g0, g1, g2, local0, local1, local2); + hKernel->_subhandler(hKernel->_args.data(), &state); + } + } + } + } + } + } + // TODO: we should avoid calling clear here by avoiding using push_back + // in setKernelArgs. + hKernel->_args.clear(); + hKernel->_localArgInfo.clear(); + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueEventsWait( + ur_queue_handle_t hQueue, uint32_t numEventsInWaitList, + const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) { + std::ignore = hQueue; + std::ignore = numEventsInWaitList; + std::ignore = phEventWaitList; + std::ignore = phEvent; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueEventsWaitWithBarrier( + ur_queue_handle_t hQueue, uint32_t numEventsInWaitList, + const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) { + std::ignore = hQueue; + std::ignore = numEventsInWaitList; + std::ignore = phEventWaitList; + std::ignore = phEvent; + + DIE_NO_IMPLEMENTATION; +} + +template +static inline ur_result_t enqueueMemBufferReadWriteRect_impl( + ur_queue_handle_t, ur_mem_handle_t Buff, bool, + ur_rect_offset_t BufferOffset, ur_rect_offset_t HostOffset, + ur_rect_region_t region, size_t BufferRowPitch, size_t BufferSlicePitch, + size_t HostRowPitch, size_t HostSlicePitch, + typename std::conditional::type DstMem, + uint32_t, const ur_event_handle_t *, ur_event_handle_t *) { + // TODO: events, blocking, check other constraints, performance optimizations + // More sharing with level_zero where possible + + if (BufferRowPitch == 0) + BufferRowPitch = region.width; + if (BufferSlicePitch == 0) + BufferSlicePitch = BufferRowPitch * region.height; + if (HostRowPitch == 0) + HostRowPitch = region.width; + if (HostSlicePitch == 0) + HostSlicePitch = HostRowPitch * region.height; + for (size_t w = 0; w < region.width; w++) + for (size_t h = 0; h < region.height; h++) + for (size_t d = 0; d < region.depth; d++) { + size_t buff_orign = (d + BufferOffset.z) * BufferSlicePitch + + (h + BufferOffset.y) * BufferRowPitch + w + + BufferOffset.x; + size_t host_origin = (d + HostOffset.z) * HostSlicePitch + + (h + HostOffset.y) * HostRowPitch + w + + HostOffset.x; + int8_t &host_mem = ur_cast(DstMem)[host_origin]; + int8_t &buff_mem = ur_cast(Buff->_mem)[buff_orign]; + if (IsRead) + host_mem = buff_mem; + else + buff_mem = host_mem; + } + return UR_RESULT_SUCCESS; +} + +static inline ur_result_t doCopy_impl(ur_queue_handle_t hQueue, void *DstPtr, + const void *SrcPtr, size_t Size, + uint32_t numEventsInWaitList, + const ur_event_handle_t *EventWaitList, + ur_event_handle_t *Event) { + // todo: non-blocking, events, UR integration + std::ignore = hQueue; + std::ignore = numEventsInWaitList; + if (SrcPtr != DstPtr && Size) + memmove(DstPtr, SrcPtr, Size); + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferRead( + ur_queue_handle_t hQueue, ur_mem_handle_t hBuffer, bool blockingRead, + size_t offset, size_t size, void *pDst, uint32_t numEventsInWaitList, + const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) { + std::ignore = blockingRead; + + void *FromPtr = /*Src*/ hBuffer->_mem + offset; + return doCopy_impl(hQueue, pDst, FromPtr, size, numEventsInWaitList, + phEventWaitList, phEvent); +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferWrite( + ur_queue_handle_t hQueue, ur_mem_handle_t hBuffer, bool blockingWrite, + size_t offset, size_t size, const void *pSrc, uint32_t numEventsInWaitList, + const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) { + std::ignore = blockingWrite; + + void *ToPtr = hBuffer->_mem + offset; + return doCopy_impl(hQueue, ToPtr, pSrc, size, numEventsInWaitList, + phEventWaitList, phEvent); +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferReadRect( + ur_queue_handle_t hQueue, ur_mem_handle_t hBuffer, bool blockingRead, + ur_rect_offset_t bufferOrigin, ur_rect_offset_t hostOrigin, + ur_rect_region_t region, size_t bufferRowPitch, size_t bufferSlicePitch, + size_t hostRowPitch, size_t hostSlicePitch, void *pDst, + uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, + ur_event_handle_t *phEvent) { + return enqueueMemBufferReadWriteRect_impl( + hQueue, hBuffer, blockingRead, bufferOrigin, hostOrigin, region, + bufferRowPitch, bufferSlicePitch, hostRowPitch, hostSlicePitch, pDst, + numEventsInWaitList, phEventWaitList, phEvent); +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( + ur_queue_handle_t hQueue, ur_mem_handle_t hBuffer, bool blockingWrite, + ur_rect_offset_t bufferOrigin, ur_rect_offset_t hostOrigin, + ur_rect_region_t region, size_t bufferRowPitch, size_t bufferSlicePitch, + size_t hostRowPitch, size_t hostSlicePitch, void *pSrc, + uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, + ur_event_handle_t *phEvent) { + return enqueueMemBufferReadWriteRect_impl( + hQueue, hBuffer, blockingWrite, bufferOrigin, hostOrigin, region, + bufferRowPitch, bufferSlicePitch, hostRowPitch, hostSlicePitch, pSrc, + numEventsInWaitList, phEventWaitList, phEvent); +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferCopy( + ur_queue_handle_t hQueue, ur_mem_handle_t hBufferSrc, + ur_mem_handle_t hBufferDst, size_t srcOffset, size_t dstOffset, size_t size, + uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, + ur_event_handle_t *phEvent) { + const void *SrcPtr = hBufferSrc->_mem + srcOffset; + void *DstPtr = hBufferDst->_mem + dstOffset; + return doCopy_impl(hQueue, DstPtr, SrcPtr, size, numEventsInWaitList, + phEventWaitList, phEvent); +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( + ur_queue_handle_t hQueue, ur_mem_handle_t hBufferSrc, + ur_mem_handle_t hBufferDst, ur_rect_offset_t srcOrigin, + ur_rect_offset_t dstOrigin, ur_rect_region_t region, size_t srcRowPitch, + size_t srcSlicePitch, size_t dstRowPitch, size_t dstSlicePitch, + uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, + ur_event_handle_t *phEvent) { + return enqueueMemBufferReadWriteRect_impl( + hQueue, hBufferSrc, false /*todo: check blocking*/, srcOrigin, + /*HostOffset*/ dstOrigin, region, srcRowPitch, srcSlicePitch, dstRowPitch, + dstSlicePitch, hBufferDst->_mem, numEventsInWaitList, phEventWaitList, + phEvent); +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferFill( + ur_queue_handle_t hQueue, ur_mem_handle_t hBuffer, const void *pPattern, + size_t patternSize, size_t offset, size_t size, + uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, + ur_event_handle_t *phEvent) { + std::ignore = numEventsInWaitList; + std::ignore = phEventWaitList; + std::ignore = phEvent; + + UR_ASSERT(hQueue, UR_RESULT_ERROR_INVALID_NULL_HANDLE); + + // TODO: error checking + // TODO: handle async + void *startingPtr = hBuffer->_mem + offset; + unsigned steps = size / patternSize; + for (unsigned i = 0; i < steps; i++) { + memcpy(static_cast(startingPtr) + i * patternSize, pPattern, + patternSize); + } + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageRead( + ur_queue_handle_t hQueue, ur_mem_handle_t hImage, bool blockingRead, + ur_rect_offset_t origin, ur_rect_region_t region, size_t rowPitch, + size_t slicePitch, void *pDst, uint32_t numEventsInWaitList, + const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) { + std::ignore = hQueue; + std::ignore = hImage; + std::ignore = blockingRead; + std::ignore = origin; + std::ignore = region; + std::ignore = rowPitch; + std::ignore = slicePitch; + std::ignore = pDst; + std::ignore = numEventsInWaitList; + std::ignore = phEventWaitList; + std::ignore = phEvent; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageWrite( + ur_queue_handle_t hQueue, ur_mem_handle_t hImage, bool blockingWrite, + ur_rect_offset_t origin, ur_rect_region_t region, size_t rowPitch, + size_t slicePitch, void *pSrc, uint32_t numEventsInWaitList, + const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) { + std::ignore = hQueue; + std::ignore = hImage; + std::ignore = blockingWrite; + std::ignore = origin; + std::ignore = region; + std::ignore = rowPitch; + std::ignore = slicePitch; + std::ignore = pSrc; + std::ignore = numEventsInWaitList; + std::ignore = phEventWaitList; + std::ignore = phEvent; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageCopy( + ur_queue_handle_t hQueue, ur_mem_handle_t hImageSrc, + ur_mem_handle_t hImageDst, ur_rect_offset_t srcOrigin, + ur_rect_offset_t dstOrigin, ur_rect_region_t region, + uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, + ur_event_handle_t *phEvent) { + std::ignore = hQueue; + std::ignore = hImageSrc; + std::ignore = hImageDst; + std::ignore = srcOrigin; + std::ignore = dstOrigin; + std::ignore = region; + std::ignore = numEventsInWaitList; + std::ignore = phEventWaitList; + std::ignore = phEvent; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferMap( + ur_queue_handle_t hQueue, ur_mem_handle_t hBuffer, bool blockingMap, + ur_map_flags_t mapFlags, size_t offset, size_t size, + uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, + ur_event_handle_t *phEvent, void **ppRetMap) { + std::ignore = hQueue; + std::ignore = blockingMap; + std::ignore = mapFlags; + std::ignore = size; + std::ignore = numEventsInWaitList; + std::ignore = phEventWaitList; + std::ignore = phEvent; + + *ppRetMap = hBuffer->_mem + offset; + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemUnmap( + ur_queue_handle_t hQueue, ur_mem_handle_t hMem, void *pMappedPtr, + uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, + ur_event_handle_t *phEvent) { + std::ignore = hQueue; + std::ignore = hMem; + std::ignore = pMappedPtr; + std::ignore = numEventsInWaitList; + std::ignore = phEventWaitList; + std::ignore = phEvent; + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueUSMFill( + ur_queue_handle_t hQueue, void *ptr, size_t patternSize, + const void *pPattern, size_t size, uint32_t numEventsInWaitList, + const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) { + std::ignore = hQueue; + std::ignore = numEventsInWaitList; + std::ignore = phEventWaitList; + std::ignore = phEvent; + + UR_ASSERT(ptr, UR_RESULT_ERROR_INVALID_NULL_POINTER); + UR_ASSERT(pPattern, UR_RESULT_ERROR_INVALID_NULL_POINTER); + UR_ASSERT(size % patternSize == 0 || patternSize > size, + UR_RESULT_ERROR_INVALID_SIZE); + + memset(ptr, *static_cast(pPattern), size * patternSize); + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueUSMMemcpy( + ur_queue_handle_t hQueue, bool blocking, void *pDst, const void *pSrc, + size_t size, uint32_t numEventsInWaitList, + const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) { + std::ignore = hQueue; + std::ignore = blocking; + std::ignore = numEventsInWaitList; + std::ignore = phEventWaitList; + std::ignore = phEvent; + + UR_ASSERT(hQueue, UR_RESULT_ERROR_INVALID_QUEUE); + UR_ASSERT(pDst, UR_RESULT_ERROR_INVALID_NULL_POINTER); + UR_ASSERT(pSrc, UR_RESULT_ERROR_INVALID_NULL_POINTER); + + memcpy(pDst, pSrc, size); + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueUSMPrefetch( + ur_queue_handle_t hQueue, const void *pMem, size_t size, + ur_usm_migration_flags_t flags, uint32_t numEventsInWaitList, + const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) { + std::ignore = hQueue; + std::ignore = pMem; + std::ignore = size; + std::ignore = flags; + std::ignore = numEventsInWaitList; + std::ignore = phEventWaitList; + std::ignore = phEvent; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urEnqueueUSMAdvise(ur_queue_handle_t hQueue, const void *pMem, size_t size, + ur_usm_advice_flags_t advice, ur_event_handle_t *phEvent) { + std::ignore = hQueue; + std::ignore = pMem; + std::ignore = size; + std::ignore = advice; + std::ignore = phEvent; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueUSMFill2D( + ur_queue_handle_t hQueue, void *pMem, size_t pitch, size_t patternSize, + const void *pPattern, size_t width, size_t height, + uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, + ur_event_handle_t *phEvent) { + std::ignore = hQueue; + std::ignore = pMem; + std::ignore = pitch; + std::ignore = patternSize; + std::ignore = pPattern; + std::ignore = width; + std::ignore = height; + std::ignore = numEventsInWaitList; + std::ignore = phEventWaitList; + std::ignore = phEvent; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueUSMMemcpy2D( + ur_queue_handle_t hQueue, bool blocking, void *pDst, size_t dstPitch, + const void *pSrc, size_t srcPitch, size_t width, size_t height, + uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, + ur_event_handle_t *phEvent) { + std::ignore = hQueue; + std::ignore = blocking; + std::ignore = pDst; + std::ignore = dstPitch; + std::ignore = pSrc; + std::ignore = srcPitch; + std::ignore = width; + std::ignore = height; + std::ignore = numEventsInWaitList; + std::ignore = phEventWaitList; + std::ignore = phEvent; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueDeviceGlobalVariableWrite( + ur_queue_handle_t hQueue, ur_program_handle_t hProgram, const char *name, + bool blockingWrite, size_t count, size_t offset, const void *pSrc, + uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, + ur_event_handle_t *phEvent) { + std::ignore = hQueue; + std::ignore = hProgram; + std::ignore = name; + std::ignore = blockingWrite; + std::ignore = count; + std::ignore = offset; + std::ignore = pSrc; + std::ignore = numEventsInWaitList; + std::ignore = phEventWaitList; + std::ignore = phEvent; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueDeviceGlobalVariableRead( + ur_queue_handle_t hQueue, ur_program_handle_t hProgram, const char *name, + bool blockingRead, size_t count, size_t offset, void *pDst, + uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, + ur_event_handle_t *phEvent) { + std::ignore = hQueue; + std::ignore = hProgram; + std::ignore = name; + std::ignore = blockingRead; + std::ignore = count; + std::ignore = offset; + std::ignore = pDst; + std::ignore = numEventsInWaitList; + std::ignore = phEventWaitList; + std::ignore = phEvent; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueReadHostPipe( + ur_queue_handle_t hQueue, ur_program_handle_t hProgram, + const char *pipe_symbol, bool blocking, void *pDst, size_t size, + uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, + ur_event_handle_t *phEvent) { + std::ignore = hQueue; + std::ignore = hProgram; + std::ignore = pipe_symbol; + std::ignore = blocking; + std::ignore = pDst; + std::ignore = size; + std::ignore = numEventsInWaitList; + std::ignore = phEventWaitList; + std::ignore = phEvent; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEnqueueWriteHostPipe( + ur_queue_handle_t hQueue, ur_program_handle_t hProgram, + const char *pipe_symbol, bool blocking, void *pSrc, size_t size, + uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, + ur_event_handle_t *phEvent) { + std::ignore = hQueue; + std::ignore = hProgram; + std::ignore = pipe_symbol; + std::ignore = blocking; + std::ignore = pSrc; + std::ignore = size; + std::ignore = numEventsInWaitList; + std::ignore = phEventWaitList; + std::ignore = phEvent; + + DIE_NO_IMPLEMENTATION; +} diff --git a/source/adapters/native_cpu/event.cpp b/source/adapters/native_cpu/event.cpp new file mode 100644 index 0000000000..c6a259c558 --- /dev/null +++ b/source/adapters/native_cpu/event.cpp @@ -0,0 +1,89 @@ +//===--------- event.cpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ur_api.h" + +#include "common.hpp" + +UR_APIEXPORT ur_result_t UR_APICALL urEventGetInfo(ur_event_handle_t hEvent, + ur_event_info_t propName, + size_t propSize, + void *pPropValue, + size_t *pPropSizeRet) { + std::ignore = hEvent; + std::ignore = propName; + std::ignore = propSize; + std::ignore = pPropValue; + std::ignore = pPropSizeRet; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEventGetProfilingInfo( + ur_event_handle_t hEvent, ur_profiling_info_t propName, size_t propSize, + void *pPropValue, size_t *pPropSizeRet) { + std::ignore = hEvent; + std::ignore = propName; + std::ignore = propSize; + std::ignore = pPropValue; + std::ignore = pPropSizeRet; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urEventWait(uint32_t numEvents, const ur_event_handle_t *phEventWaitList) { + std::ignore = numEvents; + std::ignore = phEventWaitList; + // TODO: currently we do everything synchronously so this is a no-op + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEventRetain(ur_event_handle_t hEvent) { + std::ignore = hEvent; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEventRelease(ur_event_handle_t hEvent) { + std::ignore = hEvent; + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEventGetNativeHandle( + ur_event_handle_t hEvent, ur_native_handle_t *phNativeEvent) { + std::ignore = hEvent; + std::ignore = phNativeEvent; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urEventCreateWithNativeHandle( + ur_native_handle_t hNativeEvent, ur_context_handle_t hContext, + const ur_event_native_properties_t *pProperties, + ur_event_handle_t *phEvent) { + std::ignore = hNativeEvent; + std::ignore = hContext; + std::ignore = pProperties; + std::ignore = phEvent; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urEventSetCallback(ur_event_handle_t hEvent, ur_execution_info_t execStatus, + ur_event_callback_t pfnNotify, void *pUserData) { + std::ignore = hEvent; + std::ignore = execStatus; + std::ignore = pfnNotify; + std::ignore = pUserData; + + DIE_NO_IMPLEMENTATION; +} diff --git a/source/adapters/native_cpu/image.cpp b/source/adapters/native_cpu/image.cpp new file mode 100644 index 0000000000..076f97db55 --- /dev/null +++ b/source/adapters/native_cpu/image.cpp @@ -0,0 +1,175 @@ +//===--------- image.cpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ur/ur.hpp" + +UR_APIEXPORT ur_result_t UR_APICALL urUSMPitchedAllocExp( + [[maybe_unused]] ur_context_handle_t hContext, + [[maybe_unused]] ur_device_handle_t hDevice, + [[maybe_unused]] const ur_usm_desc_t *pUSMDesc, + [[maybe_unused]] ur_usm_pool_handle_t pool, + [[maybe_unused]] size_t widthInBytes, [[maybe_unused]] size_t height, + [[maybe_unused]] size_t elementSizeBytes, [[maybe_unused]] void **ppMem, + [[maybe_unused]] size_t *pResultPitch) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urBindlessImagesUnsampledImageHandleDestroyExp( + [[maybe_unused]] ur_context_handle_t hContext, + [[maybe_unused]] ur_device_handle_t hDevice, + [[maybe_unused]] ur_exp_image_handle_t hImage) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urBindlessImagesSampledImageHandleDestroyExp( + [[maybe_unused]] ur_context_handle_t hContext, + [[maybe_unused]] ur_device_handle_t hDevice, + [[maybe_unused]] ur_exp_image_handle_t hImage) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urBindlessImagesImageAllocateExp( + [[maybe_unused]] ur_context_handle_t hContext, + [[maybe_unused]] ur_device_handle_t hDevice, + [[maybe_unused]] const ur_image_format_t *pImageFormat, + [[maybe_unused]] const ur_image_desc_t *pImageDesc, + [[maybe_unused]] ur_exp_image_mem_handle_t *phImageMem) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urBindlessImagesImageFreeExp( + [[maybe_unused]] ur_context_handle_t hContext, + [[maybe_unused]] ur_device_handle_t hDevice, + [[maybe_unused]] ur_exp_image_mem_handle_t hImageMem) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urBindlessImagesUnsampledImageCreateExp( + [[maybe_unused]] ur_context_handle_t hContext, + [[maybe_unused]] ur_device_handle_t hDevice, + [[maybe_unused]] ur_exp_image_mem_handle_t hImageMem, + [[maybe_unused]] const ur_image_format_t *pImageFormat, + [[maybe_unused]] const ur_image_desc_t *pImageDesc, + [[maybe_unused]] ur_mem_handle_t *phMem, + [[maybe_unused]] ur_exp_image_handle_t *phImage) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urBindlessImagesSampledImageCreateExp( + [[maybe_unused]] ur_context_handle_t hContext, + [[maybe_unused]] ur_device_handle_t hDevice, + [[maybe_unused]] ur_exp_image_mem_handle_t hImageMem, + [[maybe_unused]] const ur_image_format_t *pImageFormat, + [[maybe_unused]] const ur_image_desc_t *pImageDesc, + [[maybe_unused]] ur_sampler_handle_t hSampler, + [[maybe_unused]] ur_mem_handle_t *phMem, + [[maybe_unused]] ur_exp_image_handle_t *phImage) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urBindlessImagesImageCopyExp( + [[maybe_unused]] ur_queue_handle_t hQueue, [[maybe_unused]] void *pDst, + [[maybe_unused]] void *pSrc, + [[maybe_unused]] const ur_image_format_t *pImageFormat, + [[maybe_unused]] const ur_image_desc_t *pImageDesc, + [[maybe_unused]] ur_exp_image_copy_flags_t imageCopyFlags, + [[maybe_unused]] ur_rect_offset_t srcOffset, + [[maybe_unused]] ur_rect_offset_t dstOffset, + [[maybe_unused]] ur_rect_region_t copyExtent, + [[maybe_unused]] ur_rect_region_t hostExtent, + [[maybe_unused]] uint32_t numEventsInWaitList, + [[maybe_unused]] const ur_event_handle_t *phEventWaitList, + [[maybe_unused]] ur_event_handle_t *phEvent) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urBindlessImagesImageGetInfoExp( + [[maybe_unused]] ur_exp_image_mem_handle_t hImageMem, + [[maybe_unused]] ur_image_info_t propName, + [[maybe_unused]] void *pPropValue, [[maybe_unused]] size_t *pPropSizeRet) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urBindlessImagesMipmapGetLevelExp( + [[maybe_unused]] ur_context_handle_t hContext, + [[maybe_unused]] ur_device_handle_t hDevice, + [[maybe_unused]] ur_exp_image_mem_handle_t hImageMem, + [[maybe_unused]] uint32_t mipmapLevel, + [[maybe_unused]] ur_exp_image_mem_handle_t *phImageMem) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urBindlessImagesMipmapFreeExp([[maybe_unused]] ur_context_handle_t hContext, + [[maybe_unused]] ur_device_handle_t hDevice, + [[maybe_unused]] ur_exp_image_mem_handle_t hMem) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urBindlessImagesImportOpaqueFDExp( + [[maybe_unused]] ur_context_handle_t hContext, + [[maybe_unused]] ur_device_handle_t hDevice, [[maybe_unused]] size_t size, + [[maybe_unused]] ur_exp_interop_mem_desc_t *pInteropMemDesc, + [[maybe_unused]] ur_exp_interop_mem_handle_t *phInteropMem) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urBindlessImagesMapExternalArrayExp( + [[maybe_unused]] ur_context_handle_t hContext, + [[maybe_unused]] ur_device_handle_t hDevice, + [[maybe_unused]] const ur_image_format_t *pImageFormat, + [[maybe_unused]] const ur_image_desc_t *pImageDesc, + [[maybe_unused]] ur_exp_interop_mem_handle_t hInteropMem, + [[maybe_unused]] ur_exp_image_mem_handle_t *phImageMem) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urBindlessImagesReleaseInteropExp( + [[maybe_unused]] ur_context_handle_t hContext, + [[maybe_unused]] ur_device_handle_t hDevice, + [[maybe_unused]] ur_exp_interop_mem_handle_t hInteropMem) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urBindlessImagesImportExternalSemaphoreOpaqueFDExp( + [[maybe_unused]] ur_context_handle_t hContext, + [[maybe_unused]] ur_device_handle_t hDevice, + [[maybe_unused]] ur_exp_interop_semaphore_desc_t *pInteropSemaphoreDesc, + [[maybe_unused]] ur_exp_interop_semaphore_handle_t *phInteropSemaphore) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urBindlessImagesDestroyExternalSemaphoreExp( + [[maybe_unused]] ur_context_handle_t hContext, + [[maybe_unused]] ur_device_handle_t hDevice, + [[maybe_unused]] ur_exp_interop_semaphore_handle_t hInteropSemaphore) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urBindlessImagesWaitExternalSemaphoreExp( + [[maybe_unused]] ur_queue_handle_t hQueue, + [[maybe_unused]] ur_exp_interop_semaphore_handle_t hSemaphore, + [[maybe_unused]] uint32_t numEventsInWaitList, + [[maybe_unused]] const ur_event_handle_t *phEventWaitList, + [[maybe_unused]] ur_event_handle_t *phEvent) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urBindlessImagesSignalExternalSemaphoreExp( + [[maybe_unused]] ur_queue_handle_t hQueue, + [[maybe_unused]] ur_exp_interop_semaphore_handle_t hSemaphore, + [[maybe_unused]] uint32_t numEventsInWaitList, + [[maybe_unused]] const ur_event_handle_t *phEventWaitList, + [[maybe_unused]] ur_event_handle_t *phEvent) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} diff --git a/source/adapters/native_cpu/kernel.cpp b/source/adapters/native_cpu/kernel.cpp new file mode 100644 index 0000000000..e836de55d6 --- /dev/null +++ b/source/adapters/native_cpu/kernel.cpp @@ -0,0 +1,284 @@ +//===--------- kernel.cpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ur_api.h" + +#include "common.hpp" +#include "kernel.hpp" +#include "memory.hpp" +#include "program.hpp" + +UR_APIEXPORT ur_result_t UR_APICALL +urKernelCreate(ur_program_handle_t hProgram, const char *pKernelName, + ur_kernel_handle_t *phKernel) { + UR_ASSERT(hProgram, UR_RESULT_ERROR_INVALID_NULL_HANDLE); + UR_ASSERT(pKernelName, UR_RESULT_ERROR_INVALID_NULL_POINTER); + + auto kernelEntry = hProgram->_kernels.find(pKernelName); + if (kernelEntry == hProgram->_kernels.end()) + return UR_RESULT_ERROR_INVALID_KERNEL; + + auto f = reinterpret_cast(kernelEntry->second); + auto kernel = new ur_kernel_handle_t_(pKernelName, *f); + + *phKernel = kernel; + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urKernelSetArgValue( + ur_kernel_handle_t hKernel, uint32_t argIndex, size_t argSize, + const ur_kernel_arg_value_properties_t *pProperties, + const void *pArgValue) { + // Todo: error checking + // Todo: I think that the opencl spec (and therefore the pi spec mandates that + // arg is copied (this is why it is defined as const void*, I guess we should + // do it + // TODO: can args arrive out of order? + std::ignore = argIndex; + std::ignore = pProperties; + + UR_ASSERT(hKernel, UR_RESULT_ERROR_INVALID_NULL_HANDLE); + UR_ASSERT(argSize, UR_RESULT_ERROR_INVALID_KERNEL_ARGUMENT_SIZE); + + hKernel->_args.emplace_back(const_cast(pArgValue)); + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urKernelSetArgLocal( + ur_kernel_handle_t hKernel, uint32_t argIndex, size_t argSize, + const ur_kernel_arg_local_properties_t *pProperties) { + std::ignore = pProperties; + // emplace a placeholder kernel arg, gets replaced with a pointer to the + // memory pool before enqueueing the kernel. + hKernel->_args.emplace_back(nullptr); + hKernel->_localArgInfo.emplace_back(argIndex, argSize); + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urKernelGetInfo(ur_kernel_handle_t hKernel, + ur_kernel_info_t propName, + size_t propSize, + void *pPropValue, + size_t *pPropSizeRet) { + std::ignore = hKernel; + std::ignore = propName; + std::ignore = pPropValue; + + UrReturnHelper ReturnValue(propSize, pPropValue, pPropSizeRet); + // todo: check if we need this + // std::shared_lock Guard(hKernel->Mutex); + switch (propName) { + // case UR_KERNEL_INFO_CONTEXT: + // return ReturnValue(ur_context_handle_t{ hKernel->Program->Context }); + // case UR_KERNEL_INFO_PROGRAM: + // return ReturnValue(ur_program_handle_t{ Kernel->Program }); + case UR_KERNEL_INFO_FUNCTION_NAME: + if (hKernel->_name) { + return ReturnValue(hKernel->_name); + } + return UR_RESULT_ERROR_INVALID_FUNCTION_NAME; + // case UR_KERNEL_INFO_NUM_ARGS: + // return ReturnValue(uint32_t{ Kernel->ZeKernelProperties->numKernelArgs + // }); + case UR_KERNEL_INFO_REFERENCE_COUNT: + return ReturnValue(uint32_t{hKernel->getReferenceCount()}); + case UR_KERNEL_INFO_ATTRIBUTES: + return ReturnValue(""); + default: + return UR_RESULT_ERROR_INVALID_VALUE; + } + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL +urKernelGetGroupInfo(ur_kernel_handle_t hKernel, ur_device_handle_t hDevice, + ur_kernel_group_info_t propName, size_t propSize, + void *pPropValue, size_t *pPropSizeRet) { + std::ignore = hDevice; + + UR_ASSERT(hKernel, UR_RESULT_ERROR_INVALID_NULL_HANDLE); + + UrReturnHelper returnValue(propSize, pPropValue, pPropSizeRet); + + switch (propName) { + case UR_KERNEL_GROUP_INFO_GLOBAL_WORK_SIZE: { + size_t global_work_size[3] = {0, 0, 0}; + return returnValue(global_work_size, 3); + } + case UR_KERNEL_GROUP_INFO_WORK_GROUP_SIZE: { + // todo: set proper values + size_t max_threads = 128; + return returnValue(max_threads); + } + case UR_KERNEL_GROUP_INFO_COMPILE_WORK_GROUP_SIZE: { + size_t group_size[3] = {1, 1, 1}; + return returnValue(group_size, 3); + } + case UR_KERNEL_GROUP_INFO_LOCAL_MEM_SIZE: { + int bytes = 0; + return returnValue(static_cast(bytes)); + } + case UR_KERNEL_GROUP_INFO_PREFERRED_WORK_GROUP_SIZE_MULTIPLE: { + // todo: set proper values + int warpSize = 16; + return returnValue(static_cast(warpSize)); + } + case UR_KERNEL_GROUP_INFO_PRIVATE_MEM_SIZE: { + int bytes = 0; + return returnValue(static_cast(bytes)); + } + + default: + break; + } + + return UR_RESULT_ERROR_INVALID_ENUMERATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urKernelGetSubGroupInfo(ur_kernel_handle_t hKernel, ur_device_handle_t hDevice, + ur_kernel_sub_group_info_t propName, size_t propSize, + void *pPropValue, size_t *pPropSizeRet) { + std::ignore = hKernel; + std::ignore = hDevice; + + UrReturnHelper ReturnValue(propSize, pPropValue, pPropSizeRet); + switch (propName) { + case UR_KERNEL_SUB_GROUP_INFO_MAX_SUB_GROUP_SIZE: { + // todo: set proper values + int WarpSize = 8; + return ReturnValue(static_cast(WarpSize)); + } + case UR_KERNEL_SUB_GROUP_INFO_MAX_NUM_SUB_GROUPS: { + // todo: set proper values + int MaxWarps = 32; + return ReturnValue(static_cast(MaxWarps)); + } + case UR_KERNEL_SUB_GROUP_INFO_COMPILE_NUM_SUB_GROUPS: { + // todo: set proper values + return ReturnValue(0); + } + case UR_KERNEL_SUB_GROUP_INFO_SUB_GROUP_SIZE_INTEL: { + // todo: set proper values + return ReturnValue(0); + } + } + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urKernelRetain(ur_kernel_handle_t hKernel) { + hKernel->incrementReferenceCount(); + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urKernelRelease(ur_kernel_handle_t hKernel) { + delete hKernel; + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urKernelSetArgPointer(ur_kernel_handle_t hKernel, uint32_t argIndex, + const ur_kernel_arg_pointer_properties_t *pProperties, + const void *pArgValue) { + // TODO: out_of_order args? + std::ignore = argIndex; + std::ignore = pProperties; + + UR_ASSERT(hKernel, UR_RESULT_ERROR_INVALID_NULL_HANDLE); + UR_ASSERT(pArgValue, UR_RESULT_ERROR_INVALID_NULL_POINTER); + + auto ptrToPtr = reinterpret_cast(pArgValue); + auto derefPtr = reinterpret_cast(*ptrToPtr); + hKernel->_args.push_back(derefPtr); + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urKernelSetExecInfo( + ur_kernel_handle_t hKernel, ur_kernel_exec_info_t propName, size_t propSize, + const ur_kernel_exec_info_properties_t *pProperties, + const void *pPropValue) { + std::ignore = hKernel; + std::ignore = propName; + std::ignore = propSize; + std::ignore = pProperties; + std::ignore = pPropValue; + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urKernelSetArgSampler(ur_kernel_handle_t hKernel, uint32_t argIndex, + const ur_kernel_arg_sampler_properties_t *pProperties, + ur_sampler_handle_t hArgValue) { + std::ignore = hKernel; + std::ignore = argIndex; + std::ignore = pProperties; + std::ignore = hArgValue; + + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL +urKernelSetArgMemObj(ur_kernel_handle_t hKernel, uint32_t argIndex, + const ur_kernel_arg_mem_obj_properties_t *pProperties, + ur_mem_handle_t hArgValue) { + // TODO: out_of_order args? + std::ignore = argIndex; + std::ignore = pProperties; + + UR_ASSERT(hKernel, UR_RESULT_ERROR_INVALID_NULL_HANDLE); + + // Taken from ur/adapters/cuda/kernel.cpp + // zero-sized buffers are expected to be null. + if (hArgValue == nullptr) { + hKernel->_args.emplace_back(nullptr); + return UR_RESULT_SUCCESS; + } + + hKernel->_args.emplace_back(hArgValue->_mem); + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urKernelSetSpecializationConstants( + ur_kernel_handle_t hKernel, uint32_t count, + const ur_specialization_constant_info_t *pSpecConstants) { + std::ignore = hKernel; + std::ignore = count; + std::ignore = pSpecConstants; + + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL urKernelGetNativeHandle( + ur_kernel_handle_t hKernel, ur_native_handle_t *phNativeKernel) { + std::ignore = hKernel; + std::ignore = phNativeKernel; + + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL urKernelCreateWithNativeHandle( + ur_native_handle_t hNativeKernel, ur_context_handle_t hContext, + ur_program_handle_t hProgram, + const ur_kernel_native_properties_t *pProperties, + ur_kernel_handle_t *phKernel) { + std::ignore = hNativeKernel; + std::ignore = hContext; + std::ignore = hProgram; + std::ignore = pProperties; + std::ignore = phKernel; + + DIE_NO_IMPLEMENTATION +} diff --git a/source/adapters/native_cpu/kernel.hpp b/source/adapters/native_cpu/kernel.hpp new file mode 100644 index 0000000000..b38796c10c --- /dev/null +++ b/source/adapters/native_cpu/kernel.hpp @@ -0,0 +1,90 @@ +//===--------- kernel.hpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "common.hpp" +#include "nativecpu_state.hpp" +#include + +namespace native_cpu { + +struct NativeCPUArgDesc { + void *MPtr; + + NativeCPUArgDesc(void *Ptr) : MPtr(Ptr){}; +}; + +} // namespace native_cpu + +using nativecpu_kernel_t = void(const native_cpu::NativeCPUArgDesc *, + native_cpu::state *); +using nativecpu_ptr_t = nativecpu_kernel_t *; +using nativecpu_task_t = std::function; + +struct local_arg_info_t { + uint32_t argIndex; + size_t argSize; + local_arg_info_t(uint32_t argIndex, size_t argSize) + : argIndex(argIndex), argSize(argSize) {} +}; + +struct ur_kernel_handle_t_ : RefCounted { + + ur_kernel_handle_t_(const char *name, nativecpu_task_t subhandler) + : _name{name}, _subhandler{subhandler} {} + + const char *_name; + nativecpu_task_t _subhandler; + std::vector _args; + std::vector _localArgInfo; + + // To be called before enqueing the kernel. + void handleLocalArgs() { + updateMemPool(); + size_t offset = 0; + for (auto &entry : _localArgInfo) { + _args[entry.argIndex].MPtr = + reinterpret_cast(_localMemPool) + offset; + // update offset in the memory pool + // Todo: update this offset computation when we have work-group + // level parallelism. + offset += entry.argSize; + } + } + + ~ur_kernel_handle_t_() { + if (_localMemPool) { + free(_localMemPool); + } + } + +private: + void updateMemPool() { + // compute requested size. + // Todo: currently we execute only one work-group at a time, so for each + // local arg we can allocate just 1 * argSize local arg. When we implement + // work-group level parallelism we should allocate N * argSize where N is + // the number of work groups being executed in parallel (e.g. number of + // threads in the thread pool). + size_t reqSize = 0; + for (auto &entry : _localArgInfo) { + reqSize += entry.argSize; + } + if (reqSize == 0 || reqSize == _localMemPoolSize) { + return; + } + // realloc handles nullptr case + _localMemPool = realloc(_localMemPool, reqSize); + _localMemPoolSize = reqSize; + } + void *_localMemPool = nullptr; + size_t _localMemPoolSize = 0; +}; diff --git a/source/adapters/native_cpu/memory.cpp b/source/adapters/native_cpu/memory.cpp new file mode 100644 index 0000000000..4e33f23298 --- /dev/null +++ b/source/adapters/native_cpu/memory.cpp @@ -0,0 +1,172 @@ +//===--------- memory.cpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "memory.hpp" +#include "common.hpp" +#include "ur_api.h" + +UR_APIEXPORT ur_result_t UR_APICALL urMemImageCreate( + ur_context_handle_t hContext, ur_mem_flags_t flags, + const ur_image_format_t *pImageFormat, const ur_image_desc_t *pImageDesc, + void *pHost, ur_mem_handle_t *phMem) { + std::ignore = hContext; + std::ignore = flags; + std::ignore = pImageFormat; + std::ignore = pImageDesc; + std::ignore = pHost; + std::ignore = phMem; + + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL urMemBufferCreate( + ur_context_handle_t hContext, ur_mem_flags_t flags, size_t size, + const ur_buffer_properties_t *pProperties, ur_mem_handle_t *phBuffer) { + + // TODO: add proper error checking and double check flag semantics + // TODO: support UR_MEM_FLAG_ALLOC_COPY_HOST_POINTER flag + + UR_ASSERT(phBuffer, UR_RESULT_ERROR_INVALID_NULL_POINTER); + + UR_ASSERT((flags & UR_MEM_FLAGS_MASK) == 0, + UR_RESULT_ERROR_INVALID_ENUMERATION); + if (flags & + (UR_MEM_FLAG_USE_HOST_POINTER | UR_MEM_FLAG_ALLOC_COPY_HOST_POINTER)) { + UR_ASSERT(pProperties && pProperties->pHost, + UR_RESULT_ERROR_INVALID_HOST_PTR); + } + + UR_ASSERT(size != 0, UR_RESULT_ERROR_INVALID_BUFFER_SIZE); + + const bool useHostPtr = flags & UR_MEM_FLAG_USE_HOST_POINTER; + const bool copyHostPtr = flags & UR_MEM_FLAG_USE_HOST_POINTER; + + ur_mem_handle_t_ *retMem; + + if (useHostPtr) { + retMem = new _ur_buffer(hContext, pProperties->pHost); + } else if (copyHostPtr) { + retMem = new _ur_buffer(hContext, pProperties->pHost, size); + } else { + retMem = new _ur_buffer(hContext, size); + } + + *phBuffer = retMem; + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urMemRetain(ur_mem_handle_t hMem) { + std::ignore = hMem; + + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL urMemRelease(ur_mem_handle_t hMem) { + UR_ASSERT(hMem, UR_RESULT_ERROR_INVALID_NULL_HANDLE); + + hMem->decrementRefCount(); + if (hMem->_refCount > 0) { + return UR_RESULT_SUCCESS; + } + + delete hMem; + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urMemBufferPartition( + ur_mem_handle_t hBuffer, ur_mem_flags_t flags, + ur_buffer_create_type_t bufferCreateType, const ur_buffer_region_t *pRegion, + ur_mem_handle_t *phMem) { + + std::ignore = bufferCreateType; + UR_ASSERT(hBuffer && !hBuffer->isImage() && + !(static_cast<_ur_buffer *>(hBuffer))->isSubBuffer(), + UR_RESULT_ERROR_INVALID_MEM_OBJECT); + + std::shared_lock Guard(hBuffer->Mutex); + + if (flags != UR_MEM_FLAG_READ_WRITE) { + die("urMemBufferPartition: NativeCPU implements only read-write buffer," + "no read-only or write-only yet."); + } + + try { + auto partitionedBuffer = new _ur_buffer(static_cast<_ur_buffer *>(hBuffer), + pRegion->origin, pRegion->size); + *phMem = reinterpret_cast(partitionedBuffer); + } catch (const std::bad_alloc &) { + return UR_RESULT_ERROR_OUT_OF_HOST_MEMORY; + } catch (...) { + return UR_RESULT_ERROR_UNKNOWN; + } + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urMemGetNativeHandle(ur_mem_handle_t hMem, ur_native_handle_t *phNativeMem) { + std::ignore = hMem; + std::ignore = phNativeMem; + + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL urMemBufferCreateWithNativeHandle( + ur_native_handle_t hNativeMem, ur_context_handle_t hContext, + const ur_mem_native_properties_t *pProperties, ur_mem_handle_t *phMem) { + std::ignore = hNativeMem; + std::ignore = hContext; + std::ignore = pProperties; + std::ignore = phMem; + + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL urMemImageCreateWithNativeHandle( + ur_native_handle_t hNativeMem, ur_context_handle_t hContext, + const ur_image_format_t *pImageFormat, const ur_image_desc_t *pImageDesc, + const ur_mem_native_properties_t *pProperties, ur_mem_handle_t *phMem) { + std::ignore = hNativeMem; + std::ignore = hContext; + std::ignore = pImageFormat; + std::ignore = pImageDesc; + std::ignore = pProperties; + std::ignore = phMem; + + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL urMemGetInfo(ur_mem_handle_t hMemory, + ur_mem_info_t propName, + size_t propSize, + void *pPropValue, + size_t *pPropSizeRet) { + std::ignore = hMemory; + std::ignore = propName; + std::ignore = propSize; + std::ignore = pPropValue; + std::ignore = pPropSizeRet; + + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL urMemImageGetInfo(ur_mem_handle_t hMemory, + ur_image_info_t propName, + size_t propSize, + void *pPropValue, + size_t *pPropSizeRet) { + std::ignore = hMemory; + std::ignore = propName; + std::ignore = propSize; + std::ignore = pPropValue; + std::ignore = pPropSizeRet; + + DIE_NO_IMPLEMENTATION +} diff --git a/source/adapters/native_cpu/memory.hpp b/source/adapters/native_cpu/memory.hpp new file mode 100644 index 0000000000..c5ee7360e1 --- /dev/null +++ b/source/adapters/native_cpu/memory.hpp @@ -0,0 +1,75 @@ +//===--------- memory.hpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include +#include +#include + +#include "common.hpp" +#include "context.hpp" + +struct ur_mem_handle_t_ : _ur_object { + ur_mem_handle_t_(size_t Size, bool _IsImage) + : _mem{static_cast(malloc(Size))}, _ownsMem{true}, + IsImage{_IsImage} {} + + ur_mem_handle_t_(void *HostPtr, size_t Size, bool _IsImage) + : _mem{static_cast(malloc(Size))}, _ownsMem{true}, + IsImage{_IsImage} { + memcpy(_mem, HostPtr, Size); + } + + ur_mem_handle_t_(void *HostPtr, bool _IsImage) + : _mem{static_cast(HostPtr)}, _ownsMem{false}, IsImage{_IsImage} { + } + + ~ur_mem_handle_t_() { + if (_ownsMem) { + free(_mem); + } + } + + void decrementRefCount() noexcept { _refCount--; } + + // Method to get type of the derived object (image or buffer) + bool isImage() const { return this->IsImage; } + + char *_mem; + bool _ownsMem; + std::atomic_uint32_t _refCount = {1}; + +private: + const bool IsImage; +}; + +struct _ur_buffer final : ur_mem_handle_t_ { + // Buffer constructor + _ur_buffer(ur_context_handle_t /* Context*/, void *HostPtr) + : ur_mem_handle_t_(HostPtr, false) {} + _ur_buffer(ur_context_handle_t /* Context*/, void *HostPtr, size_t Size) + : ur_mem_handle_t_(HostPtr, Size, false) {} + _ur_buffer(ur_context_handle_t /* Context*/, size_t Size) + : ur_mem_handle_t_(Size, false) {} + _ur_buffer(_ur_buffer *b, size_t Offset, size_t Size) + : ur_mem_handle_t_(b->_mem + Offset, false), SubBuffer(b) { + SubBuffer.Origin = Offset; + } + + bool isSubBuffer() const { return SubBuffer.Parent != nullptr; } + + struct BB { + BB(_ur_buffer *b) : Parent(b) {} + BB() : BB(nullptr) {} + _ur_buffer *const Parent; + size_t Origin; // only valid if Parent != nullptr + } SubBuffer; +}; diff --git a/source/adapters/native_cpu/nativecpu_state.hpp b/source/adapters/native_cpu/nativecpu_state.hpp new file mode 100644 index 0000000000..129d2c0e9a --- /dev/null +++ b/source/adapters/native_cpu/nativecpu_state.hpp @@ -0,0 +1,57 @@ +//===--------- nativecpu_state.hpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#pragma once +#include +namespace native_cpu { + +struct state { + size_t MGlobal_id[3]; + size_t MGlobal_range[3]; + size_t MWorkGroup_size[3]; + size_t MWorkGroup_id[3]; + size_t MLocal_id[3]; + size_t MNumGroups[3]; + size_t MGlobalOffset[3]; + state(size_t globalR0, size_t globalR1, size_t globalR2, size_t localR0, + size_t localR1, size_t localR2, size_t globalO0, size_t globalO1, + size_t globalO2) + : MGlobal_range{globalR0, globalR1, globalR2}, + MWorkGroup_size{localR0, localR1, localR2}, + MNumGroups{globalR0 / localR0, globalR1 / localR1, globalR2 / localR2}, + MGlobalOffset{globalO0, globalO1, globalO2} { + MGlobal_id[0] = 0; + MGlobal_id[1] = 0; + MGlobal_id[2] = 0; + MWorkGroup_id[0] = 0; + MWorkGroup_id[1] = 0; + MWorkGroup_id[2] = 0; + MLocal_id[0] = 0; + MLocal_id[1] = 0; + MLocal_id[2] = 0; + } + + void update(size_t group0, size_t group1, size_t group2, size_t local0, + size_t local1, size_t local2) { + MWorkGroup_id[0] = group0; + MWorkGroup_id[1] = group1; + MWorkGroup_id[2] = group2; + MLocal_id[0] = local0; + MLocal_id[1] = local1; + MLocal_id[2] = local2; + MGlobal_id[0] = + MWorkGroup_size[0] * MWorkGroup_id[0] + MLocal_id[0] + MGlobalOffset[0]; + MGlobal_id[1] = + MWorkGroup_size[1] * MWorkGroup_id[1] + MLocal_id[1] + MGlobalOffset[1]; + MGlobal_id[2] = + MWorkGroup_size[2] * MWorkGroup_id[2] + MLocal_id[2] + MGlobalOffset[2]; + } +}; + +} // namespace native_cpu diff --git a/source/adapters/native_cpu/platform.cpp b/source/adapters/native_cpu/platform.cpp new file mode 100644 index 0000000000..d07a7a8000 --- /dev/null +++ b/source/adapters/native_cpu/platform.cpp @@ -0,0 +1,117 @@ +//===--------- platform.cpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "platform.hpp" +#include "common.hpp" + +#include "ur/ur.hpp" +#include "ur_api.h" + +#include + +UR_APIEXPORT ur_result_t UR_APICALL +urPlatformGet(ur_adapter_handle_t *, uint32_t, uint32_t NumEntries, + ur_platform_handle_t *phPlatforms, uint32_t *pNumPlatforms) { + + UR_ASSERT(pNumPlatforms || phPlatforms, UR_RESULT_ERROR_INVALID_VALUE); + + if (pNumPlatforms) { + *pNumPlatforms = 1; + } + + if (NumEntries == 0) { + if (phPlatforms != nullptr) { + if (PrintTrace) { + std::cerr << "Invalid argument combination for urPlatformsGet\n"; + } + return UR_RESULT_ERROR_INVALID_VALUE; + } + return UR_RESULT_SUCCESS; + } + if (phPlatforms && NumEntries > 0) { + static ur_platform_handle_t_ ThePlatform; + *phPlatforms = &ThePlatform; + } + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urPlatformGetApiVersion( + ur_platform_handle_t hDriver, ur_api_version_t *pVersion) { + UR_ASSERT(hDriver, UR_RESULT_ERROR_INVALID_NULL_HANDLE); + UR_ASSERT(pVersion, UR_RESULT_ERROR_INVALID_NULL_POINTER); + + *pVersion = UR_API_VERSION_CURRENT; + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urPlatformGetInfo(ur_platform_handle_t hPlatform, ur_platform_info_t propName, + size_t propSize, void *pParamValue, size_t *pSizeRet) { + + if (hPlatform == nullptr) { + return UR_RESULT_ERROR_INVALID_PLATFORM; + } + UrReturnHelper ReturnValue(propSize, pParamValue, pSizeRet); + + switch (propName) { + case UR_PLATFORM_INFO_NAME: + return ReturnValue("SYCL_NATIVE_CPU"); + + case UR_PLATFORM_INFO_VENDOR_NAME: + return ReturnValue("tbd"); + + case UR_PLATFORM_INFO_VERSION: + return ReturnValue("0.1"); + + case UR_PLATFORM_INFO_PROFILE: + return ReturnValue("FULL_PROFILE"); + + case UR_PLATFORM_INFO_EXTENSIONS: + return ReturnValue(""); + + case UR_PLATFORM_INFO_BACKEND: + // TODO(alcpz): PR with this enum value at + // https://github.com/oneapi-src/unified-runtime + return ReturnValue(UR_PLATFORM_BACKEND_NATIVE_CPU); + default: + DIE_NO_IMPLEMENTATION; + } + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urPlatformGetBackendOption( + ur_platform_handle_t hPlatform, const char *pFrontendOption, + const char **ppPlatformOption) { + std::ignore = hPlatform; + std::ignore = pFrontendOption; + std::ignore = ppPlatformOption; + + CONTINUE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urPlatformCreateWithNativeHandle( + ur_native_handle_t hNativePlatform, + const ur_platform_native_properties_t *pProperties, + ur_platform_handle_t *phPlatform) { + std::ignore = hNativePlatform; + std::ignore = pProperties; + std::ignore = phPlatform; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urPlatformGetNativeHandle( + ur_platform_handle_t hPlatform, ur_native_handle_t *phNativePlatform) { + std::ignore = hPlatform; + std::ignore = phNativePlatform; + + DIE_NO_IMPLEMENTATION; +} diff --git a/source/adapters/native_cpu/platform.hpp b/source/adapters/native_cpu/platform.hpp new file mode 100644 index 0000000000..3c69760227 --- /dev/null +++ b/source/adapters/native_cpu/platform.hpp @@ -0,0 +1,20 @@ +//===--------- platform.hpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include + +#include "common.hpp" +#include "device.hpp" + +struct ur_platform_handle_t_ { + ur_device_handle_t_ TheDevice{this}; +}; diff --git a/source/adapters/native_cpu/program.cpp b/source/adapters/native_cpu/program.cpp new file mode 100644 index 0000000000..389626fa70 --- /dev/null +++ b/source/adapters/native_cpu/program.cpp @@ -0,0 +1,188 @@ +//===--------- program.cpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ur_api.h" + +#include "common.hpp" +#include "program.hpp" + +UR_APIEXPORT ur_result_t UR_APICALL +urProgramCreateWithIL(ur_context_handle_t hContext, const void *pIL, + size_t length, const ur_program_properties_t *pProperties, + ur_program_handle_t *phProgram) { + std::ignore = hContext; + std::ignore = pIL; + std::ignore = length; + std::ignore = pProperties; + std::ignore = phProgram; + + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL urProgramCreateWithBinary( + ur_context_handle_t hContext, ur_device_handle_t hDevice, size_t size, + const uint8_t *pBinary, const ur_program_properties_t *pProperties, + ur_program_handle_t *phProgram) { + std::ignore = size; + std::ignore = pProperties; + + UR_ASSERT(hContext, UR_RESULT_ERROR_INVALID_NULL_HANDLE); + UR_ASSERT(hDevice, UR_RESULT_ERROR_INVALID_NULL_HANDLE); + UR_ASSERT(phProgram, UR_RESULT_ERROR_INVALID_NULL_POINTER); + UR_ASSERT(pBinary != nullptr, UR_RESULT_ERROR_INVALID_NULL_POINTER); + + auto hProgram = new ur_program_handle_t_( + hContext, reinterpret_cast(pBinary)); + + const nativecpu_entry *nativecpu_it = + reinterpret_cast(pBinary); + while (nativecpu_it->kernel_ptr != nullptr) { + hProgram->_kernels.insert( + std::make_pair(nativecpu_it->kernelname, nativecpu_it->kernel_ptr)); + nativecpu_it++; + } + + *phProgram = hProgram; + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urProgramBuild(ur_context_handle_t hContext, + ur_program_handle_t hProgram, + const char *pOptions) { + std::ignore = hContext; + std::ignore = hProgram; + std::ignore = pOptions; + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urProgramCompile(ur_context_handle_t hContext, ur_program_handle_t hProgram, + const char *pOptions) { + std::ignore = hContext; + std::ignore = hProgram; + std::ignore = pOptions; + + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL +urProgramLink(ur_context_handle_t hContext, uint32_t count, + const ur_program_handle_t *phPrograms, const char *pOptions, + ur_program_handle_t *phProgram) { + std::ignore = hContext; + std::ignore = count; + std::ignore = phPrograms; + std::ignore = pOptions; + std::ignore = phProgram; + + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL +urProgramRetain(ur_program_handle_t hProgram) { + hProgram->incrementReferenceCount(); + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urProgramRelease(ur_program_handle_t hProgram) { + delete hProgram; + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urProgramGetFunctionPointer( + ur_device_handle_t hDevice, ur_program_handle_t hProgram, + const char *pFunctionName, void **ppFunctionPointer) { + std::ignore = hDevice; + std::ignore = hProgram; + std::ignore = pFunctionName; + std::ignore = ppFunctionPointer; + + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL +urProgramGetInfo(ur_program_handle_t hProgram, ur_program_info_t propName, + size_t propSize, void *pPropValue, size_t *pPropSizeRet) { + UR_ASSERT(hProgram, UR_RESULT_ERROR_INVALID_NULL_HANDLE); + + UrReturnHelper returnValue(propSize, pPropValue, pPropSizeRet); + + switch (propName) { + case UR_PROGRAM_INFO_REFERENCE_COUNT: + return returnValue(hProgram->getReferenceCount()); + case UR_PROGRAM_INFO_CONTEXT: + return returnValue(nullptr); + case UR_PROGRAM_INFO_NUM_DEVICES: + return returnValue(1u); + case UR_PROGRAM_INFO_DEVICES: + return returnValue(hProgram->_ctx->_device); + case UR_PROGRAM_INFO_SOURCE: + return returnValue(nullptr); + case UR_PROGRAM_INFO_BINARY_SIZES: + return returnValue("foo"); + case UR_PROGRAM_INFO_BINARIES: + return returnValue("foo"); + case UR_PROGRAM_INFO_KERNEL_NAMES: { + return returnValue("foo"); + } + default: + break; + } + + return UR_RESULT_ERROR_INVALID_ENUMERATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urProgramGetBuildInfo(ur_program_handle_t hProgram, ur_device_handle_t hDevice, + ur_program_build_info_t propName, size_t propSize, + void *pPropValue, size_t *pPropSizeRet) { + std::ignore = hProgram; + std::ignore = hDevice; + std::ignore = propName; + std::ignore = propSize; + std::ignore = pPropValue; + std::ignore = pPropSizeRet; + + CONTINUE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL urProgramSetSpecializationConstants( + ur_program_handle_t hProgram, uint32_t count, + const ur_specialization_constant_info_t *pSpecConstants) { + std::ignore = hProgram; + std::ignore = count; + std::ignore = pSpecConstants; + + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL urProgramGetNativeHandle( + ur_program_handle_t hProgram, ur_native_handle_t *phNativeProgram) { + std::ignore = hProgram; + std::ignore = phNativeProgram; + + DIE_NO_IMPLEMENTATION +} + +UR_APIEXPORT ur_result_t UR_APICALL urProgramCreateWithNativeHandle( + ur_native_handle_t hNativeProgram, ur_context_handle_t hContext, + const ur_program_native_properties_t *pProperties, + ur_program_handle_t *phProgram) { + std::ignore = hNativeProgram; + std::ignore = hContext; + std::ignore = pProperties; + std::ignore = phProgram; + + DIE_NO_IMPLEMENTATION +} diff --git a/source/adapters/native_cpu/program.hpp b/source/adapters/native_cpu/program.hpp new file mode 100644 index 0000000000..311eb40992 --- /dev/null +++ b/source/adapters/native_cpu/program.hpp @@ -0,0 +1,42 @@ +//===--------- program.hpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include + +#include "context.hpp" +#include + +struct ur_program_handle_t_ : RefCounted { + ur_program_handle_t_(ur_context_handle_t ctx, const unsigned char *pBinary) + : _ctx{ctx}, _ptr{pBinary} {} + + uint32_t getReferenceCount() const noexcept { return _refCount; } + + ur_context_handle_t _ctx; + const unsigned char *_ptr; + struct _compare { + bool operator()(char const *a, char const *b) const { + return std::strcmp(a, b) < 0; + } + }; + + std::map _kernels; +}; + +// The nativecpu_entry struct is also defined as LLVM-IR in the +// clang-offload-wrapper tool. The two definitions need to match, +// therefore any change to this struct needs to be reflected in the +// offload-wrapper. +struct nativecpu_entry { + const char *kernelname; + const unsigned char *kernel_ptr; +}; diff --git a/source/adapters/native_cpu/queue.cpp b/source/adapters/native_cpu/queue.cpp new file mode 100644 index 0000000000..852b7981e0 --- /dev/null +++ b/source/adapters/native_cpu/queue.cpp @@ -0,0 +1,88 @@ +//===--------- queue.cpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "queue.hpp" +#include "common.hpp" + +#include "ur/ur.hpp" +#include "ur_api.h" + +UR_APIEXPORT ur_result_t UR_APICALL urQueueGetInfo(ur_queue_handle_t hQueue, + ur_queue_info_t propName, + size_t propSize, + void *pPropValue, + size_t *pPropSizeRet) { + std::ignore = hQueue; + std::ignore = propName; + std::ignore = propSize; + std::ignore = pPropValue; + std::ignore = pPropSizeRet; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urQueueCreate( + ur_context_handle_t hContext, ur_device_handle_t hDevice, + const ur_queue_properties_t *pProperties, ur_queue_handle_t *phQueue) { + std::ignore = hContext; + std::ignore = hDevice; + std::ignore = pProperties; + + auto Queue = new ur_queue_handle_t_(); + *phQueue = Queue; + + CONTINUE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urQueueRetain(ur_queue_handle_t hQueue) { + std::ignore = hQueue; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urQueueRelease(ur_queue_handle_t hQueue) { + delete hQueue; + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urQueueGetNativeHandle(ur_queue_handle_t hQueue, ur_queue_native_desc_t *pDesc, + ur_native_handle_t *phNativeQueue) { + std::ignore = hQueue; + std::ignore = pDesc; + std::ignore = phNativeQueue; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urQueueCreateWithNativeHandle( + ur_native_handle_t hNativeQueue, ur_context_handle_t hContext, + ur_device_handle_t hDevice, const ur_queue_native_properties_t *pProperties, + ur_queue_handle_t *phQueue) { + std::ignore = hNativeQueue; + std::ignore = hContext; + std::ignore = hDevice; + std::ignore = pProperties; + std::ignore = phQueue; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urQueueFinish(ur_queue_handle_t hQueue) { + std::ignore = hQueue; + // TODO: is this fine as no-op? + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urQueueFlush(ur_queue_handle_t hQueue) { + std::ignore = hQueue; + + DIE_NO_IMPLEMENTATION; +} diff --git a/source/adapters/native_cpu/queue.hpp b/source/adapters/native_cpu/queue.hpp new file mode 100644 index 0000000000..fb3a78f429 --- /dev/null +++ b/source/adapters/native_cpu/queue.hpp @@ -0,0 +1,12 @@ +//===--------- queue.hpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#pragma once + +struct ur_queue_handle_t_ {}; diff --git a/source/adapters/native_cpu/sampler.cpp b/source/adapters/native_cpu/sampler.cpp new file mode 100644 index 0000000000..962fa8dc2e --- /dev/null +++ b/source/adapters/native_cpu/sampler.cpp @@ -0,0 +1,69 @@ +//===--------- sampler.cpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ur_api.h" + +#include "common.hpp" + +UR_APIEXPORT ur_result_t UR_APICALL +urSamplerCreate(ur_context_handle_t hContext, const ur_sampler_desc_t *pDesc, + ur_sampler_handle_t *phSampler) { + std::ignore = hContext; + std::ignore = pDesc; + std::ignore = phSampler; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urSamplerRetain(ur_sampler_handle_t hSampler) { + std::ignore = hSampler; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urSamplerRelease(ur_sampler_handle_t hSampler) { + std::ignore = hSampler; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urSamplerGetInfo(ur_sampler_handle_t hSampler, ur_sampler_info_t propName, + size_t propSize, void *pPropValue, size_t *pPropSizeRet) { + std::ignore = hSampler; + std::ignore = propName; + std::ignore = propSize; + std::ignore = pPropValue; + std::ignore = pPropSizeRet; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urSamplerGetNativeHandle( + ur_sampler_handle_t hSampler, ur_native_handle_t *phNativeSampler) { + std::ignore = hSampler; + std::ignore = phNativeSampler; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urSamplerCreateWithNativeHandle( + ur_native_handle_t hNativeSampler, ur_context_handle_t hContext, + const ur_sampler_native_properties_t *pProperties, + ur_sampler_handle_t *phSampler) { + std::ignore = hNativeSampler; + std::ignore = hContext; + std::ignore = pProperties; + std::ignore = phSampler; + + DIE_NO_IMPLEMENTATION; +} diff --git a/source/adapters/native_cpu/ur_interface_loader.cpp b/source/adapters/native_cpu/ur_interface_loader.cpp new file mode 100644 index 0000000000..507044017e --- /dev/null +++ b/source/adapters/native_cpu/ur_interface_loader.cpp @@ -0,0 +1,280 @@ +//===--------- ur_interface_loader.cpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include + +namespace { + +// TODO - this is a duplicate of what is in the L0 plugin +// We should move this to somewhere common +ur_result_t validateProcInputs(ur_api_version_t version, void *pDdiTable) { + if (pDdiTable == nullptr) { + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + } + // Pre 1.0 we enforce that loader and adapter must have the same version. + // Post 1.0 only a major version match should be required. + if (version != UR_API_VERSION_CURRENT) { + return UR_RESULT_ERROR_UNSUPPORTED_VERSION; + } + return UR_RESULT_SUCCESS; +} +} // namespace + +extern "C" { + +UR_DLLEXPORT ur_result_t UR_APICALL urGetPlatformProcAddrTable( + ur_api_version_t version, ur_platform_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + pDdiTable->pfnCreateWithNativeHandle = urPlatformCreateWithNativeHandle; + pDdiTable->pfnGet = urPlatformGet; + pDdiTable->pfnGetApiVersion = urPlatformGetApiVersion; + pDdiTable->pfnGetInfo = urPlatformGetInfo; + pDdiTable->pfnGetNativeHandle = urPlatformGetNativeHandle; + pDdiTable->pfnGetBackendOption = urPlatformGetBackendOption; + return UR_RESULT_SUCCESS; +} + +UR_DLLEXPORT ur_result_t UR_APICALL urGetContextProcAddrTable( + ur_api_version_t version, ur_context_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + pDdiTable->pfnCreate = urContextCreate; + pDdiTable->pfnCreateWithNativeHandle = urContextCreateWithNativeHandle; + pDdiTable->pfnGetInfo = urContextGetInfo; + pDdiTable->pfnGetNativeHandle = urContextGetNativeHandle; + pDdiTable->pfnRelease = urContextRelease; + pDdiTable->pfnRetain = urContextRetain; + pDdiTable->pfnSetExtendedDeleter = urContextSetExtendedDeleter; + return UR_RESULT_SUCCESS; +} + +UR_DLLEXPORT ur_result_t UR_APICALL urGetEventProcAddrTable( + ur_api_version_t version, ur_event_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + pDdiTable->pfnCreateWithNativeHandle = urEventCreateWithNativeHandle; + pDdiTable->pfnGetInfo = urEventGetInfo; + pDdiTable->pfnGetNativeHandle = urEventGetNativeHandle; + pDdiTable->pfnGetProfilingInfo = urEventGetProfilingInfo; + pDdiTable->pfnRelease = urEventRelease; + pDdiTable->pfnRetain = urEventRetain; + pDdiTable->pfnSetCallback = urEventSetCallback; + pDdiTable->pfnWait = urEventWait; + return UR_RESULT_SUCCESS; +} + +UR_DLLEXPORT ur_result_t UR_APICALL urGetProgramProcAddrTable( + ur_api_version_t version, ur_program_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + pDdiTable->pfnBuild = urProgramBuild; + pDdiTable->pfnCompile = urProgramCompile; + pDdiTable->pfnCreateWithBinary = urProgramCreateWithBinary; + pDdiTable->pfnCreateWithIL = urProgramCreateWithIL; + pDdiTable->pfnCreateWithNativeHandle = urProgramCreateWithNativeHandle; + pDdiTable->pfnGetBuildInfo = urProgramGetBuildInfo; + pDdiTable->pfnGetFunctionPointer = urProgramGetFunctionPointer; + pDdiTable->pfnGetInfo = urProgramGetInfo; + pDdiTable->pfnGetNativeHandle = urProgramGetNativeHandle; + pDdiTable->pfnLink = urProgramLink; + pDdiTable->pfnRelease = urProgramRelease; + pDdiTable->pfnRetain = urProgramRetain; + pDdiTable->pfnSetSpecializationConstants = + urProgramSetSpecializationConstants; + return UR_RESULT_SUCCESS; +} + +UR_DLLEXPORT ur_result_t UR_APICALL urGetKernelProcAddrTable( + ur_api_version_t version, ur_kernel_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + pDdiTable->pfnCreate = urKernelCreate; + pDdiTable->pfnCreateWithNativeHandle = urKernelCreateWithNativeHandle; + pDdiTable->pfnGetGroupInfo = urKernelGetGroupInfo; + pDdiTable->pfnGetInfo = urKernelGetInfo; + pDdiTable->pfnGetNativeHandle = urKernelGetNativeHandle; + pDdiTable->pfnGetSubGroupInfo = urKernelGetSubGroupInfo; + pDdiTable->pfnRelease = urKernelRelease; + pDdiTable->pfnRetain = urKernelRetain; + pDdiTable->pfnSetArgLocal = urKernelSetArgLocal; + pDdiTable->pfnSetArgMemObj = urKernelSetArgMemObj; + pDdiTable->pfnSetArgPointer = urKernelSetArgPointer; + pDdiTable->pfnSetArgSampler = urKernelSetArgSampler; + pDdiTable->pfnSetArgValue = urKernelSetArgValue; + pDdiTable->pfnSetExecInfo = urKernelSetExecInfo; + pDdiTable->pfnSetSpecializationConstants = urKernelSetSpecializationConstants; + return UR_RESULT_SUCCESS; +} + +UR_DLLEXPORT ur_result_t UR_APICALL urGetSamplerProcAddrTable( + ur_api_version_t version, ur_sampler_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + pDdiTable->pfnCreate = urSamplerCreate; + pDdiTable->pfnCreateWithNativeHandle = urSamplerCreateWithNativeHandle; + pDdiTable->pfnGetInfo = urSamplerGetInfo; + pDdiTable->pfnGetNativeHandle = urSamplerGetNativeHandle; + pDdiTable->pfnRelease = urSamplerRelease; + pDdiTable->pfnRetain = urSamplerRetain; + return UR_RESULT_SUCCESS; +} + +UR_DLLEXPORT ur_result_t UR_APICALL +urGetMemProcAddrTable(ur_api_version_t version, ur_mem_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + pDdiTable->pfnBufferCreate = urMemBufferCreate; + pDdiTable->pfnBufferPartition = urMemBufferPartition; + pDdiTable->pfnBufferCreateWithNativeHandle = + urMemBufferCreateWithNativeHandle; + pDdiTable->pfnImageCreateWithNativeHandle = urMemImageCreateWithNativeHandle; + pDdiTable->pfnGetInfo = urMemGetInfo; + pDdiTable->pfnGetNativeHandle = urMemGetNativeHandle; + pDdiTable->pfnImageCreate = urMemImageCreate; + pDdiTable->pfnImageGetInfo = urMemImageGetInfo; + pDdiTable->pfnRelease = urMemRelease; + pDdiTable->pfnRetain = urMemRetain; + return UR_RESULT_SUCCESS; +} + +UR_DLLEXPORT ur_result_t UR_APICALL urGetEnqueueProcAddrTable( + ur_api_version_t version, ur_enqueue_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + pDdiTable->pfnDeviceGlobalVariableRead = urEnqueueDeviceGlobalVariableRead; + pDdiTable->pfnDeviceGlobalVariableWrite = urEnqueueDeviceGlobalVariableWrite; + pDdiTable->pfnEventsWait = urEnqueueEventsWait; + pDdiTable->pfnEventsWaitWithBarrier = urEnqueueEventsWaitWithBarrier; + pDdiTable->pfnKernelLaunch = urEnqueueKernelLaunch; + pDdiTable->pfnMemBufferCopy = urEnqueueMemBufferCopy; + pDdiTable->pfnMemBufferCopyRect = urEnqueueMemBufferCopyRect; + pDdiTable->pfnMemBufferFill = urEnqueueMemBufferFill; + pDdiTable->pfnMemBufferMap = urEnqueueMemBufferMap; + pDdiTable->pfnMemBufferRead = urEnqueueMemBufferRead; + pDdiTable->pfnMemBufferReadRect = urEnqueueMemBufferReadRect; + pDdiTable->pfnMemBufferWrite = urEnqueueMemBufferWrite; + pDdiTable->pfnMemBufferWriteRect = urEnqueueMemBufferWriteRect; + pDdiTable->pfnMemImageCopy = urEnqueueMemImageCopy; + pDdiTable->pfnMemImageRead = urEnqueueMemImageRead; + pDdiTable->pfnMemImageWrite = urEnqueueMemImageWrite; + pDdiTable->pfnMemUnmap = urEnqueueMemUnmap; + pDdiTable->pfnUSMFill2D = urEnqueueUSMFill2D; + pDdiTable->pfnUSMFill = urEnqueueUSMFill; + pDdiTable->pfnUSMAdvise = urEnqueueUSMAdvise; + pDdiTable->pfnUSMMemcpy2D = urEnqueueUSMMemcpy2D; + pDdiTable->pfnUSMMemcpy = urEnqueueUSMMemcpy; + pDdiTable->pfnUSMPrefetch = urEnqueueUSMPrefetch; + pDdiTable->pfnReadHostPipe = urEnqueueReadHostPipe; + pDdiTable->pfnWriteHostPipe = urEnqueueWriteHostPipe; + return UR_RESULT_SUCCESS; +} + +UR_DLLEXPORT ur_result_t UR_APICALL urGetGlobalProcAddrTable( + ur_api_version_t version, ur_global_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + pDdiTable->pfnInit = urInit; + pDdiTable->pfnTearDown = urTearDown; + pDdiTable->pfnAdapterGet = urAdapterGet; + pDdiTable->pfnAdapterGetInfo = urAdapterGetInfo; + pDdiTable->pfnAdapterRelease = urAdapterRelease; + pDdiTable->pfnAdapterRetain = urAdapterRetain; + return UR_RESULT_SUCCESS; +} + +UR_DLLEXPORT ur_result_t UR_APICALL urGetQueueProcAddrTable( + ur_api_version_t version, ur_queue_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + pDdiTable->pfnCreate = urQueueCreate; + pDdiTable->pfnCreateWithNativeHandle = urQueueCreateWithNativeHandle; + pDdiTable->pfnFinish = urQueueFinish; + pDdiTable->pfnFlush = urQueueFlush; + pDdiTable->pfnGetInfo = urQueueGetInfo; + pDdiTable->pfnGetNativeHandle = urQueueGetNativeHandle; + pDdiTable->pfnRelease = urQueueRelease; + pDdiTable->pfnRetain = urQueueRetain; + return UR_RESULT_SUCCESS; +} + +UR_DLLEXPORT ur_result_t UR_APICALL +urGetUSMProcAddrTable(ur_api_version_t version, ur_usm_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + pDdiTable->pfnDeviceAlloc = urUSMDeviceAlloc; + pDdiTable->pfnFree = urUSMFree; + pDdiTable->pfnGetMemAllocInfo = urUSMGetMemAllocInfo; + pDdiTable->pfnHostAlloc = urUSMHostAlloc; + pDdiTable->pfnPoolCreate = urUSMPoolCreate; + pDdiTable->pfnPoolRetain = urUSMPoolRetain; + pDdiTable->pfnPoolRelease = urUSMPoolRelease; + pDdiTable->pfnPoolGetInfo = urUSMPoolGetInfo; + pDdiTable->pfnSharedAlloc = urUSMSharedAlloc; + return UR_RESULT_SUCCESS; +} + +UR_DLLEXPORT ur_result_t UR_APICALL urGetDeviceProcAddrTable( + ur_api_version_t version, ur_device_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + pDdiTable->pfnCreateWithNativeHandle = urDeviceCreateWithNativeHandle; + pDdiTable->pfnGet = urDeviceGet; + pDdiTable->pfnGetGlobalTimestamps = urDeviceGetGlobalTimestamps; + pDdiTable->pfnGetInfo = urDeviceGetInfo; + pDdiTable->pfnGetNativeHandle = urDeviceGetNativeHandle; + pDdiTable->pfnPartition = urDevicePartition; + pDdiTable->pfnRelease = urDeviceRelease; + pDdiTable->pfnRetain = urDeviceRetain; + pDdiTable->pfnSelectBinary = urDeviceSelectBinary; + return UR_RESULT_SUCCESS; +} + +// TODO: CommandBuffer + +UR_DLLEXPORT ur_result_t UR_APICALL urGetUsmP2PExpProcAddrTable( + ur_api_version_t version, ur_usm_p2p_exp_dditable_t *pDdiTable) { + auto retVal = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != retVal) { + return retVal; + } + pDdiTable->pfnEnablePeerAccessExp = urUsmP2PEnablePeerAccessExp; + pDdiTable->pfnDisablePeerAccessExp = urUsmP2PDisablePeerAccessExp; + pDdiTable->pfnPeerAccessGetInfoExp = urUsmP2PPeerAccessGetInfoExp; + + return retVal; +} + +} // extern "C" diff --git a/source/adapters/native_cpu/usm.cpp b/source/adapters/native_cpu/usm.cpp new file mode 100644 index 0000000000..9e12bf51fb --- /dev/null +++ b/source/adapters/native_cpu/usm.cpp @@ -0,0 +1,141 @@ +//===--------- usm.cpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ur_api.h" + +#include "common.hpp" + +UR_APIEXPORT ur_result_t UR_APICALL +urUSMHostAlloc(ur_context_handle_t hContext, const ur_usm_desc_t *pUSMDesc, + ur_usm_pool_handle_t pool, size_t size, void **ppMem) { + std::ignore = hContext; + std::ignore = pUSMDesc; + std::ignore = pool; + + UR_ASSERT(ppMem, UR_RESULT_ERROR_INVALID_NULL_POINTER); + // TODO: Check Max size when UR_DEVICE_INFO_MAX_MEM_ALLOC_SIZE is implemented + UR_ASSERT(size > 0, UR_RESULT_ERROR_INVALID_USM_SIZE); + + *ppMem = malloc(size); + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urUSMDeviceAlloc(ur_context_handle_t hContext, ur_device_handle_t hDevice, + const ur_usm_desc_t *pUSMDesc, ur_usm_pool_handle_t pool, + size_t size, void **ppMem) { + std::ignore = hContext; + std::ignore = hDevice; + std::ignore = pUSMDesc; + std::ignore = pool; + + UR_ASSERT(ppMem, UR_RESULT_ERROR_INVALID_NULL_POINTER); + // TODO: Check Max size when UR_DEVICE_INFO_MAX_MEM_ALLOC_SIZE is implemented + UR_ASSERT(size > 0, UR_RESULT_ERROR_INVALID_USM_SIZE); + + *ppMem = malloc(size); + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urUSMSharedAlloc(ur_context_handle_t hContext, ur_device_handle_t hDevice, + const ur_usm_desc_t *pUSMDesc, ur_usm_pool_handle_t pool, + size_t size, void **ppMem) { + std::ignore = hContext; + std::ignore = hDevice; + std::ignore = pUSMDesc; + std::ignore = pool; + + UR_ASSERT(ppMem, UR_RESULT_ERROR_INVALID_NULL_POINTER); + // TODO: Check Max size when UR_DEVICE_INFO_MAX_MEM_ALLOC_SIZE is implemented + UR_ASSERT(size > 0, UR_RESULT_ERROR_INVALID_USM_SIZE); + + *ppMem = malloc(size); + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urUSMFree(ur_context_handle_t hContext, + void *pMem) { + std::ignore = hContext; + + UR_ASSERT(pMem, UR_RESULT_ERROR_INVALID_NULL_POINTER); + + free(pMem); + + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urUSMGetMemAllocInfo(ur_context_handle_t hContext, const void *pMem, + ur_usm_alloc_info_t propName, size_t propSize, + void *pPropValue, size_t *pPropSizeRet) { + std::ignore = hContext; + std::ignore = pMem; + std::ignore = propName; + std::ignore = propSize; + std::ignore = pPropValue; + std::ignore = pPropSizeRet; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urUSMPoolCreate(ur_context_handle_t hContext, ur_usm_pool_desc_t *pPoolDesc, + ur_usm_pool_handle_t *ppPool) { + std::ignore = hContext; + std::ignore = pPoolDesc; + std::ignore = ppPool; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urUSMPoolRetain(ur_usm_pool_handle_t pPool) { + std::ignore = pPool; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urUSMPoolRelease(ur_usm_pool_handle_t pPool) { + std::ignore = pPool; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urUSMPoolGetInfo(ur_usm_pool_handle_t hPool, ur_usm_pool_info_t propName, + size_t propSize, void *pPropValue, size_t *pPropSizeRet) { + std::ignore = hPool; + std::ignore = propName; + std::ignore = propSize; + std::ignore = pPropValue; + std::ignore = pPropSizeRet; + + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urUSMImportExp(ur_context_handle_t Context, + void *HostPtr, size_t Size) { + std::ignore = Context; + std::ignore = HostPtr; + std::ignore = Size; + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL urUSMReleaseExp(ur_context_handle_t Context, + void *HostPtr) { + std::ignore = Context; + std::ignore = HostPtr; + DIE_NO_IMPLEMENTATION; +} diff --git a/source/adapters/native_cpu/usm_p2p.cpp b/source/adapters/native_cpu/usm_p2p.cpp new file mode 100644 index 0000000000..dbb47d910e --- /dev/null +++ b/source/adapters/native_cpu/usm_p2p.cpp @@ -0,0 +1,27 @@ +//===--------- usm_p2p.cpp - Native CPU Adapter ---------------------------===// +// +// Copyright (C) 2023 Intel Corporation +// +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +// Exceptions. See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "common.hpp" + +UR_APIEXPORT ur_result_t UR_APICALL +urUsmP2PEnablePeerAccessExp(ur_device_handle_t, ur_device_handle_t) { + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urUsmP2PDisablePeerAccessExp(ur_device_handle_t, ur_device_handle_t) { + DIE_NO_IMPLEMENTATION; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urUsmP2PPeerAccessGetInfoExp(ur_device_handle_t, ur_device_handle_t, + ur_exp_peer_info_t, size_t, void *, size_t *) { + DIE_NO_IMPLEMENTATION; +} diff --git a/test/conformance/CMakeLists.txt b/test/conformance/CMakeLists.txt index 9a273470eb..480af395c1 100644 --- a/test/conformance/CMakeLists.txt +++ b/test/conformance/CMakeLists.txt @@ -51,9 +51,13 @@ function(add_conformance_test name) if(UR_BUILD_ADAPTER_OPENCL) add_test_adapter(${name} adapter_opencl) endif() + if(UR_BUILD_ADAPTER_NATIVE_CPU) + add_test_adapter(${name} adapter_native_cpu) + endif() if(NOT (UR_BUILD_ADAPTER_CUDA OR UR_BUILD_ADAPTER_HIP - OR UR_BUILD_ADAPTER_L0 OR UR_BUILD_ADAPTER_OPENCL)) + OR UR_BUILD_ADAPTER_L0 OR UR_BUILD_ADAPTER_OPENCL + OR UR_BUILD_ADAPTER_NATIVE_CPU)) add_test_adapter(${name} adapter_null) endif() endfunction()