//===-- KernelSpec.cpp - General kernel spec implementation ---------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file contains the implementation details for kernel loader specs.
///
//===----------------------------------------------------------------------===//

#include "streamexecutor/KernelSpec.h"

#include "llvm/ADT/STLExtras.h"

namespace streamexecutor {

KernelLoaderSpec::KernelLoaderSpec(llvm::StringRef KernelName)
    : KernelName(KernelName) {}

CUDAPTXInMemorySpec::CUDAPTXInMemorySpec(
    llvm::StringRef KernelName,
    const llvm::ArrayRef<CUDAPTXInMemorySpec::PTXSpec> SpecList)
    : KernelLoaderSpec(KernelName) {
  for (const auto &Spec : SpecList)
    PTXByComputeCapability.emplace(Spec.TheComputeCapability, Spec.PTXCode);
}

const char *CUDAPTXInMemorySpec::getCode(int ComputeCapabilityMajor,
                                         int ComputeCapabilityMinor) const {
  auto PTXIter =
      PTXByComputeCapability.find(CUDAPTXInMemorySpec::ComputeCapability{
          ComputeCapabilityMajor, ComputeCapabilityMinor});
  if (PTXIter == PTXByComputeCapability.end())
    return nullptr;
  return PTXIter->second;
}

CUDAFatbinInMemorySpec::CUDAFatbinInMemorySpec(llvm::StringRef KernelName,
                                               const void *Bytes)
    : KernelLoaderSpec(KernelName), Bytes(Bytes) {}

OpenCLTextInMemorySpec::OpenCLTextInMemorySpec(llvm::StringRef KernelName,
                                               const char *Text)
    : KernelLoaderSpec(KernelName), Text(Text) {}

void MultiKernelLoaderSpec::setKernelName(llvm::StringRef KernelName) {
  if (TheKernelName)
    assert(KernelName.equals(*TheKernelName) &&
           "different kernel names in one MultiKernelLoaderSpec");
  else
    TheKernelName = llvm::make_unique<std::string>(KernelName);
}

MultiKernelLoaderSpec &MultiKernelLoaderSpec::addCUDAPTXInMemory(
    llvm::StringRef KernelName,
    llvm::ArrayRef<CUDAPTXInMemorySpec::PTXSpec> SpecList) {
  assert((TheCUDAPTXInMemorySpec == nullptr) &&
         "illegal loader spec overwrite");
  setKernelName(KernelName);
  TheCUDAPTXInMemorySpec =
      llvm::make_unique<CUDAPTXInMemorySpec>(KernelName, SpecList);
  return *this;
}

MultiKernelLoaderSpec &
MultiKernelLoaderSpec::addCUDAFatbinInMemory(llvm::StringRef KernelName,
                                             const void *Bytes) {
  assert((TheCUDAFatbinInMemorySpec == nullptr) &&
         "illegal loader spec overwrite");
  setKernelName(KernelName);
  TheCUDAFatbinInMemorySpec =
      llvm::make_unique<CUDAFatbinInMemorySpec>(KernelName, Bytes);
  return *this;
}

MultiKernelLoaderSpec &
MultiKernelLoaderSpec::addOpenCLTextInMemory(llvm::StringRef KernelName,
                                             const char *OpenCLText) {
  assert((TheOpenCLTextInMemorySpec == nullptr) &&
         "illegal loader spec overwrite");
  setKernelName(KernelName);
  TheOpenCLTextInMemorySpec =
      llvm::make_unique<OpenCLTextInMemorySpec>(KernelName, OpenCLText);
  return *this;
}

} // namespace streamexecutor
