[Mlir-commits] [mlir] 28a45d5 - Create the framework and testing environment for MLIR Reduce - a tool

Mauricio Sifontes llvmlistbot at llvm.org
Mon Jul 6 18:59:54 PDT 2020


Author: Mauricio Sifontes
Date: 2020-07-07T01:59:11Z
New Revision: 28a45d54a7fe722248233165fc7fdbd18d18d233

URL: https://github.com/llvm/llvm-project/commit/28a45d54a7fe722248233165fc7fdbd18d18d233
DIFF: https://github.com/llvm/llvm-project/commit/28a45d54a7fe722248233165fc7fdbd18d18d233.diff

LOG: Create the framework and testing environment for MLIR Reduce - a tool
with the objective to reduce large test cases into smaller ones while
preserving their interesting behavior.

Implement the framework to parse the command line arguments, parse the
input MLIR test case into a module and call reduction passes on the MLIR module.

Implement the Tester class which allows the different reduction passes to test the
interesting behavior of the generated reduced variants of the test case and keep track
of the most reduced generated variant.

Added: 
    mlir/include/mlir/Reducer/Tester.h
    mlir/lib/Reducer/CMakeLists.txt
    mlir/lib/Reducer/Tester.cpp
    mlir/test/mlir-reduce/test.bat
    mlir/test/mlir-reduce/test.sh
    mlir/test/mlir-reduce/testcase-linux.mlir
    mlir/test/mlir-reduce/testcase-windows.mlir
    mlir/tools/mlir-reduce/CMakeLists.txt
    mlir/tools/mlir-reduce/mlir-reduce.cpp

Modified: 
    mlir/lib/CMakeLists.txt
    mlir/test/CMakeLists.txt
    mlir/tools/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Reducer/Tester.h b/mlir/include/mlir/Reducer/Tester.h
new file mode 100644
index 000000000000..8ca2a4a68765
--- /dev/null
+++ b/mlir/include/mlir/Reducer/Tester.h
@@ -0,0 +1,59 @@
+//===- Tester.h -------------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Tester class used in the MLIR Reduce tool.
+//
+// A Tester object is passed as an argument to the reduction passes and it is
+// used to keep track of the state of the reduction throughout the multiple
+// passes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_REDUCER_TESTER_H
+#define MLIR_REDUCER_TESTER_H
+
+#include <vector>
+
+#include "mlir/IR/Module.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Program.h"
+
+namespace mlir {
+
+/// This class is used to keep track of the state of the reduction. It contains
+/// a method to run the interestingness testing script on MLIR test case files
+/// and provides functionality to track the most reduced test case.
+class Tester {
+public:
+  Tester(StringRef testScript, ArrayRef<std::string> testScriptArgs);
+
+  /// Runs the interestingness testing script on a MLIR test case file. Returns
+  /// true if the interesting behavior is present in the test case or false
+  /// otherwise.
+  bool isInteresting(StringRef testCase);
+
+  /// Returns the most reduced MLIR test case module.
+  ModuleOp getMostReduced() const { return mostReduced; }
+
+  /// Updates the most reduced MLIR test case module. If a
+  /// generated variant is found to be successful and shorter than the
+  /// mostReduced module, the mostReduced module must be updated with the new
+  /// variant.
+  void setMostReduced(ModuleOp t) { mostReduced = t; }
+
+private:
+  StringRef testScript;
+  ArrayRef<std::string> testScriptArgs;
+  ModuleOp mostReduced;
+};
+
+} // end namespace mlir
+
+#endif
\ No newline at end of file

diff  --git a/mlir/lib/CMakeLists.txt b/mlir/lib/CMakeLists.txt
index c1392313faa9..be78a448e372 100644
--- a/mlir/lib/CMakeLists.txt
+++ b/mlir/lib/CMakeLists.txt
@@ -10,8 +10,9 @@ add_subdirectory(IR)
 add_subdirectory(Interfaces)
 add_subdirectory(Parser)
 add_subdirectory(Pass)
+add_subdirectory(Reducer)
 add_subdirectory(Support)
 add_subdirectory(TableGen)
 add_subdirectory(Target)
 add_subdirectory(Transforms)
-add_subdirectory(Translation)
+add_subdirectory(Translation)
\ No newline at end of file

diff  --git a/mlir/lib/Reducer/CMakeLists.txt b/mlir/lib/Reducer/CMakeLists.txt
new file mode 100644
index 000000000000..dd5fd277ce12
--- /dev/null
+++ b/mlir/lib/Reducer/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_mlir_library(MLIRReduce
+   Tester.cpp
+   DEPENDS
+   MLIRIR
+ )
+ 
+ mlir_check_all_link_libraries(MLIRReduce)
\ No newline at end of file

diff  --git a/mlir/lib/Reducer/Tester.cpp b/mlir/lib/Reducer/Tester.cpp
new file mode 100644
index 000000000000..dcfce3237cec
--- /dev/null
+++ b/mlir/lib/Reducer/Tester.cpp
@@ -0,0 +1,48 @@
+//===- Tester.cpp ---------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Tester class used in the MLIR Reduce tool.
+//
+// A Tester object is passed as an argument to the reduction passes and it is
+// used to keep track of the state of the reduction throughout the multiple
+// passes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Reducer/Tester.h"
+
+using namespace mlir;
+
+Tester::Tester(StringRef scriptName, ArrayRef<std::string> scriptArgs)
+    : testScript(scriptName), testScriptArgs(scriptArgs) {}
+
+/// Runs the interestingness testing script on a MLIR test case file. Returns
+/// true if the interesting behavior is present in the test case or false
+/// otherwise.
+bool Tester::isInteresting(StringRef testCase) {
+
+  std::vector<StringRef> testerArgs;
+  testerArgs.push_back(testCase);
+
+  for (const std::string &arg : testScriptArgs)
+    testerArgs.push_back(arg);
+
+  std::string errMsg;
+  int result = llvm::sys::ExecuteAndWait(
+      testScript, testerArgs, /*Env=*/None, /*Redirects=*/None,
+      /*SecondsToWait=*/0, /*MemoryLimit=*/0, &errMsg);
+
+  if (result < 0)
+    llvm::report_fatal_error("Error running interestingness test: " + errMsg,
+                             false);
+
+  if (!result)
+    return false;
+
+  return true;
+}

diff  --git a/mlir/test/CMakeLists.txt b/mlir/test/CMakeLists.txt
index 52756b6aae7f..7c06bd740773 100644
--- a/mlir/test/CMakeLists.txt
+++ b/mlir/test/CMakeLists.txt
@@ -38,6 +38,7 @@ set(MLIR_TEST_DEPENDS
   mlir-edsc-builder-api-test
   mlir-linalg-ods-gen
   mlir-opt
+  mlir-reduce
   mlir-sdbm-api-test
   mlir-tblgen
   mlir-translate

diff  --git a/mlir/test/mlir-reduce/test.bat b/mlir/test/mlir-reduce/test.bat
new file mode 100644
index 000000000000..4f2a4f0dbfb0
--- /dev/null
+++ b/mlir/test/mlir-reduce/test.bat
@@ -0,0 +1,4 @@
+::Replicate bug
+
+::Interesting behavior
+exit 1
\ No newline at end of file

diff  --git a/mlir/test/mlir-reduce/test.sh b/mlir/test/mlir-reduce/test.sh
new file mode 100755
index 000000000000..33d02f41a95e
--- /dev/null
+++ b/mlir/test/mlir-reduce/test.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+#Replicate bug
+
+#Interesting behavior
+exit 1
\ No newline at end of file

diff  --git a/mlir/test/mlir-reduce/testcase-linux.mlir b/mlir/test/mlir-reduce/testcase-linux.mlir
new file mode 100644
index 000000000000..f2bb161bb5a6
--- /dev/null
+++ b/mlir/test/mlir-reduce/testcase-linux.mlir
@@ -0,0 +1,13 @@
+// UNSUPPORTED: -windows-
+// RUN: mlir-reduce %s -test %S/test.sh
+
+func @simple1(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
+  cond_br %arg0, ^bb1, ^bb2
+^bb1:
+  br ^bb3(%arg1 : memref<2xf32>)
+^bb2:
+  %0 = alloc() : memref<2xf32>
+  br ^bb3(%0 : memref<2xf32>)
+^bb3(%1: memref<2xf32>):
+  return
+}
\ No newline at end of file

diff  --git a/mlir/test/mlir-reduce/testcase-windows.mlir b/mlir/test/mlir-reduce/testcase-windows.mlir
new file mode 100644
index 000000000000..f72046ee6843
--- /dev/null
+++ b/mlir/test/mlir-reduce/testcase-windows.mlir
@@ -0,0 +1,13 @@
+// UNSUPPORTED: -linux-
+// RUN: mlir-reduce %s -test %S/test.bat
+
+func @simple1(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
+  cond_br %arg0, ^bb1, ^bb2
+^bb1:
+  br ^bb3(%arg1 : memref<2xf32>)
+^bb2:
+  %0 = alloc() : memref<2xf32>
+  br ^bb3(%0 : memref<2xf32>)
+^bb3(%1: memref<2xf32>):
+  return
+}
\ No newline at end of file

diff  --git a/mlir/tools/CMakeLists.txt b/mlir/tools/CMakeLists.txt
index e8f61633c92b..23a2fcbc14eb 100644
--- a/mlir/tools/CMakeLists.txt
+++ b/mlir/tools/CMakeLists.txt
@@ -2,7 +2,8 @@ add_subdirectory(mlir-cuda-runner)
 add_subdirectory(mlir-cpu-runner)
 add_subdirectory(mlir-linalg-ods-gen)
 add_subdirectory(mlir-opt)
+add_subdirectory(mlir-reduce)
 add_subdirectory(mlir-rocm-runner)
-add_subdirectory(mlir-translate)
-add_subdirectory(mlir-vulkan-runner)
 add_subdirectory(mlir-shlib)
+add_subdirectory(mlir-translate)
+add_subdirectory(mlir-vulkan-runner)
\ No newline at end of file

diff  --git a/mlir/tools/mlir-reduce/CMakeLists.txt b/mlir/tools/mlir-reduce/CMakeLists.txt
new file mode 100644
index 000000000000..642c5d96c215
--- /dev/null
+++ b/mlir/tools/mlir-reduce/CMakeLists.txt
@@ -0,0 +1,41 @@
+get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
+get_property(conversion_libs GLOBAL PROPERTY MLIR_CONVERSION_LIBS)
+set(LLVM_LINK_COMPONENTS
+  AllTargetsAsmParsers
+  AllTargetsCodeGens
+  AllTargetsDescs
+  AllTargetsInfos
+  AsmParser
+  Core
+  IRReader
+  Support
+  Target
+  TransformUtils
+  )
+
+set(LIBS
+  ${dialect_libs}
+  ${conversion_libs}
+  ${test_libs}
+  MLIRAnalysis
+  MLIRDialect
+  MLIREDSC
+  MLIRIR
+  MLIRLoopAnalysis
+  MLIROptLib
+  MLIRParser
+  MLIRPass
+  MLIRReduce
+  MLIRSupport
+  MLIRTransforms
+  MLIRTransformUtils
+  )
+
+add_llvm_tool(mlir-reduce
+  mlir-reduce.cpp
+  )
+
+target_link_libraries(mlir-reduce PRIVATE ${LIBS})
+llvm_update_compile_flags(mlir-reduce)
+
+mlir_check_all_link_libraries(mlir-reduce)
\ No newline at end of file

diff  --git a/mlir/tools/mlir-reduce/mlir-reduce.cpp b/mlir/tools/mlir-reduce/mlir-reduce.cpp
new file mode 100644
index 000000000000..3edef61f1d72
--- /dev/null
+++ b/mlir/tools/mlir-reduce/mlir-reduce.cpp
@@ -0,0 +1,97 @@
+//===- mlir-reduce.cpp - The MLIR reducer ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the general framework of the MLIR reducer tool. It
+// parses the command line arguments, parses the initial MLIR test case and sets
+// up the testing environment. It  outputs the most reduced test case variant
+// after executing the reduction passes.
+//
+//===----------------------------------------------------------------------===//
+
+#include <vector>
+
+#include "mlir/InitAllDialects.h"
+#include "mlir/Parser.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Pass/PassManager.h"
+#include "mlir/Reducer/Tester.h"
+#include "mlir/Support/FileUtilities.h"
+#include "mlir/Support/LogicalResult.h"
+#include "mlir/Transforms/Passes.h"
+#include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/ToolOutputFile.h"
+
+using namespace mlir;
+
+static llvm::cl::opt<std::string> inputFilename(llvm::cl::Positional,
+                                                llvm::cl::Required,
+                                                llvm::cl::desc("<input file>"));
+
+static llvm::cl::opt<std::string>
+    testFilename("test", llvm::cl::Required, llvm::cl::desc("Testing script"));
+
+static llvm::cl::list<std::string>
+    testArguments("test-args", llvm::cl::ZeroOrMore,
+                  llvm::cl::desc("Testing script arguments"));
+
+static llvm::cl::opt<std::string>
+    outputFilename("o",
+                   llvm::cl::desc("Output filename for the reduced test case"),
+                   llvm::cl::init("-"));
+
+// Parse and verify the input MLIR file.
+static LogicalResult loadModule(MLIRContext &context, OwningModuleRef &module,
+                                StringRef inputFilename) {
+  module = parseSourceFile(inputFilename, &context);
+  if (!module)
+    return failure();
+
+  return success();
+}
+
+int main(int argc, char **argv) {
+
+  llvm::InitLLVM y(argc, argv);
+
+  registerAllDialects();
+  registerMLIRContextCLOptions();
+  registerPassManagerCLOptions();
+
+  llvm::cl::ParseCommandLineOptions(argc, argv,
+                                    "MLIR test case reduction tool.\n");
+
+  std::string errorMessage;
+
+  auto testscript = openInputFile(testFilename, &errorMessage);
+  if (!testscript)
+    llvm::report_fatal_error(errorMessage);
+
+  auto output = openOutputFile(outputFilename, &errorMessage);
+  if (!output)
+    llvm::report_fatal_error(errorMessage);
+
+  mlir::MLIRContext context;
+  mlir::OwningModuleRef moduleRef;
+  context.allowUnregisteredDialects(true);
+
+  if (failed(loadModule(context, moduleRef, inputFilename)))
+    llvm::report_fatal_error("Input test case can't be parsed");
+
+  // Initialize test environment.
+  Tester test(testFilename, testArguments);
+  test.setMostReduced(moduleRef.get());
+
+  if (!test.isInteresting(inputFilename))
+    llvm::report_fatal_error(
+        "Input test case does not exhibit interesting behavior");
+
+  test.getMostReduced().print(output->os());
+  output->keep();
+
+  return 0;
+}
\ No newline at end of file


        


More information about the Mlir-commits mailing list