Skip to content
Merged
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
18 changes: 16 additions & 2 deletions ggml/src/ggml-hrx/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
set(HRX_SOURCE_DIR "" CACHE PATH "Optional HRX source tree to build instead of using installed hrx and loomc packages")
find_package(Python3 REQUIRED COMPONENTS Interpreter)

if(HRX_SOURCE_DIR)
include(ExternalProject)
Expand All @@ -9,6 +10,21 @@ if(HRX_SOURCE_DIR)
message(FATAL_ERROR "HRX_SOURCE_DIR does not contain a CMakeLists.txt: ${HRX_SOURCE_DIR}")
endif()

# Enforce the HRX compatibility floor before building dependencies; rerun configure when the pin or checker changes.
set(GGML_HRX_REVISION_CHECK "${CMAKE_CURRENT_SOURCE_DIR}/tools/check_hrx_revision.py")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/hrx-minimum-commit.txt" "${GGML_HRX_REVISION_CHECK}")
execute_process(
COMMAND "${Python3_EXECUTABLE}" "${GGML_HRX_REVISION_CHECK}" "${HRX_SOURCE_DIR}"
RESULT_VARIABLE GGML_HRX_REVISION_RESULT
OUTPUT_VARIABLE GGML_HRX_REVISION_OUTPUT
ERROR_VARIABLE GGML_HRX_REVISION_ERROR
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT GGML_HRX_REVISION_RESULT EQUAL 0)
message(FATAL_ERROR "${GGML_HRX_REVISION_ERROR}")
endif()
message(STATUS "${GGML_HRX_REVISION_OUTPUT}")

set(GGML_HRX_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/hrx")
set(GGML_HRX_BUILD_DIR "${GGML_HRX_PREFIX}/src/ggml-hrx-deps-build")
set(GGML_HRX_LIB "${GGML_HRX_BUILD_DIR}/libhrx/src/libhrx/${CMAKE_SHARED_LIBRARY_PREFIX}hrx${CMAKE_SHARED_LIBRARY_SUFFIX}")
Expand Down Expand Up @@ -69,8 +85,6 @@ else()
find_program(GGML_HRX_IREE_BENCHMARK_LOOM NAMES iree-benchmark-loom)
endif()

find_package(Python3 REQUIRED COMPONENTS Interpreter)

set(GGML_HRX_KERNEL_CORPUS_SOURCE_FORMAT "binary" CACHE STRING "Embedded Loom corpus source format: text or binary")
set_property(CACHE GGML_HRX_KERNEL_CORPUS_SOURCE_FORMAT PROPERTY STRINGS text binary)
if(GGML_HRX_KERNEL_CORPUS_SOURCE_FORMAT STREQUAL "binary")
Expand Down
17 changes: 17 additions & 0 deletions ggml/src/ggml-hrx/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# HRX Backend

## `hrx-system` backend compatibility

`hrx-minimum-commit.txt` records the minimum required commit in ROCm/hrx-system. It contains one full Git commit SHA. The backend's C++ APIs, Loom syntax, and numerical behavior can all depend on that revision. When `GGML_HRX=ON` and `HRX_SOURCE_DIR` is set, CMake requires the HRX checkout's HEAD to equal or descend from the recorded commit.

For builds using installed packages, check the source revision used to produce both HRX and Loom against this floor before validating a repair. From the staging checkout:

```sh
python3 llama.cpp/ggml/src/ggml-hrx/tools/check_hrx_revision.py hrx-system
```

### Updating the minimum

Raise the minimum in the same llama.cpp commit that introduces a newer HRX dependency. This includes new API calls, new Loom syntax, and removing a numerical workaround after an HRX compiler or runtime fix. Unrelated repairs do not require a bump.

Choose the earliest demonstrated required commit that retains the previous floor in its ancestry. Do not replace the floor with the latest tested revision merely because it is available. Record the dependency and its HRX commit or PR in the change's validation evidence. A minimum is not a promise that every future HRX revision is compatible.
1 change: 1 addition & 0 deletions ggml/src/ggml-hrx/hrx-minimum-commit.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
40b7cc13717d9d4c7f7eb0e6885563042153566b
54 changes: 54 additions & 0 deletions ggml/src/ggml-hrx/tools/check_hrx_revision.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env python3
"""Check an HRX checkout against the backend's recorded minimum commit.

CMake and callers using installed packages share this local ancestry check.
Success prints the accepted revision; failure prints context and exits nonzero.
No history is fetched and no source files are changed.
"""

import argparse
from pathlib import Path
import subprocess
import sys


def check_revision(source: Path) -> int:
minimum = (Path(__file__).resolve().parents[1] / "hrx-minimum-commit.txt").read_text(encoding="utf-8").strip()
head = "unknown"

def git(*args: str) -> str:
return subprocess.run(
["git", "-C", str(source), *args], check=True, text=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
).stdout.strip()

try:
head = git("rev-parse", "--verify", "HEAD^{commit}")
git("cat-file", "-e", f"{minimum}^{{commit}}")
git("merge-base", "--is-ancestor", minimum, head)
except (OSError, subprocess.CalledProcessError) as error:
if isinstance(error, subprocess.CalledProcessError):
reason = error.stderr.strip() or "HRX HEAD does not have the required commit in its available ancestry."
else:
reason = str(error)
print(
f"{reason}\nHRX_SOURCE_DIR: {source}\nRequired HRX commit: {minimum}\nActual HRX HEAD: {head}\n"
"Use an HRX Git checkout at the required commit or a descendant. Ensure Git is installed, "
"fetch missing history manually (unshallow a shallow clone if needed), then rerun the check.",
file=sys.stderr,
)
return 1

print(f"HRX revision {head} satisfies minimum {minimum}")
return 0


def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("source", type=Path, help="HRX source checkout")
args = parser.parse_args()
return check_revision(args.source.resolve())


if __name__ == "__main__":
sys.exit(main())
Loading