// Copyright 2012 Google Inc. All Rights Reserved.
// Author: martint@google.com (Martin Thuresson)

#include "third_party/open64_libacml_mv/acml_trace.h"

#include <math.h>
#include <stdio.h>

#include <memory>
#include <vector>

#include "base/commandlineflags.h"
#include "base/examine_stack.h"
#include "base/googleinit.h"
#include "base/init_google.h"
#include "base/logging.h"
#include "file/base/file.h"
#include "file/base/path.h"
#include "testing/base/public/benchmark.h"
#include "testing/base/public/googletest.h"
#include "testing/base/public/gunit.h"
#include "third_party/open64_libacml_mv/libacml.h"


int main(int argc, char** argv) {
  InitGoogle(argv[0], &argc, &argv, true);
  RunSpecifiedBenchmarks();
  return RUN_ALL_TESTS();
}


// Compare two doubles given a maximum unit of least precision (ULP).
bool AlmostEqualDoubleUlps(double A, double B, int64 maxUlps) {
  CHECK_EQ(sizeof(A), sizeof(maxUlps));
  if (A == B)
    return true;
  int64 intDiff = std::abs(*(reinterpret_cast<int64*>(&A)) -
                           *(reinterpret_cast<int64*>(&B)));
  return intDiff <= maxUlps;
}

// Compare two floats given a maximum unit of least precision (ULP).
bool AlmostEqualFloatUlps(float A, float B, int32 maxUlps) {
  CHECK_EQ(sizeof(A), sizeof(maxUlps));
  if (A == B)
    return true;
  int32 intDiff = abs(*(reinterpret_cast<int32*>(&A)) -
                      *(reinterpret_cast<int32*>(&B)));
  return intDiff <= maxUlps;
}

TEST(Case, LogTest) {
  // Read trace file into memory.
  std::unique_ptr<std::vector<double>> trace(
      GetTraceDouble(file::JoinPath(FLAGS_test_srcdir,
                                    LOG_LOGFILE).c_str()));
  double d1;
  double d2;
  for (auto iter = trace->begin(); iter != trace->end(); ++iter) {
    d1 = acml_log(*iter);
    d2 = log(*iter);
    // Make sure difference is at most 1 ULP.
    EXPECT_TRUE(AlmostEqualDoubleUlps(d1, d2, 1));
  }
}

TEST(Case, ExpTest) {
  // Read trace file into memory.
  std::unique_ptr<std::vector<double>> trace(
      GetTraceDouble(file::JoinPath(FLAGS_test_srcdir,
                                    EXP_LOGFILE).c_str()));
  double d1;
  double d2;
  for (auto iter = trace->begin(); iter != trace->end(); ++iter) {
    d1 = acml_exp(*iter);
    d2 = exp(*iter);
    // Make sure difference is at most 1 ULP.
    EXPECT_TRUE(AlmostEqualDoubleUlps(d1, d2, 1));
  }
}


TEST(Case, ExpfTest) {
  // Read trace file into memory.
  std::unique_ptr<std::vector<float>> trace(
      GetTraceFloat(file::JoinPath(FLAGS_test_srcdir,
                                   EXPF_LOGFILE).c_str()));
  float f1;
  float f2;
  for (auto iter = trace->begin(); iter != trace->end(); ++iter) {
    f1 = acml_expf(*iter);
    f2 = expf(*iter);
    // Make sure difference is at most 1 ULP.
    EXPECT_TRUE(AlmostEqualFloatUlps(f1, f2, 1));
  }
}


TEST(Case, PowTest) {
  // Read trace file into memory.
  std::unique_ptr<std::vector<std::pair<double, double>>> trace(
      GetTraceDoublePair(file::JoinPath(FLAGS_test_srcdir,
                                        POW_LOGFILE).c_str()));
  double d1;
  double d2;
  for (auto iter = trace->begin(); iter != trace->end(); ++iter) {
    d1 = acml_pow((*iter).first,
                  (*iter).second);
    d2 = pow((*iter).first,
             (*iter).second);
    // Make sure difference is at most 1 ULP.
    EXPECT_TRUE(AlmostEqualDoubleUlps(d1, d2, 1));
  }
}
