1# RUN: %PYTHON %s pybind11 | FileCheck %s 2# RUN: %PYTHON %s nanobind | FileCheck %s 3 4import sys 5from mlir.ir import * 6import mlir.dialects.func as func 7import mlir.dialects.python_test as test 8import mlir.dialects.tensor as tensor 9import mlir.dialects.arith as arith 10 11if sys.argv[1] == "pybind11": 12 from mlir._mlir_libs._mlirPythonTestPybind11 import ( 13 TestAttr, 14 TestType, 15 TestTensorValue, 16 TestIntegerRankedTensorType, 17 ) 18 19 test.register_python_test_dialect(get_dialect_registry(), use_nanobind=False) 20elif sys.argv[1] == "nanobind": 21 from mlir._mlir_libs._mlirPythonTestNanobind import ( 22 TestAttr, 23 TestType, 24 TestTensorValue, 25 TestIntegerRankedTensorType, 26 ) 27 28 test.register_python_test_dialect(get_dialect_registry(), use_nanobind=True) 29else: 30 raise ValueError("Expected pybind11 or nanobind as argument") 31 32 33def run(f): 34 print("\nTEST:", f.__name__) 35 f() 36 return f 37 38 39# CHECK-LABEL: TEST: testAttributes 40@run 41def testAttributes(): 42 with Context() as ctx, Location.unknown(): 43 # 44 # Check op construction with attributes. 45 # 46 47 i32 = IntegerType.get_signless(32) 48 one = IntegerAttr.get(i32, 1) 49 two = IntegerAttr.get(i32, 2) 50 unit = UnitAttr.get() 51 52 # CHECK: python_test.attributed_op { 53 # CHECK-DAG: mandatory_i32 = 1 : i32 54 # CHECK-DAG: optional_i32 = 2 : i32 55 # CHECK-DAG: unit 56 # CHECK: } 57 op = test.AttributedOp(one, optional_i32=two, unit=unit) 58 print(f"{op}") 59 60 # CHECK: python_test.attributed_op { 61 # CHECK: mandatory_i32 = 2 : i32 62 # CHECK: } 63 op2 = test.AttributedOp(two) 64 print(f"{op2}") 65 66 # 67 # Check generic "attributes" access and mutation. 68 # 69 70 assert "additional" not in op.attributes 71 72 # CHECK: python_test.attributed_op { 73 # CHECK-DAG: additional = 1 : i32 74 # CHECK-DAG: mandatory_i32 = 2 : i32 75 # CHECK: } 76 op2.attributes["additional"] = one 77 print(f"{op2}") 78 79 # CHECK: python_test.attributed_op { 80 # CHECK-DAG: additional = 2 : i32 81 # CHECK-DAG: mandatory_i32 = 2 : i32 82 # CHECK: } 83 op2.attributes["additional"] = two 84 print(f"{op2}") 85 86 # CHECK: python_test.attributed_op { 87 # CHECK-NOT: additional = 2 : i32 88 # CHECK: mandatory_i32 = 2 : i32 89 # CHECK: } 90 del op2.attributes["additional"] 91 print(f"{op2}") 92 93 try: 94 print(op.attributes["additional"]) 95 except KeyError: 96 pass 97 else: 98 assert False, "expected KeyError on unknown attribute key" 99 100 # 101 # Check accessors to defined attributes. 102 # 103 104 # CHECK: Mandatory: 1 105 # CHECK: Optional: 2 106 # CHECK: Unit: True 107 print(f"Mandatory: {op.mandatory_i32.value}") 108 print(f"Optional: {op.optional_i32.value}") 109 print(f"Unit: {op.unit}") 110 111 # CHECK: Mandatory: 2 112 # CHECK: Optional: None 113 # CHECK: Unit: False 114 print(f"Mandatory: {op2.mandatory_i32.value}") 115 print(f"Optional: {op2.optional_i32}") 116 print(f"Unit: {op2.unit}") 117 118 # CHECK: Mandatory: 2 119 # CHECK: Optional: None 120 # CHECK: Unit: False 121 op.mandatory_i32 = two 122 op.optional_i32 = None 123 op.unit = False 124 print(f"Mandatory: {op.mandatory_i32.value}") 125 print(f"Optional: {op.optional_i32}") 126 print(f"Unit: {op.unit}") 127 assert "optional_i32" not in op.attributes 128 assert "unit" not in op.attributes 129 130 try: 131 op.mandatory_i32 = None 132 except ValueError: 133 pass 134 else: 135 assert False, "expected ValueError on setting a mandatory attribute to None" 136 137 # CHECK: Optional: 2 138 op.optional_i32 = two 139 print(f"Optional: {op.optional_i32.value}") 140 141 # CHECK: Optional: None 142 del op.optional_i32 143 print(f"Optional: {op.optional_i32}") 144 145 # CHECK: Unit: False 146 op.unit = None 147 print(f"Unit: {op.unit}") 148 assert "unit" not in op.attributes 149 150 # CHECK: Unit: True 151 op.unit = True 152 print(f"Unit: {op.unit}") 153 154 # CHECK: Unit: False 155 del op.unit 156 print(f"Unit: {op.unit}") 157 158 159# CHECK-LABEL: TEST: attrBuilder 160@run 161def attrBuilder(): 162 with Context() as ctx, Location.unknown(): 163 # CHECK: python_test.attributes_op 164 op = test.AttributesOp( 165 # CHECK-DAG: x_affinemap = affine_map<() -> (2)> 166 x_affinemap=AffineMap.get_constant(2), 167 # CHECK-DAG: x_affinemaparr = [affine_map<(d0, d1, d2) -> (d0, d1, d2)>] 168 x_affinemaparr=[AffineMap.get_identity(3)], 169 # CHECK-DAG: x_arr = [true, "x"] 170 x_arr=[BoolAttr.get(True), StringAttr.get("x")], 171 x_boolarr=[False, True], # CHECK-DAG: x_boolarr = [false, true] 172 x_bool=True, # CHECK-DAG: x_bool = true 173 x_dboolarr=[True, False], # CHECK-DAG: x_dboolarr = array<i1: true, false> 174 x_df16arr=[21, 22], # CHECK-DAG: x_df16arr = array<i16: 21, 22> 175 # CHECK-DAG: x_df32arr = array<f32: 2.300000e+01, 2.400000e+01> 176 x_df32arr=[23, 24], 177 # CHECK-DAG: x_df64arr = array<f64: 2.500000e+01, 2.600000e+01> 178 x_df64arr=[25, 26], 179 x_di32arr=[0, 1], # CHECK-DAG: x_di32arr = array<i32: 0, 1> 180 # CHECK-DAG: x_di64arr = array<i64: 1, 2> 181 x_di64arr=[1, 2], 182 x_di8arr=[2, 3], # CHECK-DAG: x_di8arr = array<i8: 2, 3> 183 # CHECK-DAG: x_dictarr = [{a = false}] 184 x_dictarr=[{"a": BoolAttr.get(False)}], 185 x_dict={"b": BoolAttr.get(True)}, # CHECK-DAG: x_dict = {b = true} 186 x_f32=-2.25, # CHECK-DAG: x_f32 = -2.250000e+00 : f32 187 # CHECK-DAG: x_f32arr = [2.000000e+00 : f32, 3.000000e+00 : f32] 188 x_f32arr=[2.0, 3.0], 189 x_f64=4.25, # CHECK-DAG: x_f64 = 4.250000e+00 : f64 190 x_f64arr=[4.0, 8.0], # CHECK-DAG: x_f64arr = [4.000000e+00, 8.000000e+00] 191 # CHECK-DAG: x_f64elems = dense<[8.000000e+00, 1.600000e+01]> : tensor<2xf64> 192 x_f64elems=[8.0, 16.0], 193 # CHECK-DAG: x_flatsymrefarr = [@symbol1, @symbol2] 194 x_flatsymrefarr=["symbol1", "symbol2"], 195 x_flatsymref="symbol3", # CHECK-DAG: x_flatsymref = @symbol3 196 x_i1=0, # CHECK-DAG: x_i1 = false 197 x_i16=42, # CHECK-DAG: x_i16 = 42 : i16 198 x_i32=6, # CHECK-DAG: x_i32 = 6 : i32 199 x_i32arr=[4, 5], # CHECK-DAG: x_i32arr = [4 : i32, 5 : i32] 200 x_i32elems=[5, 6], # CHECK-DAG: x_i32elems = dense<[5, 6]> : tensor<2xi32> 201 x_i64=9, # CHECK-DAG: x_i64 = 9 : i64 202 x_i64arr=[7, 8], # CHECK-DAG: x_i64arr = [7, 8] 203 x_i64elems=[8, 9], # CHECK-DAG: x_i64elems = dense<[8, 9]> : tensor<2xi64> 204 x_i64svecarr=[10, 11], # CHECK-DAG: x_i64svecarr = [10, 11] 205 x_i8=11, # CHECK-DAG: x_i8 = 11 : i8 206 x_idx=10, # CHECK-DAG: x_idx = 10 : index 207 # CHECK-DAG: x_idxelems = dense<[11, 12]> : tensor<2xindex> 208 x_idxelems=[11, 12], 209 # CHECK-DAG: x_idxlistarr = [{{\[}}13], [14, 15]] 210 x_idxlistarr=[[13], [14, 15]], 211 x_si1=-1, # CHECK-DAG: x_si1 = -1 : si1 212 x_si16=-2, # CHECK-DAG: x_si16 = -2 : si16 213 x_si32=-3, # CHECK-DAG: x_si32 = -3 : si32 214 x_si64=-123, # CHECK-DAG: x_si64 = -123 : si64 215 x_si8=-4, # CHECK-DAG: x_si8 = -4 : si8 216 x_strarr=["hello", "world"], # CHECK-DAG: x_strarr = ["hello", "world"] 217 x_str="hello world!", # CHECK-DAG: x_str = "hello world!" 218 # CHECK-DAG: x_symrefarr = [@flatsym, @deep::@sym] 219 x_symrefarr=["flatsym", ["deep", "sym"]], 220 x_symref=["deep", "sym2"], # CHECK-DAG: x_symref = @deep::@sym2 221 x_sym="symbol", # CHECK-DAG: x_sym = "symbol" 222 x_typearr=[F32Type.get()], # CHECK-DAG: x_typearr = [f32] 223 x_type=F64Type.get(), # CHECK-DAG: x_type = f64 224 x_ui1=1, # CHECK-DAG: x_ui1 = 1 : ui1 225 x_ui16=2, # CHECK-DAG: x_ui16 = 2 : ui16 226 x_ui32=3, # CHECK-DAG: x_ui32 = 3 : ui32 227 x_ui64=4, # CHECK-DAG: x_ui64 = 4 : ui64 228 x_ui8=5, # CHECK-DAG: x_ui8 = 5 : ui8 229 x_unit=True, # CHECK-DAG: x_unit 230 ) 231 op.verify() 232 op.print(use_local_scope=True) 233 234 235# CHECK-LABEL: TEST: inferReturnTypes 236@run 237def inferReturnTypes(): 238 with Context() as ctx, Location.unknown(ctx): 239 module = Module.create() 240 with InsertionPoint(module.body): 241 op = test.InferResultsOp() 242 dummy = test.DummyOp() 243 244 # CHECK: [Type(i32), Type(i64)] 245 iface = InferTypeOpInterface(op) 246 print(iface.inferReturnTypes()) 247 248 # CHECK: [Type(i32), Type(i64)] 249 iface_static = InferTypeOpInterface(test.InferResultsOp) 250 print(iface.inferReturnTypes()) 251 252 assert isinstance(iface.opview, test.InferResultsOp) 253 assert iface.opview == iface.operation.opview 254 255 try: 256 iface_static.opview 257 except TypeError: 258 pass 259 else: 260 assert False, ( 261 "not expected to be able to obtain an opview from a static" " interface" 262 ) 263 264 try: 265 InferTypeOpInterface(dummy) 266 except ValueError: 267 pass 268 else: 269 assert False, "not expected dummy op to implement the interface" 270 271 try: 272 InferTypeOpInterface(test.DummyOp) 273 except ValueError: 274 pass 275 else: 276 assert False, "not expected dummy op class to implement the interface" 277 278 279# CHECK-LABEL: TEST: resultTypesDefinedByTraits 280@run 281def resultTypesDefinedByTraits(): 282 with Context() as ctx, Location.unknown(ctx): 283 module = Module.create() 284 with InsertionPoint(module.body): 285 inferred = test.InferResultsOp() 286 same = test.SameOperandAndResultTypeOp([inferred.results[0]]) 287 # CHECK-COUNT-2: i32 288 print(same.one.type) 289 print(same.two.type) 290 291 first_type_attr = test.FirstAttrDeriveTypeAttrOp( 292 inferred.results[1], TypeAttr.get(IndexType.get()) 293 ) 294 # CHECK-COUNT-2: index 295 print(first_type_attr.one.type) 296 print(first_type_attr.two.type) 297 298 first_attr = test.FirstAttrDeriveAttrOp(FloatAttr.get(F32Type.get(), 3.14)) 299 # CHECK-COUNT-3: f32 300 print(first_attr.one.type) 301 print(first_attr.two.type) 302 print(first_attr.three.type) 303 304 implied = test.InferResultsImpliedOp() 305 # CHECK: i32 306 print(implied.integer.type) 307 # CHECK: f64 308 print(implied.flt.type) 309 # CHECK: index 310 print(implied.index.type) 311 312 313# CHECK-LABEL: TEST: testOptionalOperandOp 314@run 315def testOptionalOperandOp(): 316 with Context() as ctx, Location.unknown(): 317 module = Module.create() 318 with InsertionPoint(module.body): 319 op1 = test.OptionalOperandOp() 320 # CHECK: op1.input is None: True 321 print(f"op1.input is None: {op1.input is None}") 322 323 op2 = test.OptionalOperandOp(input=op1) 324 # CHECK: op2.input is None: False 325 print(f"op2.input is None: {op2.input is None}") 326 327 328# CHECK-LABEL: TEST: testCustomAttribute 329@run 330def testCustomAttribute(): 331 with Context() as ctx, Location.unknown(): 332 a = TestAttr.get() 333 # CHECK: #python_test.test_attr 334 print(a) 335 336 # CHECK: python_test.custom_attributed_op { 337 # CHECK: #python_test.test_attr 338 # CHECK: } 339 op2 = test.CustomAttributedOp(a) 340 print(f"{op2}") 341 342 # CHECK: #python_test.test_attr 343 print(f"{op2.test_attr}") 344 345 # CHECK: TestAttr(#python_test.test_attr) 346 print(repr(op2.test_attr)) 347 348 # The following cast must not assert. 349 b = TestAttr(a) 350 351 unit = UnitAttr.get() 352 try: 353 TestAttr(unit) 354 except ValueError as e: 355 assert "Cannot cast attribute to TestAttr" in str(e) 356 else: 357 raise 358 359 # The following must trigger a TypeError from our adaptors and must not 360 # crash. 361 try: 362 TestAttr(42) 363 except TypeError as e: 364 assert "Expected an MLIR object" in str(e) 365 else: 366 raise 367 368 # The following must trigger a TypeError from pybind (therefore, not 369 # checking its message) and must not crash. 370 try: 371 TestAttr(42, 56) 372 except TypeError: 373 pass 374 else: 375 raise 376 377 378@run 379def testCustomType(): 380 with Context() as ctx: 381 a = TestType.get() 382 # CHECK: !python_test.test_type 383 print(a) 384 385 # The following cast must not assert. 386 b = TestType(a) 387 # Instance custom types should have typeids 388 assert isinstance(b.typeid, TypeID) 389 # Subclasses of ir.Type should not have a static_typeid 390 # CHECK: 'TestType' object has no attribute 'static_typeid' 391 try: 392 b.static_typeid 393 except AttributeError as e: 394 print(e) 395 396 i8 = IntegerType.get_signless(8) 397 try: 398 TestType(i8) 399 except ValueError as e: 400 assert "Cannot cast type to TestType" in str(e) 401 else: 402 raise 403 404 # The following must trigger a TypeError from our adaptors and must not 405 # crash. 406 try: 407 TestType(42) 408 except TypeError as e: 409 assert "Expected an MLIR object" in str(e) 410 else: 411 raise 412 413 # The following must trigger a TypeError from pybind (therefore, not 414 # checking its message) and must not crash. 415 try: 416 TestType(42, 56) 417 except TypeError: 418 pass 419 else: 420 raise 421 422 423@run 424# CHECK-LABEL: TEST: testTensorValue 425def testTensorValue(): 426 with Context() as ctx, Location.unknown(): 427 i8 = IntegerType.get_signless(8) 428 429 class Tensor(TestTensorValue): 430 def __str__(self): 431 return super().__str__().replace("Value", "Tensor") 432 433 module = Module.create() 434 with InsertionPoint(module.body): 435 t = tensor.EmptyOp([10, 10], i8).result 436 437 # CHECK: Value(%{{.*}} = tensor.empty() : tensor<10x10xi8>) 438 print(Value(t)) 439 440 tt = Tensor(t) 441 # CHECK: Tensor(%{{.*}} = tensor.empty() : tensor<10x10xi8>) 442 print(tt) 443 444 # CHECK: False 445 print(tt.is_null()) 446 447 # Classes of custom types that inherit from concrete types should have 448 # static_typeid 449 assert isinstance(TestIntegerRankedTensorType.static_typeid, TypeID) 450 # And it should be equal to the in-tree concrete type 451 assert TestIntegerRankedTensorType.static_typeid == t.type.typeid 452 453 d = tensor.EmptyOp([1, 2, 3], IntegerType.get_signless(5)).result 454 # CHECK: Value(%{{.*}} = tensor.empty() : tensor<1x2x3xi5>) 455 print(d) 456 # CHECK: TestTensorValue 457 print(repr(d)) 458 459 460# CHECK-LABEL: TEST: inferReturnTypeComponents 461@run 462def inferReturnTypeComponents(): 463 with Context() as ctx, Location.unknown(ctx): 464 module = Module.create() 465 i32 = IntegerType.get_signless(32) 466 with InsertionPoint(module.body): 467 resultType = UnrankedTensorType.get(i32) 468 operandTypes = [ 469 RankedTensorType.get([1, 3, 10, 10], i32), 470 UnrankedTensorType.get(i32), 471 ] 472 f = func.FuncOp( 473 "test_inferReturnTypeComponents", (operandTypes, [resultType]) 474 ) 475 entry_block = Block.create_at_start(f.operation.regions[0], operandTypes) 476 with InsertionPoint(entry_block): 477 ranked_op = test.InferShapedTypeComponentsOp( 478 resultType, entry_block.arguments[0] 479 ) 480 unranked_op = test.InferShapedTypeComponentsOp( 481 resultType, entry_block.arguments[1] 482 ) 483 484 # CHECK: has rank: True 485 # CHECK: rank: 4 486 # CHECK: element type: i32 487 # CHECK: shape: [1, 3, 10, 10] 488 iface = InferShapedTypeOpInterface(ranked_op) 489 shaped_type_components = iface.inferReturnTypeComponents( 490 operands=[ranked_op.operand] 491 )[0] 492 print("has rank:", shaped_type_components.has_rank) 493 print("rank:", shaped_type_components.rank) 494 print("element type:", shaped_type_components.element_type) 495 print("shape:", shaped_type_components.shape) 496 497 # CHECK: has rank: False 498 # CHECK: rank: None 499 # CHECK: element type: i32 500 # CHECK: shape: None 501 iface = InferShapedTypeOpInterface(unranked_op) 502 shaped_type_components = iface.inferReturnTypeComponents( 503 operands=[unranked_op.operand] 504 )[0] 505 print("has rank:", shaped_type_components.has_rank) 506 print("rank:", shaped_type_components.rank) 507 print("element type:", shaped_type_components.element_type) 508 print("shape:", shaped_type_components.shape) 509 510 511# CHECK-LABEL: TEST: testCustomTypeTypeCaster 512@run 513def testCustomTypeTypeCaster(): 514 with Context() as ctx, Location.unknown(): 515 a = TestType.get() 516 assert a.typeid is not None 517 518 b = Type.parse("!python_test.test_type") 519 # CHECK: !python_test.test_type 520 print(b) 521 # CHECK: TestType(!python_test.test_type) 522 print(repr(b)) 523 524 c = TestIntegerRankedTensorType.get([10, 10], 5) 525 # CHECK: tensor<10x10xi5> 526 print(c) 527 # CHECK: TestIntegerRankedTensorType(tensor<10x10xi5>) 528 print(repr(c)) 529 530 # CHECK: Type caster is already registered 531 try: 532 533 @register_type_caster(c.typeid) 534 def type_caster(pytype): 535 return TestIntegerRankedTensorType(pytype) 536 537 except RuntimeError as e: 538 print(e) 539 540 # python_test dialect registers a caster for RankedTensorType in its extension (pybind) module. 541 # So this one replaces that one (successfully). And then just to be sure we restore the original caster below. 542 @register_type_caster(c.typeid, replace=True) 543 def type_caster(pytype): 544 return RankedTensorType(pytype) 545 546 d = tensor.EmptyOp([10, 10], IntegerType.get_signless(5)).result 547 # CHECK: tensor<10x10xi5> 548 print(d.type) 549 # CHECK: ranked tensor type RankedTensorType(tensor<10x10xi5>) 550 print("ranked tensor type", repr(d.type)) 551 552 @register_type_caster(c.typeid, replace=True) 553 def type_caster(pytype): 554 return TestIntegerRankedTensorType(pytype) 555 556 d = tensor.EmptyOp([10, 10], IntegerType.get_signless(5)).result 557 # CHECK: tensor<10x10xi5> 558 print(d.type) 559 # CHECK: TestIntegerRankedTensorType(tensor<10x10xi5>) 560 print(repr(d.type)) 561 562 563# CHECK-LABEL: TEST: testInferTypeOpInterface 564@run 565def testInferTypeOpInterface(): 566 with Context() as ctx, Location.unknown(ctx): 567 module = Module.create() 568 with InsertionPoint(module.body): 569 i64 = IntegerType.get_signless(64) 570 zero = arith.ConstantOp(i64, 0) 571 572 one_operand = test.InferResultsVariadicInputsOp(single=zero, doubled=None) 573 # CHECK: i32 574 print(one_operand.result.type) 575 576 two_operands = test.InferResultsVariadicInputsOp(single=zero, doubled=zero) 577 # CHECK: f32 578 print(two_operands.result.type) 579 580 581# CHECK-LABEL: TEST: testVariadicOperandAccess 582@run 583def testVariadicOperandAccess(): 584 def values(lst): 585 return [str(e) for e in lst] 586 587 with Context() as ctx, Location.unknown(ctx): 588 module = Module.create() 589 with InsertionPoint(module.body): 590 i32 = IntegerType.get_signless(32) 591 zero = arith.ConstantOp(i32, 0) 592 one = arith.ConstantOp(i32, 1) 593 two = arith.ConstantOp(i32, 2) 594 three = arith.ConstantOp(i32, 3) 595 four = arith.ConstantOp(i32, 4) 596 597 variadic_operands = test.SameVariadicOperandSizeOp( 598 [zero, one], two, [three, four] 599 ) 600 # CHECK: Value(%{{.*}} = arith.constant 2 : i32) 601 print(variadic_operands.non_variadic) 602 # CHECK: ['Value(%{{.*}} = arith.constant 0 : i32)', 'Value(%{{.*}} = arith.constant 1 : i32)'] 603 print(values(variadic_operands.variadic1)) 604 # CHECK: ['Value(%{{.*}} = arith.constant 3 : i32)', 'Value(%{{.*}} = arith.constant 4 : i32)'] 605 print(values(variadic_operands.variadic2)) 606 607 608# CHECK-LABEL: TEST: testVariadicResultAccess 609@run 610def testVariadicResultAccess(): 611 def types(lst): 612 return [e.type for e in lst] 613 614 with Context() as ctx, Location.unknown(ctx): 615 module = Module.create() 616 with InsertionPoint(module.body): 617 i = [IntegerType.get_signless(k) for k in range(7)] 618 619 # Test Variadic-Fixed-Variadic 620 op = test.SameVariadicResultSizeOpVFV([i[0], i[1]], i[2], [i[3], i[4]]) 621 # CHECK: i2 622 print(op.non_variadic.type) 623 # CHECK: [IntegerType(i0), IntegerType(i1)] 624 print(types(op.variadic1)) 625 # CHECK: [IntegerType(i3), IntegerType(i4)] 626 print(types(op.variadic2)) 627 628 # Test Variadic-Variadic-Variadic 629 op = test.SameVariadicResultSizeOpVVV( 630 [i[0], i[1]], [i[2], i[3]], [i[4], i[5]] 631 ) 632 # CHECK: [IntegerType(i0), IntegerType(i1)] 633 print(types(op.variadic1)) 634 # CHECK: [IntegerType(i2), IntegerType(i3)] 635 print(types(op.variadic2)) 636 # CHECK: [IntegerType(i4), IntegerType(i5)] 637 print(types(op.variadic3)) 638 639 # Test Fixed-Fixed-Variadic 640 op = test.SameVariadicResultSizeOpFFV(i[0], i[1], [i[2], i[3], i[4]]) 641 # CHECK: i0 642 print(op.non_variadic1.type) 643 # CHECK: i1 644 print(op.non_variadic2.type) 645 # CHECK: [IntegerType(i2), IntegerType(i3), IntegerType(i4)] 646 print(types(op.variadic)) 647 648 # Test Variadic-Variadic-Fixed 649 op = test.SameVariadicResultSizeOpVVF( 650 [i[0], i[1], i[2]], [i[3], i[4], i[5]], i[6] 651 ) 652 # CHECK: [IntegerType(i0), IntegerType(i1), IntegerType(i2)] 653 print(types(op.variadic1)) 654 # CHECK: [IntegerType(i3), IntegerType(i4), IntegerType(i5)] 655 print(types(op.variadic2)) 656 # CHECK: i6 657 print(op.non_variadic.type) 658 659 # Test Fixed-Variadic-Fixed-Variadic-Fixed 660 op = test.SameVariadicResultSizeOpFVFVF( 661 i[0], [i[1], i[2]], i[3], [i[4], i[5]], i[6] 662 ) 663 # CHECK: i0 664 print(op.non_variadic1.type) 665 # CHECK: [IntegerType(i1), IntegerType(i2)] 666 print(types(op.variadic1)) 667 # CHECK: i3 668 print(op.non_variadic2.type) 669 # CHECK: [IntegerType(i4), IntegerType(i5)] 670 print(types(op.variadic2)) 671 # CHECK: i6 672 print(op.non_variadic3.type) 673 674 # Test Fixed-Variadic-Fixed-Variadic-Fixed - Variadic group size 0 675 op = test.SameVariadicResultSizeOpFVFVF(i[0], [], i[1], [], i[2]) 676 # CHECK: i0 677 print(op.non_variadic1.type) 678 # CHECK: [] 679 print(types(op.variadic1)) 680 # CHECK: i1 681 print(op.non_variadic2.type) 682 # CHECK: [] 683 print(types(op.variadic2)) 684 # CHECK: i2 685 print(op.non_variadic3.type) 686 687 # Test Fixed-Variadic-Fixed-Variadic-Fixed - Variadic group size 1 688 op = test.SameVariadicResultSizeOpFVFVF(i[0], [i[1]], i[2], [i[3]], i[4]) 689 # CHECK: i0 690 print(op.non_variadic1.type) 691 # CHECK: [IntegerType(i1)] 692 print(types(op.variadic1)) 693 # CHECK: i2 694 print(op.non_variadic2.type) 695 # CHECK: [IntegerType(i3)] 696 print(types(op.variadic2)) 697 # CHECK: i4 698 print(op.non_variadic3.type) 699