mirror of https://github.com/llvm/torch-mlir
99 lines
5.0 KiB
TableGen
99 lines
5.0 KiB
TableGen
|
//===- OpInterface.td --------------------------------------*- tablegen -*-===//
|
||
|
//
|
||
|
// This file is licensed 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
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
|
||
|
include "mlir/IR/OpBase.td"
|
||
|
|
||
|
#ifndef NPCOMP_DIALECT_ATEN_IR_TORCH_OP_INTERFACES
|
||
|
#define NPCOMP_DIALECT_ATEN_IR_TORCH_OP_INTERFACES
|
||
|
|
||
|
def TorchKernelOpInterface : OpInterface<"TorchKernelOpInterface"> {
|
||
|
let description = [{
|
||
|
This interface provides metadata about ops that are isomorphic with a
|
||
|
Torch kernel call. It is implemented by both the generic torch.kernel_call
|
||
|
op and any recognized ops (i.e. in the ATen and other dialects) which
|
||
|
are transformed from it and remain isomorphic with a Torch kernel (although
|
||
|
typically with structural transformations that make them more amenable to
|
||
|
compilation).
|
||
|
|
||
|
As a reflection of the metadata that typically exists in the Torch op
|
||
|
registry (type signatures, defaults, optionality, aliasing, op name, etc),
|
||
|
it is expected that any op which implements this interface can be coerced
|
||
|
heuristically back to a call into Torch itself as needed.
|
||
|
|
||
|
Another purpose to carry this metadata is to facilitate conversions between
|
||
|
ops at this level of abstraction. Since not all information about the
|
||
|
original types and signatures is present in the ODS or MLIR types, keeping
|
||
|
it accessible makes it possible to re-assemble a complete picture.
|
||
|
}];
|
||
|
|
||
|
let methods = [
|
||
|
InterfaceMethod<"Metadata for the kernel",
|
||
|
"::mlir::NPCOMP::Torch::KernelMetadata", "getTorchKernelMetadata">,
|
||
|
];
|
||
|
}
|
||
|
|
||
|
def TorchBuildableKernelOpInterface :
|
||
|
OpInterface<"TorchBuildableKernelOpInterface"> {
|
||
|
let description = [{
|
||
|
Implemented by specific ops that can be constructed from a generic
|
||
|
torch.kernel_call op via standard conversion heuristics. When taken in
|
||
|
combination with the source op's TorchKernelOpInterface metedata, this
|
||
|
provides the additional metadata to drive the conversion to a specific
|
||
|
recognized op.
|
||
|
|
||
|
The reason that this exists is that recognized ops (as opposed to the
|
||
|
generic torch.kernel_call op) typically are formulated as befits the
|
||
|
compiler, electing to leverage several systematic transformations in the
|
||
|
conversion process from generic to the more structured forms:
|
||
|
- Differentiate between tensors and arrays when mutability semantics
|
||
|
are known. This allows most recognized ops to operate purely on
|
||
|
values, leaving operation on references to those ops/operands/results
|
||
|
that carry that semantic.
|
||
|
- A single Torch kernel may correspond to several recognized ops that
|
||
|
need to differentiate themselves based on signatures or other
|
||
|
constraints that are relevant to the compiler.
|
||
|
- Multiple Torch kernels or signatures may collapse down to a single
|
||
|
recognized op if the transformation is systematic/pervasive and can
|
||
|
be described by metadata. This is the case in at least the following
|
||
|
cases:
|
||
|
* Inplace kernels (those ending in trailing underscores) can expand
|
||
|
to the non-inplace variant of the op with additional ops for
|
||
|
loads and stores inserted as needed.
|
||
|
* "Outref" signatures (many/most ops have an alternate signature that
|
||
|
differs in the last argument, taking a Tensor to write the result
|
||
|
into). These forms can be collapsed into the non-outref form by
|
||
|
adding a trailing store.
|
||
|
* Scalar promotion. There are often dedicated variants of kernels that
|
||
|
have some of their parameters represented as scalars (for runtime
|
||
|
efficiency, presumably). There is little benefit to the compiler
|
||
|
to differentiating these forms: additional casts can be added to
|
||
|
normalize to a tensor form, and any optimizations that result from
|
||
|
the lower dimensionality should happen automatically.
|
||
|
- There may be cosmetic type tweaks that simplify the representation. For
|
||
|
example, a recognized op may elect to accept its int[] arguments as
|
||
|
a tensor instead. Casts can be inserted systematically to bridge this
|
||
|
when the metadata is known.
|
||
|
|
||
|
Ops implementing this interface, in effect, encode the structure of the
|
||
|
generic kernels that they can convert from, along with conversion hints. All
|
||
|
such implementations of the interface for a kernel can be considered and the
|
||
|
most salient chosen.
|
||
|
|
||
|
By implementing this interface, it is assumed that there are no required
|
||
|
attributes on the op, and constructing the operands and results according
|
||
|
to the metadata will result in a valid operation.
|
||
|
}];
|
||
|
|
||
|
let methods = [
|
||
|
StaticInterfaceMethod<"Gets kernel build metadata",
|
||
|
"const ::mlir::NPCOMP::Torch::BuildKernelMetadata &",
|
||
|
"getTorchBuildKernelMetadata">,
|
||
|
];
|
||
|
}
|
||
|
#endif // NPCOMP_DIALECT_ATEN_IR_TORCH_OP_INTERFACES
|