[llvm-branch-commits] [mlir] [mlir][sparse] Fix memory leaks (part 3) (PR #85184)

2024-03-14 Thread Aart Bik via llvm-branch-commits

https://github.com/aartbik approved this pull request.


https://github.com/llvm/llvm-project/pull/85184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][sparse] Fix memory leaks (part 3) (PR #85184)

2024-03-14 Thread Aart Bik via llvm-branch-commits

https://github.com/aartbik edited 
https://github.com/llvm/llvm-project/pull/85184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][sparse] Fix memory leaks (part 3) (PR #85184)

2024-03-14 Thread Aart Bik via llvm-branch-commits


@@ -167,12 +169,14 @@ module {
 call @dump(%d31) : (tensor<2x3x4xf64>) -> ()
 
 //
-// Release sparse tensors.
+// Release tensors.

aartbik wrote:

same

https://github.com/llvm/llvm-project/pull/85184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][sparse] Fix memory leaks (part 3) (PR #85184)

2024-03-14 Thread Aart Bik via llvm-branch-commits


@@ -114,12 +114,14 @@ module {
 call @dump(%d31) : (tensor<2x3x4xf64>) -> ()
 
 //
-// Release sparse tensors.
+// Release tensors.

aartbik wrote:

we usually say 

// Release the resources.

so perhaps use that here too

https://github.com/llvm/llvm-project/pull/85184
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][sparse] Add `has_runtime_library` test op (PR #85355)

2024-03-14 Thread Aart Bik via llvm-branch-commits

https://github.com/aartbik edited 
https://github.com/llvm/llvm-project/pull/85355
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][sparse] Add `has_runtime_library` test op (PR #85355)

2024-03-14 Thread Aart Bik via llvm-branch-commits

https://github.com/aartbik approved this pull request.


https://github.com/llvm/llvm-project/pull/85355
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][sparse] Add `has_runtime_library` test op (PR #85355)

2024-03-14 Thread Aart Bik via llvm-branch-commits


@@ -140,10 +140,16 @@ module {
 sparse_tensor.print %s1 : tensor<4x3x2xf32, #BatchedCSR>
 sparse_tensor.print %s2 : tensor<4x3x2xf32, #CSRDense>
 
-// FIXME: doing this explicitly crashes runtime
-// bufferization.dealloc_tensor %s0 : tensor<4x3x2xf32, #CCC>
-// bufferization.dealloc_tensor %s1 : tensor<4x3x2xf32, #BatchedCSR>
-// bufferization.dealloc_tensor %s2 : tensor<4x3x2xf32, #CSRDense>
+%has_runtime = sparse_tensor.has_runtime_library

aartbik wrote:

Can you add this information in a TODO inside the test, so we remember later 

https://github.com/llvm/llvm-project/pull/85355
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][sparse] refactoring sparse_tensor.iterate lowering pattern implementation. (PR #105566)

2024-08-23 Thread Aart Bik via llvm-branch-commits

https://github.com/aartbik approved this pull request.


https://github.com/llvm/llvm-project/pull/105566
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][sparse] unify block arguments order between iterate/coiterate operations. (PR #105567)

2024-08-23 Thread Aart Bik via llvm-branch-commits

https://github.com/aartbik approved this pull request.


https://github.com/llvm/llvm-project/pull/105567
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] f4f158b - [mlir][sparse] add vectorization strategies to sparse compiler

2021-01-13 Thread Aart Bik via llvm-branch-commits

Author: Aart Bik
Date: 2021-01-13T11:55:23-08:00
New Revision: f4f158b2f89e16ee7068d6292d2d46457d6932bb

URL: 
https://github.com/llvm/llvm-project/commit/f4f158b2f89e16ee7068d6292d2d46457d6932bb
DIFF: 
https://github.com/llvm/llvm-project/commit/f4f158b2f89e16ee7068d6292d2d46457d6932bb.diff

LOG: [mlir][sparse] add vectorization strategies to sparse compiler

Similar to the parallelization strategies, the vectorization strategies
provide control on what loops should be vectorize. Unlike the parallel
strategies, only innermost loops are considered, but including reductions,
with the control of vectorizing dense loops only or dense and sparse loops.

The vectorized loops are always controlled by a vector mask to avoid
overrunning the iterations, but subsequent vector operation folding removes
redundant masks and replaces the operations with more efficient counterparts.
Similarly, we will rely on subsequent loop optimizations to further optimize
masking, e.g. using an unconditional full vector loop and scalar cleanup loop.

The current strategy already demonstrates a nice interaction between the
sparse compiler and all prior optimizations that went into the vector dialect.

Ongoing discussion at:
https://llvm.discourse.group/t/mlir-support-for-sparse-tensors/2020/10

Reviewed By: penpornk

Differential Revision: https://reviews.llvm.org/D94551

Added: 
mlir/test/Dialect/Linalg/sparse_vector.mlir

Modified: 
mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
mlir/test/lib/Transforms/TestSparsification.cpp

Removed: 




diff  --git a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h 
b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
index de1658f96a87..0effa2f45c20 100644
--- a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
+++ b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
@@ -867,7 +867,13 @@ struct SparsificationOptions {
 SparseVectorizationStrategy v, unsigned vl,
 SparseIntType pt, SparseIntType it)
   : parallelizationStrategy(p), vectorizationStrategy(v), vectorLength(vl),
-ptrType(pt), indType(it) {}
+ptrType(pt), indType(it) {
+// TODO: remove restriction when vectors with index elements are supported
+assert((v != SparseVectorizationStrategy::kAnyStorageInnerLoop ||
+(ptrType != SparseIntType::kNative &&
+ indType != SparseIntType::kNative)) &&
+   "This combination requires support for vectors with index 
elements");
+  }
   SparsificationOptions()
   : SparsificationOptions(SparseParallelizationStrategy::kNone,
   SparseVectorizationStrategy::kNone, 1u,

diff  --git a/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp 
b/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
index dbf8d5ffcb8c..7ba0a2f63071 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
@@ -46,6 +46,7 @@
 #include "mlir/Dialect/Linalg/Utils/Utils.h"
 #include "mlir/Dialect/SCF/SCF.h"
 #include "mlir/Dialect/StandardOps/IR/Ops.h"
+#include "mlir/IR/Matchers.h"
 
 using namespace mlir;
 
@@ -301,7 +302,8 @@ struct CodeGen {
 indices(numTensors, std::vector(numLoops)),
 highs(numTensors, std::vector(numLoops)),
 pidxs(numTensors, std::vector(numLoops)),
-idxs(numTensors, std::vector(numLoops)), redExp(-1u), redVal() 
{}
+idxs(numTensors, std::vector(numLoops)), redExp(-1u), redVal(),
+curVecLength(1), curVecMask() {}
   /// Sparsification options.
   linalg::SparsificationOptions options;
   /// Universal dense indices and upper bounds (by index). The loops array
@@ -327,6 +329,9 @@ struct CodeGen {
   // is most effective; we could generalize to more outer and while-loops.
   unsigned redExp;
   Value redVal;
+  // Current vector length and mask.
+  unsigned curVecLength;
+  Value curVecMask;
 };
 
 } // namespace
@@ -558,6 +563,71 @@ static void genBuffers(Merger &merger, CodeGen &codegen,
   }
 }
 
+/// Constructs vector type from pointer.
+static VectorType vectorType(CodeGen &codegen, Value ptr) {
+  Type etp = ptr.getType().cast().getElementType();
+  return VectorType::get(codegen.curVecLength, etp);
+}
+
+/// Constructs vector iteration mask.
+static Value genVectorMask(CodeGen &codegen, PatternRewriter &rewriter,
+   Value iv, Value lo, Value hi, Value step) {
+  Location loc = iv.getLoc();
+  VectorType mtp =
+  VectorType::get(codegen.curVecLength, rewriter.getIntegerType(1));
+  // Special case if the vector length evenly divides the trip count (for
+  // example, "for i = 0, 128, 16"). A constant all-true mask is generated
+  // so that all subsequent masked memory operations are immediately folded
+  // into unconditional memory op

[llvm-branch-commits] [mlir] 5508516 - [mlir][sparse] retry sparse-only for cyclic iteration graphs

2021-01-14 Thread Aart Bik via llvm-branch-commits

Author: Aart Bik
Date: 2021-01-14T22:39:29-08:00
New Revision: 5508516b06633e95fb5c2d6a5e196e4dcaa72c8d

URL: 
https://github.com/llvm/llvm-project/commit/5508516b06633e95fb5c2d6a5e196e4dcaa72c8d
DIFF: 
https://github.com/llvm/llvm-project/commit/5508516b06633e95fb5c2d6a5e196e4dcaa72c8d.diff

LOG: [mlir][sparse] retry sparse-only for cyclic iteration graphs

This is a very minor improvement during iteration graph construction.
If the first attempt considering the dimension order of all tensors fails,
a second attempt is made using the constraints of sparse tensors only.
Dense tensors prefer dimension order (locality) but provide random access
if needed, enabling the compilation of more sparse kernels.

Reviewed By: penpornk

Differential Revision: https://reviews.llvm.org/D94709

Added: 
mlir/test/Dialect/Linalg/sparse_nd.mlir

Modified: 
mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp

Removed: 




diff  --git a/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp 
b/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
index 7ba0a2f63071..84c71e84c42e 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
@@ -274,6 +274,11 @@ class Merger {
 return false;
   }
 
+  // Returns true if tensor has any sparse dimension.
+  bool isSparseTensor(unsigned t) const {
+return llvm::any_of(dims[t], [](Dim d) { return d == Dim::kSparse; });
+  }
+
   // Setter
   void setDim(unsigned t, unsigned i, Dim d) { dims[t][i] = d; }
 
@@ -382,17 +387,22 @@ static bool topSortDFS(unsigned i, std::vector 
&visit,
 /// for sparse storage formats since these only support access along fixed
 /// dimensions. Even for dense storage formats, however, the natural index
 /// order yields innermost unit-stride access with better spatial locality.
-static bool computeIterationGraph(linalg::GenericOp op,
-  std::vector &topSort) {
+static bool computeIterationGraph(Merger &merger, linalg::GenericOp op,
+  std::vector &topSort,
+  bool sparseOnly) {
   // Set up an n x n from/to adjacency matrix of the iteration graph
   // for the implicit loop indices i_0 .. i_n-1.
   unsigned n = op.getNumLoops();
   std::vector> adjM(n, std::vector(n, false));
 
   // Iterate over the indexing maps of every tensor in the tensor expression.
-  for (auto imap : llvm::enumerate(op.indexing_maps())) {
-auto map = imap.value().template cast().getValue();
+  unsigned numTensors = op.getNumShapedOperands();
+  for (unsigned t = 0; t < numTensors; t++) {
+auto map = op.getIndexingMap(t);
 assert(map.getNumDims() == n);
+// Skip dense tensor constraints when sparse only is requested.
+if (sparseOnly && !merger.isSparseTensor(t))
+  continue;
 // At the moment, we take the index variables in the tensor access
 // expression in the order in which they appear (conceptually a
 // "row-major" layout of every tensor). So, a tensor access A_ijk
@@ -407,6 +417,7 @@ static bool computeIterationGraph(linalg::GenericOp op,
 
   // Topologically sort the iteration graph to determine loop order.
   // Report failure for a cyclic iteration graph.
+  topSort.clear();
   topSort.reserve(n);
   std::vector visit(n, 0);
   for (unsigned i = 0; i < n; i++)
@@ -1207,10 +1218,9 @@ struct GenericOpSparsifier : public 
OpRewritePattern {
 // tensors are visited in natural index order. Fails on cycles.
 // This assumes that higher-level passes have already put the
 // tensors in each tensor expression in a feasible order.
-// TODO: try again without *dense* constraints on failure or
-//   even try to insert sparse reorderings to resolve cycles
 std::vector topSort;
-if (!computeIterationGraph(op, topSort))
+if (!computeIterationGraph(merger, op, topSort, /*sparseOnly=*/false) &&
+!computeIterationGraph(merger, op, topSort, /*sparseOnly=*/true))
   return failure();
 
 // Finds the terminating yield statement and builds the tensor

diff  --git a/mlir/test/Dialect/Linalg/sparse_nd.mlir 
b/mlir/test/Dialect/Linalg/sparse_nd.mlir
new file mode 100644
index ..2b0762b1bf37
--- /dev/null
+++ b/mlir/test/Dialect/Linalg/sparse_nd.mlir
@@ -0,0 +1,94 @@
+// NOTE: Assertions have been autogenerated by utils/generate-test-checks.py
+// RUN: mlir-opt %s -test-sparsification | FileCheck %s
+
+// Example with cyclic iteration graph with sparse and dense constraints,
+// but an acyclic iteration graph using sparse constraints only.
+#trait_mul = {
+  indexing_maps = [
+affine_map<(i,j,k,l,m,n,o,p) -> (i,j,k,l,m,n,o,p)>,  // A
+affine_map<(i,j,k,l,m,n,o,p) -> (p,o,n,m,l,k,j,i)>,  // B
+affine_map<(i,j,k,l,m,n,o,p) -> (i,j,k,l,m,n,o,p)>   // X
+  ],
+  sparse = [
+[ "D", "D", "D", "D", "D", "D", "D", "D" ],  // a
+ 

[llvm-branch-commits] [mlir] d8fc273 - [mlir][sparse] improved sparse runtime support library

2021-01-16 Thread Aart Bik via llvm-branch-commits

Author: Aart Bik
Date: 2021-01-16T12:16:10-08:00
New Revision: d8fc27301d18f0935ba99ead7ac61aa6a53f16e4

URL: 
https://github.com/llvm/llvm-project/commit/d8fc27301d18f0935ba99ead7ac61aa6a53f16e4
DIFF: 
https://github.com/llvm/llvm-project/commit/d8fc27301d18f0935ba99ead7ac61aa6a53f16e4.diff

LOG: [mlir][sparse] improved sparse runtime support library

Added the ability to read (an extended version of) the FROSTT
file format, so that we can now read in sparse tensors of arbitrary
rank. Generalized the API to deal with more than two dimensions.

Also added the ability to sort the indices of sparse tensors
lexicographically. This is an important step towards supporting
auto gen of initialization code, since sparse storage formats
are easier to initialize if the indices are sorted. Since most
external formats don't enforce such properties, it is convenient
to have this ability in our runtime support library.

Lastly, the re-entrant problem of the original implementation
is fixed by passing an opaque object around (rather than having
a single static variable, ugh!).

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D94852

Added: 
mlir/integration_test/Sparse/CPU/frostt-example.mlir
mlir/integration_test/data/test.tns

Modified: 
mlir/include/mlir/ExecutionEngine/CRunnerUtils.h
mlir/integration_test/CMakeLists.txt
mlir/integration_test/Sparse/CPU/matrix-market-example.mlir
mlir/lib/ExecutionEngine/SparseUtils.cpp

Removed: 




diff  --git a/mlir/include/mlir/ExecutionEngine/CRunnerUtils.h 
b/mlir/include/mlir/ExecutionEngine/CRunnerUtils.h
index edcd8e0dc545..2d0608a8656b 100644
--- a/mlir/include/mlir/ExecutionEngine/CRunnerUtils.h
+++ b/mlir/include/mlir/ExecutionEngine/CRunnerUtils.h
@@ -198,7 +198,7 @@ class DynamicMemRefType {
 };
 
 
//===--===//
-// Small runtime support "lib" for vector.print lowering during codegen.
+// Small runtime support library for vector.print lowering during codegen.
 
//===--===//
 extern "C" MLIR_CRUNNERUTILS_EXPORT void printI64(int64_t i);
 extern "C" MLIR_CRUNNERUTILS_EXPORT void printU64(uint64_t u);
@@ -210,15 +210,13 @@ extern "C" MLIR_CRUNNERUTILS_EXPORT void printComma();
 extern "C" MLIR_CRUNNERUTILS_EXPORT void printNewline();
 
 
//===--===//
-// Small runtime support for sparse tensors.
+// Small runtime support library for sparse tensors.
 
//===--===//
-extern "C" MLIR_CRUNNERUTILS_EXPORT void openMatrixC(char *filename,
- uint64_t *mdata,
- uint64_t *ndata,
- uint64_t *nnzdata);
+extern "C" MLIR_CRUNNERUTILS_EXPORT void *openTensorC(char *filename,
+  uint64_t *idata);
 extern "C" MLIR_CRUNNERUTILS_EXPORT void
-readMatrixItemC(uint64_t *idata, uint64_t *jdata, double *ddata);
-extern "C" MLIR_CRUNNERUTILS_EXPORT void closeMatrix();
-extern "C" MLIR_CRUNNERUTILS_EXPORT char *getMatrix(uint64_t id);
+readTensorItemC(void *tensor, uint64_t *idata, double *ddata);
+extern "C" MLIR_CRUNNERUTILS_EXPORT void closeTensor(void *tensor);
+extern "C" MLIR_CRUNNERUTILS_EXPORT char *getTensorFilename(uint64_t id);
 
 #endif // EXECUTIONENGINE_CRUNNERUTILS_H_

diff  --git a/mlir/integration_test/CMakeLists.txt 
b/mlir/integration_test/CMakeLists.txt
index bc5ad90e1253..fb2be5256dcc 100644
--- a/mlir/integration_test/CMakeLists.txt
+++ b/mlir/integration_test/CMakeLists.txt
@@ -31,4 +31,5 @@ add_lit_testsuites(MLIR_INTEGRATION 
${CMAKE_CURRENT_SOURCE_DIR}
 
 # Copy test data over.
 file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data/test.mtx
+  ${CMAKE_CURRENT_SOURCE_DIR}/data/test.tns
 DESTINATION ${MLIR_INTEGRATION_TEST_DIR}/data/)

diff  --git a/mlir/integration_test/Sparse/CPU/frostt-example.mlir 
b/mlir/integration_test/Sparse/CPU/frostt-example.mlir
new file mode 100644
index ..8144270aa91f
--- /dev/null
+++ b/mlir/integration_test/Sparse/CPU/frostt-example.mlir
@@ -0,0 +1,149 @@
+// RUN: mlir-opt %s \
+// RUN:  -convert-scf-to-std -convert-vector-to-scf \
+// RUN:  -convert-linalg-to-llvm -convert-vector-to-llvm | \
+// RUN: TENSOR0="%mlir_integration_test_dir/data/test.tns" \
+// RUN: mlir-cpu-runner \
+// RUN:  -e entry -entry-point-result=void  \
+// RUN:  
-shared-libs=%mlir_integration_test_dir/libmlir_c_runner_utils%shlibext | \
+// RUN: FileCheck %s
+
+module {
+  //
+  // Example of using the sparse runtime support library to read a sparse 
tensor
+  // in the FROSTT file format (http://frostt.io/tensors/file-formats.html).
+  //
+  f

[llvm-branch-commits] [mlir] b5c542d - [mlir][sparse] add narrower choices for pointers/indices

2021-01-19 Thread Aart Bik via llvm-branch-commits

Author: Aart Bik
Date: 2021-01-19T20:20:38-08:00
New Revision: b5c542d64b98b5a74d35dedad41051a0b00d7946

URL: 
https://github.com/llvm/llvm-project/commit/b5c542d64b98b5a74d35dedad41051a0b00d7946
DIFF: 
https://github.com/llvm/llvm-project/commit/b5c542d64b98b5a74d35dedad41051a0b00d7946.diff

LOG: [mlir][sparse] add narrower choices for pointers/indices

Use cases with 16- or even 8-bit pointer/index structures have been identified.

Reviewed By: penpornk

Differential Revision: https://reviews.llvm.org/D95015

Added: 


Modified: 
mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
mlir/test/Dialect/Linalg/sparse_storage.mlir
mlir/test/lib/Transforms/TestSparsification.cpp

Removed: 




diff  --git a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h 
b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
index 0effa2f45c20..611ab6867372 100644
--- a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
+++ b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
@@ -853,13 +853,13 @@ enum class SparseVectorizationStrategy {
 };
 
 /// Defines a type for "pointer" and "index" storage in the sparse storage
-/// scheme, with a choice between the native platform-dependent index width,
-/// 64-bit integers, or 32-bit integers. A narrow width obviously reduces
+/// scheme, with a choice between the native platform-dependent index width
+/// or any of 64-/32-/16-/8-bit integers. A narrow width obviously reduces
 /// the memory footprint of the sparse storage scheme, but the width should
 /// suffice to define the total required range (viz. the maximum number of
 /// stored entries per indirection level for the "pointers" and the maximum
 /// value of each tensor index over all dimensions for the "indices").
-enum class SparseIntType { kNative, kI64, kI32 };
+enum class SparseIntType { kNative, kI64, kI32, kI16, kI8 };
 
 /// Sparsification options.
 struct SparsificationOptions {

diff  --git a/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp 
b/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
index 898b15266072..cefcdcbed9ae 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
@@ -512,6 +512,10 @@ static Type genIntType(PatternRewriter &rewriter, 
linalg::SparseIntType tp) {
 return rewriter.getIntegerType(64);
   case linalg::SparseIntType::kI32:
 return rewriter.getIntegerType(32);
+  case linalg::SparseIntType::kI16:
+return rewriter.getIntegerType(16);
+  case linalg::SparseIntType::kI8:
+return rewriter.getIntegerType(8);
   }
   llvm_unreachable("unexpected SparseIntType");
 }

diff  --git a/mlir/test/Dialect/Linalg/sparse_storage.mlir 
b/mlir/test/Dialect/Linalg/sparse_storage.mlir
index 69b8e1903d69..ef5dc0d766e3 100644
--- a/mlir/test/Dialect/Linalg/sparse_storage.mlir
+++ b/mlir/test/Dialect/Linalg/sparse_storage.mlir
@@ -6,6 +6,10 @@
 // RUN:   FileCheck %s --check-prefix=CHECK-TYPE2
 // RUN: mlir-opt %s -test-sparsification="ptr-type=2 ind-type=2" | \
 // RUN:   FileCheck %s --check-prefix=CHECK-TYPE3
+// RUN: mlir-opt %s -test-sparsification="ptr-type=3 ind-type=3" | \
+// RUN:   FileCheck %s --check-prefix=CHECK-TYPE4
+// RUN: mlir-opt %s -test-sparsification="ptr-type=4 ind-type=4" | \
+// RUN:   FileCheck %s --check-prefix=CHECK-TYPE5
 
 #trait_mul_1d = {
   indexing_maps = [
@@ -86,6 +90,38 @@
 // CHECK-TYPE3:   store %[[MUL]], %{{.*}}[%[[INDC]]] : memref<32xf64>
 // CHECK-TYPE3: }
 
+// CHECK-TYPE4-LABEL: func @mul_dd(
+// CHECK-TYPE4: %[[C0:.*]] = constant 0 : index
+// CHECK-TYPE4: %[[C1:.*]] = constant 1 : index
+// CHECK-TYPE4: %[[P0:.*]] = load %{{.*}}[%[[C0]]] : memref
+// CHECK-TYPE4: %[[B0:.*]] = index_cast %[[P0]] : i16 to index
+// CHECK-TYPE4: %[[P1:.*]] = load %{{.*}}[%[[C1]]] : memref
+// CHECK-TYPE4: %[[B1:.*]] = index_cast %[[P1]] : i16 to index
+// CHECK-TYPE4: scf.for %[[I:.*]] = %[[B0]] to %[[B1]] step %[[C1]] {
+// CHECK-TYPE4:   %[[IND0:.*]] = load %{{.*}}[%[[I]]] : memref
+// CHECK-TYPE4:   %[[INDC:.*]] = index_cast %[[IND0]] : i16 to index
+// CHECK-TYPE4:   %[[VAL0:.*]] = load %{{.*}}[%[[I]]] : memref
+// CHECK-TYPE4:   %[[VAL1:.*]] = load %{{.*}}[%[[INDC]]] : memref<32xf64>
+// CHECK-TYPE4:   %[[MUL:.*]] = mulf %[[VAL0]], %[[VAL1]] : f64
+// CHECK-TYPE4:   store %[[MUL]], %{{.*}}[%[[INDC]]] : memref<32xf64>
+// CHECK-TYPE4: }
+
+// CHECK-TYPE5-LABEL: func @mul_dd(
+// CHECK-TYPE5: %[[C0:.*]] = constant 0 : index
+// CHECK-TYPE5: %[[C1:.*]] = constant 1 : index
+// CHECK-TYPE5: %[[P0:.*]] = load %{{.*}}[%[[C0]]] : memref
+// CHECK-TYPE5: %[[B0:.*]] = index_cast %[[P0]] : i8 to index
+// CHECK-TYPE5: %[[P1:.*]] = load %{{.*}}[%[[C1]]] : memref
+// CHECK-TYPE5: %[[B1:.*]] = index_cast %[[P1]] : i8 to index
+// CHECK-TYPE5: scf.for %[[I:.*]] = %[[B0]] to %[[B1]] step %[[C1]] {
+// CHECK-TYPE5:   %[

[llvm-branch-commits] [mlir] 5959c28 - [mlir][sparse] add asserts on reading in tensor data

2021-01-20 Thread Aart Bik via llvm-branch-commits

Author: Aart Bik
Date: 2021-01-20T14:30:13-08:00
New Revision: 5959c28f24856f3d4a1db6b4743c66bdc6dcd735

URL: 
https://github.com/llvm/llvm-project/commit/5959c28f24856f3d4a1db6b4743c66bdc6dcd735
DIFF: 
https://github.com/llvm/llvm-project/commit/5959c28f24856f3d4a1db6b4743c66bdc6dcd735.diff

LOG: [mlir][sparse] add asserts on reading in tensor data

Rationale:
Since I made the argument that metadata helps with extra
verification checks, I better actually do that ;-)

Reviewed By: penpornk

Differential Revision: https://reviews.llvm.org/D95072

Added: 


Modified: 
mlir/lib/ExecutionEngine/SparseUtils.cpp

Removed: 




diff  --git a/mlir/lib/ExecutionEngine/SparseUtils.cpp 
b/mlir/lib/ExecutionEngine/SparseUtils.cpp
index 376b989975b5..d1962661fe79 100644
--- a/mlir/lib/ExecutionEngine/SparseUtils.cpp
+++ b/mlir/lib/ExecutionEngine/SparseUtils.cpp
@@ -48,9 +48,9 @@ namespace {
 /// and a rank-5 tensor element like
 ///   ({i,j,k,l,m}, a[i,j,k,l,m])
 struct Element {
-  Element(const std::vector &ind, double val)
+  Element(const std::vector &ind, double val)
   : indices(ind), value(val){};
-  std::vector indices;
+  std::vector indices;
   double value;
 };
 
@@ -61,9 +61,15 @@ struct Element {
 /// formats require the elements to appear in lexicographic index order).
 struct SparseTensor {
 public:
-  SparseTensor(int64_t capacity) : pos(0) { elements.reserve(capacity); }
+  SparseTensor(const std::vector &szs, uint64_t capacity)
+  : sizes(szs), pos(0) {
+elements.reserve(capacity);
+  }
   // Add element as indices and value.
-  void add(const std::vector &ind, double val) {
+  void add(const std::vector &ind, double val) {
+assert(sizes.size() == ind.size());
+for (int64_t r = 0, rank = sizes.size(); r < rank; r++)
+  assert(ind[r] < sizes[r]); // within bounds
 elements.emplace_back(Element(ind, val));
   }
   // Sort elements lexicographically by index.
@@ -82,6 +88,8 @@ struct SparseTensor {
 }
 return false;
   }
+
+  std::vector sizes; // per-rank dimension sizes
   std::vector elements;
   uint64_t pos;
 };
@@ -225,20 +233,24 @@ extern "C" void *openTensorC(char *filename, uint64_t 
*idata) {
 fprintf(stderr, "Unknown format %s\n", filename);
 exit(1);
   }
-  // Read all nonzero elements.
+  // Prepare sparse tensor object with per-rank dimension sizes
+  // and the number of nonzeros as initial capacity.
   uint64_t rank = idata[0];
   uint64_t nnz = idata[1];
-  SparseTensor *tensor = new SparseTensor(nnz);
-  std::vector indices(rank);
-  double value;
+  std::vector indices(rank);
+  for (uint64_t r = 0; r < rank; r++)
+indices[r] = idata[2 + r];
+  SparseTensor *tensor = new SparseTensor(indices, nnz);
+  // Read all nonzero elements.
   for (uint64_t k = 0; k < nnz; k++) {
 for (uint64_t r = 0; r < rank; r++) {
-  if (fscanf(file, "%" PRId64, &indices[r]) != 1) {
+  if (fscanf(file, "%" PRIu64, &indices[r]) != 1) {
 fprintf(stderr, "Cannot find next index in %s\n", filename);
 exit(1);
   }
   indices[r]--; // 0-based index
 }
+double value;
 if (fscanf(file, "%lg\n", &value) != 1) {
   fprintf(stderr, "Cannot find next value in %s\n", filename);
   exit(1);



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


[llvm-branch-commits] [mlir] 8b124c1 - [mlir][sparse] adjust output shape inference to new tensor abstraction

2021-01-05 Thread Aart Bik via llvm-branch-commits

Author: Aart Bik
Date: 2021-01-05T15:31:39-08:00
New Revision: 8b124c19f52cb8ed0236b602df56787553e1e1b6

URL: 
https://github.com/llvm/llvm-project/commit/8b124c19f52cb8ed0236b602df56787553e1e1b6
DIFF: 
https://github.com/llvm/llvm-project/commit/8b124c19f52cb8ed0236b602df56787553e1e1b6.diff

LOG: [mlir][sparse] adjust output shape inference to new tensor abstraction

Nicolas changed the tensor abstraction so that every output has
its own shape definition. This simplifies the "inference" that
was used in the sparse compiler.

Reviewed By: penpornk

Differential Revision: https://reviews.llvm.org/D94119

Added: 


Modified: 
mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
mlir/test/Dialect/Linalg/sparse_2d.mlir

Removed: 




diff  --git a/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp 
b/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
index a6b7277e47e3..ed81d5e24805 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
@@ -538,15 +538,8 @@ static void genBuffers(Merger &merger, CodeGen &codegen,
   // Find lower and upper bound in current dimension.
   Value up;
   if (shape[d] == TensorType::kDynamicSize) {
-// For the output tensor, we may need to infer the upper bound.
-// For all others, we look at the incoming argument.
-if (t == numInputs && !op.getNumInitTensors()) {
-  up = codegen.sizes[i];
-  assert(up); // TODO: what else?
-} else {
-  Value arg = t < numInputs ? op.getInput(t) : op.getInitTensors()[0];
-  up = rewriter.create(loc, arg, d);
-}
+Value arg = t < numInputs ? op.getInput(t) : op.getOutput(0);
+up = rewriter.create(loc, arg, d);
 args.push_back(up);
   } else {
 up = rewriter.create(loc, shape[d]);

diff  --git a/mlir/test/Dialect/Linalg/sparse_2d.mlir 
b/mlir/test/Dialect/Linalg/sparse_2d.mlir
index 6612a723f23d..9bb68ca91089 100644
--- a/mlir/test/Dialect/Linalg/sparse_2d.mlir
+++ b/mlir/test/Dialect/Linalg/sparse_2d.mlir
@@ -1139,19 +1139,19 @@ func @sum_reduction(%arga: tensor<10x20xf32>, %argx: 
tensor) -> tensor
 // CHECK:   %[[VAL_2:.*]] = constant 999 : index
 // CHECK:   %[[VAL_3:.*]] = constant 0 : index
 // CHECK:   %[[VAL_4:.*]] = constant 1 : index
-// CHECK:   %[[VAL_5:.*]] = dim %[[VAL_0]], %[[VAL_3]] : 
tensor
+// CHECK:   %[[VAL_5:.*]] = alloca(%[[VAL_2]]) : memref
 // CHECK:   %[[VAL_6:.*]] = alloca(%[[VAL_2]]) : memref
-// CHECK:   %[[VAL_7:.*]] = alloca(%[[VAL_2]]) : memref
-// CHECK:   %[[VAL_8:.*]] = dim %[[VAL_0]], %[[VAL_4]] : 
tensor
-// CHECK:   %[[VAL_9:.*]] = alloca(%[[VAL_2]]) : memref
-// CHECK:   %[[VAL_10:.*]] = alloca(%[[VAL_5]], %[[VAL_8]]) : 
memref
-// CHECK:   scf.for %[[VAL_11:.*]] = %[[VAL_3]] to %[[VAL_5]] step 
%[[VAL_4]] {
-// CHECK: %[[VAL_12:.*]] = load %[[VAL_6]]{{\[}}%[[VAL_11]]] : 
memref
+// CHECK:   %[[VAL_7:.*]] = alloca(%[[VAL_2]]) : memref
+// CHECK:   %[[VAL_8:.*]] = dim %[[VAL_0]], %[[VAL_3]] : 
tensor
+// CHECK:   %[[VAL_9:.*]] = dim %[[VAL_0]], %[[VAL_4]] : 
tensor
+// CHECK:   %[[VAL_10:.*]] = alloca(%[[VAL_8]], %[[VAL_9]]) : 
memref
+// CHECK:   scf.for %[[VAL_11:.*]] = %[[VAL_3]] to %[[VAL_8]] step 
%[[VAL_4]] {
+// CHECK: %[[VAL_12:.*]] = load %[[VAL_5]]{{\[}}%[[VAL_11]]] : 
memref
 // CHECK: %[[VAL_13:.*]] = addi %[[VAL_11]], %[[VAL_4]] : index
-// CHECK: %[[VAL_14:.*]] = load %[[VAL_6]]{{\[}}%[[VAL_13]]] : 
memref
+// CHECK: %[[VAL_14:.*]] = load %[[VAL_5]]{{\[}}%[[VAL_13]]] : 
memref
 // CHECK: scf.for %[[VAL_15:.*]] = %[[VAL_12]] to %[[VAL_14]] step 
%[[VAL_4]] {
-// CHECK:   %[[VAL_16:.*]] = load %[[VAL_7]]{{\[}}%[[VAL_15]]] : 
memref
-// CHECK:   %[[VAL_17:.*]] = load %[[VAL_9]]{{\[}}%[[VAL_15]]] : 
memref
+// CHECK:   %[[VAL_16:.*]] = load %[[VAL_6]]{{\[}}%[[VAL_15]]] : 
memref
+// CHECK:   %[[VAL_17:.*]] = load %[[VAL_7]]{{\[}}%[[VAL_15]]] : 
memref
 // CHECK:   %[[VAL_18:.*]] = mulf %[[VAL_17]], %[[VAL_1]] : f64
 // CHECK:   store %[[VAL_18]], %[[VAL_10]]{{\[}}%[[VAL_11]], 
%[[VAL_16]]] : memref
 // CHECK: }



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


[llvm-branch-commits] [mlir] a57def3 - [mlir][vector] generalized masked l/s and compressed l/s with indices

2021-01-08 Thread Aart Bik via llvm-branch-commits

Author: Aart Bik
Date: 2021-01-08T13:59:34-08:00
New Revision: a57def30f53990aafc3f64b9b7a0f60916cc7f61

URL: 
https://github.com/llvm/llvm-project/commit/a57def30f53990aafc3f64b9b7a0f60916cc7f61
DIFF: 
https://github.com/llvm/llvm-project/commit/a57def30f53990aafc3f64b9b7a0f60916cc7f61.diff

LOG: [mlir][vector] generalized masked l/s and compressed l/s with indices

Adding the ability to index the base address brings these operations closer
to the transfer read and write semantics (with lowering advantages), ensures
more consistent use in vector MLIR code (easier to read), and reduces the
amount of code duplication to lower memrefs into base addresses considerably
(making codegen less error-prone).

Reviewed By: ThomasRaoux

Differential Revision: https://reviews.llvm.org/D94278

Added: 


Modified: 
mlir/include/mlir/Dialect/Vector/VectorOps.td
mlir/integration_test/Dialect/Vector/CPU/test-compress.mlir
mlir/integration_test/Dialect/Vector/CPU/test-expand.mlir
mlir/integration_test/Dialect/Vector/CPU/test-maskedload.mlir
mlir/integration_test/Dialect/Vector/CPU/test-maskedstore.mlir
mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
mlir/lib/Dialect/Vector/VectorOps.cpp
mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir
mlir/test/Dialect/Vector/invalid.mlir
mlir/test/Dialect/Vector/ops.mlir
mlir/test/Dialect/Vector/vector-mem-transforms.mlir
mlir/test/Dialect/Vector/vector-transforms.mlir
mlir/test/lib/Transforms/TestVectorTransforms.cpp

Removed: 




diff  --git a/mlir/include/mlir/Dialect/Vector/VectorOps.td 
b/mlir/include/mlir/Dialect/Vector/VectorOps.td
index 0a98b9ffe996..0aa4950e0a9e 100644
--- a/mlir/include/mlir/Dialect/Vector/VectorOps.td
+++ b/mlir/include/mlir/Dialect/Vector/VectorOps.td
@@ -1317,6 +1317,7 @@ def Vector_TransferWriteOp :
 def Vector_MaskedLoadOp :
   Vector_Op<"maskedload">,
 Arguments<(ins AnyMemRef:$base,
+   Variadic:$indices,
VectorOfRankAndType<[1], [I1]>:$mask,
VectorOfRank<[1]>:$pass_thru)>,
 Results<(outs VectorOfRank<[1]>:$result)> {
@@ -1325,12 +1326,12 @@ def Vector_MaskedLoadOp :
 
   let description = [{
 The masked load reads elements from memory into a 1-D vector as defined
-by a base and a 1-D mask vector. When the mask is set, the element is read
-from memory. Otherwise, the corresponding element is taken from a 1-D
-pass-through vector. Informally the semantics are:
+by a base with indices and a 1-D mask vector. When the mask is set, the
+element is read from memory. Otherwise, the corresponding element is taken
+from a 1-D pass-through vector. Informally the semantics are:
 ```
-result[0] := mask[0] ? MEM[base+0] : pass_thru[0]
-result[1] := mask[1] ? MEM[base+1] : pass_thru[1]
+result[0] := mask[0] ? base[i+0] : pass_thru[0]
+result[1] := mask[1] ? base[i+1] : pass_thru[1]
 etc.
 ```
 The masked load can be used directly where applicable, or can be used
@@ -1342,7 +1343,7 @@ def Vector_MaskedLoadOp :
 Example:
 
 ```mlir
-%0 = vector.maskedload %base, %mask, %pass_thru
+%0 = vector.maskedload %base[%i], %mask, %pass_thru
: memref, vector<8xi1>, vector<8xf32> into vector<8xf32>
 ```
   }];
@@ -1360,7 +1361,7 @@ def Vector_MaskedLoadOp :
   return result().getType().cast();
 }
   }];
-  let assemblyFormat = "$base `,` $mask `,` $pass_thru attr-dict `:` "
+  let assemblyFormat = "$base `[` $indices `]` `,` $mask `,` $pass_thru 
attr-dict `:` "
 "type($base) `,` type($mask) `,` type($pass_thru) `into` type($result)";
   let hasCanonicalizer = 1;
 }
@@ -1368,6 +1369,7 @@ def Vector_MaskedLoadOp :
 def Vector_MaskedStoreOp :
   Vector_Op<"maskedstore">,
 Arguments<(ins AnyMemRef:$base,
+   Variadic:$indices,
VectorOfRankAndType<[1], [I1]>:$mask,
VectorOfRank<[1]>:$value)> {
 
@@ -1375,12 +1377,12 @@ def Vector_MaskedStoreOp :
 
   let description = [{
 The masked store operation writes elements from a 1-D vector into memory
-as defined by a base and a 1-D mask vector. When the mask is set, the
-corresponding element from the vector is written to memory. Otherwise,
+as defined by a base with indices and a 1-D mask vector. When the mask is
+set, the corresponding element from the vector is written to memory. 
Otherwise,
 no action is taken for the element. Informally the semantics are:
 ```
-if (mask[0]) MEM[base+0] = value[0]
-if (mask[1]) MEM[base+1] = value[1]
+if (mask[0]) base[i+0] = value[0]
+if (mask[1]) base[i+1] = value[1]
 etc.
 ```
 The masked store can be used directly where applicable, or can be used
@@ -1392,7 +1394,7 @@ def Vector_MaskedStoreOp :
 Example:
 
 ```mlir
-vector.maskedstore %base, %mask, %value
+vector.maskedstore %base[%

[llvm-branch-commits] [mlir] 6728af1 - [mlir][vector] modified scatter/gather syntax, pass_thru mandatory

2021-01-09 Thread Aart Bik via llvm-branch-commits

Author: Aart Bik
Date: 2021-01-09T11:41:37-08:00
New Revision: 6728af16cf987df3cf051f3a1f9c92ed2b8fbc2d

URL: 
https://github.com/llvm/llvm-project/commit/6728af16cf987df3cf051f3a1f9c92ed2b8fbc2d
DIFF: 
https://github.com/llvm/llvm-project/commit/6728af16cf987df3cf051f3a1f9c92ed2b8fbc2d.diff

LOG: [mlir][vector] modified scatter/gather syntax, pass_thru mandatory

This change makes the scatter/gather syntax more consistent with
the syntax of all the other memory operations in the Vector dialect
(order of types, use of [] for index, etc.). This will make the MLIR
code easier to read. In addition, the pass_thru parameter of the
gather has been made mandatory (there is very little benefit in
using the implicit "undefined" values).

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D94352

Added: 


Modified: 
mlir/include/mlir/Dialect/Vector/VectorOps.td
mlir/integration_test/Dialect/Vector/CPU/test-gather.mlir
mlir/integration_test/Dialect/Vector/CPU/test-scatter.mlir
mlir/integration_test/Dialect/Vector/CPU/test-sparse-dot-matvec.mlir

mlir/integration_test/Dialect/Vector/CPU/test-sparse-saxpy-jagged-matvec.mlir
mlir/lib/Dialect/Vector/VectorOps.cpp
mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir
mlir/test/Dialect/Vector/invalid.mlir
mlir/test/Dialect/Vector/ops.mlir
mlir/test/Dialect/Vector/vector-mem-transforms.mlir

Removed: 




diff  --git a/mlir/include/mlir/Dialect/Vector/VectorOps.td 
b/mlir/include/mlir/Dialect/Vector/VectorOps.td
index 0aa4950e0a9e..7f57dcd77def 100644
--- a/mlir/include/mlir/Dialect/Vector/VectorOps.td
+++ b/mlir/include/mlir/Dialect/Vector/VectorOps.td
@@ -1419,7 +1419,7 @@ def Vector_GatherOp :
 Arguments<(ins AnyMemRef:$base,
VectorOfRankAndType<[1], [AnyInteger]>:$indices,
VectorOfRankAndType<[1], [I1]>:$mask,
-   Variadic>:$pass_thru)>,
+   VectorOfRank<[1]>:$pass_thru)>,
 Results<(outs VectorOfRank<[1]>:$result)> {
 
   let summary = "gathers elements from memory into a vector as defined by an 
index vector and mask";
@@ -1428,10 +1428,8 @@ def Vector_GatherOp :
 The gather operation gathers elements from memory into a 1-D vector as
 defined by a base and a 1-D index vector, but only if the corresponding
 bit is set in a 1-D mask vector. Otherwise, the element is taken from a
-1-D pass-through vector, if provided, or left undefined. Informally the
-semantics are:
+1-D pass-through vector. Informally the semantics are:
 ```
-if (!defined(pass_thru)) pass_thru = [undef, .., undef]
 result[0] := mask[0] ? base[index[0]] : pass_thru[0]
 result[1] := mask[1] ? base[index[1]] : pass_thru[1]
 etc.
@@ -1447,8 +1445,8 @@ def Vector_GatherOp :
 Example:
 
 ```mlir
-%g = vector.gather %base, %indices, %mask, %pass_thru
-: (memref, vector<16xi32>, vector<16xi1>, vector<16xf32>) -> 
vector<16xf32>
+%g = vector.gather %base[%indices], %mask, %pass_thru
+   : memref, vector<16xi32>, vector<16xi1>, vector<16xf32> into 
vector<16xf32>
 ```
   }];
   let extraClassDeclaration = [{
@@ -1462,15 +1460,14 @@ def Vector_GatherOp :
   return mask().getType().cast();
 }
 VectorType getPassThruVectorType() {
-  return (llvm::size(pass_thru()) == 0)
-? VectorType()
-: (*pass_thru().begin()).getType().cast();
+  return pass_thru().getType().cast();
 }
 VectorType getResultVectorType() {
   return result().getType().cast();
 }
   }];
-  let assemblyFormat = "operands attr-dict `:` functional-type(operands, 
results)";
+  let assemblyFormat = "$base `[` $indices `]` `,` $mask `,` $pass_thru 
attr-dict `:` "
+"type($base) `,` type($indices) `,` type($mask) `,` type($pass_thru) 
`into` type($result)";
   let hasCanonicalizer = 1;
 }
 
@@ -1507,8 +1504,8 @@ def Vector_ScatterOp :
 Example:
 
 ```mlir
-vector.scatter %base, %indices, %mask, %value
-: vector<16xi32>, vector<16xi1>, vector<16xf32> into memref
+vector.scatter %base[%indices], %mask, %value
+: memref, vector<16xi32>, vector<16xi1>, vector<16xf32>
 ```
   }];
   let extraClassDeclaration = [{
@@ -1525,8 +1522,8 @@ def Vector_ScatterOp :
   return value().getType().cast();
 }
   }];
-  let assemblyFormat = "$base `,` $indices `,` $mask `,` $value attr-dict `:` "
-"type($indices) `,` type($mask) `,` type($value) `into` type($base)";
+  let assemblyFormat = "$base `[` $indices `]` `,` $mask `,` $value attr-dict 
`:` "
+"type($base) `,` type($indices) `,` type($mask) `,` type($value)";
   let hasCanonicalizer = 1;
 }
 

diff  --git a/mlir/integration_test/Dialect/Vector/CPU/test-gather.mlir 
b/mlir/integration_test/Dialect/Vector/CPU/test-gather.mlir
index 5ed8f3ee38f8..95df5aea06e4 100644
--- a/mlir/integration_test/Dialect/Vector/CPU/test-gath

[llvm-branch-commits] [mlir] 046612d - [mlir][vector] verify memref of vector memory ops

2021-01-11 Thread Aart Bik via llvm-branch-commits

Author: Aart Bik
Date: 2021-01-11T13:32:39-08:00
New Revision: 046612d29d7894783e8fcecbc62ebd6b4a78499f

URL: 
https://github.com/llvm/llvm-project/commit/046612d29d7894783e8fcecbc62ebd6b4a78499f
DIFF: 
https://github.com/llvm/llvm-project/commit/046612d29d7894783e8fcecbc62ebd6b4a78499f.diff

LOG: [mlir][vector] verify memref of vector memory ops

This ensures the memref base + indices expression is well-formed

Reviewed By: ThomasRaoux, ftynse

Differential Revision: https://reviews.llvm.org/D94441

Added: 


Modified: 
mlir/lib/Dialect/Vector/VectorOps.cpp
mlir/test/Dialect/Vector/invalid.mlir

Removed: 




diff  --git a/mlir/lib/Dialect/Vector/VectorOps.cpp 
b/mlir/lib/Dialect/Vector/VectorOps.cpp
index 731ddae85ead..54e5e008e56f 100644
--- a/mlir/lib/Dialect/Vector/VectorOps.cpp
+++ b/mlir/lib/Dialect/Vector/VectorOps.cpp
@@ -2365,10 +2365,12 @@ static LogicalResult verify(MaskedLoadOp op) {
   VectorType maskVType = op.getMaskVectorType();
   VectorType passVType = op.getPassThruVectorType();
   VectorType resVType = op.getResultVectorType();
+  MemRefType memType = op.getMemRefType();
 
-  if (resVType.getElementType() != op.getMemRefType().getElementType())
+  if (resVType.getElementType() != memType.getElementType())
 return op.emitOpError("base and result element type should match");
-
+  if (llvm::size(op.indices()) != memType.getRank())
+return op.emitOpError("requires ") << memType.getRank() << " indices";
   if (resVType.getDimSize(0) != maskVType.getDimSize(0))
 return op.emitOpError("expected result dim to match mask dim");
   if (resVType != passVType)
@@ -2410,10 +2412,12 @@ void MaskedLoadOp::getCanonicalizationPatterns(
 static LogicalResult verify(MaskedStoreOp op) {
   VectorType maskVType = op.getMaskVectorType();
   VectorType valueVType = op.getValueVectorType();
+  MemRefType memType = op.getMemRefType();
 
-  if (valueVType.getElementType() != op.getMemRefType().getElementType())
+  if (valueVType.getElementType() != memType.getElementType())
 return op.emitOpError("base and value element type should match");
-
+  if (llvm::size(op.indices()) != memType.getRank())
+return op.emitOpError("requires ") << memType.getRank() << " indices";
   if (valueVType.getDimSize(0) != maskVType.getDimSize(0))
 return op.emitOpError("expected value dim to match mask dim");
   return success();
@@ -2454,10 +2458,10 @@ static LogicalResult verify(GatherOp op) {
   VectorType indicesVType = op.getIndicesVectorType();
   VectorType maskVType = op.getMaskVectorType();
   VectorType resVType = op.getResultVectorType();
+  MemRefType memType = op.getMemRefType();
 
-  if (resVType.getElementType() != op.getMemRefType().getElementType())
+  if (resVType.getElementType() != memType.getElementType())
 return op.emitOpError("base and result element type should match");
-
   if (resVType.getDimSize(0) != indicesVType.getDimSize(0))
 return op.emitOpError("expected result dim to match indices dim");
   if (resVType.getDimSize(0) != maskVType.getDimSize(0))
@@ -2500,10 +2504,10 @@ static LogicalResult verify(ScatterOp op) {
   VectorType indicesVType = op.getIndicesVectorType();
   VectorType maskVType = op.getMaskVectorType();
   VectorType valueVType = op.getValueVectorType();
+  MemRefType memType = op.getMemRefType();
 
-  if (valueVType.getElementType() != op.getMemRefType().getElementType())
+  if (valueVType.getElementType() != memType.getElementType())
 return op.emitOpError("base and value element type should match");
-
   if (valueVType.getDimSize(0) != indicesVType.getDimSize(0))
 return op.emitOpError("expected value dim to match indices dim");
   if (valueVType.getDimSize(0) != maskVType.getDimSize(0))
@@ -2544,10 +2548,12 @@ static LogicalResult verify(ExpandLoadOp op) {
   VectorType maskVType = op.getMaskVectorType();
   VectorType passVType = op.getPassThruVectorType();
   VectorType resVType = op.getResultVectorType();
+  MemRefType memType = op.getMemRefType();
 
-  if (resVType.getElementType() != op.getMemRefType().getElementType())
+  if (resVType.getElementType() != memType.getElementType())
 return op.emitOpError("base and result element type should match");
-
+  if (llvm::size(op.indices()) != memType.getRank())
+return op.emitOpError("requires ") << memType.getRank() << " indices";
   if (resVType.getDimSize(0) != maskVType.getDimSize(0))
 return op.emitOpError("expected result dim to match mask dim");
   if (resVType != passVType)
@@ -2589,10 +2595,12 @@ void ExpandLoadOp::getCanonicalizationPatterns(
 static LogicalResult verify(CompressStoreOp op) {
   VectorType maskVType = op.getMaskVectorType();
   VectorType valueVType = op.getValueVectorType();
+  MemRefType memType = op.getMemRefType();
 
-  if (valueVType.getElementType() != op.getMemRefType().getElementType())
+  if (valueVType.getElementType() != memType.getElementType())

[llvm-branch-commits] [mlir] 106e66f - [mlir][ArmSVE] Add documentation generation

2020-12-17 Thread Aart Bik via llvm-branch-commits

Author: Javier Setoain
Date: 2020-12-17T12:22:48-08:00
New Revision: 106e66f3f555c8f887e82c5f04c3e77bdaf345e8

URL: 
https://github.com/llvm/llvm-project/commit/106e66f3f555c8f887e82c5f04c3e77bdaf345e8
DIFF: 
https://github.com/llvm/llvm-project/commit/106e66f3f555c8f887e82c5f04c3e77bdaf345e8.diff

LOG: [mlir][ArmSVE] Add documentation generation

Adds missing cmake command to generate documentation for ArmSVE
Dialect.

Reviewed By: aartbik

Differential Revision: https://reviews.llvm.org/D93465

Added: 


Modified: 
mlir/include/mlir/Dialect/ArmSVE/CMakeLists.txt

Removed: 




diff  --git a/mlir/include/mlir/Dialect/ArmSVE/CMakeLists.txt 
b/mlir/include/mlir/Dialect/ArmSVE/CMakeLists.txt
index fb50fac68f33..c7db56122a95 100644
--- a/mlir/include/mlir/Dialect/ArmSVE/CMakeLists.txt
+++ b/mlir/include/mlir/Dialect/ArmSVE/CMakeLists.txt
@@ -1 +1,2 @@
 add_mlir_dialect(ArmSVE arm_sve ArmSVE)
+add_mlir_doc(ArmSVE -gen-dialect-doc ArmSVE Dialects/)



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


[llvm-branch-commits] [mlir] 14da25b - [mlir][sparse] scalarize reductions in for-loops during sparse codegen

2020-12-17 Thread Aart Bik via llvm-branch-commits

Author: Aart Bik
Date: 2020-12-17T16:12:21-08:00
New Revision: 14da25b4b2eedf8a16aae34edfefd7bcaa5ceae5

URL: 
https://github.com/llvm/llvm-project/commit/14da25b4b2eedf8a16aae34edfefd7bcaa5ceae5
DIFF: 
https://github.com/llvm/llvm-project/commit/14da25b4b2eedf8a16aae34edfefd7bcaa5ceae5.diff

LOG: [mlir][sparse] scalarize reductions in for-loops during sparse codegen

Reductions in innermost loops become harder for the backend to disambiguate
after bufferization into memrefs, resulting in less efficient load-update-store
cycles. By scalarizing innermost reductions, the backend is more likely to 
assign
a register to perform the reduction (also prepares vectorization). Even though
we could scalarize reductions for more outer loops and while-loops as well,
currently scalarization is only done for chains of innermost for-loops, where
it matters most, to avoid complicating codegen unnecessary (viz. adding lots
of yield instructions).

This CL also refactors condition simplification into the merger class,
where it belongs, so that conditions are simplified only once per loop
nest and not repeatedly as was currently done. This CL also fixes a few
minor bugs, some layout issues, and comments.

Reviewed By: penpornk

Differential Revision: https://reviews.llvm.org/D93143

Added: 


Modified: 
mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
mlir/test/Dialect/Linalg/sparse_1d.mlir
mlir/test/Dialect/Linalg/sparse_2d.mlir
mlir/test/Dialect/Linalg/sparse_3d.mlir

Removed: 




diff  --git a/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp 
b/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
index cfdb371e3234..fed2eedd41a4 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
@@ -52,6 +52,7 @@ using namespace mlir;
 namespace {
 
 enum class Kind { kTensor, kInvariant, kMulF, kMulI, kAddF, kAddI };
+enum class Dim { kSparse, kDense, kUndef };
 
 /// Tensor expression. Represents a MLIR expression in tensor index notation.
 /// For tensors, e0 denotes the tensor index. For invariants, the IR value is
@@ -81,8 +82,13 @@ struct LatPoint {
 bits.set(b);
   }
   LatPoint(const llvm::BitVector &b, unsigned e) : bits(b), exp(e) {}
-  /// Conjunction of tensor loop indices as bitvector.
+  /// Conjunction of tensor loop indices as bitvector. This represents
+  /// all indices involved in the tensor expression
   llvm::BitVector bits;
+  /// Simplified conjunction of tensor loop indices as bitvector. This
+  /// represents a simplified condition under which this tensor expression
+  /// must execute. Pre-computed during codegen to avoid repeated eval.
+  llvm::BitVector simple;
   /// Index of the tensor expresssion.
   unsigned exp;
 };
@@ -93,8 +99,14 @@ struct LatPoint {
 /// independently from the basic algorithm if bottlenecks are identified.
 class Merger {
 public:
+  /// Constructs a merger for the given number of tensors and loops. The
+  /// user supplies the number of tensors involved in the kernel, with the
+  /// last tensor in this set denoting the output tensor. The merger adds an
+  /// additional synthetic tensor at the end of this set to represent all
+  /// invariant expressions in the kernel.
   Merger(unsigned t, unsigned l)
-  : numTensors(t), numLoops(l), isSparse(t, std::vector(l, false)) {}
+  : outTensor(t - 1), numTensors(t + 1), numLoops(l),
+dims(t + 1, std::vector(l, Dim::kUndef)) {}
 
   /// Adds a tensor expression. Returns its index.
   unsigned addExp(Kind k, unsigned e0, unsigned e1 = -1u, Value v = Value()) {
@@ -132,8 +144,8 @@ class Merger {
 return p;
   }
 
-  /// Conjunctive merge of L1 and L2 is conjunction of cartesian product.
-  /// Returns the index of the new set.
+  /// Conjunctive merge of two lattice sets L0 and L1 is conjunction of
+  /// cartesian product. Returns the index of the new set.
   unsigned takeConj(Kind kind, unsigned s0, unsigned s1) {
 unsigned s = addSet();
 for (unsigned p0 : latSets[s0])
@@ -142,7 +154,7 @@ class Merger {
 return s;
   }
 
-  /// Disjunctive merge of L0 and L1 is (L0 /\_op L1, L0, L1).
+  /// Disjunctive merge of two lattice sets L0 and L1 is (L0 /\_op L1, L0, L1).
   /// Returns the index of the new set.
   unsigned takeDisj(Kind kind, unsigned s0, unsigned s1) {
 unsigned s = takeConj(kind, s0, s1);
@@ -156,26 +168,27 @@ class Merger {
   /// Optimizes the iteration lattice points in the given set. This
   /// method should be called right before code generation to avoid
   /// generating redundant loops and conditions.
-  unsigned optimize(unsigned s0) {
+  unsigned optimizeSet(unsigned s0) {
 unsigned s = addSet();
 assert(latSets[s0].size() != 0);
 unsigned p0 = latSets[s0][0];
 for (unsigned p1 : latSets[s0]) {
   bool add = true;
+  llvm::BitVector simple = simplifyCond(s0, p1);
 

[llvm-branch-commits] [mlir] 9a8cab8 - [mlir][sparse] adjust output tensor to synthetic tensor

2020-12-21 Thread Aart Bik via llvm-branch-commits

Author: Aart Bik
Date: 2020-12-21T14:13:54-08:00
New Revision: 9a8cab8bacc12d48d74249d868082effe132029e

URL: 
https://github.com/llvm/llvm-project/commit/9a8cab8bacc12d48d74249d868082effe132029e
DIFF: 
https://github.com/llvm/llvm-project/commit/9a8cab8bacc12d48d74249d868082effe132029e.diff

LOG: [mlir][sparse] adjust output tensor to synthetic tensor

Fixes a merge conflict with previous two CLs.

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D93664

Added: 


Modified: 
mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp

Removed: 




diff  --git a/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp 
b/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
index eb940d0f769b..a6b7277e47e3 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
@@ -466,8 +466,8 @@ static unsigned buildLattices(Merger &merger, 
linalg::GenericOp op,
 // set to the undefined index in that dimension. An invariant expression
 // is set to a synthetic tensor with undefined indices only.
 unsigned s = merger.addSet();
-unsigned t = kind == Kind::kTensor ? merger.exp(exp).e0
-   : op.getNumShapedOperands() - 1;
+unsigned t =
+kind == Kind::kTensor ? merger.exp(exp).e0 : op.getNumShapedOperands();
 merger.set(s).push_back(merger.addLat(t, idx, exp));
 return s;
   }



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


[llvm-branch-commits] [mlir] 5c4e397 - [mlir][sparse] add parallelization strategies to sparse compiler

2020-11-24 Thread Aart Bik via llvm-branch-commits

Author: Aart Bik
Date: 2020-11-24T17:17:13-08:00
New Revision: 5c4e397e6ce5c89d63f590857e5cb0e80237de62

URL: 
https://github.com/llvm/llvm-project/commit/5c4e397e6ce5c89d63f590857e5cb0e80237de62
DIFF: 
https://github.com/llvm/llvm-project/commit/5c4e397e6ce5c89d63f590857e5cb0e80237de62.diff

LOG: [mlir][sparse] add parallelization strategies to sparse compiler

This CL adds the ability to request different parallelization strategies
for the generate code. Every "parallel" loop is a candidate, and converted
to a parallel op if it is an actual for-loop (not a while) and the strategy
allows dense/sparse outer/inner parallelization.

This will connect directly with the work of @ezhulenev on parallel loops.

Still TBD: vectorization strategy

Reviewed By: penpornk

Differential Revision: https://reviews.llvm.org/D91978

Added: 
mlir/test/Dialect/Linalg/sparse_parallel.mlir

Modified: 
mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
mlir/test/lib/Transforms/TestSparsification.cpp

Removed: 




diff  --git a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h 
b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
index d67e81ceab87..7a96a5ed1390 100644
--- a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
+++ b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
@@ -783,9 +783,62 @@ LogicalResult applyStagedPatterns(
 
 
//===--===//
 // Support for sparse tensor code generation.
+//
+// The sparse compiler part of MLIR lowers a tensor expression formulated as a
+// Linalg operation into a sequence of loops depending on what dimensions of 
the
+// tensors are marked dense or sparse. The generated code distinguishes 
between:
+// (1) for-loops that iterate over a single dense dimension,
+// (2) for-loops that iterate over a single sparse dimension,
+// (3) while-loops that co-iterate over several sparse dimensions.
+// The for-loops may be subsequently optimized for parallel or vector 
execution.
+//
+// For more details, the Dialect/Linalg/Transforms/Sparsification.cpp file.
 
//===--===//
-void populateSparsificationPatterns(MLIRContext *context,
-OwningRewritePatternList &patterns);
+
+/// Defines a parallelization strategy. Any implicit loop in the Linalg
+/// operation that is marked "parallel" (thus not "reduction") is a candidate
+/// for parallelization. The loop is made parallel if (1) allowed by the
+/// strategy (e.g., AnyStorageOuterLoop considers either a dense or sparse
+/// outermost loop only), and (2) the generated code is an actual for-loop
+/// (and not a co-iterating while-loop).
+enum class SparseParallelizationStrategy {
+  kNone,
+  kDenseOuterLoop,
+  kAnyStorageOuterLoop,
+  kDenseAnyLoop,
+  kAnyStorageAnyLoop
+  // TODO: support reduction parallelization too?
+};
+
+/// Defines a vectorization strategy. Any implicit inner loop in the Linalg
+/// operation is a candidate (full SIMD for "parallel" loops and horizontal
+/// SIMD for "reduction" loops). A loop is actually vectorized if (1) allowed
+/// by the strategy, and (2) the emitted code is an actual for-loop (and not
+/// a co-iterating while-loop).
+enum class SparseVectorizationStrategy {
+  kNone,
+  kDenseInnerLoop,
+  kAnyStorageInnerLoop
+};
+
+/// Sparsification options.
+struct SparsificationOptions {
+  SparsificationOptions(SparseParallelizationStrategy p,
+SparseVectorizationStrategy v, unsigned vl)
+  : parallelizationStrategy(p), vectorizationStrategy(v), vectorLength(vl) 
{
+  }
+  SparsificationOptions()
+  : SparsificationOptions(SparseParallelizationStrategy::kNone,
+  SparseVectorizationStrategy::kNone, 1u) {}
+  SparseParallelizationStrategy parallelizationStrategy;
+  SparseVectorizationStrategy vectorizationStrategy;
+  unsigned vectorLength;
+};
+
+/// Set up sparsification rewriting rules with the given options.
+void populateSparsificationPatterns(
+MLIRContext *context, OwningRewritePatternList &patterns,
+const SparsificationOptions &options = SparsificationOptions());
 
 } // namespace linalg
 } // namespace mlir

diff  --git a/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp 
b/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
index 69a4d7e5648e..729268393ed9 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
@@ -235,22 +235,30 @@ class Merger {
 
 // Code generation.
 struct CodeGen {
-  CodeGen(unsigned numTensors, unsigned numLoops)
-  : loops(numLoops), sizes(numLoops), buffers(numTensors),
+  CodeGen(linalg::SparsificationOptions o, unsigned numTensors,
+  unsigned numLoops)
+  : o

[llvm-branch-commits] [mlir] d5f0d0c - [mlir][sparse] add ability to select pointer/index storage type

2020-11-25 Thread Aart Bik via llvm-branch-commits

Author: Aart Bik
Date: 2020-11-25T17:32:44-08:00
New Revision: d5f0d0c0c4117295d9e76bbafaf0597e01ef3c99

URL: 
https://github.com/llvm/llvm-project/commit/d5f0d0c0c4117295d9e76bbafaf0597e01ef3c99
DIFF: 
https://github.com/llvm/llvm-project/commit/d5f0d0c0c4117295d9e76bbafaf0597e01ef3c99.diff

LOG: [mlir][sparse] add ability to select pointer/index storage type

This change gives sparse compiler clients more control over selecting
individual types for the pointers and indices in the sparse storage schemes.
Narrower width obviously results in smaller memory footprints, but the
range should always suffice for the maximum number of entries or index value.

Reviewed By: penpornk

Differential Revision: https://reviews.llvm.org/D92126

Added: 
mlir/test/Dialect/Linalg/sparse_storage.mlir

Modified: 
mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
mlir/test/lib/Transforms/TestSparsification.cpp

Removed: 




diff  --git a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h 
b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
index 7a96a5ed1390..b37a14f0eb7a 100644
--- a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
+++ b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
@@ -821,18 +821,31 @@ enum class SparseVectorizationStrategy {
   kAnyStorageInnerLoop
 };
 
+/// Defines a type for "pointer" and "index" storage in the sparse storage
+/// scheme, with a choice between the native platform-dependent index width,
+/// 64-bit integers, or 32-bit integers. A narrow width obviously reduces
+/// the memory footprint of the sparse storage scheme, but the width should
+/// suffice to define the total required range (viz. the maximum number of
+/// stored entries per indirection level for the "pointers" and the maximum
+/// value of each tensor index over all dimensions for the "indices").
+enum class SparseIntType { kNative, kI64, kI32 };
+
 /// Sparsification options.
 struct SparsificationOptions {
   SparsificationOptions(SparseParallelizationStrategy p,
-SparseVectorizationStrategy v, unsigned vl)
-  : parallelizationStrategy(p), vectorizationStrategy(v), vectorLength(vl) 
{
-  }
+SparseVectorizationStrategy v, unsigned vl,
+SparseIntType pt, SparseIntType it)
+  : parallelizationStrategy(p), vectorizationStrategy(v), vectorLength(vl),
+ptrType(pt), indType(it) {}
   SparsificationOptions()
   : SparsificationOptions(SparseParallelizationStrategy::kNone,
-  SparseVectorizationStrategy::kNone, 1u) {}
+  SparseVectorizationStrategy::kNone, 1u,
+  SparseIntType::kNative, SparseIntType::kNative) 
{}
   SparseParallelizationStrategy parallelizationStrategy;
   SparseVectorizationStrategy vectorizationStrategy;
   unsigned vectorLength;
+  SparseIntType ptrType;
+  SparseIntType indType;
 };
 
 /// Set up sparsification rewriting rules with the given options.

diff  --git a/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp 
b/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
index 729268393ed9..07a3e1569622 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
@@ -420,16 +420,27 @@ static unsigned buildLattices(Merger &merger, 
linalg::GenericOp op,
   }
 }
 
+/// Maps sparse integer option to actual integral storage type.
+static Type genIntType(PatternRewriter &rewriter, linalg::SparseIntType tp) {
+  switch (tp) {
+  case linalg::SparseIntType::kNative:
+return rewriter.getIndexType();
+  case linalg::SparseIntType::kI64:
+return rewriter.getIntegerType(64);
+  case linalg::SparseIntType::kI32:
+return rewriter.getIntegerType(32);
+  }
+}
+
 /// Local bufferization of all dense and sparse data structures.
 /// This code enables testing the first prototype sparse compiler.
 // TODO: replace this with a proliferated bufferization strategy
-void genBuffers(Merger &merger, CodeGen &codegen, PatternRewriter &rewriter,
-linalg::GenericOp op) {
+static void genBuffers(Merger &merger, CodeGen &codegen,
+   PatternRewriter &rewriter, linalg::GenericOp op) {
   Location loc = op.getLoc();
   unsigned numTensors = op.getNumInputsAndOutputs();
   unsigned numInputs = op.getNumInputs();
   assert(numTensors == numInputs + 1);
-  Type indexType = rewriter.getIndexType();
 
   // For now, set all unknown dimensions to 999.
   // TODO: compute these values (using sparsity or by reading tensor)
@@ -450,9 +461,13 @@ void genBuffers(Merger &merger, CodeGen &codegen, 
PatternRewriter &rewriter,
   // Handle sparse storage schemes.
   if (merger.isSparseAccess(t, i)) {
 allDense = false;
-auto dynTp = MemRefType::get({ShapedT

[llvm-branch-commits] [mlir] c95acf0 - [mlir][vector][avx512] move avx512 lowering pass into general vector lowering

2020-12-03 Thread Aart Bik via llvm-branch-commits

Author: Aart Bik
Date: 2020-12-03T17:23:46-08:00
New Revision: c95acf052b53e5c18e380b8632e7de24b5e65dbe

URL: 
https://github.com/llvm/llvm-project/commit/c95acf052b53e5c18e380b8632e7de24b5e65dbe
DIFF: 
https://github.com/llvm/llvm-project/commit/c95acf052b53e5c18e380b8632e7de24b5e65dbe.diff

LOG: [mlir][vector][avx512] move avx512 lowering pass into general vector 
lowering

A separate AVX512 lowering pass does not compose well with the regular
vector lowering pass. As such, it is at risk of code duplication and
lowering inconsistencies. This change removes the separate AVX512 lowering
pass and makes it an "option" in the regular vector lowering pass
(viz. vector dialect "augmented" with AVX512 dialect).

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D92614

Added: 
mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVMPass.cpp

Modified: 
mlir/include/mlir/Conversion/AVX512ToLLVM/ConvertAVX512ToLLVM.h
mlir/include/mlir/Conversion/Passes.h
mlir/include/mlir/Conversion/Passes.td
mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h
mlir/lib/Conversion/AVX512ToLLVM/ConvertAVX512ToLLVM.cpp
mlir/lib/Conversion/VectorToLLVM/CMakeLists.txt
mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
mlir/lib/Dialect/AVX512/CMakeLists.txt
mlir/test/Conversion/AVX512ToLLVM/convert-to-llvm.mlir

Removed: 




diff  --git a/mlir/include/mlir/Conversion/AVX512ToLLVM/ConvertAVX512ToLLVM.h 
b/mlir/include/mlir/Conversion/AVX512ToLLVM/ConvertAVX512ToLLVM.h
index aff5c4ca2c70..06f2958a2d5a 100644
--- a/mlir/include/mlir/Conversion/AVX512ToLLVM/ConvertAVX512ToLLVM.h
+++ b/mlir/include/mlir/Conversion/AVX512ToLLVM/ConvertAVX512ToLLVM.h
@@ -9,21 +9,15 @@
 #ifndef MLIR_CONVERSION_AVX512TOLLVM_CONVERTAVX512TOLLVM_H_
 #define MLIR_CONVERSION_AVX512TOLLVM_CONVERTAVX512TOLLVM_H_
 
-#include 
-
 namespace mlir {
+
 class LLVMTypeConverter;
-class ModuleOp;
-template  class OperationPass;
 class OwningRewritePatternList;
 
 /// Collect a set of patterns to convert from the AVX512 dialect to LLVM.
 void populateAVX512ToLLVMConversionPatterns(LLVMTypeConverter &converter,
 OwningRewritePatternList 
&patterns);
 
-/// Create a pass to convert AVX512 operations to the LLVMIR dialect.
-std::unique_ptr> createConvertAVX512ToLLVMPass();
-
 } // namespace mlir
 
 #endif // MLIR_CONVERSION_AVX512TOLLVM_CONVERTAVX512TOLLVM_H_

diff  --git a/mlir/include/mlir/Conversion/Passes.h 
b/mlir/include/mlir/Conversion/Passes.h
index 0d2281f99581..cc4f59c12496 100644
--- a/mlir/include/mlir/Conversion/Passes.h
+++ b/mlir/include/mlir/Conversion/Passes.h
@@ -9,7 +9,6 @@
 #ifndef MLIR_CONVERSION_PASSES_H
 #define MLIR_CONVERSION_PASSES_H
 
-#include "mlir/Conversion/AVX512ToLLVM/ConvertAVX512ToLLVM.h"
 #include "mlir/Conversion/AffineToStandard/AffineToStandard.h"
 #include "mlir/Conversion/AsyncToLLVM/AsyncToLLVM.h"
 #include "mlir/Conversion/GPUCommon/GPUCommonPass.h"

diff  --git a/mlir/include/mlir/Conversion/Passes.td 
b/mlir/include/mlir/Conversion/Passes.td
index fdf01b7f93d0..6c99d84ea30a 100644
--- a/mlir/include/mlir/Conversion/Passes.td
+++ b/mlir/include/mlir/Conversion/Passes.td
@@ -73,17 +73,6 @@ def ConvertAffineToStandard : Pass<"lower-affine"> {
   ];
 }
 
-//===--===//
-// AVX512ToLLVM
-//===--===//
-
-def ConvertAVX512ToLLVM : Pass<"convert-avx512-to-llvm", "ModuleOp"> {
-  let summary = "Convert the operations from the avx512 dialect into the LLVM "
-"dialect";
-  let constructor = "mlir::createConvertAVX512ToLLVMPass()";
-  let dependentDialects = ["LLVM::LLVMDialect", "LLVM::LLVMAVX512Dialect"];
-}
-
 
//===--===//
 // AsyncToLLVM
 
//===--===//
@@ -401,15 +390,28 @@ def ConvertVectorToSCF : 
FunctionPass<"convert-vector-to-scf"> {
 def ConvertVectorToLLVM : Pass<"convert-vector-to-llvm", "ModuleOp"> {
   let summary = "Lower the operations from the vector dialect into the LLVM "
 "dialect";
+  let description = [{
+
+Convert operations from the vector dialect into the LLVM IR dialect
+operations. The lowering pass provides several options to control
+the kind of optimizations that are allowed. It also provides options
+that augment the architectural-neutral vector dialect with
+architectural-specific dialects (AVX512, Neon, etc.).
+
+  }];
   let constructor = "mlir::createConvertVectorToLLVMPass()";
-  let dependentDialects = ["LLVM::LLVMDialect"];
+  let dependentDialects = ["LLVM::LLVMDialect", "LLVM::LLVMAVX512Dialect"];
   let options = [
 Option<"reassociateFPReductions", "reassociate-fp-reductions",
   

[llvm-branch-commits] [mlir] fc7818f - [mlir][vector] rephrased description

2020-12-04 Thread Aart Bik via llvm-branch-commits

Author: Aart Bik
Date: 2020-12-04T14:00:49-08:00
New Revision: fc7818f5d6906555cebad2c2e7c313a383b9cb82

URL: 
https://github.com/llvm/llvm-project/commit/fc7818f5d6906555cebad2c2e7c313a383b9cb82
DIFF: 
https://github.com/llvm/llvm-project/commit/fc7818f5d6906555cebad2c2e7c313a383b9cb82.diff

LOG: [mlir][vector] rephrased description

More carefully worded description. Added constructor to options.

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D92664

Added: 


Modified: 
mlir/include/mlir/Conversion/Passes.td
mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h

Removed: 




diff  --git a/mlir/include/mlir/Conversion/Passes.td 
b/mlir/include/mlir/Conversion/Passes.td
index 6c99d84ea30a..53158afa0530 100644
--- a/mlir/include/mlir/Conversion/Passes.td
+++ b/mlir/include/mlir/Conversion/Passes.td
@@ -394,9 +394,10 @@ def ConvertVectorToLLVM : Pass<"convert-vector-to-llvm", 
"ModuleOp"> {
 
 Convert operations from the vector dialect into the LLVM IR dialect
 operations. The lowering pass provides several options to control
-the kind of optimizations that are allowed. It also provides options
-that augment the architectural-neutral vector dialect with
-architectural-specific dialects (AVX512, Neon, etc.).
+the kinds of optimizations that are allowed. It also provides options
+that enable the use of one or more architectural-specific dialects
+(AVX512, Neon, SVE, etc.) in combination with the architectural-neutral
+vector dialect lowering.
 
   }];
   let constructor = "mlir::createConvertVectorToLLVMPass()";
@@ -411,7 +412,8 @@ def ConvertVectorToLLVM : Pass<"convert-vector-to-llvm", 
"ModuleOp"> {
   "faster code">,
 Option<"enableAVX512", "enable-avx512",
"bool", /*default=*/"false",
-   "Augments the vector dialect with the AVX512 dialect during 
lowering">
+   "Enables the use of AVX512 dialect while lowering the vector "
+  "dialect.">
   ];
 }
 

diff  --git a/mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h 
b/mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h
index 435a148e2b10..e6a515aa4564 100644
--- a/mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h
+++ b/mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h
@@ -21,9 +21,10 @@ class OperationPass;
 /// This should kept in sync with VectorToLLVM options defined for the
 /// ConvertVectorToLLVM pass in include/mlir/Conversion/Passes.td
 struct LowerVectorToLLVMOptions {
-  bool reassociateFPReductions = false;
-  bool enableIndexOptimizations = true;
-  bool enableAVX512 = false;
+  LowerVectorToLLVMOptions()
+  : reassociateFPReductions(false), enableIndexOptimizations(true),
+enableAVX512(false) {}
+
   LowerVectorToLLVMOptions &setReassociateFPReductions(bool b) {
 reassociateFPReductions = b;
 return *this;
@@ -36,6 +37,10 @@ struct LowerVectorToLLVMOptions {
 enableAVX512 = b;
 return *this;
   }
+
+  bool reassociateFPReductions;
+  bool enableIndexOptimizations;
+  bool enableAVX512;
 };
 
 /// Collect a set of patterns to convert from Vector contractions to LLVM 
Matrix



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


[llvm-branch-commits] [mlir] 74cd9e5 - [mlir][sparse] hoist loop invariant tensor loads in sparse compiler

2020-12-07 Thread Aart Bik via llvm-branch-commits

Author: Aart Bik
Date: 2020-12-07T11:59:48-08:00
New Revision: 74cd9e587d80063381242006d0690231d756aa7a

URL: 
https://github.com/llvm/llvm-project/commit/74cd9e587d80063381242006d0690231d756aa7a
DIFF: 
https://github.com/llvm/llvm-project/commit/74cd9e587d80063381242006d0690231d756aa7a.diff

LOG: [mlir][sparse] hoist loop invariant tensor loads in sparse compiler

After bufferization, the backend has much more trouble hoisting loop invariant
loads from the loops generated by the sparse compiler. Therefore, this is done
during sparse code generation. Note that we don't bother hoisting derived
invariant expressions on SSA values, since the backend does that very well.

Still TBD: scalarize reductions to avoid load-add-store cycles

Reviewed By: penpornk

Differential Revision: https://reviews.llvm.org/D92534

Added: 


Modified: 
mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
mlir/test/Dialect/Linalg/sparse_2d.mlir
mlir/test/Dialect/Linalg/sparse_3d.mlir

Removed: 




diff  --git a/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp 
b/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
index 07a3e1569622..cfdb371e3234 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Sparsification.cpp
@@ -59,14 +59,21 @@ enum class Kind { kTensor, kInvariant, kMulF, kMulI, kAddF, 
kAddI };
 /// children tensor expressions.
 struct TensorExp {
   TensorExp(Kind k, unsigned x, unsigned y, Value v)
-  : kind(k), e0(x), e1(y), val(v) {}
+  : kind(k), e0(x), e1(y), val(v) {
+assert((kind == Kind::kTensor && e0 != -1u && e1 == -1u && !val) ||
+   (kind == Kind::kInvariant && e0 == -1u && e1 == -1u && val) ||
+   (kind >= Kind::kMulF && e0 != -1u && e1 != -1u && !val));
+  }
   Kind kind;
+  /// Indices of children expression(s).
   unsigned e0;
   unsigned e1;
+  /// Direct link to IR for an invariant. During code generation,
+  /// field is used to cache "hoisted" loop invariant tensor loads.
   Value val;
 };
 
-/// Lattice point. Each lattice point consist of a conjunction of tensor
+/// Lattice point. Each lattice point consists of a conjunction of tensor
 /// loop indices (encoded in a bitvector) and the index of the corresponding
 /// tensor expression.
 struct LatPoint {
@@ -74,7 +81,9 @@ struct LatPoint {
 bits.set(b);
   }
   LatPoint(const llvm::BitVector &b, unsigned e) : bits(b), exp(e) {}
+  /// Conjunction of tensor loop indices as bitvector.
   llvm::BitVector bits;
+  /// Index of the tensor expresssion.
   unsigned exp;
 };
 
@@ -502,8 +511,16 @@ static void genBuffers(Merger &merger, CodeGen &codegen,
 /// Generates a load on a dense or sparse tensor.
 static Value genTensorLoad(Merger &merger, CodeGen &codegen,
PatternRewriter &rewriter, linalg::GenericOp op,
-   unsigned tensor) {
+   unsigned exp) {
+  // Test if the load was hoisted to a higher loop nest.
+  Value val = merger.exp(exp).val;
+  if (val) {
+merger.exp(exp).val = Value(); // reset
+return val;
+  }
+  // Actual load.
   SmallVector args;
+  unsigned tensor = merger.exp(exp).e0;
   auto map = op.getIndexingMap(tensor);
   bool sparse = false;
   for (unsigned i = 0, m = map.getNumResults(); i < m; ++i) {
@@ -515,7 +532,9 @@ static Value genTensorLoad(Merger &merger, CodeGen &codegen,
   args.push_back(codegen.pidxs[tensor][idx]); // position index
 }
   }
-  return rewriter.create(op.getLoc(), codegen.buffers[tensor], args);
+  Location loc = op.getLoc();
+  Value ptr = codegen.buffers[tensor];
+  return rewriter.create(loc, ptr, args);
 }
 
 /// Generates a store on a dense tensor.
@@ -528,25 +547,33 @@ static void genTensorStore(Merger &merger, CodeGen 
&codegen,
 unsigned idx = map.getDimPosition(i);
 args.push_back(codegen.loops[idx]); // universal dense index
   }
-  rewriter.create(op.getLoc(), rhs, codegen.buffers[tensor], args);
+  Location loc = op.getLoc();
+  Value ptr = codegen.buffers[tensor];
+  rewriter.create(loc, rhs, ptr, args);
 }
 
 /// Generates a pointer/index load from the sparse storage scheme.
-static Value genIntLoad(PatternRewriter &rewriter, Location loc, Value ptr,
-Value s) {
+static Value genLoad(PatternRewriter &rewriter, Location loc, Value ptr,
+ Value s) {
   Value load = rewriter.create(loc, ptr, s);
   return load.getType().isa()
  ? load
  : rewriter.create(loc, load, 
rewriter.getIndexType());
 }
 
+/// Generates an invariant value.
+static Value genInvariantValue(Merger &merger, CodeGen &codegen,
+   PatternRewriter &rewriter, unsigned exp) {
+  return merger.exp(exp).val;
+}
+
 /// Recursively generates tensor expression.
 static Value genExp(Merger &merger, CodeGen &codegen, PatternRewriter 
&rewriter,

[llvm-branch-commits] [flang] [mlir] [mlir][Transforms] Support 1:N mappings in `ConversionValueMapping` (PR #116524)

2024-12-20 Thread Aart Bik via llvm-branch-commits

https://github.com/aartbik commented:

+1 on the simplification for the sparse 1:N conversion!

https://github.com/llvm/llvm-project/pull/116524
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits