[PATCH] D93591: [MLIR][SPIRV] Add (de-)serialization support for SpecConstantOpeation.

2021-01-10 Thread Lei Zhang via Phabricator via cfe-commits
antiagainst accepted this revision.
antiagainst added a comment.

Awesome, thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D93591/new/

https://reviews.llvm.org/D93591

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D93591: [MLIR][SPIRV] Add (de-)serialization support for SpecConstantOpeation.

2021-01-09 Thread Lei Zhang via Phabricator via cfe-commits
antiagainst requested changes to this revision.
antiagainst added a comment.
This revision now requires changes to proceed.

Awesome! I just have a few nits left now. Marked as blocking because we need to 
avoid change Clang code.




Comment at: clang-tools-extra/clangd/ClangdLSPServer.cpp:623
 {"referencesProvider", true},
-{"astProvider", true},
+{"astProvider", true}, // clangd extension
 {"executeCommandProvider",

Accidental change or rebase leftover?

Anyway we need to revert the change here. :)



Comment at: mlir/lib/Target/SPIRV/Deserialization.cpp:557
+  // mapping.
+  DenseMap>>
+  specConstOperationMap;

Just define a `struct` instead of using `std::tuple`? It will make the code 
more readable. Also we should use `SmallVector` instead of `ArrayRef` here. I 
guess ArrayRef is okay because we have access to the underlying SPIR-V blob 
right now; but it can be a potential hazard given ArrayRef does not owns the 
data.



Comment at: mlir/lib/Target/SPIRV/Deserialization.cpp:1811
+  // that there is no need to update this fake ID since we only need to
+  // reference the creaed Value for the enclosed op from the spv::YieldOp
+  // created later in this method (both of which are the only values in their

s/creaed/created/



Comment at: mlir/lib/Target/SPIRV/Deserialization.cpp:1816
+  // previous Value assigned to it isn't visible in the current scope anyway.
+  DenseMap newValueMap;
+  std::swap(valueMap, newValueMap);

What about using `llvm::SaveAndRestore` to avoid manually swap?



Comment at: mlir/lib/Target/SPIRV/Deserialization.cpp:1791
+
+  // Since the enclosed op is emitted in the current block, split it in a
+  // separate new block.

ergawy wrote:
> antiagainst wrote:
> > What about first creating the spec op, set the insertion point to its body 
> > (with proper guard), and then process the transient instruction? This can 
> > avoid us from doing the block manipulation right? Following the above 
> > comment, this is part of swapping the "context".
> If we do this, since the transient instruction has operands that are 
> constants, global vars, or spec constants, then the instructions to 
> materialize these references will be emitted in the spec op's region. This is 
> the main reason I think we need such manipulation here; we first need to 
> materialize all references, if any, in the parent region and then isolate the 
> spec op's enclosed op.
> 
> Let me know if what you are saying is going over my head :D.
You are right. Sorry I left this comment earlier than the comment about 
serializing into `typesGlobalValues`. 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D93591/new/

https://reviews.llvm.org/D93591

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D83088: Introduce CfgTraits abstraction

2020-10-20 Thread Lei Zhang via Phabricator via cfe-commits
antiagainst added inline comments.



Comment at: mlir/include/mlir/IR/Dominance.h:49
+template <>
+struct llvm::CfgTraitsFor {
+  using CfgTraits = mlir::CfgTraits;

rriddle wrote:
> This seems to have broken the GCC5 build:
> https://buildkite.com/mlir/mlir-core/builds/8739#7a957564-9850-487c-a814-c6818890bd14
> 
> ```
> /mlir/include/mlir/IR/Dominance.h:49:14: error: specialization of 
> 'template struct llvm::CfgTraitsFor' in different 
> namespace [-fpermissive]
>  struct llvm::CfgTraitsFor {
>   ^
> In file included from mlir/include/mlir/IR/Dominance.h:13:0,
>  from mlir/lib/IR/Verifier.cpp:30:
> llvm/include/llvm/Support/CfgTraits.h:294:44: error:   from definition of 
> 'template struct llvm::CfgTraitsFor' [-fpermissive]
>  template  struct CfgTraitsFor;
> ```
Pushed 
https://github.com/llvm/llvm-project/commit/f2a06875b604c00cbe96e54363f4f5d28935d610


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83088/new/

https://reviews.llvm.org/D83088

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84780: Setting the /bigobj option globally for Windows debug build. https://bugs.llvm.org/show_bug.cgi?id=46733

2020-08-04 Thread Lei Zhang via Phabricator via cfe-commits
antiagainst accepted this revision.
antiagainst added a comment.
This revision is now accepted and ready to land.

LGTM for SPIR-V side.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84780/new/

https://reviews.llvm.org/D84780

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D79830: Add support of __builtin_expect_with_probability

2020-06-22 Thread Lei Zhang via Phabricator via cfe-commits
antiagainst added inline comments.



Comment at: llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp:62
+// __builtin_expect
+return {LikelyBranchWeight, UnlikelyBranchWeight};
+  } else {

FYI: this breaks GCC5: 
https://buildkite.com/mlir/mlir-core/builds/5841#4a7c245b-9841-44aa-a82a-97686b04b672


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79830/new/

https://reviews.llvm.org/D79830



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73437: [mlir][spirv] Convert linalg.generic for reduction to SPIR-V ops

2020-01-31 Thread Lei Zhang via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
antiagainst marked an inline comment as done.
Closed by commit rGdf71000d7d5d: [mlir][spirv] Convert linalg.generic for 
reduction to SPIR-V ops (authored by antiagainst).

Changed prior to commit:
  https://reviews.llvm.org/D73437?vs=241431=241720#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73437/new/

https://reviews.llvm.org/D73437

Files:
  mlir/include/mlir/Conversion/LinalgToSPIRV/LinalgToSPIRV.h
  mlir/include/mlir/Conversion/LinalgToSPIRV/LinalgToSPIRVPass.h
  mlir/include/mlir/Dialect/Linalg/IR/LinalgStructuredOps.td
  mlir/include/mlir/Dialect/Linalg/IR/LinalgTraits.h
  mlir/include/mlir/Dialect/Linalg/Utils/Utils.h
  mlir/include/mlir/Dialect/SPIRV/SPIRVAtomicOps.td
  mlir/include/mlir/Dialect/SPIRV/SPIRVControlFlowOps.td
  mlir/include/mlir/Dialect/SPIRV/SPIRVLowering.h
  mlir/include/mlir/Dialect/SPIRV/TargetAndABI.h
  mlir/lib/Conversion/CMakeLists.txt
  mlir/lib/Conversion/LinalgToSPIRV/CMakeLists.txt
  mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRV.cpp
  mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRVPass.cpp
  mlir/lib/Conversion/StandardToSPIRV/ConvertStandardToSPIRV.cpp
  mlir/lib/Dialect/Linalg/Utils/Utils.cpp
  mlir/lib/Dialect/SPIRV/SPIRVLowering.cpp
  mlir/lib/Dialect/SPIRV/SPIRVOps.cpp
  mlir/lib/Dialect/SPIRV/TargetAndABI.cpp
  mlir/test/Conversion/LinalgToSPIRV/linalg-to-spirv.mlir
  mlir/tools/mlir-opt/CMakeLists.txt

Index: mlir/tools/mlir-opt/CMakeLists.txt
===
--- mlir/tools/mlir-opt/CMakeLists.txt
+++ mlir/tools/mlir-opt/CMakeLists.txt
@@ -41,6 +41,7 @@
   MLIRQuantOps
   MLIRROCDLIR
   MLIRSPIRV
+  MLIRLinalgToSPIRVTransforms
   MLIRStandardToSPIRVTransforms
   MLIRSPIRVTestPasses
   MLIRSPIRVTransforms
Index: mlir/test/Conversion/LinalgToSPIRV/linalg-to-spirv.mlir
===
--- /dev/null
+++ mlir/test/Conversion/LinalgToSPIRV/linalg-to-spirv.mlir
@@ -0,0 +1,162 @@
+// RUN: mlir-opt -split-input-file -convert-linalg-to-spirv -canonicalize -verify-diagnostics %s -o - | FileCheck %s
+
+//===--===//
+// Single workgroup reduction
+//===--===//
+
+#single_workgroup_reduction_trait = {
+  args_in = 1,
+  args_out = 1,
+  iterator_types = ["reduction"],
+  indexing_maps = [
+affine_map<(i) -> (i)>,
+affine_map<(i) -> (0)>
+  ]
+}
+
+module attributes {
+  spv.target_env = {
+version = 3 : i32,
+extensions = [],
+capabilities = [1: i32, 63: i32] // Shader, GroupNonUniformArithmetic
+  }
+} {
+
+// CHECK:  spv.globalVariable
+// CHECK-SAME: built_in("LocalInvocationId")
+
+// CHECK:  func @single_workgroup_reduction
+// CHECK-SAME: (%[[INPUT:.+]]: !spv.ptr{{.+}}, %[[OUTPUT:.+]]: !spv.ptr{{.+}})
+
+// CHECK:%[[ZERO:.+]] = spv.constant 0 : i32
+// CHECK:%[[ID:.+]] = spv.Load "Input" %{{.+}} : vector<3xi32>
+// CHECK:%[[X:.+]] = spv.CompositeExtract %[[ID]][0 : i32]
+
+// CHECK:%[[INPTR:.+]] = spv.AccessChain %[[INPUT]][%[[ZERO]], %[[X]]]
+// CHECK:%[[VAL:.+]] = spv.Load "StorageBuffer" %[[INPTR]] : i32
+// CHECK:%[[ADD:.+]] = spv.GroupNonUniformIAdd "Subgroup" "Reduce" %[[VAL]] : i32
+
+// CHECK:%[[OUTPTR:.+]] = spv.AccessChain %[[OUTPUT]][%[[ZERO]], %[[ZERO]]]
+// CHECK:%[[ELECT:.+]] = spv.GroupNonUniformElect "Subgroup" : i1
+
+// CHECK:spv.selection {
+// CHECK:  spv.BranchConditional %[[ELECT]], ^bb1, ^bb2
+// CHECK:^bb1:
+// CHECK:  spv.AtomicIAdd "Device" "AcquireRelease" %[[OUTPTR]], %[[ADD]]
+// CHECK:  spv.Branch ^bb2
+// CHECK:^bb2:
+// CHECK:  spv._merge
+// CHECK:}
+// CHECK:spv.Return
+
+func @single_workgroup_reduction(%input: memref<16xi32>, %output: memref<1xi32>) attributes {
+  spv.entry_point_abi = {local_size = dense<[16, 1, 1]>: vector<3xi32>}
+} {
+  linalg.generic #single_workgroup_reduction_trait %input, %output {
+^bb(%in: i32, %out: i32):
+  %sum = addi %in, %out : i32
+  linalg.yield %sum : i32
+  } : memref<16xi32>, memref<1xi32>
+  spv.Return
+}
+}
+
+// -
+
+// Missing shader entry point ABI
+
+#single_workgroup_reduction_trait = {
+  args_in = 1,
+  args_out = 1,
+  iterator_types = ["reduction"],
+  indexing_maps = [
+affine_map<(i) -> (i)>,
+affine_map<(i) -> (0)>
+  ]
+}
+
+module attributes {
+  spv.target_env = {
+version = 3 : i32,
+extensions = [],
+capabilities = [1: i32, 63: i32] // Shader, GroupNonUniformArithmetic
+  }
+} {
+func @single_workgroup_reduction(%input: memref<16xi32>, %output: memref<1xi32>) {
+  // expected-error @+1 {{failed to legalize operation 'linalg.generic'}}
+  linalg.generic #single_workgroup_reduction_trait %input, %output {
+^bb(%in: i32, 

[PATCH] D73437: [mlir][spirv] Convert linalg.generic for reduction to SPIR-V ops

2020-01-31 Thread Lei Zhang via Phabricator via cfe-commits
antiagainst marked 4 inline comments as done.
antiagainst added inline comments.



Comment at: mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRV.cpp:125
+
+PatternMatchResult SingleWorkgroupReduction::matchAndRewrite(
+linalg::GenericOp genericOp, ArrayRef operands,

nicolasvasilache wrote:
> antiagainst wrote:
> > nicolasvasilache wrote:
> > > Please split this into a precondition and an apply that must succeed so 
> > > we can use the precondition as a Constraint and the apply as a simple 
> > > Rewrite.
> > > I have found this split to be crucial to write custom fused passes with 
> > > DRR.
> > > I claim this is generally the way we should be writing transformations 
> > > when we can, which is the case for Linalg ops. 
> > I feel I don't have all the backgrounds here so I'd appreciate some 
> > explanation as for why it's necessary to separate the match and rewrite. I 
> > think that's the original design of patterns (that we have `match` and 
> > `rewrite` separately) and then later we found it's too cumbersome to carry 
> > over a large matched state between them and then came up with 
> > `matchAndRewrite`? IIUC, every pattern is applied as a whole. I can 
> > understand that the match/rewrite side can be potentially reusable across 
> > patterns as components if they are exposed as helper functions, but that's 
> > more from a library organization and code reuse's perspective; I feel 
> > you've more reasons than that so I'd like to learn about them. :) 
> > 
> > Another question here is that I've matches that is generally useful to 
> > other patterns (checking whether this is a linalg doing reduction) and 
> > matches that is only useful to SPIR-V here (checking whether the workload 
> > can be fit in one local workgroup). How do you handle such cases?
> > 
> > For now I separated the check that whether this is a linalg doing reduction 
> > as a helper function. I haven't put it in some linalg file yet because 
> > currently it's too rigid and overfitting to a specific case. I plan to 
> > extend it and then later maybe we can move it to some linalg file. 
> Let's sync up over video for this, this is a longer discussion and touches 
> phase ordering issues, local patterns etc.
> If you want some of the deeper details please look at the rationale doc: 
> https://mlir.llvm.org/docs/Dialects/Linalg/ (which will soon move to 
> https://mlir.llvm.org/docs/Dialects/LinalgRationale/).
> 
> In the meantime, this is not a blocker but it would be great to sync up in 
> particular on the implementation on those ideas today in DRR.
Awesome, thanks! I've opened https://mlir.llvm.org/docs/Dialects/Linalg/ in a 
tab but haven't read it through yet. ;-P Will do now. 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73437/new/

https://reviews.llvm.org/D73437



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73437: [mlir][spirv] Convert linalg.generic for reduction to SPIR-V ops

2020-01-30 Thread Lei Zhang via Phabricator via cfe-commits
antiagainst updated this revision to Diff 241431.
antiagainst marked 16 inline comments as done.
antiagainst added a comment.

Address comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73437/new/

https://reviews.llvm.org/D73437

Files:
  mlir/include/mlir/Conversion/LinalgToSPIRV/LinalgToSPIRV.h
  mlir/include/mlir/Conversion/LinalgToSPIRV/LinalgToSPIRVPass.h
  mlir/include/mlir/Dialect/Linalg/IR/LinalgStructuredOps.td
  mlir/include/mlir/Dialect/Linalg/IR/LinalgTraits.h
  mlir/include/mlir/Dialect/Linalg/Utils/Utils.h
  mlir/include/mlir/Dialect/SPIRV/SPIRVAtomicOps.td
  mlir/include/mlir/Dialect/SPIRV/SPIRVControlFlowOps.td
  mlir/include/mlir/Dialect/SPIRV/SPIRVLowering.h
  mlir/include/mlir/Dialect/SPIRV/TargetAndABI.h
  mlir/lib/Conversion/CMakeLists.txt
  mlir/lib/Conversion/LinalgToSPIRV/CMakeLists.txt
  mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRV.cpp
  mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRVPass.cpp
  mlir/lib/Conversion/StandardToSPIRV/ConvertStandardToSPIRV.cpp
  mlir/lib/Dialect/Linalg/Utils/Utils.cpp
  mlir/lib/Dialect/SPIRV/SPIRVLowering.cpp
  mlir/lib/Dialect/SPIRV/SPIRVOps.cpp
  mlir/lib/Dialect/SPIRV/TargetAndABI.cpp
  mlir/test/Conversion/LinalgToSPIRV/linalg-to-spirv.mlir
  mlir/tools/mlir-opt/CMakeLists.txt

Index: mlir/tools/mlir-opt/CMakeLists.txt
===
--- mlir/tools/mlir-opt/CMakeLists.txt
+++ mlir/tools/mlir-opt/CMakeLists.txt
@@ -40,6 +40,7 @@
   MLIRQuantOps
   MLIRROCDLIR
   MLIRSPIRV
+  MLIRLinalgToSPIRVTransforms
   MLIRStandardToSPIRVTransforms
   MLIRSPIRVTestPasses
   MLIRSPIRVTransforms
Index: mlir/test/Conversion/LinalgToSPIRV/linalg-to-spirv.mlir
===
--- /dev/null
+++ mlir/test/Conversion/LinalgToSPIRV/linalg-to-spirv.mlir
@@ -0,0 +1,162 @@
+// RUN: mlir-opt -split-input-file -convert-linalg-to-spirv -canonicalize -verify-diagnostics %s -o - | FileCheck %s
+
+//===--===//
+// Single workgroup reduction
+//===--===//
+
+#single_workgroup_reduction_trait = {
+  args_in = 1,
+  args_out = 1,
+  iterator_types = ["reduction"],
+  indexing_maps = [
+affine_map<(i) -> (i)>,
+affine_map<(i) -> (0)>
+  ]
+}
+
+module attributes {
+  spv.target_env = {
+version = 3 : i32,
+extensions = [],
+capabilities = [1: i32, 63: i32] // Shader, GroupNonUniformArithmetic
+  }
+} {
+
+// CHECK:  spv.globalVariable
+// CHECK-SAME: built_in("LocalInvocationId")
+
+// CHECK:  func @single_workgroup_reduction
+// CHECK-SAME: (%[[INPUT:.+]]: !spv.ptr{{.+}}, %[[OUTPUT:.+]]: !spv.ptr{{.+}})
+
+// CHECK:%[[ZERO:.+]] = spv.constant 0 : i32
+// CHECK:%[[ID:.+]] = spv.Load "Input" %{{.+}} : vector<3xi32>
+// CHECK:%[[X:.+]] = spv.CompositeExtract %[[ID]][0 : i32]
+
+// CHECK:%[[INPTR:.+]] = spv.AccessChain %[[INPUT]][%[[ZERO]], %[[X]]]
+// CHECK:%[[VAL:.+]] = spv.Load "StorageBuffer" %[[INPTR]] : i32
+// CHECK:%[[ADD:.+]] = spv.GroupNonUniformIAdd "Subgroup" "Reduce" %[[VAL]] : i32
+
+// CHECK:%[[OUTPTR:.+]] = spv.AccessChain %[[OUTPUT]][%[[ZERO]], %[[ZERO]]]
+// CHECK:%[[ELECT:.+]] = spv.GroupNonUniformElect "Subgroup" : i1
+
+// CHECK:spv.selection {
+// CHECK:  spv.BranchConditional %[[ELECT]], ^bb1, ^bb2
+// CHECK:^bb1:
+// CHECK:  spv.AtomicIAdd "Device" "AcquireRelease" %[[OUTPTR]], %[[ADD]]
+// CHECK:  spv.Branch ^bb2
+// CHECK:^bb2:
+// CHECK:  spv._merge
+// CHECK:}
+// CHECK:spv.Return
+
+func @single_workgroup_reduction(%input: memref<16xi32>, %output: memref<1xi32>) attributes {
+  spv.entry_point_abi = {local_size = dense<[16, 1, 1]>: vector<3xi32>}
+} {
+  linalg.generic #single_workgroup_reduction_trait %input, %output {
+^bb(%in: i32, %out: i32):
+  %sum = addi %in, %out : i32
+  linalg.yield %sum : i32
+  } : memref<16xi32>, memref<1xi32>
+  spv.Return
+}
+}
+
+// -
+
+// Missing shader entry point ABI
+
+#single_workgroup_reduction_trait = {
+  args_in = 1,
+  args_out = 1,
+  iterator_types = ["reduction"],
+  indexing_maps = [
+affine_map<(i) -> (i)>,
+affine_map<(i) -> (0)>
+  ]
+}
+
+module attributes {
+  spv.target_env = {
+version = 3 : i32,
+extensions = [],
+capabilities = [1: i32, 63: i32] // Shader, GroupNonUniformArithmetic
+  }
+} {
+func @single_workgroup_reduction(%input: memref<16xi32>, %output: memref<1xi32>) {
+  // expected-error @+1 {{failed to legalize operation 'linalg.generic'}}
+  linalg.generic #single_workgroup_reduction_trait %input, %output {
+^bb(%in: i32, %out: i32):
+  %sum = addi %in, %out : i32
+  linalg.yield %sum : i32
+  } : memref<16xi32>, memref<1xi32>
+  return
+}
+}
+
+// -
+
+// Mismatch between shader entry 

[PATCH] D73437: [mlir][spirv] Convert linalg.generic for reduction to SPIR-V ops

2020-01-30 Thread Lei Zhang via Phabricator via cfe-commits
antiagainst added inline comments.



Comment at: mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRV.cpp:182
+  // Perform the group reduction operation.
+  Value groupOperation = rewriter.create(
+  loc, originalInputType.getElementType(), spirv::Scope::Subgroup,

mravishankar wrote:
> mravishankar wrote:
> > antiagainst wrote:
> > > mravishankar wrote:
> > > > This is hard-wiring to IAdd. We probably need to structure this 
> > > > differently. We need to have a pattern to lower the linalg.generic with 
> > > > reduction iterator into the kernel generated here, and then lower the 
> > > > operations within the region separately.
> > > It was intentional to only support IAdd. I've re-structured this a bit so 
> > > it's extensible to other binary op kinds.
> > The way I see this structured is
> > 
> > 1) You check the "structure" of the linalg.generic op to see if it is a 1D 
> > reduction. You assume that the body of the generic op represents a binary 
> > operation that can be used for the reduction.
> > 2) You write a separate pattern that converts the operations of the body 
> > itself into the spirv::GroupNonUniform*Op.
> > 
> > The dialect conversion will first convert the generic op, and then it will 
> > attempt to convert the body of the op. The way this is strucutred, it can 
> > only handle straight-forward binary operations. THere could be more 
> > complicated operations in the region of a generic op that implements the 
> > reduction, which would be hard to incorporate in this approach.
> > 
> > With your updated changes, it is easy to extend to other ops, but I think a 
> > more general solution is needed where we are not constrained in handling 
> > just simple reductions. It might need some more careful design though, 
> > which I dont have a full picture of right now. So for now this OK, but 
> > please leave a TODO to say something like "handle more general reductions".
> Thought about this a little bit more. It will be a more sane strategy to not 
> handle cases where the region is "inlined" into the generic op, but rather 
> the region is specified as a function using the `fun` attribute of the 
> `linalg.generic` op. Then we can split the lowering of the generic op and the 
> lowering of the function that does the reduction separately.
> This too not needed for this CL. Should revisit this
Yeah, right now linalg.generic is an integrated entity; I'm not sure how we can 
easily convert part of it (the "structure") and then the inlined scalar region. 
I guess it's fine for now to overfit a bit until later we see concrete cases 
that we want to support, which will give us a more tangible problem to solve. 



Comment at: mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRV.cpp:27
+/// types.
+static bool areAllValuesMemref(Operation *op) {
+  auto isOfMemrefType = [](Value val) {

nicolasvasilache wrote:
> Please use `LinalgOp::hasBufferSemantics` instead of rolling your own
Oh, didn't know we have that. Thanks!



Comment at: mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRV.cpp:80
+  auto  = op.region();
+  if (region.empty() || !has_single_element(region.getBlocks()))
+return BinaryOpKind::Unknown;

rriddle wrote:
> You should be able to remove the .empty() call as well as the .getBlocks()
Nice, thanks!



Comment at: mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRV.cpp:125
+
+PatternMatchResult SingleWorkgroupReduction::matchAndRewrite(
+linalg::GenericOp genericOp, ArrayRef operands,

nicolasvasilache wrote:
> Please split this into a precondition and an apply that must succeed so we 
> can use the precondition as a Constraint and the apply as a simple Rewrite.
> I have found this split to be crucial to write custom fused passes with DRR.
> I claim this is generally the way we should be writing transformations when 
> we can, which is the case for Linalg ops. 
I feel I don't have all the backgrounds here so I'd appreciate some explanation 
as for why it's necessary to separate the match and rewrite. I think that's the 
original design of patterns (that we have `match` and `rewrite` separately) and 
then later we found it's too cumbersome to carry over a large matched state 
between them and then came up with `matchAndRewrite`? IIUC, every pattern is 
applied as a whole. I can understand that the match/rewrite side can be 
potentially reusable across patterns as components if they are exposed as 
helper functions, but that's more from a library organization and code reuse's 
perspective; I feel you've more reasons than that so I'd like to learn about 
them. :) 

Another question here is that I've matches that is generally useful to other 
patterns (checking whether this is a linalg doing reduction) and matches that 
is only useful to SPIR-V here (checking whether the workload can be fit in one 
local workgroup). How do you handle such cases?

For now I 

[PATCH] D73437: [mlir][spirv] Convert linalg.generic for reduction to SPIR-V ops

2020-01-28 Thread Lei Zhang via Phabricator via cfe-commits
antiagainst added a comment.

Messed up the revision history with Arc... Please show the diff between "Diff 
1" and "Diff 4" to check the modifications.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73437/new/

https://reviews.llvm.org/D73437



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73437: [mlir][spirv] Convert linalg.generic for reduction to SPIR-V ops

2020-01-28 Thread Lei Zhang via Phabricator via cfe-commits
antiagainst updated this revision to Diff 240861.
antiagainst added a comment.

Clean up unrelated commits again


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73437/new/

https://reviews.llvm.org/D73437

Files:
  mlir/include/mlir/Conversion/LinalgToSPIRV/LinalgToSPIRV.h
  mlir/include/mlir/Conversion/LinalgToSPIRV/LinalgToSPIRVPass.h
  mlir/include/mlir/Dialect/SPIRV/SPIRVAtomicOps.td
  mlir/include/mlir/Dialect/SPIRV/SPIRVControlFlowOps.td
  mlir/include/mlir/Dialect/SPIRV/SPIRVLowering.h
  mlir/include/mlir/Dialect/SPIRV/TargetAndABI.h
  mlir/lib/Conversion/CMakeLists.txt
  mlir/lib/Conversion/LinalgToSPIRV/CMakeLists.txt
  mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRV.cpp
  mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRVPass.cpp
  mlir/lib/Conversion/StandardToSPIRV/ConvertStandardToSPIRV.cpp
  mlir/lib/Dialect/SPIRV/SPIRVLowering.cpp
  mlir/lib/Dialect/SPIRV/SPIRVOps.cpp
  mlir/lib/Dialect/SPIRV/TargetAndABI.cpp
  mlir/test/Conversion/LinalgToSPIRV/linalg-to-spirv.mlir
  mlir/tools/mlir-opt/CMakeLists.txt

Index: mlir/tools/mlir-opt/CMakeLists.txt
===
--- mlir/tools/mlir-opt/CMakeLists.txt
+++ mlir/tools/mlir-opt/CMakeLists.txt
@@ -40,6 +40,7 @@
   MLIRQuantOps
   MLIRROCDLIR
   MLIRSPIRV
+  MLIRLinalgToSPIRVTransforms
   MLIRStandardToSPIRVTransforms
   MLIRSPIRVTestPasses
   MLIRSPIRVTransforms
Index: mlir/test/Conversion/LinalgToSPIRV/linalg-to-spirv.mlir
===
--- /dev/null
+++ mlir/test/Conversion/LinalgToSPIRV/linalg-to-spirv.mlir
@@ -0,0 +1,162 @@
+// RUN: mlir-opt -split-input-file -convert-linalg-to-spirv -canonicalize -verify-diagnostics %s -o - | FileCheck %s
+
+//===--===//
+// Single workgroup reduction
+//===--===//
+
+#single_workgroup_reduction_trait = {
+  args_in = 1,
+  args_out = 1,
+  iterator_types = ["reduction"],
+  indexing_maps = [
+affine_map<(i) -> (i)>,
+affine_map<(i) -> (0)>
+  ]
+}
+
+module attributes {
+  spv.target_env = {
+version = 3 : i32,
+extensions = [],
+capabilities = [1: i32, 63: i32] // Shader, GroupNonUniformArithmetic
+  }
+} {
+
+// CHECK:  spv.globalVariable
+// CHECK-SAME: built_in("LocalInvocationId")
+
+// CHECK:  func @single_workgroup_reduction
+// CHECK-SAME: (%[[INPUT:.+]]: !spv.ptr{{.+}}, %[[OUTPUT:.+]]: !spv.ptr{{.+}})
+
+// CHECK:%[[ZERO:.+]] = spv.constant 0 : i32
+// CHECK:%[[ID:.+]] = spv.Load "Input" %{{.+}} : vector<3xi32>
+// CHECK:%[[X:.+]] = spv.CompositeExtract %[[ID]][0 : i32]
+
+// CHECK:%[[INPTR:.+]] = spv.AccessChain %[[INPUT]][%[[ZERO]], %[[X]]]
+// CHECK:%[[VAL:.+]] = spv.Load "StorageBuffer" %[[INPTR]] : i32
+// CHECK:%[[ADD:.+]] = spv.GroupNonUniformIAdd "Subgroup" "Reduce" %[[VAL]] : i32
+
+// CHECK:%[[OUTPTR:.+]] = spv.AccessChain %[[OUTPUT]][%[[ZERO]], %[[ZERO]]]
+// CHECK:%[[ELECT:.+]] = spv.GroupNonUniformElect "Subgroup" : i1
+
+// CHECK:spv.selection {
+// CHECK:  spv.BranchConditional %[[ELECT]], ^bb1, ^bb2
+// CHECK:^bb1:
+// CHECK:  spv.AtomicIAdd "Device" "AcquireRelease" %[[OUTPTR]], %[[ADD]]
+// CHECK:  spv.Branch ^bb2
+// CHECK:^bb2:
+// CHECK:  spv._merge
+// CHECK:}
+// CHECK:spv.Return
+
+func @single_workgroup_reduction(%input: memref<16xi32>, %output: memref<1xi32>) attributes {
+  spv.entry_point_abi = {local_size = dense<[16, 1, 1]>: vector<3xi32>}
+} {
+  linalg.generic #single_workgroup_reduction_trait %input, %output {
+^bb(%in: i32, %out: i32):
+  %sum = addi %in, %out : i32
+  linalg.yield %sum : i32
+  } : memref<16xi32>, memref<1xi32>
+  spv.Return
+}
+}
+
+// -
+
+// Missing shader entry point ABI
+
+#single_workgroup_reduction_trait = {
+  args_in = 1,
+  args_out = 1,
+  iterator_types = ["reduction"],
+  indexing_maps = [
+affine_map<(i) -> (i)>,
+affine_map<(i) -> (0)>
+  ]
+}
+
+module attributes {
+  spv.target_env = {
+version = 3 : i32,
+extensions = [],
+capabilities = [1: i32, 63: i32] // Shader, GroupNonUniformArithmetic
+  }
+} {
+func @single_workgroup_reduction(%input: memref<16xi32>, %output: memref<1xi32>) {
+  // expected-error @+1 {{failed to legalize operation 'linalg.generic'}}
+  linalg.generic #single_workgroup_reduction_trait %input, %output {
+^bb(%in: i32, %out: i32):
+  %sum = addi %in, %out : i32
+  linalg.yield %sum : i32
+  } : memref<16xi32>, memref<1xi32>
+  return
+}
+}
+
+// -
+
+// Mismatch between shader entry point ABI and input memref shape
+
+#single_workgroup_reduction_trait = {
+  args_in = 1,
+  args_out = 1,
+  iterator_types = ["reduction"],
+  indexing_maps = [
+affine_map<(i) -> (i)>,
+affine_map<(i) -> (0)>
+  ]
+}
+
+module 

[PATCH] D73437: [mlir][spirv] Convert linalg.generic for reduction to SPIR-V ops

2020-01-28 Thread Lei Zhang via Phabricator via cfe-commits
antiagainst marked 2 inline comments as done.
antiagainst added inline comments.
Herald added a reviewer: mclow.lists.



Comment at: mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRV.cpp:27
+/// types.
+static inline bool areAllValuesMemref(Operation *op) {
+  auto isOfMemrefType = [](Value val) {

rriddle wrote:
> Why the inline keyword?
Added initially because this function was trivial enough. I guess right now 
it's better to let the compiler decide.



Comment at: mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRV.cpp:60
+  auto  = op.region();
+  if (region.empty() || region.getBlocks().size() != 1)
+return false;

rriddle wrote:
> Don't use size, it is O(N). Use 'has_single_element' instead.
Oh, good to know! Thanks!



Comment at: mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRV.cpp:70
+  auto  = block.getOperations();
+  if (ops.size() != 2)
+return false;

rriddle wrote:
> Same here, size() is O(N): `!has_single_element(block.without_terminator())`
Nice, thanks!



Comment at: mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRV.cpp:73
+
+  using mlir::matchers::m_Val;
+  auto a = m_Val(block.getArgument(0));

mravishankar wrote:
> I feel like this is not required. If the linalg.generic operation says this 
> is a reduction, we should not be checking the region to verify that it is. 
> linalg as a contract is guaranteeing this is a reduction.
I'm not sure I get your idea correctly; but this is checking we are doing the 
expected kind of reduction (`BinaryOp`). 



Comment at: mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRV.cpp:103
+linalg::GenericOp genericOp, ArrayRef operands,
+ConversionPatternRewriter ) const {
+  Operation *op = genericOp.getOperation();

rriddle wrote:
> This function is huge, is there any way to split it up a bit?
Good point. Split out two helper functions.



Comment at: mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRV.cpp:182
+  // Perform the group reduction operation.
+  Value groupOperation = rewriter.create(
+  loc, originalInputType.getElementType(), spirv::Scope::Subgroup,

mravishankar wrote:
> This is hard-wiring to IAdd. We probably need to structure this differently. 
> We need to have a pattern to lower the linalg.generic with reduction iterator 
> into the kernel generated here, and then lower the operations within the 
> region separately.
It was intentional to only support IAdd. I've re-structured this a bit so it's 
extensible to other binary op kinds.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73437/new/

https://reviews.llvm.org/D73437



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D25669: [Driver] Simplify ToolChain::GetCXXStdlibType (NFC)

2016-12-06 Thread Lei Zhang via Phabricator via cfe-commits
zlei added a comment.

LGTM


https://reviews.llvm.org/D25669



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits