This op defines a SPIR-V module using a MLIR region. The region contains
one block. Module-level operations, including functions definitions,
are all placed in this block.
This CL extracts common definitions from SPIRVOps.td into SPIRVBase.td.
The new op is placed in SPIRVStructureOps.td.
--
PiperOrigin-RevId: 250522320
This CL adds lowering of linalg.for to LLVM IR and adds an IR test.
This also replaces the usage of affine.for with linalg.for and enables the LLVM IR path in the integration test.
--
PiperOrigin-RevId: 250503798
Region body constructors in EDSC now take a callback to the function that fills
in the body. This callback is called immediately and not stored, so it is
sufficient to pass a reference to it and avoid a potentially expensive copy.
--
PiperOrigin-RevId: 250473793
The affine.for operation has restrictions that make it suitable for dependence analysis. The Linalg dialect aims at being more general.
This CL introduces linalg.for, and its associated terminator, along with a simple roundtripping test.
A `linalg.for` only takes one value of index type for lower bound, upper bound and step.
Example usage:
```
linalg.for %iv = %lb to %ub step %step {
... // body
}
```
--
PiperOrigin-RevId: 250369722
Fix Block::splitBlock and Block::eraseFromFunction that erronously assume
blocks belong to functions. They now belong to regions. When splitting, new
blocks should be created in the same region as the existing block. When
erasing a block, it should be removed from the region rather than from the
function body that transitively contains the region.
Also rename Block::eraseFromFunction to Block::erase for consistency with other
IR containers.
--
PiperOrigin-RevId: 250278272
The original implementation did not map the return value of the intrinsics
call to the result value of the special register op. Uses of the result
value hence hit a nullpointer.
--
PiperOrigin-RevId: 250255436
The lowering from the Affine dialect to the Standard dialect was originally
implemented as a standalone pass. However, it may be used by other passes
willing to lower away some of the affine constructs as a part of their
operation. Decouple the transformation functions from the pass infrastructure
and expose the entry point for the lowering.
Also update the lowering functions to use `LogicalResult` instead of bool for
return values.
--
PiperOrigin-RevId: 250229198
Verify pattern specification, added benefit, named pattern and location recording using TestDialect. Naming is verified via explicitly adding named pattern to TestPatternDriver pass. Refactoring test to verify the desired functionality rather than generated code.
--
PiperOrigin-RevId: 250205618
Report errors using the file and line location using SourceMgr's diagnostic reporting. Reduce some horizontal white spacing too.
--
PiperOrigin-RevId: 250193646
This CL sets up the basic structure for a SPIR-V dialect: operation
definition specification, dialect registration, testing, etc.
A single op, FMul, is defined and tested to showcase.
The SPIR-V dialect aims to be a simple proxy for the SPIR-V binary format
to enable straightforward and lightweight conversion from/to the binary
format. Ops in this dialect should stay as the same semantic level and
try to be a mechanical mapping to the corresponding SPIR-V instructions;
but they can deviate representationally to allow using MLIR mechanisms.
--
PiperOrigin-RevId: 250040830
This does tracks the location by recording all the ops in the source pattern and using the fused location for the transformed op. Track the locations via the rewrite state which is a bit heavy weight, in follow up to change to matchAndRewrite this will be addressed (and need for extra array go away).
--
PiperOrigin-RevId: 249986555
Introduces a hasRank() method to make checking for rank a bit easier.
This is partially to make it easier to make MemRef subclass ShapedType
--
PiperOrigin-RevId: 249927442
*) Adds LoopFusionUtils which will expose a set of loop fusion utilities (e.g. dependence checks, fusion cost/storage reduction, loop fusion transformation) for use by loop fusion algorithms. Support for checking block-level fusion-preventing dependences is added in this CL (additional loop fusion utilities will be added in subsequent CLs).
*) Adds TestLoopFusion test pass for testing LoopFusionUtils at a fine granularity.
*) Adds unit test for testing dependence check for block-level fusion-preventing dependences.
--
PiperOrigin-RevId: 249861071
Originally, FunctionConverter::convertRegion in the DialectConversion framework
was implemented as a function template because it was creating a new region in
the parent object, which could have been an op or a function. Since
DialectConversion now operates in place, new region is no longer created so
there is no need for convertRegion to be aware of the parent, only of the error
reporting location.
--
PiperOrigin-RevId: 249826392
This better matches other container types. Seems better to do that, even though tuples are a little different, since they don't have a single element type.
Also fixed its description to mention the element type.
--
PiperOrigin-RevId: 249730341
This emphasizes that it is potentially less constrained than you might desire (especially dialects will frequently not support all bit widths), and better matches the other type names, especially the container types.
--
PiperOrigin-RevId: 249718409
This CL prepares for mixing lowering of tiled linalg operations to loops with load and store operations. In particular it is necessary to capture partial tile information in views. This CL makes slice ops during Linalg tiling properly stop at partial tile boundaries by implementing `min` with a `cmpi` and `select` over values of index type.
To be consistent with lowering to loops, the implementation of tiling also drops specifics of accessing values via ranges and instead uses ranges of the form
`[0, dim(view), 1]` for creating view slices. This simplifies the code for the implementation of tiling and utils.
This also allows removing restrictions around needing a View or SliceOp defined in the current function context (as well as all it RangeOps). The restriction removal is tested by making the dot test operate directly on views.
The above is still subject to folding of the linalg.dim operation left for a future CL.
At this time, mixing tiling and lowering to loops all the way to execution is not yet functional because affine.for does not allow arbitrarily defined values of index type as its operands.
The previously introduced linalg.range_intersection was not sufficient to capture the necessary information and still required dealing with max quantities.
A followup CL will remove linalg.range_intersection.
--
PiperOrigin-RevId: 249698823
This CL makes lowering to loops always be a:
```
%D = linalg.dim %view, constant : !linalg.view<...>
affine.for %ix = %c0 to %D {
...
}
```
This form composes correctly with tiling and is also the proper way to emit loops from views that across function boundaries.
The previous version that would extract the range_min/max/step was composing incorrectly with tiling (i.e. would shift by range_min both in the loop bounds and in the slice) and would not work across function boundaries.
The relevant tests are updated and a new test `dot_view`---which lowers to loops from views passed as function parameters---is added.
When additional context is available, the linalg.dim operations should be folded away but this is left for a future CL.
--
PiperOrigin-RevId: 249634712
* There is no longer a need to explicitly remap function attrs.
- This removes a potentially expensive call from the destructor of Function.
- This will enable some interprocedural transformations to now run intraprocedurally.
- This wasn't scalable and forces dialect defined attributes to override
a virtual function.
* Replacing a function is now a trivial operation.
* This is a necessary first step to representing functions as operations.
--
PiperOrigin-RevId: 249510802
This avoids crashing when trying to dump an operation nested in a region that isn't yet attached to an operation, which is quite useful when debugging.
This alone won't be enough to print an unlink Operation, it'll display `<<UNLINKED INSTRUCTION>>`.
--
PiperOrigin-RevId: 249496388
EDSC builder test uses FileCheck to match the IR produced by EDSC in the
textual order. For mathematical operations, EDSC relies on overloaded
operators. Since they are essentially function calls, the order of evaluation
of their operands is unspecified and differs between compilers. Do not rely on
a specific order of operands and just check they are all emitted before the
last operation. Give names to matched SSA values in order to make sure the
right operands are used in relevant places.
--
PiperOrigin-RevId: 249494995
The passed element type description is usually unnecessary, and it's just as valid to want to pass a description for the entire container. In either case there's an alternative (Separate element type def or a TypeAlias) and we don't need to pollute the main API.
To allow for this, I cleaned up the TF op definitions and added some additional utilities.
--
PiperOrigin-RevId: 249340979
Establish the following convention:
1. Container class types end in "Of" (e.g. TensorOf) and take a list of allowed types.
2. An X container where only a single type is allowed is called TypeX (e.g. I32Tensor).
3. An X container where any type is allowed is called AnyX (e.g. AnyTensor).
--
PiperOrigin-RevId: 249281018
Otherwise, GCC < 7 does not link in the dialect registration, fails to look up
the dialect in the context and cannot construct SDBM objects.
--
PiperOrigin-RevId: 249259758
MLIRContext does not have to be aware of the SDBM unique data structures
directly. Move the SDBM storage uniquer from MLIRContext to the SDBM dialect
instance. Expressions that previously required a context to be constructed now
require an instance of the dialect in order to access the uniquer. While they
could look up the dialect in the context, it would have introduced a rather
expensive lookup into each construction. Instead, the caller is expected to
obtain the dialect instance and cache it.
--
PiperOrigin-RevId: 249245199
We now have sufficient extensibility in dialects to move attribute components
such as SDBM out of the core IR into a dedicated dialect and make them
optional. Introduce an SDBM dialect and move the code. This is a mostly
non-functional change.
--
PiperOrigin-RevId: 249244802
SDBM expressions are designed as components of an attribute, similarly to
affine expressions. As such, they need to be unique'd in the MLIRContext.
When SDBM expressions were implemented, uniqu'ing objects in a context required
to modify MLIRContext implementation. This is no longer the case as generic
StorageUniquer has been introduced. Port the SDBMExpr uniqu'ing to use a newly
introduced uniquer and remove SDBM construction from MLIRContext.cpp.
--
PiperOrigin-RevId: 249244739
A couple of warnings was produced when compiling this test due to comaprisons
with a signed literal. Used unsigned literals instead.
--
PiperOrigin-RevId: 249242970
The Op Definition Generator will automatically insert the VariadicOperands
trait if an op has variadic operands or results. It already derives from
MultiOperandTraitBase.
--
PiperOrigin-RevId: 249227268
* Use `cast` rather than `dyn_cast` to get an assertion failure rather than a segfault in case of a type mismatch.
* Use stream operators to `emitOpError`s.
--
PiperOrigin-RevId: 249208135
Affine expressions are designed as components of an attribute and are unique'd
in the MLIRContext. When affine expressions were implemented, uniqu'ing
objects in a context required to modify MLIRContext implementation. This is no
longer the case as generic StorageUniquer has been introduced. Port the
AffineExpr construction to use the new infrastructure by introducing an
affineUniquer into the MLIRContext.
--
PiperOrigin-RevId: 249207539
Similarly to other value-type wrappers, the default constructor of AffineExpr
constructs a null object and removes the need for an explicit ::Null
constructor. Drop it and remove the only user which can trivially rely on the
default constructor.
--
PiperOrigin-RevId: 249207502
This adds the basic passes needed and ties them into mlir-opt. Also adds two specific unit tests that exercise them.
Next step is a standalone quantizer tool and additional cleanup.
Tested:
ninja check-mlir
--
PiperOrigin-RevId: 249167690
Using ArrayRef introduces issues with the order of evaluation between a constructor and
the arguments of the subsequent calls to the `operator()`.
As a consequence the order of captures is not well-defined can go wrong with certain compilers (e.g. gcc-6.4).
This CL fixes the issue by using lambdas in lieu of ArrayRef.
--
PiperOrigin-RevId: 249114775
Unfortunately, this now gives a segfault if you pass it an empty list, similar to stringify. Given how fiddly this is, we should probably have a string join helper. I'll fix both of these using better tablegen helpers in a follow-up.
--
PiperOrigin-RevId: 249076849
This reduces conflict between these and other type names, where we're moving towards "Of" indicating a container type containing certain types. It also better matches the "Neg" predicate modifier and generally is pretty understandable/readable for predicates.
--
PiperOrigin-RevId: 249076508
These don't have any behavior and just delegate to Type. The only references are in OpBase.td Since the tablegen type hierarchy is not realized in the generated C++ these also aren't providing value for examining the type hierarchy
--
PiperOrigin-RevId: 249073939
Previously we force the C++ namespaces to be `NS` if `SomeOp` is defined as
`NS_SomeOp`. This is too rigid as it does not support nested namespaces
well. This CL adds a "namespace" field into the Dialect class to allow
flexible namespaces.
--
PiperOrigin-RevId: 249064981
This CL adds a pass to lower out of dot,matvec,matmul etc and into a combination of affine.for, linalg.load and linalg.store operations.
Such operations can then later lowered to LLVM.
This CL essentially performs op expansion using EDSCs and factors out a few common utils from Tiling.cpp.
--
PiperOrigin-RevId: 249049518
SDBM has an output format representing the unterlying matrix and stripe
expressions. Move the SDBM tests from unit testing framework to
FileCheck-based tests, printing them to the standard output and using FileCheck
to test the output. Tests that check the API proper (e.g. that SDBM
expressions have a specific subtype) and that rely on non-syntatic properties
(equality of the set of constraints) are not ported.
--
PiperOrigin-RevId: 249006055
Originally, ExecutionEngine was created before MLIR had a proper pass
management infrastructure or an LLVM IR dialect (using the LLVM target
directly). It has been running a bunch of lowering passes to convert the input
IR from Standard+Affine dialects to LLVM IR and, later, to the LLVM IR dialect.
This is no longer necessary and is even undesirable for compilation flows that
perform their own conversion to the LLVM IR dialect. Drop this integration and
make ExecutionEngine accept only the LLVM IR dialect. Users of the
ExecutionEngine can call the relevant passes themselves.
--
PiperOrigin-RevId: 249004676
The converter now works by inserting fake producer operations when replacing the results of an existing operation with values of a different, now legal, type. These fake operations are guaranteed to never escape the converter.
--
PiperOrigin-RevId: 248969130
The current implementation makes some assumptions about what can be a shaped type, which aren't really necessary. It also has strange behavior for types that aren't in the limited set it handles (e.g. dialect-defined types)
Updated the comment to match the implementation.
This is partially motivated by the desire to make MemRef a subclass of ShapedType
--
PiperOrigin-RevId: 248859674
There was a weird mix of names, styles, and inheritance here. I think this makes it cleaner and more consistent. We can also have a more principled and far-reaching refactor of some of this naming, but this seems like a good improvement regardless
--
PiperOrigin-RevId: 248827005
This upstreams the config and constraints for a reference quantization scheme based on the FxpMathOps dialect.
There are probably two more CLs to get the rest: one with the passes/tests, and one with the tool main() itself.
--
PiperOrigin-RevId: 248817505
EDSC subsystem contains an API test which is a .cpp file calling the API in
question and producing IR. This IR is further checked using FileCheck and
should plug into lit. Provide a CMakeLists.txt to build the test and modify
the lit configuration to process the source file.
--
PiperOrigin-RevId: 248794443
Provide an "unsafe" version of the overloaded arithmetic operators for SDBM
expressions. These operators expect the operands to be of the right SDBM
expression subtype and assert if they are not. They also perform simple
folding operations as well as some semantically correct operations that
construct an SDBM expression of a different subtype, e.g., a difference
expression if the RHS of an operator+ is a negated variable. These operators
are scoped in a namespace to allow for a future "safe" version of the operators
that propagates null expressions to denote the error state when expressions
have wrong subtypes.
--
PiperOrigin-RevId: 248704153
Implement the storage class for striped difference-bound matrices (SDBM) as a
container with a difference bounds matrix and a list of stripe expressions. An
SDBM defines an integer set. Provide conversion mechanisms between lists of
SDBM expressions treated as equalities with zero or less-than-or-equal
inequalities with zero.
--
PiperOrigin-RevId: 248702871
Make it clear that it cares about the aggregate type being a vector or tensor and not just that it has a shape.
Remove redundant validation from the custom method that is now covered by the tablegen'ed verification
This is related to making MemRefs a ShapedType as well.
--
PiperOrigin-RevId: 248610443
tensor<*xf32> could be a tensor<1xf32> at runtime but this verifyShapeMatch would return failure and say function is invalid.
--
PiperOrigin-RevId: 248583038
This CL adds an operation whose purpose is to encode boundary conditions directly in the view type. In particular, full/partial tile distinction can
occur at the level of metadata only.
This CL also adopts a Linalg_Op pattern that is similar to Std_Op.
--
PiperOrigin-RevId: 248529469
This is in preparation for making it also support/be a parent class of MemRefType. MemRefs have similar shape/rank/element semantics and it would be useful to be able to use these same utilities for them.
This CL should not change any semantics and only change variables, types, string literals, and comments. In follow-up CLs I will prepare all callers to handle MemRef types or remove their dependence on ShapedType.
Discussion/Rationale in https://groups.google.com/a/tensorflow.org/forum/#!topic/mlir/cHLoyfGu8y8
--
PiperOrigin-RevId: 248476449
This adds some additional core types and utilities, notably the constraint analysis graph (CAG) structures, associated metadata and configuration policy object base class.
The CAG is not particularly memory efficient as it stands now. I had started some work to turn it into a form that could be better managed by a bump pointer allocator but abandoned that for now in favor of having something that does semantically what I was going for as a starting point.
--
PiperOrigin-RevId: 248413133
This CL performs post-commit cleanups.
It adds the ability to specify which shared libraries to load dynamically in ExecutionEngine. The linalg integration test is updated to use a shared library.
Additional minor cleanups related to LLVM lowering of Linalg are also included.
--
PiperOrigin-RevId: 248346589
This is being integrated from an experimental side repository piece by piece over the course of several patches and will ultimately include full build support, documentation and e2e tests.
--
PiperOrigin-RevId: 248259895
This CL uses a pattern proposed by aminim@ to add a base Linalg op that further dispatches to the proper op implementation.
This CL adds a LinalgOp which implements isclassof for only a subset of the linalg ops: the ops that behave like a library call for the purpose of transformations like tiling.
This uses a static dispatch mechanism based on the LinalgLibraryOps.td ops declarations to avoid switch or visitor patterns. This may later be replaced by Tablegen'd dispatch when it is available.
As a consequence, the list of library like operations in Linalg may now grow without having to modify any of the dispatch or transformation support.
More details in the concept-based dispatch, as explained by aminim@
```
This is inspired by Sean Parent's: https://sean-parent.stlab.cc/papers-and-presentations/#value-semantics-and-concept-based-polymorphism
A key difference is that the set of classes erased is statically known, which avoids to use dynamic memory allocation.
We use a zero-sized templated class to emit the virtual table and generate a singleton object for each instantiation of this class. We pay the cost of initialization once on construction (find which class to dispatch to) and then a virtual dispatch on every call.
```
--
PiperOrigin-RevId: 248258921
This CL gives a pattern-matching-y look and feel to AffineExpr.
For now this uses a shared_ptr instead of unique'ing into a bumpPtrAllocator.
SDBM gives a simple use case with more idiomatic syntax for matchers.
--
PiperOrigin-RevId: 248188075
Adding the additional layer of directory was discussed offline and matches the Target/ tree. The names match the defacto convention we seem to be following where the C++ namespace is ^(.+)Ops/$ matched against the directory name.
This is in preparation for patching the Quantizer into this tree, which would have been confusing without moving the Quantization dialect to its more proper home. It is left to others to move other dialects if desired.
Tested:
ninja check-mlir
--
PiperOrigin-RevId: 248171982
Example:
/tmp/file_C.py:21:5: error: 'foo.bar' op attribute 'something'
raise app.UsageError('Too many command-line arguments.')
^
/tmp/file_D.py:20:3: note: called from
if len(argv) > 1:
^
/tmp/file_E.py:19:1: note: called from
def main(argv):
^
/tmp/file_F.py:24:3: note: called from
app.run(main)
^
--
PiperOrigin-RevId: 248151212
Example:
/tmp/file_C.py:17:1: error: 'foo.bar' op attribute 'something' ...
app.run(main)
^
/tmp/file_D.py:14:1: note: called from
raise app.UsageError('Too many command-line arguments.')
^
/tmp/file_E.py:12:1: note: called from
def main(argv):
^
/tmp/file_F.py:13:1: note: called from
if len(argv) > 1:
^
--
PiperOrigin-RevId: 248074804
A linalg.dim operation is used to extract size information from !linalg.view objects passed
through function call boundaries.
--
PiperOrigin-RevId: 248017488
This CL turns the previous "Op Definition" doc into a manual for table-driven
op definition specification by fleshing out more details of existing mechanisms.
--
PiperOrigin-RevId: 248013274
This means that we can now do something like:
ctx->getRegisteredDialect<LLVMDialect>();
as opposed to:
static_cast<LLVMDialect *>(ctx->getRegisteredDialect("llvm");
--
PiperOrigin-RevId: 247989896
This CL extends the execution engine to allow the additional resolution of symbols names
that have been registered explicitly. This allows linking static library symbols that have not been explicitly exported with the -rdynamic linking flag (which is deemed too intrusive).
--
PiperOrigin-RevId: 247969504
Restructure the Regions section in LangRef to avoid having a wall of text and
reflect a recent evolution of the design. Unspecify region types, that are put
on hold until use cases arise.
Update the Rationale doc with a list of design decisions related to regions.
Separately list the design alternatives that were considered and discarded due
to the lack of existing use cases.
--
PiperOrigin-RevId: 247943144
generates remarks for testing, it isn't itself a transformation.
While there, upgrade its diagnostic emission to use the streaming interface.
Prune some unnecessary #includes.
--
PiperOrigin-RevId: 247768062
OSS build was broken (missing CMakeLists.txt changes and compilation failures on Ubuntu)
Automated rollback of changelist 247564213.
PiperOrigin-RevId: 247713812
This is intended to fix a GCC warning:
> mlir/lib/IR/LocationDetail.h:32:25: warning: ‘mlir::detail::LocationStorage::kind’ is too small to hold all values of ‘enum class mlir::Location::Kind’
--
PiperOrigin-RevId: 247672213
If the attribute needs to exist for the validity of the op, then no need to use
dyn_cast_or_null as the op would be invalid in the cases where cast fails, so
just use cast.
--
PiperOrigin-RevId: 247617696
This CL orders the python tests to:
1. allow introspecting on the EdscTest class and avoid the error-prone process of having to add the test call by hand;
2. account for differences in the order of `dir(edscTest)` between python2, <= python3.5 and >= python 3.6
--
PiperOrigin-RevId: 247609687
The previous approach is too restrictive; we end up forbidding all dialect-specific
types as element types. Changed to not consider element types entirely.
--
PiperOrigin-RevId: 247486537
This CL adds support for functions in the Linalg dialect to run with mlir-cpu-runner.
For this purpose, this CL adds BufferAllocOp, BufferDeallocOp, LoadOp and StoreOp to the Linalg dialect as well as their lowering to LLVM. To avoid collisions with mlir::LoadOp/StoreOp (which should really become mlir::affine::LoadOp/StoreOp), the mlir::linalg namespace is added.
The execution uses a dummy linalg_dot function that just returns for now. In the future a proper library call will be used.
--
PiperOrigin-RevId: 247476061
Historically, the conversion from standard and built-in types to the LLVM IR
dialect types was performed by a dedicated class, TypeConverter. This class
served to contain references to the LLVM IR dialect and to the LLVM IR Module
to allow querying the data layout. Recently, the LLVMLowering class was
introduced to make the conversion to the LLVM IR dialect extensible to other
source dialects. This class also includes the references to the LLVM IR
dialect and module. TypeConverter was extended with basic support for
dialect-specific type conversion through callbacks. This is not sufficient in
cases where dialect-specific types appear inside other types, such as function
or container types.
Integrate TypeConverter into LLVMLowering. Whenever a subtype needs to be
converted during standard type conversion (e.g. an argument or a result of a
FunctionType), the conversion will call to the virtual function
`LLVMLowering::convertType`, which can be extended to support dialect-specific
types.
Provide a new LLVMOpConversion class that serves as a base class for all
conversions to the LLVM IR dialect and gives them access to LLVMLowering for
the purpose of type conversion. Update Linalg to LLVM IR lowering to use this
class.
--
PiperOrigin-RevId: 247407314
The string was referenced but not captured in the lambda, which causes
a failure when compiling with MSVC.
This issue was discovered by @loic-joly-sonarsource with a proposed fix
in https://github.com/tensorflow/mlir/pull/22.
--
PiperOrigin-RevId: 247085897
This closely mirrors the llvm fcmp instruction, defining 16 different predicates
Constant folding is unsupported for NaN and Inf because there's no way to represent those as constants at the moment
--
PiperOrigin-RevId: 246932358
`#` alias `=` attribute-value
This also allows for dialects to define aliases for attributes in the AsmPrinter. The printer supports two types of attribute aliases, 'direct' and 'kind'.
* Direct aliases are synonymous with the current support for type aliases, i.e. this maps an alias to a specific instance of an attribute.
// A direct alias ("foo_str") for the string attribute "foo".
#foo_str = "foo"
* Kind aliases generates unique names for all instances of a given attribute kind. The generated aliases are of the form: `alias[0-9]+`.
// A kind alias ("strattr") for all string attributes could generate.
#strattr0 = "foo"
#strattr1 = "bar"
...
#strattrN = "baz"
--
PiperOrigin-RevId: 246851916