//===--- Level Zero Target RTL Implementation -----------------------------===//
//
// Part of the LLVM Project, 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
//
//===----------------------------------------------------------------------===//
//
// Level Zero RTL Options support.
//
//===----------------------------------------------------------------------===//

#ifndef OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0OPTIONS_H
#define OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0OPTIONS_H

#include <level_zero/ze_api.h>

#include "Shared/EnvironmentVar.h"
#include "llvm/Support/Allocator.h"

#include "L0Defs.h"

namespace llvm::omp::target::plugin {
/// Command submission mode.
enum class CommandModeTy { Sync = 0, InOrder };

/// Specialization constants used for a module compilation.
class SpecConstantsTy {
  std::vector<uint32_t> ConstantIds;
  std::vector<const void *> ConstantValues;
  BumpPtrAllocator &Allocator;

public:
  SpecConstantsTy(BumpPtrAllocator &Allocator) : Allocator(Allocator) {}
  SpecConstantsTy(const SpecConstantsTy &) = delete;
  SpecConstantsTy(SpecConstantsTy &&) = delete;
  SpecConstantsTy &operator=(const SpecConstantsTy &) = delete;
  SpecConstantsTy &operator=(const SpecConstantsTy &&) = delete;
  SpecConstantsTy(const SpecConstantsTy &&Other)
      : ConstantIds(std::move(Other.ConstantIds)),
        ConstantValues(std::move(Other.ConstantValues)),
        Allocator(Other.Allocator) {}
  ~SpecConstantsTy() = default;

  template <typename T> void addConstant(uint32_t Id, T Val) {
    T *ValuePtr =
        reinterpret_cast<T *>(Allocator.Allocate(sizeof(T), alignof(T)));
    *ValuePtr = Val;

    ConstantIds.push_back(Id);
    ConstantValues.push_back(reinterpret_cast<void *>(ValuePtr));
  }

  ze_module_constants_t getModuleConstants() const {
    ze_module_constants_t Tmp{static_cast<uint32_t>(ConstantValues.size()),
                              ConstantIds.data(),
                              // Unfortunately we have to const_cast it.
                              // L0 data type should probably be fixed.
                              const_cast<const void **>(ConstantValues.data())};
    return Tmp;
  }
};

/// L0 Plugin flags.
struct L0OptionFlagsTy {
  uint64_t UseMemoryPool : 1;
  uint64_t UseCopyOffloadHint : 1;
  uint64_t Reserved : 62;
  L0OptionFlagsTy() : UseMemoryPool(1), UseCopyOffloadHint(1), Reserved(0) {}
};

struct L0OptionsTy {
  /// Binary flags.
  L0OptionFlagsTy Flags;

  /// Staging buffer size.
  size_t StagingBufferSize = L0StagingBufferSize;

  /// Staging buffer count.
  size_t StagingBufferCount = L0StagingBufferCount;

  struct MemPoolConfigTy {
    bool Use;
    int32_t AllocMax;
    int32_t Capacity;
    int32_t PoolSize;
  };
  /// Memory pool default parameters for each allocation kind:
  /// {UseByDefault, AllocMax(MB), Capacity, PoolSize(MB)}
  std::array<MemPoolConfigTy, 3> MemPoolConfig{
      MemPoolConfigTy{true, 1, 4, 256},  // TARGET_ALLOC_DEVICE
      MemPoolConfigTy{true, 1, 4, 256},  // TARGET_ALLOC_HOST
      MemPoolConfigTy{true, 8, 4, 256}}; // TARGET_ALLOC_SHARED

  /// Parameters for memory pools dedicated to reduction scratch space.
  std::array<int32_t, 3> ReductionPoolInfo{256, 8, 8192};

  // Compilation options for IGC.
  // OpenCL 2.0 builtins (like atomic_load_explicit and etc.) are used by
  // runtime, so we have to explicitly specify the "-cl-std=CL2.0" compilation
  // option. With it, the SPIR-V will be converted to LLVM IR with OpenCL 2.0
  // builtins. Otherwise, SPIR-V will be converted to LLVM IR with OpenCL 1.2
  // builtins.
  static constexpr std::string_view CompilationOptions = "-cl-std=CL2.0 ";
  static constexpr std::string_view InternalCompilationOptions =
      "-cl-take-global-address";
  std::string UserCompilationOptions;

  /// Spec constants used for all modules.
  SpecConstantsTy CommonSpecConstants;

  /// Command execution mode.
  CommandModeTy CommandMode = CommandModeTy::InOrder;

  bool Init = false; // Have the options already been processed.

  // Allocator for long-lived allocations (e.g. spec constants).
  BumpPtrAllocator Allocator;

  L0OptionsTy() : CommonSpecConstants(Allocator) {}

  /// Read environment variables.
  void processEnvironmentVars();

  void init() {
    if (!Init) {
      processEnvironmentVars();
      Init = true;
    }
  }

  bool match(const StringEnvar &Var, const llvm::StringRef Matched) {
    return Matched.equals_insensitive(Var.get());
  }

}; // L0OptionsTy

} // namespace llvm::omp::target::plugin

#endif // OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0OPTIONS_H
