// 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},
                                MLIRFuncOpConfig().setEmitCInterface(true));

  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());
  Value A = func.getArgument(0), B = func.getArgument(1);
  Value idx_0 = std_constant_index(0);
  Value A_val = std_load(A, idx_0);
  Value B_val = std_load(B, idx_0);
  Value flt_0 = std_constant_float(APFloat(0.0f), f32);
  Value res_val = (vector_contract(A_val, B_val, flt_0,
                                   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
  // CHECK: ( 0, 3, 6, 9 )
  // CHECK: ( 0, 2, 4, 6 )
  // CHECK: 84
  auto err = runner.invoke(funcName, _A, _B);

  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();
}
