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
7 changes: 4 additions & 3 deletions src/xtc/runtimes/host/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
# Copyright (c) 2024-2026 The XTC Project Authors
#
import ctypes
import ctypes.util
import tempfile
import subprocess
import threading
Expand All @@ -14,7 +13,7 @@
from typing import Any
from enum import Enum

from xtc.utils.tools import get_mlir_prefix, get_cuda_prefix
from xtc.utils.tools import get_mlir_prefix, get_cuda_prefix, check_compile

__all__ = ["runtime_funcs", "resolve_runtime", "RuntimeType"]

Expand Down Expand Up @@ -147,7 +146,9 @@ def from_param(obj: str | bytes):


def _compile_runtime(out_dll: str, tdir: str, runtime_type: RuntimeType):
has_pfm = ctypes.util.find_library("pfm") is not None
has_pfm = check_compile(
"#include <perfmon/pfmlib.h>\nint main() { return 0; }\n", libs="pfm"
)
pfm_opts = "-DHAS_PFM=1" if has_pfm else ""
pfm_libs = "-lpfm" if has_pfm else ""
has_gpu = runtime_type == RuntimeType.GPU
Expand Down
27 changes: 27 additions & 0 deletions src/xtc/utils/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import os
import shutil
from pathlib import Path
import subprocess
import tempfile


def get_mlir_prefix(prefix: Path | str | None = None):
Expand Down Expand Up @@ -102,3 +104,28 @@ def get_cuda_prefix(prefix: Path | str | None = None):
if not prefix.exists():
raise RuntimeError(f"could not find CUDA installation dir at: {prefix}")
return prefix


def check_compile(code: str, libs: str | list[str] | None = None):
"""
Attempt to compile (and link) a small C program.
"""
compiler = shutil.which("cc") or shutil.which("gcc")
if compiler is None:
return False

if isinstance(libs, str):
libs = [libs]
libs = libs or []

with tempfile.TemporaryDirectory() as tmpdir:
src_path = os.path.join(tmpdir, "test.c")
exe_path = os.path.join(tmpdir, "test")

with open(src_path, "w") as f:
f.write(code)

cmd = [compiler, src_path, "-o", exe_path] + [f"-l{lib}" for lib in libs]

result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return result.returncode == 0