Skip to content

Commit

Permalink
Adding a null HAL driver. (#18675)
Browse files Browse the repository at this point in the history
This is a dummy that can be used as a template and documentation for new
HAL drivers and a change detector for HAL APIs. It's also useful as a
way to get the minimum size of a HAL driver with default emulation.
  • Loading branch information
benvanik authored Oct 3, 2024
1 parent 0bbc432 commit a6043e2
Show file tree
Hide file tree
Showing 32 changed files with 2,832 additions and 40 deletions.
67 changes: 40 additions & 27 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -257,26 +257,36 @@ set(IREE_HAL_DRIVER_CUDA_DEFAULT OFF)
# required to actually run HIP workloads.
set(IREE_HAL_DRIVER_HIP_DEFAULT OFF)

# Vulkan support is enabled by default if the platform might support Vulkan.
# Apple platforms support Metal instead of Vulkan, though MoltenVK may work.
set(IREE_HAL_DRIVER_VULKAN_DEFAULT ${IREE_HAL_DRIVER_DEFAULTS})
if(APPLE)
set(IREE_HAL_DRIVER_VULKAN_DEFAULT OFF)
endif()

# Metal support is enabled if it's one of the Apple platforms.
set(IREE_HAL_DRIVER_METAL_DEFAULT ${IREE_HAL_DRIVER_DEFAULTS})
# Right now only support Apple silicon devices.
if(NOT APPLE OR NOT ${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm64")
set(IREE_HAL_DRIVER_METAL_DEFAULT OFF)
endif()

# Null skeleton driver is only enabled in debug builds or dev mode.
# We don't want to ship release builds with it or count it when calculating
# binary sizes of minified builds.
set(IREE_HAL_DRIVER_NULL_DEFAULT OFF)
string(TOUPPER "${CMAKE_BUILD_TYPE}" _UPPERCASE_CMAKE_BUILD_TYPE)
if (IREE_DEV_MODE OR (_UPPERCASE_CMAKE_BUILD_TYPE STREQUAL "DEBUG"))
set(IREE_HAL_DRIVER_NULL_DEFAULT ON)
endif()

# Vulkan support is enabled by default if the platform might support Vulkan.
# Apple platforms support Metal instead of Vulkan, though MoltenVK may work.
set(IREE_HAL_DRIVER_VULKAN_DEFAULT ${IREE_HAL_DRIVER_DEFAULTS})
if(APPLE)
set(IREE_HAL_DRIVER_VULKAN_DEFAULT OFF)
endif()

option(IREE_HAL_DRIVER_CUDA "Enables the 'cuda' runtime HAL driver" ${IREE_HAL_DRIVER_CUDA_DEFAULT})
option(IREE_HAL_DRIVER_HIP "Enables the 'hip' runtime HAL driver" ${IREE_HAL_DRIVER_HIP_DEFAULT})
option(IREE_HAL_DRIVER_LOCAL_SYNC "Enables the 'local-sync' runtime HAL driver" ${IREE_HAL_DRIVER_DEFAULTS})
option(IREE_HAL_DRIVER_LOCAL_TASK "Enables the 'local-task' runtime HAL driver" ${IREE_HAL_DRIVER_DEFAULTS})
option(IREE_HAL_DRIVER_VULKAN "Enables the 'vulkan' runtime HAL driver" ${IREE_HAL_DRIVER_VULKAN_DEFAULT})
option(IREE_HAL_DRIVER_METAL "Enables the 'metal' runtime HAL driver" ${IREE_HAL_DRIVER_METAL_DEFAULT})
option(IREE_HAL_DRIVER_NULL "Enables the 'null' runtime HAL driver" ${IREE_HAL_DRIVER_NULL_DEFAULT})
option(IREE_HAL_DRIVER_VULKAN "Enables the 'vulkan' runtime HAL driver" ${IREE_HAL_DRIVER_VULKAN_DEFAULT})

option(IREE_HAL_EXECUTABLE_LOADER_DEFAULTS "Sets the default value for all runtime HAL executable loaders" ON)
set(IREE_HAL_EXECUTABLE_LOADER_EMBEDDED_ELF_DEFAULT ${IREE_HAL_EXECUTABLE_LOADER_DEFAULTS})
Expand Down Expand Up @@ -332,12 +342,15 @@ endif()
if(IREE_HAL_DRIVER_LOCAL_TASK)
message(STATUS " - local-task")
endif()
if(IREE_HAL_DRIVER_VULKAN)
message(STATUS " - vulkan")
endif()
if(IREE_HAL_DRIVER_METAL)
message(STATUS " - metal")
endif()
if(IREE_HAL_DRIVER_NULL)
message(STATUS " - null")
endif()
if(IREE_HAL_DRIVER_VULKAN)
message(STATUS " - vulkan")
endif()
if(IREE_EXTERNAL_HAL_DRIVERS)
message(STATUS " + external: ${IREE_EXTERNAL_HAL_DRIVERS}")
endif()
Expand Down Expand Up @@ -501,22 +514,22 @@ option(IREE_ENABLE_ASSERTIONS "Force unset of NDEBUG compile option" OFF)
function(iree_fix_ndebug)
string(TOUPPER "${CMAKE_BUILD_TYPE}" _UPPERCASE_CMAKE_BUILD_TYPE)
if(IREE_ENABLE_ASSERTIONS AND NOT "${_UPPERCASE_CMAKE_BUILD_TYPE}" STREQUAL "DEBUG")
# Also remove /D NDEBUG to avoid MSVC warnings about conflicting defines.
foreach(_FLAGS_VAR_TO_SCRUB
CMAKE_CXX_FLAGS_${_UPPERCASE_CMAKE_BUILD_TYPE}
CMAKE_C_FLAGS_${_UPPERCASE_CMAKE_BUILD_TYPE})
set(_ORIGINAL_FLAGS "${${_FLAGS_VAR_TO_SCRUB}}")
string(REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" " " _ALTERED_FLAGS "${_ORIGINAL_FLAGS}")
if(NOT "${_ORIGINAL_FLAGS}" STREQUAL "${_ALTERED_FLAGS}")
message(STATUS
"IREE_ENABLE_ASSERTIONS force disabled NDEBUG for ${_FLAGS_VAR_TO_SCRUB}: '${_ORIGINAL_FLAGS}' -> '${_ALTERED_FLAGS}'")
set(${_FLAGS_VAR_TO_SCRUB} "${_ALTERED_FLAGS}" PARENT_SCOPE)
endif()
endforeach()

# Make sure that LLVM doesn't add its own logic for assertion disabling.
# We'd like to make sure that we are not dueling over globals.
set(LLVM_ENABLE_ASSERTIONS OFF PARENT_SCOPE)
# Also remove /D NDEBUG to avoid MSVC warnings about conflicting defines.
foreach(_FLAGS_VAR_TO_SCRUB
CMAKE_CXX_FLAGS_${_UPPERCASE_CMAKE_BUILD_TYPE}
CMAKE_C_FLAGS_${_UPPERCASE_CMAKE_BUILD_TYPE})
set(_ORIGINAL_FLAGS "${${_FLAGS_VAR_TO_SCRUB}}")
string(REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" " " _ALTERED_FLAGS "${_ORIGINAL_FLAGS}")
if(NOT "${_ORIGINAL_FLAGS}" STREQUAL "${_ALTERED_FLAGS}")
message(STATUS
"IREE_ENABLE_ASSERTIONS force disabled NDEBUG for ${_FLAGS_VAR_TO_SCRUB}: '${_ORIGINAL_FLAGS}' -> '${_ALTERED_FLAGS}'")
set(${_FLAGS_VAR_TO_SCRUB} "${_ALTERED_FLAGS}" PARENT_SCOPE)
endif()
endforeach()

# Make sure that LLVM doesn't add its own logic for assertion disabling.
# We'd like to make sure that we are not dueling over globals.
set(LLVM_ENABLE_ASSERTIONS OFF PARENT_SCOPE)
endif()
endfunction()
iree_fix_ndebug()
Expand Down
6 changes: 6 additions & 0 deletions runtime/src/iree/hal/drivers/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ string_list_flag(
"cuda",
"local-sync",
"local-task",
"null",
"vulkan",
],
)

UNCONDITIONAL_DRIVERS = [
"local-sync",
"local-task",
"null",
"vulkan",
]

Expand Down Expand Up @@ -67,6 +69,10 @@ iree_runtime_cc_library(
":local-task_enabled": ["//runtime/src/iree/hal/drivers/local_task/registration"],
"//conditions:default": [],
}) +
select({
":null_enabled": ["//runtime/src/iree/hal/drivers/null/registration"],
"//conditions:default": [],
}) +
select({
":vulkan_enabled": ["//runtime/src/iree/hal/drivers/vulkan/registration"],
"//conditions:default": [],
Expand Down
12 changes: 8 additions & 4 deletions runtime/src/iree/hal/drivers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,18 @@ if(IREE_HAL_DRIVER_LOCAL_TASK)
add_subdirectory(local_task)
list(APPEND _INIT_INTERNAL_DEPS iree::hal::drivers::local_task::registration)
endif()
if(IREE_HAL_DRIVER_VULKAN)
add_subdirectory(vulkan)
list(APPEND _INIT_INTERNAL_DEPS iree::hal::drivers::vulkan::registration)
endif()
if(IREE_HAL_DRIVER_METAL)
add_subdirectory(metal)
list(APPEND _INIT_INTERNAL_DEPS iree::hal::drivers::metal::registration)
endif()
if(IREE_HAL_DRIVER_NULL)
add_subdirectory(null)
list(APPEND _INIT_INTERNAL_DEPS iree::hal::drivers::null::registration)
endif()
if(IREE_HAL_DRIVER_VULKAN)
add_subdirectory(vulkan)
list(APPEND _INIT_INTERNAL_DEPS iree::hal::drivers::vulkan::registration)
endif()

iree_cc_library(
NAME
Expand Down
27 changes: 18 additions & 9 deletions runtime/src/iree/hal/drivers/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,20 @@

#if defined(IREE_HAVE_HAL_LOCAL_TASK_DRIVER_MODULE)
#include "iree/hal/drivers/local_task/registration/driver_module.h"

#if defined(IREE_HAVE_HAL_METAL_DRIVER_MODULE)
#include "iree/hal/drivers/metal/registration/driver_module.h"
#endif // IREE_HAVE_HAL_METAL_DRIVER_MODULE
#endif // IREE_HAVE_HAL_LOCAL_TASK_DRIVER_MODULE

#if defined(IREE_HAVE_HAL_NULL_DRIVER_MODULE)
#include "iree/hal/drivers/null/registration/driver_module.h"
#endif // IREE_HAVE_HAL_NULL_DRIVER_MODULE

#if defined(IREE_HAVE_HAL_VULKAN_DRIVER_MODULE)
#include "iree/hal/drivers/vulkan/registration/driver_module.h"
#endif // IREE_HAVE_HAL_VULKAN_DRIVER_MODULE

#if defined(IREE_HAVE_HAL_METAL_DRIVER_MODULE)
#include "iree/hal/drivers/metal/registration/driver_module.h"
#endif // IREE_HAVE_HAL_METAL_DRIVER_MODULE

#if defined(IREE_HAVE_HAL_EXTERNAL_DRIVERS)
// Defined in the generated init_external.c file:
extern iree_status_t iree_hal_register_external_drivers(
Expand Down Expand Up @@ -65,16 +69,21 @@ iree_hal_register_all_available_drivers(iree_hal_driver_registry_t* registry) {
z0, iree_hal_local_task_driver_module_register(registry));
#endif // IREE_HAVE_HAL_LOCAL_TASK_DRIVER_MODULE

#if defined(IREE_HAVE_HAL_VULKAN_DRIVER_MODULE)
IREE_RETURN_AND_END_ZONE_IF_ERROR(
z0, iree_hal_vulkan_driver_module_register(registry));
#endif // IREE_HAVE_HAL_VULKAN_DRIVER_MODULE

#if defined(IREE_HAVE_HAL_METAL_DRIVER_MODULE)
IREE_RETURN_AND_END_ZONE_IF_ERROR(
z0, iree_hal_metal_driver_module_register(registry));
#endif // IREE_HAVE_HAL_METAL_DRIVER_MODULE

#if defined(IREE_HAVE_HAL_NULL_DRIVER_MODULE)
IREE_RETURN_AND_END_ZONE_IF_ERROR(
z0, iree_hal_null_driver_module_register(registry));
#endif // IREE_HAVE_HAL_NULL_DRIVER_MODULE

#if defined(IREE_HAVE_HAL_VULKAN_DRIVER_MODULE)
IREE_RETURN_AND_END_ZONE_IF_ERROR(
z0, iree_hal_vulkan_driver_module_register(registry));
#endif // IREE_HAVE_HAL_VULKAN_DRIVER_MODULE

IREE_RETURN_AND_END_ZONE_IF_ERROR(
z0, iree_hal_register_external_drivers(registry));

Expand Down
50 changes: 50 additions & 0 deletions runtime/src/iree/hal/drivers/null/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Copyright 2024 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

load("//build_tools/bazel:build_defs.oss.bzl", "iree_runtime_cc_library")

package(
default_visibility = ["//visibility:public"],
features = ["layering_check"],
licenses = ["notice"], # Apache 2.0
)

iree_runtime_cc_library(
name = "null",
srcs = [
"allocator.c",
"allocator.h",
"buffer.c",
"buffer.h",
"channel.c",
"channel.h",
"command_buffer.c",
"command_buffer.h",
"device.c",
"device.h",
"driver.c",
"driver.h",
"event.c",
"event.h",
"executable.c",
"executable.h",
"executable_cache.c",
"executable_cache.h",
"semaphore.c",
"semaphore.h",
],
hdrs = [
"api.h",
],
deps = [
"//runtime/src/iree/base",
"//runtime/src/iree/base/internal",
"//runtime/src/iree/hal",
"//runtime/src/iree/hal/utils:file_transfer",
"//runtime/src/iree/hal/utils:memory_file",
"//runtime/src/iree/hal/utils:semaphore_base",
],
)
49 changes: 49 additions & 0 deletions runtime/src/iree/hal/drivers/null/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
################################################################################
# Autogenerated by build_tools/bazel_to_cmake/bazel_to_cmake.py from #
# runtime/src/iree/hal/drivers/null/BUILD.bazel #
# #
# Use iree_cmake_extra_content from iree/build_defs.oss.bzl to add arbitrary #
# CMake-only content. #
# #
# To disable autogeneration for this file entirely, delete this header. #
################################################################################

iree_add_all_subdirs()

iree_cc_library(
NAME
null
HDRS
"api.h"
SRCS
"allocator.c"
"allocator.h"
"buffer.c"
"buffer.h"
"channel.c"
"channel.h"
"command_buffer.c"
"command_buffer.h"
"device.c"
"device.h"
"driver.c"
"driver.h"
"event.c"
"event.h"
"executable.c"
"executable.h"
"executable_cache.c"
"executable_cache.h"
"semaphore.c"
"semaphore.h"
DEPS
iree::base
iree::base::internal
iree::hal
iree::hal::utils::file_transfer
iree::hal::utils::memory_file
iree::hal::utils::semaphore_base
PUBLIC
)

### BAZEL_TO_CMAKE_PRESERVES_ALL_CONTENT_BELOW_THIS_LINE ###
66 changes: 66 additions & 0 deletions runtime/src/iree/hal/drivers/null/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Null HAL Driver (`null`)

This is a skeleton HAL driver that implements most interfaces needed by a HAL
driver. It contains notes that can be useful to implementers, stubs for
easy copy/paste/renaming, and some default behavior in places that many
implementations can use (such as file queue operations). It doesn't run anything
and nearly all methods return `UNIMPLEMENTED` errors: this can be used to
incrementally build a driver by running until you hit an UNIMPLEMENTED,
implementing it, and running again. Note however that the HAL is fairly regular
and starting with the files and running down the methods is often much easier
to do than the trial-and-error approach: if you can implement command buffer
fill (memset) you can often implement copy (memcpy) as well at the same time.

## Instructions for Cloning

1. Duplicate the entire directory in your own repository or the IREE
`experimental/` folder if going in-tree.
1. Find/replace `{Null}` with the friendly name of your driver (e.g. `Vulkan`).
1. Find/replace `_null_` with the C name of your driver (e.g. `vulkan`).
1. Find/replace `// TODO(null):` with your github ID, your driver name, or a
GitHub issue number tracking driver creation (e.g. `// TODO(#1234):`).

## Build Setup

HAL drivers are setup by adding some specially named cmake variables and then
pointing the IREE build at them by name. Projects embedding IREE runtime builds
as a submodule can use the `iree_register_external_hal_driver` cmake function
to do this, set the variables on the command line during cmake configure, or
via top-level project `CMakeLists.txt` before adding the IREE subdirectory.

See [runtime/src/iree/hal/drivers/CMakeLists.txt](runtime/src/iree/hal/drivers/CMakeLists.txt) for more information.

Example using the helper function:
```cmake
iree_register_external_hal_driver(
NAME
webgpu
SOURCE_DIR
"${CMAKE_CURRENT_SOURCE_DIR}/experimental/webgpu"
BINARY_DIR
"${CMAKE_CURRENT_BINARY_DIR}/experimental/webgpu"
DRIVER_TARGET
iree::experimental::webgpu::registration
REGISTER_FN
iree_hal_webgpu_driver_module_register
)
set(IREE_EXTERNAL_HAL_DRIVERS my_driver)
```

Example using the command line:
```sh
cmake ... \
-DIREE_EXTERNAL_MY_DRIVER_HAL_DRIVER_TARGET=my_driver_static_library \
-DIREE_EXTERNAL_MY_DRIVER_HAL_DRIVER_REGISTER=my_driver_register \
-DIREE_EXTERNAL_HAL_DRIVERS=my_driver
```

## In-tree Drivers (`iree/hal/drivers/...`)

IREE is generally conservative about hosting in-tree HAL drivers unless authored
by the core team or an SLA is in-place and maintained. Any new HAL drivers
should expect to start in forks or external repositories and not be expected
to merge without deep involvement with the IREE maintainers. IREE is not a
monorepo and it's perfectly fine to be out-of-tree. If ergonomics issues are
encountered with being out of tree please file issues so that support can be
improved.
Loading

0 comments on commit a6043e2

Please sign in to comment.