// Copyright 2026 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

// CTS backend registration for the HIP HAL driver.

#include "iree/hal/api.h"
#include "iree/hal/cts/util/registry.h"
#include "iree/hal/drivers/hip/registration/driver_module.h"

namespace iree::hal::cts {

static iree_status_t CreateHipDevice(
    const iree_hal_device_create_params_t* create_params,
    iree_hal_driver_t** out_driver, iree_hal_device_t** out_device) {
  iree_status_t status =
      iree_hal_hip_driver_module_register(iree_hal_driver_registry_default());
  if (iree_status_is_already_exists(status)) {
    iree_status_ignore(status);
    status = iree_ok_status();
  }

  iree_hal_driver_t* driver = nullptr;
  if (iree_status_is_ok(status)) {
    status = iree_hal_driver_registry_try_create(
        iree_hal_driver_registry_default(), iree_make_cstring_view("hip"),
        iree_allocator_system(), &driver);
  }

  iree_hal_device_t* device = nullptr;
  if (iree_status_is_ok(status)) {
    status = iree_hal_driver_create_default_device(
        driver, create_params, iree_allocator_system(), &device);
  }

  if (iree_status_is_ok(status)) {
    *out_driver = driver;
    *out_device = device;
  } else {
    iree_hal_device_release(device);
    iree_hal_driver_release(driver);
  }
  return status;
}

static bool hip_registered_ =
    (CtsRegistry::RegisterBackend({
         "hip",
         {"hip",
          CreateHipDevice,
          /*executable_format=*/nullptr,
          /*executable_data=*/nullptr,
          RecordingMode::kDirect,
          /*unsupported_tests=*/
          {
              {"QueueAllocaTest.AllocaWithWaitSemaphores",
               "HIP queue_alloca waits synchronously for host-visible buffers"},
              {"QueueAllocaTest.ExplicitPassthroughPoolAllocaDealloca",
               "iree_hal_hip_device_queue_alloca rejects any non-NULL pool "
               "argument with UNIMPLEMENTED; the existing path routes only "
               "through iree_hal_hip_device_prepare_async_alloc against the "
               "device's HIP memory pool. Caller-supplied pools require a "
               "transient-buffer wrapper that bridges "
               "pool_acquire_reservation/release_reservation through the "
               "async-alloc path."},
              {"QueueAllocaTest.ExplicitTLSFPoolTransferAllocaDealloca",
               "Blocked by the same iree_hal_hip_device_queue_alloca "
               "non-NULL pool rejection as "
               "ExplicitPassthroughPoolAllocaDealloca."},
              {"QueueAllocaTest.ExplicitFixedBlockPoolCrossQueueWaitFrontier",
               "Blocked by the same iree_hal_hip_device_queue_alloca "
               "non-NULL pool rejection as "
               "ExplicitPassthroughPoolAllocaDealloca."},
              {"QueueAllocaTest."
               "ExplicitFixedBlockPoolPendingDeallocaWaitFrontier",
               "Blocked by the same iree_hal_hip_device_queue_alloca "
               "non-NULL pool rejection as "
               "ExplicitPassthroughPoolAllocaDealloca."},
              {"QueueAllocaTest.ExplicitFixedBlockPoolRequiresWaitFrontierFlag",
               "Blocked by the same iree_hal_hip_device_queue_alloca "
               "non-NULL pool rejection as "
               "ExplicitPassthroughPoolAllocaDealloca."},
              {"QueueAllocaTest.ExplicitTLSFPoolCrossQueueWaitFrontier",
               "Blocked by the same iree_hal_hip_device_queue_alloca "
               "non-NULL pool rejection as "
               "ExplicitPassthroughPoolAllocaDealloca."},
              {"QueueAllocaTest.ExplicitTLSFPoolCrossQueueStaleBlockGrows",
               "Blocked by the same iree_hal_hip_device_query_queue_pool_"
               "backend UNIMPLEMENTED path as "
               "ExplicitTLSFPoolCrossQueueWaitFrontier."},
              {"QueueAllocaTest.ExplicitFixedBlockPoolNotificationRetry",
               "Blocked by the same iree_hal_hip_device_queue_alloca "
               "non-NULL pool rejection as "
               "ExplicitPassthroughPoolAllocaDealloca."},
              {"SemaphoreSubmissionTest.CrossQueueWaitBeforeSignal",
               "HIP does not implement iree_hal_device_query_queue_pool_"
               "backend, so CTS cannot prove that explicit cross-queue "
               "wait-before-signal dependencies are mapped onto distinct HIP "
               "queue domains."},
              {"SemaphoreSubmissionTest."
               "MultiQueueFanOutDifferentValuesBeforeSignal",
               "Blocked by the same HIP queue pool backend UNIMPLEMENTED "
               "path as CrossQueueWaitBeforeSignal."},
              {"EventTest.*", "HIP does not implement HAL events"},
              {"ExecutableTest.*",
               "HIP does not implement executable reflection"},
              {"QueueDispatchIndirectParametersTest.*",
               "HIP queue_dispatch is implemented via one-shot command "
               "buffer emulation, and HIP stream/graph command buffers "
               "require host-provided launch dimensions rather than "
               "device-resident indirect workgroup counts."},
              {"BufferMappingTest.*",
               "HIP graph command buffers lack memcpy node support"},
              {"CommandBufferCopyBufferTest.*",
               "HIP graph command buffers lack memcpy node support"},
              {"CommandBufferFillBufferTest.*",
               "HIP graph command buffers lack fill node support"},
              {"CommandBufferUpdateBufferTest.*",
               "HIP graph command buffers lack memcpy node support"},
              {"DispatchTest.*",
               "HIP CTS dispatch tests crash on GPU memory reservation "
               "failures"},
              {"DispatchMultiEntrypointTest.*",
               "HIP CTS dispatch tests crash on GPU memory reservation "
               "failures"},
              {"DispatchMultiWorkgroupTest.*",
               "HIP CTS dispatch tests crash on GPU memory reservation "
               "failures"},
              {"DispatchConstantsTest.*",
               "HIP graph command buffers lack fill node support"},
              {"DispatchConstantsBindingsTest.*",
               "HIP CTS dispatch tests crash on GPU memory reservation "
               "failures"},
              {"DispatchIndirectParametersTest.*",
               "HIP stream/graph command buffers explicitly reject indirect "
               "workgroup count parameters; supporting them requires a "
               "device-side launch or packet-patching mechanism."},
          },
          /*expected_failures=*/
          {
              {"TransientBufferTest.FillTransientBuffer",
               "HIP stream command buffers can hang when filling a transient "
               "buffer after stream-ordered queue_alloca; this requires a HIP "
               "transient-buffer sequencing fix."},
              {"TransientBufferTest.FillTransientBufferSubrange",
               "HIP stream command buffers can hang when a transient buffer "
               "subspan is filled after stream-ordered queue_alloca; this "
               "requires a HIP transient-buffer sequencing fix."},
              {"TransientBufferTest.FillTransientBuffer1Byte",
               "HIP graph command buffers can hang on gfx950 when a transient "
               "buffer is filled with a 1-byte pattern after stream-ordered "
               "queue_alloca; gfx1100 passes locally, so this requires a HIP "
               "transient-buffer sequencing fix across targets."},
              {"TransientBufferTest.FillTransientWithZeroAccessFlags",
               "HIP stream command buffers can hang on gfx950 when filling a "
               "transient buffer allocated with HAL-module access=0; gfx1100 "
               "passes locally, so this requires a HIP transient-buffer "
               "access/sequence fix across targets."},
              {"CommandBufferStressTest.RapidFillSubmit",
               "HIP command-buffer stress CTS can hit ROCm memory reservation "
               "failures on RDNA runners and then fail validation with an "
               "empty binding table."},
              {"CommandBufferStressTest.RapidCopySubmit",
               "Blocked by the same HIP command-buffer stress memory "
               "reservation path as RapidFillSubmit."},
              {"QueueAllocaTest.AllocaDeallocaCycle",
               "HIP async queue_dealloca does not yet reliably advance "
               "stream-ordered dealloca dependencies for transient buffers."},
              {"QueueAllocaTest.BufferMetadata",
               "The metadata assertions are valid after queue-affinity "
               "normalization, but the test still performs queue_dealloca "
               "cleanup and hits the same HIP async dealloca gap as "
               "AllocaDeallocaCycle."},
              {"QueueAllocaTest.DeallocaReleasesMemory",
               "HIP async queue_dealloca does not yet report the "
               "failed-precondition post-use behavior required for "
               "decommitted transient buffers."},
              {"QueueAllocaTest.FailedDeallocaWaitDoesNotDealloca",
               "HIP queue_dealloca does not yet propagate failed wait "
               "dependencies before preserving the transient allocation."},
              {"QueueAllocaTest.ChainedAllocaDealloca",
               "HIP async queue_dealloca does not yet reliably advance "
               "when chained directly behind queue_alloca."},
              {"QueueAllocaTest.DefaultPoolRepeatedChainedAllocaDealloca",
               "Blocked by the same HIP queue_alloca -> queue_dealloca "
               "dependency issue as ChainedAllocaDealloca."},
              {"QueueAllocaTest.DeallocaPrefersOriginPlacement",
               "HIP queue_dealloca origin routing still depends on the same "
               "async dealloca sequencing path as ChainedAllocaDealloca."},
              {"QueueAllocaTest.ZeroAccessFlagsCanonicalized",
               "HIP graph queues can hang on RDNA4 when queue_alloca "
               "canonicalizes access=0 before transient-buffer use."},
              {"QueueTransferTest.*",
               "HIP direct queue transfer CTS can hit ROCm memory reservation "
               "failures on RDNA runners and then fail validation with an "
               "empty binding table."},
              {"SemaphoreSubmissionTest."
               "IndirectCommandBufferBindingTableRetainedUntilSignal",
               "HIP graph queues can hit ROCm memory reservation failures "
               "while retaining indirect command-buffer binding tables."},
              {"DispatchPipelineTest.*",
               "HIP dispatch pipeline CTS can hit ROCm memory reservation "
               "failures on RDNA runners or hang on transient dispatch input "
               "sequencing."},
              {"DispatchReuseTest.*",
               "HIP dispatch reuse CTS can hit ROCm memory reservation "
               "failures and invalid binding tables on RDNA runners."},
          }},
         {"async_queue"},
     }),
     true);

}  // namespace iree::hal::cts
