Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/workflows/ci_core_linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ jobs:
run_tests: true
ctest_exclude_regex: ""
package: true
- variant: AMDXDNA Host
sanitizer: none
assertions: false
run_tests: true
ctest_exclude_regex: ""
cmake_options: |
-DIREE_HAL_DRIVER_AMDGPU=OFF
-DIREE_HAL_DRIVER_AMDXDNA=ON
-DLIBHRX_BUILD_PASSTHROUGH=OFF
-DIREE_HAL_AMDGPU_TARGETS=
package: false
- variant: ASAN
sanitizer: asan
assertions: true
Expand Down Expand Up @@ -91,6 +102,7 @@ jobs:
ctest_label_exclude_regex: "runtime-resource=|manual"
cmake_options: |
-DIREE_HAL_AMDGPU_TARGETS=gfx942;gfx1151;gfx1201
${{ matrix.cmake_options }}
package: ${{ matrix.package }}

gpu_linux:
Expand Down
16 changes: 13 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,21 @@ option(IREE_ENABLE_ASSERTIONS "Force unset of NDEBUG compile option." OFF)
option(IREE_DEV_MODE
"Configure settings optimized for IREE development instead of CI/release."
OFF)
option(IREE_HAL_DRIVER_AMDXDNA
"Enables the amdxdna runtime HAL driver."
OFF)
option(LIBHRX_BUILD
"Build libhrx and HRX compatibility targets." ON)
if(LIBHRX_BUILD)
if(DEFINED IREE_HAL_DRIVER_AMDGPU AND NOT IREE_HAL_DRIVER_AMDGPU)
if(NOT DEFINED IREE_HAL_DRIVER_AMDGPU)
if(NOT IREE_HAL_DRIVER_AMDXDNA)
set(IREE_HAL_DRIVER_AMDGPU_DEFAULT ON)
endif()
elseif(NOT IREE_HAL_DRIVER_AMDGPU AND NOT IREE_HAL_DRIVER_AMDXDNA)
message(FATAL_ERROR
"LIBHRX_BUILD=ON requires IREE_HAL_DRIVER_AMDGPU=ON.")
"LIBHRX_BUILD=ON requires at least one accelerator driver "
"(IREE_HAL_DRIVER_AMDGPU=ON or IREE_HAL_DRIVER_AMDXDNA=ON).")
endif()
set(IREE_HAL_DRIVER_AMDGPU_DEFAULT ON)
endif()

set(IREE_USE_LINKER "" CACHE STRING "")
Expand Down Expand Up @@ -187,6 +194,9 @@ endif()
if(IREE_HAL_DRIVER_HIP)
message(STATUS " - hip")
endif()
if(IREE_HAL_DRIVER_AMDXDNA)
message(STATUS " - amdxdna")
endif()
if(IREE_HAL_DRIVER_LOCAL_SYNC)
message(STATUS " - local-sync")
endif()
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,13 @@ ctest --test-dir build/hrx-tests/share/hrx-system/tests \
--output-on-failure -L runtime-resource=amd-gpu
```

NPU runners use the AMD NPU resource label:

```bash
ctest --test-dir build/hrx-tests/share/hrx-system/tests \
--output-on-failure -L runtime-resource=amd-npu
```

## Release Artifacts

Tagged releases publish one tarball per artifact, plus manifests and environment
Expand Down
3 changes: 3 additions & 0 deletions libhrx/.bazel_to_cmake.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ def hrx_cts_test(self, name, deps=[], **kwargs):
includes = kwargs.get("includes")
tags = kwargs.get("tags")
args = kwargs.get("args")
target_compatible_with = kwargs.get("target_compatible_with")
full_deps = (
[
":core",
Expand Down Expand Up @@ -146,6 +147,7 @@ def hrx_cts_test(self, name, deps=[], **kwargs):
if platform_deps_block:
self._converter.body += platform_deps_block
labels_block = self._convert_string_list_block("LABELS", tags)
self._emit_platform_guard_begin(target_compatible_with)
self._converter.body += (
f"hrx_cc_test(\n"
f"{name_block}"
Expand All @@ -160,6 +162,7 @@ def hrx_cts_test(self, name, deps=[], **kwargs):
f"{labels_block}"
f")\n\n"
)
self._emit_platform_guard_end(target_compatible_with)


def convert_unmatched_target(converter, target):
Expand Down
21 changes: 21 additions & 0 deletions libhrx/include/hrx_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,27 @@ HRX_API hrx_status_t hrx_buffer_map(hrx_buffer_t buffer, hrx_map_flags_t flags,

HRX_API hrx_status_t hrx_buffer_unmap(hrx_buffer_t buffer);

// Maps the whole buffer persistently (map once, keep the pointer for the
// buffer's lifetime). The returned pointer stays valid until the buffer is
// released; callers must use hrx_buffer_flush_range /
// hrx_buffer_invalidate_range to maintain host<->device cache coherence around
// device work instead of re-mapping. The buffer must be allocated with
// HRX_BUFFER_USAGE_MAPPING_PERSISTENT.
HRX_API hrx_status_t hrx_buffer_map_persistent(hrx_buffer_t buffer,
hrx_map_flags_t flags,
void** mapped_ptr);

// Flushes host writes in [offset, offset+size) out to the device (host->device
// cache management). Cheap (no copy); the buffer must be currently mapped.
HRX_API hrx_status_t hrx_buffer_flush_range(hrx_buffer_t buffer, size_t offset,
size_t size);

// Invalidates the host cache for [offset, offset+size) so subsequent host reads
// observe device writes (device->host cache management). Cheap (no copy); the
// buffer must be currently mapped.
HRX_API hrx_status_t hrx_buffer_invalidate_range(hrx_buffer_t buffer,
size_t offset, size_t size);

HRX_API hrx_status_t hrx_buffer_get_device_ptr(hrx_buffer_t buffer,
void** device_ptr);

Expand Down
10 changes: 10 additions & 0 deletions libhrx/src/libhrx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ if(IREE_HAL_DRIVER_AMDGPU)
HRX_HAS_IREE_AMDGPU_DRIVER
)
endif()
if(IREE_HAL_DRIVER_AMDXDNA)
target_link_libraries(libhrx_src_libhrx_hrx PRIVATE
iree::hal::drivers::amdxdna::registration
iree::hal::drivers::amdxdna
iree::base::tooling::flags
)
target_compile_definitions(libhrx_src_libhrx_hrx.objects PRIVATE
HRX_HAS_IREE_AMDXDNA_DRIVER
)
endif()
# IREE's allocator selector is exposed as a compile definition on the base
# library target. libhrx is compiled through IREE's object-library wrapper, so
# forward that definition to the object target that actually compiles the
Expand Down
59 changes: 59 additions & 0 deletions libhrx/src/libhrx/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,65 @@ hrx_status_t hrx_buffer_unmap(hrx_buffer_t buffer) {
HRX_RETURN_AND_END_ZONE(z0, hrx_status_from_iree(status));
}

hrx_status_t hrx_buffer_map_persistent(hrx_buffer_t buffer,
hrx_map_flags_t flags,
void** mapped_ptr) {
HRX_TRACE_ZONE_BEGIN(z0, "hrx_buffer_map_persistent");
if (!buffer || !mapped_ptr) {
HRX_RETURN_AND_END_ZONE(z0,
hrx_make_status(HRX_STATUS_INVALID_ARGUMENT,
"buffer or mapped_ptr is NULL"));
}
if (buffer->is_mapped) {
// Already mapped (persistent): hand back the existing pointer.
*mapped_ptr = buffer->mapped_ptr;
HRX_RETURN_AND_END_ZONE(z0, hrx_ok_status());
}

iree_hal_memory_access_t access = 0;
if (flags & HRX_MAP_READ) access |= IREE_HAL_MEMORY_ACCESS_READ;
if (flags & HRX_MAP_WRITE) access |= IREE_HAL_MEMORY_ACCESS_WRITE;
if (!access) access = IREE_HAL_MEMORY_ACCESS_ALL;

iree_status_t status = iree_hal_buffer_map_range(
buffer->hal_buffer, IREE_HAL_MAPPING_MODE_PERSISTENT, access,
/*byte_offset=*/0, (iree_device_size_t)buffer->size, &buffer->mapping);
if (!iree_status_is_ok(status)) {
HRX_RETURN_AND_END_ZONE(z0, hrx_status_from_iree(status));
}

buffer->is_mapped = true;
buffer->mapped_ptr = buffer->mapping.contents.data;
*mapped_ptr = buffer->mapped_ptr;
HRX_RETURN_AND_END_ZONE(z0, hrx_ok_status());
}

hrx_status_t hrx_buffer_flush_range(hrx_buffer_t buffer, size_t offset,
size_t size) {
if (!buffer) {
return hrx_make_status(HRX_STATUS_INVALID_ARGUMENT, "buffer is NULL");
}
if (!buffer->is_mapped) {
return hrx_make_status(HRX_STATUS_FAILED_PRECONDITION,
"buffer is not mapped");
}
return hrx_status_from_iree(iree_hal_buffer_mapping_flush_range(
&buffer->mapping, (iree_device_size_t)offset, (iree_device_size_t)size));
}

hrx_status_t hrx_buffer_invalidate_range(hrx_buffer_t buffer, size_t offset,
size_t size) {
if (!buffer) {
return hrx_make_status(HRX_STATUS_INVALID_ARGUMENT, "buffer is NULL");
}
if (!buffer->is_mapped) {
return hrx_make_status(HRX_STATUS_FAILED_PRECONDITION,
"buffer is not mapped");
}
return hrx_status_from_iree(iree_hal_buffer_mapping_invalidate_range(
&buffer->mapping, (iree_device_size_t)offset, (iree_device_size_t)size));
}

hrx_status_t hrx_buffer_get_device_ptr(hrx_buffer_t buffer, void** device_ptr) {
HRX_TRACE_ZONE_BEGIN(z0, "hrx_buffer_get_device_ptr");
if (buffer) {
Expand Down
Loading