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
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
Region is the generalization of a function body (a list of blocks forming a CFG) to be allowed to be enclosed inside any operation. This nesting of IR is already leveraged in the affine dialect to support `affine.for`, `affine.if`, and `gpu.launch` operations.
--
PiperOrigin-RevId: 246766830
This trait only works for tensor and vector types at the moment, verifying that the element type of an op with only tensor and vector types match. Added a unit test for it as there is no op currently in core that uses this trait.
--
PiperOrigin-RevId: 246661697
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
Notes are a way to add additional context to a diagnostic, but don't really make sense as standalone diagnostics. Moving forward, notes will no longer be able to be constructed directly and must be attached to a parent Diagnostic.
Notes can be attached via `attachNote`:
auto diag = ...;
diag.attachNote() << "This is a note";
--
PiperOrigin-RevId: 246545971
Trying to activate both LLVM and MLIR passes in mlir-cpu-runner showed name collisions when registering pass names.
One possible way of disambiguating that should also work across dialects is to prepend the dialect name to the passes that specifically operate on that dialect.
With this CL, mlir-cpu-runner tests still run when both LLVM and MLIR passes are registered
--
PiperOrigin-RevId: 246539917
The Diagnostic class contains all of the information necessary to report a diagnostic to the DiagnosticEngine. It should generally not be constructed directly, and instead used transitively via InFlightDiagnostic. A diagnostic is currently comprised of several different elements:
* A severity level.
* A source Location.
* A list of DiagnosticArguments that help compose and comprise the output message.
* A DiagnosticArgument represents any value that may be part of the diagnostic, e.g. string, integer, Type, Attribute, etc.
* Arguments can be added to the diagnostic via the stream(<<) operator.
* (In a future cl) A list of attached notes.
* These are in the form of other diagnostics that provide supplemental information to the main diagnostic, but do not have context on their own.
The InFlightDiagnostic class represents an RAII wrapper around a Diagnostic that is set to be reported with the diagnostic engine. This allows for the user to modify a diagnostic that is inflight. The internally wrapped diagnostic can be reported directly or automatically upon destruction.
These classes allow for more natural composition of diagnostics by removing the restriction that the message of a diagnostic is comprised of a single Twine. They should also allow for nice incremental improvements to the diagnostics experience in the future, e.g. formatv style diagnostics.
Simple Example:
emitError(loc, "integer bitwidth is limited to " + Twine(IntegerType::kMaxWidth) + " bits");
emitError(loc) << "integer bitwidth is limited to " << IntegerType::kMaxWidth << " bits";
--
PiperOrigin-RevId: 246526439
Extend the LLVM lowering class following the original idea of the "bag of
conversions". LLVMLowering class is now exposed as and can be derived from.
It provides hooks for derived classes to inject operation conversions and to
convert custom types. It is under responsibility of the caller to make sure
patterns don't overlap.
Update the lowering from the Linalg dialect to the LLVM IR dialect to use this
new approach.
--
PiperOrigin-RevId: 246492919
This is just a bare skeleton to start populating developer policies and
guidelines. LLVM side this would be multiple separate documents (coding
standard & programmer's manual) but starting with one and we can break it out
into multiple if the content so dictates.
--
PiperOrigin-RevId: 246433346
Also:
- cleans up some operand names for consistency
- remove the broadcast_dims attribute as it isn't used
- adds an IsNullAttr predicate which is needed to match optional clamp attributes on these kind of ops (needed to simplify some out of tree transforms on the new matmul op)
--
PiperOrigin-RevId: 246370576
Add ConstantOp's Op Definition Spec. Currently we don't use convertFromStorage in the generated patterns and so needed to add a few casts to support patterns restricted to ElementsAttrs and to compensate for old rules where we defined ConstantOp to have a ElementsAttr to simplify writing the pattern.
--
PiperOrigin-RevId: 246361555
This CL builds upon ftynse@'s Linalg dialect conversion (in examples/Linalg/Linalg1) and updates it to support buffers and the fully composed form of view and slice operations.
A new BufferSizeOp is introduced for the purpose of extracting the size information from a buffer.
This will be useful in a followup CL for an end-to-end LLVM execution path where mlir-cpu-runner will allocate a buffer.
--
PiperOrigin-RevId: 246358593
This CL adds a primitive tiling pass for Linalg.
The tiling pass uses the loopToOperandRangesMaps property which should be ideally Tablegen'd and in-class.
The tiling specification uses 0 as a convention to skip loops that should not be tiled.
Tiling proceeds in 3 steps, for each op:
1. Pad tile sizes with 0 to match the number of loops, this simplifies the implementation and avoids affine map manipulations to align dimensions.
2. Create loop ranges that represent the min/max/step by which to iterate. This should be later complemented by a range intersection to avoid the out-of-bounds case.
3. Map the loop ranges to view ranges in order to create subviews on which the op can be called.
Relevant utility and helper functions are added separately that support writing the transformation in a declarative fashion.
Simplifying assumptions are made for now on the views and the ranges that are constructed
in the function and are not passed as function arguments. This restriction will be lifted
in the future.
--
PiperOrigin-RevId: 246124419
Simple mechanism to allow specifying arbitrary function declarations. The modelling will not cover all cases so allow a means for users to declare a method function that they will define in their C++ files. The goal is to allow full C++ flexibility as the goal is to cover cases not modelled.
--
PiperOrigin-RevId: 245889819
This CL implements the previously unsupported parsing for Range, View and Slice operations.
A pass is introduced to lower to the LLVM.
Tests are moved out of C++ land and into mlir/test/Examples.
This allows better fitting within standard developer workflows.
--
PiperOrigin-RevId: 245796600
Enables specifying the documentation for dialect along with defining the ops of the dialect. The doc generator will be expanded in follow up to emit the documentation in the autogenerated files. This is precursor to allowing common base for all ops in a dialect.
All the dialect documentation is super sparse and just added as placeholder.
I was tempted (and started) to move ConstantOp to be generated too, but this will be easier post adding extra_methods, so deferring until then.
--
PiperOrigin-RevId: 245759984
Define a new dialect related to GPU kernels. Currently, it only contains a
single operation for launching a kernel on a three-dimensional grid of thread
blocks, following a model similar to that of CUDA. In particular, the body of
the kernel contains operations executed by each thread and uses region
arguments to accept thread and block identifiers (similar to how the loop body
region accepts the induction value).
--
PiperOrigin-RevId: 245713728
Instead, fold such operations. This way callers don't need to conditionally create cast operations depending on if a value already has the target type.
Also, introduce areCastCompatible to allow cast users to verify that the generated op will be valid before creating the operation.
TESTED with unit tests
--
PiperOrigin-RevId: 245606133
none-type ::= `none`
The `none` type is a unit type, i.e. a type with exactly one possible value, where its value does not have a defined dynamic representation.
--
PiperOrigin-RevId: 245599248
Add a tutorial document explaining how to define a conversion from the Linalg
dialect to the LLVM IR dialect, bypassing the Affine dialect. It defines a
dynamic representation for a range and a view for the sake of type conversion.
Operation conversion becomes straightforward given the dynamic representation.
The code in the tutorial is better structured and better document that what we
currently have in the example, which will be updated separately.
--
PiperOrigin-RevId: 245498394
Since SDBM expressions are a subset of affine expressions, they can be
converted to affine expressions in a straightforward way. The inverse
conversion may fail when the affine expression is not an SDBM. Implement the
inverse convresion assuming affine expressions are simplified and
canonicalizied, detect subtractive and multiplicative forms of the stripe
operation.
--
PiperOrigin-RevId: 245494735
The parser currently expects region arguments to have a fixed, known type when
the %-name of the region argument is parsed. This may not necessarily be the
case, for example, if the region argument types are the same as the operand
types, located at the end of the operation. Furthermore, the parser currently
stores the values for region arguments internally and attaches them to the next
parsed region implicitly. This makes it impossible to attach some of the
arguments to one region and some other arguments to another region if the
regions are not textually interleaved with operation arguments.
Provide `OpAsmParser::parseRegionArgument` that parses an SSA identifier and
delays its type assignment until the region is parsed, similarly to operands.
Update `OpAsmParser::parseRegion` to accept a list of pre-parsed SSA
identifiers and a list of types instead of using SSA identifiers stored in the
parser.
--
PiperOrigin-RevId: 245491133
Striped difference-bound matrix expressions are a subset of affine expressions
supporting low-complexity algorithms that can be useful for loop
transformations. This introduces the basic data data structures for building
such expressions and unique'ing them in a MLIRContext.
--
PiperOrigin-RevId: 245380206
Currently, this is limited to operations that give access to the special registers of
NVIDIA gpus that represent block and thread indices.
--
PiperOrigin-RevId: 245378632
Certain ops can have multiple variadic operands/results, e.g., `tf.DynamicStitch`.
Even if an op has only one variadic operand/result, it is not necessarily the
very last one, e.g., `tf.RaggedGather`. This CL enhances TableGen subsystem to be
able to represent such cases.
In order to deduce the operand/result value range for each variadic operand,
currently we only support variadic operands/results all of the same size.
So two new traits, `SameVariadicOperandSize` and `SameVariadicResultSize` are
introduced.
--
PiperOrigin-RevId: 245310628
A unit attribute is an attribute that represents a value of `unit` type. The
`unit` type allows only one value forming a singleton set. This attribute value
is used to represent attributes that only have meaning from their existence.
One example of such an attribute could be the `swift.self` attribute. This attribute indicates that a function parameter is the self/context
parameter. It could be represented as a boolean attribute(true or false), but a
value of false doesn't really bring any value. The parameter either is the
self/context or it isn't.
```mlir {.mlir}
// A unit attribute defined with the `unit` value specifier.
func @verbose_form(i1 {unitAttr : unit})
// A unit attribute can also be defined without the `unit` value specifier.
func @simple_form(i1 {unitAttr})
```
--
PiperOrigin-RevId: 245254045
Add member functions for Regions to query if another Region is a ancestor. The
implementation is naive and traverses all parent regions performing one-to-one
comparisons. As a side effect, this introduces `getContainingRegion` function
for Operations and Values to return the Region in which they are defined, and
for Regions to return the "parent" region if any.
--
PiperOrigin-RevId: 245057980
Similar to MultiOperandTraitBase, this can simply the implementation of
NResults, AtLeastNResults, and VariadicResults.
--
PiperOrigin-RevId: 245052333
The -all_load flag will apply to all future libraries added on the command line,
while the -force_load flag only applies to the next library. Using the latter
allows to selectively force load the specific libraries we want.
--
PiperOrigin-RevId: 244949770
This CL adds linalg.dot, linalg.matvec and linalg.matmul ops with the proper roundtripping test. These are the first LinalgOp that operate on views and that will lower to library calls.
Linalg ops exhibit some common properties and behavior that are modeled with Traits.
A LinalgOp is defined as a generic Op that operates on input and output views (passed as operands) and has the following properties:
1. a number of input and outputs captured by the `NInputsAndOutputs` trait.
2. a list of ranks for each operand captured by the `ViewRanks` trait.
3. a set of parallel, reduction and windowing loops captured by `NLoopTypes` trait.
These represent are a first set of generic properties that will enable the definition of generic linear algebra operations and the properties necessary for upcoming transformations.
--
PiperOrigin-RevId: 244912754