Skip to content

ENHANCEMENT: Hostcall on Windows without HSA Runtime #1089

Description

@ehgus

AMDGPU.jl Hostcall allows GPU device kernels to invoke host-side Julia callbacks.
Current hostcall implementation depends directly on HSA runtime, which is not supported by Windows.
This invoke any kernel that triggers hostcalls fails on Windows.

Proposed Solution

Hostcall can be implemented by adhering on AMDGPU Compute ABI Signal Specification
and hip SDK.
HSA-lib-dependent CAS and memcpy operations will be replaced with Julia-native ones.

Here is the example:

function create_hostcall_signal(init_val::Int64 = 1)
    @static if Sys.iswindows()
        # Reference (AMDGPU Compute ABI - Signal Object):
        # https://github.com/RadeonOpenCompute/ROCm-ComputeABI-Doc/blob/master/AMDGPU-ABI.md#signal-object#signals
        # Layout of `amd_signal_t` (64 bytes total, 64-byte aligned):
        #   - Offset 0..7  (int64_t): `kind` = AMD_SIGNAL_KIND_USER (1)
        #   - Offset 8..15 (int64_t): `value` = init_val (signal payload / counter)
        ptr_ref = Ref{Ptr{Cvoid}}()
        HIP.hipHostMalloc(ptr_ref, 64, HIP.hipHostMallocCoherent)
        # Zero out all 64 bytes
        unsafe_wrap(Array, reinterpret(Ptr{UInt8}, ptr_ref[]), 64) .= 0
        p64 = reinterpret(Ptr{Int64}, ptr_ref[])
        # Offset 0..7: kind = AMD_SIGNAL_KIND_USER (1) (element 1 in Int64 indexing)
        unsafe_store!(p64, Int64(1), 1)
        # Offset 8..15: value = init_val (element 2 in Int64 indexing)
        unsafe_store!(p64, init_val, 2)
        return HSA.Signal(reinterpret(UInt64, ptr_ref[]))
    else
        # existing implementation
        signal_ref = Ref{HSA.Signal}()
        HSA.signal_create(init_val, 0, C_NULL, signal_ref) |> Runtime.check
        return signal_ref[]
    end
end

@inline function host_signal_cmpxchg!(signal::HSA.Signal, expected, value)
    @static if Sys.iswindows()
        # In AMDGPU ABI, amd_signal_t.value is at offset 8 (after 8-byte kind)
        ptr = reinterpret(Ptr{Int64}, signal.handle + 8)
        return first(Core.Intrinsics.atomic_pointerreplace(
            ptr, Int64(expected), Int64(value), :acquire_release, :acquire))
    else
        HSA.signal_cas_scacq_screl(signal, expected, value)
    end
end

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions