// 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 CUDA HAL driver.

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

namespace iree::hal::cts {

static iree_status_t CreateCudaDevice(
    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_cuda_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("cuda"),
        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 cuda_registered_ =
    (CtsRegistry::RegisterBackend({
         "cuda",
         {"cuda",
          CreateCudaDevice,
          /*executable_format=*/nullptr,
          /*executable_data=*/nullptr,
          RecordingMode::kDirect,
          /*unsupported_tests=*/
          {
              {"QueueAllocaTest.AllocaWithWaitSemaphores",
               "CUDA queue_alloca waits synchronously on wait semaphores"},
              {"QueueAllocaTest.ExplicitPassthroughPoolAllocaDealloca",
               "iree_hal_cuda_device_queue_alloca rejects any non-NULL pool "
               "argument with UNIMPLEMENTED; the existing path routes only "
               "through iree_hal_cuda_memory_pools_alloca (stream-ordered "
               "cuMemAllocAsync) or the device allocator. Caller-supplied "
               "pools require a transient-buffer wrapper that bridges "
               "pool_acquire_reservation/release_reservation through the "
               "stream-ordered allocator path."},
              {"QueueAllocaTest.ExplicitTLSFPoolTransferAllocaDealloca",
               "Blocked by the same iree_hal_cuda_device_queue_alloca "
               "non-NULL pool rejection as "
               "ExplicitPassthroughPoolAllocaDealloca."},
              {"QueueAllocaTest.ExplicitFixedBlockPoolCrossQueueWaitFrontier",
               "Blocked by the same iree_hal_cuda_device_queue_alloca "
               "non-NULL pool rejection as "
               "ExplicitPassthroughPoolAllocaDealloca."},
              {"QueueAllocaTest."
               "ExplicitFixedBlockPoolPendingDeallocaWaitFrontier",
               "Blocked by the same iree_hal_cuda_device_queue_alloca "
               "non-NULL pool rejection as "
               "ExplicitPassthroughPoolAllocaDealloca."},
              {"QueueAllocaTest.ExplicitFixedBlockPoolRequiresWaitFrontierFlag",
               "Blocked by the same iree_hal_cuda_device_queue_alloca "
               "non-NULL pool rejection as "
               "ExplicitPassthroughPoolAllocaDealloca."},
              {"QueueAllocaTest.ExplicitTLSFPoolCrossQueueWaitFrontier",
               "Blocked by the same iree_hal_cuda_device_queue_alloca "
               "non-NULL pool rejection as "
               "ExplicitPassthroughPoolAllocaDealloca."},
              {"QueueAllocaTest.ExplicitTLSFPoolCrossQueueStaleBlockGrows",
               "Blocked by the same CUDA queue pool backend UNIMPLEMENTED "
               "path as ExplicitTLSFPoolCrossQueueWaitFrontier."},
              {"QueueAllocaTest.ExplicitFixedBlockPoolNotificationRetry",
               "Blocked by the same iree_hal_cuda_device_queue_alloca "
               "non-NULL pool rejection as "
               "ExplicitPassthroughPoolAllocaDealloca."},
              {"SemaphoreSubmissionTest.CrossQueueWaitBeforeSignal",
               "CUDA 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 CUDA "
               "queue domains."},
              {"SemaphoreSubmissionTest."
               "MultiQueueFanOutDifferentValuesBeforeSignal",
               "Blocked by the same CUDA queue pool backend UNIMPLEMENTED "
               "path as CrossQueueWaitBeforeSignal."},
              {"EventTest.*", "CUDA does not implement HAL events"},
              {"ExecutableTest.*",
               "CUDA does not implement executable reflection"},
              {"QueueDispatchIndirectParametersTest.*",
               "CUDA queue_dispatch is implemented via one-shot command "
               "buffer emulation, and CUDA stream/graph command buffers "
               "require host-provided launch dimensions rather than "
               "device-resident indirect workgroup counts."},
              {"DispatchIndirectParametersTest.*",
               "CUDA stream/graph command buffers explicitly reject indirect "
               "workgroup count parameters; supporting them requires a "
               "device-side launch or packet-patching mechanism."},
          }},
         {"async_queue"},
     }),
     true);

}  // namespace iree::hal::cts
