//===--- acxxel_test.cpp - Tests for the Acxxel API -----------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "acxxel.h"
#include "config.h"
#include "gtest/gtest.h"

#include <chrono>
#include <condition_variable>
#include <mutex>
#include <thread>

namespace {

template <typename T, size_t N> constexpr size_t size(T (&)[N]) { return N; }

using PlatformGetter = acxxel::Expected<acxxel::Platform *> (*)();
class AcxxelTest : public ::testing::TestWithParam<PlatformGetter> {};

TEST_P(AcxxelTest, GetDeviceCount) {
  acxxel::Platform *Platform = GetParam()().takeValue();
  int DeviceCount = Platform->getDeviceCount().getValue();
  EXPECT_GE(DeviceCount, 0);
}

// Tests all the methods of a DeviceMemorySpan that was created from the asSpan
// method of a DeviceMemory object.
//
// The length is the number of elements in the span. The ElementByteSize is the
// number of bytes per element in the span.
//
// It is assumed that the input span has 10 or more elements.
template <typename SpanType>
void testFullDeviceMemorySpan(SpanType &&Span, ptrdiff_t Length,
                              ptrdiff_t ElementByteSize) {
  EXPECT_GE(Length, 10);
  EXPECT_GT(ElementByteSize, 0);

  // Full span
  EXPECT_EQ(Length, Span.length());
  EXPECT_EQ(Length, Span.size());
  EXPECT_EQ(Length * ElementByteSize, Span.byte_size());
  EXPECT_EQ(0, Span.offset());
  EXPECT_EQ(0, Span.byte_offset());
  EXPECT_FALSE(Span.empty());

  // Sub-span with first method.
  auto First2 = Span.first(2);
  EXPECT_EQ(2, First2.length());
  EXPECT_EQ(2, First2.size());
  EXPECT_EQ(2 * ElementByteSize, First2.byte_size());
  EXPECT_EQ(0, First2.offset());
  EXPECT_EQ(0, First2.byte_offset());
  EXPECT_FALSE(First2.empty());

  auto First0 = Span.first(0);
  EXPECT_EQ(0, First0.length());
  EXPECT_EQ(0, First0.size());
  EXPECT_EQ(0, First0.byte_size());
  EXPECT_EQ(0, First0.offset());
  EXPECT_EQ(0, First0.byte_offset());
  EXPECT_TRUE(First0.empty());

  // Sub-span with last method.
  auto Last2 = Span.last(2);
  EXPECT_EQ(2, Last2.length());
  EXPECT_EQ(2, Last2.size());
  EXPECT_EQ(2 * ElementByteSize, Last2.byte_size());
  EXPECT_EQ(Length - 2, Last2.offset());
  EXPECT_EQ((Length - 2) * ElementByteSize, Last2.byte_offset());
  EXPECT_FALSE(Last2.empty());

  auto Last0 = Span.last(0);
  EXPECT_EQ(0, Last0.length());
  EXPECT_EQ(0, Last0.size());
  EXPECT_EQ(0, Last0.byte_size());
  EXPECT_EQ(Length, Last0.offset());
  EXPECT_EQ(Length * ElementByteSize, Last0.byte_offset());
  EXPECT_TRUE(Last0.empty());

  // Sub-span with subspan method.
  auto Middle2 = Span.subspan(4, 2);
  EXPECT_EQ(2, Middle2.length());
  EXPECT_EQ(2, Middle2.size());
  EXPECT_EQ(2 * ElementByteSize, Middle2.byte_size());
  EXPECT_EQ(4, Middle2.offset());
  EXPECT_EQ(4 * ElementByteSize, Middle2.byte_offset());
  EXPECT_FALSE(Middle2.empty());

  auto Middle0 = Span.subspan(4, 0);
  EXPECT_EQ(0, Middle0.length());
  EXPECT_EQ(0, Middle0.size());
  EXPECT_EQ(0, Middle0.byte_size());
  EXPECT_EQ(4, Middle0.offset());
  EXPECT_EQ(4 * ElementByteSize, Middle0.byte_offset());
  EXPECT_TRUE(Middle0.empty());

  auto Subspan2AtStart = Span.subspan(0, 2);
  EXPECT_EQ(2, Subspan2AtStart.length());
  EXPECT_EQ(2, Subspan2AtStart.size());
  EXPECT_EQ(2 * ElementByteSize, Subspan2AtStart.byte_size());
  EXPECT_EQ(0, Subspan2AtStart.offset());
  EXPECT_EQ(0, Subspan2AtStart.byte_offset());
  EXPECT_FALSE(Subspan2AtStart.empty());

  auto Subspan2AtEnd = Span.subspan(Length - 2, 2);
  EXPECT_EQ(2, Subspan2AtEnd.length());
  EXPECT_EQ(2, Subspan2AtEnd.size());
  EXPECT_EQ(2 * ElementByteSize, Subspan2AtEnd.byte_size());
  EXPECT_EQ(Length - 2, Subspan2AtEnd.offset());
  EXPECT_EQ((Length - 2) * ElementByteSize, Subspan2AtEnd.byte_offset());
  EXPECT_FALSE(Subspan2AtEnd.empty());

  auto Subspan0AtStart = Span.subspan(0, 0);
  EXPECT_EQ(0, Subspan0AtStart.length());
  EXPECT_EQ(0, Subspan0AtStart.size());
  EXPECT_EQ(0, Subspan0AtStart.byte_size());
  EXPECT_EQ(0, Subspan0AtStart.offset());
  EXPECT_EQ(0, Subspan0AtStart.byte_offset());
  EXPECT_TRUE(Subspan0AtStart.empty());

  auto Subspan0AtEnd = Span.subspan(Length, 0);
  EXPECT_EQ(0, Subspan0AtEnd.length());
  EXPECT_EQ(0, Subspan0AtEnd.size());
  EXPECT_EQ(0, Subspan0AtEnd.byte_size());
  EXPECT_EQ(Length, Subspan0AtEnd.offset());
  EXPECT_EQ(Length * ElementByteSize, Subspan0AtEnd.byte_offset());
  EXPECT_TRUE(Subspan0AtEnd.empty());
}

TEST_P(AcxxelTest, DeviceMemory) {
  acxxel::Platform *Platform = GetParam()().takeValue();
  acxxel::Expected<acxxel::DeviceMemory<int>> MaybeMemory =
      Platform->mallocD<int>(10);
  EXPECT_FALSE(MaybeMemory.isError());

  // ref
  acxxel::DeviceMemory<int> &MemoryRef = MaybeMemory.getValue();
  EXPECT_EQ(10, MemoryRef.length());
  EXPECT_EQ(10, MemoryRef.size());
  EXPECT_EQ(10 * sizeof(int), static_cast<size_t>(MemoryRef.byte_size()));
  EXPECT_FALSE(MemoryRef.empty());

  // mutable span
  acxxel::DeviceMemorySpan<int> MutableSpan = MemoryRef.asSpan();
  testFullDeviceMemorySpan(MutableSpan, 10, sizeof(int));

  // const ref
  const acxxel::DeviceMemory<int> &ConstMemoryRef = MaybeMemory.getValue();
  EXPECT_EQ(10, ConstMemoryRef.length());
  EXPECT_EQ(10, ConstMemoryRef.size());
  EXPECT_EQ(10 * sizeof(int), static_cast<size_t>(ConstMemoryRef.byte_size()));
  EXPECT_FALSE(ConstMemoryRef.empty());

  // immutable span
  acxxel::DeviceMemorySpan<const int> ImmutableSpan = ConstMemoryRef.asSpan();
  testFullDeviceMemorySpan(ImmutableSpan, 10, sizeof(int));
}

TEST_P(AcxxelTest, CopyHostAndDevice) {
  acxxel::Platform *Platform = GetParam()().takeValue();
  acxxel::Stream Stream = Platform->createStream().takeValue();
  int A[] = {0, 1, 2};
  std::array<int, size(A)> B;
  acxxel::DeviceMemory<int> X = Platform->mallocD<int>(size(A)).takeValue();
  Stream.syncCopyHToD(A, X);
  Stream.syncCopyDToH(X, B);
  for (size_t I = 0; I < size(A); ++I)
    EXPECT_EQ(A[I], B[I]);
  EXPECT_FALSE(Stream.takeStatus().isError());
}

TEST_P(AcxxelTest, CopyDToD) {
  acxxel::Platform *Platform = GetParam()().takeValue();
  acxxel::Stream Stream = Platform->createStream().takeValue();
  int A[] = {0, 1, 2};
  std::array<int, size(A)> B;
  acxxel::DeviceMemory<int> X = Platform->mallocD<int>(size(A)).takeValue();
  acxxel::DeviceMemory<int> Y = Platform->mallocD<int>(size(A)).takeValue();
  Stream.syncCopyHToD(A, X);
  Stream.syncCopyDToD(X, Y);
  Stream.syncCopyDToH(Y, B);
  for (size_t I = 0; I < size(A); ++I)
    EXPECT_EQ(A[I], B[I]);
  EXPECT_FALSE(Stream.takeStatus().isError());
}

TEST_P(AcxxelTest, AsyncCopyHostAndDevice) {
  acxxel::Platform *Platform = GetParam()().takeValue();
  int A[] = {0, 1, 2};
  std::array<int, size(A)> B;
  acxxel::DeviceMemory<int> X = Platform->mallocD<int>(size(A)).takeValue();
  acxxel::Stream Stream = Platform->createStream().takeValue();
  acxxel::AsyncHostMemory<int> AsyncA =
      Platform->registerHostMem(A).takeValue();
  acxxel::AsyncHostMemory<int> AsyncB =
      Platform->registerHostMem(B).takeValue();
  EXPECT_FALSE(Stream.asyncCopyHToD(AsyncA, X).takeStatus().isError());
  EXPECT_FALSE(Stream.asyncCopyDToH(X, AsyncB).takeStatus().isError());
  EXPECT_FALSE(Stream.sync().isError());
  for (size_t I = 0; I < size(A); ++I)
    EXPECT_EQ(A[I], B[I]);
}

TEST_P(AcxxelTest, AsyncMemsetD) {
  acxxel::Platform *Platform = GetParam()().takeValue();
  constexpr size_t ArrayLength = 10;
  std::array<uint32_t, ArrayLength> Host;
  acxxel::DeviceMemory<uint32_t> X =
      Platform->mallocD<uint32_t>(ArrayLength).takeValue();
  acxxel::Stream Stream = Platform->createStream().takeValue();
  acxxel::AsyncHostMemory<uint32_t> AsyncHost =
      Platform->registerHostMem(Host).takeValue();
  EXPECT_FALSE(Stream.asyncMemsetD(X, 0x12).takeStatus().isError());
  EXPECT_FALSE(Stream.asyncCopyDToH(X, AsyncHost).takeStatus().isError());
  EXPECT_FALSE(Stream.sync().isError());
  for (size_t I = 0; I < ArrayLength; ++I)
    EXPECT_EQ(0x12121212u, Host[I]);
}

TEST_P(AcxxelTest, RegisterHostMem) {
  acxxel::Platform *Platform = GetParam()().takeValue();
  auto Data = std::unique_ptr<int[]>(new int[3]);
  acxxel::Expected<acxxel::AsyncHostMemory<const int>> MaybeAsyncHostMemory =
      Platform->registerHostMem<int>({Data.get(), 3});
  EXPECT_FALSE(MaybeAsyncHostMemory.isError())
      << MaybeAsyncHostMemory.getError().getMessage();
  acxxel::AsyncHostMemory<const int> AsyncHostMemory =
      MaybeAsyncHostMemory.takeValue();
  EXPECT_EQ(Data.get(), AsyncHostMemory.data());
  EXPECT_EQ(3, AsyncHostMemory.size());
}

struct RefCounter {
  static int Count;

  RefCounter() { ++Count; }
  ~RefCounter() { --Count; }
  RefCounter(const RefCounter &) = delete;
  RefCounter &operator=(const RefCounter &) = delete;
};

int RefCounter::Count;

TEST_P(AcxxelTest, OwnedAsyncHost) {
  acxxel::Platform *Platform = GetParam()().takeValue();
  RefCounter::Count = 0;
  {
    acxxel::OwnedAsyncHostMemory<RefCounter> A =
        Platform->newAsyncHostMem<RefCounter>(3).takeValue();
    EXPECT_EQ(3, RefCounter::Count);
  }
  EXPECT_EQ(0, RefCounter::Count);
}

TEST_P(AcxxelTest, OwnedAsyncCopyHostAndDevice) {
  acxxel::Platform *Platform = GetParam()().takeValue();
  size_t Length = 3;
  acxxel::OwnedAsyncHostMemory<int> A =
      Platform->newAsyncHostMem<int>(Length).takeValue();
  for (size_t I = 0; I < Length; ++I)
    A[I] = I;
  acxxel::OwnedAsyncHostMemory<int> B =
      Platform->newAsyncHostMem<int>(Length).takeValue();
  acxxel::DeviceMemory<int> X = Platform->mallocD<int>(Length).takeValue();
  acxxel::Stream Stream = Platform->createStream().takeValue();
  EXPECT_FALSE(Stream.asyncCopyHToD(A, X).takeStatus().isError());
  EXPECT_FALSE(Stream.asyncCopyDToH(X, B).takeStatus().isError());
  EXPECT_FALSE(Stream.sync().isError());
  for (size_t I = 0; I < Length; ++I)
    EXPECT_EQ(A[I], B[I]);
}

TEST_P(AcxxelTest, AsyncCopyDToD) {
  acxxel::Platform *Platform = GetParam()().takeValue();
  int A[] = {0, 1, 2};
  std::array<int, size(A)> B;
  acxxel::DeviceMemory<int> X = Platform->mallocD<int>(size(A)).takeValue();
  acxxel::DeviceMemory<int> Y = Platform->mallocD<int>(size(A)).takeValue();
  acxxel::Stream Stream = Platform->createStream().takeValue();
  acxxel::AsyncHostMemory<int> AsyncA =
      Platform->registerHostMem(A).takeValue();
  acxxel::AsyncHostMemory<int> AsyncB =
      Platform->registerHostMem(B).takeValue();
  EXPECT_FALSE(Stream.asyncCopyHToD(AsyncA, X).takeStatus().isError());
  EXPECT_FALSE(Stream.asyncCopyDToD(X, Y).takeStatus().isError());
  EXPECT_FALSE(Stream.asyncCopyDToH(Y, AsyncB).takeStatus().isError());
  EXPECT_FALSE(Stream.sync().isError());
  for (size_t I = 0; I < size(A); ++I)
    EXPECT_EQ(A[I], B[I]);
}

TEST_P(AcxxelTest, Stream) {
  acxxel::Platform *Platform = GetParam()().takeValue();
  acxxel::Stream Stream = Platform->createStream().takeValue();
  EXPECT_FALSE(Stream.sync().isError());
}

TEST_P(AcxxelTest, Event) {
  acxxel::Platform *Platform = GetParam()().takeValue();
  acxxel::Event Event = Platform->createEvent().takeValue();
  EXPECT_TRUE(Event.isDone());
  EXPECT_FALSE(Event.sync().isError());
}

TEST_P(AcxxelTest, RecordEventsInAStream) {
  acxxel::Platform *Platform = GetParam()().takeValue();
  acxxel::Stream Stream = Platform->createStream().takeValue();
  acxxel::Event Start = Platform->createEvent().takeValue();
  acxxel::Event End = Platform->createEvent().takeValue();
  EXPECT_FALSE(Stream.enqueueEvent(Start).takeStatus().isError());
  EXPECT_FALSE(Start.sync().isError());
  std::this_thread::sleep_for(std::chrono::milliseconds(10));
  EXPECT_FALSE(Stream.enqueueEvent(End).takeStatus().isError());
  EXPECT_FALSE(End.sync().isError());
  EXPECT_GT(End.getSecondsSince(Start).takeValue(), 0);
}

TEST_P(AcxxelTest, StreamCallback) {
  acxxel::Platform *Platform = GetParam()().takeValue();
  int Value = 0;
  acxxel::Stream Stream = Platform->createStream().takeValue();
  EXPECT_FALSE(
      Stream
          .addCallback([&Value](acxxel::Stream &, const acxxel::Status &) {
            Value = 42;
          })
          .takeStatus()
          .isError());
  EXPECT_FALSE(Stream.sync().isError());
  EXPECT_EQ(42, Value);
}

TEST_P(AcxxelTest, WaitForEventsInAStream) {
  acxxel::Platform *Platform = GetParam()().takeValue();
  acxxel::Stream Stream0 = Platform->createStream().takeValue();
  acxxel::Stream Stream1 = Platform->createStream().takeValue();
  acxxel::Event Event0 = Platform->createEvent().takeValue();
  acxxel::Event Event1 = Platform->createEvent().takeValue();

  // Thread loops on Stream0 until someone sets the GoFlag, then set the
  // MarkerFlag.

  std::mutex Mutex;
  std::condition_variable ConditionVar;
  bool GoFlag = false;
  bool MarkerFlag = false;

  EXPECT_FALSE(Stream0
                   .addCallback([&Mutex, &ConditionVar, &GoFlag, &MarkerFlag](
                       acxxel::Stream &, const acxxel::Status &) {
                     std::unique_lock<std::mutex> Lock(Mutex);
                     ConditionVar.wait(Lock,
                                       [&GoFlag] { return GoFlag == true; });
                     MarkerFlag = true;
                   })
                   .takeStatus()
                   .isError());

  // Event0 can only occur after GoFlag and MarkerFlag are set.
  EXPECT_FALSE(Stream0.enqueueEvent(Event0).takeStatus().isError());

  // Use waitOnEvent to make a callback on Stream1 wait for an event on Stream0.
  EXPECT_FALSE(Stream1.waitOnEvent(Event0).isError());
  EXPECT_FALSE(Stream1.enqueueEvent(Event1).takeStatus().isError());
  EXPECT_FALSE(Stream1
                   .addCallback([&Mutex, &MarkerFlag](acxxel::Stream &,
                                                      const acxxel::Status &) {
                     std::unique_lock<std::mutex> Lock(Mutex);
                     // This makes sure that this callback runs after the
                     // callback on Stream0.
                     EXPECT_TRUE(MarkerFlag);
                   })
                   .takeStatus()
                   .isError());

  // Allow the callback on Stream0 to set MarkerFlag and finish.
  {
    std::unique_lock<std::mutex> Lock(Mutex);
    GoFlag = true;
  }
  ConditionVar.notify_one();

  // Make sure the events have finished and that Event1 did not happen before
  // Event0.
  EXPECT_FALSE(Event0.sync().isError());
  EXPECT_FALSE(Event1.sync().isError());
  EXPECT_FALSE(Stream1.sync().isError());
}

#if defined(ACXXEL_ENABLE_CUDA) || defined(ACXXEL_ENABLE_OPENCL)
INSTANTIATE_TEST_CASE_P(BothPlatformTest, AcxxelTest,
                        ::testing::Values(
#ifdef ACXXEL_ENABLE_CUDA
                            acxxel::getCUDAPlatform
#ifdef ACXXEL_ENABLE_OPENCL
                            ,
#endif
#endif
#ifdef ACXXEL_ENABLE_OPENCL
                            acxxel::getOpenCLPlatform
#endif
                            ));
#endif

} // namespace
