// 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-vector-transfers-jit -runtime-support=$(dirname %s)/runtime-support.so | 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 TestVectorTransfers(ArrayRef<int64_t> szA, ArrayRef<int64_t> szB,
                         ArrayRef<int64_t> szVec, ArrayRef<int64_t> shA,
                         ArrayRef<int64_t> shBWr, ArrayRef<int64_t> shBRd) {
  assert(szA.size() == shA.size());
  assert(szB.size() == shBWr.size());
  assert(szB.size() == shBRd.size());
  assert(szVec.size() <= shA.size());
  assert(szVec.size() <= shBWr.size());
  assert(szVec.size() <= shBRd.size());
  ModelBuilder mb;
  // Build a func "vector_transfers".
  constexpr StringLiteral funcName = "vector_transfers";
  auto func = mb.makeFunction(funcName, {}, {},
                              MLIRFuncOpConfig().setEmitCInterface(true));
  OpBuilder b(&func.getBody());
  ScopedContext scope(b, func.getLoc());

  SmallVector<Value, 4> indicesA;
  indicesA.reserve(szA.size());
  for (auto s : shA) indicesA.push_back(std_constant_index(s));
  SmallVector<Value, 4> indicesBWr;
  indicesBWr.reserve(szB.size());
  for (auto s : shBWr) indicesBWr.push_back(std_constant_index(s));
  SmallVector<Value, 4> indicesBRd;
  indicesBRd.reserve(indicesBRd.size());
  for (auto s : shBRd) indicesBRd.push_back(std_constant_index(s));

  // clang-format off
  MLIRContext *ctx = mb.getContext();
  Value flt_0 = mb.constant_f32(0.0f);
  Value flt_1 = mb.constant_f32(1.0f);
  Value flt_42 = mb.constant_f32(42.0f);

  Value A = std_alloc(mb.getMemRefType(szA, mb.f32));
  Value B = std_alloc(mb.getMemRefType(szB, mb.f32));
  linalg_fill(A, flt_0);
  linalg_fill(B, flt_1);

  Value vFullA = vector_transfer_read(
      mb.getVectorType(szA, mb.f32),
      A,
      SmallVector<Value, 4>(szA.size(), std_constant_index(0)),
      AffineMap::getMinorIdentityMap(szA.size(), szA.size(), ctx),
      flt_42,
      ArrayAttr());
  Value vA = vector_transfer_read(
      mb.getVectorType(szVec, mb.f32),
      A,
      indicesA,
      AffineMap::getMinorIdentityMap(szA.size(), szVec.size(), ctx),
      flt_42,
      ArrayAttr());

  auto mapB = AffineMap::getMinorIdentityMap(szB.size(), szVec.size(), ctx);
  vector_transfer_write(vA, B, indicesBWr, mapB);

  Value flt_13 = std_constant_float(APFloat(13.0f), mb.f32);
  Value vFullB = vector_transfer_read(
      mb.getVectorType(szB, mb.f32),
      B,
      SmallVector<Value, 4>(szB.size(), std_constant_index(0)),
      AffineMap::getMinorIdentityMap(szB.size(), szB.size(), ctx),
      flt_13,
      ArrayAttr());
  Value vB = vector_transfer_read(
      mb.getVectorType(szVec, mb.f32),
      B,
      indicesBRd,
      AffineMap::getMinorIdentityMap(szB.size(), szVec.size(), ctx),
      flt_13,
      ArrayAttr());

  (vector_print(vFullA));
  (vector_print(vA));
  (vector_print(vFullB));
  (vector_print(vB));

  (std_dealloc(A));
  (std_dealloc(B));
  std_ret();
  // clang-format on

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

  // Call the funcOp.
  auto err = runner.invoke(funcName);
  if (err) llvm_unreachable("Error running function.");
}

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

  // A[5]
  // CHECK: ( 0, 0, 0, 0, 0 )
  // Load v4 from A[5]@{3:7} with 42 padding
  // CHECK: ( 0, 0, 42, 42 )
  // Store v4 into B[6]@{1:5}
  // CHECK: ( 1, 0, 0, 42, 42, 1 )
  // Load v4 from B[6]@{4:8} with 13 padding
  // CHECK: ( 42, 1, 13, 13 )
  TestVectorTransfers(
      /*szA=*/{5}, /*szB=*/{6}, /*szVec=*/{4}, /*shA=*/{3}, /*shBWr=*/{1},
      /*shBRd=*/{4});

  // A[5]
  // CHECK: ( 0, 0, 0, 0, 0 )
  // Load v4 from A[5]@{3:7} with 42 padding
  // CHECK: ( 0, 0, 42, 42 )
  // Store v4 into B[7]@{4:8} don't write out of bounds
  // CHECK: ( 1, 1, 1, 1, 0, 0, 42 )
  // Load v4 from B[7]@{5:9} with 13 padding
  // CHECK: ( 0, 42,  13, 13 )
  TestVectorTransfers(
      /*szA=*/{5}, /*szB=*/{7}, /*szVec=*/{4}, /*shA=*/{3}, /*shBWr=*/{4},
      /*shBRd=*/{5});

  // A[2][5]
  //      CHECK: ( ( 0, 0, 0, 0, 0 ), ( 0, 0, 0, 0, 0 ), ( 0, 0, 0, 0, 0 ),
  // CHECK-SAME: ( 0, 0, 0, 0, 0 ) )
  // Load v4 from A[4][5]@{3:3}{3:7} with 42 padding
  // CHECK: ( 0, 0, 42, 42 )
  // Store v4 into B[6]@{1:5}
  // CHECK: ( 1, 0, 0, 42, 42, 1 )
  // Load v4 from B[6]@{3:7} with 13 padding
  // CHECK: ( 42, 42, 1, 13 )
  TestVectorTransfers(
      /*szA=*/{4, 5}, /*szB=*/{6}, /*szVec=*/{4}, /*shA=*/{3, 3}, /*shBWr=*/{1},
      /*shBRd=*/{3});

  // A[3][4]
  //      CHECK: ( ( 0, 0, 0, 0 ), ( 0, 0, 0, 0 ), ( 0, 0, 0, 0 ) )
  // Load v2x3 from A[3][4]@{2:4}{3:6} with 42 padding
  //      CHECK: ( ( 0, 42, 42 ), ( 42, 42, 42 ) )
  // Store v2x3 into B[4][5]@{1:3}{3:6}
  //      CHECK: ( ( 1, 1, 1, 1, 1 ), ( 1, 1, 1, 0, 42 ),
  // CHECK-SAME: ( 1, 1, 1, 42, 42 ), ( 1, 1, 1, 1, 1 ) )
  // Load v2x3 from B[4][5]@{0:2}{3:6} with 13 padding
  //      CHECK: ( ( 1, 1, 13 ), ( 0, 42, 13 ) )
  TestVectorTransfers(
      /*szA=*/{3, 4}, /*szB=*/{4, 5}, /*szVec=*/{2, 3}, /*shA=*/{2, 3},
      /*shBWr=*/{1, 3},
      /*shBRd=*/{0, 3});
}
