Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td
Show First 20 Lines • Show All 315 Lines • ▼ Show 20 Lines | let description = [{ | ||||
``` | ``` | ||||
operation ::= ssa-id `=` `memref.cast` ssa-use `:` type `to` type | operation ::= ssa-id `=` `memref.cast` ssa-use `:` type `to` type | ||||
``` | ``` | ||||
The `memref.cast` operation converts a memref from one type to an equivalent | The `memref.cast` operation converts a memref from one type to an equivalent | ||||
type with a compatible shape. The source and destination types are | type with a compatible shape. The source and destination types are | ||||
compatible if: | compatible if: | ||||
a. Both are ranked memref types with the same element type, address space, | a. Both memrefs have compatible element types: element type is the same or | ||||
and rank and: | differs only it the signed/signless/unsigned bit. | ||||
b. Both are ranked memref types with compatible element types, address | |||||
space, and rank and: | |||||
1. Both have the same layout or both have compatible strided layouts. | 1. Both have the same layout or both have compatible strided layouts. | ||||
2. The individual sizes (resp. offset and strides in the case of strided | 2. The individual sizes (resp. offset and strides in the case of strided | ||||
memrefs) may convert constant dimensions to dynamic dimensions and | memrefs) may convert constant dimensions to dynamic dimensions and | ||||
vice-versa. | vice-versa. | ||||
If the cast converts any dimensions from an unknown to a known size, then it | If the cast converts any dimensions from an unknown to a known size, then it | ||||
acts as an assertion that fails at runtime if the dynamic dimensions | acts as an assertion that fails at runtime if the dynamic dimensions | ||||
disagree with resultant destination size. | disagree with resultant destination size. | ||||
Show All 12 Lines | let description = [{ | ||||
%4 = memref.cast %1 : memref<12x4xf32, strided<[?, ?], offset: ?>> to | %4 = memref.cast %1 : memref<12x4xf32, strided<[?, ?], offset: ?>> to | ||||
memref<12x4xf32, strided<[4, 1], offset: 5>> | memref<12x4xf32, strided<[4, 1], offset: 5>> | ||||
// Erase static offset and stride information, replacing it with | // Erase static offset and stride information, replacing it with | ||||
// dynamic information. | // dynamic information. | ||||
%5 = memref.cast %1 : memref<12x4xf32, strided<[4, 1], offset: 5>> to | %5 = memref.cast %1 : memref<12x4xf32, strided<[4, 1], offset: 5>> to | ||||
memref<12x4xf32, strided<[?, ?], offset: ?>> | memref<12x4xf32, strided<[?, ?], offset: ?>> | ||||
``` | ``` | ||||
b. Either or both memref types are unranked with the same element type, and | c. Either or both memref types are unranked with compatible element type, | ||||
address space. | and the same address space. | ||||
Example: | Example: | ||||
```mlir | ```mlir | ||||
Cast to concrete shape. | Cast to concrete shape. | ||||
%4 = memref.cast %1 : memref<*xf32> to memref<4x?xf32> | %4 = memref.cast %1 : memref<*xf32> to memref<4x?xf32> | ||||
Erase rank information. | Erase rank information. | ||||
▲ Show 20 Lines • Show All 341 Lines • ▼ Show 20 Lines | let description = [{ | ||||
of transformations and foldings to be added as lowering progresses from | of transformations and foldings to be added as lowering progresses from | ||||
higher-level dialect to lower-level dialects such as the LLVM dialect. | higher-level dialect to lower-level dialects such as the LLVM dialect. | ||||
The op requires a strided memref source operand. If the source operand is not | The op requires a strided memref source operand. If the source operand is not | ||||
a strided memref, then verification fails. | a strided memref, then verification fails. | ||||
This operation is also useful for completeness to the existing memref.dim op. | This operation is also useful for completeness to the existing memref.dim op. | ||||
While accessing strides, offsets and the base pointer independently is not | While accessing strides, offsets and the base pointer independently is not | ||||
available, this is useful for composing with its natural complement op: | available, this is useful for composing with its natural complement op: | ||||
`memref.reinterpret_cast`. | `memref.reinterpret_cast`. | ||||
Intended Use Cases: | Intended Use Cases: | ||||
The main use case is to expose the logic for manipulate memref metadata at a | The main use case is to expose the logic for manipulate memref metadata at a | ||||
higher level than the LLVM dialect. | higher level than the LLVM dialect. | ||||
This makes lowering more progressive and brings the following benefits: | This makes lowering more progressive and brings the following benefits: | ||||
- not all users of MLIR want to lower to LLVM and the information to e.g. | - not all users of MLIR want to lower to LLVM and the information to e.g. | ||||
lower to library calls---like libxsmm---or to SPIR-V was not available. | lower to library calls---like libxsmm---or to SPIR-V was not available. | ||||
- foldings and canonicalizations can happen at a higher level in MLIR: | - foldings and canonicalizations can happen at a higher level in MLIR: | ||||
before this op existed, lowering to LLVM would create large amounts of | before this op existed, lowering to LLVM would create large amounts of | ||||
LLVMIR. Even when LLVM does a good job at folding the low-level IR from | LLVMIR. Even when LLVM does a good job at folding the low-level IR from | ||||
a performance perspective, it is unnecessarily opaque and inefficient to | a performance perspective, it is unnecessarily opaque and inefficient to | ||||
send unkempt IR to LLVM. | send unkempt IR to LLVM. | ||||
Example: | Example: | ||||
```mlir | ```mlir | ||||
%base, %offset, %sizes:2, %strides:2 = | %base, %offset, %sizes:2, %strides:2 = | ||||
memref.extract_strided_metadata %memref : | memref.extract_strided_metadata %memref : | ||||
memref<10x?xf32>, index, index, index, index, index | memref<10x?xf32>, index, index, index, index, index | ||||
// After folding, the type of %m2 can be memref<10x?xf32> and further | // After folding, the type of %m2 can be memref<10x?xf32> and further | ||||
// folded to %memref. | // folded to %memref. | ||||
%m2 = memref.reinterpret_cast %base to | %m2 = memref.reinterpret_cast %base to | ||||
offset: [%offset], | offset: [%offset], | ||||
sizes: [%sizes#0, %sizes#1], | sizes: [%sizes#0, %sizes#1], | ||||
strides: [%strides#0, %strides#1] | strides: [%strides#0, %strides#1] | ||||
: memref<f32> to memref<?x?xf32, offset: ?, strides: [?, ?]> | : memref<f32> to memref<?x?xf32, offset: ?, strides: [?, ?]> | ||||
``` | ``` | ||||
}]; | }]; | ||||
▲ Show 20 Lines • Show All 1,201 Lines • Show Last 20 Lines |