https://www.khronos.org/registry/spir-v/specs/1.0/SPIRV.html#OpTypeImage.
Add new enums to describe Image dimensionality, Image Depth, Arrayed
information, Sampling, Sampler User information, and Image format.
Doesn's support the Optional Access qualifier at this stage
Fix Enum generator for tblgen to add "_" at the beginning if the enum
starts with a number.
PiperOrigin-RevId: 254091423
* Support for 1->0 type mappings, i.e. when the argument is being removed.
* Reordering types when converting a type signature.
* Adding new inputs when converting a type signature.
This cl also lays down the initial foundation for supporting 1->N type mappings, but full support will come in a followup.
Moving forward, function signature changes will be driven by populating a SignatureConversion instance. This class contains all of the necessary information for adding/removing/remapping function signatures; e.g. addInputs, addResults, remapInputs, etc.
PiperOrigin-RevId: 254064665
These were likely added in error because of confusion about the flag when it was just called "-verify". The extra flag doesn't cause much harm, but it does make mlir-opt do more work and clutter the RUN line
PiperOrigin-RevId: 254037016
This name has caused some confusion because it suggests that it's running op verification (and that this verification isn't getting run by default).
PiperOrigin-RevId: 254035268
By default MSVC does not export any symbol and does not create a companion
.lib for a .dll. This will cause problems when trying to link against the
library.
PiperOrigin-RevId: 254033454
This is a direct modelling of SPIR-V's OpVariable. The custom assembly format
parsers/prints descriptor in a nicer way if presents. There are other common
decorations that can appear on variables like builtin, which can be supported
later.
This CL additionally deduplicates the parser/printer/verifier declaration
in op definitions by adding defaults to SPV_Op base.
by adding
PiperOrigin-RevId: 253828254
Index types integers of platform-specific bit width. They are used to index
memrefs and as loop induction variables, however they could not be obtained
from an integer until now, making it virtually impossible to express indirect
accesses (given that memrefs of indices are not allowed) or data-dependent
loops. Introduce `std.index_cast` to transform indices into integers and vice
versa. The semantics of this cast is to sign-extend when casting to a wider
integer, and to truncate when casting to a narrower integer. It belongs to
StandardOps because both types it operates on are standard types, and because
its results are likely to be used in std.load and std.store.
Introduce llvm.sext, llvm.zext and llvm.trunc operations to the LLVM dialect.
Provide the conversion of `std.index_cast` to llvm.sext or llvm.trunc,
depending on the actual bitwidth of `index` known during the conversion.
PiperOrigin-RevId: 253624100
This CL adds a generic CopyOp to Linalg and its lowering to loops.
The CopyOp supports input and output permutation maps.
When combined with tiling and allocating a new local buffer, this should provide basic support for implementing simple memory transfers with coalescing.
At the moment, lowering copies to a library call is not supported.
PiperOrigin-RevId: 253250497
This converts entire loops into threads/blocks. No check on the size of the
block or grid, or on the validity of parallelization is performed, it is under
the responsibility of the caller to strip-mine the loops and to perform the
dependence analysis before calling the conversion.
PiperOrigin-RevId: 253189268
`affine.apply` is supposed to operate on values of index types in context of
affine loops. It is possible to programmatically constuct an `affine.apply`
that takes values of other types as operands or returns them, but it would not
be parseable. Disallow such cases in the verifier.
PiperOrigin-RevId: 253021704
This terminator operation should appear at the end of the blocks in the body
region of `gpu.launch` when the control flow needs to be returned from the
kernel. Using `std.return` in this place is ambiguous: it may exit the body
region or the enclosing function. Furthermore, this allows the GPU dialect to
impose the absence of return values as required by the underlying kernel
execution models.
Update outlining transformation from `gpu.launch` to `gpu.launch_func` so that
it replaces `gpu.return` with `std.return`.
PiperOrigin-RevId: 252985992
Pointer types need to specify the storage class. We use the utility functions
generated from SPV_StorageClassAttr to parse and print the storage classes.
Also improved the case that no element type is provided for (runtime) array.
PiperOrigin-RevId: 252935599
This CL adds a generic FillOp to Linalg and its lowering to loops.
This is achieved by avoiding to specify the static NLoopTypes and ViewRanks type traits but instead defines the relevant methods as `extraClassDeclaration`.
The relevant AffineMap and scalar emission code are added, with relevant tests.
This gives us a first rank-agnostic Linalg op with its generic lowering to loops that should compose with view-based tiling and fusion.
PiperOrigin-RevId: 252869205
1) Lowest minimum pattern stack depth when legalizing.
- This leads the system to favor patterns that have lower legalization stacks, i.e. represent a more direct mapping to the target.
2) Pattern benefit.
- When considering multiple patterns with the same legalization depth, this favors patterns with a larger specified benefit.
PiperOrigin-RevId: 252713470
This CL adds a fusion pass for the Linalg dialect.
Fusion is backed by a simple analysis on SSA values and proceeds as follows:
1. A dependence and alias analyses are performed on views.
2. A Linalg op is tiled by a particular tile size. This creates a new Linalg op operating on tiled loops and tiled views.
3. The dependence analysis is used to obtain ops that produce views that are consumed by the original Linalg op.
4. Dependence analysis is used to determine whether op-level fusion would violate any dependence.
5. If fusion is safe, matching tiled views are sliced for the producing op.
6. A tiled clone of the producer op is written before the tiled consumer op.
If a producer is fused, its entire output view has been computed in tiled form.
The original producer op is then erased.
PiperOrigin-RevId: 252695194
This CL adds a lowering to LLVM for MamulOp and a corresponding integration test.
View descriptor manipulation is moved from MLIR's LLVM dialect to C++ code compiled on the side. To this end a separation is introduced between `cblas.cpp` and `cblas_interface.cpp`, the latter operating on view types whose ABI correspond to the LLVM signature generated by MLIR.
An intermediary step is introduced that allocates a new descriptor on the MLIR side for the purpose of passing it to LLVM. The reason for this extra step is that the ABI for by-value ViewType objects wants aligned descriptors, e.g.:
```
extern "C" void linalg_dot_impl(ViewType<float, 1> X, ViewType<float, 1> Y,
BaseViewType<float> Z) {
...
}
```
produces LLVM IR with the signature:
```
%struct.ViewType = type { %struct.BaseViewType, [1 x i64], [1 x i64] }
%struct.BaseViewType = type { float*, i64 }
define void @linalg_dot_impl(%struct.ViewType* byval align 8, %struct.ViewType* byval align 8, float*, i64) tensorflow/mlir#0 {
...
}
```
We don't seem to be able to make such aligned allocations in the MLIR -> LLVM converter atm.
Going through a level of indirection allows the test to pass.
The temporary tradeoff is that the MLIR shims have to be written by hand.
They will disappear in the future.
PiperOrigin-RevId: 252670672
This CL exposes a parseType method which allows standalone reuse of the MLIR type parsing mechanism. This is a free function for now because the underlying MLIR parser is not guaranteed to receive a StringRef which lives in the proper MemBuffer. This requires building a new MemBuffer/SourceMgr and modifying the Parser constructor to not require an mlir::Module.
The error diagnostic emitted by parseType has context limited to the local string.
For now the dialect has the additional option to emit its own extra error that has the FileLineColLoc context.
In the future, both error messages should be combined into a single error.
PiperOrigin-RevId: 252468911
This CL enables verification code generation for variadic operands and results.
In verify(), we use fallback getter methods to access all the dynamic values
belonging to one static variadic operand/result to reuse the value range
calculation there.
PiperOrigin-RevId: 252288219
This CL added getODSOperands() and getODSResults() as fallback getter methods for
getting all the dynamic values corresponding to a static operand/result (which
can be variadic). It should provide a uniform way of calculating the value ranges.
All named getter methods are layered on top of these methods now.
PiperOrigin-RevId: 252284270
This function returns the element type of the underlying type or the input type itself. This removes some of the casting and code from ODS and into C++ code.
I've not converted all the call sites (as this requires a new include and target) and wanted to run it past folks first.
PiperOrigin-RevId: 251978156
Considered adding more placeholders to designate types in the replacement pattern, but convinced for now sticking to simpler approach. This should at least enable specifying constraints across operands/results/attributes and we can start getting rid of the special cases.
PiperOrigin-RevId: 251564893
This CL adds SPV_ModuleEndOp for terminating the only block inside a
SPV_ModuleOp's only region. Verification now enforces a spv.module only
contains func or spv.* ops and no external or nested functions are
present. Because of the structural requirement of a block, spv.Return
is also added in this CL.
PiperOrigin-RevId: 251510706
The initial implementation of SDBM mistakenly swapped the order of variables in
the inequalities induced by a stripe equality: y = x # B actually implies
y - x <= 0 and x - y <= B - 1 rather than x - y <= 0 and y - x <= B - 1 as
implemented. Textual comments in the test files were correct but did not
correspond to the emitted IR. Round-tripping between SDBM and expression lists
was not affected because the wrong order was used in both directions of the
conversion. Use the correct order.
PiperOrigin-RevId: 251252980
When manipulating generic operations, such as in dialect conversion /
rewriting, it is often necessary to view a list of Values as operands to an
operation without creating the operation itself. The absence of such view
makes dialect conversion patterns, among others, to use magic numbers to obtain
specific operands from a list of rewritten values when converting an operation.
Introduce XOpOperandAdaptor classes that wrap an ArrayRef<Value *> and provide
accessor functions identical to those available in XOp. This makes it possible
for conversions to use these adaptors to address the operands with names rather
than rely on their position in the list. The adaptors are generated from ODS
together with the actual operation definitions.
This is another step towards making dialect conversion patterns specific for a
given operation.
Illustrate the approach on conversion patterns in the standard to LLVM dialect
conversion.
PiperOrigin-RevId: 251232899
Similar to arguments and results, now we require region definition in ops to
be specified as a DAG expression with the 'region' operator. This way we can
specify the constraints for each region and optionally give the region a name.
Two kinds of region constraints are added, one allowing any region, and the
other requires a certain number of blocks.
--
PiperOrigin-RevId: 250790211
This allow specifying $x to refer to an operand's named argument (operand or attribute) or result. Skip variadic operands/results for now pending autogenerated discussion of their accessors.
This adds a new predicate, following feedback on the naming but does not remove the old one. Post feedback I'll do that, potentially in follow up.
--
PiperOrigin-RevId: 250720003
This is in preparation for making MemRef a ShapedType. In general, a shaped type should be anything with shape, rank, and element type properties, so use sites shouldn't assume more than that.
I also pulled the trailing comma parsing out the parseElementsLiteralType (new name) method. It seems weird to have the method parse the type + a trailing comma, even if all call sites currently need that. It's surprising behavior without looking at the implementation.
--
PiperOrigin-RevId: 250558363
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
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
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
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
*) 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
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 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
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
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
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
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
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
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
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
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
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
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 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
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
A linalg.dim operation is used to extract size information from !linalg.view objects passed
through function call boundaries.
--
PiperOrigin-RevId: 248017488
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
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
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 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
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
The idea is to lower `gpu.launch` operations into `gpu.launch_func` operations by outlining the kernel body into a function, which is closer to the NVVM model.
--
PiperOrigin-RevId: 246806890
This syntax removes boilerplate and verbose list of region arguments in the
header of the entry block. It groups operands into segments related to GPU
blocks, GPU threads as well as the operands that are forwarded to the kernel.
The two former segments are also used to give names to the region arguments
that are used for GPU blocks and threads inside the kernel body region.
--
PiperOrigin-RevId: 246792329
The generic form of operations currently supports optional regions to be
located after the operation type. As we are going to add a type to each
region in a leading position in the region syntax, similarly to functions, it
becomes ambiguous to have regions immediately after the operation type. Put
regions between operands the optional list of successors in the generic
operation syntax and wrap them in parentheses. The effect on the exisitng IR
syntax is minimal since only three operations (`affine.for`, `affine.if` and
`gpu.kernel`) currently use regions.
--
PiperOrigin-RevId: 246787087
Added a definition for the newly added None type.
Fix TCopVTEtAreSameAt to be a Predicate rather than a PredOpTrait. This makes it more of a primitive and allows flexible composition.
--
PiperOrigin-RevId: 246631975