profile
viewpoint
Oleksandr "Alex" Zinenko ftynse @google Paris, France https://ozinenko.com Compilers and optimization. Polyhedral model. TensorComprehensions. MLIR.

ftynse/cs373 46

Homework for Course cs373: Programming a Robotic Car

ftynse/clint 12

Chunky Loop Interaction

ftynse/clan 1

Chunky Loop Analyzer: A Polyhedral Representation Extraction Tool for High Level Programs

ftynse/one-ovz-driver 1

OpenNebula driver for OpenVZ hypervisor

ftynse/candl 0

Data Dependence Analyzer in the Polyhedral Model

ftynse/chlore 0

chlore: chunky loop optimization recoverer

ftynse/clay 0

Clay, the Chunky Loop Alteration wizardrY

ftynse/cloog 0

The CLooG Code Generator in the Polytope Model

ftynse/clope 0

Chunky LOop Parallelism Extractor

push eventllvm/llvm-project

Alex Zinenko

commit sha 0f04384daf78e26652bae3c5ea9cc201c9099b9d

[mlir] NFC: Rename LLVMOpLowering::lowering to LLVMOpLowering::typeConverter The existing name is an artifact dating back to the times when we did not have a dedicated TypeConverter infrastructure. It is also confusing with with the name of classes using it. Differential revision: https://reviews.llvm.org/D74707

view details

push time in an hour

push eventllvm/llvm-project

Pierre Oechsel

commit sha 0acd7e02f293378aeb2a4e1f8067a79ba5e04e6c

[mlir] Linalg: Extend promotion to non f32 buffers. Summary: Linalg's promotion pass was only supporting f32 buffers due to how the zero value was build for the `fill` operation. Moreover, `promoteSubViewOperands` was returning a vector with one entry per float subview while omitting integer subviews. For a program with only integer subviews the return vector would be of size 0. However, `promoteSubViewsOperands` would try to access a non zero number of entries of this vector, resulting in a sefgault. Reviewers: nicolasvasilache, ftynse Reviewed By: ftynse Subscribers: mehdi_amini, rriddle, jpienaar, burmako, shauheen, antiagainst, nicolasvasilache, arpith-jacob, mgester, lucyrfox, liufengdb, Joonsoo, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D74532

view details

push time in a day

push eventllvm/llvm-project

Alex Zinenko

commit sha 39cb2a8fc79976171b20369ff756f7fa43232b50

[mlir] Fix argument attribute attribute reassignment in ConvertStandardToLLVM The commit switching the calling convention for memrefs (5a1778057) inadvertently introduced a bug in the function argument attribute conversion: due to incorrect indexing of function arguments it was not assigning the attributes to the arguments beyond those generated from the first original argument. This was not caught in the commit since the test suite does have a test for converting multi-argument functions with argument attributes. Fix the bug and add relevant tests.

view details

push time in 4 days

push eventllvm/llvm-project

Abdurrahman Akkas

commit sha 2e8c112ecf562afdd8a6b3c3467571233b9b55ae

[mlir] Add elementAttr to TypedArrayAttrBase. In code generators, one can automate the translation of typed ArrayAttrs if element attribute translators are already implemented. However, the type of the element attribute is lost at the construction of TypedArrayAttrBase. With this change one can inspect the element type and generate the translation logic automatically, which will reduce the code repetition. Differential Revision: https://reviews.llvm.org/D73579

view details

push time in 5 days

push eventllvm/llvm-project

Kern Handa

commit sha 005b720373f163b153957d35db24722b8f72ad9b

[NFC][mlir] Adding some helpful EDSC intrinsics Differential Revision: https://reviews.llvm.org/D74119

view details

push time in 5 days

push eventllvm/llvm-project

Valentin Clement

commit sha 56aba9699d8d1d10f7e93f60dd11f7e4cce3eb93

[MLIR] Fix wrong header for mlir-cuda-runner Just updated the wrong header probably copied from the mlir-cpu-runner Differential Revision: https://reviews.llvm.org/D74497

view details

Tobias Gysi

commit sha 4f865b77941db364eaf0a6c265d183274c503ecb

[mlir] support creating memref descriptors from static shape with non-zero offset This patch adapts the method MemRefDescriptor::fromStaticShape to support static non-zero offsets. The updated method uses the getStridesAndOffset method to extract strides and offset. The patch also adapts the test cases since sizes and strides are now set in forward instead of reverse order. Differential Revision: https://reviews.llvm.org/D74474

view details

push time in 6 days

push eventllvm/llvm-project

Pierre Oechsel

commit sha fd11cda2519f91e2f522f58f137b3082a65b5f62

[mlir] StdToLLVM: Add error when the sourceMemRef of a subview is not a llvm type. A memref_cast casting to a memref with a non identity map can't be lowered to llvm. Take the following case: ``` func @invalid_memref_cast(%arg0: memref<?x?xf64>) { %c1 = constant 1 : index %c0 = constant 0 : index %5 = memref_cast %arg0 : memref<?x?xf64> to memref<?x?xf64, #map1> %25 = std.subview %5[%c0, %c0][%c1, %c1][] : memref<?x?xf64, #map1> to memref<?x?xf64, #map1> return } ``` When lowering the subview mlir was assuming `%5` to have an llvm type (which is not the case as mlir failed to lower the memref_cast). Differential Revision: https://reviews.llvm.org/D74466

view details

Alex Zinenko

commit sha 5ae9c4c86806811cab3735dd56237ec1a9614354

[mlir] Linalg fusion: ignore indexed_generic producers They are currently not supported and we should not attempt fusing them.

view details

push time in 6 days

Pull request review commentllvm/mlir-www

Add a section on using Arcanist to Contributing.md

 to enable build and test of your Phabricator revisions. Once a patch is approved on Phabricator and pass continuous integration checks, it can be pushed directly to the master branch of the repository. +#### Using Arcanist++Use [Arcanist](https://llvm.org/docs/Phabricator.html#requesting-a-review-via-the-command-line)+to send your patches for review. This triggers the continuous build system and+preserves the authorship information in case somebody else commits the patch on+your behalf.++**Do not use `arc land`**, push commits to master directly with `git`. Arcanist+adds noisy tags to the commit message that we prefer to remove. See the+[llvm-dev thread](http://lists.llvm.org/pipermail/llvm-dev/2019-December/137848.html)+on the subject for more information. *Note:* Arcanist also adds tags when you+send a patch for review, by quietly amending your commit message. Make sure to+**remove Phabricator tags** other than "Differential Revision" before pushing+commits out to the repository.++The following script can be added to your `.bashrc` to create the `arcfilter`+command. When called as `arcfilter` from the command line, it removes the+Arcanist-injected tags from the last commit by amending its message.++```sh+function arcfilter() {  git log -1 --pretty=%B | awk '/Reviewers: /{p=1; sub(/Reviewers: .*Differential Revision: /, "")}; /Differential Revision: /{p=0;}; !p'   | git commit --amend -F - ; }+```++#### First-time contributors++LLVM follows a [policy](https://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access)+of granting established contributors direct commit access to the repository.+If you make your first contributions to the LLVM infrastructure, you are unlikely+to have commit access. In this case, ask the reviewers to commit the change+for you after it has been accepted. Once you have demonstrated the ability to+write high-quality patches, follow the+[policy](https://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access) to+obtain commit access for yourself.++*Note:* if you haven't used Arcanist to send your patch for review, committers+don't have access to your preferred identity for commit messages. Make sure+to communicate it to them through available channels or use the git sign-off+functionality to make your identity visible in the commit message.++#### Commit messages++Follow the git conventions for writing a commit message, in particular the +first line is the short title of the commit. Prefix it with `[mlir]` to make+it easily findable in the general flow of LLVM project commits. The title

Okay, removed this mention.

ftynse

comment created time in 6 days

push eventllvm/mlir-www

Jacques Pienaar

commit sha aa541bb35e4563703b0d12305fcb31064bd8d008

Update openprojects.md

view details

Oleksandr "Alex" Zinenko

commit sha 7f813f2f5463144b9dea0974ae553308570dae8b

Add a section on using Arcanist to Contributing.md The "contributing" guide was not describing the use of Arcanist to trigger builds and the caveats of Arcanist adding noisy tags to the commit message. It also did not reference the commit access policy. Describe these in a new section. Additionally, mention the commit message etiquette.

view details

push time in 6 days

push eventllvm/llvm-project

Marius Brehler

commit sha a9a305716bbfa657ce0f7ae9cd50df82720a6db0

[mlir] Revise naming of MLIROptMain and MLIRMlirOptLib * Rename CMake target MLIROptMain to MLIROptLib: The target provides the main library * Rename CMake target MLIRMlirOptLib to MLIRMlirOptMain: The target provides the main() entry function At the moment, the Bazel configuration of TenorFlow maps the target MlirOptLib to "lib/Support/MlirOptMain.cpp" and MlirOptMain to "tools/mlir-opt/mlir-opt.cpp". This is the other way around in the CMake configuration. As discussed in the context of the pull request https://github.com/tensorflow/tensorflow/pull/36301, it seems useful to revise the naming in the MLIR repo. Differential Revision: https://reviews.llvm.org/D73778

view details

push time in 6 days

create barnchftynse/llvm-project

branch : mdh

created branch time in 7 days

fork ftynse/llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. Note: the repository does not accept github pull requests at this moment. Please submit your patches at http://reviews.llvm.org.

http://llvm.org

fork in 7 days

push eventllvm/llvm-project

Alex Zinenko

commit sha ea3a25e4f5166ccd5e523f0165f5270b24d71f46

[mlir] StdToLLVM: add a separate test for the new memref calling convention

view details

push time in 7 days

issue commenttensorflow/mlir

memref lowering: stack overflow due to alloca's for memref descriptors for calls inside a loop

This should be addressed by https://github.com/llvm/llvm-project/commit/5a1778057f72b8e0444a7932144a3fa441b641bc

bondhugula

comment created time in 7 days

push eventllvm/llvm-project

Tobias Gysi

commit sha 1555d7f729089382520b93634cc24e600fcd21ae

[mlir] subview op lowering for target memrefs with const offset The current standard to llvm conversion pass lowers subview ops only if dynamic offsets are provided. This commit extends the lowering with a code path that uses the constant offset of the target memref for the subview op lowering (see Example 3 of the subview op definition for an example) if no dynamic offsets are provided. Differential Revision: https://reviews.llvm.org/D74280

view details

push time in 8 days

push eventllvm/llvm-project

Alex Zinenko

commit sha 5a1778057f72b8e0444a7932144a3fa441b641bc

[mlir] use unpacked memref descriptors at function boundaries The existing (default) calling convention for memrefs in standard-to-LLVM conversion was motivated by interfacing with LLVM IR produced from C sources. In particular, it passes a pointer to the memref descriptor structure when calling the function. Therefore, the descriptor is allocated on stack before the call. This convention leads to several problems. PR44644 indicates a problem with stack exhaustion when calling functions with memref-typed arguments in a loop. Allocating outside of the loop may lead to concurrent access problems in case the loop is parallel. When targeting GPUs, the contents of the stack-allocated memory for the descriptor (passed by pointer) needs to be explicitly copied to the device. Using an aggregate type makes it impossible to attach pointer-specific argument attributes pertaining to alignment and aliasing in the LLVM dialect. Change the default calling convention for memrefs in standard-to-LLVM conversion to transform a memref into a list of arguments, each of primitive type, that are comprised in the memref descriptor. This avoids stack allocation for ranked memrefs (and thus stack exhaustion and potential concurrent access problems) and simplifies the device function invocation on GPUs. Provide an option in the standard-to-LLVM conversion to generate auxiliary wrapper function with the same interface as the previous calling convention, compatible with LLVM IR porduced from C sources. These auxiliary functions pack the individual values into a descriptor structure or unpack it. They also handle descriptor stack allocation if necessary, serving as an allocation scope: the memory reserved by `alloca` will be freed on exiting the auxiliary function. The effect of this change on MLIR-generated only LLVM IR is minimal. When interfacing MLIR-generated LLVM IR with C-generated LLVM IR, the integration only needs to require auxiliary functions and change the function name to call the wrapper function instead of the original function. This also opens the door to forwarding aliasing and alignment information from memrefs to LLVM IR pointers in the standrd-to-LLVM conversion.

view details

push time in 8 days

Pull request review commentllvm/mlir-www

Add a section on using Arcanist to Contributing.md

 to enable build and test of your Phabricator revisions. Once a patch is approved on Phabricator and pass continuous integration checks, it can be pushed directly to the master branch of the repository. +#### Using Arcanist++Use [Arcanist](https://llvm.org/docs/Phabricator.html#requesting-a-review-via-the-command-line)+to send your patches for review. This triggers the continuous build system and+preserves the authorship information in case somebody else commits the patch on+your behalf.++**Do not use `arc land`**, push commits to master directly with `git`. Arcanist+adds noisy tags to the commit message that we prefer to remove. See the+[llvm-dev thread](http://lists.llvm.org/pipermail/llvm-dev/2019-December/137848.html)+on the subject for more information. *Note:* Arcanist also adds tags when you+send a patch for review, by quietly amending your commit message. Make sure to+**remove Phabricator tags** other than "Differential Revision" before pushing+commits out to the repository.++The following script can be added to your `.bashrc` to create the `arcfilter`+command. When called as `arcfilter` from the command line, it removes the+Arcanist-injected tags from the last commit by amending its message.++```sh+function arcfilter() {  git log -1 --pretty=%B | awk '/Reviewers: /{p=1; sub(/Reviewers: .*Differential Revision: /, "")}; /Differential Revision: /{p=0;}; !p'   | git commit --amend -F - ; }+```++#### First-time contributors++LLVM follows a [policy](https://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access)+of granting established contributors direct commit access to the repository.+If you make your first contributions to the LLVM infrastructure, you are unlikely+to have commit access. In this case, ask the reviewers to commit the change+for you after it has been accepted. Once you have demonstrated the ability to+write high-quality patches, follow the+[policy](https://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access) to+obtain commit access for yourself.++*Note:* if you haven't used Arcanist to send your patch for review, committers+don't have access to your preferred identity for commit messages. Make sure+to communicate it to them through available channels or use the git sign-off+functionality to make your identity visible in the commit message.++#### Commit messages++Follow the git conventions for writing a commit message, in particular the +first line is the short title of the commit. Prefix it with `[mlir]` to make+it easily findable in the general flow of LLVM project commits. The title+should be followed by an empty line and a longer description. Prefer describing+*why* the change is implemented rather than what it does. The latter can be+inferred from the code. This [post](https://chris.beams.io/posts/git-commit/)+give examples and more details.

We do, but it's significantly more terse and arguably misplaced: it makes more sense to describe git etiquette in the doc that discusses committing than in the doc that discusses code-related issues IMO. I was thinking to add a reference from the developer guide to here.

ftynse

comment created time in 8 days

Pull request review commentllvm/mlir-www

Add a section on using Arcanist to Contributing.md

 to enable build and test of your Phabricator revisions. Once a patch is approved on Phabricator and pass continuous integration checks, it can be pushed directly to the master branch of the repository. +#### Using Arcanist++Use [Arcanist](https://llvm.org/docs/Phabricator.html#requesting-a-review-via-the-command-line)+to send your patches for review. This triggers the continuous build system and+preserves the authorship information in case somebody else commits the patch on+your behalf.++**Do not use `arc land`**, push commits to master directly with `git`. Arcanist+adds noisy tags to the commit message that we prefer to remove. See the+[llvm-dev thread](http://lists.llvm.org/pipermail/llvm-dev/2019-December/137848.html)+on the subject for more information. *Note:* Arcanist also adds tags when you+send a patch for review, by quietly amending your commit message. Make sure to+**remove Phabricator tags** other than "Differential Revision" before pushing+commits out to the repository.++The following script can be added to your `.bashrc` to create the `arcfilter`+command. When called as `arcfilter` from the command line, it removes the+Arcanist-injected tags from the last commit by amending its message.++```sh+function arcfilter() {  git log -1 --pretty=%B | awk '/Reviewers: /{p=1; sub(/Reviewers: .*Differential Revision: /, "")}; /Differential Revision: /{p=0;}; !p'   | git commit --amend -F - ; }+```++#### First-time contributors++LLVM follows a [policy](https://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access)+of granting established contributors direct commit access to the repository.+If you make your first contributions to the LLVM infrastructure, you are unlikely+to have commit access. In this case, ask the reviewers to commit the change+for you after it has been accepted. Once you have demonstrated the ability to+write high-quality patches, follow the+[policy](https://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access) to+obtain commit access for yourself.++*Note:* if you haven't used Arcanist to send your patch for review, committers+don't have access to your preferred identity for commit messages. Make sure+to communicate it to them through available channels or use the git sign-off+functionality to make your identity visible in the commit message.++#### Commit messages++Follow the git conventions for writing a commit message, in particular the +first line is the short title of the commit. Prefix it with `[mlir]` to make+it easily findable in the general flow of LLVM project commits. The title

This should be brought to llvm-dev. I'm trying to solve a local problem: if we don't put the prefix ourselves, random people will change our phabricator diff to add it (happened repeatedly in the past), which will break the email chain associated with the diff. Unless it's agreed upon in the broader community, we cannot insist nobody does it.

ftynse

comment created time in 8 days

Pull request review commentllvm/mlir-www

Add a section on using Arcanist to Contributing.md

 to enable build and test of your Phabricator revisions. Once a patch is approved on Phabricator and pass continuous integration checks, it can be pushed directly to the master branch of the repository. +#### Using Arcanist++Use [Arcanist](https://llvm.org/docs/Phabricator.html#requesting-a-review-via-the-command-line)+to send your patches for review. This triggers the continuous build system and+preserves the authorship information in case somebody else commits the patch on+your behalf.++**Do not use `arc land`**, push commits to master directly with `git`. Arcanist+adds noisy tags to the commit message that we prefer to remove. See the+[llvm-dev thread](http://lists.llvm.org/pipermail/llvm-dev/2019-December/137848.html)+on the subject for more information. *Note:* Arcanist also adds tags when you+send a patch for review, by quietly amending your commit message. Make sure to+**remove Phabricator tags** other than "Differential Revision" before pushing+commits out to the repository.++The following script can be added to your `.bashrc` to create the `arcfilter`+command. When called as `arcfilter` from the command line, it removes the+Arcanist-injected tags from the last commit by amending its message.++```sh+function arcfilter() {  git log -1 --pretty=%B | awk '/Reviewers: /{p=1; sub(/Reviewers: .*Differential Revision: /, "")}; /Differential Revision: /{p=0;}; !p'   | git commit --amend -F - ; }

Cool, thanks!

ftynse

comment created time in 8 days

push eventllvm/mlir-www

Oleksandr "Alex" Zinenko

commit sha c118a12bceba18d53d306fcdc30ff36308f8add6

Add a section on using Arcanist to Contributing.md The "contributing" guide was not describing the use of Arcanist to trigger builds and the caveats of Arcanist adding noisy tags to the commit message. It also did not reference the commit access policy. Describe these in a new section. Additionally, mention the commit message etiquette.

view details

push time in 8 days

push eventllvm/llvm-project

OuHangKresnik

commit sha 7edf27f7a75affd3a9198de834014c78f5604500

[mlir] Add NoSideEffect to Affine min max Add NoSideEffect to Affine min and max operations. Differential Revision: https://reviews.llvm.org/D74203

view details

push time in 11 days

PR opened llvm/mlir-www

Reviewers
Add a section on using Arcanist to Contributing.md

The "contributing" guide was not describing the use of Arcanist to trigger builds and the caveats of Arcanist adding noisy tags to the commit message. It also did not reference the commit access policy. Describe these in a new section.

Additionally, mention the commit message etiquette.

+49 -0

0 comment

1 changed file

pr created time in 12 days

create barnchllvm/mlir-www

branch : ftynse-patch-1

created branch time in 12 days

push eventllvm/llvm-project

OuHangKresnik

commit sha 5c3b34930c31227b5f33f1886d13431c4c90a1b0

[mlir] Add AffineMaxOp Differential Revision: https://reviews.llvm.org/D73848

view details

push time in 12 days

push eventllvm/llvm-project

Alex Zinenko

commit sha 3b4d24d7701484bee32b97d547b11958fee2622b

[mlir] Accept an LLVM::LLVMFuncOp in the builder of LLVM::CallOp Summary: Replace the generic zero- and one-result builders in LLVM::CallOp with a custom builder that takes an LLVMFuncOp, which can be used to extract the result type and create the symbol reference attribute. This is merely a convenience for upcoming changes. The ODS-generated builders remain present. Introduce LLVM::LLVMType::isVoidTy by analogy with the underlying LLVM type. Differential Revision: https://reviews.llvm.org/D73895

view details

push time in 15 days

push eventllvm/llvm-project

Alex Zinenko

commit sha e0ea706a59b9032b7f3590478080adf4f3e1486a

[mlir] ConvertStandardToLLVM: do not rely on command line options internally The patterns for converting `std.alloc` and `std.dealoc` can be configured to use `llvm.alloca` instead of calling `malloc` and `free`. This configuration has been only possible through a command-line flag, despite the presence of a (misleading) parameter in the pass constructor. Use the parameter instead and only initalize it from the command line flags if the pass is constructed from the mlir-opt registration.

view details

push time in 15 days

push eventllvm/llvm-project

Alex Zinenko

commit sha f3fa4a34b62ec283ffda136af4dd55c223c1e6b3

[mlir] Drop customization hooks from StandardToLLVM conversion Summary: These hooks were originally introduced to support passes deriving the StandardToLLVM conversion, in particular converting types from different dialects to LLVM types in a single-step conversion. They are no longer in use since the pass and conversion infrastructure has evolved sufficiently to make defining new passes with exactly the same functionality simple through the use of populate* functions, conversion targets and type converters. Remove the hooks. Any users of this hooks can call the dialect conversion infrastructure directly instead, which is likely to require less LoC than these hooks. Differential Revision: https://reviews.llvm.org/D73795

view details

push time in 15 days

push eventllvm/llvm-project

Marius Brehler

commit sha 9adbb6c468c1c4010727a1bfb8e3959eea11f5c7

[mlir] Fix link to 'Getting started with MLIR' The link in the toy example pointed to the 'tensorflow/mlir' repo and is replaced with https://mlir.llvm.org. Differential Revision: https://reviews.llvm.org/D73770

view details

push time in 15 days

push eventllvm/llvm-project

Alex Zinenko

commit sha 23ccc055c760f30c52011861894ff35a9fa0b7b7

[mlir] Remove the dependency of StdToLLVM on LoopToStd This is a leftover of a temporary state where loop operations were in Standard dialect.

view details

push time in 18 days

push eventllvm/llvm-project

Alex Zinenko

commit sha 9dfcddfaae50a3138173311a15e7ab19d36c1860

[mlir] Linalg tiling: generate code avoding out-of-bounds accesses Summary: After the `subview` operation was migrated from Linalg to Standard, it changed semantics and does not guarantee the absence of out-of-bounds accesses through the created view anymore. Compute the size of the subview to make sure it always fits within the view (subviews in last iterations of the loops may be smaller than those in other iterations). Differential Revision: https://reviews.llvm.org/D73614

view details

push time in 18 days

PR opened llvm/mlir-www

Reviewers
Mention Doxygen-style comments in style guide

We are following this convention implicitly, making it explicit. The reason for using Doxygen-style comments even for non-public APIs is that these APIs often become public at some point, but the comments are not necessarily updated to reflect that. Also, simpler rules (i.e. not thinking whether you are working on a public API or not) are simpler to follow.

+2 -0

0 comment

1 changed file

pr created time in 18 days

create barnchllvm/mlir-www

branch : comments

created branch time in 18 days

push eventllvm/llvm-project

Alex Zinenko

commit sha eb67bd78dc1865fce0c35f241f62cf65f4452e3e

[mlir] LLVM dialect: Generate conversions between EnumAttrCase and LLVM API Summary: MLIR materializes various enumeration-based LLVM IR operands as enumeration attributes using ODS. This requires bidirectional conversion between different but very similar enums, currently hardcoded. Extend the ODS modeling of LLVM-specific enumeration attributes to include the name of the corresponding enum in the LLVM C++ API as well as the names of specific enumerants. Use this new information to automatically generate the conversion functions between enum attributes and LLVM API enums in the two-way conversion between the LLVM dialect and LLVM IR proper. Differential Revision: https://reviews.llvm.org/D73468

view details

push time in 19 days

push eventllvm/llvm-project

Alex Zinenko

commit sha fdc496a3d30d2d82814965a6aa987b7ef0b136ef

[mlir] EnumsGen: dissociate string form of integer enum from C++ symbol name Summary: In some cases, one may want to use different names for C++ symbol of an enumerand from its string representation. In particular, in the LLVM dialect for, e.g., Linkage, we would like to preserve the same enumerand names as LLVM API and the same textual IR form as LLVM IR, yet the two are different (CamelCase vs snake_case with additional limitations on not being a C++ keyword). Modify EnumAttrCaseInfo in OpBase.td to include both the integer value and its string representation. By default, this representation is the same as C++ symbol name. Introduce new IntStrAttrCaseBase that allows one to use different names. Exercise it for LLVM Dialect Linkage attribute. Other attributes will follow as separate changes. Differential Revision: https://reviews.llvm.org/D73362

view details

push time in 19 days

push eventllvm/llvm-project

Shraiysh Vaishay

commit sha d242aa245ccfaa527d27c75e50f9b73223aec14b

[MLIR] Added llvm.invoke and llvm.landingpad Summary: I have tried to implement `llvm.invoke` and `llvm.landingpad`. # `llvm.invoke` is similar to `llvm.call` with two successors added, the first one is the normal label and the second one is unwind label. # `llvm.launchpad` takes a variable number of args with either `catch` or `filter` associated with them. Catch clauses are not array types and filter clauses are array types. This is same as the criteria used by LLVM (https://github.com/llvm/llvm-project/blob/4f82af81a04d711721300f6ca32f402f2ea6faf4/llvm/include/llvm/IR/Instructions.h#L2866) Examples: LLVM IR ``` define i32 @caller(i32 %a) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { invoke i32 @foo(i32 2) to label %success unwind label %fail success: ret i32 2 fail: landingpad {i8*, i32} catch i8** @_ZTIi catch i8** null catch i8* bitcast (i8** @_ZTIi to i8*) filter [1 x i8] [ i8 1 ] ret i32 3 } ``` MLIR LLVM Dialect ``` llvm.func @caller(%arg0: !llvm.i32) -> !llvm.i32 { %0 = llvm.mlir.constant(3 : i32) : !llvm.i32 %1 = llvm.mlir.constant("\01") : !llvm<"[1 x i8]"> %2 = llvm.mlir.addressof @_ZTIi : !llvm<"i8**"> %3 = llvm.bitcast %2 : !llvm<"i8**"> to !llvm<"i8*"> %4 = llvm.mlir.null : !llvm<"i8**"> %5 = llvm.mlir.addressof @_ZTIi : !llvm<"i8**"> %6 = llvm.mlir.constant(2 : i32) : !llvm.i32 %7 = llvm.invoke @foo(%6) to ^bb1 unwind ^bb2 : (!llvm.i32) -> !llvm.i32 ^bb1: // pred: ^bb0 llvm.return %6 : !llvm.i32 ^bb2: // pred: ^bb0 %8 = llvm.landingpad (catch %5 : !llvm<"i8**">) (catch %4 : !llvm<"i8**">) (catch %3 : !llvm<"i8*">) (filter %1 : !llvm<"[1 x i8]">) : !llvm<"{ i8*, i32 }"> llvm.return %0 : !llvm.i32 } ``` Signed-off-by: Shraiysh Vaishay <cs17btech11050@iith.ac.in> Differential Revision: https://reviews.llvm.org/D72006

view details

push time in 19 days

CommitCommentEvent

push eventllvm/llvm-project

Alex Zinenko

commit sha 8ed47b74300e524de45d4589609b490581e9db2f

[mlir] NFC: use ValueRange in AffineToStandard conversion ValueRange is a more flexible way of passing around ranges of Values that avoids Value vector materialization in affine expression expansion.

view details

push time in 21 days

push eventllvm/llvm-project

Alex Zinenko

commit sha 6895a1c37e44f286138b9d57e5d15467d278ec75

[mlir] NFC: use doxygen-style comments in AffineToStandard.cpp

view details

push time in 21 days

push eventllvm/llvm-project

Alex Zinenko

commit sha 51ba5b528a98e0569325e83fe53f5a789543620f

[mlir] add lowering from affine.min to std Summary: Affine minimum computation will be used in tiling transformation. The implementation is mostly boilerplate as we already lower the minimum in the upper bound of an affine loop. Differential Revision: https://reviews.llvm.org/D73488

view details

Kern Handa

commit sha 74df89f67f17f1e95c249831ce2d9c9d9830e496

[NFC][mlir][linalg] Merge Utils/Intrinsics.h into EDSC/Intrinsics.h Differential Revision: https://reviews.llvm.org/D73377

view details

push time in 22 days

push eventllvm/llvm-project

Alex Zinenko

commit sha 07328944efb6454b74563b61a97d61545888757b

[mlir] LLVM import: handle constant data and array/vector aggregates Summary: Implement the handling of llvm::ConstantDataSequential and llvm::ConstantAggregate for (nested) array and vector types when imporitng LLVM IR to MLIR. In all cases, the result is a DenseElementsAttr that can be used in either a `llvm.mlir.global` or a `llvm.mlir.constant`. Nested aggregates are unpacked recursively until an element or a constant data is found. Nested arrays with innermost scalar type are represented as DenseElementsAttr of tensor type. Nested arrays with innermost vector type are represented as DenseElementsAttr with (multidimensional) vector type. Constant aggregates of struct type are not yet supported as the LLVM dialect does not have a well-defined way of modeling struct-type constants. Differential Revision: https://reviews.llvm.org/D72834

view details

Alex Zinenko

commit sha 84c3f05c8e3e28fd58c458f842e721bbbaa837b2

[mlir] Harden error propagation in LLVM import Summary: LLVM importer to MLIR was implemented mostly as a prototype. As such, it did not deal handle errors in a consistent way, reporting them out stderr in some cases and continuing the execution in the error state until eventually crashing. This is not desirable for a user-facing tool. Make sure errors are returned from functions, consistently checked at call sites and propagated further. Functions returning nullable IR values return nullptr to denote the error state. Other functions return LogicalResult. LLVM importer in mlir-translate should no longer crash on unsupported inputs. The errors are reported without association with the source file (and therefore cannot be checked using -verify-diagnostics). Attaching them to the actual input file is left for future work. Differential Revision: https://reviews.llvm.org/D72839

view details

push time in 22 days

push eventllvm/llvm-project

Alex Zinenko

commit sha b9013351936d51424badfecbb3cd1e92c1209bb3

[mlir] Use all_of instead of a manual loop in IntrinsicGen. NFC This was suggested in post-commit review of D72926.

view details

push time in 25 days

push eventllvm/llvm-project

Alex Zinenko

commit sha c8695ba9cdebfc25af3312a84d91ae6f0f98487b

Revert "[mlir] Add baseAttr to TypedArrayAttrBase." This reverts commit eec36909c18b8788773abc95d199e6acde6eb42c. This modeling is incorrect. baseAttr is intended for attribute decorators that are not backed by C++ attribute classes. It essentially says DerivedAttr isa BaseAttr, which is wrong for ArrayAttr classes. If one needs to store the element type, it should be stored as a separate filed in the tablegen class.

view details

push time in a month

push eventllvm/llvm-project

Alex Zinenko

commit sha 7984b47401f7f36475619abf2ff02de3b5ff0481

[mlir][orc] unbreak MLIR ExecutionEngine after ORC changes Changes to ORC in ce2207abaf9a925b35f15ef92aaff6b301ba6d22 changed the APIs in IRCompileLayer, now requiring the custom compiler to be wrapped in IRCompileLayer::IRCompiler. Even though MLIR relies on Orc CompileUtils, the type is still visible in several places in the code. Adapt those to the new API.

view details

push time in a month

push eventllvm/llvm-project

Alex Zinenko

commit sha f63f5a228f30199ed04f9a862e6125ccb977e530

[mlir] clarify LangRef wording around control flow in regions It was unclear what "exiting a region" meant in the existing formulation. Phrase it in terms of control flow transfer to the operation enclosing the region. Discussion: https://groups.google.com/a/tensorflow.org/d/msg/mlir/73d2O8gjTuA/xVj1KoCTBAAJ

view details

push time in a month

push eventllvm/llvm-project

Eric Schweitz

commit sha 37e2560d3d24d7858493d30fc5b6e6a001f2a197

[Flang][mlir] add a band-aid to support the creation of mutually recursive types when lowering to LLVM IR Summary: This is a temporary implementation to support Flang. The LLVM-IR parser will need to be extended in some way to support recursive types. The exact approach here is still a work-in-progress. Unfortunately, this won't pass roundtrip testing yet. Adding a comment to the test file as a reminder. Differential Revision: https://reviews.llvm.org/D72542

view details

Frank Laub

commit sha 60a0c612df515cffcf4489b97bfff7b97b78018b

[MLIR] LLVM dialect: Add llvm.atomicrmw Summary: This op is the counterpart to LLVM's atomicrmw instruction. Note that volatile and syncscope attributes are not yet supported. This will be useful for upcoming parallel versions of `affine.for` and generally for reduction-like semantics. Differential Revision: https://reviews.llvm.org/D72741

view details

push time in a month

push eventllvm/llvm-project

Alex Zinenko

commit sha f343544b813891387add8ef01406d36b82ed0a7e

[mlir] Generator converting LLVM intrinsics defs to MLIR ODS Introduce a new generator for MLIR tablegen driver that consumes LLVM IR intrinsic definitions and produces MLIR ODS definitions. This is useful to bulk-generate MLIR operations equivalent to existing LLVM IR intrinsics, such as additional arithmetic instructions or NVVM. A test exercising the generation is also added. It reads the main LLVM intrinsics file and produces ODS to make sure the TableGen model remains in sync with what is used in LLVM. Differential Revision: https://reviews.llvm.org/D72926

view details

push time in a month

push eventllvm/llvm-project

Alex Zinenko

commit sha a922e23101b882e22fc14ffb78b5857954dc86f3

[mlir] Improve documentation in ModuleTranslation MLIR to LLVM IR Several functions were missing documentation.

view details

push time in a month

push eventllvm/llvm-project

Alex Zinenko

commit sha a4a42160c4463eac74c5d0cfa9a88c4971d8a23e

[mlir] support translation of multidimensional vectors to LLVM IR Summary: MLIR unlike LLVM IR supports multidimensional vector types. Such types are lowered to nested LLVM IR arrays wrapping an LLVM IR vector for the innermost dimension of the MLIR vector. MLIR supports constants of such types using ElementsAttr for values. Introduce support for converting ElementsAttr into LLVM IR Constant Aggregates recursively. This enables translation of multidimensional vector constants from MLIR to LLVM IR. Differential Revision: https://reviews.llvm.org/D72846

view details

push time in a month

push eventllvm/llvm-project

Kazuaki Ishizaki

commit sha 73f371c31d2774b3e4d51e4e276737d54922aa18

[mlir] NFC: Fix trivial typos Summary: Fix trivial typos Differential Revision: https://reviews.llvm.org/D72672

view details

push time in a month

push eventllvm/llvm-project

Alex Zinenko

commit sha dc553ce646cdbab32d72d263d3f289952648b920

[mlir] LLVM import: handle function-typed constants The current implementation of the LLVM-to-MLIR translation could not handle functions used as constant values in instructions. The handling is added trivially as `llvm.mlir.constant` can define constants of function type using SymbolRef attributes, which works even for functions that have not been declared yet.

view details

push time in a month

push eventllvm/llvm-project

Alex Zinenko

commit sha d6ea8ff0d74bfe5cd181ccfe91c2c300c5f7a35d

[mlir] Fix translation of splat constants to LLVM IR Summary: When converting splat constants for nested sequential LLVM IR types wrapped in MLIR, the constant conversion was erroneously assuming it was always possible to recursively construct a constant of a sequential type given only one value. Instead, wait until all sequential types are unpacked recursively before constructing a scalar constant and wrapping it into the surrounding sequential type. Subscribers: mehdi_amini, rriddle, jpienaar, burmako, shauheen, antiagainst, nicolasvasilache, arpith-jacob, mgester, lucyrfox, aartbik, liufengdb, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D72688

view details

push time in a month

push eventllvm/llvm-project

Lorenzo Chelini

commit sha 81e7922e83cf9782a39f4072e20eab8ab1e99828

[mlir] m_Constant() Summary: Introduce m_Constant() which allows matching a constant operation without forcing the user also to capture the attribute value. Differential Revision: https://reviews.llvm.org/D72397

view details

push time in a month

push eventllvm/llvm-project

Pruthvi

commit sha 3cad8ada4947dc6793e5af56d6dd0e6eed9e570f

Add zero_extendi and sign_extendi to intrinsic namespace Summary: - update zero_extendi and sign_extendi in edsc/intrinsic namespace - Builder API test for zero_extendi and sign_extendi Differential Revision: https://reviews.llvm.org/D72298

view details

push time in a month

push eventllvm/llvm-project

Kern Handa

commit sha ea67737b166fc6cb5fd98874fbd2b4639b2d7ecd

[mlir] mlir-cpu-runner test's cblas_interface should export functions on Windows This change fixes the build on Windows, so that cblas_interface.dll exports functions correctly and an implib is created and installed correctly. Currently, LLVM cannot be consumed on Windows after it has been installed in a location because cblas_interface.lib is not created/installed, thus failing the import check in `LLVMExports.cmake`. Differential Revision: https://reviews.llvm.org/D72384

view details

Eric Schweitz

commit sha 016bf03ef6fcd9dce43b0c17971f76323f07a684

[mlir] add a missing dependency for Linalg conversion We were seeing some occasional build failures that would come and go. It appeared to be this missing dependence. Differential Revision: https://reviews.llvm.org/D72419

view details

push time in a month

push eventllvm/llvm-project

Alex Zinenko

commit sha 08778d8c4fd8a6519c7f27bfa6b09c47262cb844

[mlir][GPU] introduce utilities for promotion to workgroup memory Introduce a set of function that promote a memref argument of a `gpu.func` to workgroup memory using memory attribution. The promotion boils down to additional loops performing the copy from the original argument to the attributed memory in the beginning of the function, and back at the end of the function using all available threads. The loop bounds are specified so as to adapt to any size of the workgroup. These utilities are intended to compose with other existing utilities (loop coalescing and tiling) in cases where the distribution of work across threads is uneven, e.g. copying a 2D memref with only the threads along the "x" dimension. Similarly, specialization of the kernel to specific launch sizes should be implemented as a separate pass combining constant propagation and canonicalization. Introduce a simple attribute-driven pass to test the promotion transformation since we don't have a heuristic at the moment. Differential revision: https://reviews.llvm.org/D71904

view details

push time in a month

push eventllvm/llvm-project

Kern Handa

commit sha aab72f89b19ae38ea7ac3b7b51aae68fc10aef4f

[mlir] Update mlir/CMakeLists.txt to install *.def files This is needed to consume mlir after it has been installed of the source tree. Without this, consuming mlir results a build error. Differential Revision: https://reviews.llvm.org/D72232

view details

push time in a month

issue commenttensorflow/mlir

[LLVM] Implement missing LLVM IR instructions

We have not migrated issues (yet).

AFAIK, there's ongoing work on switch, invoke and landingpad.

On Thu, Jan 2, 2020 at 12:42 PM Marius Brehler notifications@github.com wrote:

Is this issue still up to date? So far it was at least not transferred to LLVM bug tracker https://bugs.llvm.org/buglist.cgi?keywords=beginner%2C &keywords_type=allwords&list_id=176893&product=MLIR&query_format=advanced&resolution=---, as mentioned in docs https://mlir.llvm.org/getting_started/Contributing/ .

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/tensorflow/mlir/issues/276?email_source=notifications&email_token=AALRG237WRQDC7A46WIUIHLQ3XHK7A5CNFSM4JR5FSM2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEH6FIVY#issuecomment-570184791, or unsubscribe https://github.com/notifications/unsubscribe-auth/AALRG2ZGTFGWQF6RSJRFUP3Q3XHK7ANCNFSM4JR5FSMQ .

-- Alex

ftynse

comment created time in 2 months

push eventllvm/mlir-www

Alex Zinenko

commit sha 54d3a579472fec97603d0dc3f1e1884356c9e980

Fix link to DeveloperGuide from Contributing.md

view details

push time in 2 months

push eventllvm/llvm-project

Kern Handa

commit sha cde071c4bfb78ee8fe34f7c4f4cead7869b26a76

[mlir] Update mlir/CMakeLists.txt to install *.td files Currently when you build the `install` target, TableGen files don't get installed. TableGen files are needed when authoring new MLIR dialects, but right now they're missing when using the pre-built binaries. Differential Revision: https://reviews.llvm.org/D71958

view details

push time in 2 months

pull request commenttensorflow/mlir

Fix the wrong computation of dynamic strides for lowering AllocOp to LLVM

Landed as https://github.com/llvm/llvm-project/commit/e5957ac3d7135eca95b4019eaa394703ad6112a6.

Since MLIR moved to LLVM, please submit your following contributions through https://reviews.llvm.org. Thank you!

@joker-eph could you please close?

tungld

comment created time in 2 months

push eventllvm/llvm-project

Tung Le Duc

commit sha e5957ac3d7135eca95b4019eaa394703ad6112a6

[mlir] Fix the wrong computation of dynamic strides for lowering AllocOp to LLVM Leftover change from before the MLIR merge, reviewed at accepted at https://github.com/tensorflow/mlir/pull/338.

view details

push time in 2 months

pull request commenttensorflow/mlir

fix typos

Landed as https://github.com/llvm/llvm-project/commit/2e5a75581c7636fb223ebda6297f7be62ffe6b1e. Thanks for your contribution! MLIR moved to the LLVM project, please follow the new contributing guide for your subsequent patches.

wyzero

comment created time in 2 months

push eventllvm/llvm-project

wyzhao

commit sha 2e5a75581c7636fb223ebda6297f7be62ffe6b1e

[mlir] fix typo in a comment Trivial patch, reviewed and accepted on https://github.com/tensorflow/mlir/pull/336 before MLIR merge.

view details

push time in 2 months

push eventllvm/llvm-project

Uday Bondhugula

commit sha be775a003856fe65ce8dc05075192da65975806f

[MLIR] [NFC] fix unused var warning Summary: Fix this warning: ` [69/106] Building CXX object tools/mlir/lib/Dialect/StandardOps/CMakeFiles/MLIRStandardOps.dir/Ops.cpp.o /home/uday/llvm-project/mlir/lib/Dialect/StandardOps/Ops.cpp: In member function ‘virtual mlir::PatternMatchResult {anonymous}::ViewOpShapeFolder::matchAndRewrite(mlir::ViewOp, mlir::PatternRewriter&) const’: /home/uday/llvm-project/mlir/lib/Dialect/StandardOps/Ops.cpp:2575:14: warning: variable ‘dynamicOffsetOperandCount’ set but not used [-Wunused-but-set-variable] 2575 | unsigned dynamicOffsetOperandCount = 0; ` Reviewers: rriddle, mehdi_amini, ftynse Reviewed By: ftynse Subscribers: jpienaar, burmako, shauheen, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D71922

view details

push time in 2 months

push eventllvm/llvm-project

Alex Zinenko

commit sha cda94d3e8ae3679eb75988afc85faa1e14068a83

[mlir] Floating constants for import-llvm Summary: `mlir-translate -import-llvm test.ll` was going into segmentation fault if `test.ll` had `float` or `double` constants. For example, ``` %3 = fadd double 3.030000e+01, %0 ``` Now, it is handled in `Importer::getConstantAsAttr` (similar behaviour as normal integers) Added tests for FP arithmetic Reviewers: ftynse, mehdi_amini Reviewed By: ftynse, mehdi_amini Subscribers: shauheen, mehdi_amini, rriddle, jpienaar, burmako, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D71912

view details

push time in 2 months

pull request commenttensorflow/mlir

Custom lowering of MemRefs to LLVM

It's a typical trade-off. If there is a new operation added to dialect X, somebody will have to implement conversions from it to other dialects. Whether it should be the owner of dialect X, or the owners of other dialects is up for negotiation between those owners. If the other dialects are not upstream, it's unlikely that the owner of dialect X will be able to do anything about it. (that being said, the conversion will not necessarily break, but may not support the newly added operation).

So it feels like your main concern is about the lowering being out-of-tree. If we did have an API for the descriptor, nothing would prevent the owner of the in-tree lowering from changing that API and still breaking external projects that rely on it. And it would be a compilation error, not just a properly reported "could not lower" runtime error.

dcaballe

comment created time in 2 months

issue commenttensorflow/mlir

llvm.noalias attribute on Memref arguments is not properly lowered

Basically, what I said in the PR. Of course we can always create our own LLVM lowering but that has a high maintainability and code duplication cost.

LLVM lowering isn't a monolithic pass and it shouldn't be, so I would argue you are not creating an entirely new lowering, just changing the part that you want to be handled differently. As for the duplication cost, given how different is the lowering scheme, how much code would be actually duplicated? Most of the code in the current patterns is handling dynamic sizes and strides and it's essentially dead if you don't have them. If there is something reusable indeed, that can be factored out into helper functions or something like pattern factories.

A custom LLVM lowering won't have control on the Std ops reaching the lowering

It should be possible to return matchFailure() from the pattern. Actually, by having a custom pattern you get the possibility of accepting different operations than the current lowering does. By patching into the current lowering you must support everything it does and cannot support anything else.

That's because I didn't want to change the existing API to minimize changes. I hoped the API could be turned into something more generic in subsequent patches.

If we push the "being generic" part a couple of steps further (e.g., don't rely on the specific descriptor API, having allocated/aligned pointers, etc.), we will essentially get the default pattern along the lines of

// load/store loewring
BaseDescriptor d = lowering.convertMemRefToOpaqueDescriptor(memref.getType());
Value *p = lowering.computeActualAddressAndGetPointerFromDescriptor(d, indices);
rewriter.repalceOpWithNewOp<LLVM::LoadOp>(op, p);

at which point, having any sort of dispatch to actual implementations from the "default" pattern looks like overhead compared to just having different patterns.

Maybe a good trade-off could be hosting upstream these alternative LLVM patterns to lower MemRef to plain pointers. If I understood correctly, there are more people interested in this. That would reduce the maintainability burden and maybe some code reuse across lowerings is possible. WDYT?

This would shift the burden on whoever updates the core, not necessarily reduce it. But I understand the concern of getting out of sync. So I'm fine with upstreaming an additional lowering for memrefs to go to bare pointers when possible and failing otherwise. IMO, this can still be implemented as separate patterns producing simple code, sharing implementation helpers if reasonable. The choice between lowerings can be controlled by an option in the pass, similarly to what we do for malloc/alloca.

dcaballe

comment created time in 2 months

Pull request review commenttensorflow/mlir

Fix the wrong computation of dynamic strides for lowering AllocOp to LLVM

 struct AllocOpLowering : public LLVMLegalizationPattern<AllocOp> {     // Iterate strides in reverse order, compute runningStride and strideValues.     auto nStrides = strides.size();     SmallVector<Value, 4> strideValues(nStrides, nullptr);-    for (auto indexedStride : llvm::enumerate(llvm::reverse(strides))) {+    for (auto indexedStride : llvm::enumerate(strides)) {

Actually, enumerate is useless here, the body of the loop never accesses indexedStride.value(). Could you just rewrite the loop to iterate on index to remove the confusion that led to the bug in the first place?

tungld

comment created time in 2 months

pull request commenttensorflow/mlir

Custom lowering of MemRefs to LLVM

Wouldn't it be simpler to just provide a set of patterns that lower memref-related ops differently, here's a list https://github.com/llvm/llvm-project/blob/master/mlir/lib/Conversion/StandardToLLVM/ConvertStandardToLLVM.cpp#L2126

dcaballe

comment created time in 2 months

issue commenttensorflow/mlir

llvm.noalias attribute on Memref arguments is not properly lowered

However, that was not enough since Std-to-LLVM conversion uses MemRefDescriptor class all over the place, which assumes that MemRef type is lowered to the struct descriptor and generates the corresponding insertion and extraction operations to/from the struct.

That's why I separated the memref-related patterns into a separate populate* function. My suggestion was to

provide the lowering patterns for std operations listed in populateStdToLLVMMemoryConversionPattern

that is, implement new patterns that are aware of a different lowering scheme and use them instead of the existing ones. A different lowering pattern indeed removes your problem with ABI requirements in function signature. I think using different patterns for different lowering schemes is the right solution achieving better separation of concerns. It is also significantly easier to implement that custom ABI support. Why are you not happy with it?

I did not read #337 in detail, but it goes in the wrong direction IMO. It essentially makes the current descriptor more standard and requires any other implementation to comply with its API. There may be cases where the offset field or the differentiation between allocated and aligned don't make sense. (Bare pointers is one of them, although you might get away with it. Using more complex layouts than sizes+strides will be impossible). So why insist on reusing the existing patterns through an extra layer of indirection when defining new patterns, which would also produce cleaner IR that is aware of the actual descriptor, is relatively cheap?

dcaballe

comment created time in 2 months

push eventllvm/mlir-www

Alex Zinenko

commit sha f1355ce7eb1fc0239322df899053130995547ce0

Hugo config: disable URL conversion to lower case MLIR documentation pervasively uses CamelCased file names and links to them were broken if the served files were lowercased.

view details

Alex Zinenko

commit sha e35b0d8cf3e3f0b120b16ccf1e97bed75ae6ae3f

Fix link to "symbol references" on the main page

view details

push time in 2 months

push eventllvm/llvm-project

Alex Zinenko

commit sha a28b65b27922b49cbc7bfba5b35cc5ebe7340373

[docs] fix typo in Lexicon.rst Differential revision: https://reviews.llvm.org/D71844

view details

push time in 2 months

Pull request review commenttensorflow/mlir

Add zero_extendi and sign_extendi to intrinsic namespace

 TEST_FUNC(insertion_in_block) {   f.erase(); } +TEST_FUNC(zeroextendi_op_i1_to_i8) {+  using namespace edsc;+  using namespace edsc::intrinsics;+  using namespace edsc::op;+  auto i1Type = IntegerType::get(1, &globalContext());+  auto i8Type = IntegerType::get(8, &globalContext());+  auto memrefType = MemRefType::get({-1, -1}, i1Type, {}, 0);+  auto f = makeFunction("zero_extendi_op", {}, {memrefType});++  OpBuilder builder(f.getBody());+  ScopedContext scope(builder, f.getLoc());+  // clang-format off+  ValueHandle zero = constant_index(0), one = constant_index(1);+  MemRefView vA(f.getArgument(0));+  IndexedValue A(f.getArgument(0));+  IndexHandle i, j;+  AffineLoopNestBuilder({&i, &j}, {zero, zero}, {one, one}, {1, 1})([&]{+    // This test exercises IndexedValue::operator Value*.+    // Without it, one must force conversion to ValueHandle as such:+    // edsc::intrinsics::zero_extendi(ValueHandle(ValueA(i, j), i8Type)+    edsc::intrinsics::zero_extendi(*A(i, j), i8Type);+  });++  // CHECK-LABEL: @zero_extendi_op+  //      CHECK: affine.for %{{.*}} = 0 to 1 {+  // CHECK-NEXT:   affine.for %{{.*}} = 0 to 1 {+  // CHECK-NEXT:     %[[SRC:.*]] = affine.load+  //      CHECK:     zexti %[[SRC]] : i1 to i8+  // clang-format on+  f.print(llvm::outs());+  f.erase();+}++TEST_FUNC(signextendi_op_i1_to_i8) {+  using namespace edsc;+  using namespace edsc::intrinsics;+  using namespace edsc::op;+  auto i1Type = IntegerType::get(1, &globalContext());+  auto i8Type = IntegerType::get(8, &globalContext());+  auto memrefType = MemRefType::get({-1, -1}, i1Type, {}, 0);+  auto f = makeFunction("sign_extendi_op", {}, {memrefType});++  OpBuilder builder(f.getBody());+  ScopedContext scope(builder, f.getLoc());+  // clang-format off+  ValueHandle zero = constant_index(0), one = constant_index(1);+  MemRefView vA(f.getArgument(0));+  IndexedValue A(f.getArgument(0));+  IndexHandle i, j;+  AffineLoopNestBuilder({&i, &j}, {zero, zero}, {one, one}, {1, 1})([&]{

Could you make these tests more minimal? They end up testing the combination of AffineLoopNextBuilder, IndexedValue, accessor generator and the call you introduced. Building something like

func @f(%arg0: i1) -> i8 {
  %0 = sextend_i %arg0 : i1 to i8
  return %0 : i8
}

should be sufficient and would minimize the risk of this test being broken when irrelevant parts (affine loops, indexedValue) are changed.

pruthviIntel

comment created time in 2 months

pull request commenttensorflow/mlir

fix isValidDim for block arg case

Could you please describe what is the problem that you are fixing in the commit message? Thanks!

I was thinking the test case was sufficient - but have updated the commit message. Thanks!

I'm nitpicking, but as the scale of the project grows, I'm expecting some people following the development will read commit messages but will not take the time to look into the actual change. Thanks!

bondhugula

comment created time in 2 months

Pull request review commenttensorflow/mlir

fix isValidDim for block arg case

 func @slicing_test() { // FWDBWD-LABEL: slicing_test_2 func @slicing_test_2() {   %c0 = constant 0 : index-  %c1 = constant 1 : index   %c2 = constant 2 : index   %c16 = constant 16 : index-  loop.for %i0 = %c0 to %c16 step %c1 {

My bad, I missed it was used in the map in the nested affine.for.

bondhugula

comment created time in 2 months

Pull request review commenttensorflow/mlir

fix isValidDim for block arg case

 func @slicing_test() { // FWDBWD-LABEL: slicing_test_2 func @slicing_test_2() {   %c0 = constant 0 : index-  %c1 = constant 1 : index   %c2 = constant 2 : index   %c16 = constant 16 : index-  loop.for %i0 = %c0 to %c16 step %c1 {

This change doesn't look relevant to the commit.

bondhugula

comment created time in 2 months

PR opened LoopTactics/mlir

First take on matchers

DO NOT MERGE: for illustrative purposes only

I wrote a quick sketch of an operational matcher for matmul, with permutations of indices and permutations of independent operations (loads) thanks to use-def chains. It's only the matching, the builder should be rather straighforward if we go to Linalg.

I did not want to bother with the infrastructure setup so I (ab)used the affine-to-std lowering to experiment, should be runnable with mlir-opt -lower-affine.

func @foo(%A: memref<42x42xf32>, %B: memref<42x42xf32>, %C: memref<42x42xf32>) {
  affine.for %i = 0 to 42 {
    affine.for %j = 0 to 42 {
      affine.for %k = 0 to 42 {
        %0 = affine.load %A[%i, %k] : memref<42x42xf32>
        %1 = affine.load %B[%k, %j] : memref<42x42xf32>
        %2 = affine.load %C[%i, %j] : memref<42x42xf32>
        %3 = mulf %0, %1 : f32
        %4 = addf %2, %3 : f32
        affine.store %4, %C[%i, %j] : memref<42x42xf32>
      }
    }
  }
  return
}
+322 -24

0 comment

7 changed files

pr created time in 2 months

create barnchftynse/mlir

branch : matchers

created branch time in 2 months

push eventftynse/mlir

brett koonce

commit sha ed79884122e73f0c40e491eb9f4be42aecf3d89f

docs: minor spelling tweaks Closes #262 COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/mlir/pull/262 from brettkoonce:docs-sp 6833fc8aa41edd02d8bc7c3cbb84211cb8b0334c PiperOrigin-RevId: 283352765

view details

Mehdi Amini

commit sha 0d5578bd1e9d213d426b21f6257207ff7746b616

Generate dialect documentations in the doc folder for every dialect Also add a mlir-doc build target to general all the docs PiperOrigin-RevId: 283353529

view details

Lei Zhang

commit sha 6b1aaa445dbe4bc497ff4d067ba6bbe66f08dd54

[ODS] Generate builders taking unwrapped value and defaults for attributes Existing builders generated by ODS require attributes to be passed in as mlir::Attribute or its subclasses. This is okay foraggregate- parameter builders, which is primarily to be used by programmatic C++ code generation; it is inconvenient for separate-parameter builders meant to be called in manually written C++ code because it requires developers to wrap raw values into mlir::Attribute by themselves. This CL extends to generate additional builder methods that take raw values for attributes and handles the wrapping in the builder implementation. Additionally, if an attribute appears late in the arguments list and has a default value, the default value is supplied in the declaration if possible. PiperOrigin-RevId: 283355919

view details

Aart Bik

commit sha e7d0ee30cd7284deab62d71d362b7ca447709461

[VectorOps] Add legality rules to broadcast PiperOrigin-RevId: 283360101

view details

Lei Zhang

commit sha 69c78bed1610906ee078ff7f188820d18812724d

NFC: use `&&` instead of `and` PiperOrigin-RevId: 283392575

view details

Lei Zhang

commit sha b7e6270e6a06fb67b5215e1647774143abaf506c

[spirv] NFC: reorder sections in SPIRVBase.td Put extensions and capabilities at the very beginning because they will be referenced later by other definitions. PiperOrigin-RevId: 283416972

view details

Alex Zinenko

commit sha ff338ae017fe26b06f0fe5cd669b621fdb9ff7ab

Add linkage support to LLVMFuncOp A recent commit introduced the Linkage attribute to the LLVM dialect and used it in the Global Op. Also use it in LLVMFuncOp. As per LLVM Language Reference, if the linkage attribute is omitted, the function is assumed to have external linkage. PiperOrigin-RevId: 283493299

view details

Alexander Belyaev

commit sha 223636113a55aa283fac9d42e66f3f48df72ae7f

[Linalg] Update/fix documentation for linalg.indexed_generic. PiperOrigin-RevId: 283503642

view details

Lei Zhang

commit sha 504af824c095154fd9616d349a43b0cb31e2ec4b

[spirv] Add spv.SubgroupBallotKHROp PiperOrigin-RevId: 283522284

view details

Stephan Herhut

commit sha 822f589ea604d97f89163218af4e22b4c0a4c7df

Extend conversion of SubViewOp to llvm to also support cases where size and stride are constant (i.e., there are no size and stride operands). We recently added canonicalization that rewrites constant size and stride operands to SubViewOp into static information in the type, so these patterns now occur during code generation. PiperOrigin-RevId: 283524688

view details

Diego Caballero

commit sha 69607ea4d76e0ae3f391ef388edc9b6aa8aa3f28

AffineLoopFusion: Prevent fusion of multi-out-edge producer loops #162 introduced a bug that incorrectly allowed fusion of producer loops with multiple outgoing edges. This commit fixes that problem. It also introduces a new flag to disable sibling loop fusion so that we can test producer-consumer fusion in isolation. Closes #259 COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/mlir/pull/259 from dcaballe:dcaballe/fix_multi_out_edge_producer_fusion 578d5661705fd5c56c555832d5e0528df88c5282 PiperOrigin-RevId: 283531105

view details

Alex Zinenko

commit sha 721a07c11feb30eee2462ec2fa7b3ce3ac2b4779

Fix ViewOp to have at most one offset operand As described in the documentation, ViewOp is expected to take an optional dynamic offset followed by a list of dynamic sizes. However, the ViewOp parser did not include a check for the offset being a single value and accepeted a list of values instead. Furthermore, several tests have been exercising the wrong syntax of a ViewOp, passing multiple values to the dyanmic stride list, which was not caught by the parser. The trailing values could have been erronously interpreted as dynamic sizes. This is likely due to resyntaxing of the ViewOp, with the previous syntax taking the list of sizes before the offset. Update the tests to use the syntax with the offset preceding the sizes. Worse, the conversion of ViewOp to the LLVM dialect assumed the wrong order of operands with offset in the trailing position, and erronously relied on the permissive parsing that interpreted trailing dynamic offset values as leading dynamic sizes. Fix the lowering to use the correct order of operands. PiperOrigin-RevId: 283532506

view details

MLIR Team

commit sha 06f6958c9771ef2a26f67fb14aa0138ae4a46304

Add python bindings for ArrayAttr, AffineMapAttr. PiperOrigin-RevId: 283561252

view details

MLIR Team

commit sha 343469c09d600381f92157b2c542fc6b69e33073

Add Python bindings for affine expressions with binary operators. PiperOrigin-RevId: 283569325

view details

Mahesh Ravishankar

commit sha 569f3c5940bb27d8553a21a3f132dd492f3553b7

Convert MemRefType to a linearized array in SPIR-V lowering. The SPIR-V lowering used nested !spv.arrays to represented multi-dimensional arrays, with the hope that in-conjunction with the layout annotations, the shape and layout of memref can be represented directly. It is unclear though how portable this representation will end up being. It will rely on driver compilers implementing complex index computations faithfully. A more portable approach is to use linearized arrays to represent memrefs and explicitly instantiate all the index computation in SPIR-V. This gives added benefit that we can further optimize the generated code in MLIR before generating the SPIR-V binary. PiperOrigin-RevId: 283571167

view details

River Riddle

commit sha 908965b38bc36f71fa1ee14a114da5efb9657361

Allow analyses to provide a hook 'isInvalidated' to determine if they are truly invalidated. The hook has the following form: * `bool isInvalidated(const AnalysisManager::PreservedAnalyses &)` Given a preserved analysis set, the analysis returns true if it should truly be invalidated. This allows for more fine-tuned invalidation in cases where an analysis wasn't explicitly marked preserved, but may be preserved(or invalidated) based upon other properties; such as analyses sets. PiperOrigin-RevId: 283582889

view details

Sean Silva

commit sha 15c73d3b4127712885adc623e267c8487cbff5ed

Verifier: Better error message in case of successor operand mismatch. In particular, print the successor number in the diagnostic. PiperOrigin-RevId: 283585084

view details

Andy Davis

commit sha 3823548ef17c3e6103167e565a52d4315cb5e712

Add CreateMaskOp to the VectorOps dialect. PiperOrigin-RevId: 283591888

view details

Sean Silva

commit sha 155babc78c5b463bc185c0dc3421e4269cd64338

Make diagnostic a bit clearer. This prints out in case of any pass failure. Not just a crash. PiperOrigin-RevId: 283616719

view details

Mahesh Ravishankar

commit sha f8bac485e4010e390fee72c3ae567f7e95225731

Add a pass to legalize operations before lowering to SPIR-V. Not all StandardOps can be lowered to SPIR-V. For example, subview op implementation requires use of pointer bitcasts which is not valid according to SPIR-V spec (or at least is ambiguous about it). Such ops need to be removed/transformed before lowering to SPIR-V. The SPIRVLegalizationPass is added a place where such legalizations can be added. Current implementation folds the subview ops with load/stores so that the lowering itself does not have to convert a subview op. PiperOrigin-RevId: 283642981

view details

push time in 2 months

delete branch ftynse/mlir

delete branch : matchers

delete time in 2 months

issue commenttensorflow/mlir

llvm.noalias attribute on Memref arguments is not properly lowered

https://github.com/tensorflow/mlir/commit/291a309d7164d9d38a8cc11cfdf88ca2ff709da0 implemented a separation between memory-related conversion patterns and the remaining patterns. From there, it should suffice to derive LLVMTypeConverter, override its convertType() to lower MemRefType differently while deferring to the base class for the other types, and provide the lowering patterns for std operations listed in populateStdToLLVMMemoryConversionPattern. This should unblock you in the short term by doing local changes in your pipeline. We remain open to discuss upstream solutions.

dcaballe

comment created time in 2 months

pull request commenttensorflow/mlir

Introduce prefetch op: affine -> std -> llvm intrinsic

@bondhugula please fix this and let's land

/usr/local/google/home/zinenko/llvm-project/llvm/projects/mlir/lib/Conversion/StandardToLLVM/ConvertStandardToLLVM.cpp: In member function ‘virtual mlir::PatternMatchResult {anonymous}::PrefetchOpLowering::matchAndRewrite(mlir::Operation*, llvm::ArrayRef<mlir::Value*>, mlir::ConversionPatternRewriter&) const’:
/usr/local/google/home/zinenko/llvm-project/llvm/projects/mlir/lib/Conversion/StandardToLLVM/ConvertStandardToLLVM.cpp:1470:39: error: ‘prefetch’ is not a member of ‘mlir::LLVM’
     rewriter.replaceOpWithNewOp<LLVM::prefetch>(op, dataPtr, isWrite,
                                       ^~~~~~~~
/usr/local/google/home/zinenko/llvm-project/llvm/projects/mlir/lib/Conversion/StandardToLLVM/ConvertStandardToLLVM.cpp:1470:39: note: suggested alternative: ‘Prefetch’
     rewriter.replaceOpWithNewOp<LLVM::prefetch>(op, dataPtr, isWrite,
                                       ^~~~~~~~
                                       Prefetch
/usr/local/google/home/zinenko/llvm-project/llvm/projects/mlir/lib/Conversion/StandardToLLVM/ConvertStandardToLLVM.cpp:1470:39: error: ‘prefetch’ is not a member of ‘mlir::LLVM’
/usr/local/google/home/zinenko/llvm-project/llvm/projects/mlir/lib/Conversion/StandardToLLVM/ConvertStandardToLLVM.cpp:1470:39: note: suggested alternative: ‘Prefetch’
     rewriter.replaceOpWithNewOp<LLVM::prefetch>(op, dataPtr, isWrite,
                                       ^~~~~~~~
                                       Prefetch
/usr/local/google/home/zinenko/llvm-project/llvm/projects/mlir/lib/Conversion/StandardToLLVM/ConvertStandardToLLVM.cpp:1471:69: error: no matching function for call to ‘mlir::ConversionPatternRewriter::replaceOpWithNewOp<<expression error> >(mlir::Operation*&, mlir::Value*&, mlir::LLVM::ConstantOp&, mlir::LLVM::ConstantOp&, mlir::LLVM::ConstantOp&)’
                                                 localityHint, isData);
bondhugula

comment created time in 2 months

issue commenttensorflow/mlir

can toy language generate cuda code?

Are there any plans to add an GPU path tutorial/example?

GPU path is pretty much work-in-progress, there is no robust lowering from arbitrary loops to GPU kernels. We may consider it for an updated version of the tutorial in future.

MingliSun

comment created time in 2 months

issue commenttensorflow/mlir

llvm.noalias attribute on Memref arguments is not properly lowered

There was another person on the mailing list interested in mermef lowering schemes other than our current descriptors, so I think providing an easy way to plug into the std->llvm lowering is a reasonable short-term solution. This will allow one to implement the point 2. from Nicolas's comment above as a lowering option.

Note that the dialect conversion framework actually supports one-to-many rewrites of function arguments, so it is technically possible to unpack the descriptor into individual arguments, and potentially rewrite the allocated+aligned pair of aliasing pointers into allocated+alignment_offset pair of non-aliasing pointers and integer. However, using multiple arguments to a function quickly gets into the ABI territory if you want to interact with C code.

The longer-term solution would be to introduce an alias model into MLIR proper, and I would be happy to see an RFC going into that direction.

I was wondering if we currently have support to represent metadata in LLVM-IR dialect in some way.

There's no direct support for LLVM metadata, but using attributes to model individual pieces of metadata on the need-driven basis is the way to go IMO.

AFAIK, they are the only thing (besides integer sets) which have out of line definitions/IR printing.

Any attributes are allowed in attribute aliases, https://github.com/tensorflow/mlir/blob/master/g3doc/LangRef.md#attribute-value-aliases, in particular array and dictionary attributes work perfectly fine and are exercised by linalg/structured ops.

#scope0 = [0,1]
#scope1 = [2,3]
#scope3 = [#scope0, #scope1]

llvm.func @foo() {
  // ...
  llvm.load %0 {llvm.alias_scope = #scope3} : !llvm<"float*">
}

could work just fine. The problem with this approach (and with affine maps) is that it could create arbitrarily nested structures, potentially with repeating values inside, rather than become a flattened integer set. If we were to model this properly, I would suggest introducing a separate attribute type that has set-like behavior with unpacking on top of a list. There was a discussion in the mailing list on introducing leading keywords in attribute syntax to disambiguate between affine maps and function types, so something like #scope = flatset {0, 1} would make sense eventually.

dcaballe

comment created time in 2 months

issue commenttensorflow/mlir

three unexpected test failures:mlir-cuda-runner

CUDA failed with 700 in StreamSync

700 is an illegal memory access...

MingliSun

comment created time in 2 months

pull request commenttensorflow/mlir

Introduce prefetch op: affine -> std -> llvm intrinsic

Sorry for more delay, we are experiencing integration issues with LLVM that cause test breakage. This will be landed as soon as the tests are able to pass again.

bondhugula

comment created time in 2 months

pull request commenttensorflow/mlir

Fix warning with struct forward declared as class

Thanks!

thewilsonator

comment created time in 2 months

pull request commenttensorflow/mlir

Introduce prefetch op: affine -> std -> llvm intrinsic

The point of having a prefetch op's affine map with the op is no different than the motivation of keeping an affine load or store's map with the op itself. The idea is that whenever the op moves, we want its affine function to move along with it - it's math sort of atomic with it as opposed to a real operation. It's an unnecessary pain to trace the chain of affine.applys and move those along when the prefetch op moves (for eg. when performing fusion/code motion where the prefetch ops are being moved, its affine.applys would have to move along.). We are completely getting rid of creating affine applys that supply results into affine.load/store from everywhere in Transforms/ (it's not completely done yet @andydavis1 @nicolasvasilache have had this discussion ) - affine applys will only exist in some other cases. As for affine.prefetch ops, they could be inserted by passes as well as domain op-specific optimization recipes (typically just in front of loads but with negative shifted subscripts). So their movement is better treated in a way consistent with affine.load/store for things like loop fusion/distribution, peeling, relative shifting, and pipelining.

My main concern here is duplication of ops and relevant code. I know the rationale for affine.load/store, I pushed for it. The question is how many other operations would need a similar affine/std duplication? If there are some more coming, we should consider some consolidation scheme that would be able to "lift" standard ops into affine counterparts by adding more features/constraints in the code. Out of scope for this PR, obviously.

I don't have anything else similiar in the pipeline - nor any future ops that'd follow this path. The other pending affine op (affine.grayboxop) is completely different.

Works for me, please fix the remaining small comments so we can land.

bondhugula

comment created time in 2 months

Pull request review commenttensorflow/mlir

Introduce prefetch op: affine -> std -> llvm intrinsic

 OpFoldResult AffineMinOp::fold(ArrayRef<Attribute> operands) {   return results[minIndex]; } +//===----------------------------------------------------------------------===//+// AffinePrefetchOp+//===----------------------------------------------------------------------===//++ParseResult parseAffinePrefetchOp(OpAsmParser &parser, OperationState &result) {

Could we have a comment describing the syntax this function understands?

Also, consider declaring it and functions below static

bondhugula

comment created time in 2 months

Pull request review commenttensorflow/mlir

Introduce prefetch op: affine -> std -> llvm intrinsic

 def LLVM_FMulAddOp : LLVM_Op<"intr.fmuladd", [NoSideEffect]>,   }]; } +def LLVM_prefetch : LLVM_ZeroResultOp<"intr.prefetch">,

The classes around follow the naming pattern LLVM_CamelCasedOp, please make sure we keep it that way.

bondhugula

comment created time in 2 months

Pull request review commenttensorflow/mlir

Introduce prefetch op: affine -> std -> llvm intrinsic

 OpFoldResult AffineMinOp::fold(ArrayRef<Attribute> operands) {   return results[minIndex]; } +//===----------------------------------------------------------------------===//+// AffinePrefetchOp+//===----------------------------------------------------------------------===//++ParseResult parseAffinePrefetchOp(OpAsmParser &parser, OperationState &result) {+  auto &builder = parser.getBuilder();+  auto indexTy = builder.getIndexType();++  MemRefType type;+  OpAsmParser::OperandType memrefInfo;+  IntegerAttr hintInfo;+  BoolAttr isWriteInfo;+  BoolAttr isDataCacheInfo;+  auto i32Type = parser.getBuilder().getIntegerType(32);++  AffineMapAttr mapAttr;+  SmallVector<OpAsmParser::OperandType, 1> mapOperands;+  if (parser.parseOperand(memrefInfo) ||+      parser.parseAffineMapOfSSAIds(mapOperands, mapAttr,+                                    AffinePrefetchOp::getMapAttrName(),+                                    result.attributes) ||+      parser.parseComma() ||+      parser.parseAttribute(isWriteInfo, AffinePrefetchOp::getIsWriteAttrName(),+                            result.attributes) ||+      parser.parseComma() ||+      parser.parseAttribute(hintInfo, i32Type,+                            AffinePrefetchOp::getLocalityHintAttrName(),+                            result.attributes) ||+      parser.parseComma() ||+      parser.parseAttribute(isDataCacheInfo,+                            AffinePrefetchOp::getIsDataCacheAttrName(),+                            result.attributes) ||+      parser.parseOptionalAttrDict(result.attributes) ||+      parser.parseColonType(type) ||+      parser.resolveOperand(memrefInfo, type, result.operands) ||+      parser.resolveOperands(mapOperands, indexTy, result.operands))+    return failure();++  return success();+}++void print(OpAsmPrinter &p, AffinePrefetchOp op) {+  p << "affine.prefetch " << *op.getMemRef() << '[';+  AffineMapAttr mapAttr = op.getAttrOfType<AffineMapAttr>(op.getMapAttrName());+  if (mapAttr) {+    SmallVector<Value *, 2> operands(op.getMapOperands());+    p.printAffineMapOfSSAIds(mapAttr, operands);+  }+  p << ']' << ", " << (op.isWrite() ? "true" : "false") << ", "+    << op.localityHint() << ", " << (op.isDataCache() ? "true" : "false");+  p.printOptionalAttrDict(+      op.getAttrs(),+      /*elidedAttrs=*/{op.getMapAttrName(), op.getLocalityHintAttrName(),+                       op.getIsDataCacheAttrName(), op.getIsWriteAttrName()});+  p << " : " << op.getMemRefType();+}++LogicalResult verify(AffinePrefetchOp op) {+  auto mapAttr = op.getAttrOfType<AffineMapAttr>(op.getMapAttrName());+  if (mapAttr) {+    AffineMap map =+        op.getAttrOfType<AffineMapAttr>(op.getMapAttrName()).getValue();+    if (map.getNumResults() != op.getMemRefType().getRank())+      return op.emitOpError("affine.prefetch affine map num results must equal"+                            " memref rank");+    if (map.getNumInputs() + 1 != op.getNumOperands())+      return op.emitOpError("too few operands");

maybe we should provide more information there as well, it does not really cost us much

bondhugula

comment created time in 2 months

Pull request review commenttensorflow/mlir

Introduce prefetch op: affine -> std -> llvm intrinsic

 def AffineMinOp : Affine_Op<"min"> {   let hasFolder = 1; } +def AffinePrefetchOp : Affine_Op<"prefetch"> {+  let summary = "affine prefetch operation";+  let description = [{+    The "affine.prefetch" op prefetches data from a memref location described+    with an affine subscript similar to affine.load. For example:++      affine.prefetch %0[%i, %j + 5], %w, %h, %d : memref<400x400xi32>++    %w is true if the fetch should be for a write, false for a read, %h is a+    temporal locality specifier ranging from (0) - no locality, to (3) -+    extremely local keep in cache. %d specifies whether the prefetch+    is performed on the data cache, false if on the instruction cache.+  }];++  let arguments = (ins AnyMemRef:$memref, Variadic<Index>:$indices,+                   BoolAttr:$isWrite,+                   Confined<I32Attr, [IntMinValue<0>,+                     IntMaxValue<3>]>:$localityHint,+                   BoolAttr:$isDataCache);++  let builders = [OpBuilder<+    "Builder *builder, OperationState &result, Value *memref,"+    "AffineMap map, ArrayRef<Value *> mapOperands, bool isWrite,"

Any pointers on how I could add this to the ODS?

Since we ultimately generate C++ from ODS, you can declare classes enums in the header file in which you include the ODS-generated code, then just use them in builder signature.

assuming that checkers can catch out of order arguments. In fact, I find the latter more readable.

Readability is subjective so I won't insist on it. However, if I can have the mandatory tool (compiler) do the check, I take it instead of relying on some non-mandatory tool (linter) to complain that somebody forgot a comment or used a mismatching comment. A typical problem with sequences of non-typed bools/ints is the API change that changes, e.g., the order of arguments without breaking the compilation. Yes, we have linters that can catch it, but it is more a bandaid for legacy codebases IMO since we now have language features (enum classes) that prevent this problem from appearing in the first place.

bondhugula

comment created time in 2 months

pull request commenttensorflow/mlir

Introduce prefetch op: affine -> std -> llvm intrinsic

The point of having a prefetch op's affine map with the op is no different than the motivation of keeping an affine load or store's map with the op itself. The idea is that whenever the op moves, we want its affine function to move along with it - it's math sort of atomic with it as opposed to a real operation. It's an unnecessary pain to trace the chain of affine.applys and move those along when the prefetch op moves (for eg. when performing fusion/code motion where the prefetch ops are being moved, its affine.applys would have to move along.). We are completely getting rid of creating affine applys that supply results into affine.load/store from everywhere in Transforms/ (it's not completely done yet @andydavis1 @nicolasvasilache have had this discussion ) - affine applys will only exist in some other cases. As for affine.prefetch ops, they could be inserted by passes as well as domain op-specific optimization recipes (typically just in front of loads but with negative shifted subscripts). So their movement is better treated in a way consistent with affine.load/store for things like loop fusion/distribution, peeling, relative shifting, and pipelining.

My main concern here is duplication of ops and relevant code. I know the rationale for affine.load/store, I pushed for it. The question is how many other operations would need a similar affine/std duplication? If there are some more coming, we should consider some consolidation scheme that would be able to "lift" standard ops into affine counterparts by adding more features/constraints in the code. Out of scope for this PR, obviously.

bondhugula

comment created time in 2 months

Pull request review commenttensorflow/mlir

Added LLVM ops and lowering phases from standard dialect.

 def LLVM_ExpOp : LLVM_Op<"intr.exp", [NoSideEffect]>,     $res = builder.CreateCall(fn, {$in});   }]; }++def LLVM_FAbsOp : LLVM_Op<"intr.fabs", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$in)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::fabs, {$in->getType()});+    $res = builder.CreateCall(fn, {$in});+  }];+}++def LLVM_FCeilOp : LLVM_Op<"intr.ceil", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$in)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::ceil, {$in->getType()});+    $res = builder.CreateCall(fn, {$in});+  }];+}++def LLVM_CosOp : LLVM_Op<"intr.cos", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$in)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::cos, {$in->getType()});+    $res = builder.CreateCall(fn, {$in});+  }];+}++def LLVM_CopySignOp : LLVM_Op<"intr.copysign", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$a, LLVM_Type:$b)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::copysign, {$a->getType(), $b->getType()});+    $res = builder.CreateCall(fn, {$a, $b});+  }];+}++def LLVM_TanhOp : LLVM_Op<"tanh", [NoSideEffect]>,

We need a more detailed explanation of where these values come from and what is computed in the end.

dfki-jugr

comment created time in 2 months

pull request commenttensorflow/mlir

Added LLVM ops and lowering phases from standard dialect.

please do not merge this until the concerns on translation are addressed.

dfki-jugr

comment created time in 2 months

Pull request review commenttensorflow/mlir

Added LLVM ops and lowering phases from standard dialect.

 def LLVM_ExpOp : LLVM_Op<"intr.exp", [NoSideEffect]>,     $res = builder.CreateCall(fn, {$in});   }]; }++def LLVM_FAbsOp : LLVM_Op<"intr.fabs", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$in)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::fabs, {$in->getType()});+    $res = builder.CreateCall(fn, {$in});+  }];+}++def LLVM_FCeilOp : LLVM_Op<"intr.ceil", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$in)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::ceil, {$in->getType()});+    $res = builder.CreateCall(fn, {$in});+  }];+}++def LLVM_CosOp : LLVM_Op<"intr.cos", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$in)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::cos, {$in->getType()});+    $res = builder.CreateCall(fn, {$in});+  }];+}++def LLVM_CopySignOp : LLVM_Op<"intr.copysign", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$a, LLVM_Type:$b)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::copysign, {$a->getType(), $b->getType()});+    $res = builder.CreateCall(fn, {$a, $b});+  }];+}++def LLVM_TanhOp : LLVM_Op<"tanh", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$in)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{

This is way too long to be inline code in Tablegen. Please extract into a function and just call it here.

dfki-jugr

comment created time in 2 months

Pull request review commenttensorflow/mlir

Added LLVM ops and lowering phases from standard dialect.

 def LLVM_ExpOp : LLVM_Op<"intr.exp", [NoSideEffect]>,     $res = builder.CreateCall(fn, {$in});   }]; }++def LLVM_FAbsOp : LLVM_Op<"intr.fabs", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$in)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::fabs, {$in->getType()});+    $res = builder.CreateCall(fn, {$in});+  }];+}++def LLVM_FCeilOp : LLVM_Op<"intr.ceil", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$in)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::ceil, {$in->getType()});+    $res = builder.CreateCall(fn, {$in});+  }];+}++def LLVM_CosOp : LLVM_Op<"intr.cos", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$in)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::cos, {$in->getType()});+    $res = builder.CreateCall(fn, {$in});+  }];+}++def LLVM_CopySignOp : LLVM_Op<"intr.copysign", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$a, LLVM_Type:$b)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::copysign, {$a->getType(), $b->getType()});+    $res = builder.CreateCall(fn, {$a, $b});+  }];+}++def LLVM_TanhOp : LLVM_Op<"tanh", [NoSideEffect]>,

If there is no tanh op in LLVM, it should not be an LLVM Op. Create it in some dialect and implement a lowering from that dialect to the LLVM dialect instead, so the translation from the LLVM dialect to LLVM IR is as simple as possible. Having magic constants in the translation wouldn't cut it.

If you implement your non-trivial conversion in as a conversion pattern, it is significantly easier to replace.

dfki-jugr

comment created time in 2 months

Pull request review commenttensorflow/mlir

Added LLVM ops and lowering phases from standard dialect.

 def LLVM_ExpOp : LLVM_Op<"intr.exp", [NoSideEffect]>,     $res = builder.CreateCall(fn, {$in});   }]; }++def LLVM_FAbsOp : LLVM_Op<"intr.fabs", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$in)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::fabs, {$in->getType()});+    $res = builder.CreateCall(fn, {$in});+  }];+}++def LLVM_FCeilOp : LLVM_Op<"intr.ceil", [NoSideEffect]>,

There's a mismatch between op name (fceil) and intrinsic name (ceil), please fix.

dfki-jugr

comment created time in 2 months

Pull request review commenttensorflow/mlir

Added LLVM ops and lowering phases from standard dialect.

 def LLVM_ExpOp : LLVM_Op<"intr.exp", [NoSideEffect]>,     $res = builder.CreateCall(fn, {$in});   }]; }++def LLVM_FAbsOp : LLVM_Op<"intr.fabs", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$in)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::fabs, {$in->getType()});+    $res = builder.CreateCall(fn, {$in});+  }];+}++def LLVM_FCeilOp : LLVM_Op<"intr.ceil", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$in)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::ceil, {$in->getType()});+    $res = builder.CreateCall(fn, {$in});+  }];+}++def LLVM_CosOp : LLVM_Op<"intr.cos", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$in)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::cos, {$in->getType()});+    $res = builder.CreateCall(fn, {$in});+  }];+}++def LLVM_CopySignOp : LLVM_Op<"intr.copysign", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$a, LLVM_Type:$b)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::copysign, {$a->getType(), $b->getType()});+    $res = builder.CreateCall(fn, {$a, $b});+  }];+}++def LLVM_TanhOp : LLVM_Op<"tanh", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$in)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();++    llvm::Type *type = $in->getType();+    llvm::Value *max_value = llvm::ConstantFP::get(type, 20.0);

MLIR uses camelBack for variable names (see https://github.com/tensorflow/mlir/blob/master/g3doc/DeveloperGuide.md).

dfki-jugr

comment created time in 2 months

Pull request review commenttensorflow/mlir

Added LLVM ops and lowering phases from standard dialect.

 def LLVM_ExpOp : LLVM_Op<"intr.exp", [NoSideEffect]>,     $res = builder.CreateCall(fn, {$in});   }]; }++def LLVM_FAbsOp : LLVM_Op<"intr.fabs", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$in)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::fabs, {$in->getType()});+    $res = builder.CreateCall(fn, {$in});+  }];+}++def LLVM_FCeilOp : LLVM_Op<"intr.ceil", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$in)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::ceil, {$in->getType()});+    $res = builder.CreateCall(fn, {$in});+  }];+}++def LLVM_CosOp : LLVM_Op<"intr.cos", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$in)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::cos, {$in->getType()});+    $res = builder.CreateCall(fn, {$in});+  }];+}++def LLVM_CopySignOp : LLVM_Op<"intr.copysign", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$a, LLVM_Type:$b)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();+    llvm::Function *fn = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::copysign, {$a->getType(), $b->getType()});+    $res = builder.CreateCall(fn, {$a, $b});+  }];+}++def LLVM_TanhOp : LLVM_Op<"tanh", [NoSideEffect]>,+                   Arguments<(ins LLVM_Type:$in)>,+                   Results<(outs LLVM_Type:$res)> {+  let llvmBuilder = [{+    llvm::Module *module = builder.GetInsertBlock()->getModule();++    llvm::Type *type = $in->getType();+    llvm::Value *max_value = llvm::ConstantFP::get(type, 20.0);+    llvm::Function *fn_abs = llvm::Intrinsic::getDeclaration(+        module, llvm::Intrinsic::fabs, {$in->getType()});+    llvm::Value *abs_value = builder.CreateCall(fn_abs, {$in});++    llvm::Value *use_aprox =+      builder.CreateFCmpOLT(abs_value, llvm::ConstantFP::get(type, 0.0004));++    llvm::Value *clamp_max = llvm::ConstantFP::get(type, -9.0);+    llvm::Value *clamp_min = llvm::ConstantFP::get(type, 9.0);++    llvm::Value *cmp_upper_bound = builder.CreateFCmpOLT($in, clamp_max);+    llvm::Value *select_res =+      builder.CreateSelect(cmp_upper_bound, clamp_max, $in);+    llvm::Value *cmp_lower_bound =+      builder.CreateFCmpOLT(clamp_min, select_res);+    llvm::Value *input_clamped =+      builder.CreateSelect(cmp_lower_bound, clamp_min, select_res);++    static constexpr std::array<float, 7> numerator_coeffs{

The must be accompanied by a detailed comment of what you are doing here and why it should work.

dfki-jugr

comment created time in 2 months

more