Skip to content

[MLIR][SparseTensor] Enable strict property assembly format - #217292

Merged
aartbik merged 1 commit into
llvm:mainfrom
joker-eph:users/mamini/strict_prop_ods-SparseTensor
Aug 20, 2026
Merged

[MLIR][SparseTensor] Enable strict property assembly format#217292
aartbik merged 1 commit into
llvm:mainfrom
joker-eph:users/mamini/strict_prop_ods-SparseTensor

Conversation

@joker-eph

Copy link
Copy Markdown
Contributor

Enable strict property assembly format mode for the SparseTensor dialect. Spell level, dimension, sort, and iteration-order properties directly in declarative assembly formats while dropping unneeded property dictionaries from formats that already cover their inherent attributes.

Refresh SparseTensor dialect and integration tests so those properties use direct syntax while ordinary attributes remain in attr-dict.

Assisted-by: Codex

@llvmorg-github-actions

llvmorg-github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown

@llvm/pr-subscribers-mlir-gpu
@llvm/pr-subscribers-mlir

@llvm/pr-subscribers-mlir-sparse

Author: Mehdi Amini (joker-eph)

Changes

Enable strict property assembly format mode for the SparseTensor dialect. Spell level, dimension, sort, and iteration-order properties directly in declarative assembly formats while dropping unneeded property dictionaries from formats that already cover their inherent attributes.

Refresh SparseTensor dialect and integration tests so those properties use direct syntax while ordinary attributes remain in attr-dict.

Assisted-by: Codex


Patch is 273.91 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/217292.diff

55 Files Affected:

  • (modified) mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorBase.td (+1)
  • (modified) mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorOps.td (+15-10)
  • (modified) mlir/test/Dialect/SparseTensor/GPU/gpu_matmul_lib.mlir (+2-2)
  • (modified) mlir/test/Dialect/SparseTensor/GPU/gpu_matvec_lib.mlir (+2-2)
  • (modified) mlir/test/Dialect/SparseTensor/GPU/gpu_sampled_matmul_lib.mlir (+2-2)
  • (modified) mlir/test/Dialect/SparseTensor/GPU/gpu_sddmm_lib.mlir (+2-2)
  • (modified) mlir/test/Dialect/SparseTensor/GPU/gpu_spgemm_lib.mlir (+4-4)
  • (modified) mlir/test/Dialect/SparseTensor/buffer_rewriting.mlir (+4-4)
  • (modified) mlir/test/Dialect/SparseTensor/codegen.mlir (+3-3)
  • (modified) mlir/test/Dialect/SparseTensor/conversion.mlir (+6-6)
  • (modified) mlir/test/Dialect/SparseTensor/fold.mlir (+3-3)
  • (modified) mlir/test/Dialect/SparseTensor/fuse_sparse_pad_with_consumer.mlir (+2-2)
  • (modified) mlir/test/Dialect/SparseTensor/invalid.mlir (+18-18)
  • (modified) mlir/test/Dialect/SparseTensor/roundtrip.mlir (+10-10)
  • (modified) mlir/test/Dialect/SparseTensor/semi_ring.mlir (+1-1)
  • (modified) mlir/test/Dialect/SparseTensor/sorted_coo.mlir (+11-11)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_1d.mlir (+49-49)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_2d.mlir (+77-77)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_3d.mlir (+53-53)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_affine.mlir (+14-14)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_batch.mlir (+2-2)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_broadcast.mlir (+4-4)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_concat.mlir (+39-39)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_foreach.mlir (+10-10)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_fp_ops.mlir (+20-20)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_fusion.mlir (+2-2)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_index.mlir (+4-4)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_int_ops.mlir (+22-22)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_itertion_licm.mlir (+2-2)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_kernels.mlir (+28-28)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_kernels_to_iterator.mlir (+5-5)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_lower.mlir (+2-2)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_lower_col.mlir (+2-2)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_lower_inplace.mlir (+2-2)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_nd.mlir (+4-4)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_out.mlir (+26-26)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_outbuf.mlir (+6-6)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_parallel_reduce.mlir (+2-2)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_reshape.mlir (+12-12)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_scalars.mlir (+4-4)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_sddmm.mlir (+8-8)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_sddmm_org.mlir (+4-4)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_tensor_reshape.mlir (+4-4)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_transpose.mlir (+4-4)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_vector_chain.mlir (+4-4)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_vector_concat.mlir (+1-1)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_vector_index.mlir (+4-4)
  • (modified) mlir/test/Dialect/SparseTensor/spy_sddmm.mlir (+4-4)
  • (modified) mlir/test/Dialect/SparseTensor/spy_sddmm_bsr.mlir (+2-2)
  • (modified) mlir/test/Dialect/SparseTensor/vectorize_reduction.mlir (+14-14)
  • (modified) mlir/test/Integration/Dialect/SparseTensor/CPU/concatenate_dim_0.mlir (+4-4)
  • (modified) mlir/test/Integration/Dialect/SparseTensor/CPU/concatenate_dim_0_permute.mlir (+4-4)
  • (modified) mlir/test/Integration/Dialect/SparseTensor/CPU/concatenate_dim_1.mlir (+4-4)
  • (modified) mlir/test/Integration/Dialect/SparseTensor/CPU/concatenate_dim_1_permute.mlir (+4-4)
  • (modified) mlir/test/Integration/Dialect/SparseTensor/CPU/sparse_rewrite_sort_coo.mlir (+3-3)
diff --git a/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorBase.td b/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorBase.td
index 74e6783e260fa..e29358c6aa558 100644
--- a/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorBase.td
+++ b/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorBase.td
@@ -91,6 +91,7 @@ def SparseTensor_Dialect : Dialect {
   let useDefaultAttributePrinterParser = 1;
   let useDefaultTypePrinterParser = 1;
   let hasConstantMaterializer = 1;
+  let useStrictPropertiesInAssemblyFormat = 1;
 }
 
 #endif // SPARSETENSOR_BASE
diff --git a/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorOps.td b/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorOps.td
index d4901645c51d1..6f235c5dc74bb 100644
--- a/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorOps.td
+++ b/mlir/include/mlir/Dialect/SparseTensor/IR/SparseTensorOps.td
@@ -278,14 +278,15 @@ def SparseTensor_ToPositionsOp : SparseTensor_Op<"positions",
     Example:
 
     ```mlir
-    %1 = sparse_tensor.positions %0 { level = 1 : index }
+    %1 = sparse_tensor.positions %0 level = 1
        : tensor<64x64xf64, #CSR> to memref<?xindex>
     ```
   }];
 
   let arguments = (ins AnySparseTensor:$tensor, LevelAttr:$level);
   let results = (outs AnyNon0RankedMemRef:$result);
-  let assemblyFormat = "$tensor attr-dict `:` type($tensor) `to` type($result)";
+  let assemblyFormat =
+      "$tensor `level` `=` $level attr-dict `:` type($tensor) `to` type($result)";
 
   let hasVerifier = 1;
 }
@@ -307,14 +308,15 @@ def SparseTensor_ToCoordinatesOp : SparseTensor_Op<"coordinates",
     Example:
 
     ```mlir
-    %1 = sparse_tensor.coordinates %0 { level = 1 : index }
+    %1 = sparse_tensor.coordinates %0 level = 1
        : tensor<64x64xf64, #CSR> to memref<?xindex>
     ```
   }];
 
   let arguments = (ins AnySparseTensor:$tensor, LevelAttr:$level);
   let results = (outs AnyNon0RankedMemRef:$result);
-  let assemblyFormat = "$tensor attr-dict `:` type($tensor) `to` type($result)";
+  let assemblyFormat =
+      "$tensor `level` `=` $level attr-dict `:` type($tensor) `to` type($result)";
 
   let hasVerifier = 1;
 }
@@ -417,7 +419,7 @@ def SparseTensor_ConcatenateOp : SparseTensor_Op<"concatenate",
      Example:
 
      ```mlir
-     %0 = sparse_tensor.concatenate %1, %2 { dimension = 0 : index }
+     %0 = sparse_tensor.concatenate %1, %2 dimension = 0
        : tensor<64x64xf64, #CSR>, tensor<64x64xf64, #CSR> to tensor<128x64xf64, #CSR>
      ```
    }];
@@ -430,7 +432,8 @@ def SparseTensor_ConcatenateOp : SparseTensor_Op<"concatenate",
 
   let arguments = (ins Variadic<AnyRankedTensor>:$inputs, DimensionAttr:$dimension);
   let results = (outs AnyRankedTensor:$result);
-  let assemblyFormat = "$inputs attr-dict `:` type($inputs) `to` type($result)";
+  let assemblyFormat =
+      "$inputs `dimension` `=` $dimension attr-dict `:` type($inputs) `to` type($result)";
 
   let hasVerifier = 1;
 }
@@ -922,7 +925,7 @@ def SparseTensor_SortOp : SparseTensor_Op<"sort"> {
     Example:
 
     ```mlir
-    sparse_tensor.sort insertion_sort_stable %n, %x { perm_map = affine_map<(i,j) -> (j,i)> }
+    sparse_tensor.sort insertion_sort_stable %n, %x perm_map = affine_map<(i,j) -> (j,i)>
       : memref<?xindex>
     ```
   }];
@@ -933,7 +936,8 @@ def SparseTensor_SortOp : SparseTensor_Op<"sort"> {
                        AffineMapAttr:$perm_map, OptionalAttr<IndexAttr>:$ny,
                        SparseTensorSortKindAttr:$algorithm);
   let assemblyFormat = "$algorithm $n"
-                       "`,`$xy (`jointly` $ys^)? attr-dict"
+                       "`,`$xy (`jointly` $ys^)? `perm_map` `=` $perm_map"
+                       " (`ny` `=` $ny^)? attr-dict"
                        "`:` type($xy) (`jointly` type($ys)^)?";
   let hasVerifier = 1;
 }
@@ -1418,7 +1422,7 @@ def SparseTensor_ForeachOp : SparseTensor_Op<"foreach",
      }
 
      // foreach on a row-major dense tensor but visit column first
-     sparse_tensor.foreach in %0 {order=affine_map<(i,j)->(j,i)>}: tensor<2x3xf64> do {
+     sparse_tensor.foreach in %0 order = affine_map<(i,j)->(j,i)> : tensor<2x3xf64> do {
       ^bb0(%row: index, %col: index, %arg3: f64):
          // [%row, %col] -> [0, 0], [1, 0], [2, 0], [0, 1], [1, 1], [2, 1]
      }
@@ -1451,7 +1455,8 @@ def SparseTensor_ForeachOp : SparseTensor_Op<"foreach",
                        Variadic<AnyType>:$initArgs,
                        OptionalAttr<AffineMapAttr>:$order);
   let results = (outs Variadic<AnyType>:$results);
-  let assemblyFormat = "`in` $tensor (`init``(`$initArgs^`)`)? attr-dict"
+  let assemblyFormat = "`in` $tensor (`init``(`$initArgs^`)`)?"
+                       " (`order` `=` $order^)? attr-dict"
                        "    `:` type($tensor) (`,` type($initArgs)^)?"
                        "  (`->` type($results)^)?  `do` $region";
   let hasVerifier = 1;
diff --git a/mlir/test/Dialect/SparseTensor/GPU/gpu_matmul_lib.mlir b/mlir/test/Dialect/SparseTensor/GPU/gpu_matmul_lib.mlir
index 01906f4c45171..7437297ce708e 100644
--- a/mlir/test/Dialect/SparseTensor/GPU/gpu_matmul_lib.mlir
+++ b/mlir/test/Dialect/SparseTensor/GPU/gpu_matmul_lib.mlir
@@ -15,8 +15,8 @@
 // CHECK-DAG:       %[[VAL_6:.*]] = tensor.dim %[[VAL_0]], %[[VAL_3]] : tensor<?x?xf64, #sparse{{[0-9]*}}>
 // CHECK-DAG:       %[[VAL_7:.*]] = tensor.dim %[[VAL_0]], %[[VAL_4]] : tensor<?x?xf64, #sparse{{[0-9]*}}>
 // CHECK-DAG:       %[[VAL_8:.*]] = tensor.dim %[[VAL_1]], %[[VAL_4]] : tensor<?x?xf64>
-// CHECK-DAG:       %[[VAL_9:.*]] = sparse_tensor.positions %[[VAL_0]] {level = 1 : index} : tensor<?x?xf64, #sparse{{[0-9]*}}> to memref<?xindex>
-// CHECK-DAG:       %[[VAL_10:.*]] = sparse_tensor.coordinates %[[VAL_0]] {level = 1 : index} : tensor<?x?xf64, #sparse{{[0-9]*}}> to memref<?xindex>
+// CHECK-DAG:       %[[VAL_9:.*]] = sparse_tensor.positions %[[VAL_0]] level = 1 : tensor<?x?xf64, #sparse{{[0-9]*}}> to memref<?xindex>
+// CHECK-DAG:       %[[VAL_10:.*]] = sparse_tensor.coordinates %[[VAL_0]] level = 1 : tensor<?x?xf64, #sparse{{[0-9]*}}> to memref<?xindex>
 // CHECK-DAG:       %[[VAL_11:.*]] = sparse_tensor.values %[[VAL_0]] : tensor<?x?xf64, #sparse{{[0-9]*}}> to memref<?xf64>
 // CHECK:           %[[VAL_12:.*]] = gpu.wait async
 // CHECK:           %[[VAL_13:.*]] = memref.dim %[[VAL_9]], %[[VAL_3]] : memref<?xindex>
diff --git a/mlir/test/Dialect/SparseTensor/GPU/gpu_matvec_lib.mlir b/mlir/test/Dialect/SparseTensor/GPU/gpu_matvec_lib.mlir
index dea71fa03c777..d110d91943067 100644
--- a/mlir/test/Dialect/SparseTensor/GPU/gpu_matvec_lib.mlir
+++ b/mlir/test/Dialect/SparseTensor/GPU/gpu_matvec_lib.mlir
@@ -15,8 +15,8 @@ module {
 // CHECK-DAG:       %[[VAL_5:.*]] = sparse_tensor.number_of_entries %[[VAL_0]] : tensor<?x?xf64, #sparse{{[0-9]*}}>
 // CHECK-DAG:       %[[VAL_6:.*]] = tensor.dim %[[VAL_0]], %[[VAL_3]] : tensor<?x?xf64, #sparse{{[0-9]*}}>
 // CHECK-DAG:       %[[VAL_7:.*]] = tensor.dim %[[VAL_0]], %[[VAL_4]] : tensor<?x?xf64, #sparse{{[0-9]*}}>
-// CHECK-DAG:       %[[VAL_8:.*]] = sparse_tensor.coordinates %[[VAL_0]] {level = 0 : index} : tensor<?x?xf64, #sparse{{[0-9]*}}> to memref<?xindex, strided<[?], offset: ?>>
-// CHECK-DAG:       %[[VAL_9:.*]] = sparse_tensor.coordinates %[[VAL_0]] {level = 1 : index} : tensor<?x?xf64, #sparse{{[0-9]*}}> to memref<?xindex, strided<[?], offset: ?>>
+// CHECK-DAG:       %[[VAL_8:.*]] = sparse_tensor.coordinates %[[VAL_0]] level = 0 : tensor<?x?xf64, #sparse{{[0-9]*}}> to memref<?xindex, strided<[?], offset: ?>>
+// CHECK-DAG:       %[[VAL_9:.*]] = sparse_tensor.coordinates %[[VAL_0]] level = 1 : tensor<?x?xf64, #sparse{{[0-9]*}}> to memref<?xindex, strided<[?], offset: ?>>
 // CHECK-DAG:       %[[VAL_10:.*]] = sparse_tensor.values %[[VAL_0]] : tensor<?x?xf64, #sparse{{[0-9]*}}> to memref<?xf64>
 // CHECK:           %[[VAL_11:.*]] = gpu.wait async
 // CHECK:           %[[VAL_12:.*]] = memref.dim %[[VAL_8]], %[[VAL_3]] : memref<?xindex, strided<[?], offset: ?>>
diff --git a/mlir/test/Dialect/SparseTensor/GPU/gpu_sampled_matmul_lib.mlir b/mlir/test/Dialect/SparseTensor/GPU/gpu_sampled_matmul_lib.mlir
index 6675df2be0c53..89fe46c0e7a72 100644
--- a/mlir/test/Dialect/SparseTensor/GPU/gpu_sampled_matmul_lib.mlir
+++ b/mlir/test/Dialect/SparseTensor/GPU/gpu_sampled_matmul_lib.mlir
@@ -36,8 +36,8 @@
 // CHECK:           %[[VAL_12:.*]] = gpu.wait async
 // CHECK:           %[[VAL_13:.*]], %[[VAL_14:.*]] = gpu.alloc async {{\[}}%[[VAL_12]]] () : memref<8x8xf64>
 // CHECK:           %[[VAL_15:.*]] = gpu.memcpy async {{\[}}%[[VAL_14]]] %[[VAL_13]], %[[VAL_11]] : memref<8x8xf64>, memref<8x8xf64>
-// CHECK:           %[[VAL_16:.*]] = sparse_tensor.positions %[[VAL_0]] {level = 1 : index} : tensor<8x8xf64, #sparse{{[0-9]*}}> to memref<?xindex>
-// CHECK:           %[[VAL_17:.*]] = sparse_tensor.coordinates %[[VAL_0]] {level = 1 : index} : tensor<8x8xf64, #sparse{{[0-9]*}}> to memref<?xindex>
+// CHECK:           %[[VAL_16:.*]] = sparse_tensor.positions %[[VAL_0]] level = 1 : tensor<8x8xf64, #sparse{{[0-9]*}}> to memref<?xindex>
+// CHECK:           %[[VAL_17:.*]] = sparse_tensor.coordinates %[[VAL_0]] level = 1 : tensor<8x8xf64, #sparse{{[0-9]*}}> to memref<?xindex>
 // CHECK:           %[[VAL_18:.*]] = sparse_tensor.values %[[VAL_0]] : tensor<8x8xf64, #sparse{{[0-9]*}}> to memref<?xf64>
 // CHECK:           %[[VAL_19:.*]] = gpu.wait async
 // CHECK:           %[[VAL_20:.*]] = memref.dim %[[VAL_16]], %[[VAL_4]] : memref<?xindex>
diff --git a/mlir/test/Dialect/SparseTensor/GPU/gpu_sddmm_lib.mlir b/mlir/test/Dialect/SparseTensor/GPU/gpu_sddmm_lib.mlir
index 7b7657a0e9ba5..df3ed0f4dc74c 100644
--- a/mlir/test/Dialect/SparseTensor/GPU/gpu_sddmm_lib.mlir
+++ b/mlir/test/Dialect/SparseTensor/GPU/gpu_sddmm_lib.mlir
@@ -42,8 +42,8 @@
 // CHECK:           %[[VAL_21:.*]] = memref.dim %[[VAL_18]], %[[VAL_4]] : memref<?x?xf32>
 // CHECK:           %[[VAL_22:.*]], %[[VAL_23:.*]] = gpu.alloc async {{\[}}%[[VAL_19]]] (%[[VAL_20]], %[[VAL_21]]) : memref<?x?xf32>
 // CHECK:           %[[VAL_24:.*]] = gpu.memcpy async {{\[}}%[[VAL_23]]] %[[VAL_22]], %[[VAL_18]] : memref<?x?xf32>, memref<?x?xf32>
-// CHECK:           %[[VAL_25:.*]] = sparse_tensor.positions %[[VAL_0]] {level = 1 : index}
-// CHECK:           %[[VAL_26:.*]] = sparse_tensor.coordinates %[[VAL_0]] {level = 1 : index}
+// CHECK:           %[[VAL_25:.*]] = sparse_tensor.positions %[[VAL_0]] level = 1
+// CHECK:           %[[VAL_26:.*]] = sparse_tensor.coordinates %[[VAL_0]] level = 1
 // CHECK:           %[[VAL_27:.*]] = sparse_tensor.values %[[VAL_0]]
 // CHECK:           %[[VAL_28:.*]] = gpu.wait async
 // CHECK:           %[[VAL_29:.*]] = memref.dim %[[VAL_25]], %[[VAL_3]] : memref<?xindex>
diff --git a/mlir/test/Dialect/SparseTensor/GPU/gpu_spgemm_lib.mlir b/mlir/test/Dialect/SparseTensor/GPU/gpu_spgemm_lib.mlir
index 9688e886f69ca..6e7f7e0453db4 100644
--- a/mlir/test/Dialect/SparseTensor/GPU/gpu_spgemm_lib.mlir
+++ b/mlir/test/Dialect/SparseTensor/GPU/gpu_spgemm_lib.mlir
@@ -10,11 +10,11 @@
 // CHECK-DAG:       %[[VAL_4:.*]] = arith.constant 9 : index
 // CHECK:           %[[VAL_6:.*]] = sparse_tensor.number_of_entries %[[VAL_0]] : tensor<8x8xf32, #{{.*}}>
 // CHECK:           %[[VAL_7:.*]] = sparse_tensor.number_of_entries %[[VAL_1]] : tensor<8x8xf32, #{{.*}}>
-// CHECK:           %[[VAL_8:.*]] = sparse_tensor.positions %[[VAL_0]] {level = 1 : index} : tensor<8x8xf32, #{{.*}}>
-// CHECK:           %[[VAL_9:.*]] = sparse_tensor.coordinates %[[VAL_0]] {level = 1 : index} : tensor<8x8xf32, #{{.*}}>
+// CHECK:           %[[VAL_8:.*]] = sparse_tensor.positions %[[VAL_0]] level = 1 : tensor<8x8xf32, #{{.*}}>
+// CHECK:           %[[VAL_9:.*]] = sparse_tensor.coordinates %[[VAL_0]] level = 1 : tensor<8x8xf32, #{{.*}}>
 // CHECK:           %[[VAL_10:.*]] = sparse_tensor.values %[[VAL_0]] : tensor<8x8xf32, #{{.*}}>
-// CHECK:           %[[VAL_11:.*]] = sparse_tensor.positions %[[VAL_1]] {level = 1 : index} : tensor<8x8xf32, #{{.*}}>
-// CHECK:           %[[VAL_12:.*]] = sparse_tensor.coordinates %[[VAL_1]] {level = 1 : index} : tensor<8x8xf32, #{{.*}}>
+// CHECK:           %[[VAL_11:.*]] = sparse_tensor.positions %[[VAL_1]] level = 1 : tensor<8x8xf32, #{{.*}}>
+// CHECK:           %[[VAL_12:.*]] = sparse_tensor.coordinates %[[VAL_1]] level = 1 : tensor<8x8xf32, #{{.*}}>
 // CHECK:           %[[VAL_13:.*]] = sparse_tensor.values %[[VAL_1]] : tensor<8x8xf32, #{{.*}}>
 // CHECK:           %[[VAL_14:.*]] = gpu.wait async
 // CHECK:           %[[VAL_15:.*]] = memref.dim %[[VAL_8]], %[[VAL_3]] : memref<?xindex>
diff --git a/mlir/test/Dialect/SparseTensor/buffer_rewriting.mlir b/mlir/test/Dialect/SparseTensor/buffer_rewriting.mlir
index cafb431b75306..ef585b5a9141f 100644
--- a/mlir/test/Dialect/SparseTensor/buffer_rewriting.mlir
+++ b/mlir/test/Dialect/SparseTensor/buffer_rewriting.mlir
@@ -84,7 +84,7 @@ func.func @sparse_push_back_inbound(%arg0: index, %arg1: memref<?xf64>, %arg2: f
 // CHECK-DAG:     func.func private @_sparse_qsort_0_1_index_coo_1_f32_i32(%arg0: index, %arg1: index, %arg2: memref<?xindex>, %arg3: memref<?xf32>, %arg4: memref<?xi32>) {
 // CHECK-LABEL:   func.func @sparse_sort_coo_quick
 func.func @sparse_sort_coo_quick(%arg0: index, %arg1: memref<100xindex>, %arg2: memref<?xf32>, %arg3: memref<10xi32>) -> (memref<100xindex>, memref<?xf32>, memref<10xi32>) {
-  sparse_tensor.sort quick_sort %arg0, %arg1 jointly %arg2, %arg3 {perm_map = #ID_MAP, ny = 1: index} : memref<100xindex> jointly memref<?xf32>, memref<10xi32>
+  sparse_tensor.sort quick_sort %arg0, %arg1 jointly %arg2, %arg3 perm_map = #ID_MAP ny = 1 : memref<100xindex> jointly memref<?xf32>, memref<10xi32>
   return %arg1, %arg2, %arg3 : memref<100xindex>, memref<?xf32>, memref<10xi32>
 }
 
@@ -103,7 +103,7 @@ func.func @sparse_sort_coo_quick(%arg0: index, %arg1: memref<100xindex>, %arg2:
 // CHECK-DAG:     func.func private @_sparse_hybrid_qsort_0_1_index_coo_1_f32_i32(%arg0: index, %arg1: index, %arg2: memref<?xindex>, %arg3: memref<?xf32>, %arg4: memref<?xi32>, %arg5: i64) {
 // CHECK-LABEL:   func.func @sparse_sort_coo_hybrid
 func.func @sparse_sort_coo_hybrid(%arg0: index, %arg1: memref<100xindex>, %arg2: memref<?xf32>, %arg3: memref<10xi32>) -> (memref<100xindex>, memref<?xf32>, memref<10xi32>) {
-  sparse_tensor.sort hybrid_quick_sort %arg0, %arg1 jointly %arg2, %arg3 {perm_map = #ID_MAP, ny = 1: index} : memref<100xindex> jointly memref<?xf32>, memref<10xi32>
+  sparse_tensor.sort hybrid_quick_sort %arg0, %arg1 jointly %arg2, %arg3 perm_map = #ID_MAP ny = 1 : memref<100xindex> jointly memref<?xf32>, memref<10xi32>
   return %arg1, %arg2, %arg3 : memref<100xindex>, memref<?xf32>, memref<10xi32>
 }
 
@@ -118,7 +118,7 @@ func.func @sparse_sort_coo_hybrid(%arg0: index, %arg1: memref<100xindex>, %arg2:
 // CHECK-DAG:     func.func private @_sparse_sort_stable_0_1_index_coo_1_f32_i32(%arg0: index, %arg1: index, %arg2: memref<?xindex>, %arg3: memref<?xf32>, %arg4: memref<?xi32>) {
 // CHECK-LABEL:   func.func @sparse_sort_coo_stable
 func.func @sparse_sort_coo_stable(%arg0: index, %arg1: memref<100xindex>, %arg2: memref<?xf32>, %arg3: memref<10xi32>) -> (memref<100xindex>, memref<?xf32>, memref<10xi32>) {
-  sparse_tensor.sort insertion_sort_stable %arg0, %arg1 jointly %arg2, %arg3 {perm_map = #ID_MAP, ny = 1: index} : memref<100xindex> jointly memref<?xf32>, memref<10xi32>
+  sparse_tensor.sort insertion_sort_stable %arg0, %arg1 jointly %arg2, %arg3 perm_map = #ID_MAP ny = 1 : memref<100xindex> jointly memref<?xf32>, memref<10xi32>
   return %arg1, %arg2, %arg3 : memref<100xindex>, memref<?xf32>, memref<10xi32>
 }
 
@@ -133,6 +133,6 @@ func.func @sparse_sort_coo_stable(%arg0: index, %arg1: memref<100xindex>, %arg2:
 // CHECK-DAG:     func.func private @_sparse_heap_sort_0_1_index_coo_1_f32_i32(%arg0: index, %arg1: index, %arg2: memref<?xindex>, %arg3: memref<?xf32>, %arg4: memref<?xi32>) {
 // CHECK-LABEL:   func.func @sparse_sort_coo_heap
 func.func @sparse_sort_coo_heap(%arg0: index, %arg1: memref<100xindex>, %arg2: memref<?xf32>, %arg3: memref<10xi32>) -> (memref<100xindex>, memref<?xf32>, memref<10xi32>) {
-  sparse_tensor.sort heap_sort %arg0, %arg1 jointly %arg2, %arg3 {perm_map = #ID_MAP, ny = 1: index} : memref<100xindex> jointly memref<?xf32>, memref<10xi32>
+  sparse_tensor.sort heap_sort %arg0, %arg1 jointly %arg2, %arg3 perm_map = #ID_MAP ny = 1 : memref<100xindex> jointly memref<?xf32>, memref<10xi32>
   return %arg1, %arg2, %arg3 : memref<100xindex>, memref<?xf32>, memref<10xi32>
 }
diff --git a/mlir/test/Dialect/SparseTensor/codegen.mlir b/mlir/test/Dialect/SparseTensor/codegen.mlir
index af78458f10932..34cf0f042a303 100644
--- a/mlir/test/Dialect/SparseTensor/codegen.mlir
+++ b/mlir/test/Dialect/SparseTensor/codegen.mlir
@@ -270,7 +270,7 @@ func.func @sparse_dense_3d_dyn(%arg0: tensor<?x?x?xf64, #Dense3D>) -> index {
 //       CHECK: %[[V:.*]] = memref.subview %[[A2]][0] [%[[S]]] [1]
 //       CHECK: return %[[V]] : memref<?xi32>
 func.func @sparse_positions_dcsr(%arg0: tensor<?x?xf64, #DCSR>) -> memref<?xi32> {
-  %0 = sparse_tensor.positions %arg0 { level = 1 : index } : tensor<?x?xf64, #DCSR> to memref<?xi32>
+  %0 = sparse_tensor.positions %arg0 level = 1 : tensor<?x?xf64, #DCSR> to memref<?xi32>
   return %0 : memref<?xi32>
 }
 
@@ -285,7 +285,7 @@ func.func @sparse_positions_dcsr(%arg0: tensor<?x?xf64, #DCSR>) -> memref<?xi32>
 //       CHECK: %[[V:.*]] = memref.subview %[[A3]][0] [%[[S]]] [1]
 //       CHECK: return %[[V]] : memref<?xi64>
 func.func @sparse_indices_dcsr(%arg0: tensor<?x?xf64, #DCSR>) -> memref<?xi64> {
-  %0 = sparse_tensor.coordinates %arg0 { level = 1 : index } : tensor<?x?xf64, #DCSR> to memref<?xi64>
+  %0 = sparse_tensor.coordinates %arg0 level = 1 : tensor<?x?xf64, #DCSR> to memref<?xi64>
   return %0 : memref<?xi64>
 }
 
@@ -333,7 +333,7 @@ func.func @sparse_values_coo(%arg0: tensor<?x?x?xf64, #ccoo>) -> memref<?xf64> {
 //       CHECK: %[[R2:.*]] = memref.cast %[[R1]] : memref<?xindex, strided<[2]>> to memref<?xindex, strided<[?], offset: ?>>
 //       CHECK: return %[[R2]] : memref<?xindex, strided<[?], offset: ?>>
 func.func @sparse_indices_coo(%arg0: tensor<?x?x?xf64, #ccoo>) -> memref<?xindex, strided<[?], offset: ?>> {
-  %0 = sparse_tensor.coordinates  %arg0 { level = 1 : index } : tensor<?x?x?xf64, #ccoo> to memref<?xindex, strided<[?], offset: ?>>
+  %0 = sparse_tensor.coordinates  %arg0 level = 1 : tensor<?x?x?xf64, #ccoo> to memref<?xindex, strided<[?], offset: ?>>
   return %0 : memref<?xindex, strided<[?], offset: ?>>
 }
 
diff --git a/mlir/test/Dialect/SparseTensor/conversion.mlir b/mlir/test/Dialect/SparseTensor/conversion.mlir
index ff0fb22431d69..17a0932ccebb6 100644
--- a/mlir/test/Dialect/SparseTensor/conversion.mlir
+++ b/mlir/test/Dialect/SparseTensor/conversion.mlir
@@ -176,7 +176,7 @@ func.func @sparse_nop_cast(%arg0: tensor<64xf32, #SparseVector>) -> tensor<?xf32
 //       CHECK: %[[T:.*]] = call @sparsePositions0(%[[A]], %[[C]]) : (!llvm.ptr, index) -> memref<?xindex>
 //       CHECK: return %[[T]] : memref<?xindex>
 func.func @sparse_positions(%arg0: tensor<128xf64, #SparseVector>) -> memref<?xindex> {
-  %0 = sparse_tensor.positions %arg0 { level = 0 : index } : tensor<128xf64, #SparseVector> to memref<?xindex>
+  %0 = sparse_tensor.positions %arg0 level = 0 : tensor<128xf64, #SparseVector> to memref<?xindex>
   return %0 : memref<?xindex>
 }
 
@@ -186,7 +186,7 @@ func.func @sparse_positions(%arg0: tensor<128xf64, #SparseVector>) -> memref<?xi
 //       CHECK: %[[T:.*]] = call @sparsePositions64(%[[A]], %[[C]]) : (!llvm.ptr, index) -> memref<?xi64>
 //       CHECK: return %[[T]] : memref<?xi64>
 func.func @sparse_positions64(%arg0: tensor<128xf64, #SparseVector64>) -> memref<?xi64> {
-  %0 = sparse_tensor.positions %arg0 { level = 0 : index } : tensor<128xf64, #SparseVector64> to memref<?xi64>
+  %0 = sparse_tensor.positions %arg0 level = 0 : tensor<128xf64, #SparseVector64> to memref<?xi64>
   return %0 : memref<?xi64>
 }
 
@@ -196,7 +196,7 @@ func.func @sparse_positions64(%arg0: tensor<128xf64, #SparseVector64>) -> memref
 //       CHECK: %[[T:.*]] = call @sparsePositions32(%[[A]], %[[C]]) : (!llvm.ptr, index) -> memref<?xi32>
 //       CHECK: return %[[T]] : memref<?xi32>
 func.func @sparse_positions32(%arg0: tensor<128xf64, #SparseVector32>) -> memref<?xi32> {
-  %0 = sparse_tensor.positions %arg0 { level = 0 : index } : tensor<128xf64, #SparseVector32> to memref<?xi32>
+  %0 = sparse_tensor.positions %arg0 level = 0 : tensor<128xf64, #SparseVector3...
[truncated]

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown

🪟 Windows x64 Test Results

  • 4049 tests passed
  • 446 tests skipped

✅ The build succeeded and all tests passed.

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown

🐧 Linux x64 Test Results

  • 8779 tests passed
  • 646 tests skipped

✅ The build succeeded and all tests passed.

Enable strict property assembly format mode for the SparseTensor dialect. Spell
level, dimension, sort, and iteration-order properties directly in declarative
assembly formats while dropping unneeded property dictionaries from formats that
already cover their inherent attributes.

Refresh SparseTensor dialect and integration tests so those properties use
direct syntax while ordinary attributes remain in attr-dict.

Assisted-by: Codex
@joker-eph
joker-eph force-pushed the users/mamini/strict_prop_ods-SparseTensor branch from 13064e6 to 7c448c2 Compare August 19, 2026 11:58

@aartbik aartbik left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for my understanding, it this part of a general move towards strict property assembly format in all dialects, or did this come from another requirement?

@joker-eph

Copy link
Copy Markdown
Contributor Author

Yes this is a migration to strict property assembly as the new default, and deprecation for support of the non-strict mode.

@aartbik
aartbik merged commit b35f809 into llvm:main Aug 20, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants