forked from iree-org/iree
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[HIP] Adds basics to implement HIP HAL driver
This commit starts a HIP backend in HAL. Following the steps of CUDA rewrite (iree-org#13245) effort, this backend will provide improvements over the existing ROCm HAL backend. Building this commmit with -DIREE_EXTERNAL_HAL_DRIVERS=hip will initialize this driver and the driver information can be seen using `tools/iree-run-module --dump_devices`.
- Loading branch information
1 parent
41a8152
commit c3f2071
Showing
13 changed files
with
1,105 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# Copyright 2023 The IREE Authors | ||
# | ||
# Licensed under the Apache License v2.0 with LLVM Exceptions. | ||
# See https://llvm.org/LICENSE.txt for license information. | ||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
# Set the root for package namespacing to the current directory. | ||
set(IREE_PACKAGE_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}") | ||
set(IREE_PACKAGE_ROOT_PREFIX "iree/experimental/hip") | ||
|
||
iree_add_all_subdirs() | ||
|
||
if(NOT DEFINED ROCM_HEADERS_API_ROOT) | ||
set(ROCM_HEADERS_API_ROOT "${IREE_SOURCE_DIR}/third_party/hip-build-deps/include") | ||
endif() | ||
|
||
if(NOT EXISTS "${ROCM_HEADERS_API_ROOT}/hip/hip_version.h") | ||
message(SEND_ERROR "Could not find HIP headers at: ${ROCM_HEADERS_API_ROOT}") | ||
endif() | ||
|
||
iree_cc_library( | ||
NAME | ||
hip | ||
HDRS | ||
"api.h" | ||
SRCS | ||
"api.h" | ||
"hip_driver.c" | ||
INCLUDES | ||
"${ROCM_HEADERS_API_ROOT}" | ||
DEPS | ||
::dynamic_symbols | ||
iree::base | ||
iree::base::core_headers | ||
iree::hal | ||
COPTS | ||
"-D__HIP_PLATFORM_HCC__=1" | ||
PUBLIC | ||
) | ||
|
||
iree_cc_library( | ||
NAME | ||
dynamic_symbols | ||
HDRS | ||
"dynamic_symbols.h" | ||
"status_util.h" | ||
TEXTUAL_HDRS | ||
"dynamic_symbol_tables.h" | ||
SRCS | ||
"hip_headers.h" | ||
"dynamic_symbols.c" | ||
"status_util.c" | ||
INCLUDES | ||
"${ROCM_HEADERS_API_ROOT}" | ||
COPTS | ||
"-D__HIP_PLATFORM_HCC__=1" | ||
DEPS | ||
iree::base | ||
iree::base::core_headers | ||
iree::base::internal::dynamic_library | ||
PUBLIC | ||
) | ||
|
||
iree_cc_test( | ||
NAME | ||
dynamic_symbols_test | ||
SRCS | ||
"dynamic_symbols_test.cc" | ||
DEPS | ||
::dynamic_symbols | ||
iree::base | ||
iree::testing::gtest | ||
iree::testing::gtest_main | ||
LABELS | ||
"driver=hip" | ||
COPTS | ||
"-D__HIP_PLATFORM_HCC__=1" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// Copyright 2023 The IREE Authors | ||
// | ||
// Licensed under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
// See iree/base/api.h for documentation on the API conventions used. | ||
|
||
#ifndef IREE_EXPERIMENTAL_HIP_API_H_ | ||
#define IREE_EXPERIMENTAL_HIP_API_H_ | ||
|
||
#include "iree/base/api.h" | ||
#include "iree/hal/api.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif // __cplusplus | ||
|
||
//===----------------------------------------------------------------------===// | ||
// iree_hal_hip_driver_t | ||
//===----------------------------------------------------------------------===// | ||
|
||
// HIP HAL driver creation options. | ||
typedef struct iree_hal_hip_driver_options_t { | ||
// The index of the default HIP device to use within the list of available | ||
// devices. | ||
int default_device_index; | ||
} iree_hal_hip_driver_options_t; | ||
|
||
// Initializes the given |out_options| with default driver creation options. | ||
IREE_API_EXPORT void iree_hal_hip_driver_options_initialize( | ||
iree_hal_hip_driver_options_t* out_options); | ||
|
||
// Creates a HIP HAL driver with the given |options|, from which HIP devices | ||
// can be enumerated and created with specific parameters. | ||
// | ||
// |out_driver| must be released by the caller (see iree_hal_driver_release). | ||
IREE_API_EXPORT iree_status_t iree_hal_hip_driver_create( | ||
iree_string_view_t identifier, | ||
const iree_hal_hip_driver_options_t* options, | ||
iree_allocator_t host_allocator, iree_hal_driver_t** out_driver); | ||
|
||
#ifdef __cplusplus | ||
} // extern "C" | ||
#endif // __cplusplus | ||
|
||
#endif // IREE_EXPERIMENTAL_HIP_API_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// Copyright 2023 The IREE Authors | ||
// | ||
// Licensed under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
//===----------------------------------------------------------------------===// | ||
// HIP symbols | ||
//===----------------------------------------------------------------------===// | ||
IREE_HIP_PFN_DECL(hipCtxCreate, hipCtx_t *, unsigned int, hipDevice_t) | ||
IREE_HIP_PFN_DECL(hipCtxDestroy, hipCtx_t) | ||
IREE_HIP_PFN_DECL(hipDeviceGet, hipDevice_t *, int) // No direct, need to modify | ||
IREE_HIP_PFN_DECL(hipGetDeviceCount, int *) | ||
IREE_HIP_PFN_DECL(hipGetDeviceProperties, hipDeviceProp_t *, int) | ||
IREE_HIP_PFN_DECL(hipDeviceGetName, char *, int, | ||
hipDevice_t) // No direct, need to modify | ||
IREE_HIP_PFN_STR_DECL( | ||
hipGetErrorName, | ||
hipError_t) // Unlike other functions hipGetErrorName(hipError_t) return | ||
// const char* instead of hipError_t so it uses a different | ||
// macro | ||
IREE_HIP_PFN_STR_DECL( | ||
hipGetErrorString, | ||
hipError_t) // Unlike other functions hipGetErrorName(hipError_t) return | ||
// const char* instead of hipError_t so it uses a different | ||
// macro | ||
IREE_HIP_PFN_DECL(hipInit, unsigned int) | ||
IREE_HIP_PFN_DECL(hipModuleLaunchKernel, hipFunction_t, unsigned int, unsigned int, | ||
unsigned int, unsigned int, unsigned int, unsigned int, | ||
unsigned int, hipStream_t, void **, void **) | ||
IREE_HIP_PFN_DECL(hipMemset, void *, int, size_t) | ||
IREE_HIP_PFN_DECL(hipMemsetAsync, void *, int, size_t, hipStream_t) | ||
IREE_HIP_PFN_DECL(hipMemsetD32Async, void *, int, size_t, hipStream_t) | ||
IREE_HIP_PFN_DECL(hipMemsetD16Async, void *, short, size_t, hipStream_t) | ||
IREE_HIP_PFN_DECL(hipMemsetD8Async, void *, char, size_t, hipStream_t) | ||
IREE_HIP_PFN_DECL(hipMemcpy, void *, const void *, size_t, hipMemcpyKind) | ||
IREE_HIP_PFN_DECL(hipMemcpyAsync, void *, const void *, size_t, hipMemcpyKind, | ||
hipStream_t) | ||
IREE_HIP_PFN_DECL(hipMalloc, void **, size_t) | ||
IREE_HIP_PFN_DECL(hipMallocManaged, hipDeviceptr_t *, size_t, unsigned int) | ||
IREE_HIP_PFN_DECL(hipFree, void *) | ||
IREE_HIP_PFN_DECL(hipHostFree, void *) | ||
IREE_HIP_PFN_DECL(hipMemAllocHost, void **, size_t, unsigned int) | ||
IREE_HIP_PFN_DECL(hipHostGetDevicePointer, void **, void *, unsigned int) | ||
IREE_HIP_PFN_DECL(hipModuleGetFunction, hipFunction_t *, hipModule_t, const char *) | ||
IREE_HIP_PFN_DECL(hipModuleLoadDataEx, hipModule_t *, const void *, unsigned int, | ||
hipJitOption *, void **) | ||
IREE_HIP_PFN_DECL(hipModuleLoadData, hipModule_t *, const void *) | ||
IREE_HIP_PFN_DECL(hipModuleUnload, hipModule_t) | ||
IREE_HIP_PFN_DECL(hipStreamCreateWithFlags, hipStream_t *, unsigned int) | ||
IREE_HIP_PFN_DECL(hipStreamDestroy, hipStream_t) | ||
IREE_HIP_PFN_DECL(hipStreamSynchronize, hipStream_t) | ||
IREE_HIP_PFN_DECL(hipStreamWaitEvent, hipStream_t, hipEvent_t, unsigned int) | ||
IREE_HIP_PFN_DECL(hipEventCreate, hipEvent_t *) | ||
IREE_HIP_PFN_DECL(hipEventDestroy, hipEvent_t) | ||
IREE_HIP_PFN_DECL(hipEventElapsedTime, float *, hipEvent_t, hipEvent_t) | ||
IREE_HIP_PFN_DECL(hipEventQuery, hipEvent_t) | ||
IREE_HIP_PFN_DECL(hipEventRecord, hipEvent_t, hipStream_t) | ||
IREE_HIP_PFN_DECL(hipEventSynchronize, hipEvent_t) | ||
IREE_HIP_PFN_DECL(hipDeviceGetAttribute, int *, hipDeviceAttribute_t, int) | ||
IREE_HIP_PFN_DECL(hipFuncSetAttribute, const void *, hipFuncAttribute, int) | ||
IREE_HIP_PFN_DECL(hipDeviceGetUuid, hipUUID *, hipDevice_t) | ||
IREE_HIP_PFN_DECL(hipDevicePrimaryCtxRetain, hipCtx_t *, hipDevice_t) | ||
IREE_HIP_PFN_DECL(hipCtxGetDevice, hipDevice_t *) | ||
IREE_HIP_PFN_DECL(hipCtxSetCurrent, hipCtx_t) | ||
IREE_HIP_PFN_DECL(hipDevicePrimaryCtxRelease, hipDevice_t) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
// Copyright 2023 The IREE Authors | ||
// | ||
// Licensed under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
#include "experimental/hip/dynamic_symbols.h" | ||
|
||
#include <string.h> | ||
|
||
#include "experimental/hip/status_util.h" | ||
#include "iree/base/assert.h" | ||
#include "iree/base/internal/dynamic_library.h" | ||
#include "iree/base/target_platform.h" | ||
#include "iree/base/tracing.h" | ||
|
||
//===----------------------------------------------------------------------===// | ||
// HIP dynamic symbols | ||
//===----------------------------------------------------------------------===// | ||
|
||
static const char* iree_hal_hip_dylib_names[] = { | ||
#if defined(IREE_PLATFORM_WINDOWS) | ||
"amdhip64.dll", | ||
#else | ||
"libamdhip64.so", | ||
#endif // IREE_PLATFORM_WINDOWS | ||
}; | ||
|
||
// Resolves all HIP dynamic symbols in `dynamic_symbol_tables.h` | ||
static iree_status_t iree_hal_hip_dynamic_symbols_resolve_all( | ||
iree_hal_hip_dynamic_symbols_t* syms) { | ||
#define IREE_HIP_PFN_DECL(hip_symbol_name, ...) \ | ||
{ \ | ||
static const char* name = #hip_symbol_name; \ | ||
IREE_RETURN_IF_ERROR(iree_dynamic_library_lookup_symbol( \ | ||
syms->dylib, name, (void**)&syms->hip_symbol_name)); \ | ||
} | ||
#define IREE_HIP_PFN_STR_DECL(hip_symbol_name, ...) IREE_HIP_PFN_DECL(hip_symbol_name, ...) | ||
#include "experimental/hip/dynamic_symbol_tables.h" // IWYU pragma: keep | ||
#undef IREE_HIP_PFN_DECL | ||
#undef IREE_HIP_PFN_STR_DECL | ||
return iree_ok_status(); | ||
} | ||
|
||
// #undef IREE_CONCAT | ||
|
||
iree_status_t iree_hal_hip_dynamic_symbols_initialize( | ||
iree_allocator_t host_allocator, | ||
iree_hal_hip_dynamic_symbols_t* out_syms) { | ||
IREE_ASSERT_ARGUMENT(out_syms); | ||
IREE_TRACE_ZONE_BEGIN(z0); | ||
|
||
memset(out_syms, 0, sizeof(*out_syms)); | ||
iree_status_t status = iree_dynamic_library_load_from_files( | ||
IREE_ARRAYSIZE(iree_hal_hip_dylib_names), iree_hal_hip_dylib_names, | ||
IREE_DYNAMIC_LIBRARY_FLAG_NONE, host_allocator, &out_syms->dylib); | ||
if (iree_status_is_not_found(status)) { | ||
iree_status_ignore(status); | ||
status = iree_make_status( | ||
IREE_STATUS_UNAVAILABLE, | ||
"HIP runtime library 'amdhip64.dll'/'libamdhip64.so' not available; please" | ||
"ensure installed and in dynamic library search path"); | ||
} | ||
if (iree_status_is_ok(status)) { | ||
status = iree_hal_hip_dynamic_symbols_resolve_all(out_syms); | ||
} | ||
if (!iree_status_is_ok(status)) { | ||
iree_hal_hip_dynamic_symbols_deinitialize(out_syms); | ||
} | ||
|
||
IREE_TRACE_ZONE_END(z0); | ||
return status; | ||
} | ||
|
||
void iree_hal_hip_dynamic_symbols_deinitialize( | ||
iree_hal_hip_dynamic_symbols_t* syms) { | ||
IREE_TRACE_ZONE_BEGIN(z0); | ||
|
||
iree_dynamic_library_release(syms->dylib); | ||
memset(syms, 0, sizeof(*syms)); | ||
|
||
IREE_TRACE_ZONE_END(z0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// Copyright 2023 The IREE Authors | ||
// | ||
// Licensed under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
#ifndef IREE_EXPERIMENTAL_HIP_DYNAMIC_SYMBOLS_H_ | ||
#define IREE_EXPERIMENTAL_HIP_DYNAMIC_SYMBOLS_H_ | ||
|
||
#include "experimental/hip/hip_headers.h" | ||
#include "iree/base/api.h" | ||
#include "iree/base/internal/dynamic_library.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif // __cplusplus | ||
|
||
// iree_dynamic_library_t allows dynamically loading a subset of HIP driver API. | ||
// We load all the symbols in `dynamic_symbol_tables.h` and | ||
// fail if any of the symbol is not available. The functions signatures are | ||
// matching the declarations in `hipruntime.h`. | ||
|
||
//===----------------------------------------------------------------------===// | ||
// HIP dynamic symbols | ||
//===----------------------------------------------------------------------===// | ||
|
||
// HIP driver API dynamic symbols. | ||
typedef struct iree_hal_hip_dynamic_symbols_t { | ||
// The dynamic library handle. | ||
iree_dynamic_library_t* dylib; | ||
|
||
// Concrete HIP symbols defined by including the `dynamic_symbol_tables.h`. | ||
#define IREE_HIP_PFN_DECL(hipSymbolName, ...) \ | ||
hipError_t (*hipSymbolName)(__VA_ARGS__); | ||
#define IREE_HIP_PFN_STR_DECL(hipSymbolName, ...) \ | ||
const char* (*hipSymbolName)(__VA_ARGS__); | ||
#include "experimental/hip/dynamic_symbol_tables.h" // IWYU pragma: export | ||
#undef IREE_HIP_PFN_DECL | ||
#undef IREE_HIP_PFN_STR_DECL | ||
} iree_hal_hip_dynamic_symbols_t; | ||
|
||
// Initializes |out_syms| in-place with dynamically loaded HIP symbols. | ||
// iree_hal_hip_dynamic_symbols_deinitialize must be used to release the | ||
// library resources. | ||
iree_status_t iree_hal_hip_dynamic_symbols_initialize( | ||
iree_allocator_t host_allocator, | ||
iree_hal_hip_dynamic_symbols_t* out_syms); | ||
|
||
// Deinitializes |syms| by unloading the backing library. All function pointers | ||
// will be invalidated. They _may_ still work if there are other reasons the | ||
// library remains loaded so be careful. | ||
void iree_hal_hip_dynamic_symbols_deinitialize( | ||
iree_hal_hip_dynamic_symbols_t* syms); | ||
|
||
#ifdef __cplusplus | ||
} // extern "C" | ||
#endif // __cplusplus | ||
|
||
#endif // IREE_EXPERIMENTAL_HIP_DYNAMIC_SYMBOLS_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Copyright 2023 The IREE Authors | ||
// | ||
// Licensed under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
#include "experimental/hip/dynamic_symbols.h" | ||
|
||
#include <iostream> | ||
|
||
#include "iree/base/api.h" | ||
#include "iree/testing/gtest.h" | ||
|
||
namespace iree { | ||
namespace hal { | ||
namespace hip { | ||
namespace { | ||
|
||
#define HIP_CHECK_ERRORS(expr) \ | ||
{ \ | ||
hipError_t status = expr; \ | ||
ASSERT_EQ(hipSuccess, status); \ | ||
} | ||
|
||
TEST(DynamicSymbolsTest, CreateFromSystemLoader) { | ||
iree_hal_hip_dynamic_symbols_t symbols; | ||
iree_status_t status = iree_hal_hip_dynamic_symbols_initialize( | ||
iree_allocator_system(), &symbols); | ||
if (!iree_status_is_ok(status)) { | ||
iree_status_fprint(stderr, status); | ||
iree_status_ignore(status); | ||
std::cerr << "Symbols cannot be loaded, skipping test."; | ||
GTEST_SKIP(); | ||
} | ||
|
||
int device_count = 0; | ||
HIP_CHECK_ERRORS(symbols.hipInit(0)); | ||
HIP_CHECK_ERRORS(symbols.hipGetDeviceCount(&device_count)); | ||
if (device_count > 0) { | ||
hipDevice_t device; | ||
HIP_CHECK_ERRORS(symbols.hipDeviceGet(&device, /*ordinal=*/0)); | ||
} | ||
|
||
iree_hal_hip_dynamic_symbols_deinitialize(&symbols); | ||
} | ||
|
||
} // namespace | ||
} // namespace hip | ||
} // namespace hal | ||
} // namespace iree |
Oops, something went wrong.