<commit_before>// Copyright 2021 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

#include "iree/hal/utils/deferred_command_buffer.h"

#include "iree/base/internal/arena.h"
#include "iree/base/tracing.h"
#include "iree/hal/utils/resource_set.h"

//===----------------------------------------------------------------------===//
// Command recording structures
//===----------------------------------------------------------------------===//

typedef enum iree_hal_command_type_e {
  IREE_HAL_CMD_EXECUTION_BARRIER = 0,
  IREE_HAL_CMD_SIGNAL_EVENT,
  IREE_HAL_CMD_RESET_EVENT,
  IREE_HAL_CMD_WAIT_EVENTS,
  IREE_HAL_CMD_DISCARD_BUFFER,
  IREE_HAL_CMD_FILL_BUFFER,
  IREE_HAL_CMD_UPDATE_BUFFER,
  IREE_HAL_CMD_COPY_BUFFER,
  IREE_HAL_CMD_PUSH_CONSTANTS,
  IREE_HAL_CMD_PUSH_DESCRIPTOR_SET,
  IREE_HAL_CMD_BIND_DESCRIPTOR_SET,
  IREE_HAL_CMD_DISPATCH,
  IREE_HAL_CMD_DISPATCH_INDIRECT,
} iree_hal_cmd_type_t;

// Header prefixed to all commands, forming a linked-list.
//
// Each command is allocated from the arena and does *not* retain any resources.
// We could elide some of these commands by keeping local state however that
// requires knowing more about the target device (executable layouts, etc) and
// prevents using this as a way to debug or benchmark command buffers. The
// intent is that each command captures the exact information passed during the
// call such that the target command buffer cannot tell they were deferred.
//
// As each command is variable sized we store pointers to the following command
// to allow us to walk the list during replay. Storing just a size would be
// insufficient as commands may be spread across many arena blocks from the
// block pool.
typedef struct iree_hal_cmd_header_t {
  // Next command in the list or NULL if the end.
  struct iree_hal_cmd_header_t* next;
  // Type of the command that follows.
  iree_hal_cmd_type_t type;
} iree_hal_cmd_header_t;

typedef iree_status_t (*iree_hal_cmd_apply_fn_t)(
    iree_hal_command_buffer_t* target_command_buffer,
    iree_hal_cmd_header_t* cmd_header);

//===----------------------------------------------------------------------===//
// Command list allocation and storage
//===----------------------------------------------------------------------===//

// A singly-linked list of commands allocated from an arena.
typedef struct iree_hal_cmd_list_t {
  // Arena used to hold the recorded commands using block_pool for storage.
  // Will be reset as the command buffer is re-recorded.
  iree_arena_allocator_t arena;

  // Head of the command list.
  iree_hal_cmd_header_t* head;
  // Tail of the command list (may be head).
  iree_hal_cmd_header_t* tail;
} iree_hal_cmd_list_t;

// Initializes a new command list that allocates from the given |block_pool|.
// Upon return the command list is ready for recording.
static void iree_hal_cmd_list_initialize(iree_arena_block_pool_t* block_pool,
                                         iree_hal_cmd_list_t* out_cmd_list) {
  iree_arena_initialize(block_pool, &out_cmd_list->arena);
  out_cmd_list->head = NULL;
  out_cmd_list->tail = NULL;
}

// Returns true if the |cmd_list| is empty.
static bool iree_hal_cmd_list_is_empty(const iree_hal_cmd_list_t* cmd_list) {
  return cmd_list->head != NULL;
}

// Resets the command list and returns all arena blocks back to the block pool.
// Upon return the command list is ready for recording.
static void iree_hal_cmd_list_reset(iree_hal_cmd_list_t* cmd_list) {
  // We could make reset retain a single block so as we know that we'll be
  // adding more commands on this path and it would remove a round-trip through
  // the pool.
  iree_arena_reset(&cmd_list->arena);
  cmd_list->head = NULL;
  cmd_list->tail = NULL;
}

// Deinitializes the command list, preparing for destruction.
static void iree_hal_cmd_list_deinitialize(iree_hal_cmd_list_t* cmd_list) {
  iree_hal_cmd_list_reset(cmd_list);
}

// Appends a new command to the command list and returns the base pointer to its<commit_msg>Fixing CUDA command buffer issue introduced in #9645. (#9661)<commit_after>// Copyright 2021 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

#include "iree/hal/utils/deferred_command_buffer.h"

#include "iree/base/internal/arena.h"
#include "iree/base/tracing.h"
#include "iree/hal/utils/resource_set.h"

//===----------------------------------------------------------------------===//
// Command recording structures
//===----------------------------------------------------------------------===//

typedef enum iree_hal_command_type_e {
  IREE_HAL_CMD_EXECUTION_BARRIER = 0,
  IREE_HAL_CMD_SIGNAL_EVENT,
  IREE_HAL_CMD_RESET_EVENT,
  IREE_HAL_CMD_WAIT_EVENTS,
  IREE_HAL_CMD_DISCARD_BUFFER,
  IREE_HAL_CMD_FILL_BUFFER,
  IREE_HAL_CMD_UPDATE_BUFFER,
  IREE_HAL_CMD_COPY_BUFFER,
  IREE_HAL_CMD_PUSH_CONSTANTS,
  IREE_HAL_CMD_PUSH_DESCRIPTOR_SET,
  IREE_HAL_CMD_BIND_DESCRIPTOR_SET,
  IREE_HAL_CMD_DISPATCH,
  IREE_HAL_CMD_DISPATCH_INDIRECT,
} iree_hal_cmd_type_t;

// Header prefixed to all commands, forming a linked-list.
//
// Each command is allocated from the arena and does *not* retain any resources.
// We could elide some of these commands by keeping local state however that
// requires knowing more about the target device (executable layouts, etc) and
// prevents using this as a way to debug or benchmark command buffers. The
// intent is that each command captures the exact information passed during the
// call such that the target command buffer cannot tell they were deferred.
//
// As each command is variable sized we store pointers to the following command
// to allow us to walk the list during replay. Storing just a size would be
// insufficient as commands may be spread across many arena blocks from the
// block pool.
typedef struct iree_hal_cmd_header_t {
  // Next command in the list or NULL if the end.
  struct iree_hal_cmd_header_t* next;
  // Type of the command that follows.
  iree_hal_cmd_type_t type;
} iree_hal_cmd_header_t;

typedef iree_status_t (*iree_hal_cmd_apply_fn_t)(
    iree_hal_command_buffer_t* target_command_buffer,
    iree_hal_cmd_header_t* cmd_header);

//===----------------------------------------------------------------------===//
// Command list allocation and storage
//===----------------------------------------------------------------------===//

// A singly-linked list of commands allocated from an arena.
typedef struct iree_hal_cmd_list_t {
  // Arena used to hold the recorded commands using block_pool for storage.
  // Will be reset as the command buffer is re-recorded.
  iree_arena_allocator_t arena;

  // Head of the command list.
  iree_hal_cmd_header_t* head;
  // Tail of the command list (may be head).
  iree_hal_cmd_header_t* tail;
} iree_hal_cmd_list_t;

// Initializes a new command list that allocates from the given |block_pool|.
// Upon return the command list is ready for recording.
static void iree_hal_cmd_list_initialize(iree_arena_block_pool_t* block_pool,
                                         iree_hal_cmd_list_t* out_cmd_list) {
  iree_arena_initialize(block_pool, &out_cmd_list->arena);
  out_cmd_list->head = NULL;
  out_cmd_list->tail = NULL;
}

// Returns true if the |cmd_list| is empty.
static bool iree_hal_cmd_list_is_empty(const iree_hal_cmd_list_t* cmd_list) {
  return cmd_list->head == NULL;
}

// Resets the command list and returns all arena blocks back to the block pool.
// Upon return the command list is ready for recording.
static void iree_hal_cmd_list_reset(iree_hal_cmd_list_t* cmd_list) {
  // We could make reset retain a single block so as we know that we'll be
  // adding more commands on this path and it would remove a round-trip through
  // the pool.
  iree_arena_reset(&cmd_list->arena);
  cmd_list->head = NULL;
  cmd_list->tail = NULL;
}

// Deinitializes the command list, preparing for destruction.
static void iree_hal_cmd_list_deinitialize(iree_hal_cmd_list_t* cmd_list) {
  iree_hal_cmd_list_reset(cmd_list);
}

// Appends a new command to the command list and returns the base pointer to its
{'fraction_non_alphanumeric': 0.13896228681239492, 'fraction_numerical': 0.0031227480182560653, 'mean_word_length': 3.0500972762645913, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6982169', 'n_tokens_mistral': 2645, 'n_tokens_neox': 2583, 'n_words': 813}