1 //===- ir.c - Simple test of C APIs ---------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM 4 // Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 /* RUN: mlir-capi-ir-test 2>&1 | FileCheck %s 11 */ 12 13 #include "mlir-c/IR.h" 14 #include "mlir-c/AffineExpr.h" 15 #include "mlir-c/AffineMap.h" 16 #include "mlir-c/BuiltinAttributes.h" 17 #include "mlir-c/BuiltinTypes.h" 18 #include "mlir-c/Diagnostics.h" 19 #include "mlir-c/Dialect/Standard.h" 20 #include "mlir-c/IntegerSet.h" 21 #include "mlir-c/Registration.h" 22 23 #include <assert.h> 24 #include <math.h> 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 29 void populateLoopBody(MlirContext ctx, MlirBlock loopBody, 30 MlirLocation location, MlirBlock funcBody) { 31 MlirValue iv = mlirBlockGetArgument(loopBody, 0); 32 MlirValue funcArg0 = mlirBlockGetArgument(funcBody, 0); 33 MlirValue funcArg1 = mlirBlockGetArgument(funcBody, 1); 34 MlirType f32Type = 35 mlirTypeParseGet(ctx, mlirStringRefCreateFromCString("f32")); 36 37 MlirOperationState loadLHSState = mlirOperationStateGet( 38 mlirStringRefCreateFromCString("memref.load"), location); 39 MlirValue loadLHSOperands[] = {funcArg0, iv}; 40 mlirOperationStateAddOperands(&loadLHSState, 2, loadLHSOperands); 41 mlirOperationStateAddResults(&loadLHSState, 1, &f32Type); 42 MlirOperation loadLHS = mlirOperationCreate(&loadLHSState); 43 mlirBlockAppendOwnedOperation(loopBody, loadLHS); 44 45 MlirOperationState loadRHSState = mlirOperationStateGet( 46 mlirStringRefCreateFromCString("memref.load"), location); 47 MlirValue loadRHSOperands[] = {funcArg1, iv}; 48 mlirOperationStateAddOperands(&loadRHSState, 2, loadRHSOperands); 49 mlirOperationStateAddResults(&loadRHSState, 1, &f32Type); 50 MlirOperation loadRHS = mlirOperationCreate(&loadRHSState); 51 mlirBlockAppendOwnedOperation(loopBody, loadRHS); 52 53 MlirOperationState addState = mlirOperationStateGet( 54 mlirStringRefCreateFromCString("std.addf"), location); 55 MlirValue addOperands[] = {mlirOperationGetResult(loadLHS, 0), 56 mlirOperationGetResult(loadRHS, 0)}; 57 mlirOperationStateAddOperands(&addState, 2, addOperands); 58 mlirOperationStateAddResults(&addState, 1, &f32Type); 59 MlirOperation add = mlirOperationCreate(&addState); 60 mlirBlockAppendOwnedOperation(loopBody, add); 61 62 MlirOperationState storeState = mlirOperationStateGet( 63 mlirStringRefCreateFromCString("memref.store"), location); 64 MlirValue storeOperands[] = {mlirOperationGetResult(add, 0), funcArg0, iv}; 65 mlirOperationStateAddOperands(&storeState, 3, storeOperands); 66 MlirOperation store = mlirOperationCreate(&storeState); 67 mlirBlockAppendOwnedOperation(loopBody, store); 68 69 MlirOperationState yieldState = mlirOperationStateGet( 70 mlirStringRefCreateFromCString("scf.yield"), location); 71 MlirOperation yield = mlirOperationCreate(&yieldState); 72 mlirBlockAppendOwnedOperation(loopBody, yield); 73 } 74 75 MlirModule makeAndDumpAdd(MlirContext ctx, MlirLocation location) { 76 MlirModule moduleOp = mlirModuleCreateEmpty(location); 77 MlirBlock moduleBody = mlirModuleGetBody(moduleOp); 78 79 MlirType memrefType = 80 mlirTypeParseGet(ctx, mlirStringRefCreateFromCString("memref<?xf32>")); 81 MlirType funcBodyArgTypes[] = {memrefType, memrefType}; 82 MlirRegion funcBodyRegion = mlirRegionCreate(); 83 MlirBlock funcBody = mlirBlockCreate( 84 sizeof(funcBodyArgTypes) / sizeof(MlirType), funcBodyArgTypes); 85 mlirRegionAppendOwnedBlock(funcBodyRegion, funcBody); 86 87 MlirAttribute funcTypeAttr = mlirAttributeParseGet( 88 ctx, 89 mlirStringRefCreateFromCString("(memref<?xf32>, memref<?xf32>) -> ()")); 90 MlirAttribute funcNameAttr = 91 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("\"add\"")); 92 MlirNamedAttribute funcAttrs[] = { 93 mlirNamedAttributeGet( 94 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("type")), 95 funcTypeAttr), 96 mlirNamedAttributeGet( 97 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("sym_name")), 98 funcNameAttr)}; 99 MlirOperationState funcState = 100 mlirOperationStateGet(mlirStringRefCreateFromCString("func"), location); 101 mlirOperationStateAddAttributes(&funcState, 2, funcAttrs); 102 mlirOperationStateAddOwnedRegions(&funcState, 1, &funcBodyRegion); 103 MlirOperation func = mlirOperationCreate(&funcState); 104 mlirBlockInsertOwnedOperation(moduleBody, 0, func); 105 106 MlirType indexType = 107 mlirTypeParseGet(ctx, mlirStringRefCreateFromCString("index")); 108 MlirAttribute indexZeroLiteral = 109 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("0 : index")); 110 MlirNamedAttribute indexZeroValueAttr = mlirNamedAttributeGet( 111 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), 112 indexZeroLiteral); 113 MlirOperationState constZeroState = mlirOperationStateGet( 114 mlirStringRefCreateFromCString("std.constant"), location); 115 mlirOperationStateAddResults(&constZeroState, 1, &indexType); 116 mlirOperationStateAddAttributes(&constZeroState, 1, &indexZeroValueAttr); 117 MlirOperation constZero = mlirOperationCreate(&constZeroState); 118 mlirBlockAppendOwnedOperation(funcBody, constZero); 119 120 MlirValue funcArg0 = mlirBlockGetArgument(funcBody, 0); 121 MlirValue constZeroValue = mlirOperationGetResult(constZero, 0); 122 MlirValue dimOperands[] = {funcArg0, constZeroValue}; 123 MlirOperationState dimState = mlirOperationStateGet( 124 mlirStringRefCreateFromCString("memref.dim"), location); 125 mlirOperationStateAddOperands(&dimState, 2, dimOperands); 126 mlirOperationStateAddResults(&dimState, 1, &indexType); 127 MlirOperation dim = mlirOperationCreate(&dimState); 128 mlirBlockAppendOwnedOperation(funcBody, dim); 129 130 MlirRegion loopBodyRegion = mlirRegionCreate(); 131 MlirBlock loopBody = mlirBlockCreate(0, NULL); 132 mlirBlockAddArgument(loopBody, indexType); 133 mlirRegionAppendOwnedBlock(loopBodyRegion, loopBody); 134 135 MlirAttribute indexOneLiteral = 136 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("1 : index")); 137 MlirNamedAttribute indexOneValueAttr = mlirNamedAttributeGet( 138 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), 139 indexOneLiteral); 140 MlirOperationState constOneState = mlirOperationStateGet( 141 mlirStringRefCreateFromCString("std.constant"), location); 142 mlirOperationStateAddResults(&constOneState, 1, &indexType); 143 mlirOperationStateAddAttributes(&constOneState, 1, &indexOneValueAttr); 144 MlirOperation constOne = mlirOperationCreate(&constOneState); 145 mlirBlockAppendOwnedOperation(funcBody, constOne); 146 147 MlirValue dimValue = mlirOperationGetResult(dim, 0); 148 MlirValue constOneValue = mlirOperationGetResult(constOne, 0); 149 MlirValue loopOperands[] = {constZeroValue, dimValue, constOneValue}; 150 MlirOperationState loopState = mlirOperationStateGet( 151 mlirStringRefCreateFromCString("scf.for"), location); 152 mlirOperationStateAddOperands(&loopState, 3, loopOperands); 153 mlirOperationStateAddOwnedRegions(&loopState, 1, &loopBodyRegion); 154 MlirOperation loop = mlirOperationCreate(&loopState); 155 mlirBlockAppendOwnedOperation(funcBody, loop); 156 157 populateLoopBody(ctx, loopBody, location, funcBody); 158 159 MlirOperationState retState = mlirOperationStateGet( 160 mlirStringRefCreateFromCString("std.return"), location); 161 MlirOperation ret = mlirOperationCreate(&retState); 162 mlirBlockAppendOwnedOperation(funcBody, ret); 163 164 MlirOperation module = mlirModuleGetOperation(moduleOp); 165 mlirOperationDump(module); 166 // clang-format off 167 // CHECK: module { 168 // CHECK: func @add(%[[ARG0:.*]]: memref<?xf32>, %[[ARG1:.*]]: memref<?xf32>) { 169 // CHECK: %[[C0:.*]] = constant 0 : index 170 // CHECK: %[[DIM:.*]] = memref.dim %[[ARG0]], %[[C0]] : memref<?xf32> 171 // CHECK: %[[C1:.*]] = constant 1 : index 172 // CHECK: scf.for %[[I:.*]] = %[[C0]] to %[[DIM]] step %[[C1]] { 173 // CHECK: %[[LHS:.*]] = memref.load %[[ARG0]][%[[I]]] : memref<?xf32> 174 // CHECK: %[[RHS:.*]] = memref.load %[[ARG1]][%[[I]]] : memref<?xf32> 175 // CHECK: %[[SUM:.*]] = addf %[[LHS]], %[[RHS]] : f32 176 // CHECK: memref.store %[[SUM]], %[[ARG0]][%[[I]]] : memref<?xf32> 177 // CHECK: } 178 // CHECK: return 179 // CHECK: } 180 // CHECK: } 181 // clang-format on 182 183 return moduleOp; 184 } 185 186 struct OpListNode { 187 MlirOperation op; 188 struct OpListNode *next; 189 }; 190 typedef struct OpListNode OpListNode; 191 192 struct ModuleStats { 193 unsigned numOperations; 194 unsigned numAttributes; 195 unsigned numBlocks; 196 unsigned numRegions; 197 unsigned numValues; 198 unsigned numBlockArguments; 199 unsigned numOpResults; 200 }; 201 typedef struct ModuleStats ModuleStats; 202 203 int collectStatsSingle(OpListNode *head, ModuleStats *stats) { 204 MlirOperation operation = head->op; 205 stats->numOperations += 1; 206 stats->numValues += mlirOperationGetNumResults(operation); 207 stats->numAttributes += mlirOperationGetNumAttributes(operation); 208 209 unsigned numRegions = mlirOperationGetNumRegions(operation); 210 211 stats->numRegions += numRegions; 212 213 intptr_t numResults = mlirOperationGetNumResults(operation); 214 for (intptr_t i = 0; i < numResults; ++i) { 215 MlirValue result = mlirOperationGetResult(operation, i); 216 if (!mlirValueIsAOpResult(result)) 217 return 1; 218 if (mlirValueIsABlockArgument(result)) 219 return 2; 220 if (!mlirOperationEqual(operation, mlirOpResultGetOwner(result))) 221 return 3; 222 if (i != mlirOpResultGetResultNumber(result)) 223 return 4; 224 ++stats->numOpResults; 225 } 226 227 for (unsigned i = 0; i < numRegions; ++i) { 228 MlirRegion region = mlirOperationGetRegion(operation, i); 229 for (MlirBlock block = mlirRegionGetFirstBlock(region); 230 !mlirBlockIsNull(block); block = mlirBlockGetNextInRegion(block)) { 231 ++stats->numBlocks; 232 intptr_t numArgs = mlirBlockGetNumArguments(block); 233 stats->numValues += numArgs; 234 for (intptr_t j = 0; j < numArgs; ++j) { 235 MlirValue arg = mlirBlockGetArgument(block, j); 236 if (!mlirValueIsABlockArgument(arg)) 237 return 5; 238 if (mlirValueIsAOpResult(arg)) 239 return 6; 240 if (!mlirBlockEqual(block, mlirBlockArgumentGetOwner(arg))) 241 return 7; 242 if (j != mlirBlockArgumentGetArgNumber(arg)) 243 return 8; 244 ++stats->numBlockArguments; 245 } 246 247 for (MlirOperation child = mlirBlockGetFirstOperation(block); 248 !mlirOperationIsNull(child); 249 child = mlirOperationGetNextInBlock(child)) { 250 OpListNode *node = malloc(sizeof(OpListNode)); 251 node->op = child; 252 node->next = head->next; 253 head->next = node; 254 } 255 } 256 } 257 return 0; 258 } 259 260 int collectStats(MlirOperation operation) { 261 OpListNode *head = malloc(sizeof(OpListNode)); 262 head->op = operation; 263 head->next = NULL; 264 265 ModuleStats stats; 266 stats.numOperations = 0; 267 stats.numAttributes = 0; 268 stats.numBlocks = 0; 269 stats.numRegions = 0; 270 stats.numValues = 0; 271 stats.numBlockArguments = 0; 272 stats.numOpResults = 0; 273 274 do { 275 int retval = collectStatsSingle(head, &stats); 276 if (retval) 277 return retval; 278 OpListNode *next = head->next; 279 free(head); 280 head = next; 281 } while (head); 282 283 if (stats.numValues != stats.numBlockArguments + stats.numOpResults) 284 return 100; 285 286 fprintf(stderr, "@stats\n"); 287 fprintf(stderr, "Number of operations: %u\n", stats.numOperations); 288 fprintf(stderr, "Number of attributes: %u\n", stats.numAttributes); 289 fprintf(stderr, "Number of blocks: %u\n", stats.numBlocks); 290 fprintf(stderr, "Number of regions: %u\n", stats.numRegions); 291 fprintf(stderr, "Number of values: %u\n", stats.numValues); 292 fprintf(stderr, "Number of block arguments: %u\n", stats.numBlockArguments); 293 fprintf(stderr, "Number of op results: %u\n", stats.numOpResults); 294 // clang-format off 295 // CHECK-LABEL: @stats 296 // CHECK: Number of operations: 12 297 // CHECK: Number of attributes: 4 298 // CHECK: Number of blocks: 3 299 // CHECK: Number of regions: 3 300 // CHECK: Number of values: 9 301 // CHECK: Number of block arguments: 3 302 // CHECK: Number of op results: 6 303 // clang-format on 304 return 0; 305 } 306 307 static void printToStderr(MlirStringRef str, void *userData) { 308 (void)userData; 309 fwrite(str.data, 1, str.length, stderr); 310 } 311 312 static void printFirstOfEach(MlirContext ctx, MlirOperation operation) { 313 // Assuming we are given a module, go to the first operation of the first 314 // function. 315 MlirRegion region = mlirOperationGetRegion(operation, 0); 316 MlirBlock block = mlirRegionGetFirstBlock(region); 317 operation = mlirBlockGetFirstOperation(block); 318 region = mlirOperationGetRegion(operation, 0); 319 MlirOperation parentOperation = operation; 320 block = mlirRegionGetFirstBlock(region); 321 operation = mlirBlockGetFirstOperation(block); 322 323 // Verify that parent operation and block report correctly. 324 fprintf(stderr, "Parent operation eq: %d\n", 325 mlirOperationEqual(mlirOperationGetParentOperation(operation), 326 parentOperation)); 327 fprintf(stderr, "Block eq: %d\n", 328 mlirBlockEqual(mlirOperationGetBlock(operation), block)); 329 // CHECK: Parent operation eq: 1 330 // CHECK: Block eq: 1 331 332 // In the module we created, the first operation of the first function is 333 // an "memref.dim", which has an attribute and a single result that we can 334 // use to test the printing mechanism. 335 mlirBlockPrint(block, printToStderr, NULL); 336 fprintf(stderr, "\n"); 337 fprintf(stderr, "First operation: "); 338 mlirOperationPrint(operation, printToStderr, NULL); 339 fprintf(stderr, "\n"); 340 // clang-format off 341 // CHECK: %[[C0:.*]] = constant 0 : index 342 // CHECK: %[[DIM:.*]] = memref.dim %{{.*}}, %[[C0]] : memref<?xf32> 343 // CHECK: %[[C1:.*]] = constant 1 : index 344 // CHECK: scf.for %[[I:.*]] = %[[C0]] to %[[DIM]] step %[[C1]] { 345 // CHECK: %[[LHS:.*]] = memref.load %{{.*}}[%[[I]]] : memref<?xf32> 346 // CHECK: %[[RHS:.*]] = memref.load %{{.*}}[%[[I]]] : memref<?xf32> 347 // CHECK: %[[SUM:.*]] = addf %[[LHS]], %[[RHS]] : f32 348 // CHECK: memref.store %[[SUM]], %{{.*}}[%[[I]]] : memref<?xf32> 349 // CHECK: } 350 // CHECK: return 351 // CHECK: First operation: {{.*}} = constant 0 : index 352 // clang-format on 353 354 // Get the operation name and print it. 355 MlirIdentifier ident = mlirOperationGetName(operation); 356 MlirStringRef identStr = mlirIdentifierStr(ident); 357 fprintf(stderr, "Operation name: '"); 358 for (size_t i = 0; i < identStr.length; ++i) 359 fputc(identStr.data[i], stderr); 360 fprintf(stderr, "'\n"); 361 // CHECK: Operation name: 'std.constant' 362 363 // Get the identifier again and verify equal. 364 MlirIdentifier identAgain = mlirIdentifierGet(ctx, identStr); 365 fprintf(stderr, "Identifier equal: %d\n", 366 mlirIdentifierEqual(ident, identAgain)); 367 // CHECK: Identifier equal: 1 368 369 // Get the block terminator and print it. 370 MlirOperation terminator = mlirBlockGetTerminator(block); 371 fprintf(stderr, "Terminator: "); 372 mlirOperationPrint(terminator, printToStderr, NULL); 373 fprintf(stderr, "\n"); 374 // CHECK: Terminator: return 375 376 // Get the attribute by index. 377 MlirNamedAttribute namedAttr0 = mlirOperationGetAttribute(operation, 0); 378 fprintf(stderr, "Get attr 0: "); 379 mlirAttributePrint(namedAttr0.attribute, printToStderr, NULL); 380 fprintf(stderr, "\n"); 381 // CHECK: Get attr 0: 0 : index 382 383 // Now re-get the attribute by name. 384 MlirAttribute attr0ByName = mlirOperationGetAttributeByName( 385 operation, mlirIdentifierStr(namedAttr0.name)); 386 fprintf(stderr, "Get attr 0 by name: "); 387 mlirAttributePrint(attr0ByName, printToStderr, NULL); 388 fprintf(stderr, "\n"); 389 // CHECK: Get attr 0 by name: 0 : index 390 391 // Get a non-existing attribute and assert that it is null (sanity). 392 fprintf(stderr, "does_not_exist is null: %d\n", 393 mlirAttributeIsNull(mlirOperationGetAttributeByName( 394 operation, mlirStringRefCreateFromCString("does_not_exist")))); 395 // CHECK: does_not_exist is null: 1 396 397 // Get result 0 and its type. 398 MlirValue value = mlirOperationGetResult(operation, 0); 399 fprintf(stderr, "Result 0: "); 400 mlirValuePrint(value, printToStderr, NULL); 401 fprintf(stderr, "\n"); 402 fprintf(stderr, "Value is null: %d\n", mlirValueIsNull(value)); 403 // CHECK: Result 0: {{.*}} = constant 0 : index 404 // CHECK: Value is null: 0 405 406 MlirType type = mlirValueGetType(value); 407 fprintf(stderr, "Result 0 type: "); 408 mlirTypePrint(type, printToStderr, NULL); 409 fprintf(stderr, "\n"); 410 // CHECK: Result 0 type: index 411 412 // Set a custom attribute. 413 mlirOperationSetAttributeByName(operation, 414 mlirStringRefCreateFromCString("custom_attr"), 415 mlirBoolAttrGet(ctx, 1)); 416 fprintf(stderr, "Op with set attr: "); 417 mlirOperationPrint(operation, printToStderr, NULL); 418 fprintf(stderr, "\n"); 419 // CHECK: Op with set attr: {{.*}} {custom_attr = true} 420 421 // Remove the attribute. 422 fprintf(stderr, "Remove attr: %d\n", 423 mlirOperationRemoveAttributeByName( 424 operation, mlirStringRefCreateFromCString("custom_attr"))); 425 fprintf(stderr, "Remove attr again: %d\n", 426 mlirOperationRemoveAttributeByName( 427 operation, mlirStringRefCreateFromCString("custom_attr"))); 428 fprintf(stderr, "Removed attr is null: %d\n", 429 mlirAttributeIsNull(mlirOperationGetAttributeByName( 430 operation, mlirStringRefCreateFromCString("custom_attr")))); 431 // CHECK: Remove attr: 1 432 // CHECK: Remove attr again: 0 433 // CHECK: Removed attr is null: 1 434 435 // Add a large attribute to verify printing flags. 436 int64_t eltsShape[] = {4}; 437 int32_t eltsData[] = {1, 2, 3, 4}; 438 mlirOperationSetAttributeByName( 439 operation, mlirStringRefCreateFromCString("elts"), 440 mlirDenseElementsAttrInt32Get( 441 mlirRankedTensorTypeGet(1, eltsShape, mlirIntegerTypeGet(ctx, 32), 442 mlirAttributeGetNull()), 4, eltsData)); 443 MlirOpPrintingFlags flags = mlirOpPrintingFlagsCreate(); 444 mlirOpPrintingFlagsElideLargeElementsAttrs(flags, 2); 445 mlirOpPrintingFlagsPrintGenericOpForm(flags); 446 mlirOpPrintingFlagsEnableDebugInfo(flags, /*prettyForm=*/0); 447 mlirOpPrintingFlagsUseLocalScope(flags); 448 fprintf(stderr, "Op print with all flags: "); 449 mlirOperationPrintWithFlags(operation, flags, printToStderr, NULL); 450 fprintf(stderr, "\n"); 451 // clang-format off 452 // CHECK: Op print with all flags: %{{.*}} = "std.constant"() {elts = opaque<"_", "0xDEADBEEF"> : tensor<4xi32>, value = 0 : index} : () -> index loc(unknown) 453 // clang-format on 454 455 mlirOpPrintingFlagsDestroy(flags); 456 } 457 458 static int constructAndTraverseIr(MlirContext ctx) { 459 MlirLocation location = mlirLocationUnknownGet(ctx); 460 461 MlirModule moduleOp = makeAndDumpAdd(ctx, location); 462 MlirOperation module = mlirModuleGetOperation(moduleOp); 463 464 int errcode = collectStats(module); 465 if (errcode) 466 return errcode; 467 468 printFirstOfEach(ctx, module); 469 470 mlirModuleDestroy(moduleOp); 471 return 0; 472 } 473 474 /// Creates an operation with a region containing multiple blocks with 475 /// operations and dumps it. The blocks and operations are inserted using 476 /// block/operation-relative API and their final order is checked. 477 static void buildWithInsertionsAndPrint(MlirContext ctx) { 478 MlirLocation loc = mlirLocationUnknownGet(ctx); 479 480 MlirRegion owningRegion = mlirRegionCreate(); 481 MlirBlock nullBlock = mlirRegionGetFirstBlock(owningRegion); 482 MlirOperationState state = mlirOperationStateGet( 483 mlirStringRefCreateFromCString("insertion.order.test"), loc); 484 mlirOperationStateAddOwnedRegions(&state, 1, &owningRegion); 485 MlirOperation op = mlirOperationCreate(&state); 486 MlirRegion region = mlirOperationGetRegion(op, 0); 487 488 // Use integer types of different bitwidth as block arguments in order to 489 // differentiate blocks. 490 MlirType i1 = mlirIntegerTypeGet(ctx, 1); 491 MlirType i2 = mlirIntegerTypeGet(ctx, 2); 492 MlirType i3 = mlirIntegerTypeGet(ctx, 3); 493 MlirType i4 = mlirIntegerTypeGet(ctx, 4); 494 MlirBlock block1 = mlirBlockCreate(1, &i1); 495 MlirBlock block2 = mlirBlockCreate(1, &i2); 496 MlirBlock block3 = mlirBlockCreate(1, &i3); 497 MlirBlock block4 = mlirBlockCreate(1, &i4); 498 // Insert blocks so as to obtain the 1-2-3-4 order, 499 mlirRegionInsertOwnedBlockBefore(region, nullBlock, block3); 500 mlirRegionInsertOwnedBlockBefore(region, block3, block2); 501 mlirRegionInsertOwnedBlockAfter(region, nullBlock, block1); 502 mlirRegionInsertOwnedBlockAfter(region, block3, block4); 503 504 MlirOperationState op1State = 505 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op1"), loc); 506 MlirOperationState op2State = 507 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op2"), loc); 508 MlirOperationState op3State = 509 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op3"), loc); 510 MlirOperationState op4State = 511 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op4"), loc); 512 MlirOperationState op5State = 513 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op5"), loc); 514 MlirOperationState op6State = 515 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op6"), loc); 516 MlirOperationState op7State = 517 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op7"), loc); 518 MlirOperation op1 = mlirOperationCreate(&op1State); 519 MlirOperation op2 = mlirOperationCreate(&op2State); 520 MlirOperation op3 = mlirOperationCreate(&op3State); 521 MlirOperation op4 = mlirOperationCreate(&op4State); 522 MlirOperation op5 = mlirOperationCreate(&op5State); 523 MlirOperation op6 = mlirOperationCreate(&op6State); 524 MlirOperation op7 = mlirOperationCreate(&op7State); 525 526 // Insert operations in the first block so as to obtain the 1-2-3-4 order. 527 MlirOperation nullOperation = mlirBlockGetFirstOperation(block1); 528 assert(mlirOperationIsNull(nullOperation)); 529 mlirBlockInsertOwnedOperationBefore(block1, nullOperation, op3); 530 mlirBlockInsertOwnedOperationBefore(block1, op3, op2); 531 mlirBlockInsertOwnedOperationAfter(block1, nullOperation, op1); 532 mlirBlockInsertOwnedOperationAfter(block1, op3, op4); 533 534 // Append operations to the rest of blocks to make them non-empty and thus 535 // printable. 536 mlirBlockAppendOwnedOperation(block2, op5); 537 mlirBlockAppendOwnedOperation(block3, op6); 538 mlirBlockAppendOwnedOperation(block4, op7); 539 540 mlirOperationDump(op); 541 mlirOperationDestroy(op); 542 // clang-format off 543 // CHECK-LABEL: "insertion.order.test" 544 // CHECK: ^{{.*}}(%{{.*}}: i1 545 // CHECK: "dummy.op1" 546 // CHECK-NEXT: "dummy.op2" 547 // CHECK-NEXT: "dummy.op3" 548 // CHECK-NEXT: "dummy.op4" 549 // CHECK: ^{{.*}}(%{{.*}}: i2 550 // CHECK: "dummy.op5" 551 // CHECK: ^{{.*}}(%{{.*}}: i3 552 // CHECK: "dummy.op6" 553 // CHECK: ^{{.*}}(%{{.*}}: i4 554 // CHECK: "dummy.op7" 555 // clang-format on 556 } 557 558 /// Creates operations with type inference and tests various failure modes. 559 static int createOperationWithTypeInference(MlirContext ctx) { 560 MlirLocation loc = mlirLocationUnknownGet(ctx); 561 MlirAttribute iAttr = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 32), 4); 562 563 // The shape.const_size op implements result type inference and is only used 564 // for that reason. 565 MlirOperationState state = mlirOperationStateGet( 566 mlirStringRefCreateFromCString("shape.const_size"), loc); 567 MlirNamedAttribute valueAttr = mlirNamedAttributeGet( 568 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), iAttr); 569 mlirOperationStateAddAttributes(&state, 1, &valueAttr); 570 mlirOperationStateEnableResultTypeInference(&state); 571 572 // Expect result type inference to succeed. 573 MlirOperation op = mlirOperationCreate(&state); 574 if (mlirOperationIsNull(op)) { 575 fprintf(stderr, "ERROR: Result type inference unexpectedly failed"); 576 return 1; 577 } 578 579 // CHECK: RESULT_TYPE_INFERENCE: !shape.size 580 fprintf(stderr, "RESULT_TYPE_INFERENCE: "); 581 mlirTypeDump(mlirValueGetType(mlirOperationGetResult(op, 0))); 582 fprintf(stderr, "\n"); 583 mlirOperationDestroy(op); 584 return 0; 585 } 586 587 /// Dumps instances of all builtin types to check that C API works correctly. 588 /// Additionally, performs simple identity checks that a builtin type 589 /// constructed with C API can be inspected and has the expected type. The 590 /// latter achieves full coverage of C API for builtin types. Returns 0 on 591 /// success and a non-zero error code on failure. 592 static int printBuiltinTypes(MlirContext ctx) { 593 // Integer types. 594 MlirType i32 = mlirIntegerTypeGet(ctx, 32); 595 MlirType si32 = mlirIntegerTypeSignedGet(ctx, 32); 596 MlirType ui32 = mlirIntegerTypeUnsignedGet(ctx, 32); 597 if (!mlirTypeIsAInteger(i32) || mlirTypeIsAF32(i32)) 598 return 1; 599 if (!mlirTypeIsAInteger(si32) || !mlirIntegerTypeIsSigned(si32)) 600 return 2; 601 if (!mlirTypeIsAInteger(ui32) || !mlirIntegerTypeIsUnsigned(ui32)) 602 return 3; 603 if (mlirTypeEqual(i32, ui32) || mlirTypeEqual(i32, si32)) 604 return 4; 605 if (mlirIntegerTypeGetWidth(i32) != mlirIntegerTypeGetWidth(si32)) 606 return 5; 607 fprintf(stderr, "@types\n"); 608 mlirTypeDump(i32); 609 fprintf(stderr, "\n"); 610 mlirTypeDump(si32); 611 fprintf(stderr, "\n"); 612 mlirTypeDump(ui32); 613 fprintf(stderr, "\n"); 614 // CHECK-LABEL: @types 615 // CHECK: i32 616 // CHECK: si32 617 // CHECK: ui32 618 619 // Index type. 620 MlirType index = mlirIndexTypeGet(ctx); 621 if (!mlirTypeIsAIndex(index)) 622 return 6; 623 mlirTypeDump(index); 624 fprintf(stderr, "\n"); 625 // CHECK: index 626 627 // Floating-point types. 628 MlirType bf16 = mlirBF16TypeGet(ctx); 629 MlirType f16 = mlirF16TypeGet(ctx); 630 MlirType f32 = mlirF32TypeGet(ctx); 631 MlirType f64 = mlirF64TypeGet(ctx); 632 if (!mlirTypeIsABF16(bf16)) 633 return 7; 634 if (!mlirTypeIsAF16(f16)) 635 return 9; 636 if (!mlirTypeIsAF32(f32)) 637 return 10; 638 if (!mlirTypeIsAF64(f64)) 639 return 11; 640 mlirTypeDump(bf16); 641 fprintf(stderr, "\n"); 642 mlirTypeDump(f16); 643 fprintf(stderr, "\n"); 644 mlirTypeDump(f32); 645 fprintf(stderr, "\n"); 646 mlirTypeDump(f64); 647 fprintf(stderr, "\n"); 648 // CHECK: bf16 649 // CHECK: f16 650 // CHECK: f32 651 // CHECK: f64 652 653 // None type. 654 MlirType none = mlirNoneTypeGet(ctx); 655 if (!mlirTypeIsANone(none)) 656 return 12; 657 mlirTypeDump(none); 658 fprintf(stderr, "\n"); 659 // CHECK: none 660 661 // Complex type. 662 MlirType cplx = mlirComplexTypeGet(f32); 663 if (!mlirTypeIsAComplex(cplx) || 664 !mlirTypeEqual(mlirComplexTypeGetElementType(cplx), f32)) 665 return 13; 666 mlirTypeDump(cplx); 667 fprintf(stderr, "\n"); 668 // CHECK: complex<f32> 669 670 // Vector (and Shaped) type. ShapedType is a common base class for vectors, 671 // memrefs and tensors, one cannot create instances of this class so it is 672 // tested on an instance of vector type. 673 int64_t shape[] = {2, 3}; 674 MlirType vector = 675 mlirVectorTypeGet(sizeof(shape) / sizeof(int64_t), shape, f32); 676 if (!mlirTypeIsAVector(vector) || !mlirTypeIsAShaped(vector)) 677 return 14; 678 if (!mlirTypeEqual(mlirShapedTypeGetElementType(vector), f32) || 679 !mlirShapedTypeHasRank(vector) || mlirShapedTypeGetRank(vector) != 2 || 680 mlirShapedTypeGetDimSize(vector, 0) != 2 || 681 mlirShapedTypeIsDynamicDim(vector, 0) || 682 mlirShapedTypeGetDimSize(vector, 1) != 3 || 683 !mlirShapedTypeHasStaticShape(vector)) 684 return 15; 685 mlirTypeDump(vector); 686 fprintf(stderr, "\n"); 687 // CHECK: vector<2x3xf32> 688 689 // Ranked tensor type. 690 MlirType rankedTensor = mlirRankedTensorTypeGet( 691 sizeof(shape) / sizeof(int64_t), shape, f32, mlirAttributeGetNull()); 692 if (!mlirTypeIsATensor(rankedTensor) || 693 !mlirTypeIsARankedTensor(rankedTensor)) 694 return 16; 695 mlirTypeDump(rankedTensor); 696 fprintf(stderr, "\n"); 697 // CHECK: tensor<2x3xf32> 698 699 // Unranked tensor type. 700 MlirType unrankedTensor = mlirUnrankedTensorTypeGet(f32); 701 if (!mlirTypeIsATensor(unrankedTensor) || 702 !mlirTypeIsAUnrankedTensor(unrankedTensor) || 703 mlirShapedTypeHasRank(unrankedTensor)) 704 return 17; 705 mlirTypeDump(unrankedTensor); 706 fprintf(stderr, "\n"); 707 // CHECK: tensor<*xf32> 708 709 // MemRef type. 710 MlirAttribute memSpace2 = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 64), 2); 711 MlirType memRef = mlirMemRefTypeContiguousGet( 712 f32, sizeof(shape) / sizeof(int64_t), shape, memSpace2); 713 if (!mlirTypeIsAMemRef(memRef) || 714 mlirMemRefTypeGetNumAffineMaps(memRef) != 0 || 715 !mlirAttributeEqual(mlirMemRefTypeGetMemorySpace(memRef), memSpace2)) 716 return 18; 717 mlirTypeDump(memRef); 718 fprintf(stderr, "\n"); 719 // CHECK: memref<2x3xf32, 2> 720 721 // Unranked MemRef type. 722 MlirAttribute memSpace4 = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 64), 4); 723 MlirType unrankedMemRef = mlirUnrankedMemRefTypeGet(f32, memSpace4); 724 if (!mlirTypeIsAUnrankedMemRef(unrankedMemRef) || 725 mlirTypeIsAMemRef(unrankedMemRef) || 726 !mlirAttributeEqual(mlirUnrankedMemrefGetMemorySpace(unrankedMemRef), 727 memSpace4)) 728 return 19; 729 mlirTypeDump(unrankedMemRef); 730 fprintf(stderr, "\n"); 731 // CHECK: memref<*xf32, 4> 732 733 // Tuple type. 734 MlirType types[] = {unrankedMemRef, f32}; 735 MlirType tuple = mlirTupleTypeGet(ctx, 2, types); 736 if (!mlirTypeIsATuple(tuple) || mlirTupleTypeGetNumTypes(tuple) != 2 || 737 !mlirTypeEqual(mlirTupleTypeGetType(tuple, 0), unrankedMemRef) || 738 !mlirTypeEqual(mlirTupleTypeGetType(tuple, 1), f32)) 739 return 20; 740 mlirTypeDump(tuple); 741 fprintf(stderr, "\n"); 742 // CHECK: tuple<memref<*xf32, 4>, f32> 743 744 // Function type. 745 MlirType funcInputs[2] = {mlirIndexTypeGet(ctx), mlirIntegerTypeGet(ctx, 1)}; 746 MlirType funcResults[3] = {mlirIntegerTypeGet(ctx, 16), 747 mlirIntegerTypeGet(ctx, 32), 748 mlirIntegerTypeGet(ctx, 64)}; 749 MlirType funcType = mlirFunctionTypeGet(ctx, 2, funcInputs, 3, funcResults); 750 if (mlirFunctionTypeGetNumInputs(funcType) != 2) 751 return 21; 752 if (mlirFunctionTypeGetNumResults(funcType) != 3) 753 return 22; 754 if (!mlirTypeEqual(funcInputs[0], mlirFunctionTypeGetInput(funcType, 0)) || 755 !mlirTypeEqual(funcInputs[1], mlirFunctionTypeGetInput(funcType, 1))) 756 return 23; 757 if (!mlirTypeEqual(funcResults[0], mlirFunctionTypeGetResult(funcType, 0)) || 758 !mlirTypeEqual(funcResults[1], mlirFunctionTypeGetResult(funcType, 1)) || 759 !mlirTypeEqual(funcResults[2], mlirFunctionTypeGetResult(funcType, 2))) 760 return 24; 761 mlirTypeDump(funcType); 762 fprintf(stderr, "\n"); 763 // CHECK: (index, i1) -> (i16, i32, i64) 764 765 return 0; 766 } 767 768 void callbackSetFixedLengthString(const char *data, intptr_t len, 769 void *userData) { 770 strncpy(userData, data, len); 771 } 772 773 bool stringIsEqual(const char *lhs, MlirStringRef rhs) { 774 if (strlen(lhs) != rhs.length) { 775 return false; 776 } 777 return !strncmp(lhs, rhs.data, rhs.length); 778 } 779 780 int printBuiltinAttributes(MlirContext ctx) { 781 MlirAttribute floating = 782 mlirFloatAttrDoubleGet(ctx, mlirF64TypeGet(ctx), 2.0); 783 if (!mlirAttributeIsAFloat(floating) || 784 fabs(mlirFloatAttrGetValueDouble(floating) - 2.0) > 1E-6) 785 return 1; 786 fprintf(stderr, "@attrs\n"); 787 mlirAttributeDump(floating); 788 // CHECK-LABEL: @attrs 789 // CHECK: 2.000000e+00 : f64 790 791 // Exercise mlirAttributeGetType() just for the first one. 792 MlirType floatingType = mlirAttributeGetType(floating); 793 mlirTypeDump(floatingType); 794 // CHECK: f64 795 796 MlirAttribute integer = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 32), 42); 797 if (!mlirAttributeIsAInteger(integer) || 798 mlirIntegerAttrGetValueInt(integer) != 42) 799 return 2; 800 mlirAttributeDump(integer); 801 // CHECK: 42 : i32 802 803 MlirAttribute boolean = mlirBoolAttrGet(ctx, 1); 804 if (!mlirAttributeIsABool(boolean) || !mlirBoolAttrGetValue(boolean)) 805 return 3; 806 mlirAttributeDump(boolean); 807 // CHECK: true 808 809 const char data[] = "abcdefghijklmnopqestuvwxyz"; 810 MlirAttribute opaque = 811 mlirOpaqueAttrGet(ctx, mlirStringRefCreateFromCString("std"), 3, data, 812 mlirNoneTypeGet(ctx)); 813 if (!mlirAttributeIsAOpaque(opaque) || 814 !stringIsEqual("std", mlirOpaqueAttrGetDialectNamespace(opaque))) 815 return 4; 816 817 MlirStringRef opaqueData = mlirOpaqueAttrGetData(opaque); 818 if (opaqueData.length != 3 || 819 strncmp(data, opaqueData.data, opaqueData.length)) 820 return 5; 821 mlirAttributeDump(opaque); 822 // CHECK: #std.abc 823 824 MlirAttribute string = 825 mlirStringAttrGet(ctx, mlirStringRefCreate(data + 3, 2)); 826 if (!mlirAttributeIsAString(string)) 827 return 6; 828 829 MlirStringRef stringValue = mlirStringAttrGetValue(string); 830 if (stringValue.length != 2 || 831 strncmp(data + 3, stringValue.data, stringValue.length)) 832 return 7; 833 mlirAttributeDump(string); 834 // CHECK: "de" 835 836 MlirAttribute flatSymbolRef = 837 mlirFlatSymbolRefAttrGet(ctx, mlirStringRefCreate(data + 5, 3)); 838 if (!mlirAttributeIsAFlatSymbolRef(flatSymbolRef)) 839 return 8; 840 841 MlirStringRef flatSymbolRefValue = 842 mlirFlatSymbolRefAttrGetValue(flatSymbolRef); 843 if (flatSymbolRefValue.length != 3 || 844 strncmp(data + 5, flatSymbolRefValue.data, flatSymbolRefValue.length)) 845 return 9; 846 mlirAttributeDump(flatSymbolRef); 847 // CHECK: @fgh 848 849 MlirAttribute symbols[] = {flatSymbolRef, flatSymbolRef}; 850 MlirAttribute symbolRef = 851 mlirSymbolRefAttrGet(ctx, mlirStringRefCreate(data + 8, 2), 2, symbols); 852 if (!mlirAttributeIsASymbolRef(symbolRef) || 853 mlirSymbolRefAttrGetNumNestedReferences(symbolRef) != 2 || 854 !mlirAttributeEqual(mlirSymbolRefAttrGetNestedReference(symbolRef, 0), 855 flatSymbolRef) || 856 !mlirAttributeEqual(mlirSymbolRefAttrGetNestedReference(symbolRef, 1), 857 flatSymbolRef)) 858 return 10; 859 860 MlirStringRef symbolRefLeaf = mlirSymbolRefAttrGetLeafReference(symbolRef); 861 MlirStringRef symbolRefRoot = mlirSymbolRefAttrGetRootReference(symbolRef); 862 if (symbolRefLeaf.length != 3 || 863 strncmp(data + 5, symbolRefLeaf.data, symbolRefLeaf.length) || 864 symbolRefRoot.length != 2 || 865 strncmp(data + 8, symbolRefRoot.data, symbolRefRoot.length)) 866 return 11; 867 mlirAttributeDump(symbolRef); 868 // CHECK: @ij::@fgh::@fgh 869 870 MlirAttribute type = mlirTypeAttrGet(mlirF32TypeGet(ctx)); 871 if (!mlirAttributeIsAType(type) || 872 !mlirTypeEqual(mlirF32TypeGet(ctx), mlirTypeAttrGetValue(type))) 873 return 12; 874 mlirAttributeDump(type); 875 // CHECK: f32 876 877 MlirAttribute unit = mlirUnitAttrGet(ctx); 878 if (!mlirAttributeIsAUnit(unit)) 879 return 13; 880 mlirAttributeDump(unit); 881 // CHECK: unit 882 883 int64_t shape[] = {1, 2}; 884 885 int bools[] = {0, 1}; 886 uint32_t uints32[] = {0u, 1u}; 887 int32_t ints32[] = {0, 1}; 888 uint64_t uints64[] = {0u, 1u}; 889 int64_t ints64[] = {0, 1}; 890 float floats[] = {0.0f, 1.0f}; 891 double doubles[] = {0.0, 1.0}; 892 MlirAttribute encoding = mlirAttributeGetNull(); 893 MlirAttribute boolElements = mlirDenseElementsAttrBoolGet( 894 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 1), encoding), 895 2, bools); 896 MlirAttribute uint32Elements = mlirDenseElementsAttrUInt32Get( 897 mlirRankedTensorTypeGet(2, shape, 898 mlirIntegerTypeUnsignedGet(ctx, 32), encoding), 899 2, uints32); 900 MlirAttribute int32Elements = mlirDenseElementsAttrInt32Get( 901 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 32), encoding), 902 2, ints32); 903 MlirAttribute uint64Elements = mlirDenseElementsAttrUInt64Get( 904 mlirRankedTensorTypeGet(2, shape, 905 mlirIntegerTypeUnsignedGet(ctx, 64), encoding), 906 2, uints64); 907 MlirAttribute int64Elements = mlirDenseElementsAttrInt64Get( 908 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64), encoding), 909 2, ints64); 910 MlirAttribute floatElements = mlirDenseElementsAttrFloatGet( 911 mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx), encoding), 912 2, floats); 913 MlirAttribute doubleElements = mlirDenseElementsAttrDoubleGet( 914 mlirRankedTensorTypeGet(2, shape, mlirF64TypeGet(ctx), encoding), 915 2, doubles); 916 917 if (!mlirAttributeIsADenseElements(boolElements) || 918 !mlirAttributeIsADenseElements(uint32Elements) || 919 !mlirAttributeIsADenseElements(int32Elements) || 920 !mlirAttributeIsADenseElements(uint64Elements) || 921 !mlirAttributeIsADenseElements(int64Elements) || 922 !mlirAttributeIsADenseElements(floatElements) || 923 !mlirAttributeIsADenseElements(doubleElements)) 924 return 14; 925 926 if (mlirDenseElementsAttrGetBoolValue(boolElements, 1) != 1 || 927 mlirDenseElementsAttrGetUInt32Value(uint32Elements, 1) != 1 || 928 mlirDenseElementsAttrGetInt32Value(int32Elements, 1) != 1 || 929 mlirDenseElementsAttrGetUInt64Value(uint64Elements, 1) != 1 || 930 mlirDenseElementsAttrGetInt64Value(int64Elements, 1) != 1 || 931 fabsf(mlirDenseElementsAttrGetFloatValue(floatElements, 1) - 1.0f) > 932 1E-6f || 933 fabs(mlirDenseElementsAttrGetDoubleValue(doubleElements, 1) - 1.0) > 1E-6) 934 return 15; 935 936 mlirAttributeDump(boolElements); 937 mlirAttributeDump(uint32Elements); 938 mlirAttributeDump(int32Elements); 939 mlirAttributeDump(uint64Elements); 940 mlirAttributeDump(int64Elements); 941 mlirAttributeDump(floatElements); 942 mlirAttributeDump(doubleElements); 943 // CHECK: dense<{{\[}}[false, true]]> : tensor<1x2xi1> 944 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xui32> 945 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xi32> 946 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xui64> 947 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xi64> 948 // CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xf32> 949 // CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xf64> 950 951 MlirAttribute splatBool = mlirDenseElementsAttrBoolSplatGet( 952 mlirRankedTensorTypeGet(2, shape, 953 mlirIntegerTypeGet(ctx, 1), encoding), 1); 954 MlirAttribute splatUInt32 = mlirDenseElementsAttrUInt32SplatGet( 955 mlirRankedTensorTypeGet(2, shape, 956 mlirIntegerTypeGet(ctx, 32), encoding), 1); 957 MlirAttribute splatInt32 = mlirDenseElementsAttrInt32SplatGet( 958 mlirRankedTensorTypeGet(2, shape, 959 mlirIntegerTypeGet(ctx, 32), encoding), 1); 960 MlirAttribute splatUInt64 = mlirDenseElementsAttrUInt64SplatGet( 961 mlirRankedTensorTypeGet(2, shape, 962 mlirIntegerTypeGet(ctx, 64), encoding), 1); 963 MlirAttribute splatInt64 = mlirDenseElementsAttrInt64SplatGet( 964 mlirRankedTensorTypeGet(2, shape, 965 mlirIntegerTypeGet(ctx, 64), encoding), 1); 966 MlirAttribute splatFloat = mlirDenseElementsAttrFloatSplatGet( 967 mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx), encoding), 1.0f); 968 MlirAttribute splatDouble = mlirDenseElementsAttrDoubleSplatGet( 969 mlirRankedTensorTypeGet(2, shape, mlirF64TypeGet(ctx), encoding), 1.0); 970 971 if (!mlirAttributeIsADenseElements(splatBool) || 972 !mlirDenseElementsAttrIsSplat(splatBool) || 973 !mlirAttributeIsADenseElements(splatUInt32) || 974 !mlirDenseElementsAttrIsSplat(splatUInt32) || 975 !mlirAttributeIsADenseElements(splatInt32) || 976 !mlirDenseElementsAttrIsSplat(splatInt32) || 977 !mlirAttributeIsADenseElements(splatUInt64) || 978 !mlirDenseElementsAttrIsSplat(splatUInt64) || 979 !mlirAttributeIsADenseElements(splatInt64) || 980 !mlirDenseElementsAttrIsSplat(splatInt64) || 981 !mlirAttributeIsADenseElements(splatFloat) || 982 !mlirDenseElementsAttrIsSplat(splatFloat) || 983 !mlirAttributeIsADenseElements(splatDouble) || 984 !mlirDenseElementsAttrIsSplat(splatDouble)) 985 return 16; 986 987 if (mlirDenseElementsAttrGetBoolSplatValue(splatBool) != 1 || 988 mlirDenseElementsAttrGetUInt32SplatValue(splatUInt32) != 1 || 989 mlirDenseElementsAttrGetInt32SplatValue(splatInt32) != 1 || 990 mlirDenseElementsAttrGetUInt64SplatValue(splatUInt64) != 1 || 991 mlirDenseElementsAttrGetInt64SplatValue(splatInt64) != 1 || 992 fabsf(mlirDenseElementsAttrGetFloatSplatValue(splatFloat) - 1.0f) > 993 1E-6f || 994 fabs(mlirDenseElementsAttrGetDoubleSplatValue(splatDouble) - 1.0) > 1E-6) 995 return 17; 996 997 uint32_t *uint32RawData = 998 (uint32_t *)mlirDenseElementsAttrGetRawData(uint32Elements); 999 int32_t *int32RawData = 1000 (int32_t *)mlirDenseElementsAttrGetRawData(int32Elements); 1001 uint64_t *uint64RawData = 1002 (uint64_t *)mlirDenseElementsAttrGetRawData(uint64Elements); 1003 int64_t *int64RawData = 1004 (int64_t *)mlirDenseElementsAttrGetRawData(int64Elements); 1005 float *floatRawData = (float *)mlirDenseElementsAttrGetRawData(floatElements); 1006 double *doubleRawData = 1007 (double *)mlirDenseElementsAttrGetRawData(doubleElements); 1008 if (uint32RawData[0] != 0u || uint32RawData[1] != 1u || 1009 int32RawData[0] != 0 || int32RawData[1] != 1 || uint64RawData[0] != 0u || 1010 uint64RawData[1] != 1u || int64RawData[0] != 0 || int64RawData[1] != 1 || 1011 floatRawData[0] != 0.0f || floatRawData[1] != 1.0f || 1012 doubleRawData[0] != 0.0 || doubleRawData[1] != 1.0) 1013 return 18; 1014 1015 mlirAttributeDump(splatBool); 1016 mlirAttributeDump(splatUInt32); 1017 mlirAttributeDump(splatInt32); 1018 mlirAttributeDump(splatUInt64); 1019 mlirAttributeDump(splatInt64); 1020 mlirAttributeDump(splatFloat); 1021 mlirAttributeDump(splatDouble); 1022 // CHECK: dense<true> : tensor<1x2xi1> 1023 // CHECK: dense<1> : tensor<1x2xi32> 1024 // CHECK: dense<1> : tensor<1x2xi32> 1025 // CHECK: dense<1> : tensor<1x2xi64> 1026 // CHECK: dense<1> : tensor<1x2xi64> 1027 // CHECK: dense<1.000000e+00> : tensor<1x2xf32> 1028 // CHECK: dense<1.000000e+00> : tensor<1x2xf64> 1029 1030 mlirAttributeDump(mlirElementsAttrGetValue(floatElements, 2, uints64)); 1031 mlirAttributeDump(mlirElementsAttrGetValue(doubleElements, 2, uints64)); 1032 // CHECK: 1.000000e+00 : f32 1033 // CHECK: 1.000000e+00 : f64 1034 1035 int64_t indices[] = {4, 7}; 1036 int64_t two = 2; 1037 MlirAttribute indicesAttr = mlirDenseElementsAttrInt64Get( 1038 mlirRankedTensorTypeGet(1, &two, mlirIntegerTypeGet(ctx, 64), encoding), 1039 2, indices); 1040 MlirAttribute valuesAttr = mlirDenseElementsAttrFloatGet( 1041 mlirRankedTensorTypeGet(1, &two, mlirF32TypeGet(ctx), encoding), 1042 2, floats); 1043 MlirAttribute sparseAttr = mlirSparseElementsAttribute( 1044 mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx), encoding), 1045 indicesAttr, valuesAttr); 1046 mlirAttributeDump(sparseAttr); 1047 // CHECK: sparse<[4, 7], [0.000000e+00, 1.000000e+00]> : tensor<1x2xf32> 1048 1049 return 0; 1050 } 1051 1052 int printAffineMap(MlirContext ctx) { 1053 MlirAffineMap emptyAffineMap = mlirAffineMapEmptyGet(ctx); 1054 MlirAffineMap affineMap = mlirAffineMapZeroResultGet(ctx, 3, 2); 1055 MlirAffineMap constAffineMap = mlirAffineMapConstantGet(ctx, 2); 1056 MlirAffineMap multiDimIdentityAffineMap = 1057 mlirAffineMapMultiDimIdentityGet(ctx, 3); 1058 MlirAffineMap minorIdentityAffineMap = 1059 mlirAffineMapMinorIdentityGet(ctx, 3, 2); 1060 unsigned permutation[] = {1, 2, 0}; 1061 MlirAffineMap permutationAffineMap = mlirAffineMapPermutationGet( 1062 ctx, sizeof(permutation) / sizeof(unsigned), permutation); 1063 1064 fprintf(stderr, "@affineMap\n"); 1065 mlirAffineMapDump(emptyAffineMap); 1066 mlirAffineMapDump(affineMap); 1067 mlirAffineMapDump(constAffineMap); 1068 mlirAffineMapDump(multiDimIdentityAffineMap); 1069 mlirAffineMapDump(minorIdentityAffineMap); 1070 mlirAffineMapDump(permutationAffineMap); 1071 // CHECK-LABEL: @affineMap 1072 // CHECK: () -> () 1073 // CHECK: (d0, d1, d2)[s0, s1] -> () 1074 // CHECK: () -> (2) 1075 // CHECK: (d0, d1, d2) -> (d0, d1, d2) 1076 // CHECK: (d0, d1, d2) -> (d1, d2) 1077 // CHECK: (d0, d1, d2) -> (d1, d2, d0) 1078 1079 if (!mlirAffineMapIsIdentity(emptyAffineMap) || 1080 mlirAffineMapIsIdentity(affineMap) || 1081 mlirAffineMapIsIdentity(constAffineMap) || 1082 !mlirAffineMapIsIdentity(multiDimIdentityAffineMap) || 1083 mlirAffineMapIsIdentity(minorIdentityAffineMap) || 1084 mlirAffineMapIsIdentity(permutationAffineMap)) 1085 return 1; 1086 1087 if (!mlirAffineMapIsMinorIdentity(emptyAffineMap) || 1088 mlirAffineMapIsMinorIdentity(affineMap) || 1089 !mlirAffineMapIsMinorIdentity(multiDimIdentityAffineMap) || 1090 !mlirAffineMapIsMinorIdentity(minorIdentityAffineMap) || 1091 mlirAffineMapIsMinorIdentity(permutationAffineMap)) 1092 return 2; 1093 1094 if (!mlirAffineMapIsEmpty(emptyAffineMap) || 1095 mlirAffineMapIsEmpty(affineMap) || mlirAffineMapIsEmpty(constAffineMap) || 1096 mlirAffineMapIsEmpty(multiDimIdentityAffineMap) || 1097 mlirAffineMapIsEmpty(minorIdentityAffineMap) || 1098 mlirAffineMapIsEmpty(permutationAffineMap)) 1099 return 3; 1100 1101 if (mlirAffineMapIsSingleConstant(emptyAffineMap) || 1102 mlirAffineMapIsSingleConstant(affineMap) || 1103 !mlirAffineMapIsSingleConstant(constAffineMap) || 1104 mlirAffineMapIsSingleConstant(multiDimIdentityAffineMap) || 1105 mlirAffineMapIsSingleConstant(minorIdentityAffineMap) || 1106 mlirAffineMapIsSingleConstant(permutationAffineMap)) 1107 return 4; 1108 1109 if (mlirAffineMapGetSingleConstantResult(constAffineMap) != 2) 1110 return 5; 1111 1112 if (mlirAffineMapGetNumDims(emptyAffineMap) != 0 || 1113 mlirAffineMapGetNumDims(affineMap) != 3 || 1114 mlirAffineMapGetNumDims(constAffineMap) != 0 || 1115 mlirAffineMapGetNumDims(multiDimIdentityAffineMap) != 3 || 1116 mlirAffineMapGetNumDims(minorIdentityAffineMap) != 3 || 1117 mlirAffineMapGetNumDims(permutationAffineMap) != 3) 1118 return 6; 1119 1120 if (mlirAffineMapGetNumSymbols(emptyAffineMap) != 0 || 1121 mlirAffineMapGetNumSymbols(affineMap) != 2 || 1122 mlirAffineMapGetNumSymbols(constAffineMap) != 0 || 1123 mlirAffineMapGetNumSymbols(multiDimIdentityAffineMap) != 0 || 1124 mlirAffineMapGetNumSymbols(minorIdentityAffineMap) != 0 || 1125 mlirAffineMapGetNumSymbols(permutationAffineMap) != 0) 1126 return 7; 1127 1128 if (mlirAffineMapGetNumResults(emptyAffineMap) != 0 || 1129 mlirAffineMapGetNumResults(affineMap) != 0 || 1130 mlirAffineMapGetNumResults(constAffineMap) != 1 || 1131 mlirAffineMapGetNumResults(multiDimIdentityAffineMap) != 3 || 1132 mlirAffineMapGetNumResults(minorIdentityAffineMap) != 2 || 1133 mlirAffineMapGetNumResults(permutationAffineMap) != 3) 1134 return 8; 1135 1136 if (mlirAffineMapGetNumInputs(emptyAffineMap) != 0 || 1137 mlirAffineMapGetNumInputs(affineMap) != 5 || 1138 mlirAffineMapGetNumInputs(constAffineMap) != 0 || 1139 mlirAffineMapGetNumInputs(multiDimIdentityAffineMap) != 3 || 1140 mlirAffineMapGetNumInputs(minorIdentityAffineMap) != 3 || 1141 mlirAffineMapGetNumInputs(permutationAffineMap) != 3) 1142 return 9; 1143 1144 if (!mlirAffineMapIsProjectedPermutation(emptyAffineMap) || 1145 !mlirAffineMapIsPermutation(emptyAffineMap) || 1146 mlirAffineMapIsProjectedPermutation(affineMap) || 1147 mlirAffineMapIsPermutation(affineMap) || 1148 mlirAffineMapIsProjectedPermutation(constAffineMap) || 1149 mlirAffineMapIsPermutation(constAffineMap) || 1150 !mlirAffineMapIsProjectedPermutation(multiDimIdentityAffineMap) || 1151 !mlirAffineMapIsPermutation(multiDimIdentityAffineMap) || 1152 !mlirAffineMapIsProjectedPermutation(minorIdentityAffineMap) || 1153 mlirAffineMapIsPermutation(minorIdentityAffineMap) || 1154 !mlirAffineMapIsProjectedPermutation(permutationAffineMap) || 1155 !mlirAffineMapIsPermutation(permutationAffineMap)) 1156 return 10; 1157 1158 intptr_t sub[] = {1}; 1159 1160 MlirAffineMap subMap = mlirAffineMapGetSubMap( 1161 multiDimIdentityAffineMap, sizeof(sub) / sizeof(intptr_t), sub); 1162 MlirAffineMap majorSubMap = 1163 mlirAffineMapGetMajorSubMap(multiDimIdentityAffineMap, 1); 1164 MlirAffineMap minorSubMap = 1165 mlirAffineMapGetMinorSubMap(multiDimIdentityAffineMap, 1); 1166 1167 mlirAffineMapDump(subMap); 1168 mlirAffineMapDump(majorSubMap); 1169 mlirAffineMapDump(minorSubMap); 1170 // CHECK: (d0, d1, d2) -> (d1) 1171 // CHECK: (d0, d1, d2) -> (d0) 1172 // CHECK: (d0, d1, d2) -> (d2) 1173 1174 return 0; 1175 } 1176 1177 int printAffineExpr(MlirContext ctx) { 1178 MlirAffineExpr affineDimExpr = mlirAffineDimExprGet(ctx, 5); 1179 MlirAffineExpr affineSymbolExpr = mlirAffineSymbolExprGet(ctx, 5); 1180 MlirAffineExpr affineConstantExpr = mlirAffineConstantExprGet(ctx, 5); 1181 MlirAffineExpr affineAddExpr = 1182 mlirAffineAddExprGet(affineDimExpr, affineSymbolExpr); 1183 MlirAffineExpr affineMulExpr = 1184 mlirAffineMulExprGet(affineDimExpr, affineSymbolExpr); 1185 MlirAffineExpr affineModExpr = 1186 mlirAffineModExprGet(affineDimExpr, affineSymbolExpr); 1187 MlirAffineExpr affineFloorDivExpr = 1188 mlirAffineFloorDivExprGet(affineDimExpr, affineSymbolExpr); 1189 MlirAffineExpr affineCeilDivExpr = 1190 mlirAffineCeilDivExprGet(affineDimExpr, affineSymbolExpr); 1191 1192 // Tests mlirAffineExprDump. 1193 fprintf(stderr, "@affineExpr\n"); 1194 mlirAffineExprDump(affineDimExpr); 1195 mlirAffineExprDump(affineSymbolExpr); 1196 mlirAffineExprDump(affineConstantExpr); 1197 mlirAffineExprDump(affineAddExpr); 1198 mlirAffineExprDump(affineMulExpr); 1199 mlirAffineExprDump(affineModExpr); 1200 mlirAffineExprDump(affineFloorDivExpr); 1201 mlirAffineExprDump(affineCeilDivExpr); 1202 // CHECK-LABEL: @affineExpr 1203 // CHECK: d5 1204 // CHECK: s5 1205 // CHECK: 5 1206 // CHECK: d5 + s5 1207 // CHECK: d5 * s5 1208 // CHECK: d5 mod s5 1209 // CHECK: d5 floordiv s5 1210 // CHECK: d5 ceildiv s5 1211 1212 // Tests methods of affine binary operation expression, takes add expression 1213 // as an example. 1214 mlirAffineExprDump(mlirAffineBinaryOpExprGetLHS(affineAddExpr)); 1215 mlirAffineExprDump(mlirAffineBinaryOpExprGetRHS(affineAddExpr)); 1216 // CHECK: d5 1217 // CHECK: s5 1218 1219 // Tests methods of affine dimension expression. 1220 if (mlirAffineDimExprGetPosition(affineDimExpr) != 5) 1221 return 1; 1222 1223 // Tests methods of affine symbol expression. 1224 if (mlirAffineSymbolExprGetPosition(affineSymbolExpr) != 5) 1225 return 2; 1226 1227 // Tests methods of affine constant expression. 1228 if (mlirAffineConstantExprGetValue(affineConstantExpr) != 5) 1229 return 3; 1230 1231 // Tests methods of affine expression. 1232 if (mlirAffineExprIsSymbolicOrConstant(affineDimExpr) || 1233 !mlirAffineExprIsSymbolicOrConstant(affineSymbolExpr) || 1234 !mlirAffineExprIsSymbolicOrConstant(affineConstantExpr) || 1235 mlirAffineExprIsSymbolicOrConstant(affineAddExpr) || 1236 mlirAffineExprIsSymbolicOrConstant(affineMulExpr) || 1237 mlirAffineExprIsSymbolicOrConstant(affineModExpr) || 1238 mlirAffineExprIsSymbolicOrConstant(affineFloorDivExpr) || 1239 mlirAffineExprIsSymbolicOrConstant(affineCeilDivExpr)) 1240 return 4; 1241 1242 if (!mlirAffineExprIsPureAffine(affineDimExpr) || 1243 !mlirAffineExprIsPureAffine(affineSymbolExpr) || 1244 !mlirAffineExprIsPureAffine(affineConstantExpr) || 1245 !mlirAffineExprIsPureAffine(affineAddExpr) || 1246 mlirAffineExprIsPureAffine(affineMulExpr) || 1247 mlirAffineExprIsPureAffine(affineModExpr) || 1248 mlirAffineExprIsPureAffine(affineFloorDivExpr) || 1249 mlirAffineExprIsPureAffine(affineCeilDivExpr)) 1250 return 5; 1251 1252 if (mlirAffineExprGetLargestKnownDivisor(affineDimExpr) != 1 || 1253 mlirAffineExprGetLargestKnownDivisor(affineSymbolExpr) != 1 || 1254 mlirAffineExprGetLargestKnownDivisor(affineConstantExpr) != 5 || 1255 mlirAffineExprGetLargestKnownDivisor(affineAddExpr) != 1 || 1256 mlirAffineExprGetLargestKnownDivisor(affineMulExpr) != 1 || 1257 mlirAffineExprGetLargestKnownDivisor(affineModExpr) != 1 || 1258 mlirAffineExprGetLargestKnownDivisor(affineFloorDivExpr) != 1 || 1259 mlirAffineExprGetLargestKnownDivisor(affineCeilDivExpr) != 1) 1260 return 6; 1261 1262 if (!mlirAffineExprIsMultipleOf(affineDimExpr, 1) || 1263 !mlirAffineExprIsMultipleOf(affineSymbolExpr, 1) || 1264 !mlirAffineExprIsMultipleOf(affineConstantExpr, 5) || 1265 !mlirAffineExprIsMultipleOf(affineAddExpr, 1) || 1266 !mlirAffineExprIsMultipleOf(affineMulExpr, 1) || 1267 !mlirAffineExprIsMultipleOf(affineModExpr, 1) || 1268 !mlirAffineExprIsMultipleOf(affineFloorDivExpr, 1) || 1269 !mlirAffineExprIsMultipleOf(affineCeilDivExpr, 1)) 1270 return 7; 1271 1272 if (!mlirAffineExprIsFunctionOfDim(affineDimExpr, 5) || 1273 mlirAffineExprIsFunctionOfDim(affineSymbolExpr, 5) || 1274 mlirAffineExprIsFunctionOfDim(affineConstantExpr, 5) || 1275 !mlirAffineExprIsFunctionOfDim(affineAddExpr, 5) || 1276 !mlirAffineExprIsFunctionOfDim(affineMulExpr, 5) || 1277 !mlirAffineExprIsFunctionOfDim(affineModExpr, 5) || 1278 !mlirAffineExprIsFunctionOfDim(affineFloorDivExpr, 5) || 1279 !mlirAffineExprIsFunctionOfDim(affineCeilDivExpr, 5)) 1280 return 8; 1281 1282 // Tests 'IsA' methods of affine binary operation expression. 1283 if (!mlirAffineExprIsAAdd(affineAddExpr)) 1284 return 9; 1285 1286 if (!mlirAffineExprIsAMul(affineMulExpr)) 1287 return 10; 1288 1289 if (!mlirAffineExprIsAMod(affineModExpr)) 1290 return 11; 1291 1292 if (!mlirAffineExprIsAFloorDiv(affineFloorDivExpr)) 1293 return 12; 1294 1295 if (!mlirAffineExprIsACeilDiv(affineCeilDivExpr)) 1296 return 13; 1297 1298 if (!mlirAffineExprIsABinary(affineAddExpr)) 1299 return 14; 1300 1301 // Test other 'IsA' method on affine expressions. 1302 if (!mlirAffineExprIsAConstant(affineConstantExpr)) 1303 return 15; 1304 1305 if (!mlirAffineExprIsADim(affineDimExpr)) 1306 return 16; 1307 1308 if (!mlirAffineExprIsASymbol(affineSymbolExpr)) 1309 return 17; 1310 1311 // Test equality and nullity. 1312 MlirAffineExpr otherDimExpr = mlirAffineDimExprGet(ctx, 5); 1313 if (!mlirAffineExprEqual(affineDimExpr, otherDimExpr)) 1314 return 18; 1315 1316 if (mlirAffineExprIsNull(affineDimExpr)) 1317 return 19; 1318 1319 return 0; 1320 } 1321 1322 int affineMapFromExprs(MlirContext ctx) { 1323 MlirAffineExpr affineDimExpr = mlirAffineDimExprGet(ctx, 0); 1324 MlirAffineExpr affineSymbolExpr = mlirAffineSymbolExprGet(ctx, 1); 1325 MlirAffineExpr exprs[] = {affineDimExpr, affineSymbolExpr}; 1326 MlirAffineMap map = mlirAffineMapGet(ctx, 3, 3, 2, exprs); 1327 1328 // CHECK-LABEL: @affineMapFromExprs 1329 fprintf(stderr, "@affineMapFromExprs"); 1330 // CHECK: (d0, d1, d2)[s0, s1, s2] -> (d0, s1) 1331 mlirAffineMapDump(map); 1332 1333 if (mlirAffineMapGetNumResults(map) != 2) 1334 return 1; 1335 1336 if (!mlirAffineExprEqual(mlirAffineMapGetResult(map, 0), affineDimExpr)) 1337 return 2; 1338 1339 if (!mlirAffineExprEqual(mlirAffineMapGetResult(map, 1), affineSymbolExpr)) 1340 return 3; 1341 1342 return 0; 1343 } 1344 1345 int printIntegerSet(MlirContext ctx) { 1346 MlirIntegerSet emptySet = mlirIntegerSetEmptyGet(ctx, 2, 1); 1347 1348 // CHECK-LABEL: @printIntegerSet 1349 fprintf(stderr, "@printIntegerSet"); 1350 1351 // CHECK: (d0, d1)[s0] : (1 == 0) 1352 mlirIntegerSetDump(emptySet); 1353 1354 if (!mlirIntegerSetIsCanonicalEmpty(emptySet)) 1355 return 1; 1356 1357 MlirIntegerSet anotherEmptySet = mlirIntegerSetEmptyGet(ctx, 2, 1); 1358 if (!mlirIntegerSetEqual(emptySet, anotherEmptySet)) 1359 return 2; 1360 1361 // Construct a set constrained by: 1362 // d0 - s0 == 0, 1363 // d1 - 42 >= 0. 1364 MlirAffineExpr negOne = mlirAffineConstantExprGet(ctx, -1); 1365 MlirAffineExpr negFortyTwo = mlirAffineConstantExprGet(ctx, -42); 1366 MlirAffineExpr d0 = mlirAffineDimExprGet(ctx, 0); 1367 MlirAffineExpr d1 = mlirAffineDimExprGet(ctx, 1); 1368 MlirAffineExpr s0 = mlirAffineSymbolExprGet(ctx, 0); 1369 MlirAffineExpr negS0 = mlirAffineMulExprGet(negOne, s0); 1370 MlirAffineExpr d0minusS0 = mlirAffineAddExprGet(d0, negS0); 1371 MlirAffineExpr d1minus42 = mlirAffineAddExprGet(d1, negFortyTwo); 1372 MlirAffineExpr constraints[] = {d0minusS0, d1minus42}; 1373 bool flags[] = {true, false}; 1374 1375 MlirIntegerSet set = mlirIntegerSetGet(ctx, 2, 1, 2, constraints, flags); 1376 // CHECK: (d0, d1)[s0] : ( 1377 // CHECK-DAG: d0 - s0 == 0 1378 // CHECK-DAG: d1 - 42 >= 0 1379 mlirIntegerSetDump(set); 1380 1381 // Transform d1 into s0. 1382 MlirAffineExpr s1 = mlirAffineSymbolExprGet(ctx, 1); 1383 MlirAffineExpr repl[] = {d0, s1}; 1384 MlirIntegerSet replaced = mlirIntegerSetReplaceGet(set, repl, &s0, 1, 2); 1385 // CHECK: (d0)[s0, s1] : ( 1386 // CHECK-DAG: d0 - s0 == 0 1387 // CHECK-DAG: s1 - 42 >= 0 1388 mlirIntegerSetDump(replaced); 1389 1390 if (mlirIntegerSetGetNumDims(set) != 2) 1391 return 3; 1392 if (mlirIntegerSetGetNumDims(replaced) != 1) 1393 return 4; 1394 1395 if (mlirIntegerSetGetNumSymbols(set) != 1) 1396 return 5; 1397 if (mlirIntegerSetGetNumSymbols(replaced) != 2) 1398 return 6; 1399 1400 if (mlirIntegerSetGetNumInputs(set) != 3) 1401 return 7; 1402 1403 if (mlirIntegerSetGetNumConstraints(set) != 2) 1404 return 8; 1405 1406 if (mlirIntegerSetGetNumEqualities(set) != 1) 1407 return 9; 1408 1409 if (mlirIntegerSetGetNumInequalities(set) != 1) 1410 return 10; 1411 1412 MlirAffineExpr cstr1 = mlirIntegerSetGetConstraint(set, 0); 1413 MlirAffineExpr cstr2 = mlirIntegerSetGetConstraint(set, 1); 1414 bool isEq1 = mlirIntegerSetIsConstraintEq(set, 0); 1415 bool isEq2 = mlirIntegerSetIsConstraintEq(set, 1); 1416 if (!mlirAffineExprEqual(cstr1, isEq1 ? d0minusS0 : d1minus42)) 1417 return 11; 1418 if (!mlirAffineExprEqual(cstr2, isEq2 ? d0minusS0 : d1minus42)) 1419 return 12; 1420 1421 return 0; 1422 } 1423 1424 int registerOnlyStd() { 1425 MlirContext ctx = mlirContextCreate(); 1426 // The built-in dialect is always loaded. 1427 if (mlirContextGetNumLoadedDialects(ctx) != 1) 1428 return 1; 1429 1430 MlirDialectHandle stdHandle = mlirGetDialectHandle__std__(); 1431 1432 MlirDialect std = mlirContextGetOrLoadDialect( 1433 ctx, mlirDialectHandleGetNamespace(stdHandle)); 1434 if (!mlirDialectIsNull(std)) 1435 return 2; 1436 1437 mlirDialectHandleRegisterDialect(stdHandle, ctx); 1438 1439 std = mlirContextGetOrLoadDialect(ctx, 1440 mlirDialectHandleGetNamespace(stdHandle)); 1441 if (mlirDialectIsNull(std)) 1442 return 3; 1443 1444 MlirDialect alsoStd = mlirDialectHandleLoadDialect(stdHandle, ctx); 1445 if (!mlirDialectEqual(std, alsoStd)) 1446 return 4; 1447 1448 MlirStringRef stdNs = mlirDialectGetNamespace(std); 1449 MlirStringRef alsoStdNs = mlirDialectHandleGetNamespace(stdHandle); 1450 if (stdNs.length != alsoStdNs.length || 1451 strncmp(stdNs.data, alsoStdNs.data, stdNs.length)) 1452 return 5; 1453 1454 fprintf(stderr, "@registration\n"); 1455 // CHECK-LABEL: @registration 1456 1457 // CHECK: std.cond_br is_registered: 1 1458 fprintf(stderr, "std.cond_br is_registered: %d\n", 1459 mlirContextIsRegisteredOperation( 1460 ctx, mlirStringRefCreateFromCString("std.cond_br"))); 1461 1462 // CHECK: std.not_existing_op is_registered: 0 1463 fprintf(stderr, "std.not_existing_op is_registered: %d\n", 1464 mlirContextIsRegisteredOperation( 1465 ctx, mlirStringRefCreateFromCString("std.not_existing_op"))); 1466 1467 // CHECK: not_existing_dialect.not_existing_op is_registered: 0 1468 fprintf(stderr, "not_existing_dialect.not_existing_op is_registered: %d\n", 1469 mlirContextIsRegisteredOperation( 1470 ctx, mlirStringRefCreateFromCString( 1471 "not_existing_dialect.not_existing_op"))); 1472 1473 return 0; 1474 } 1475 1476 /// Tests backreference APIs 1477 static int testBackreferences() { 1478 fprintf(stderr, "@test_backreferences\n"); 1479 1480 MlirContext ctx = mlirContextCreate(); 1481 mlirContextSetAllowUnregisteredDialects(ctx, true); 1482 MlirLocation loc = mlirLocationUnknownGet(ctx); 1483 1484 MlirOperationState opState = 1485 mlirOperationStateGet(mlirStringRefCreateFromCString("invalid.op"), loc); 1486 MlirRegion region = mlirRegionCreate(); 1487 MlirBlock block = mlirBlockCreate(0, NULL); 1488 mlirRegionAppendOwnedBlock(region, block); 1489 mlirOperationStateAddOwnedRegions(&opState, 1, ®ion); 1490 MlirOperation op = mlirOperationCreate(&opState); 1491 MlirIdentifier ident = 1492 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("identifier")); 1493 1494 if (!mlirContextEqual(ctx, mlirOperationGetContext(op))) { 1495 fprintf(stderr, "ERROR: Getting context from operation failed\n"); 1496 return 1; 1497 } 1498 if (!mlirOperationEqual(op, mlirBlockGetParentOperation(block))) { 1499 fprintf(stderr, "ERROR: Getting parent operation from block failed\n"); 1500 return 2; 1501 } 1502 if (!mlirContextEqual(ctx, mlirIdentifierGetContext(ident))) { 1503 fprintf(stderr, "ERROR: Getting context from identifier failed\n"); 1504 return 3; 1505 } 1506 1507 mlirOperationDestroy(op); 1508 mlirContextDestroy(ctx); 1509 1510 // CHECK-LABEL: @test_backreferences 1511 return 0; 1512 } 1513 1514 /// Tests operand APIs. 1515 int testOperands() { 1516 fprintf(stderr, "@testOperands\n"); 1517 // CHECK-LABEL: @testOperands 1518 1519 MlirContext ctx = mlirContextCreate(); 1520 MlirLocation loc = mlirLocationUnknownGet(ctx); 1521 MlirType indexType = mlirIndexTypeGet(ctx); 1522 1523 // Create some constants to use as operands. 1524 MlirAttribute indexZeroLiteral = 1525 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("0 : index")); 1526 MlirNamedAttribute indexZeroValueAttr = mlirNamedAttributeGet( 1527 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), 1528 indexZeroLiteral); 1529 MlirOperationState constZeroState = mlirOperationStateGet( 1530 mlirStringRefCreateFromCString("std.constant"), loc); 1531 mlirOperationStateAddResults(&constZeroState, 1, &indexType); 1532 mlirOperationStateAddAttributes(&constZeroState, 1, &indexZeroValueAttr); 1533 MlirOperation constZero = mlirOperationCreate(&constZeroState); 1534 MlirValue constZeroValue = mlirOperationGetResult(constZero, 0); 1535 1536 MlirAttribute indexOneLiteral = 1537 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("1 : index")); 1538 MlirNamedAttribute indexOneValueAttr = mlirNamedAttributeGet( 1539 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), 1540 indexOneLiteral); 1541 MlirOperationState constOneState = mlirOperationStateGet( 1542 mlirStringRefCreateFromCString("std.constant"), loc); 1543 mlirOperationStateAddResults(&constOneState, 1, &indexType); 1544 mlirOperationStateAddAttributes(&constOneState, 1, &indexOneValueAttr); 1545 MlirOperation constOne = mlirOperationCreate(&constOneState); 1546 MlirValue constOneValue = mlirOperationGetResult(constOne, 0); 1547 1548 // Create the operation under test. 1549 MlirOperationState opState = 1550 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op"), loc); 1551 MlirValue initialOperands[] = {constZeroValue}; 1552 mlirOperationStateAddOperands(&opState, 1, initialOperands); 1553 MlirOperation op = mlirOperationCreate(&opState); 1554 1555 // Test operand APIs. 1556 intptr_t numOperands = mlirOperationGetNumOperands(op); 1557 fprintf(stderr, "Num Operands: %ld\n", numOperands); 1558 // CHECK: Num Operands: 1 1559 1560 MlirValue opOperand = mlirOperationGetOperand(op, 0); 1561 fprintf(stderr, "Original operand: "); 1562 mlirValuePrint(opOperand, printToStderr, NULL); 1563 // CHECK: Original operand: {{.+}} {value = 0 : index} 1564 1565 mlirOperationSetOperand(op, 0, constOneValue); 1566 opOperand = mlirOperationGetOperand(op, 0); 1567 fprintf(stderr, "Updated operand: "); 1568 mlirValuePrint(opOperand, printToStderr, NULL); 1569 // CHECK: Updated operand: {{.+}} {value = 1 : index} 1570 1571 mlirOperationDestroy(op); 1572 mlirOperationDestroy(constZero); 1573 mlirOperationDestroy(constOne); 1574 mlirContextDestroy(ctx); 1575 1576 return 0; 1577 } 1578 1579 // Wraps a diagnostic into additional text we can match against. 1580 MlirLogicalResult errorHandler(MlirDiagnostic diagnostic, void *userData) { 1581 fprintf(stderr, "processing diagnostic (userData: %ld) <<\n", (long)userData); 1582 mlirDiagnosticPrint(diagnostic, printToStderr, NULL); 1583 fprintf(stderr, "\n"); 1584 MlirLocation loc = mlirDiagnosticGetLocation(diagnostic); 1585 mlirLocationPrint(loc, printToStderr, NULL); 1586 assert(mlirDiagnosticGetNumNotes(diagnostic) == 0); 1587 fprintf(stderr, "\n>> end of diagnostic (userData: %ld)\n", (long)userData); 1588 return mlirLogicalResultSuccess(); 1589 } 1590 1591 // Logs when the delete user data callback is called 1592 static void deleteUserData(void *userData) { 1593 fprintf(stderr, "deleting user data (userData: %ld)\n", (long)userData); 1594 } 1595 1596 void testDiagnostics() { 1597 MlirContext ctx = mlirContextCreate(); 1598 MlirDiagnosticHandlerID id = mlirContextAttachDiagnosticHandler( 1599 ctx, errorHandler, (void *)42, deleteUserData); 1600 fprintf(stderr, "@test_diagnostics\n"); 1601 MlirLocation unknownLoc = mlirLocationUnknownGet(ctx); 1602 mlirEmitError(unknownLoc, "test diagnostics"); 1603 MlirLocation fileLineColLoc = mlirLocationFileLineColGet( 1604 ctx, mlirStringRefCreateFromCString("file.c"), 1, 2); 1605 mlirEmitError(fileLineColLoc, "test diagnostics"); 1606 MlirLocation callSiteLoc = mlirLocationCallSiteGet( 1607 mlirLocationFileLineColGet( 1608 ctx, mlirStringRefCreateFromCString("other-file.c"), 2, 3), 1609 fileLineColLoc); 1610 mlirEmitError(callSiteLoc, "test diagnostics"); 1611 mlirContextDetachDiagnosticHandler(ctx, id); 1612 mlirEmitError(unknownLoc, "more test diagnostics"); 1613 // CHECK-LABEL: @test_diagnostics 1614 // CHECK: processing diagnostic (userData: 42) << 1615 // CHECK: test diagnostics 1616 // CHECK: loc(unknown) 1617 // CHECK: >> end of diagnostic (userData: 42) 1618 // CHECK: processing diagnostic (userData: 42) << 1619 // CHECK: test diagnostics 1620 // CHECK: loc("file.c":1:2) 1621 // CHECK: >> end of diagnostic (userData: 42) 1622 // CHECK: processing diagnostic (userData: 42) << 1623 // CHECK: test diagnostics 1624 // CHECK: loc(callsite("other-file.c":2:3 at "file.c":1:2)) 1625 // CHECK: >> end of diagnostic (userData: 42) 1626 // CHECK: deleting user data (userData: 42) 1627 // CHECK-NOT: processing diagnostic 1628 // CHECK: more test diagnostics 1629 } 1630 1631 int main() { 1632 MlirContext ctx = mlirContextCreate(); 1633 mlirRegisterAllDialects(ctx); 1634 if (constructAndTraverseIr(ctx)) 1635 return 1; 1636 buildWithInsertionsAndPrint(ctx); 1637 if (createOperationWithTypeInference(ctx)) 1638 return 2; 1639 1640 if (printBuiltinTypes(ctx)) 1641 return 3; 1642 if (printBuiltinAttributes(ctx)) 1643 return 4; 1644 if (printAffineMap(ctx)) 1645 return 5; 1646 if (printAffineExpr(ctx)) 1647 return 6; 1648 if (affineMapFromExprs(ctx)) 1649 return 7; 1650 if (printIntegerSet(ctx)) 1651 return 8; 1652 if (registerOnlyStd()) 1653 return 9; 1654 if (testBackreferences()) 1655 return 10; 1656 if (testOperands()) 1657 return 11; 1658 1659 mlirContextDestroy(ctx); 1660 1661 testDiagnostics(); 1662 return 0; 1663 } 1664