torch-mlir/include/npcomp/Dialect/Npcomprt/IR/NpcomprtOps.td

116 lines
3.8 KiB
TableGen
Raw Normal View History

Rework e2e flow to use new "npcomprt" This ~totally reworks the existing "runtime" stuff to be more principled and usable, such as from Python. It's still not fully production-quality, mainly in the department of memory management (e.g. it currently leaks memory; we need to figure out "who frees memrefs" + the analysis and transformation needed to do that (maybe use upstream buffer allocation pass?)). The user API is in include/npcomp/runtime/UserAPI.h, though include/npcomp/JITRuntime/JITModule.h is a friendlier wrapper. The stuff under {include,lib}/runtime is totally firewalled from the compiler and tiny (<6kB, though no attention has gone into optimizing that size). For example, we don't link in libSupport into the runtime, instead having our own bare bones replacements for basics like ArrayRef (the JITRuntime helps with bridging that gap, since it *can* depend on all common LLVM utilities). The overall features of npcomprt is that it exposes a module that with multiple function entry points. Each function has arguments and results that are tensor-valued, and npcomprt::Tensor is the runtime type that is used to interact with that (and a npcomprt::Ref<T> reference-counting wrapper is provided to wrap npcomprt::Tensor in the common case). From an implementation perspective, an npcomprt module at the LLVM/object/binary level exposes a single module descriptor struct that has pointers to other metadata (currently just a list of function metadata descriptors). All interactions with the npcomp runtime are keyed off of that module descriptor, including function lookups and dispatching. This is done to dodge platform ABI issues and also allow enough reflection to e.g. verify provided arguments. Most of the compiler-side work here was in LowerToNpcomprtABI and LowerToLLVM. Also, - Rename npcomp_rt/NpcompRt to npcomprt/Npcomprt; it was getting annoying to type the underscores/caps. - misc improvements to bash_helpers.sh
2020-07-09 08:15:40 +08:00
//===-------------------------------------------------------*- tablegen -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef NPCOMPRT_OPS
#define NPCOMPRT_OPS
include "npcomp/Dialect/Npcomprt/IR/NpcomprtBase.td"
class Npcomprt_Op<string mnemonic, list<OpTrait> traits = []>
: Op<Npcomprt_Dialect, mnemonic, traits> {
}
def Npcomprt_ToMemrefOp : Npcomprt_Op<"to_memref"> {
let summary = "Gets a memref descriptor from a tensor";
let description = [{
Gets a memref descriptor from a tensor.
}];
let arguments = (ins Npcomprt_Tensor:$tensor);
let results = (outs AnyUnrankedMemRef:$memref);
let assemblyFormat = "$tensor attr-dict `:` type($memref)";
}
def Npcomprt_FromMemrefOp : Npcomprt_Op<"from_memref"> {
let summary = "Converts a memref descriptor to a tensor";
let description = [{
Copies the data from a memref into a new tensor.
}];
let arguments = (ins AnyUnrankedMemRef:$memref);
let results = (outs Npcomprt_Tensor:$tensor);
let assemblyFormat = "$memref attr-dict `:` type($memref)";
}
def Npcomprt_GetExtentOp : Npcomprt_Op<"get_extent"> {
let summary = "Gets the specified extent of the tensor";
let description = [{
Gets the `dim`'th extent of the tensor.
}];
let arguments = (ins Npcomprt_Tensor:$tensor, I32:$dim);
// TODO: Use i32 instead of index so the runtime function
// can return std::int32_t.
let results = (outs Index:$extent);
let assemblyFormat = "$tensor `,` $dim attr-dict";
}
def Npcomprt_AbortIfOp : Npcomprt_Op<"abort_if"> {
let summary = "Aborts if the predicate is true";
let description = [{
Aborts if the predicate is true.
}];
let arguments = (ins I1:$pred);
let results = (outs);
let assemblyFormat = "$pred attr-dict";
}
def Npcomprt_ModuleMetadataOp : Npcomprt_Op<"module_metadata", [
SingleBlockImplicitTerminator<"ModuleMetadataTerminatorOp">
]> {
let summary = "Global metadata for the module";
let description = [{
This op contains a region containing npcomprt.func_metadata ops,
which give information about the functions in the module. This allows
the module to be introspected when it is loaded, such as looking up
functions.
Future uses are checking how many results functions should have, or
what their argument types are expected to be to provide clean and safe
errors when invocations fail.
TODO: Verify that there should be no more than one of these ops in a
module.
This op is designed to hold a region, which makes it easy to convert to
a single LLVM global with a single conversion pattern.
}];
let arguments = (ins);
let results = (outs);
let regions = (region SizedRegion<1>:$metadatas);
let printer = [{ return ::print$cppClass(p, *this); }];
let parser = [{ return ::parse$cppClass(parser, result); }];
}
def Npcomprt_ModuleMetadataTerminatorOp
: Npcomprt_Op<"module_metadata_terminator",
[Terminator, HasParent<"ModuleMetadataOp">]> {
let summary = "Implicit terminator for ModuleMetadataOp's region";
let arguments = (ins);
let results = (outs);
let assemblyFormat = "attr-dict";
}
def Npcomprt_FuncMetadataOp
: Npcomprt_Op<"func_metadata", [HasParent<"ModuleMetadataOp">]> {
let summary = "Runtime metadata for a single func";
let description = [{
Runtime metadata for a single func.
TODO: Augment this with information for type/shape checking of arguments.
}];
let arguments = (ins
FlatSymbolRefAttr:$funcName,
I32Attr:$numInputs,
I32Attr:$numOutputs
);
let results = (outs);
let assemblyFormat = "attr-dict";
let verifier = [{ return ::verify(*this); }];
}
#endif // #ifndef NPCOMPRT_OPS