//===--- acxxel.h - The Acxxel API ------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

/// \mainpage Welcome to Acxxel
///
/// \section Introduction
///
/// \b Acxxel is a library providing a modern C++ interface for managing
/// accelerator devices such as GPUs. Acxxel handles operations such as
/// allocating device memory, copying data to and from device memory, creating
/// and managing device events, and creating and managing device streams.
///
/// \subsection ExampleUsage Example Usage
///
/// Below is some example code to show you the basics of Acxxel.
///
/// \snippet examples/simple_example.cu Example simple saxpy
///
/// The above code could be compiled with either `clang` or `nvcc`. Compare this
/// with the standard CUDA runtime library code to perform these same
/// operations:
///
/// \snippet examples/simple_example.cu Example CUDA simple saxpy
///
/// Notice that the CUDA runtime calls are not type safe. For example, if you
/// change the type of the inputs from `float` to `double`, you have to remember
/// to change the size calculation. If you forget, you will get garbage output
/// data. In the Acxxel example, you would instead get a helpful compile-time
/// error that wouldn't let you forget to change the types inside the function.
///
/// The Acxxel example also automatically uses the right sizes for memory
/// copies, so you don't have to worry about computing the sizes yourself.
///
/// The CUDA runtime interface makes it easy to get the source and destination
/// mixed up in a call to `cudaMemcpy`. If you pass the pointers in the wrong
/// order or pass the wrong enum value for the direction parameter, you won't
/// find out until runtime (if you remembered to check the error return value of
/// `cudaMemcpy`). In Acxxel there is no verbose direction enum because the name
/// of the function says which way the copy goes, and mixing up the order of
/// source and destination is a compile-time error.
///
/// The CUDA runtime interface makes you clean up your device memory by calling
/// `cudaFree` for each call to `cudaMalloc`. In Acxxel, you don't have to worry
/// about that because the memory cleans itself up when it goes out of scope.
///
/// \subsection AcxxelFeatures Acxxel Features
///
/// Acxxel provides many nice features compared to the C-like interfaces, such
/// as the CUDA runtime API, which are normally used for the host code in
/// applications using accelerators.
///
/// \subsubsection TypeSafety Type safety
///
/// Most errors involving mixing up types, sources and destinations, or host and
/// device memory result in helpful compile-time errors.
///
/// \subsubsection NoCopySizes No need to specify sizes for memory copies
///
/// When the arguments to copy functions such as acxxel::Platform::copyHToD know
/// their sizes (e.g std::array, std::vector, and C-style arrays), there is no
/// need to specify the amount of memory to copy; Acxxel will just copy the
/// whole thing. Of course the copy functions also have overloads that accept an
/// element count for those times when you don't want to copy everything.
///
/// \subsubsection MemoryCleanup Automatic memory cleanup
///
/// Device memory allocated with acxxel::Platform::mallocD is automatically
/// freed when it goes out of scope.
///
/// \subsubsection NiceErrorHandling Error handling
///
/// Operations that would normally return values return acxxel::Expected obects
/// in Acxxel. These `Expected` objects contain either a value or an error
/// message explaining why the value is not present. This reminds the user to
/// check for errors, but also allows them to opt-out easily be calling the
/// acxxel::Expected::getValue or acxxel::Expected::takeValue methods. The
/// `getValue` method returns a reference to the value, leaving the `Expected`
/// instance as the value owner, whereas the `takeValue` method moves the value
/// out of the `Expected` object and transfers ownership to the caller.
///
/// \subsubsection PlatformIndependence Platform independence
///
/// Acxxel code works not only with CUDA, but also with any other platform that
/// can support its interface. For example, Acxxel supports OpenCL. The
/// acxxel::getCUDAPlatform and acxxel::getOpenCLPlatform functions are provided
/// to allow easy access to the built-in CUDA and OpenCL platforms. Other
/// platforms can be created by implementing the acxxel::Platform interface, and
/// instances of those classes can be created directly.
///
/// \subsubsection CUDAInterop Seamless interoperation with CUDA
///
/// Acxxel functions as a modern replacement for the standard CUDA runtime
/// library and interoperates seamlessly with kernel calls.

#ifndef ACXXEL_ACXXEL_H
#define ACXXEL_ACXXEL_H

#include "span.h"
#include "status.h"

#include <functional>
#include <memory>
#include <string>
#include <type_traits>

#if defined(__clang__) || defined(__GNUC__)
#define ACXXEL_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define ACXXEL_WARN_UNUSED_RESULT
#endif

/// This type is declared here to provide smooth interoperability with the CUDA
/// triple-chevron kernel launch syntax.
///
/// A acxxel::Stream instance will be implicitly convertible to a CUstream_st*,
/// which is the type expected for the stream argument in the triple-chevron
/// CUDA kernel launch. This means that a acxxel::Stream can be passed without
/// explicit casting as the fourth argument to a triple-chevron CUDA kernel
/// launch.
struct CUstream_st; // NOLINT

namespace acxxel {

class Event;
class Platform;
class Stream;

template <typename T> class DeviceMemory;

template <typename T> class DeviceMemorySpan;

template <typename T> class AsyncHostMemory;

template <typename T> class AsyncHostMemorySpan;

template <typename T> class OwnedAsyncHostMemory;

/// Function type used to destroy opaque handles given out by the platform.
using HandleDestructor = void (*)(void *);

/// Functor type for enqueuing host callbacks on a stream.
using StreamCallback = std::function<void(Stream &, const Status &)>;

struct KernelLaunchDimensions {
  // Intentionally implicit
  KernelLaunchDimensions(unsigned int BlockX = 1, unsigned int BlockY = 1,
                         unsigned int BlockZ = 1, unsigned int GridX = 1,
                         unsigned int GridY = 1, unsigned int GridZ = 1)
      : BlockX(BlockX), BlockY(BlockY), BlockZ(BlockZ), GridX(GridX),
        GridY(GridY), GridZ(GridZ) {}

  unsigned int BlockX;
  unsigned int BlockY;
  unsigned int BlockZ;
  unsigned int GridX;
  unsigned int GridY;
  unsigned int GridZ;
};

/// Logs a warning message.
void logWarning(const std::string &Message);

/// Gets a pointer to the standard CUDA platform.
Expected<Platform *> getCUDAPlatform();

/// Gets a pointer to the standard OpenCL platform.
Expected<Platform *> getOpenCLPlatform();

/// A function that can be executed on the device.
///
/// A Kernel is created from a Program by calling Program::createKernel, and a
/// kernel is enqueued into a Stream by calling Stream::asyncKernelLaunch.
class Kernel {
public:
  Kernel(const Kernel &) = delete;
  Kernel &operator=(const Kernel &) = delete;
  Kernel(Kernel &&) noexcept;
  Kernel &operator=(Kernel &&That) noexcept;
  ~Kernel() = default;

private:
  // Only a Program can make a kernel.
  friend class Program;
  Kernel(Platform *APlatform, void *AHandle, HandleDestructor Destructor)
      : ThePlatform(APlatform), TheHandle(AHandle, Destructor) {}

  // Let stream get raw handle for kernel launches.
  friend class Stream;

  Platform *ThePlatform;
  std::unique_ptr<void, HandleDestructor> TheHandle;
};

/// A program loaded on a device.
///
/// A program can be created by calling Platform::createProgramFromSource, and a
/// Kernel can be created from a program by running Program::createKernel.
///
/// A program can contain any number of kernels, and a program only needs to be
/// loaded once in order to use all its kernels.
class Program {
public:
  Program(const Program &) = delete;
  Program &operator=(const Program &) = delete;
  Program(Program &&) noexcept;
  Program &operator=(Program &&That) noexcept;
  ~Program() = default;

  Expected<Kernel> createKernel(const std::string &Name);

private:
  // Only a platform can make a program.
  friend class Platform;
  Program(Platform *APlatform, void *AHandle, HandleDestructor Destructor)
      : ThePlatform(APlatform), TheHandle(AHandle, Destructor) {}

  Platform *ThePlatform;
  std::unique_ptr<void, HandleDestructor> TheHandle;
};

/// A stream of computation.
///
/// All operations enqueued on a Stream are serialized, but operations enqueued
/// on different Streams may run concurrently.
///
/// Each Platform has a notion of the currently active device on a particular
/// thread (see Platform::getActiveDeviceForThread and
/// Platform::setActiveDeviceForThread). Each Stream is associated with a
/// specific, fixed device, set to the current thread's active device when the
/// Stream is created. Whenver a thread enqueues commands onto a Stream, its
/// active device must match the Stream's device.
class Stream {
public:
  Stream(const Stream &) = delete;
  Stream &operator=(const Stream &) = delete;
  Stream(Stream &&) noexcept;
  Stream &operator=(Stream &&) noexcept;
  ~Stream() = default;

  /// Gets the index of the device on which this Stream operates.
  int getDeviceIndex() { return TheDeviceIndex; }

  /// Blocks the host until the Stream is done executing all previously enqueued
  /// work.
  ///
  /// Returns a Status for any errors emitted by the asynchronous work on the
  /// Stream, or by any error in the synchronization process itself. Clears the
  /// Status state of the stream.
  Status sync() ACXXEL_WARN_UNUSED_RESULT;

  /// Makes all future work submitted to this stream wait until the event
  /// reports completion.
  ///
  /// This is useful because the event argument may be recorded on a different
  /// stream, so this method allows for synchronization between streams without
  /// synchronizing all streams.
  ///
  /// Returns a Status for any errors emitted by the asynchronous work on the
  /// Stream, or by any error in the synchronization process itself. Clears the
  /// Status state of the stream.
  Status waitOnEvent(Event &Event) ACXXEL_WARN_UNUSED_RESULT;

  /// Adds a host callback function to the stream.
  ///
  /// The callback will be called on the host after all previously enqueued work
  /// on the stream is complete, and no work enqueued after the callback will
  /// begin until after the callback has finished.
  Stream &addCallback(std::function<void(Stream &, const Status &)> Callback);

  /// \name Asynchronous device memory copies.
  ///
  /// These functions enqueue asynchronous memory copy operations into the
  /// stream. Only async host memory is allowed for host arguments to these
  /// functions. Async host memory can be created from normal host memory by
  /// registering it with Platform::registerHostMem. AsyncHostMemory can also be
  /// allocated directly by calling Platform::newAsyncHostMem.
  ///
  /// For all these functions, DeviceSrcTy must be convertible to
  /// DeviceMemorySpan<const T>, DeviceDstTy must be convertible to
  /// DeviceMemorySpan<T>, HostSrcTy must be convertible to
  /// AsyncHostMemorySpan<const T> and HostDstTy must be convertible to
  /// AsyncHostMemorySpan<T>. Additionally, the T types must match for the
  /// destination and source.
  /// \{

  /// Copies from device memory to device memory.
  template <typename DeviceSrcTy, typename DeviceDstTy>
  Stream &asyncCopyDToD(DeviceSrcTy &&DeviceSrc, DeviceDstTy &&DeviceDst);

  /// Copies from device memory to device memory with a given element count.
  template <typename DeviceSrcTy, typename DeviceDstTy>
  Stream &asyncCopyDToD(DeviceSrcTy &&DeviceSrc, DeviceDstTy &&DeviceDst,
                        ptrdiff_t ElementCount);

  /// Copies from device memory to host memory.
  template <typename DeviceSrcTy, typename HostDstTy>
  Stream &asyncCopyDToH(DeviceSrcTy &&DeviceSrc, HostDstTy &&HostDst);

  /// Copies from device memory to host memory with a given element count.
  template <typename DeviceSrcTy, typename HostDstTy>
  Stream &asyncCopyDToH(DeviceSrcTy &&DeviceSrc, HostDstTy &&HostDst,
                        ptrdiff_t ElementCount);

  /// Copies from host memory to device memory.
  template <typename HostSrcTy, typename DeviceDstTy>
  Stream &asyncCopyHToD(HostSrcTy &&HostSrc, DeviceDstTy &&DeviceDst);

  /// Copies from host memory to device memory with a given element count.
  template <typename HostSrcTy, typename DeviceDstTy>
  Stream &asyncCopyHToD(HostSrcTy &&HostSrc, DeviceDstTy &DeviceDst,
                        ptrdiff_t ElementCount);

  /// \}

  /// \name Stream-synchronous device memory copies
  ///
  /// These functions block the host until the copy and all previously-enqueued
  /// work on the stream has completed.
  ///
  /// For all these functions, DeviceSrcTy must be convertible to
  /// DeviceMemorySpan<const T>, DeviceDstTy must be convertible to
  /// DeviceMemorySpan<T>, HostSrcTy must be convertible to Span<const T> and
  /// HostDstTy must be convertible to Span<T>. Additionally, the T types must
  /// match for the destination and source.
  /// \{

  template <typename DeviceSrcTy, typename DeviceDstTy>
  Stream &syncCopyDToD(DeviceSrcTy &&DeviceSrc, DeviceDstTy &&DeviceDst);

  template <typename DeviceSrcTy, typename DeviceDstTy>
  Stream &syncCopyDToD(DeviceSrcTy &&DeviceSrc, DeviceDstTy &&DeviceDst,
                       ptrdiff_t ElementCount);

  template <typename DeviceSrcTy, typename HostDstTy>
  Stream &syncCopyDToH(DeviceSrcTy &&DeviceSrc, HostDstTy &&HostDst);

  template <typename DeviceSrcTy, typename HostDstTy>
  Stream &syncCopyDToH(DeviceSrcTy &&DeviceSrc, HostDstTy &&HostDst,
                       ptrdiff_t ElementCount);

  template <typename HostSrcTy, typename DeviceDstTy>
  Stream &syncCopyHToD(HostSrcTy &&HostSrc, DeviceDstTy &&DeviceDst);

  template <typename HostSrcTy, typename DeviceDstTy>
  Stream &syncCopyHToD(HostSrcTy &&HostSrc, DeviceDstTy &DeviceDst,
                       ptrdiff_t ElementCount);

  /// \}

  /// Enqueues an operation in the stream to set the bytes of a given device
  /// memory region to a given value.
  ///
  /// DeviceDstTy must be convertible to DeviceMemorySpan<T> for non-const T.
  template <typename DeviceDstTy>
  Stream &asyncMemsetD(DeviceDstTy &&DeviceDst, char ByteValue);

  /// Enqueues a kernel launch operation on this stream.
  Stream &asyncKernelLaunch(const Kernel &TheKernel,
                            KernelLaunchDimensions LaunchDimensions,
                            Span<void *> Arguments, Span<size_t> ArgumentSizes,
                            size_t SharedMemoryBytes = 0);

  /// Enqueues an event in the stream.
  Stream &enqueueEvent(Event &E);

  // Allows implicit conversion to (CUstream_st *). This makes triple-chevron
  // kernel calls look nicer because you can just pass a acxxel::Stream
  // directly.
  operator CUstream_st *() {
    return static_cast<CUstream_st *>(TheHandle.get());
  }

  /// Gets the current status for the Stream and clears the Stream's status.
  Status takeStatus() ACXXEL_WARN_UNUSED_RESULT {
    Status OldStatus = TheStatus;
    TheStatus = Status();
    return OldStatus;
  }

private:
  // Only a platform can make a stream.
  friend class Platform;
  Stream(Platform *APlatform, int DeviceIndex, void *AHandle,
         HandleDestructor Destructor)
      : ThePlatform(APlatform), TheDeviceIndex(DeviceIndex),
        TheHandle(AHandle, Destructor) {}

  const Status &setStatus(const Status &S) {
    if (S.isError() && !TheStatus.isError()) {
      TheStatus = S;
    }
    return S;
  }

  Status takeStatusOr(const Status &S) {
    if (TheStatus.isError()) {
      Status OldStatus = TheStatus;
      TheStatus = Status();
      return OldStatus;
    }
    return S;
  }

  // The platform that created the stream.
  Platform *ThePlatform;

  // The index of the device on which the stream operates.
  int TheDeviceIndex;

  // A handle to the platform-specific handle implementation.
  std::unique_ptr<void, HandleDestructor> TheHandle;
  Status TheStatus;
};

/// A user-created event on a device.
///
/// This is useful for setting synchronization points in a Stream. The host can
/// synchronize with a Stream without using events, but that requires all the
/// work in the Stream to be finished in order for the host to be notified.
/// Events provide more flexibility by allowing the host to be notified when a
/// single Event in the Stream is finished, rather than all the work in the
/// Stream.
class Event {
public:
  Event(const Event &) = delete;
  Event &operator=(const Event &) = delete;
  Event(Event &&) noexcept;
  Event &operator=(Event &&That) noexcept;
  ~Event() = default;

  /// Checks to see if the event is done running.
  bool isDone();

  /// Blocks the host until the event is done.
  Status sync();

  /// Gets the time elapsed between the previous event's execution and this
  /// event's execution.
  Expected<float> getSecondsSince(const Event &Previous);

private:
  // Only a platform can make an event.
  friend class Platform;
  Event(Platform *APlatform, void *AHandle, HandleDestructor Destructor)
      : ThePlatform(APlatform), TheHandle(AHandle, Destructor) {}

  Platform *ThePlatform;
  std::unique_ptr<void, HandleDestructor> TheHandle;
};

/// An accelerator platform.
///
/// This is the base class for all platforms such as CUDA and OpenCL. It
/// contains many virtual methods that must be overridden by each platform
/// implementation.
///
/// It also has some template wrapper functions that take care of type checking
/// and then forward their arguments on to raw virtual functions that are
/// implemented by each specific platform.
class Platform {
public:
  virtual ~Platform(){};

  /// Gets the number of devices for this platform in this system.
  virtual Expected<int> getDeviceCount() = 0;

  /// Sets the active device for this platform in this thread.
  virtual Status setActiveDeviceForThread(int DeviceIndex) = 0;

  /// Gets the currently active device for this platform in this thread.
  virtual int getActiveDeviceForThread() = 0;

  /// Creates a stream for the platform.
  ///
  /// The created Stream is associated with the active device for this thread.
  virtual Expected<Stream> createStream() = 0;

  /// Creates an event for the platform.
  ///
  /// The created Event is associated with the active device for this thread.
  virtual Expected<Event> createEvent() = 0;

  /// Allocates owned device memory.
  ///
  /// \warning This function only allocates space in device memory, it does not
  /// call the constructor of T.
  template <typename T>
  Expected<DeviceMemory<T>> mallocD(ptrdiff_t ElementCount) {
    Expected<void *> MaybePointer = rawMallocD(ElementCount * sizeof(T));
    if (MaybePointer.isError())
      return MaybePointer.getError();
    return DeviceMemory<T>(this, MaybePointer.getValue(), ElementCount,
                           this->getDeviceMemoryHandleDestructor());
  }

  /// Creates a DeviceMemorySpan for a device symbol.
  ///
  /// This function is present to support __device__ variables in CUDA. Given a
  /// pointer to a __device__ variable, this function returns a DeviceMemorySpan
  /// referencing the device memory that stores that __device__ variable.
  template <typename ElementType>
  Expected<DeviceMemorySpan<ElementType>> getSymbolMemory(ElementType *Symbol) {
    Expected<void *> MaybeAddress = rawGetDeviceSymbolAddress(Symbol);
    if (MaybeAddress.isError())
      return MaybeAddress.getError();
    ElementType *Address = static_cast<ElementType *>(MaybeAddress.getValue());
    Expected<ptrdiff_t> MaybeSize = rawGetDeviceSymbolSize(Symbol);
    if (MaybeSize.isError())
      return MaybeSize.getError();
    ptrdiff_t Size = MaybeSize.getValue();
    return DeviceMemorySpan<ElementType>(this, Address,
                                         Size / sizeof(ElementType), 0);
  }

  /// \name Host memory registration functions.
  /// \{

  template <typename T>
  Expected<AsyncHostMemory<const T>> registerHostMem(Span<const T> Memory) {
    Status S = rawRegisterHostMem(Memory.data(), Memory.size() * sizeof(T));
    if (S.isError())
      return S;
    return AsyncHostMemory<const T>(
        Memory.data(), Memory.size(),
        this->getUnregisterHostMemoryHandleDestructor());
  }

  template <typename T>
  Expected<AsyncHostMemory<T>> registerHostMem(Span<T> Memory) {
    Status S = rawRegisterHostMem(Memory.data(), Memory.size() * sizeof(T));
    if (S.isError())
      return S;
    return AsyncHostMemory<T>(Memory.data(), Memory.size(),
                              this->getUnregisterHostMemoryHandleDestructor());
  }

  template <typename T, size_t N>
  Expected<AsyncHostMemory<T>> registerHostMem(T (&Array)[N]) {
    Span<T> Span(Array);
    Status S = rawRegisterHostMem(Span.data(), Span.size() * sizeof(T));
    if (S.isError())
      return S;
    return AsyncHostMemory<T>(Span.data(), Span.size(),
                              this->getUnregisterHostMemoryHandleDestructor());
  }

  /// Registers memory stored in a container with a data() member function and
  /// which can be converted to a Span<T*>.
  template <typename Container>
  auto registerHostMem(Container &Cont) -> Expected<AsyncHostMemory<
      typename std::remove_reference<decltype(*Cont.data())>::type>> {
    using ValueType =
        typename std::remove_reference<decltype(*Cont.data())>::type;
    Span<ValueType> Span(Cont);
    Status S = rawRegisterHostMem(Span.data(), Span.size() * sizeof(ValueType));
    if (S.isError())
      return S;
    return AsyncHostMemory<ValueType>(
        Span.data(), Span.size(),
        this->getUnregisterHostMemoryHandleDestructor());
  }

  /// Allocates an owned, registered array of objects on the host.
  ///
  /// Default constructs each element in the resulting array.
  template <typename T>
  Expected<OwnedAsyncHostMemory<T>> newAsyncHostMem(ptrdiff_t ElementCount) {
    Expected<void *> MaybeMemory =
        rawMallocRegisteredH(ElementCount * sizeof(T));
    if (MaybeMemory.isError())
      return MaybeMemory.getError();
    T *Memory = static_cast<T *>(MaybeMemory.getValue());
    for (ptrdiff_t I = 0; I < ElementCount; ++I)
      new (Memory + I) T;
    return OwnedAsyncHostMemory<T>(Memory, ElementCount,
                                   this->getFreeHostMemoryHandleDestructor());
  }

  /// \}

  virtual Expected<Program>
  createProgramFromSource(Span<const char> Source) = 0;

protected:
  friend class Stream;
  friend class Event;
  friend class Program;
  template <typename T> friend class DeviceMemorySpan;

  void *getStreamHandle(Stream &Stream) { return Stream.TheHandle.get(); }
  void *getEventHandle(Event &Event) { return Event.TheHandle.get(); }

  // Pass along access to Stream constructor to subclasses.
  Stream constructStream(Platform *APlatform, void *AHandle,
                         HandleDestructor Destructor) {
    return Stream(APlatform, getActiveDeviceForThread(), AHandle, Destructor);
  }

  // Pass along access to Event constructor to subclasses.
  Event constructEvent(Platform *APlatform, void *AHandle,
                       HandleDestructor Destructor) {
    return Event(APlatform, AHandle, Destructor);
  }

  // Pass along access to Program constructor to subclasses.
  Program constructProgram(Platform *APlatform, void *AHandle,
                           HandleDestructor Destructor) {
    return Program(APlatform, AHandle, Destructor);
  }

  virtual Status streamSync(void *Stream) = 0;
  virtual Status streamWaitOnEvent(void *Stream, void *Event) = 0;

  virtual Status enqueueEvent(void *Event, void *Stream) = 0;
  virtual bool eventIsDone(void *Event) = 0;
  virtual Status eventSync(void *Event) = 0;
  virtual Expected<float> getSecondsBetweenEvents(void *StartEvent,
                                                  void *EndEvent) = 0;

  virtual Expected<void *> rawMallocD(ptrdiff_t ByteCount) = 0;
  virtual HandleDestructor getDeviceMemoryHandleDestructor() = 0;
  virtual void *getDeviceMemorySpanHandle(void *BaseHandle, size_t ByteSize,
                                          size_t ByteOffset) = 0;
  virtual void rawDestroyDeviceMemorySpanHandle(void *Handle) = 0;

  virtual Expected<void *> rawGetDeviceSymbolAddress(const void *Symbol) = 0;
  virtual Expected<ptrdiff_t> rawGetDeviceSymbolSize(const void *Symbol) = 0;

  virtual Status rawCopyDToD(const void *DeviceSrc,
                             ptrdiff_t DeviceSrcByteOffset, void *DeviceDst,
                             ptrdiff_t DeviceDstByteOffset,
                             ptrdiff_t ByteCount) = 0;
  virtual Status rawCopyDToH(const void *DeviceSrc,
                             ptrdiff_t DeviceSrcByteOffset, void *HostDst,
                             ptrdiff_t ByteCount) = 0;
  virtual Status rawCopyHToD(const void *HostSrc, void *DeviceDst,
                             ptrdiff_t DeviceDstByteOffset,
                             ptrdiff_t ByteCount) = 0;

  virtual Status rawMemsetD(void *DeviceDst, ptrdiff_t ByteOffset,
                            ptrdiff_t ByteCount, char ByteValue) = 0;

  virtual Status rawRegisterHostMem(const void *Memory,
                                    ptrdiff_t ByteCount) = 0;
  virtual HandleDestructor getUnregisterHostMemoryHandleDestructor() = 0;

  virtual Expected<void *> rawMallocRegisteredH(ptrdiff_t ByteCount) = 0;
  virtual HandleDestructor getFreeHostMemoryHandleDestructor() = 0;

  virtual Status asyncCopyDToD(const void *DeviceSrc,
                               ptrdiff_t DeviceSrcByteOffset, void *DeviceDst,
                               ptrdiff_t DeviceDstByteOffset,
                               ptrdiff_t ByteCount, void *Stream) = 0;
  virtual Status asyncCopyDToH(const void *DeviceSrc,
                               ptrdiff_t DeviceSrcByteOffset, void *HostDst,
                               ptrdiff_t ByteCount, void *Stream) = 0;
  virtual Status asyncCopyHToD(const void *HostSrc, void *DeviceDst,
                               ptrdiff_t DeviceDstByteOffset,
                               ptrdiff_t ByteCount, void *Stream) = 0;

  virtual Status asyncMemsetD(void *DeviceDst, ptrdiff_t ByteOffset,
                              ptrdiff_t ByteCount, char ByteValue,
                              void *Stream) = 0;

  virtual Status addStreamCallback(Stream &Stream, StreamCallback Callback) = 0;

  virtual Expected<void *> rawCreateKernel(void *Program,
                                           const std::string &Name) = 0;
  virtual HandleDestructor getKernelHandleDestructor() = 0;

  virtual Status rawEnqueueKernelLaunch(void *Stream, void *Kernel,
                                        KernelLaunchDimensions LaunchDimensions,
                                        Span<void *> Arguments,
                                        Span<size_t> ArgumentSizes,
                                        size_t SharedMemoryBytes) = 0;
};

// Implementation of templated Stream functions.

template <typename DeviceSrcTy, typename DeviceDstTy>
Stream &Stream::asyncCopyDToD(DeviceSrcTy &&DeviceSrc,
                              DeviceDstTy &&DeviceDst) {
  using SrcElementTy =
      typename std::remove_reference<DeviceSrcTy>::type::value_type;
  using DstElementTy =
      typename std::remove_reference<DeviceDstTy>::type::value_type;
  static_assert(std::is_same<SrcElementTy, DstElementTy>::value,
                "asyncCopyDToD cannot copy between arrays of different types");
  DeviceMemorySpan<const SrcElementTy> DeviceSrcSpan(DeviceSrc);
  DeviceMemorySpan<DstElementTy> DeviceDstSpan(DeviceDst);
  if (DeviceSrcSpan.size() != DeviceDstSpan.size()) {
    setStatus(Status("asyncCopyDToD source element count " +
                     std::to_string(DeviceSrcSpan.size()) +
                     " does not equal destination element count " +
                     std::to_string(DeviceDstSpan.size())));
    return *this;
  }
  setStatus(ThePlatform->asyncCopyDToD(
      DeviceSrcSpan.baseHandle(), DeviceSrcSpan.byte_offset(),
      DeviceDstSpan.baseHandle(), DeviceDstSpan.byte_offset(),
      DeviceSrcSpan.byte_size(), TheHandle.get()));
  return *this;
}

template <typename DeviceSrcTy, typename DeviceDstTy>
Stream &Stream::asyncCopyDToD(DeviceSrcTy &&DeviceSrc, DeviceDstTy &&DeviceDst,
                              ptrdiff_t ElementCount) {
  using SrcElementTy =
      typename std::remove_reference<DeviceSrcTy>::type::value_type;
  using DstElementTy =
      typename std::remove_reference<DeviceDstTy>::type::value_type;
  static_assert(std::is_same<SrcElementTy, DstElementTy>::value,
                "asyncCopyDToD cannot copy between arrays of different types");
  DeviceMemorySpan<const SrcElementTy> DeviceSrcSpan(DeviceSrc);
  DeviceMemorySpan<DstElementTy> DeviceDstSpan(DeviceDst);
  if (DeviceSrcSpan.size() < ElementCount) {
    setStatus(Status("asyncCopyDToD source element count " +
                     std::to_string(DeviceSrcSpan.size()) +
                     " is less than requested element count " +
                     std::to_string(ElementCount)));
    return *this;
  }
  if (DeviceDstSpan.size() < ElementCount) {
    setStatus(Status("asyncCopyDToD destination element count " +
                     std::to_string(DeviceDst.size()) +
                     " is less than requested element count " +
                     std::to_string(ElementCount)));
    return *this;
  }
  setStatus(ThePlatform->asyncCopyDToD(
      DeviceSrcSpan.baseHandle(), DeviceSrcSpan.byte_offset(),
      DeviceDstSpan.baseHandle(), DeviceDstSpan.byte_offset(),
      ElementCount * sizeof(SrcElementTy), TheHandle.get()));
  return *this;
}

template <typename DeviceSrcTy, typename HostDstTy>
Stream &Stream::asyncCopyDToH(DeviceSrcTy &&DeviceSrc, HostDstTy &&HostDst) {
  using SrcElementTy =
      typename std::remove_reference<DeviceSrcTy>::type::value_type;
  DeviceMemorySpan<const SrcElementTy> DeviceSrcSpan(DeviceSrc);
  AsyncHostMemorySpan<SrcElementTy> HostDstSpan(HostDst);
  if (DeviceSrcSpan.size() != HostDstSpan.size()) {
    setStatus(Status("asyncCopyDToH source element count " +
                     std::to_string(DeviceSrcSpan.size()) +
                     " does not equal destination element count " +
                     std::to_string(HostDstSpan.size())));
    return *this;
  }
  setStatus(ThePlatform->asyncCopyDToH(
      DeviceSrcSpan.baseHandle(), DeviceSrcSpan.byte_offset(),
      HostDstSpan.data(), DeviceSrcSpan.byte_size(), TheHandle.get()));
  return *this;
}

template <typename DeviceSrcTy, typename HostDstTy>
Stream &Stream::asyncCopyDToH(DeviceSrcTy &&DeviceSrc, HostDstTy &&HostDst,
                              ptrdiff_t ElementCount) {
  using SrcElementTy =
      typename std::remove_reference<DeviceSrcTy>::type::value_type;
  DeviceMemorySpan<const SrcElementTy> DeviceSrcSpan(DeviceSrc);
  AsyncHostMemorySpan<SrcElementTy> HostDstSpan(HostDst);
  if (DeviceSrcSpan.size() < ElementCount) {
    setStatus(Status("asyncCopyDToH source element count " +
                     std::to_string(DeviceSrcSpan.size()) +
                     " is less than requested element count " +
                     std::to_string(ElementCount)));
    return *this;
  }
  if (HostDstSpan.size() < ElementCount) {
    setStatus(Status("asyncCopyDToH destination element count " +
                     std::to_string(HostDstSpan.size()) +
                     " is less than requested element count " +
                     std::to_string(ElementCount)));
    return *this;
  }
  setStatus(ThePlatform->asyncCopyDToH(
      DeviceSrcSpan.baseHandle(), DeviceSrcSpan.byte_offset(),
      HostDstSpan.data(), ElementCount * sizeof(SrcElementTy),
      TheHandle.get()));
  return *this;
}

template <typename HostSrcTy, typename DeviceDstTy>
Stream &Stream::asyncCopyHToD(HostSrcTy &&HostSrc, DeviceDstTy &&DeviceDst) {
  using DstElementTy =
      typename std::remove_reference<DeviceDstTy>::type::value_type;
  AsyncHostMemorySpan<const DstElementTy> HostSrcSpan(HostSrc);
  DeviceMemorySpan<DstElementTy> DeviceDstSpan(DeviceDst);
  if (HostSrcSpan.size() != DeviceDstSpan.size()) {
    setStatus(Status("asyncCopyHToD source element count " +
                     std::to_string(HostSrcSpan.size()) +
                     " does not equal destination element count " +
                     std::to_string(DeviceDstSpan.size())));
    return *this;
  }
  setStatus(ThePlatform->asyncCopyHToD(
      HostSrcSpan.data(), DeviceDstSpan.baseHandle(),
      DeviceDstSpan.byte_offset(), HostSrcSpan.byte_size(), TheHandle.get()));
  return *this;
}

template <typename HostSrcTy, typename DeviceDstTy>
Stream &Stream::asyncCopyHToD(HostSrcTy &&HostSrc, DeviceDstTy &DeviceDst,
                              ptrdiff_t ElementCount) {
  using DstElementTy =
      typename std::remove_reference<DeviceDstTy>::type::value_type;
  AsyncHostMemorySpan<const DstElementTy> HostSrcSpan(HostSrc);
  DeviceMemorySpan<DstElementTy> DeviceDstSpan(DeviceDst);
  if (HostSrcSpan.size() < ElementCount) {
    setStatus(Status("copyHToD source element count " +
                     std::to_string(HostSrcSpan.size()) +
                     " is less than requested element count " +
                     std::to_string(ElementCount)));
    return *this;
  }
  if (DeviceDstSpan.size() < ElementCount) {
    setStatus(Status("copyHToD destination element count " +
                     std::to_string(DeviceDstSpan.size()) +
                     " is less than requested element count " +
                     std::to_string(ElementCount)));
    return *this;
  }
  setStatus(ThePlatform->asyncCopyHToD(
      HostSrcSpan.data(), DeviceDstSpan.baseHandle(),
      DeviceDstSpan.byte_offset(), ElementCount * sizeof(DstElementTy),
      TheHandle.get()));
  return *this;
}

template <typename DeviceDstTy>
Stream &Stream::asyncMemsetD(DeviceDstTy &&DeviceDst, char ByteValue) {
  using DstElementTy =
      typename std::remove_reference<DeviceDstTy>::type::value_type;
  DeviceMemorySpan<DstElementTy> DeviceDstSpan(DeviceDst);
  setStatus(ThePlatform->asyncMemsetD(
      DeviceDstSpan.baseHandle(), DeviceDstSpan.byte_offset(),
      DeviceDstSpan.byte_size(), ByteValue, TheHandle.get()));
  return *this;
}

template <typename DeviceSrcTy, typename DeviceDstTy>
Stream &Stream::syncCopyDToD(DeviceSrcTy &&DeviceSrc, DeviceDstTy &&DeviceDst) {
  using SrcElementTy =
      typename std::remove_reference<DeviceSrcTy>::type::value_type;
  using DstElementTy =
      typename std::remove_reference<DeviceDstTy>::type::value_type;
  static_assert(std::is_same<SrcElementTy, DstElementTy>::value,
                "copyDToD cannot copy between arrays of different types");
  DeviceMemorySpan<const SrcElementTy> DeviceSrcSpan(DeviceSrc);
  DeviceMemorySpan<DstElementTy> DeviceDstSpan(DeviceDst);
  if (DeviceSrcSpan.size() != DeviceDstSpan.size()) {
    setStatus(Status("copyDToD source element count " +
                     std::to_string(DeviceSrcSpan.size()) +
                     " does not equal destination element count " +
                     std::to_string(DeviceDstSpan.size())));
    return *this;
  }
  if (setStatus(ThePlatform->asyncCopyDToD(
                    DeviceSrcSpan.baseHandle(), DeviceSrcSpan.byte_offset(),
                    DeviceDstSpan.baseHandle(), DeviceDstSpan.byte_offset(),
                    DeviceSrcSpan.byte_size(), TheHandle.get()))
          .isError()) {
    return *this;
  }
  setStatus(sync());
  return *this;
}

template <typename DeviceSrcTy, typename DeviceDstTy>
Stream &Stream::syncCopyDToD(DeviceSrcTy &&DeviceSrc, DeviceDstTy &&DeviceDst,
                             ptrdiff_t ElementCount) {
  using SrcElementTy =
      typename std::remove_reference<DeviceSrcTy>::type::value_type;
  using DstElementTy =
      typename std::remove_reference<DeviceDstTy>::type::value_type;
  static_assert(std::is_same<SrcElementTy, DstElementTy>::value,
                "copyDToD cannot copy between arrays of different types");
  DeviceMemorySpan<const SrcElementTy> DeviceSrcSpan(DeviceSrc);
  DeviceMemorySpan<DstElementTy> DeviceDstSpan(DeviceDst);
  if (DeviceSrcSpan.size() < ElementCount) {
    setStatus(Status("copyDToD source element count " +
                     std::to_string(DeviceSrcSpan.size()) +
                     " is less than requested element count " +
                     std::to_string(ElementCount)));
    return *this;
  }
  if (DeviceDstSpan.size() < ElementCount) {
    setStatus(Status("copyDToD destination element count " +
                     std::to_string(DeviceDst.size()) +
                     " is less than requested element count " +
                     std::to_string(ElementCount)));
    return *this;
  }
  if (setStatus(ThePlatform->asyncCopyDToD(
                    DeviceSrcSpan.baseHandle(), DeviceSrcSpan.byte_offset(),
                    DeviceDstSpan.baseHandle(), DeviceDstSpan.byte_offset(),
                    ElementCount * sizeof(SrcElementTy), TheHandle.get()))
          .isError()) {
    return *this;
  }
  setStatus(sync());
  return *this;
}

template <typename DeviceSrcTy, typename HostDstTy>
Stream &Stream::syncCopyDToH(DeviceSrcTy &&DeviceSrc, HostDstTy &&HostDst) {
  using SrcElementTy =
      typename std::remove_reference<DeviceSrcTy>::type::value_type;
  DeviceMemorySpan<const SrcElementTy> DeviceSrcSpan(DeviceSrc);
  Span<SrcElementTy> HostDstSpan(HostDst);
  if (DeviceSrcSpan.size() != HostDstSpan.size()) {
    setStatus(Status("copyDToH source element count " +
                     std::to_string(DeviceSrcSpan.size()) +
                     " does not equal destination element count " +
                     std::to_string(HostDstSpan.size())));
    return *this;
  }
  if (setStatus(ThePlatform->asyncCopyDToH(
                    DeviceSrcSpan.baseHandle(), DeviceSrcSpan.byte_offset(),
                    HostDstSpan.data(), DeviceSrcSpan.byte_size(),
                    TheHandle.get()))
          .isError()) {
    return *this;
  }
  setStatus(sync());
  return *this;
}

template <typename DeviceSrcTy, typename HostDstTy>
Stream &Stream::syncCopyDToH(DeviceSrcTy &&DeviceSrc, HostDstTy &&HostDst,
                             ptrdiff_t ElementCount) {
  using SrcElementTy =
      typename std::remove_reference<DeviceSrcTy>::type::value_type;
  DeviceMemorySpan<const SrcElementTy> DeviceSrcSpan(DeviceSrc);
  Span<SrcElementTy> HostDstSpan(HostDst);
  if (DeviceSrcSpan.size() < ElementCount) {
    setStatus(Status("copyDToH source element count " +
                     std::to_string(DeviceSrcSpan.size()) +
                     " is less than requested element count " +
                     std::to_string(ElementCount)));
    return *this;
  }
  if (HostDstSpan.size() < ElementCount) {
    setStatus(Status("copyDToH destination element count " +
                     std::to_string(HostDstSpan.size()) +
                     " is less than requested element count " +
                     std::to_string(ElementCount)));
    return *this;
  }
  if (setStatus(ThePlatform->asyncCopyDToH(
                    DeviceSrcSpan.baseHandle(), DeviceSrcSpan.byte_offset(),
                    HostDstSpan.data(), ElementCount * sizeof(SrcElementTy),
                    TheHandle.get()))
          .isError()) {
    return *this;
  }
  setStatus(sync());
  return *this;
}

template <typename HostSrcTy, typename DeviceDstTy>
Stream &Stream::syncCopyHToD(HostSrcTy &&HostSrc, DeviceDstTy &&DeviceDst) {
  using DstElementTy =
      typename std::remove_reference<DeviceDstTy>::type::value_type;
  Span<const DstElementTy> HostSrcSpan(HostSrc);
  DeviceMemorySpan<DstElementTy> DeviceDstSpan(DeviceDst);
  if (HostSrcSpan.size() != DeviceDstSpan.size()) {
    setStatus(Status("copyHToD source element count " +
                     std::to_string(HostSrcSpan.size()) +
                     " does not equal destination element count " +
                     std::to_string(DeviceDstSpan.size())));
    return *this;
  }
  if (setStatus(ThePlatform->asyncCopyHToD(
                    HostSrcSpan.data(), DeviceDstSpan.baseHandle(),
                    DeviceDstSpan.byte_offset(), DeviceDstSpan.byte_size(),
                    TheHandle.get()))
          .isError()) {
    return *this;
  }
  setStatus(sync());
  return *this;
}

template <typename HostSrcTy, typename DeviceDstTy>
Stream &Stream::syncCopyHToD(HostSrcTy &&HostSrc, DeviceDstTy &DeviceDst,
                             ptrdiff_t ElementCount) {
  using DstElementTy =
      typename std::remove_reference<DeviceDstTy>::type::value_type;
  Span<const DstElementTy> HostSrcSpan(HostSrc);
  DeviceMemorySpan<DstElementTy> DeviceDstSpan(DeviceDst);
  if (HostSrcSpan.size() < ElementCount) {
    setStatus(Status("copyHToD source element count " +
                     std::to_string(HostSrcSpan.size()) +
                     " is less than requested element count " +
                     std::to_string(ElementCount)));
    return *this;
  }
  if (DeviceDstSpan.size() < ElementCount) {
    setStatus(Status("copyHToD destination element count " +
                     std::to_string(DeviceDstSpan.size()) +
                     " is less than requested element count " +
                     std::to_string(ElementCount)));
    return *this;
  }
  if (setStatus(ThePlatform->asyncCopyHToD(
                    HostSrcSpan.data(), DeviceDstSpan.baseHandle(),
                    DeviceDstSpan.byte_offset(),
                    ElementCount * sizeof(DstElementTy), TheHandle.get()))
          .isError()) {
    return *this;
  }
  setStatus(sync());
  return *this;
}

/// Owned device memory.
///
/// Device memory that frees itself when it goes out of scope.
template <typename ElementType> class DeviceMemory {
public:
  using element_type = ElementType;
  using index_type = std::ptrdiff_t;
  using value_type = typename std::remove_const<element_type>::type;

  DeviceMemory(const DeviceMemory &) = delete;
  DeviceMemory &operator=(const DeviceMemory &) = delete;
  DeviceMemory(DeviceMemory &&) noexcept;
  DeviceMemory &operator=(DeviceMemory &&) noexcept;
  ~DeviceMemory() = default;

  /// Gets the raw base handle for the underlying platform implementation.
  void *handle() const { return ThePointer.get(); }

  index_type length() const { return TheSize; }
  index_type size() const { return TheSize; }
  index_type byte_size() const { // NOLINT
    return TheSize * sizeof(element_type);
  }
  bool empty() const { return TheSize == 0; }

  // These conversion operators are useful for making triple-chevron kernel
  // launches more concise.
  operator element_type *() {
    return static_cast<element_type *>(ThePointer.get());
  }
  operator const element_type *() const { return ThePointer.get(); }

  /// Converts a const object to a DeviceMemorySpan of const elements.
  DeviceMemorySpan<const element_type> asSpan() const {
    return DeviceMemorySpan<const element_type>(
        ThePlatform, static_cast<const element_type *>(ThePointer.get()),
        TheSize, 0);
  }

  /// Converts an object to a DeviceMemorySpan.
  DeviceMemorySpan<element_type> asSpan() {
    return DeviceMemorySpan<element_type>(
        ThePlatform, static_cast<element_type *>(ThePointer.get()), TheSize, 0);
  }

private:
  friend class Platform;
  template <typename T> friend class DeviceMemorySpan;

  DeviceMemory(Platform *ThePlatform, void *Pointer, index_type ElementCount,
               HandleDestructor Destructor)
      : ThePlatform(ThePlatform), ThePointer(Pointer, Destructor),
        TheSize(ElementCount) {}

  Platform *ThePlatform;
  std::unique_ptr<void, HandleDestructor> ThePointer;
  ptrdiff_t TheSize;
};

template <typename T>
DeviceMemory<T>::DeviceMemory(DeviceMemory &&) noexcept = default;
template <typename T>
DeviceMemory<T> &DeviceMemory<T>::operator=(DeviceMemory &&) noexcept = default;

/// View into device memory.
///
/// Like a Span, but for device memory rather than host memory.
template <typename ElementType> class DeviceMemorySpan {
public:
  /// \name constants and types
  /// \{
  using element_type = ElementType;
  using index_type = std::ptrdiff_t;
  using pointer = element_type *;
  using reference = element_type &;
  using iterator = element_type *;
  using const_iterator = const element_type *;
  using value_type = typename std::remove_const<element_type>::type;
  /// \}

  DeviceMemorySpan()
      : ThePlatform(nullptr), TheHandle(nullptr), TheSize(0), TheOffset(0),
        TheSpanHandle(nullptr) {}

  // Intentionally implicit.
  template <typename OtherElementType>
  DeviceMemorySpan(DeviceMemorySpan<OtherElementType> &ASpan)
      : ThePlatform(ASpan.ThePlatform),
        TheHandle(static_cast<pointer>(ASpan.baseHandle())),
        TheSize(ASpan.size()), TheOffset(ASpan.offset()),
        TheSpanHandle(nullptr) {}

  // Intentionally implicit.
  template <typename OtherElementType>
  DeviceMemorySpan(DeviceMemorySpan<OtherElementType> &&ASpan)
      : ThePlatform(ASpan.ThePlatform),
        TheHandle(static_cast<pointer>(ASpan.baseHandle())),
        TheSize(ASpan.size()), TheOffset(ASpan.offset()),
        TheSpanHandle(nullptr) {}

  // Intentionally implicit.
  template <typename OtherElementType>
  DeviceMemorySpan(DeviceMemory<OtherElementType> &Memory)
      : ThePlatform(Memory.ThePlatform),
        TheHandle(static_cast<value_type *>(Memory.handle())),
        TheSize(Memory.size()), TheOffset(0), TheSpanHandle(nullptr) {}

  ~DeviceMemorySpan() {
    if (TheSpanHandle) {
      ThePlatform->rawDestroyDeviceMemorySpanHandle(
          const_cast<value_type *>(TheSpanHandle));
    }
  }

  /// \name observers
  /// \{
  index_type length() const { return TheSize; }
  index_type size() const { return TheSize; }
  index_type byte_size() const { // NOLINT
    return TheSize * sizeof(element_type);
  }
  index_type offset() const { return TheOffset; }
  index_type byte_offset() const { // NOLINT
    return TheOffset * sizeof(element_type);
  }
  bool empty() const { return TheSize == 0; }
  /// \}

  void *baseHandle() const {
    return static_cast<void *>(const_cast<value_type *>(TheHandle));
  }

  /// Casts to a host memory pointer.
  ///
  /// This is only guaranteed to make sense for the CUDA platform, where device
  /// pointers can be stored and manipulated much like host pointers. This makes
  /// it easy to do triple-chevron kernel launches in CUDA because
  /// DeviceMemorySpan values can be passed to parameters expecting regular
  /// pointers.
  ///
  /// If the CUDA platform is using unified memory, it may also be possible to
  /// dereference this pointer on the host.
  ///
  /// For platforms other than CUDA, this may return a garbage pointer.
  operator element_type *() const {
    if (!TheSpanHandle)
      TheSpanHandle = ThePlatform->getDeviceMemorySpanHandle(
          TheHandle, TheSize * sizeof(element_type),
          TheOffset * sizeof(element_type));
    return TheSpanHandle;
  }

  DeviceMemorySpan<element_type> first(index_type Count) const {
    bool Valid = Count >= 0 && Count <= TheSize;
    if (!Valid)
      std::terminate();
    return DeviceMemorySpan<element_type>(ThePlatform, TheHandle, Count,
                                          TheOffset);
  }

  DeviceMemorySpan<element_type> last(index_type Count) const {
    bool Valid = Count >= 0 && Count <= TheSize;
    if (!Valid)
      std::terminate();
    return DeviceMemorySpan<element_type>(ThePlatform, TheHandle, Count,
                                          TheOffset + TheSize - Count);
  }

  DeviceMemorySpan<element_type>
  subspan(index_type Offset, index_type Count = dynamic_extent) const {
    bool Valid =
        (Offset == 0 || (Offset > 0 && Offset <= TheSize)) &&
        (Count == dynamic_extent || (Count >= 0 && Offset + Count <= TheSize));
    if (!Valid)
      std::terminate();
    return DeviceMemorySpan<element_type>(ThePlatform, TheHandle, Count,
                                          TheOffset + Offset);
  }

private:
  template <typename T> friend class DeviceMemory;
  template <typename T> friend class DeviceMemorySpan;
  friend class Platform;

  DeviceMemorySpan(Platform *ThePlatform, pointer AHandle, index_type Size,
                   index_type Offset)
      : ThePlatform(ThePlatform), TheHandle(AHandle), TheSize(Size),
        TheOffset(Offset), TheSpanHandle(nullptr) {}

  Platform *ThePlatform;
  pointer TheHandle;
  index_type TheSize;
  index_type TheOffset;
  pointer TheSpanHandle;
};

/// Asynchronous host memory.
///
/// This memory is pinned or otherwise registered in the host memory space to
/// allow for asynchronous copies between it and device memory.
///
/// This memory unpins/unregisters itself when it goes out of scope, but does
/// not free itself.
template <typename ElementType> class AsyncHostMemory {
public:
  using value_type = ElementType;
  using remove_const_type = typename std::remove_const<ElementType>::type;

  AsyncHostMemory(const AsyncHostMemory &) = delete;
  AsyncHostMemory &operator=(const AsyncHostMemory &) = delete;
  AsyncHostMemory(AsyncHostMemory &&) noexcept;
  AsyncHostMemory &operator=(AsyncHostMemory &&) noexcept;
  ~AsyncHostMemory() = default;

  template <typename OtherElementType>
  AsyncHostMemory(AsyncHostMemory<OtherElementType> &&Other)
      : ThePointer(std::move(Other.ThePointer)),
        TheElementCount(Other.TheElementCount) {
    static_assert(
        std::is_assignable<ElementType *, OtherElementType *>::value,
        "cannot assign OtherElementType pointer to ElementType pointer type");
  }

  ElementType *data() const {
    return const_cast<ElementType *>(
        static_cast<remove_const_type *>(ThePointer.get()));
  }
  ptrdiff_t size() const { return TheElementCount; }

private:
  template <typename U> friend class AsyncHostMemory;
  friend class Platform;
  AsyncHostMemory(ElementType *Pointer, ptrdiff_t ElementCount,
                  HandleDestructor Destructor)
      : ThePointer(
            static_cast<void *>(const_cast<remove_const_type *>(Pointer)),
            Destructor),
        TheElementCount(ElementCount) {}

  std::unique_ptr<void, HandleDestructor> ThePointer;
  ptrdiff_t TheElementCount;
};

template <typename T>
AsyncHostMemory<T>::AsyncHostMemory(AsyncHostMemory &&) noexcept = default;
template <typename T>
AsyncHostMemory<T> &AsyncHostMemory<T>::
operator=(AsyncHostMemory &&) noexcept = default;

/// Owned registered host memory.
///
/// Like AsyncHostMemory, but this memory also frees itself in addition to
/// unpinning/unregistering itself when it goes out of scope.
template <typename ElementType> class OwnedAsyncHostMemory {
public:
  using remove_const_type = typename std::remove_const<ElementType>::type;

  OwnedAsyncHostMemory(const OwnedAsyncHostMemory &) = delete;
  OwnedAsyncHostMemory &operator=(const OwnedAsyncHostMemory &) = delete;
  OwnedAsyncHostMemory(OwnedAsyncHostMemory &&) noexcept;
  OwnedAsyncHostMemory &operator=(OwnedAsyncHostMemory &&) noexcept;

  ~OwnedAsyncHostMemory() {
    if (ThePointer.get()) {
      // We use placement new to construct these objects, so we have to call the
      // destructors explicitly.
      for (ptrdiff_t I = 0; I < TheElementCount; ++I)
        static_cast<ElementType *>(ThePointer.get())[I].~ElementType();
    }
  }

  ElementType *get() const {
    return const_cast<ElementType *>(
        static_cast<remove_const_type *>(ThePointer.get()));
  }

  ElementType &operator[](ptrdiff_t I) const {
    assert(I >= 0 && I < TheElementCount);
    return get()[I];
  }

private:
  template <typename T> friend class AsyncHostMemorySpan;

  friend class Platform;

  OwnedAsyncHostMemory(void *Memory, ptrdiff_t ElementCount,
                       HandleDestructor Destructor)
      : ThePointer(Memory, Destructor), TheElementCount(ElementCount) {}

  std::unique_ptr<void, HandleDestructor> ThePointer;
  ptrdiff_t TheElementCount;
};

template <typename T>
OwnedAsyncHostMemory<T>::OwnedAsyncHostMemory(
    OwnedAsyncHostMemory &&) noexcept = default;
template <typename T>
OwnedAsyncHostMemory<T> &OwnedAsyncHostMemory<T>::
operator=(OwnedAsyncHostMemory &&) noexcept = default;

/// View into registered host memory.
///
/// Like Span but for registered host memory.
template <typename ElementType> class AsyncHostMemorySpan {
public:
  /// \name constants and types
  /// \{
  using element_type = ElementType;
  using index_type = std::ptrdiff_t;
  using pointer = element_type *;
  using reference = element_type &;
  using iterator = element_type *;
  using const_iterator = const element_type *;
  using value_type = typename std::remove_const<element_type>::type;
  /// \}

  AsyncHostMemorySpan() : TheSpan() {}

  // Intentionally implicit.
  template <typename OtherElementType>
  AsyncHostMemorySpan(AsyncHostMemory<OtherElementType> &Memory)
      : TheSpan(Memory.data(), Memory.size()) {}

  // Intentionally implicit.
  template <typename OtherElementType>
  AsyncHostMemorySpan(OwnedAsyncHostMemory<OtherElementType> &Owned)
      : TheSpan(Owned.get(), Owned.TheElementCount) {}

  // Intentionally implicit.
  template <typename OtherElementType>
  AsyncHostMemorySpan(AsyncHostMemorySpan<OtherElementType> &ASpan)
      : TheSpan(ASpan) {}

  // Intentionally implicit.
  template <typename OtherElementType>
  AsyncHostMemorySpan(AsyncHostMemorySpan<OtherElementType> &&Span)
      : TheSpan(Span) {}

  /// \name observers
  /// \{
  index_type length() const { return TheSpan.length(); }
  index_type size() const { return TheSpan.size(); }
  index_type byte_size() const { // NOLINT
    return TheSpan.size() * sizeof(element_type);
  }
  bool empty() const { return TheSpan.empty(); }
  /// \}

  pointer data() const noexcept { return TheSpan.data(); }
  operator element_type *() const { return TheSpan.data(); }

  AsyncHostMemorySpan<element_type> first(index_type Count) const {
    return AsyncHostMemorySpan<element_type>(TheSpan.first(Count));
  }

  AsyncHostMemorySpan<element_type> last(index_type Count) const {
    return AsyncHostMemorySpan<element_type>(TheSpan.last(Count));
  }

  AsyncHostMemorySpan<element_type>
  subspan(index_type Offset, index_type Count = dynamic_extent) const {
    return AsyncHostMemorySpan<element_type>(TheSpan.subspan(Offset, Count));
  }

private:
  template <typename T> friend class AsyncHostMemory;

  explicit AsyncHostMemorySpan(Span<ElementType> ArraySpan)
      : TheSpan(ArraySpan) {}

  Span<ElementType> TheSpan;
};

} // namespace acxxel

#endif // ACXXEL_ACXXEL_H
