// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// clang-format off

// NOLINTNEXTLINE
// RUN: test-dot-prod -runtime-support=$(dirname %s)/runtime-support.so 2>&1 | IreeFileCheck %s

// clang-format on

#include "experimental/ModelBuilder/MemRefUtils.h"
#include "experimental/ModelBuilder/ModelBuilder.h"
#include "experimental/ModelBuilder/ModelRunner.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InitLLVM.h"

using namespace mlir;                    // NOLINT
using namespace mlir::edsc;              // NOLINT
using namespace mlir::edsc::intrinsics;  // NOLINT

static llvm::cl::opt<std::string> runtimeSupport(
    "runtime-support", llvm::cl::desc("Runtime support library filename"),
    llvm::cl::value_desc("filename"), llvm::cl::init("-"));

void DotProdOnVectors() {
  constexpr unsigned N = 4;

  ModelBuilder modelBuilder;
  // Build a func "dot_prod".
  constexpr StringLiteral funcName = "dot-prod";
  auto f32 = modelBuilder.f32;
  auto vectorType = modelBuilder.getVectorType(N, f32);
  auto refType = modelBuilder.getMemRefType(1, vectorType);

  auto func = modelBuilder.makeFunction(funcName, {}, {refType, refType});

  SmallVector<AffineMap, 3> accesses;
  accesses.push_back(modelBuilder.getDimIdentityMap());
  accesses.push_back(accesses[0]);
  accesses.push_back(AffineMap::get(1, 0, modelBuilder.getContext()));

  SmallVector<Attribute, 1> iterator_types;
  iterator_types.push_back(modelBuilder.getStringAttr("reduction"));

  OpBuilder b(&func.getBody());
  ScopedContext scope(b, func.getLoc());
  ValueHandle A(func.getArgument(0)), B(func.getArgument(1));
  Value zero = ValueBuilder<ConstantIndexOp>(0);
  Value A_val = std_load(A, ValueRange(zero));
  Value B_val = std_load(B, ValueRange(zero));
  Value zeroF = std_constant_float(APFloat(0.0f), f32);
  Value res_val = (vector_contract(A_val, B_val, zeroF,
                                   modelBuilder.getAffineMapArrayAttr(accesses),
                                   modelBuilder.getArrayAttr(iterator_types)));

  (vector_print(A_val));
  (vector_print(B_val));
  (vector_print(res_val));

  std_ret();

  // Compile the function, pass in runtime support library
  //    to the execution engine for vector.print.
  ModelRunner runner(modelBuilder.getModuleRef());
  runner.compile(CompilationOptions(), runtimeSupport);

  // initialize data by interoperating with the MLIR ABI by codegen.
  auto inputInit1 = [](unsigned idx, Vector1D<N, float> *ptr) {
    for (unsigned i = 0; i < N; ++i) ptr[idx][i] = 3.0 * i;
  };
  auto inputInit2 = [](unsigned idx, Vector1D<N, float> *ptr) {
    for (unsigned i = 0; i < N; ++i) ptr[idx][i] = 2.0 * i;
  };

  auto _A = makeInitializedStridedMemRefDescriptor<Vector1D<N, float>, 1>(
      {N}, inputInit1);
  auto _B = makeInitializedStridedMemRefDescriptor<Vector1D<N, float>, 1>(
      {N}, inputInit2);

  // Call the funcOp
  const std::string funAdapterName =
      (llvm::Twine("_mlir_ciface_") + funcName).str();
  auto *bufferA = _A.get();
  auto *bufferB = _B.get();
  void *args[3] = {&bufferA, &bufferB};

  // CHECK: ( 0, 3, 6, 9 )
  // CHECK: ( 0, 2, 4, 6 )
  // CHECK: 84
  auto err =
      runner.engine->invoke(funAdapterName, MutableArrayRef<void *>{args});

  if (err) llvm_unreachable("Error running function.");
}

int main(int argc, char **argv) {
  llvm::InitLLVM y(argc, argv);
  llvm::cl::ParseCommandLineOptions(argc, argv, "TestDotProd\n");
  DotProdOnVectors();
}
