-
Notifications
You must be signed in to change notification settings - Fork 15k
Description
Task
Standarise operand naming for Vector dialect operations.
Context
Below is a list of vector dialect operations that move values from an abstract source to an abstract destination, i.e. "read"/"write" operations:
vector.load,vector.store,vector.transfer_read,
vector.transfer_write,vector.gather,vector.scatter,
vector.compressstore,vector.expandload,vector.maskedload,
vector.maskedstore,vector.extract,vector.insert,
vector.scalable_extract,vector.scalable_insert,
vector.extract_strided_slice,vector.insert_strided_slice.
| **Vector Dialect Op** | **Operand Names** | **Operand Types** | **Result Name** | **Result Type** |
|--------------------------------|--------------------------|-------------------------------|------------------|----------------------|
| `vector.load` | `base` | `memref` | `result` | `vector` |
| `vector.store` | `valueToStore`, `base` | `vector`, `memref` | - | - |
| `vector.transfer_read` | `source` | `memref` / `tensor` | `vector` | `vector` |
| `vector.transfer_write` | `vector`, `source` | `vector`, `memref`/ `tensor` | `result` | `vector` |
| `vector.gather` | `base` | `memref` / `tensor` | `result` | `vector` |
| `vector.scatter` | `valueToStore`, `base` | `vector`, `memref` | - | - |
| `vector.expandload` | `base` | `memref` | `result` | `vector` |
| `vector.compressstore` | `valueToStore`,`base` | `vector`, `memref` | - | - |
| `vector.maskedload` | `base` | `memref` | `result` | `vector` |
| `vector.maskedstore` | `valueToStore`, `base` | `vector`, `memref` | - | - |
| `vector.extract` | `vector` | `vector` | `result` | `scalar` / `vector` |
| `vector.insert` | `source`, `dest` | `scalar` / `vector`, `vector` | `result` | `vector` |
| `vector.scalable_extract` | `source` | `vector` | `res` | `scalar` / `vector` |
| `vector.scalable_insert` | `source`, `dest` | `scalar` / `vector`, `vector` | `res` | `vector` |
| `vector.extract_strided_slice` | `vector` | `vector` | (missing name) | `vector` |
| `vector.insert_strided_slice` | `source`, `dest` | `vector` | `res` | `vector` |
Note that "read" operations take one operand ("from"), whereas "write"
operations require two ("value-to-store" and "to").
Observations
Each "read" operation has a "from" argument, while each "write" operation has a
"to" and a "value-to-store" operand. However, the naming conventions are
inconsistent, making it difficult to extract common patterns or determine
operand roles. Here are some inconsistencies:
getBase()invector.loadrefers to the "from" operand (source).getBase()invector.storerefers to the "to" operand (destination).vector.transfer_readandvector.transfer_writeusegetSource(), which:- Conflicts with the
vector.load/vector.storenaming pattern. - Does not clearly indicate whether the operand represents a source
or destination.
- Conflicts with the
vector.insertdefinesgetSource()andgetDest(), making the distinction
between "to" and "from" operands clear. However, its sibling operation,
vector.extract, only definesgetVector(), making it unclear whether it
represents a source or destination.vector.storeusesgetValueToStore(), whereas
vector.insert_strided_slicedoes not.
There is no consistent way to identify:
"from"(read operand)"to"(write operand)"value-to-store"(written value)
Proposed re-naming
To address these inconsistencies, we propose adopting the following standardised naming conventions:
| **Vector Dialect Op** | **Operand Names** | **Operand Types** | **Result Name** | **Result Type** |
|--------------------------------|--------------------------|-------------------------------|------------------|----------------------|
| `vector.load` | `base` | `memref` | `result` | `vector` |
| `vector.store` | `valueToStore`, `base` | `vector`, `memref` | - | - |
| `vector.transfer_read` | `base` | `memref` / `tensor` | `result` | `vector` |
| `vector.transfer_write` | `valueToStore`, `base` | `vector`, `memref`/ `tensor` | `result` | `vector` |
| `vector.gather` | `base` | `memref` / `tensor` | `result` | `vector` |
| `vector.scatter` | `valueToStore`, `base` | `vector`, `memref` | - | - |
| `vector.expandload` | `base` | `memref` | `result` | `vector` |
| `vector.compressstore` | `valueToStore`, `base` | `vector`, `memref` | - | - |
| `vector.maskedload` | `base` | `memref` | `result` | `vector` |
| `vector.maskedstore` | `valueToStore`, `base` | `vector`, `memref` | - | - |
| `vector.extract` | `source` | `vector` | `result` | `scalar` / `vector` |
| `vector.insert` | `valueToStore`, `dest` | `scalar` / `vector`, `vector` | `result` | `vector` |
| `vector.scalable_extract` | `source` | `vector` | `result` | `scalar` / `vector` |
| `vector.scalable_insert` | `valueToStore`, `dest` | `scalar` / `vector`, `vector` | `result` | `vector` |
| `vector.extract_strided_slice` | `source` | `vector` | `result` | `vector` |
| `vector.insert_strided_slice` | `valueToStore`, `dest` | `vector` | `result` | `vector` |
Next steps
I will leave this open for 1-2 weeks to gather feedback. If there is broad support, I will prepare a patch to implement these changes.
LAST UPDATE: 12/9/24
List of PRs that implement this (updated whenever a new PR is sent):
- [mlir][vector] Standardise
valueToStoreNaming Across Vector Ops (NFC) #134206 - [mlir][vector] Standardize
baseNaming Across Vector Ops (NFC) #137859 - [mlir][vector] Use
resultconsistently as the result argument name #144739 - [mlir][vector] Use
sourceas the source argument name #158258
TODOs
- Remove all the newly
[[deprecated]]hooks before LLVM 21 release. - Remove all the newly [[deprecated]] hooks before LLVM 22 release (this refers to the hooks added post LLVM 21 release).
Thanks!