[Tosa] Add tosa-to-linalg-pipeline for testing (#69997)

Add tosa-to-linalg-pipeline that calls the function
addTosaToLinalgPasses, so it gets tested in core

also added tests in tosa-to-linalg-pipeline.mlir

Signed-off-by: Tai Ly <tai.ly@arm.com>
This commit is contained in:
Tai Ly
2023-10-26 14:41:37 -05:00
committed by GitHub
parent 92b4e05494
commit cfc922fc5a
6 changed files with 80 additions and 7 deletions

View File

@@ -388,8 +388,8 @@ def ConvertFuncToLLVMPass : Pass<"convert-func-to-llvm", "ModuleOp"> {
already present in the IR will be kept as is.
An LLVM datalayout string can be attached as an attribute to the module on
which the pass anchors. Such an attribute is attached by calling the
set-module-datalayout pass. If present, an llvm::DataLayout object is
which the pass anchors. Such an attribute is attached by calling the
set-module-datalayout pass. If present, an llvm::DataLayout object is
created from this attribute and used in the conversion to LLVM.
#### Output IR
@@ -816,12 +816,12 @@ def ConvertMemRefToSPIRV : Pass<"convert-memref-to-spirv"> {
def ConvertNVVMToLLVMPass : Pass<"convert-nvvm-to-llvm"> {
let summary = "Convert NVVM to PTX with Inline Assembly in LLVM dialect";
let description = [{
This pass generates PTX instructions using inline assembly for NVVM
This pass generates PTX instructions using inline assembly for NVVM
operations implements `BasicPtxBuilderInterface`.
}];
let dependentDialects = [
"NVVM::NVVMDialect",
];
];
}
//===----------------------------------------------------------------------===//

View File

@@ -38,6 +38,10 @@ void addTosaToLinalgPasses(
tosa::TosaValidationOptions const &validationOptions = {
tosa::TosaProfileEnum::Undefined, false, tosa::TosaLevelEnum::None});
/// Populates TOSA to linalg pipelines
/// Currently, this includes only the "tosa-to-linalg-pipeline".
void registerTosaToLinalgPipelines();
/// Populates conversion passes from TOSA dialect to Linalg dialect.
void populateTosaToLinalgConversionPatterns(RewritePatternSet *patterns);

View File

@@ -88,6 +88,7 @@ inline void registerAllPasses() {
// Dialect pipelines
bufferization::registerBufferizationPipelines();
sparse_tensor::registerSparseTensorPipelines();
tosa::registerTosaToLinalgPipelines();
}
} // namespace mlir

View File

@@ -90,7 +90,26 @@ void mlir::tosa::addTosaToLinalgPasses(
pm.addNestedPass<func::FuncOp>(tosa::createTosaLayerwiseConstantFoldPass(
{options.aggressiveReduceConstant}));
pm.addNestedPass<func::FuncOp>(tosa::createTosaMakeBroadcastablePass());
pm.addNestedPass<mlir::ModuleOp>(
tosa::createTosaValidation(validationOptions));
pm.addPass(tosa::createTosaValidation(validationOptions));
pm.addNestedPass<func::FuncOp>(tosa::createTosaToLinalg());
}
//===----------------------------------------------------------------------===//
// Pipeline registration.
//===----------------------------------------------------------------------===//
void mlir::tosa::registerTosaToLinalgPipelines() {
PassPipelineRegistration<>(
"tosa-to-linalg-pipeline",
"The default pipeline for converting TOSA operators to the equivalent "
"operations using the tensor operations in LinAlg as well as LinAlg "
"named operations.",
[](OpPassManager &pm) {
TosaToLinalgOptions tosaToLinalgOptions;
tosa::addTosaToLinalgPasses(pm, tosaToLinalgOptions,
/* validationOptions = */
{tosa::TosaProfileEnum::BaseInference,
/* StrictOperationSpecAlignment = */ true,
tosa::TosaLevelEnum::EightK});
});
}

View File

@@ -15,7 +15,6 @@
#include "mlir/Dialect/Tosa/Transforms/PassesEnums.cpp.inc"
#include <string>
#include <unordered_map>
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/Tosa/IR/TosaOps.h"

View File

@@ -0,0 +1,50 @@
// RUN: mlir-opt %s --split-input-file --tosa-to-linalg-pipeline -verify-diagnostics
// -----
// check that -tosa-validate of stateful ops kick in
func.func @test_variable_write_shape(%arg0: tensor<1x4x8xi32>) -> () {
tosa.variable @stored_var = dense<-1> : tensor<2x4x8xi32>
// expected-error@+1 {{'tosa.variable.write' op operand type does not equal variable type}}
tosa.variable.write @stored_var, %arg0 : tensor<1x4x8xi32>
return
}
// -----
// check that -tosa-validate level checking kick in
func.func @tensor_with_unknown_rank(%arg0: tensor<*xi8>) -> tensor<*xi8> {
// expected-error@+1 {{'tosa.abs' op failed level check: unranked tensor}}
%0 = "tosa.abs"(%arg0) : (tensor<*xi8>) -> tensor<*xi8>
return %0 : tensor<*xi8>
}
// -----
// check that tosa verify kick in
func.func @test_avg_pool2d_zero_dim_input(%arg0: tensor<1x0x?x9xf32>) -> tensor<1x7x7x9xf32> {
// expected-error@+1 {{'tosa.avg_pool2d' op tensor has a dimension with size zero. Each dimension of a tensor must have size >= 1}}
%0 = "tosa.avg_pool2d"(%arg0) {acc_type = f32, kernel = array<i64: 2, 2>, pad = array<i64: 0, 1, 0, 1>, stride = array<i64: 1, 1>}
: (tensor<1x0x?x9xf32>) -> tensor<1x7x7x9xf32>
return %0 : tensor<1x7x7x9xf32>
}
// -----
// check that --tosa-to-linalg kick in
func.func @avg_pool2d_with_unsupported_quant_type(%arg0: tensor<1x7x7x9x!quant.uniform<i8:f32, 0.01>>) -> tensor<1x7x7x9x!quant.uniform<i8:f32, 0.01>> {
// expected-error@+1 {{failed to legalize operation 'tosa.avg_pool2d'}}
%0 = "tosa.avg_pool2d"(%arg0) {acc_type = i32, kernel = array<i64: 2, 2>, pad = array<i64: 0, 1, 0, 1>, stride = array<i64: 1, 1>} : (tensor<1x7x7x9x!quant.uniform<i8:f32, 0.01>>) -> tensor<1x7x7x9x!quant.uniform<i8:f32, 0.01>>
return %0 : tensor<1x7x7x9x!quant.uniform<i8:f32, 0.01>>
}
// -----
// check that --tosa-validate=strict-op-spec-alignment does not kick in because tosa-to-linalg-named comes before tosa-validate
// this would have failed tosa strict-op-spec-alignment because perms of transpose is not constant
// but tosa.transpose is lowered by tosa-to-linalg-named pass which is earlier than tosa-validate pass in the pipeline
func.func @test_transpose_non_const(%arg0: tensor<13x21x3xf32>, %arg1: tensor<3xi32>) -> tensor<3x13x21xf32> {
%0 = tosa.transpose %arg0, %arg1 : (tensor<13x21x3xf32>, tensor<3xi32>) -> tensor<3x13x21xf32>
return %0 : tensor<3x13x21xf32>
}