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

// Pure HAL sample: buffer fill, copy, and readback via command buffer.
//
// Demonstrates the core HAL workflow without any VM, bytecode modules, or
// compiled executables. This is the minimal path through the HAL:
//
//   1. Create a device from the registry by URI.
//   2. Allocate two buffers with appropriate memory types and usage flags.
//   3. Record a command buffer that fills one buffer and copies to the other.
//   4. Submit the command buffer to the device queue with a signal semaphore.
//   5. Wait for the semaphore, then read back and verify results.
//
// No compiled shaders are needed -- fill and copy are built-in transfer
// operations supported by every HAL driver.
//
// Usage:
//   hello --device=local-sync
//   hello --device=local-task
//   hello --device=vulkan

#include <inttypes.h>
#include <stdio.h>

#include "iree/async/util/proactor_pool.h"
#include "iree/base/api.h"
#include "iree/base/threading/numa.h"
#include "iree/base/tooling/flags.h"
#include "iree/hal/api.h"
#include "iree/hal/drivers/init.h"

IREE_FLAG(string, device, "local-sync",
          "HAL device URI to use for execution.\n"
          "Examples: local-sync, local-task, vulkan, cuda, hip");

// The fill pattern and buffer size are chosen to be small enough to print
// but large enough to exercise the command buffer path (not inlined).
#define BUFFER_ELEMENT_COUNT 16
#define BUFFER_SIZE (BUFFER_ELEMENT_COUNT * sizeof(uint32_t))
#define FILL_PATTERN UINT32_C(0xCAFEF00D)

//===----------------------------------------------------------------------===//
// Command recording, submission, and verification.
//
// This function owns nothing -- all resources are passed in and released by
// the caller. That means every operation can use IREE_RETURN_IF_ERROR without
// worrying about cleanup.
//===----------------------------------------------------------------------===//

static iree_status_t record_and_verify(
    iree_hal_device_t* device, iree_hal_buffer_t* source_buffer,
    iree_hal_buffer_t* destination_buffer,
    iree_hal_command_buffer_t* command_buffer,
    iree_hal_semaphore_t* semaphore) {
  //--- Record command buffer --------------------------------------------------

  fprintf(stdout, "3. Recording command buffer...\n");

  IREE_RETURN_IF_ERROR(iree_hal_command_buffer_begin(command_buffer));

  // Fill the source buffer with a repeating 32-bit pattern.
  // The fill operation writes directly into device memory via the transfer
  // engine -- no shader or dispatch is needed.
  uint32_t fill_pattern = FILL_PATTERN;
  IREE_RETURN_IF_ERROR(iree_hal_command_buffer_fill_buffer(
      command_buffer,
      iree_hal_make_buffer_ref(source_buffer, /*offset=*/0, BUFFER_SIZE),
      &fill_pattern, sizeof(fill_pattern), IREE_HAL_FILL_FLAG_NONE));

  // Barrier: the fill must complete before we read the source buffer for copy.
  iree_hal_memory_barrier_t memory_barrier = {
      .source_scope = IREE_HAL_ACCESS_SCOPE_TRANSFER_WRITE,
      .target_scope = IREE_HAL_ACCESS_SCOPE_TRANSFER_READ,
  };
  IREE_RETURN_IF_ERROR(iree_hal_command_buffer_execution_barrier(
      command_buffer, IREE_HAL_EXECUTION_STAGE_TRANSFER,
      IREE_HAL_EXECUTION_STAGE_TRANSFER, IREE_HAL_EXECUTION_BARRIER_FLAG_NONE,
      /*memory_barrier_count=*/1, &memory_barrier,
      /*buffer_barrier_count=*/0, /*buffer_barriers=*/NULL));

  // Copy the entire source buffer into the destination buffer.
  IREE_RETURN_IF_ERROR(iree_hal_command_buffer_copy_buffer(
      command_buffer,
      iree_hal_make_buffer_ref(source_buffer, /*offset=*/0, BUFFER_SIZE),
      iree_hal_make_buffer_ref(destination_buffer, /*offset=*/0, BUFFER_SIZE),
      IREE_HAL_COPY_FLAG_NONE));

  IREE_RETURN_IF_ERROR(iree_hal_command_buffer_end(command_buffer));

  //--- Submit to queue with semaphore signaling -------------------------------

  fprintf(stdout, "4. Submitting to device queue...\n");

  // Submit: no wait semaphores (execute immediately), signal semaphore to 1
  // when the command buffer retires.
  uint64_t signal_value = 1;
  iree_hal_semaphore_list_t signal_list = {
      .count = 1,
      .semaphores = &semaphore,
      .payload_values = &signal_value,
  };
  IREE_RETURN_IF_ERROR(iree_hal_device_queue_execute(
      device, IREE_HAL_QUEUE_AFFINITY_ANY, iree_hal_semaphore_list_empty(),
      signal_list, command_buffer, iree_hal_buffer_binding_table_empty(),
      IREE_HAL_EXECUTE_FLAG_NONE));

  //--- Wait and verify --------------------------------------------------------

  fprintf(stdout, "5. Waiting for completion...\n");

  // Block until the semaphore reaches value 1 (command buffer retired).
  IREE_RETURN_IF_ERROR(iree_hal_semaphore_wait(semaphore, signal_value,
                                               iree_infinite_timeout(),
                                               IREE_ASYNC_WAIT_FLAG_NONE));

  fprintf(stdout, "   Command buffer completed.\n");

  // Read back the destination buffer and verify every element matches the fill
  // pattern. This uses a synchronous map -- for production code you would use
  // queue_copy to a staging buffer instead.
  uint32_t readback[BUFFER_ELEMENT_COUNT] = {0};
  IREE_RETURN_IF_ERROR(iree_hal_buffer_map_read(
      destination_buffer, /*source_offset=*/0, readback, sizeof(readback)));

  fprintf(stdout, "   Verifying %d elements...\n", BUFFER_ELEMENT_COUNT);
  for (int i = 0; i < BUFFER_ELEMENT_COUNT; ++i) {
    if (readback[i] != FILL_PATTERN) {
      return iree_make_status(IREE_STATUS_DATA_LOSS,
                              "mismatch at element %d: expected 0x%08" PRIX32
                              ", got 0x%08" PRIX32,
                              i, (uint32_t)FILL_PATTERN, readback[i]);
    }
  }

  fprintf(stdout, "\nAll %d elements verified: 0x%08" PRIX32 "\n",
          BUFFER_ELEMENT_COUNT, (uint32_t)FILL_PATTERN);
  return iree_ok_status();
}

//===----------------------------------------------------------------------===//
// Resource creation and teardown.
//
// All resources are initialized to NULL and unconditionally released at the
// end -- every iree_hal_*_release is safe to call with NULL.
//===----------------------------------------------------------------------===//

static iree_status_t run_sample(void) {
  iree_allocator_t host_allocator = iree_allocator_system();

  // All NULL-initialized so cleanup is unconditional.
  iree_async_proactor_pool_t* proactor_pool = NULL;
  iree_hal_device_t* device = NULL;
  iree_hal_buffer_t* source_buffer = NULL;
  iree_hal_buffer_t* destination_buffer = NULL;
  iree_hal_command_buffer_t* command_buffer = NULL;
  iree_hal_semaphore_t* semaphore = NULL;

  //--- 1. Create device from registry -----------------------------------------

  fprintf(stdout, "1. Creating device (--device=%s)...\n", FLAG_device);

  // Register all linked-in drivers with the default registry.
  iree_status_t status = iree_hal_register_all_available_drivers(
      iree_hal_driver_registry_default());

  // Create a shared proactor pool for async I/O. The device retains the pool
  // so we release our reference immediately after device creation.
  if (iree_status_is_ok(status)) {
    status = iree_async_proactor_pool_create(
        iree_numa_node_count(), /*node_ids=*/NULL,
        iree_async_proactor_pool_options_default(), host_allocator,
        &proactor_pool);
  }

  // Create a device directly from the URI. This handles driver lookup,
  // instantiation, and default device selection in one step.
  iree_hal_device_create_params_t create_params =
      iree_hal_device_create_params_default();
  create_params.proactor_pool = proactor_pool;
  if (iree_status_is_ok(status)) {
    status = iree_hal_create_device(iree_hal_driver_registry_default(),
                                    iree_make_cstring_view(FLAG_device),
                                    &create_params, host_allocator, &device);
  }
  iree_async_proactor_pool_release(proactor_pool);

  if (iree_status_is_ok(status)) {
    iree_string_view_t device_id = iree_hal_device_id(device);
    if (!device_id.size) device_id = iree_make_cstring_view("(unnamed)");
    fprintf(stdout, "   Device: '%.*s'\n", (int)device_id.size, device_id.data);
  }

  //--- 2. Allocate buffers, command buffer, semaphore -------------------------

  if (iree_status_is_ok(status)) {
    fprintf(stdout, "2. Allocating buffers (%" PRIhsz " bytes each)...\n",
            (iree_host_size_t)BUFFER_SIZE);
  }

  // Source buffer: lives on-device. Filled by the command buffer and read
  // during copy -- the host never touches it, so it can be device-local for
  // optimal placement (VRAM on GPUs, same as host memory on CPU backends).
  iree_hal_buffer_params_t source_params = {
      .type = IREE_HAL_MEMORY_TYPE_DEVICE_LOCAL,
      .usage = IREE_HAL_BUFFER_USAGE_TRANSFER_SOURCE |
               IREE_HAL_BUFFER_USAGE_TRANSFER_TARGET,
  };
  if (iree_status_is_ok(status)) {
    status = iree_hal_allocator_allocate_buffer(
        iree_hal_device_allocator(device), source_params, BUFFER_SIZE,
        &source_buffer);
  }

  // Destination buffer: host-visible for readback. The device writes it via
  // copy, then the host maps it to verify results. HOST_LOCAL + DEVICE_VISIBLE
  // places this in system RAM accessible to both host and device.
  iree_hal_buffer_params_t destination_params = {
      .type =
          IREE_HAL_MEMORY_TYPE_HOST_LOCAL | IREE_HAL_MEMORY_TYPE_DEVICE_VISIBLE,
      .usage =
          IREE_HAL_BUFFER_USAGE_TRANSFER_TARGET | IREE_HAL_BUFFER_USAGE_MAPPING,
  };
  if (iree_status_is_ok(status)) {
    status = iree_hal_allocator_allocate_buffer(
        iree_hal_device_allocator(device), destination_params, BUFFER_SIZE,
        &destination_buffer);
  }

  // One-shot command buffer for transfer operations.
  if (iree_status_is_ok(status)) {
    status = iree_hal_command_buffer_create(
        device, IREE_HAL_COMMAND_BUFFER_MODE_ONE_SHOT,
        IREE_HAL_COMMAND_CATEGORY_TRANSFER, IREE_HAL_QUEUE_AFFINITY_ANY,
        /*binding_capacity=*/0, &command_buffer);
  }

  // Timeline semaphore: initial value 0, will be signaled to 1 on completion.
  if (iree_status_is_ok(status)) {
    status = iree_hal_semaphore_create(
        device, IREE_HAL_QUEUE_AFFINITY_ANY,
        /*initial_value=*/0, IREE_HAL_SEMAPHORE_FLAG_NONE, &semaphore);
  }

  //--- 3-5. Record, submit, wait, verify --------------------------------------

  if (iree_status_is_ok(status)) {
    status = record_and_verify(device, source_buffer, destination_buffer,
                               command_buffer, semaphore);
  }

  if (iree_status_is_ok(status)) {
    fprintf(stdout, "HAL hello sample completed successfully.\n");
  }

  //--- Cleanup (all NULL-safe, reverse order) ---------------------------------

  iree_hal_semaphore_release(semaphore);
  iree_hal_command_buffer_release(command_buffer);
  iree_hal_buffer_release(destination_buffer);
  iree_hal_buffer_release(source_buffer);
  iree_hal_device_release(device);
  return status;
}

//===----------------------------------------------------------------------===//
// Main
//===----------------------------------------------------------------------===//

int main(int argc, char** argv) {
  iree_flags_parse_checked(IREE_FLAGS_PARSE_MODE_DEFAULT, &argc, &argv);
  iree_status_t status = run_sample();
  if (iree_status_is_ok(status)) {
    return 0;
  }
  iree_status_fprint(stderr, status);
  fprintf(stderr, "\n");
  int code = (int)iree_status_code(status);
  iree_status_free(status);
  return code;
}
