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/Func.h" 20 #include "mlir-c/IntegerSet.h" 21 #include "mlir-c/RegisterEverything.h" 22 #include "mlir-c/Support.h" 23 24 #include <assert.h> 25 #include <inttypes.h> 26 #include <math.h> 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <string.h> 30 31 static void registerAllUpstreamDialects(MlirContext ctx) { 32 MlirDialectRegistry registry = mlirDialectRegistryCreate(); 33 mlirRegisterAllDialects(registry); 34 mlirContextAppendDialectRegistry(ctx, registry); 35 mlirDialectRegistryDestroy(registry); 36 } 37 38 struct ResourceDeleteUserData { 39 const char *name; 40 }; 41 static struct ResourceDeleteUserData resourceI64BlobUserData = { 42 "resource_i64_blob"}; 43 static void reportResourceDelete(void *userData, const void *data, size_t size, 44 size_t align) { 45 fprintf(stderr, "reportResourceDelete: %s\n", 46 ((struct ResourceDeleteUserData *)userData)->name); 47 } 48 49 void populateLoopBody(MlirContext ctx, MlirBlock loopBody, 50 MlirLocation location, MlirBlock funcBody) { 51 MlirValue iv = mlirBlockGetArgument(loopBody, 0); 52 MlirValue funcArg0 = mlirBlockGetArgument(funcBody, 0); 53 MlirValue funcArg1 = mlirBlockGetArgument(funcBody, 1); 54 MlirType f32Type = 55 mlirTypeParseGet(ctx, mlirStringRefCreateFromCString("f32")); 56 57 MlirOperationState loadLHSState = mlirOperationStateGet( 58 mlirStringRefCreateFromCString("memref.load"), location); 59 MlirValue loadLHSOperands[] = {funcArg0, iv}; 60 mlirOperationStateAddOperands(&loadLHSState, 2, loadLHSOperands); 61 mlirOperationStateAddResults(&loadLHSState, 1, &f32Type); 62 MlirOperation loadLHS = mlirOperationCreate(&loadLHSState); 63 mlirBlockAppendOwnedOperation(loopBody, loadLHS); 64 65 MlirOperationState loadRHSState = mlirOperationStateGet( 66 mlirStringRefCreateFromCString("memref.load"), location); 67 MlirValue loadRHSOperands[] = {funcArg1, iv}; 68 mlirOperationStateAddOperands(&loadRHSState, 2, loadRHSOperands); 69 mlirOperationStateAddResults(&loadRHSState, 1, &f32Type); 70 MlirOperation loadRHS = mlirOperationCreate(&loadRHSState); 71 mlirBlockAppendOwnedOperation(loopBody, loadRHS); 72 73 MlirOperationState addState = mlirOperationStateGet( 74 mlirStringRefCreateFromCString("arith.addf"), location); 75 MlirValue addOperands[] = {mlirOperationGetResult(loadLHS, 0), 76 mlirOperationGetResult(loadRHS, 0)}; 77 mlirOperationStateAddOperands(&addState, 2, addOperands); 78 mlirOperationStateAddResults(&addState, 1, &f32Type); 79 MlirOperation add = mlirOperationCreate(&addState); 80 mlirBlockAppendOwnedOperation(loopBody, add); 81 82 MlirOperationState storeState = mlirOperationStateGet( 83 mlirStringRefCreateFromCString("memref.store"), location); 84 MlirValue storeOperands[] = {mlirOperationGetResult(add, 0), funcArg0, iv}; 85 mlirOperationStateAddOperands(&storeState, 3, storeOperands); 86 MlirOperation store = mlirOperationCreate(&storeState); 87 mlirBlockAppendOwnedOperation(loopBody, store); 88 89 MlirOperationState yieldState = mlirOperationStateGet( 90 mlirStringRefCreateFromCString("scf.yield"), location); 91 MlirOperation yield = mlirOperationCreate(&yieldState); 92 mlirBlockAppendOwnedOperation(loopBody, yield); 93 } 94 95 MlirModule makeAndDumpAdd(MlirContext ctx, MlirLocation location) { 96 MlirModule moduleOp = mlirModuleCreateEmpty(location); 97 MlirBlock moduleBody = mlirModuleGetBody(moduleOp); 98 99 MlirType memrefType = 100 mlirTypeParseGet(ctx, mlirStringRefCreateFromCString("memref<?xf32>")); 101 MlirType funcBodyArgTypes[] = {memrefType, memrefType}; 102 MlirLocation funcBodyArgLocs[] = {location, location}; 103 MlirRegion funcBodyRegion = mlirRegionCreate(); 104 MlirBlock funcBody = 105 mlirBlockCreate(sizeof(funcBodyArgTypes) / sizeof(MlirType), 106 funcBodyArgTypes, funcBodyArgLocs); 107 mlirRegionAppendOwnedBlock(funcBodyRegion, funcBody); 108 109 MlirAttribute funcTypeAttr = mlirAttributeParseGet( 110 ctx, 111 mlirStringRefCreateFromCString("(memref<?xf32>, memref<?xf32>) -> ()")); 112 MlirAttribute funcNameAttr = 113 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("\"add\"")); 114 MlirNamedAttribute funcAttrs[] = { 115 mlirNamedAttributeGet( 116 mlirIdentifierGet(ctx, 117 mlirStringRefCreateFromCString("function_type")), 118 funcTypeAttr), 119 mlirNamedAttributeGet( 120 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("sym_name")), 121 funcNameAttr)}; 122 MlirOperationState funcState = mlirOperationStateGet( 123 mlirStringRefCreateFromCString("func.func"), location); 124 mlirOperationStateAddAttributes(&funcState, 2, funcAttrs); 125 mlirOperationStateAddOwnedRegions(&funcState, 1, &funcBodyRegion); 126 MlirOperation func = mlirOperationCreate(&funcState); 127 mlirBlockInsertOwnedOperation(moduleBody, 0, func); 128 129 MlirType indexType = 130 mlirTypeParseGet(ctx, mlirStringRefCreateFromCString("index")); 131 MlirAttribute indexZeroLiteral = 132 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("0 : index")); 133 MlirNamedAttribute indexZeroValueAttr = mlirNamedAttributeGet( 134 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), 135 indexZeroLiteral); 136 MlirOperationState constZeroState = mlirOperationStateGet( 137 mlirStringRefCreateFromCString("arith.constant"), location); 138 mlirOperationStateAddResults(&constZeroState, 1, &indexType); 139 mlirOperationStateAddAttributes(&constZeroState, 1, &indexZeroValueAttr); 140 MlirOperation constZero = mlirOperationCreate(&constZeroState); 141 mlirBlockAppendOwnedOperation(funcBody, constZero); 142 143 MlirValue funcArg0 = mlirBlockGetArgument(funcBody, 0); 144 MlirValue constZeroValue = mlirOperationGetResult(constZero, 0); 145 MlirValue dimOperands[] = {funcArg0, constZeroValue}; 146 MlirOperationState dimState = mlirOperationStateGet( 147 mlirStringRefCreateFromCString("memref.dim"), location); 148 mlirOperationStateAddOperands(&dimState, 2, dimOperands); 149 mlirOperationStateAddResults(&dimState, 1, &indexType); 150 MlirOperation dim = mlirOperationCreate(&dimState); 151 mlirBlockAppendOwnedOperation(funcBody, dim); 152 153 MlirRegion loopBodyRegion = mlirRegionCreate(); 154 MlirBlock loopBody = mlirBlockCreate(0, NULL, NULL); 155 mlirBlockAddArgument(loopBody, indexType, location); 156 mlirRegionAppendOwnedBlock(loopBodyRegion, loopBody); 157 158 MlirAttribute indexOneLiteral = 159 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("1 : index")); 160 MlirNamedAttribute indexOneValueAttr = mlirNamedAttributeGet( 161 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), 162 indexOneLiteral); 163 MlirOperationState constOneState = mlirOperationStateGet( 164 mlirStringRefCreateFromCString("arith.constant"), location); 165 mlirOperationStateAddResults(&constOneState, 1, &indexType); 166 mlirOperationStateAddAttributes(&constOneState, 1, &indexOneValueAttr); 167 MlirOperation constOne = mlirOperationCreate(&constOneState); 168 mlirBlockAppendOwnedOperation(funcBody, constOne); 169 170 MlirValue dimValue = mlirOperationGetResult(dim, 0); 171 MlirValue constOneValue = mlirOperationGetResult(constOne, 0); 172 MlirValue loopOperands[] = {constZeroValue, dimValue, constOneValue}; 173 MlirOperationState loopState = mlirOperationStateGet( 174 mlirStringRefCreateFromCString("scf.for"), location); 175 mlirOperationStateAddOperands(&loopState, 3, loopOperands); 176 mlirOperationStateAddOwnedRegions(&loopState, 1, &loopBodyRegion); 177 MlirOperation loop = mlirOperationCreate(&loopState); 178 mlirBlockAppendOwnedOperation(funcBody, loop); 179 180 populateLoopBody(ctx, loopBody, location, funcBody); 181 182 MlirOperationState retState = mlirOperationStateGet( 183 mlirStringRefCreateFromCString("func.return"), location); 184 MlirOperation ret = mlirOperationCreate(&retState); 185 mlirBlockAppendOwnedOperation(funcBody, ret); 186 187 MlirOperation module = mlirModuleGetOperation(moduleOp); 188 mlirOperationDump(module); 189 // clang-format off 190 // CHECK: module { 191 // CHECK: func @add(%[[ARG0:.*]]: memref<?xf32>, %[[ARG1:.*]]: memref<?xf32>) { 192 // CHECK: %[[C0:.*]] = arith.constant 0 : index 193 // CHECK: %[[DIM:.*]] = memref.dim %[[ARG0]], %[[C0]] : memref<?xf32> 194 // CHECK: %[[C1:.*]] = arith.constant 1 : index 195 // CHECK: scf.for %[[I:.*]] = %[[C0]] to %[[DIM]] step %[[C1]] { 196 // CHECK: %[[LHS:.*]] = memref.load %[[ARG0]][%[[I]]] : memref<?xf32> 197 // CHECK: %[[RHS:.*]] = memref.load %[[ARG1]][%[[I]]] : memref<?xf32> 198 // CHECK: %[[SUM:.*]] = arith.addf %[[LHS]], %[[RHS]] : f32 199 // CHECK: memref.store %[[SUM]], %[[ARG0]][%[[I]]] : memref<?xf32> 200 // CHECK: } 201 // CHECK: return 202 // CHECK: } 203 // CHECK: } 204 // clang-format on 205 206 return moduleOp; 207 } 208 209 struct OpListNode { 210 MlirOperation op; 211 struct OpListNode *next; 212 }; 213 typedef struct OpListNode OpListNode; 214 215 struct ModuleStats { 216 unsigned numOperations; 217 unsigned numAttributes; 218 unsigned numBlocks; 219 unsigned numRegions; 220 unsigned numValues; 221 unsigned numBlockArguments; 222 unsigned numOpResults; 223 }; 224 typedef struct ModuleStats ModuleStats; 225 226 int collectStatsSingle(OpListNode *head, ModuleStats *stats) { 227 MlirOperation operation = head->op; 228 stats->numOperations += 1; 229 stats->numValues += mlirOperationGetNumResults(operation); 230 stats->numAttributes += mlirOperationGetNumAttributes(operation); 231 232 unsigned numRegions = mlirOperationGetNumRegions(operation); 233 234 stats->numRegions += numRegions; 235 236 intptr_t numResults = mlirOperationGetNumResults(operation); 237 for (intptr_t i = 0; i < numResults; ++i) { 238 MlirValue result = mlirOperationGetResult(operation, i); 239 if (!mlirValueIsAOpResult(result)) 240 return 1; 241 if (mlirValueIsABlockArgument(result)) 242 return 2; 243 if (!mlirOperationEqual(operation, mlirOpResultGetOwner(result))) 244 return 3; 245 if (i != mlirOpResultGetResultNumber(result)) 246 return 4; 247 ++stats->numOpResults; 248 } 249 250 MlirRegion region = mlirOperationGetFirstRegion(operation); 251 while (!mlirRegionIsNull(region)) { 252 for (MlirBlock block = mlirRegionGetFirstBlock(region); 253 !mlirBlockIsNull(block); block = mlirBlockGetNextInRegion(block)) { 254 ++stats->numBlocks; 255 intptr_t numArgs = mlirBlockGetNumArguments(block); 256 stats->numValues += numArgs; 257 for (intptr_t j = 0; j < numArgs; ++j) { 258 MlirValue arg = mlirBlockGetArgument(block, j); 259 if (!mlirValueIsABlockArgument(arg)) 260 return 5; 261 if (mlirValueIsAOpResult(arg)) 262 return 6; 263 if (!mlirBlockEqual(block, mlirBlockArgumentGetOwner(arg))) 264 return 7; 265 if (j != mlirBlockArgumentGetArgNumber(arg)) 266 return 8; 267 ++stats->numBlockArguments; 268 } 269 270 for (MlirOperation child = mlirBlockGetFirstOperation(block); 271 !mlirOperationIsNull(child); 272 child = mlirOperationGetNextInBlock(child)) { 273 OpListNode *node = malloc(sizeof(OpListNode)); 274 node->op = child; 275 node->next = head->next; 276 head->next = node; 277 } 278 } 279 region = mlirRegionGetNextInOperation(region); 280 } 281 return 0; 282 } 283 284 int collectStats(MlirOperation operation) { 285 OpListNode *head = malloc(sizeof(OpListNode)); 286 head->op = operation; 287 head->next = NULL; 288 289 ModuleStats stats; 290 stats.numOperations = 0; 291 stats.numAttributes = 0; 292 stats.numBlocks = 0; 293 stats.numRegions = 0; 294 stats.numValues = 0; 295 stats.numBlockArguments = 0; 296 stats.numOpResults = 0; 297 298 do { 299 int retval = collectStatsSingle(head, &stats); 300 if (retval) { 301 free(head); 302 return retval; 303 } 304 OpListNode *next = head->next; 305 free(head); 306 head = next; 307 } while (head); 308 309 if (stats.numValues != stats.numBlockArguments + stats.numOpResults) 310 return 100; 311 312 fprintf(stderr, "@stats\n"); 313 fprintf(stderr, "Number of operations: %u\n", stats.numOperations); 314 fprintf(stderr, "Number of attributes: %u\n", stats.numAttributes); 315 fprintf(stderr, "Number of blocks: %u\n", stats.numBlocks); 316 fprintf(stderr, "Number of regions: %u\n", stats.numRegions); 317 fprintf(stderr, "Number of values: %u\n", stats.numValues); 318 fprintf(stderr, "Number of block arguments: %u\n", stats.numBlockArguments); 319 fprintf(stderr, "Number of op results: %u\n", stats.numOpResults); 320 // clang-format off 321 // CHECK-LABEL: @stats 322 // CHECK: Number of operations: 12 323 // CHECK: Number of attributes: 5 324 // CHECK: Number of blocks: 3 325 // CHECK: Number of regions: 3 326 // CHECK: Number of values: 9 327 // CHECK: Number of block arguments: 3 328 // CHECK: Number of op results: 6 329 // clang-format on 330 return 0; 331 } 332 333 static void printToStderr(MlirStringRef str, void *userData) { 334 (void)userData; 335 fwrite(str.data, 1, str.length, stderr); 336 } 337 338 static void printFirstOfEach(MlirContext ctx, MlirOperation operation) { 339 // Assuming we are given a module, go to the first operation of the first 340 // function. 341 MlirRegion region = mlirOperationGetRegion(operation, 0); 342 MlirBlock block = mlirRegionGetFirstBlock(region); 343 MlirOperation function = mlirBlockGetFirstOperation(block); 344 region = mlirOperationGetRegion(function, 0); 345 MlirOperation parentOperation = function; 346 block = mlirRegionGetFirstBlock(region); 347 operation = mlirBlockGetFirstOperation(block); 348 assert(mlirModuleIsNull(mlirModuleFromOperation(operation))); 349 350 // Verify that parent operation and block report correctly. 351 // CHECK: Parent operation eq: 1 352 fprintf(stderr, "Parent operation eq: %d\n", 353 mlirOperationEqual(mlirOperationGetParentOperation(operation), 354 parentOperation)); 355 // CHECK: Block eq: 1 356 fprintf(stderr, "Block eq: %d\n", 357 mlirBlockEqual(mlirOperationGetBlock(operation), block)); 358 // CHECK: Block parent operation eq: 1 359 fprintf( 360 stderr, "Block parent operation eq: %d\n", 361 mlirOperationEqual(mlirBlockGetParentOperation(block), parentOperation)); 362 // CHECK: Block parent region eq: 1 363 fprintf(stderr, "Block parent region eq: %d\n", 364 mlirRegionEqual(mlirBlockGetParentRegion(block), region)); 365 366 // In the module we created, the first operation of the first function is 367 // an "memref.dim", which has an attribute and a single result that we can 368 // use to test the printing mechanism. 369 mlirBlockPrint(block, printToStderr, NULL); 370 fprintf(stderr, "\n"); 371 fprintf(stderr, "First operation: "); 372 mlirOperationPrint(operation, printToStderr, NULL); 373 fprintf(stderr, "\n"); 374 // clang-format off 375 // CHECK: %[[C0:.*]] = arith.constant 0 : index 376 // CHECK: %[[DIM:.*]] = memref.dim %{{.*}}, %[[C0]] : memref<?xf32> 377 // CHECK: %[[C1:.*]] = arith.constant 1 : index 378 // CHECK: scf.for %[[I:.*]] = %[[C0]] to %[[DIM]] step %[[C1]] { 379 // CHECK: %[[LHS:.*]] = memref.load %{{.*}}[%[[I]]] : memref<?xf32> 380 // CHECK: %[[RHS:.*]] = memref.load %{{.*}}[%[[I]]] : memref<?xf32> 381 // CHECK: %[[SUM:.*]] = arith.addf %[[LHS]], %[[RHS]] : f32 382 // CHECK: memref.store %[[SUM]], %{{.*}}[%[[I]]] : memref<?xf32> 383 // CHECK: } 384 // CHECK: return 385 // CHECK: First operation: {{.*}} = arith.constant 0 : index 386 // clang-format on 387 388 // Get the operation name and print it. 389 MlirIdentifier ident = mlirOperationGetName(operation); 390 MlirStringRef identStr = mlirIdentifierStr(ident); 391 fprintf(stderr, "Operation name: '"); 392 for (size_t i = 0; i < identStr.length; ++i) 393 fputc(identStr.data[i], stderr); 394 fprintf(stderr, "'\n"); 395 // CHECK: Operation name: 'arith.constant' 396 397 // Get the identifier again and verify equal. 398 MlirIdentifier identAgain = mlirIdentifierGet(ctx, identStr); 399 fprintf(stderr, "Identifier equal: %d\n", 400 mlirIdentifierEqual(ident, identAgain)); 401 // CHECK: Identifier equal: 1 402 403 // Get the block terminator and print it. 404 MlirOperation terminator = mlirBlockGetTerminator(block); 405 fprintf(stderr, "Terminator: "); 406 mlirOperationPrint(terminator, printToStderr, NULL); 407 fprintf(stderr, "\n"); 408 // CHECK: Terminator: func.return 409 410 // Get the attribute by name. 411 bool hasValueAttr = mlirOperationHasInherentAttributeByName( 412 operation, mlirStringRefCreateFromCString("value")); 413 if (hasValueAttr) 414 // CHECK: Has attr "value" 415 fprintf(stderr, "Has attr \"value\""); 416 417 MlirAttribute valueAttr0 = mlirOperationGetInherentAttributeByName( 418 operation, mlirStringRefCreateFromCString("value")); 419 fprintf(stderr, "Get attr \"value\": "); 420 mlirAttributePrint(valueAttr0, printToStderr, NULL); 421 fprintf(stderr, "\n"); 422 // CHECK: Get attr "value": 0 : index 423 424 // Get a non-existing attribute and assert that it is null (sanity). 425 fprintf(stderr, "does_not_exist is null: %d\n", 426 mlirAttributeIsNull(mlirOperationGetDiscardableAttributeByName( 427 operation, mlirStringRefCreateFromCString("does_not_exist")))); 428 // CHECK: does_not_exist is null: 1 429 430 // Get result 0 and its type. 431 MlirValue value = mlirOperationGetResult(operation, 0); 432 fprintf(stderr, "Result 0: "); 433 mlirValuePrint(value, printToStderr, NULL); 434 fprintf(stderr, "\n"); 435 fprintf(stderr, "Value is null: %d\n", mlirValueIsNull(value)); 436 // CHECK: Result 0: {{.*}} = arith.constant 0 : index 437 // CHECK: Value is null: 0 438 439 MlirType type = mlirValueGetType(value); 440 fprintf(stderr, "Result 0 type: "); 441 mlirTypePrint(type, printToStderr, NULL); 442 fprintf(stderr, "\n"); 443 // CHECK: Result 0 type: index 444 445 // Set a discardable attribute. 446 mlirOperationSetDiscardableAttributeByName( 447 operation, mlirStringRefCreateFromCString("custom_attr"), 448 mlirBoolAttrGet(ctx, 1)); 449 fprintf(stderr, "Op with set attr: "); 450 mlirOperationPrint(operation, printToStderr, NULL); 451 fprintf(stderr, "\n"); 452 // CHECK: Op with set attr: {{.*}} {custom_attr = true} 453 454 // Remove the attribute. 455 fprintf(stderr, "Remove attr: %d\n", 456 mlirOperationRemoveDiscardableAttributeByName( 457 operation, mlirStringRefCreateFromCString("custom_attr"))); 458 fprintf(stderr, "Remove attr again: %d\n", 459 mlirOperationRemoveDiscardableAttributeByName( 460 operation, mlirStringRefCreateFromCString("custom_attr"))); 461 fprintf(stderr, "Removed attr is null: %d\n", 462 mlirAttributeIsNull(mlirOperationGetDiscardableAttributeByName( 463 operation, mlirStringRefCreateFromCString("custom_attr")))); 464 // CHECK: Remove attr: 1 465 // CHECK: Remove attr again: 0 466 // CHECK: Removed attr is null: 1 467 468 // Add a large attribute to verify printing flags. 469 int64_t eltsShape[] = {4}; 470 int32_t eltsData[] = {1, 2, 3, 4}; 471 mlirOperationSetDiscardableAttributeByName( 472 operation, mlirStringRefCreateFromCString("elts"), 473 mlirDenseElementsAttrInt32Get( 474 mlirRankedTensorTypeGet(1, eltsShape, mlirIntegerTypeGet(ctx, 32), 475 mlirAttributeGetNull()), 476 4, eltsData)); 477 MlirOpPrintingFlags flags = mlirOpPrintingFlagsCreate(); 478 mlirOpPrintingFlagsElideLargeElementsAttrs(flags, 2); 479 mlirOpPrintingFlagsPrintGenericOpForm(flags); 480 mlirOpPrintingFlagsEnableDebugInfo(flags, /*enable=*/1, /*prettyForm=*/0); 481 mlirOpPrintingFlagsUseLocalScope(flags); 482 fprintf(stderr, "Op print with all flags: "); 483 mlirOperationPrintWithFlags(operation, flags, printToStderr, NULL); 484 fprintf(stderr, "\n"); 485 fprintf(stderr, "Op print with state: "); 486 MlirAsmState state = mlirAsmStateCreateForOperation(parentOperation, flags); 487 mlirOperationPrintWithState(operation, state, printToStderr, NULL); 488 fprintf(stderr, "\n"); 489 // clang-format off 490 // CHECK: Op print with all flags: %{{.*}} = "arith.constant"() <{value = 0 : index}> {elts = dense_resource<__elided__> : tensor<4xi32>} : () -> index loc(unknown) 491 // clang-format on 492 493 mlirOpPrintingFlagsDestroy(flags); 494 flags = mlirOpPrintingFlagsCreate(); 495 mlirOpPrintingFlagsSkipRegions(flags); 496 fprintf(stderr, "Op print with skip regions flag: "); 497 mlirOperationPrintWithFlags(function, flags, printToStderr, NULL); 498 fprintf(stderr, "\n"); 499 // clang-format off 500 // CHECK: Op print with skip regions flag: func.func @add(%[[ARG0:.*]]: memref<?xf32>, %[[ARG1:.*]]: memref<?xf32>) 501 // CHECK-NOT: constant 502 // CHECK-NOT: return 503 // clang-format on 504 505 fprintf(stderr, "With state: |"); 506 mlirValuePrintAsOperand(value, state, printToStderr, NULL); 507 // CHECK: With state: |%0| 508 fprintf(stderr, "|\n"); 509 mlirAsmStateDestroy(state); 510 511 mlirOpPrintingFlagsDestroy(flags); 512 } 513 514 static int constructAndTraverseIr(MlirContext ctx) { 515 MlirLocation location = mlirLocationUnknownGet(ctx); 516 517 MlirModule moduleOp = makeAndDumpAdd(ctx, location); 518 MlirOperation module = mlirModuleGetOperation(moduleOp); 519 assert(!mlirModuleIsNull(mlirModuleFromOperation(module))); 520 521 int errcode = collectStats(module); 522 if (errcode) 523 return errcode; 524 525 printFirstOfEach(ctx, module); 526 527 mlirModuleDestroy(moduleOp); 528 return 0; 529 } 530 531 /// Creates an operation with a region containing multiple blocks with 532 /// operations and dumps it. The blocks and operations are inserted using 533 /// block/operation-relative API and their final order is checked. 534 static void buildWithInsertionsAndPrint(MlirContext ctx) { 535 MlirLocation loc = mlirLocationUnknownGet(ctx); 536 mlirContextSetAllowUnregisteredDialects(ctx, true); 537 538 MlirRegion owningRegion = mlirRegionCreate(); 539 MlirBlock nullBlock = mlirRegionGetFirstBlock(owningRegion); 540 MlirOperationState state = mlirOperationStateGet( 541 mlirStringRefCreateFromCString("insertion.order.test"), loc); 542 mlirOperationStateAddOwnedRegions(&state, 1, &owningRegion); 543 MlirOperation op = mlirOperationCreate(&state); 544 MlirRegion region = mlirOperationGetRegion(op, 0); 545 546 // Use integer types of different bitwidth as block arguments in order to 547 // differentiate blocks. 548 MlirType i1 = mlirIntegerTypeGet(ctx, 1); 549 MlirType i2 = mlirIntegerTypeGet(ctx, 2); 550 MlirType i3 = mlirIntegerTypeGet(ctx, 3); 551 MlirType i4 = mlirIntegerTypeGet(ctx, 4); 552 MlirType i5 = mlirIntegerTypeGet(ctx, 5); 553 MlirBlock block1 = mlirBlockCreate(1, &i1, &loc); 554 MlirBlock block2 = mlirBlockCreate(1, &i2, &loc); 555 MlirBlock block3 = mlirBlockCreate(1, &i3, &loc); 556 MlirBlock block4 = mlirBlockCreate(1, &i4, &loc); 557 MlirBlock block5 = mlirBlockCreate(1, &i5, &loc); 558 // Insert blocks so as to obtain the 1-2-3-4 order, 559 mlirRegionInsertOwnedBlockBefore(region, nullBlock, block3); 560 mlirRegionInsertOwnedBlockBefore(region, block3, block2); 561 mlirRegionInsertOwnedBlockAfter(region, nullBlock, block1); 562 mlirRegionInsertOwnedBlockAfter(region, block3, block4); 563 mlirRegionInsertOwnedBlockBefore(region, block3, block5); 564 565 MlirOperationState op1State = 566 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op1"), loc); 567 MlirOperationState op2State = 568 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op2"), loc); 569 MlirOperationState op3State = 570 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op3"), loc); 571 MlirOperationState op4State = 572 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op4"), loc); 573 MlirOperationState op5State = 574 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op5"), loc); 575 MlirOperationState op6State = 576 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op6"), loc); 577 MlirOperationState op7State = 578 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op7"), loc); 579 MlirOperationState op8State = 580 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op8"), loc); 581 MlirOperation op1 = mlirOperationCreate(&op1State); 582 MlirOperation op2 = mlirOperationCreate(&op2State); 583 MlirOperation op3 = mlirOperationCreate(&op3State); 584 MlirOperation op4 = mlirOperationCreate(&op4State); 585 MlirOperation op5 = mlirOperationCreate(&op5State); 586 MlirOperation op6 = mlirOperationCreate(&op6State); 587 MlirOperation op7 = mlirOperationCreate(&op7State); 588 MlirOperation op8 = mlirOperationCreate(&op8State); 589 590 // Insert operations in the first block so as to obtain the 1-2-3-4 order. 591 MlirOperation nullOperation = mlirBlockGetFirstOperation(block1); 592 assert(mlirOperationIsNull(nullOperation)); 593 mlirBlockInsertOwnedOperationBefore(block1, nullOperation, op3); 594 mlirBlockInsertOwnedOperationBefore(block1, op3, op2); 595 mlirBlockInsertOwnedOperationAfter(block1, nullOperation, op1); 596 mlirBlockInsertOwnedOperationAfter(block1, op3, op4); 597 598 // Append operations to the rest of blocks to make them non-empty and thus 599 // printable. 600 mlirBlockAppendOwnedOperation(block2, op5); 601 mlirBlockAppendOwnedOperation(block3, op6); 602 mlirBlockAppendOwnedOperation(block4, op7); 603 mlirBlockAppendOwnedOperation(block5, op8); 604 605 // Remove block5. 606 mlirBlockDetach(block5); 607 mlirBlockDestroy(block5); 608 609 mlirOperationDump(op); 610 mlirOperationDestroy(op); 611 mlirContextSetAllowUnregisteredDialects(ctx, false); 612 // clang-format off 613 // CHECK-LABEL: "insertion.order.test" 614 // CHECK: ^{{.*}}(%{{.*}}: i1 615 // CHECK: "dummy.op1" 616 // CHECK-NEXT: "dummy.op2" 617 // CHECK-NEXT: "dummy.op3" 618 // CHECK-NEXT: "dummy.op4" 619 // CHECK: ^{{.*}}(%{{.*}}: i2 620 // CHECK: "dummy.op5" 621 // CHECK-NOT: ^{{.*}}(%{{.*}}: i5 622 // CHECK-NOT: "dummy.op8" 623 // CHECK: ^{{.*}}(%{{.*}}: i3 624 // CHECK: "dummy.op6" 625 // CHECK: ^{{.*}}(%{{.*}}: i4 626 // CHECK: "dummy.op7" 627 // clang-format on 628 } 629 630 /// Creates operations with type inference and tests various failure modes. 631 static int createOperationWithTypeInference(MlirContext ctx) { 632 MlirLocation loc = mlirLocationUnknownGet(ctx); 633 MlirAttribute iAttr = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 32), 4); 634 635 // The shape.const_size op implements result type inference and is only used 636 // for that reason. 637 MlirOperationState state = mlirOperationStateGet( 638 mlirStringRefCreateFromCString("shape.const_size"), loc); 639 MlirNamedAttribute valueAttr = mlirNamedAttributeGet( 640 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), iAttr); 641 mlirOperationStateAddAttributes(&state, 1, &valueAttr); 642 mlirOperationStateEnableResultTypeInference(&state); 643 644 // Expect result type inference to succeed. 645 MlirOperation op = mlirOperationCreate(&state); 646 if (mlirOperationIsNull(op)) { 647 fprintf(stderr, "ERROR: Result type inference unexpectedly failed"); 648 return 1; 649 } 650 651 // CHECK: RESULT_TYPE_INFERENCE: !shape.size 652 fprintf(stderr, "RESULT_TYPE_INFERENCE: "); 653 mlirTypeDump(mlirValueGetType(mlirOperationGetResult(op, 0))); 654 fprintf(stderr, "\n"); 655 mlirOperationDestroy(op); 656 return 0; 657 } 658 659 /// Dumps instances of all builtin types to check that C API works correctly. 660 /// Additionally, performs simple identity checks that a builtin type 661 /// constructed with C API can be inspected and has the expected type. The 662 /// latter achieves full coverage of C API for builtin types. Returns 0 on 663 /// success and a non-zero error code on failure. 664 static int printBuiltinTypes(MlirContext ctx) { 665 // Integer types. 666 MlirType i32 = mlirIntegerTypeGet(ctx, 32); 667 MlirType si32 = mlirIntegerTypeSignedGet(ctx, 32); 668 MlirType ui32 = mlirIntegerTypeUnsignedGet(ctx, 32); 669 if (!mlirTypeIsAInteger(i32) || mlirTypeIsAF32(i32)) 670 return 1; 671 if (!mlirTypeIsAInteger(si32) || !mlirIntegerTypeIsSigned(si32)) 672 return 2; 673 if (!mlirTypeIsAInteger(ui32) || !mlirIntegerTypeIsUnsigned(ui32)) 674 return 3; 675 if (mlirTypeEqual(i32, ui32) || mlirTypeEqual(i32, si32)) 676 return 4; 677 if (mlirIntegerTypeGetWidth(i32) != mlirIntegerTypeGetWidth(si32)) 678 return 5; 679 fprintf(stderr, "@types\n"); 680 mlirTypeDump(i32); 681 fprintf(stderr, "\n"); 682 mlirTypeDump(si32); 683 fprintf(stderr, "\n"); 684 mlirTypeDump(ui32); 685 fprintf(stderr, "\n"); 686 // CHECK-LABEL: @types 687 // CHECK: i32 688 // CHECK: si32 689 // CHECK: ui32 690 691 // Index type. 692 MlirType index = mlirIndexTypeGet(ctx); 693 if (!mlirTypeIsAIndex(index)) 694 return 6; 695 mlirTypeDump(index); 696 fprintf(stderr, "\n"); 697 // CHECK: index 698 699 // Floating-point types. 700 MlirType bf16 = mlirBF16TypeGet(ctx); 701 MlirType f16 = mlirF16TypeGet(ctx); 702 MlirType f32 = mlirF32TypeGet(ctx); 703 MlirType f64 = mlirF64TypeGet(ctx); 704 if (!mlirTypeIsABF16(bf16)) 705 return 7; 706 if (!mlirTypeIsAF16(f16)) 707 return 9; 708 if (!mlirTypeIsAF32(f32)) 709 return 10; 710 if (!mlirTypeIsAF64(f64)) 711 return 11; 712 mlirTypeDump(bf16); 713 fprintf(stderr, "\n"); 714 mlirTypeDump(f16); 715 fprintf(stderr, "\n"); 716 mlirTypeDump(f32); 717 fprintf(stderr, "\n"); 718 mlirTypeDump(f64); 719 fprintf(stderr, "\n"); 720 // CHECK: bf16 721 // CHECK: f16 722 // CHECK: f32 723 // CHECK: f64 724 725 // None type. 726 MlirType none = mlirNoneTypeGet(ctx); 727 if (!mlirTypeIsANone(none)) 728 return 12; 729 mlirTypeDump(none); 730 fprintf(stderr, "\n"); 731 // CHECK: none 732 733 // Complex type. 734 MlirType cplx = mlirComplexTypeGet(f32); 735 if (!mlirTypeIsAComplex(cplx) || 736 !mlirTypeEqual(mlirComplexTypeGetElementType(cplx), f32)) 737 return 13; 738 mlirTypeDump(cplx); 739 fprintf(stderr, "\n"); 740 // CHECK: complex<f32> 741 742 // Vector (and Shaped) type. ShapedType is a common base class for vectors, 743 // memrefs and tensors, one cannot create instances of this class so it is 744 // tested on an instance of vector type. 745 int64_t shape[] = {2, 3}; 746 MlirType vector = 747 mlirVectorTypeGet(sizeof(shape) / sizeof(int64_t), shape, f32); 748 if (!mlirTypeIsAVector(vector) || !mlirTypeIsAShaped(vector)) 749 return 14; 750 if (!mlirTypeEqual(mlirShapedTypeGetElementType(vector), f32) || 751 !mlirShapedTypeHasRank(vector) || mlirShapedTypeGetRank(vector) != 2 || 752 mlirShapedTypeGetDimSize(vector, 0) != 2 || 753 mlirShapedTypeIsDynamicDim(vector, 0) || 754 mlirShapedTypeGetDimSize(vector, 1) != 3 || 755 !mlirShapedTypeHasStaticShape(vector)) 756 return 15; 757 mlirTypeDump(vector); 758 fprintf(stderr, "\n"); 759 // CHECK: vector<2x3xf32> 760 761 // Scalable vector type. 762 bool scalable[] = {false, true}; 763 MlirType scalableVector = mlirVectorTypeGetScalable( 764 sizeof(shape) / sizeof(int64_t), shape, scalable, f32); 765 if (!mlirTypeIsAVector(scalableVector)) 766 return 16; 767 if (!mlirVectorTypeIsScalable(scalableVector) || 768 mlirVectorTypeIsDimScalable(scalableVector, 0) || 769 !mlirVectorTypeIsDimScalable(scalableVector, 1)) 770 return 17; 771 mlirTypeDump(scalableVector); 772 fprintf(stderr, "\n"); 773 // CHECK: vector<2x[3]xf32> 774 775 // Ranked tensor type. 776 MlirType rankedTensor = mlirRankedTensorTypeGet( 777 sizeof(shape) / sizeof(int64_t), shape, f32, mlirAttributeGetNull()); 778 if (!mlirTypeIsATensor(rankedTensor) || 779 !mlirTypeIsARankedTensor(rankedTensor) || 780 !mlirAttributeIsNull(mlirRankedTensorTypeGetEncoding(rankedTensor))) 781 return 18; 782 mlirTypeDump(rankedTensor); 783 fprintf(stderr, "\n"); 784 // CHECK: tensor<2x3xf32> 785 786 // Unranked tensor type. 787 MlirType unrankedTensor = mlirUnrankedTensorTypeGet(f32); 788 if (!mlirTypeIsATensor(unrankedTensor) || 789 !mlirTypeIsAUnrankedTensor(unrankedTensor) || 790 mlirShapedTypeHasRank(unrankedTensor)) 791 return 19; 792 mlirTypeDump(unrankedTensor); 793 fprintf(stderr, "\n"); 794 // CHECK: tensor<*xf32> 795 796 // MemRef type. 797 MlirAttribute memSpace2 = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 64), 2); 798 MlirType memRef = mlirMemRefTypeContiguousGet( 799 f32, sizeof(shape) / sizeof(int64_t), shape, memSpace2); 800 if (!mlirTypeIsAMemRef(memRef) || 801 !mlirAttributeEqual(mlirMemRefTypeGetMemorySpace(memRef), memSpace2)) 802 return 20; 803 mlirTypeDump(memRef); 804 fprintf(stderr, "\n"); 805 // CHECK: memref<2x3xf32, 2> 806 807 // Unranked MemRef type. 808 MlirAttribute memSpace4 = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 64), 4); 809 MlirType unrankedMemRef = mlirUnrankedMemRefTypeGet(f32, memSpace4); 810 if (!mlirTypeIsAUnrankedMemRef(unrankedMemRef) || 811 mlirTypeIsAMemRef(unrankedMemRef) || 812 !mlirAttributeEqual(mlirUnrankedMemrefGetMemorySpace(unrankedMemRef), 813 memSpace4)) 814 return 21; 815 mlirTypeDump(unrankedMemRef); 816 fprintf(stderr, "\n"); 817 // CHECK: memref<*xf32, 4> 818 819 // Tuple type. 820 MlirType types[] = {unrankedMemRef, f32}; 821 MlirType tuple = mlirTupleTypeGet(ctx, 2, types); 822 if (!mlirTypeIsATuple(tuple) || mlirTupleTypeGetNumTypes(tuple) != 2 || 823 !mlirTypeEqual(mlirTupleTypeGetType(tuple, 0), unrankedMemRef) || 824 !mlirTypeEqual(mlirTupleTypeGetType(tuple, 1), f32)) 825 return 22; 826 mlirTypeDump(tuple); 827 fprintf(stderr, "\n"); 828 // CHECK: tuple<memref<*xf32, 4>, f32> 829 830 // Function type. 831 MlirType funcInputs[2] = {mlirIndexTypeGet(ctx), mlirIntegerTypeGet(ctx, 1)}; 832 MlirType funcResults[3] = {mlirIntegerTypeGet(ctx, 16), 833 mlirIntegerTypeGet(ctx, 32), 834 mlirIntegerTypeGet(ctx, 64)}; 835 MlirType funcType = mlirFunctionTypeGet(ctx, 2, funcInputs, 3, funcResults); 836 if (mlirFunctionTypeGetNumInputs(funcType) != 2) 837 return 23; 838 if (mlirFunctionTypeGetNumResults(funcType) != 3) 839 return 24; 840 if (!mlirTypeEqual(funcInputs[0], mlirFunctionTypeGetInput(funcType, 0)) || 841 !mlirTypeEqual(funcInputs[1], mlirFunctionTypeGetInput(funcType, 1))) 842 return 25; 843 if (!mlirTypeEqual(funcResults[0], mlirFunctionTypeGetResult(funcType, 0)) || 844 !mlirTypeEqual(funcResults[1], mlirFunctionTypeGetResult(funcType, 1)) || 845 !mlirTypeEqual(funcResults[2], mlirFunctionTypeGetResult(funcType, 2))) 846 return 26; 847 mlirTypeDump(funcType); 848 fprintf(stderr, "\n"); 849 // CHECK: (index, i1) -> (i16, i32, i64) 850 851 // Opaque type. 852 MlirStringRef namespace = mlirStringRefCreate("dialect", 7); 853 MlirStringRef data = mlirStringRefCreate("type", 4); 854 mlirContextSetAllowUnregisteredDialects(ctx, true); 855 MlirType opaque = mlirOpaqueTypeGet(ctx, namespace, data); 856 mlirContextSetAllowUnregisteredDialects(ctx, false); 857 if (!mlirTypeIsAOpaque(opaque) || 858 !mlirStringRefEqual(mlirOpaqueTypeGetDialectNamespace(opaque), 859 namespace) || 860 !mlirStringRefEqual(mlirOpaqueTypeGetData(opaque), data)) 861 return 27; 862 mlirTypeDump(opaque); 863 fprintf(stderr, "\n"); 864 // CHECK: !dialect.type 865 866 return 0; 867 } 868 869 void callbackSetFixedLengthString(const char *data, intptr_t len, 870 void *userData) { 871 strncpy(userData, data, len); 872 } 873 874 bool stringIsEqual(const char *lhs, MlirStringRef rhs) { 875 if (strlen(lhs) != rhs.length) { 876 return false; 877 } 878 return !strncmp(lhs, rhs.data, rhs.length); 879 } 880 881 int printBuiltinAttributes(MlirContext ctx) { 882 MlirAttribute floating = 883 mlirFloatAttrDoubleGet(ctx, mlirF64TypeGet(ctx), 2.0); 884 if (!mlirAttributeIsAFloat(floating) || 885 fabs(mlirFloatAttrGetValueDouble(floating) - 2.0) > 1E-6) 886 return 1; 887 fprintf(stderr, "@attrs\n"); 888 mlirAttributeDump(floating); 889 // CHECK-LABEL: @attrs 890 // CHECK: 2.000000e+00 : f64 891 892 // Exercise mlirAttributeGetType() just for the first one. 893 MlirType floatingType = mlirAttributeGetType(floating); 894 mlirTypeDump(floatingType); 895 // CHECK: f64 896 897 MlirAttribute integer = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 32), 42); 898 MlirAttribute signedInteger = 899 mlirIntegerAttrGet(mlirIntegerTypeSignedGet(ctx, 8), -1); 900 MlirAttribute unsignedInteger = 901 mlirIntegerAttrGet(mlirIntegerTypeUnsignedGet(ctx, 8), 255); 902 if (!mlirAttributeIsAInteger(integer) || 903 mlirIntegerAttrGetValueInt(integer) != 42 || 904 mlirIntegerAttrGetValueSInt(signedInteger) != -1 || 905 mlirIntegerAttrGetValueUInt(unsignedInteger) != 255) 906 return 2; 907 mlirAttributeDump(integer); 908 mlirAttributeDump(signedInteger); 909 mlirAttributeDump(unsignedInteger); 910 // CHECK: 42 : i32 911 // CHECK: -1 : si8 912 // CHECK: 255 : ui8 913 914 MlirAttribute boolean = mlirBoolAttrGet(ctx, 1); 915 if (!mlirAttributeIsABool(boolean) || !mlirBoolAttrGetValue(boolean)) 916 return 3; 917 mlirAttributeDump(boolean); 918 // CHECK: true 919 920 const char data[] = "abcdefghijklmnopqestuvwxyz"; 921 MlirAttribute opaque = 922 mlirOpaqueAttrGet(ctx, mlirStringRefCreateFromCString("func"), 3, data, 923 mlirNoneTypeGet(ctx)); 924 if (!mlirAttributeIsAOpaque(opaque) || 925 !stringIsEqual("func", mlirOpaqueAttrGetDialectNamespace(opaque))) 926 return 4; 927 928 MlirStringRef opaqueData = mlirOpaqueAttrGetData(opaque); 929 if (opaqueData.length != 3 || 930 strncmp(data, opaqueData.data, opaqueData.length)) 931 return 5; 932 mlirAttributeDump(opaque); 933 // CHECK: #func.abc 934 935 MlirAttribute string = 936 mlirStringAttrGet(ctx, mlirStringRefCreate(data + 3, 2)); 937 if (!mlirAttributeIsAString(string)) 938 return 6; 939 940 MlirStringRef stringValue = mlirStringAttrGetValue(string); 941 if (stringValue.length != 2 || 942 strncmp(data + 3, stringValue.data, stringValue.length)) 943 return 7; 944 mlirAttributeDump(string); 945 // CHECK: "de" 946 947 MlirAttribute flatSymbolRef = 948 mlirFlatSymbolRefAttrGet(ctx, mlirStringRefCreate(data + 5, 3)); 949 if (!mlirAttributeIsAFlatSymbolRef(flatSymbolRef)) 950 return 8; 951 952 MlirStringRef flatSymbolRefValue = 953 mlirFlatSymbolRefAttrGetValue(flatSymbolRef); 954 if (flatSymbolRefValue.length != 3 || 955 strncmp(data + 5, flatSymbolRefValue.data, flatSymbolRefValue.length)) 956 return 9; 957 mlirAttributeDump(flatSymbolRef); 958 // CHECK: @fgh 959 960 MlirAttribute symbols[] = {flatSymbolRef, flatSymbolRef}; 961 MlirAttribute symbolRef = 962 mlirSymbolRefAttrGet(ctx, mlirStringRefCreate(data + 8, 2), 2, symbols); 963 if (!mlirAttributeIsASymbolRef(symbolRef) || 964 mlirSymbolRefAttrGetNumNestedReferences(symbolRef) != 2 || 965 !mlirAttributeEqual(mlirSymbolRefAttrGetNestedReference(symbolRef, 0), 966 flatSymbolRef) || 967 !mlirAttributeEqual(mlirSymbolRefAttrGetNestedReference(symbolRef, 1), 968 flatSymbolRef)) 969 return 10; 970 971 MlirStringRef symbolRefLeaf = mlirSymbolRefAttrGetLeafReference(symbolRef); 972 MlirStringRef symbolRefRoot = mlirSymbolRefAttrGetRootReference(symbolRef); 973 if (symbolRefLeaf.length != 3 || 974 strncmp(data + 5, symbolRefLeaf.data, symbolRefLeaf.length) || 975 symbolRefRoot.length != 2 || 976 strncmp(data + 8, symbolRefRoot.data, symbolRefRoot.length)) 977 return 11; 978 mlirAttributeDump(symbolRef); 979 // CHECK: @ij::@fgh::@fgh 980 981 MlirAttribute type = mlirTypeAttrGet(mlirF32TypeGet(ctx)); 982 if (!mlirAttributeIsAType(type) || 983 !mlirTypeEqual(mlirF32TypeGet(ctx), mlirTypeAttrGetValue(type))) 984 return 12; 985 mlirAttributeDump(type); 986 // CHECK: f32 987 988 MlirAttribute unit = mlirUnitAttrGet(ctx); 989 if (!mlirAttributeIsAUnit(unit)) 990 return 13; 991 mlirAttributeDump(unit); 992 // CHECK: unit 993 994 int64_t shape[] = {1, 2}; 995 996 int bools[] = {0, 1}; 997 uint8_t uints8[] = {0u, 1u}; 998 int8_t ints8[] = {0, 1}; 999 uint16_t uints16[] = {0u, 1u}; 1000 int16_t ints16[] = {0, 1}; 1001 uint32_t uints32[] = {0u, 1u}; 1002 int32_t ints32[] = {0, 1}; 1003 uint64_t uints64[] = {0u, 1u}; 1004 int64_t ints64[] = {0, 1}; 1005 float floats[] = {0.0f, 1.0f}; 1006 double doubles[] = {0.0, 1.0}; 1007 uint16_t bf16s[] = {0x0, 0x3f80}; 1008 uint16_t f16s[] = {0x0, 0x3c00}; 1009 MlirAttribute encoding = mlirAttributeGetNull(); 1010 MlirAttribute boolElements = mlirDenseElementsAttrBoolGet( 1011 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 1), encoding), 1012 2, bools); 1013 MlirAttribute uint8Elements = mlirDenseElementsAttrUInt8Get( 1014 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 8), 1015 encoding), 1016 2, uints8); 1017 MlirAttribute int8Elements = mlirDenseElementsAttrInt8Get( 1018 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 8), encoding), 1019 2, ints8); 1020 MlirAttribute uint16Elements = mlirDenseElementsAttrUInt16Get( 1021 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 16), 1022 encoding), 1023 2, uints16); 1024 MlirAttribute int16Elements = mlirDenseElementsAttrInt16Get( 1025 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 16), encoding), 1026 2, ints16); 1027 MlirAttribute uint32Elements = mlirDenseElementsAttrUInt32Get( 1028 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 32), 1029 encoding), 1030 2, uints32); 1031 MlirAttribute int32Elements = mlirDenseElementsAttrInt32Get( 1032 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 32), encoding), 1033 2, ints32); 1034 MlirAttribute uint64Elements = mlirDenseElementsAttrUInt64Get( 1035 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 64), 1036 encoding), 1037 2, uints64); 1038 MlirAttribute int64Elements = mlirDenseElementsAttrInt64Get( 1039 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64), encoding), 1040 2, ints64); 1041 MlirAttribute floatElements = mlirDenseElementsAttrFloatGet( 1042 mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx), encoding), 2, 1043 floats); 1044 MlirAttribute doubleElements = mlirDenseElementsAttrDoubleGet( 1045 mlirRankedTensorTypeGet(2, shape, mlirF64TypeGet(ctx), encoding), 2, 1046 doubles); 1047 MlirAttribute bf16Elements = mlirDenseElementsAttrBFloat16Get( 1048 mlirRankedTensorTypeGet(2, shape, mlirBF16TypeGet(ctx), encoding), 2, 1049 bf16s); 1050 MlirAttribute f16Elements = mlirDenseElementsAttrFloat16Get( 1051 mlirRankedTensorTypeGet(2, shape, mlirF16TypeGet(ctx), encoding), 2, 1052 f16s); 1053 1054 if (!mlirAttributeIsADenseElements(boolElements) || 1055 !mlirAttributeIsADenseElements(uint8Elements) || 1056 !mlirAttributeIsADenseElements(int8Elements) || 1057 !mlirAttributeIsADenseElements(uint32Elements) || 1058 !mlirAttributeIsADenseElements(int32Elements) || 1059 !mlirAttributeIsADenseElements(uint64Elements) || 1060 !mlirAttributeIsADenseElements(int64Elements) || 1061 !mlirAttributeIsADenseElements(floatElements) || 1062 !mlirAttributeIsADenseElements(doubleElements) || 1063 !mlirAttributeIsADenseElements(bf16Elements) || 1064 !mlirAttributeIsADenseElements(f16Elements)) 1065 return 14; 1066 1067 if (mlirDenseElementsAttrGetBoolValue(boolElements, 1) != 1 || 1068 mlirDenseElementsAttrGetUInt8Value(uint8Elements, 1) != 1 || 1069 mlirDenseElementsAttrGetInt8Value(int8Elements, 1) != 1 || 1070 mlirDenseElementsAttrGetUInt16Value(uint16Elements, 1) != 1 || 1071 mlirDenseElementsAttrGetInt16Value(int16Elements, 1) != 1 || 1072 mlirDenseElementsAttrGetUInt32Value(uint32Elements, 1) != 1 || 1073 mlirDenseElementsAttrGetInt32Value(int32Elements, 1) != 1 || 1074 mlirDenseElementsAttrGetUInt64Value(uint64Elements, 1) != 1 || 1075 mlirDenseElementsAttrGetInt64Value(int64Elements, 1) != 1 || 1076 fabsf(mlirDenseElementsAttrGetFloatValue(floatElements, 1) - 1.0f) > 1077 1E-6f || 1078 fabs(mlirDenseElementsAttrGetDoubleValue(doubleElements, 1) - 1.0) > 1E-6) 1079 return 15; 1080 1081 mlirAttributeDump(boolElements); 1082 mlirAttributeDump(uint8Elements); 1083 mlirAttributeDump(int8Elements); 1084 mlirAttributeDump(uint32Elements); 1085 mlirAttributeDump(int32Elements); 1086 mlirAttributeDump(uint64Elements); 1087 mlirAttributeDump(int64Elements); 1088 mlirAttributeDump(floatElements); 1089 mlirAttributeDump(doubleElements); 1090 mlirAttributeDump(bf16Elements); 1091 mlirAttributeDump(f16Elements); 1092 // CHECK: dense<{{\[}}[false, true]]> : tensor<1x2xi1> 1093 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xui8> 1094 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xi8> 1095 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xui32> 1096 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xi32> 1097 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xui64> 1098 // CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xi64> 1099 // CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xf32> 1100 // CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xf64> 1101 // CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xbf16> 1102 // CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xf16> 1103 1104 MlirAttribute splatBool = mlirDenseElementsAttrBoolSplatGet( 1105 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 1), encoding), 1106 1); 1107 MlirAttribute splatUInt8 = mlirDenseElementsAttrUInt8SplatGet( 1108 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 8), 1109 encoding), 1110 1); 1111 MlirAttribute splatInt8 = mlirDenseElementsAttrInt8SplatGet( 1112 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 8), encoding), 1113 1); 1114 MlirAttribute splatUInt32 = mlirDenseElementsAttrUInt32SplatGet( 1115 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 32), 1116 encoding), 1117 1); 1118 MlirAttribute splatInt32 = mlirDenseElementsAttrInt32SplatGet( 1119 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 32), encoding), 1120 1); 1121 MlirAttribute splatUInt64 = mlirDenseElementsAttrUInt64SplatGet( 1122 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 64), 1123 encoding), 1124 1); 1125 MlirAttribute splatInt64 = mlirDenseElementsAttrInt64SplatGet( 1126 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64), encoding), 1127 1); 1128 MlirAttribute splatFloat = mlirDenseElementsAttrFloatSplatGet( 1129 mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx), encoding), 1.0f); 1130 MlirAttribute splatDouble = mlirDenseElementsAttrDoubleSplatGet( 1131 mlirRankedTensorTypeGet(2, shape, mlirF64TypeGet(ctx), encoding), 1.0); 1132 1133 if (!mlirAttributeIsADenseElements(splatBool) || 1134 !mlirDenseElementsAttrIsSplat(splatBool) || 1135 !mlirAttributeIsADenseElements(splatUInt8) || 1136 !mlirDenseElementsAttrIsSplat(splatUInt8) || 1137 !mlirAttributeIsADenseElements(splatInt8) || 1138 !mlirDenseElementsAttrIsSplat(splatInt8) || 1139 !mlirAttributeIsADenseElements(splatUInt32) || 1140 !mlirDenseElementsAttrIsSplat(splatUInt32) || 1141 !mlirAttributeIsADenseElements(splatInt32) || 1142 !mlirDenseElementsAttrIsSplat(splatInt32) || 1143 !mlirAttributeIsADenseElements(splatUInt64) || 1144 !mlirDenseElementsAttrIsSplat(splatUInt64) || 1145 !mlirAttributeIsADenseElements(splatInt64) || 1146 !mlirDenseElementsAttrIsSplat(splatInt64) || 1147 !mlirAttributeIsADenseElements(splatFloat) || 1148 !mlirDenseElementsAttrIsSplat(splatFloat) || 1149 !mlirAttributeIsADenseElements(splatDouble) || 1150 !mlirDenseElementsAttrIsSplat(splatDouble)) 1151 return 16; 1152 1153 if (mlirDenseElementsAttrGetBoolSplatValue(splatBool) != 1 || 1154 mlirDenseElementsAttrGetUInt8SplatValue(splatUInt8) != 1 || 1155 mlirDenseElementsAttrGetInt8SplatValue(splatInt8) != 1 || 1156 mlirDenseElementsAttrGetUInt32SplatValue(splatUInt32) != 1 || 1157 mlirDenseElementsAttrGetInt32SplatValue(splatInt32) != 1 || 1158 mlirDenseElementsAttrGetUInt64SplatValue(splatUInt64) != 1 || 1159 mlirDenseElementsAttrGetInt64SplatValue(splatInt64) != 1 || 1160 fabsf(mlirDenseElementsAttrGetFloatSplatValue(splatFloat) - 1.0f) > 1161 1E-6f || 1162 fabs(mlirDenseElementsAttrGetDoubleSplatValue(splatDouble) - 1.0) > 1E-6) 1163 return 17; 1164 1165 const uint8_t *uint8RawData = 1166 (const uint8_t *)mlirDenseElementsAttrGetRawData(uint8Elements); 1167 const int8_t *int8RawData = 1168 (const int8_t *)mlirDenseElementsAttrGetRawData(int8Elements); 1169 const uint32_t *uint32RawData = 1170 (const uint32_t *)mlirDenseElementsAttrGetRawData(uint32Elements); 1171 const int32_t *int32RawData = 1172 (const int32_t *)mlirDenseElementsAttrGetRawData(int32Elements); 1173 const uint64_t *uint64RawData = 1174 (const uint64_t *)mlirDenseElementsAttrGetRawData(uint64Elements); 1175 const int64_t *int64RawData = 1176 (const int64_t *)mlirDenseElementsAttrGetRawData(int64Elements); 1177 const float *floatRawData = 1178 (const float *)mlirDenseElementsAttrGetRawData(floatElements); 1179 const double *doubleRawData = 1180 (const double *)mlirDenseElementsAttrGetRawData(doubleElements); 1181 const uint16_t *bf16RawData = 1182 (const uint16_t *)mlirDenseElementsAttrGetRawData(bf16Elements); 1183 const uint16_t *f16RawData = 1184 (const uint16_t *)mlirDenseElementsAttrGetRawData(f16Elements); 1185 if (uint8RawData[0] != 0u || uint8RawData[1] != 1u || int8RawData[0] != 0 || 1186 int8RawData[1] != 1 || uint32RawData[0] != 0u || uint32RawData[1] != 1u || 1187 int32RawData[0] != 0 || int32RawData[1] != 1 || uint64RawData[0] != 0u || 1188 uint64RawData[1] != 1u || int64RawData[0] != 0 || int64RawData[1] != 1 || 1189 floatRawData[0] != 0.0f || floatRawData[1] != 1.0f || 1190 doubleRawData[0] != 0.0 || doubleRawData[1] != 1.0 || 1191 bf16RawData[0] != 0 || bf16RawData[1] != 0x3f80 || f16RawData[0] != 0 || 1192 f16RawData[1] != 0x3c00) 1193 return 18; 1194 1195 mlirAttributeDump(splatBool); 1196 mlirAttributeDump(splatUInt8); 1197 mlirAttributeDump(splatInt8); 1198 mlirAttributeDump(splatUInt32); 1199 mlirAttributeDump(splatInt32); 1200 mlirAttributeDump(splatUInt64); 1201 mlirAttributeDump(splatInt64); 1202 mlirAttributeDump(splatFloat); 1203 mlirAttributeDump(splatDouble); 1204 // CHECK: dense<true> : tensor<1x2xi1> 1205 // CHECK: dense<1> : tensor<1x2xui8> 1206 // CHECK: dense<1> : tensor<1x2xi8> 1207 // CHECK: dense<1> : tensor<1x2xui32> 1208 // CHECK: dense<1> : tensor<1x2xi32> 1209 // CHECK: dense<1> : tensor<1x2xui64> 1210 // CHECK: dense<1> : tensor<1x2xi64> 1211 // CHECK: dense<1.000000e+00> : tensor<1x2xf32> 1212 // CHECK: dense<1.000000e+00> : tensor<1x2xf64> 1213 1214 mlirAttributeDump(mlirElementsAttrGetValue(floatElements, 2, uints64)); 1215 mlirAttributeDump(mlirElementsAttrGetValue(doubleElements, 2, uints64)); 1216 mlirAttributeDump(mlirElementsAttrGetValue(bf16Elements, 2, uints64)); 1217 mlirAttributeDump(mlirElementsAttrGetValue(f16Elements, 2, uints64)); 1218 // CHECK: 1.000000e+00 : f32 1219 // CHECK: 1.000000e+00 : f64 1220 // CHECK: 1.000000e+00 : bf16 1221 // CHECK: 1.000000e+00 : f16 1222 1223 int64_t indices[] = {0, 1}; 1224 int64_t one = 1; 1225 MlirAttribute indicesAttr = mlirDenseElementsAttrInt64Get( 1226 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64), encoding), 1227 2, indices); 1228 MlirAttribute valuesAttr = mlirDenseElementsAttrFloatGet( 1229 mlirRankedTensorTypeGet(1, &one, mlirF32TypeGet(ctx), encoding), 1, 1230 floats); 1231 MlirAttribute sparseAttr = mlirSparseElementsAttribute( 1232 mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx), encoding), 1233 indicesAttr, valuesAttr); 1234 mlirAttributeDump(sparseAttr); 1235 // CHECK: sparse<{{\[}}[0, 1]], 0.000000e+00> : tensor<1x2xf32> 1236 1237 MlirAttribute boolArray = mlirDenseBoolArrayGet(ctx, 2, bools); 1238 MlirAttribute int8Array = mlirDenseI8ArrayGet(ctx, 2, ints8); 1239 MlirAttribute int16Array = mlirDenseI16ArrayGet(ctx, 2, ints16); 1240 MlirAttribute int32Array = mlirDenseI32ArrayGet(ctx, 2, ints32); 1241 MlirAttribute int64Array = mlirDenseI64ArrayGet(ctx, 2, ints64); 1242 MlirAttribute floatArray = mlirDenseF32ArrayGet(ctx, 2, floats); 1243 MlirAttribute doubleArray = mlirDenseF64ArrayGet(ctx, 2, doubles); 1244 if (!mlirAttributeIsADenseBoolArray(boolArray) || 1245 !mlirAttributeIsADenseI8Array(int8Array) || 1246 !mlirAttributeIsADenseI16Array(int16Array) || 1247 !mlirAttributeIsADenseI32Array(int32Array) || 1248 !mlirAttributeIsADenseI64Array(int64Array) || 1249 !mlirAttributeIsADenseF32Array(floatArray) || 1250 !mlirAttributeIsADenseF64Array(doubleArray)) 1251 return 19; 1252 1253 if (mlirDenseArrayGetNumElements(boolArray) != 2 || 1254 mlirDenseArrayGetNumElements(int8Array) != 2 || 1255 mlirDenseArrayGetNumElements(int16Array) != 2 || 1256 mlirDenseArrayGetNumElements(int32Array) != 2 || 1257 mlirDenseArrayGetNumElements(int64Array) != 2 || 1258 mlirDenseArrayGetNumElements(floatArray) != 2 || 1259 mlirDenseArrayGetNumElements(doubleArray) != 2) 1260 return 20; 1261 1262 if (mlirDenseBoolArrayGetElement(boolArray, 1) != 1 || 1263 mlirDenseI8ArrayGetElement(int8Array, 1) != 1 || 1264 mlirDenseI16ArrayGetElement(int16Array, 1) != 1 || 1265 mlirDenseI32ArrayGetElement(int32Array, 1) != 1 || 1266 mlirDenseI64ArrayGetElement(int64Array, 1) != 1 || 1267 fabsf(mlirDenseF32ArrayGetElement(floatArray, 1) - 1.0f) > 1E-6f || 1268 fabs(mlirDenseF64ArrayGetElement(doubleArray, 1) - 1.0) > 1E-6) 1269 return 21; 1270 1271 int64_t layoutStrides[3] = {5, 7, 13}; 1272 MlirAttribute stridedLayoutAttr = 1273 mlirStridedLayoutAttrGet(ctx, 42, 3, &layoutStrides[0]); 1274 1275 // CHECK: strided<[5, 7, 13], offset: 42> 1276 mlirAttributeDump(stridedLayoutAttr); 1277 1278 if (mlirStridedLayoutAttrGetOffset(stridedLayoutAttr) != 42 || 1279 mlirStridedLayoutAttrGetNumStrides(stridedLayoutAttr) != 3 || 1280 mlirStridedLayoutAttrGetStride(stridedLayoutAttr, 0) != 5 || 1281 mlirStridedLayoutAttrGetStride(stridedLayoutAttr, 1) != 7 || 1282 mlirStridedLayoutAttrGetStride(stridedLayoutAttr, 2) != 13) 1283 return 22; 1284 1285 MlirAttribute uint8Blob = mlirUnmanagedDenseUInt8ResourceElementsAttrGet( 1286 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 8), 1287 encoding), 1288 mlirStringRefCreateFromCString("resource_ui8"), 2, uints8); 1289 MlirAttribute uint16Blob = mlirUnmanagedDenseUInt16ResourceElementsAttrGet( 1290 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 16), 1291 encoding), 1292 mlirStringRefCreateFromCString("resource_ui16"), 2, uints16); 1293 MlirAttribute uint32Blob = mlirUnmanagedDenseUInt32ResourceElementsAttrGet( 1294 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 32), 1295 encoding), 1296 mlirStringRefCreateFromCString("resource_ui32"), 2, uints32); 1297 MlirAttribute uint64Blob = mlirUnmanagedDenseUInt64ResourceElementsAttrGet( 1298 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 64), 1299 encoding), 1300 mlirStringRefCreateFromCString("resource_ui64"), 2, uints64); 1301 MlirAttribute int8Blob = mlirUnmanagedDenseInt8ResourceElementsAttrGet( 1302 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 8), encoding), 1303 mlirStringRefCreateFromCString("resource_i8"), 2, ints8); 1304 MlirAttribute int16Blob = mlirUnmanagedDenseInt16ResourceElementsAttrGet( 1305 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 16), encoding), 1306 mlirStringRefCreateFromCString("resource_i16"), 2, ints16); 1307 MlirAttribute int32Blob = mlirUnmanagedDenseInt32ResourceElementsAttrGet( 1308 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 32), encoding), 1309 mlirStringRefCreateFromCString("resource_i32"), 2, ints32); 1310 MlirAttribute int64Blob = mlirUnmanagedDenseInt64ResourceElementsAttrGet( 1311 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64), encoding), 1312 mlirStringRefCreateFromCString("resource_i64"), 2, ints64); 1313 MlirAttribute floatsBlob = mlirUnmanagedDenseFloatResourceElementsAttrGet( 1314 mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx), encoding), 1315 mlirStringRefCreateFromCString("resource_f32"), 2, floats); 1316 MlirAttribute doublesBlob = mlirUnmanagedDenseDoubleResourceElementsAttrGet( 1317 mlirRankedTensorTypeGet(2, shape, mlirF64TypeGet(ctx), encoding), 1318 mlirStringRefCreateFromCString("resource_f64"), 2, doubles); 1319 MlirAttribute blobBlob = mlirUnmanagedDenseResourceElementsAttrGet( 1320 mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64), encoding), 1321 mlirStringRefCreateFromCString("resource_i64_blob"), /*data=*/uints64, 1322 /*dataLength=*/sizeof(uints64), 1323 /*dataAlignment=*/_Alignof(uint64_t), 1324 /*dataIsMutable=*/false, 1325 /*deleter=*/reportResourceDelete, 1326 /*userData=*/(void *)&resourceI64BlobUserData); 1327 1328 mlirAttributeDump(uint8Blob); 1329 mlirAttributeDump(uint16Blob); 1330 mlirAttributeDump(uint32Blob); 1331 mlirAttributeDump(uint64Blob); 1332 mlirAttributeDump(int8Blob); 1333 mlirAttributeDump(int16Blob); 1334 mlirAttributeDump(int32Blob); 1335 mlirAttributeDump(int64Blob); 1336 mlirAttributeDump(floatsBlob); 1337 mlirAttributeDump(doublesBlob); 1338 mlirAttributeDump(blobBlob); 1339 // CHECK: dense_resource<resource_ui8> : tensor<1x2xui8> 1340 // CHECK: dense_resource<resource_ui16> : tensor<1x2xui16> 1341 // CHECK: dense_resource<resource_ui32> : tensor<1x2xui32> 1342 // CHECK: dense_resource<resource_ui64> : tensor<1x2xui64> 1343 // CHECK: dense_resource<resource_i8> : tensor<1x2xi8> 1344 // CHECK: dense_resource<resource_i16> : tensor<1x2xi16> 1345 // CHECK: dense_resource<resource_i32> : tensor<1x2xi32> 1346 // CHECK: dense_resource<resource_i64> : tensor<1x2xi64> 1347 // CHECK: dense_resource<resource_f32> : tensor<1x2xf32> 1348 // CHECK: dense_resource<resource_f64> : tensor<1x2xf64> 1349 // CHECK: dense_resource<resource_i64_blob> : tensor<1x2xi64> 1350 1351 if (mlirDenseUInt8ResourceElementsAttrGetValue(uint8Blob, 1) != 1 || 1352 mlirDenseUInt16ResourceElementsAttrGetValue(uint16Blob, 1) != 1 || 1353 mlirDenseUInt32ResourceElementsAttrGetValue(uint32Blob, 1) != 1 || 1354 mlirDenseUInt64ResourceElementsAttrGetValue(uint64Blob, 1) != 1 || 1355 mlirDenseInt8ResourceElementsAttrGetValue(int8Blob, 1) != 1 || 1356 mlirDenseInt16ResourceElementsAttrGetValue(int16Blob, 1) != 1 || 1357 mlirDenseInt32ResourceElementsAttrGetValue(int32Blob, 1) != 1 || 1358 mlirDenseInt64ResourceElementsAttrGetValue(int64Blob, 1) != 1 || 1359 fabsf(mlirDenseF32ArrayGetElement(floatArray, 1) - 1.0f) > 1E-6f || 1360 fabsf(mlirDenseFloatResourceElementsAttrGetValue(floatsBlob, 1) - 1.0f) > 1361 1e-6 || 1362 fabs(mlirDenseDoubleResourceElementsAttrGetValue(doublesBlob, 1) - 1.0f) > 1363 1e-6 || 1364 mlirDenseUInt64ResourceElementsAttrGetValue(blobBlob, 1) != 1) 1365 return 23; 1366 1367 MlirLocation loc = mlirLocationUnknownGet(ctx); 1368 MlirAttribute locAttr = mlirLocationGetAttribute(loc); 1369 if (!mlirAttributeIsALocation(locAttr)) 1370 return 24; 1371 1372 return 0; 1373 } 1374 1375 int printAffineMap(MlirContext ctx) { 1376 MlirAffineMap emptyAffineMap = mlirAffineMapEmptyGet(ctx); 1377 MlirAffineMap affineMap = mlirAffineMapZeroResultGet(ctx, 3, 2); 1378 MlirAffineMap constAffineMap = mlirAffineMapConstantGet(ctx, 2); 1379 MlirAffineMap multiDimIdentityAffineMap = 1380 mlirAffineMapMultiDimIdentityGet(ctx, 3); 1381 MlirAffineMap minorIdentityAffineMap = 1382 mlirAffineMapMinorIdentityGet(ctx, 3, 2); 1383 unsigned permutation[] = {1, 2, 0}; 1384 MlirAffineMap permutationAffineMap = mlirAffineMapPermutationGet( 1385 ctx, sizeof(permutation) / sizeof(unsigned), permutation); 1386 1387 fprintf(stderr, "@affineMap\n"); 1388 mlirAffineMapDump(emptyAffineMap); 1389 mlirAffineMapDump(affineMap); 1390 mlirAffineMapDump(constAffineMap); 1391 mlirAffineMapDump(multiDimIdentityAffineMap); 1392 mlirAffineMapDump(minorIdentityAffineMap); 1393 mlirAffineMapDump(permutationAffineMap); 1394 // CHECK-LABEL: @affineMap 1395 // CHECK: () -> () 1396 // CHECK: (d0, d1, d2)[s0, s1] -> () 1397 // CHECK: () -> (2) 1398 // CHECK: (d0, d1, d2) -> (d0, d1, d2) 1399 // CHECK: (d0, d1, d2) -> (d1, d2) 1400 // CHECK: (d0, d1, d2) -> (d1, d2, d0) 1401 1402 if (!mlirAffineMapIsIdentity(emptyAffineMap) || 1403 mlirAffineMapIsIdentity(affineMap) || 1404 mlirAffineMapIsIdentity(constAffineMap) || 1405 !mlirAffineMapIsIdentity(multiDimIdentityAffineMap) || 1406 mlirAffineMapIsIdentity(minorIdentityAffineMap) || 1407 mlirAffineMapIsIdentity(permutationAffineMap)) 1408 return 1; 1409 1410 if (!mlirAffineMapIsMinorIdentity(emptyAffineMap) || 1411 mlirAffineMapIsMinorIdentity(affineMap) || 1412 !mlirAffineMapIsMinorIdentity(multiDimIdentityAffineMap) || 1413 !mlirAffineMapIsMinorIdentity(minorIdentityAffineMap) || 1414 mlirAffineMapIsMinorIdentity(permutationAffineMap)) 1415 return 2; 1416 1417 if (!mlirAffineMapIsEmpty(emptyAffineMap) || 1418 mlirAffineMapIsEmpty(affineMap) || mlirAffineMapIsEmpty(constAffineMap) || 1419 mlirAffineMapIsEmpty(multiDimIdentityAffineMap) || 1420 mlirAffineMapIsEmpty(minorIdentityAffineMap) || 1421 mlirAffineMapIsEmpty(permutationAffineMap)) 1422 return 3; 1423 1424 if (mlirAffineMapIsSingleConstant(emptyAffineMap) || 1425 mlirAffineMapIsSingleConstant(affineMap) || 1426 !mlirAffineMapIsSingleConstant(constAffineMap) || 1427 mlirAffineMapIsSingleConstant(multiDimIdentityAffineMap) || 1428 mlirAffineMapIsSingleConstant(minorIdentityAffineMap) || 1429 mlirAffineMapIsSingleConstant(permutationAffineMap)) 1430 return 4; 1431 1432 if (mlirAffineMapGetSingleConstantResult(constAffineMap) != 2) 1433 return 5; 1434 1435 if (mlirAffineMapGetNumDims(emptyAffineMap) != 0 || 1436 mlirAffineMapGetNumDims(affineMap) != 3 || 1437 mlirAffineMapGetNumDims(constAffineMap) != 0 || 1438 mlirAffineMapGetNumDims(multiDimIdentityAffineMap) != 3 || 1439 mlirAffineMapGetNumDims(minorIdentityAffineMap) != 3 || 1440 mlirAffineMapGetNumDims(permutationAffineMap) != 3) 1441 return 6; 1442 1443 if (mlirAffineMapGetNumSymbols(emptyAffineMap) != 0 || 1444 mlirAffineMapGetNumSymbols(affineMap) != 2 || 1445 mlirAffineMapGetNumSymbols(constAffineMap) != 0 || 1446 mlirAffineMapGetNumSymbols(multiDimIdentityAffineMap) != 0 || 1447 mlirAffineMapGetNumSymbols(minorIdentityAffineMap) != 0 || 1448 mlirAffineMapGetNumSymbols(permutationAffineMap) != 0) 1449 return 7; 1450 1451 if (mlirAffineMapGetNumResults(emptyAffineMap) != 0 || 1452 mlirAffineMapGetNumResults(affineMap) != 0 || 1453 mlirAffineMapGetNumResults(constAffineMap) != 1 || 1454 mlirAffineMapGetNumResults(multiDimIdentityAffineMap) != 3 || 1455 mlirAffineMapGetNumResults(minorIdentityAffineMap) != 2 || 1456 mlirAffineMapGetNumResults(permutationAffineMap) != 3) 1457 return 8; 1458 1459 if (mlirAffineMapGetNumInputs(emptyAffineMap) != 0 || 1460 mlirAffineMapGetNumInputs(affineMap) != 5 || 1461 mlirAffineMapGetNumInputs(constAffineMap) != 0 || 1462 mlirAffineMapGetNumInputs(multiDimIdentityAffineMap) != 3 || 1463 mlirAffineMapGetNumInputs(minorIdentityAffineMap) != 3 || 1464 mlirAffineMapGetNumInputs(permutationAffineMap) != 3) 1465 return 9; 1466 1467 if (!mlirAffineMapIsProjectedPermutation(emptyAffineMap) || 1468 !mlirAffineMapIsPermutation(emptyAffineMap) || 1469 mlirAffineMapIsProjectedPermutation(affineMap) || 1470 mlirAffineMapIsPermutation(affineMap) || 1471 mlirAffineMapIsProjectedPermutation(constAffineMap) || 1472 mlirAffineMapIsPermutation(constAffineMap) || 1473 !mlirAffineMapIsProjectedPermutation(multiDimIdentityAffineMap) || 1474 !mlirAffineMapIsPermutation(multiDimIdentityAffineMap) || 1475 !mlirAffineMapIsProjectedPermutation(minorIdentityAffineMap) || 1476 mlirAffineMapIsPermutation(minorIdentityAffineMap) || 1477 !mlirAffineMapIsProjectedPermutation(permutationAffineMap) || 1478 !mlirAffineMapIsPermutation(permutationAffineMap)) 1479 return 10; 1480 1481 intptr_t sub[] = {1}; 1482 1483 MlirAffineMap subMap = mlirAffineMapGetSubMap( 1484 multiDimIdentityAffineMap, sizeof(sub) / sizeof(intptr_t), sub); 1485 MlirAffineMap majorSubMap = 1486 mlirAffineMapGetMajorSubMap(multiDimIdentityAffineMap, 1); 1487 MlirAffineMap minorSubMap = 1488 mlirAffineMapGetMinorSubMap(multiDimIdentityAffineMap, 1); 1489 1490 mlirAffineMapDump(subMap); 1491 mlirAffineMapDump(majorSubMap); 1492 mlirAffineMapDump(minorSubMap); 1493 // CHECK: (d0, d1, d2) -> (d1) 1494 // CHECK: (d0, d1, d2) -> (d0) 1495 // CHECK: (d0, d1, d2) -> (d2) 1496 1497 // CHECK: distinct[0]<"foo"> 1498 mlirAttributeDump(mlirDisctinctAttrCreate( 1499 mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("foo")))); 1500 1501 return 0; 1502 } 1503 1504 int printAffineExpr(MlirContext ctx) { 1505 MlirAffineExpr affineDimExpr = mlirAffineDimExprGet(ctx, 5); 1506 MlirAffineExpr affineSymbolExpr = mlirAffineSymbolExprGet(ctx, 5); 1507 MlirAffineExpr affineConstantExpr = mlirAffineConstantExprGet(ctx, 5); 1508 MlirAffineExpr affineAddExpr = 1509 mlirAffineAddExprGet(affineDimExpr, affineSymbolExpr); 1510 MlirAffineExpr affineMulExpr = 1511 mlirAffineMulExprGet(affineDimExpr, affineSymbolExpr); 1512 MlirAffineExpr affineModExpr = 1513 mlirAffineModExprGet(affineDimExpr, affineSymbolExpr); 1514 MlirAffineExpr affineFloorDivExpr = 1515 mlirAffineFloorDivExprGet(affineDimExpr, affineSymbolExpr); 1516 MlirAffineExpr affineCeilDivExpr = 1517 mlirAffineCeilDivExprGet(affineDimExpr, affineSymbolExpr); 1518 1519 // Tests mlirAffineExprDump. 1520 fprintf(stderr, "@affineExpr\n"); 1521 mlirAffineExprDump(affineDimExpr); 1522 mlirAffineExprDump(affineSymbolExpr); 1523 mlirAffineExprDump(affineConstantExpr); 1524 mlirAffineExprDump(affineAddExpr); 1525 mlirAffineExprDump(affineMulExpr); 1526 mlirAffineExprDump(affineModExpr); 1527 mlirAffineExprDump(affineFloorDivExpr); 1528 mlirAffineExprDump(affineCeilDivExpr); 1529 // CHECK-LABEL: @affineExpr 1530 // CHECK: d5 1531 // CHECK: s5 1532 // CHECK: 5 1533 // CHECK: d5 + s5 1534 // CHECK: d5 * s5 1535 // CHECK: d5 mod s5 1536 // CHECK: d5 floordiv s5 1537 // CHECK: d5 ceildiv s5 1538 1539 // Tests methods of affine binary operation expression, takes add expression 1540 // as an example. 1541 mlirAffineExprDump(mlirAffineBinaryOpExprGetLHS(affineAddExpr)); 1542 mlirAffineExprDump(mlirAffineBinaryOpExprGetRHS(affineAddExpr)); 1543 // CHECK: d5 1544 // CHECK: s5 1545 1546 // Tests methods of affine dimension expression. 1547 if (mlirAffineDimExprGetPosition(affineDimExpr) != 5) 1548 return 1; 1549 1550 // Tests methods of affine symbol expression. 1551 if (mlirAffineSymbolExprGetPosition(affineSymbolExpr) != 5) 1552 return 2; 1553 1554 // Tests methods of affine constant expression. 1555 if (mlirAffineConstantExprGetValue(affineConstantExpr) != 5) 1556 return 3; 1557 1558 // Tests methods of affine expression. 1559 if (mlirAffineExprIsSymbolicOrConstant(affineDimExpr) || 1560 !mlirAffineExprIsSymbolicOrConstant(affineSymbolExpr) || 1561 !mlirAffineExprIsSymbolicOrConstant(affineConstantExpr) || 1562 mlirAffineExprIsSymbolicOrConstant(affineAddExpr) || 1563 mlirAffineExprIsSymbolicOrConstant(affineMulExpr) || 1564 mlirAffineExprIsSymbolicOrConstant(affineModExpr) || 1565 mlirAffineExprIsSymbolicOrConstant(affineFloorDivExpr) || 1566 mlirAffineExprIsSymbolicOrConstant(affineCeilDivExpr)) 1567 return 4; 1568 1569 if (!mlirAffineExprIsPureAffine(affineDimExpr) || 1570 !mlirAffineExprIsPureAffine(affineSymbolExpr) || 1571 !mlirAffineExprIsPureAffine(affineConstantExpr) || 1572 !mlirAffineExprIsPureAffine(affineAddExpr) || 1573 mlirAffineExprIsPureAffine(affineMulExpr) || 1574 mlirAffineExprIsPureAffine(affineModExpr) || 1575 mlirAffineExprIsPureAffine(affineFloorDivExpr) || 1576 mlirAffineExprIsPureAffine(affineCeilDivExpr)) 1577 return 5; 1578 1579 if (mlirAffineExprGetLargestKnownDivisor(affineDimExpr) != 1 || 1580 mlirAffineExprGetLargestKnownDivisor(affineSymbolExpr) != 1 || 1581 mlirAffineExprGetLargestKnownDivisor(affineConstantExpr) != 5 || 1582 mlirAffineExprGetLargestKnownDivisor(affineAddExpr) != 1 || 1583 mlirAffineExprGetLargestKnownDivisor(affineMulExpr) != 1 || 1584 mlirAffineExprGetLargestKnownDivisor(affineModExpr) != 1 || 1585 mlirAffineExprGetLargestKnownDivisor(affineFloorDivExpr) != 1 || 1586 mlirAffineExprGetLargestKnownDivisor(affineCeilDivExpr) != 1) 1587 return 6; 1588 1589 if (!mlirAffineExprIsMultipleOf(affineDimExpr, 1) || 1590 !mlirAffineExprIsMultipleOf(affineSymbolExpr, 1) || 1591 !mlirAffineExprIsMultipleOf(affineConstantExpr, 5) || 1592 !mlirAffineExprIsMultipleOf(affineAddExpr, 1) || 1593 !mlirAffineExprIsMultipleOf(affineMulExpr, 1) || 1594 !mlirAffineExprIsMultipleOf(affineModExpr, 1) || 1595 !mlirAffineExprIsMultipleOf(affineFloorDivExpr, 1) || 1596 !mlirAffineExprIsMultipleOf(affineCeilDivExpr, 1)) 1597 return 7; 1598 1599 if (!mlirAffineExprIsFunctionOfDim(affineDimExpr, 5) || 1600 mlirAffineExprIsFunctionOfDim(affineSymbolExpr, 5) || 1601 mlirAffineExprIsFunctionOfDim(affineConstantExpr, 5) || 1602 !mlirAffineExprIsFunctionOfDim(affineAddExpr, 5) || 1603 !mlirAffineExprIsFunctionOfDim(affineMulExpr, 5) || 1604 !mlirAffineExprIsFunctionOfDim(affineModExpr, 5) || 1605 !mlirAffineExprIsFunctionOfDim(affineFloorDivExpr, 5) || 1606 !mlirAffineExprIsFunctionOfDim(affineCeilDivExpr, 5)) 1607 return 8; 1608 1609 // Tests 'IsA' methods of affine binary operation expression. 1610 if (!mlirAffineExprIsAAdd(affineAddExpr)) 1611 return 9; 1612 1613 if (!mlirAffineExprIsAMul(affineMulExpr)) 1614 return 10; 1615 1616 if (!mlirAffineExprIsAMod(affineModExpr)) 1617 return 11; 1618 1619 if (!mlirAffineExprIsAFloorDiv(affineFloorDivExpr)) 1620 return 12; 1621 1622 if (!mlirAffineExprIsACeilDiv(affineCeilDivExpr)) 1623 return 13; 1624 1625 if (!mlirAffineExprIsABinary(affineAddExpr)) 1626 return 14; 1627 1628 // Test other 'IsA' method on affine expressions. 1629 if (!mlirAffineExprIsAConstant(affineConstantExpr)) 1630 return 15; 1631 1632 if (!mlirAffineExprIsADim(affineDimExpr)) 1633 return 16; 1634 1635 if (!mlirAffineExprIsASymbol(affineSymbolExpr)) 1636 return 17; 1637 1638 // Test equality and nullity. 1639 MlirAffineExpr otherDimExpr = mlirAffineDimExprGet(ctx, 5); 1640 if (!mlirAffineExprEqual(affineDimExpr, otherDimExpr)) 1641 return 18; 1642 1643 if (mlirAffineExprIsNull(affineDimExpr)) 1644 return 19; 1645 1646 return 0; 1647 } 1648 1649 int affineMapFromExprs(MlirContext ctx) { 1650 MlirAffineExpr affineDimExpr = mlirAffineDimExprGet(ctx, 0); 1651 MlirAffineExpr affineSymbolExpr = mlirAffineSymbolExprGet(ctx, 1); 1652 MlirAffineExpr exprs[] = {affineDimExpr, affineSymbolExpr}; 1653 MlirAffineMap map = mlirAffineMapGet(ctx, 3, 3, 2, exprs); 1654 1655 // CHECK-LABEL: @affineMapFromExprs 1656 fprintf(stderr, "@affineMapFromExprs"); 1657 // CHECK: (d0, d1, d2)[s0, s1, s2] -> (d0, s1) 1658 mlirAffineMapDump(map); 1659 1660 if (mlirAffineMapGetNumResults(map) != 2) 1661 return 1; 1662 1663 if (!mlirAffineExprEqual(mlirAffineMapGetResult(map, 0), affineDimExpr)) 1664 return 2; 1665 1666 if (!mlirAffineExprEqual(mlirAffineMapGetResult(map, 1), affineSymbolExpr)) 1667 return 3; 1668 1669 MlirAffineExpr affineDim2Expr = mlirAffineDimExprGet(ctx, 1); 1670 MlirAffineExpr composed = mlirAffineExprCompose(affineDim2Expr, map); 1671 // CHECK: s1 1672 mlirAffineExprDump(composed); 1673 if (!mlirAffineExprEqual(composed, affineSymbolExpr)) 1674 return 4; 1675 1676 return 0; 1677 } 1678 1679 int printIntegerSet(MlirContext ctx) { 1680 MlirIntegerSet emptySet = mlirIntegerSetEmptyGet(ctx, 2, 1); 1681 1682 // CHECK-LABEL: @printIntegerSet 1683 fprintf(stderr, "@printIntegerSet"); 1684 1685 // CHECK: (d0, d1)[s0] : (1 == 0) 1686 mlirIntegerSetDump(emptySet); 1687 1688 if (!mlirIntegerSetIsCanonicalEmpty(emptySet)) 1689 return 1; 1690 1691 MlirIntegerSet anotherEmptySet = mlirIntegerSetEmptyGet(ctx, 2, 1); 1692 if (!mlirIntegerSetEqual(emptySet, anotherEmptySet)) 1693 return 2; 1694 1695 // Construct a set constrained by: 1696 // d0 - s0 == 0, 1697 // d1 - 42 >= 0. 1698 MlirAffineExpr negOne = mlirAffineConstantExprGet(ctx, -1); 1699 MlirAffineExpr negFortyTwo = mlirAffineConstantExprGet(ctx, -42); 1700 MlirAffineExpr d0 = mlirAffineDimExprGet(ctx, 0); 1701 MlirAffineExpr d1 = mlirAffineDimExprGet(ctx, 1); 1702 MlirAffineExpr s0 = mlirAffineSymbolExprGet(ctx, 0); 1703 MlirAffineExpr negS0 = mlirAffineMulExprGet(negOne, s0); 1704 MlirAffineExpr d0minusS0 = mlirAffineAddExprGet(d0, negS0); 1705 MlirAffineExpr d1minus42 = mlirAffineAddExprGet(d1, negFortyTwo); 1706 MlirAffineExpr constraints[] = {d0minusS0, d1minus42}; 1707 bool flags[] = {true, false}; 1708 1709 MlirIntegerSet set = mlirIntegerSetGet(ctx, 2, 1, 2, constraints, flags); 1710 // CHECK: (d0, d1)[s0] : ( 1711 // CHECK-DAG: d0 - s0 == 0 1712 // CHECK-DAG: d1 - 42 >= 0 1713 mlirIntegerSetDump(set); 1714 1715 // Transform d1 into s0. 1716 MlirAffineExpr s1 = mlirAffineSymbolExprGet(ctx, 1); 1717 MlirAffineExpr repl[] = {d0, s1}; 1718 MlirIntegerSet replaced = mlirIntegerSetReplaceGet(set, repl, &s0, 1, 2); 1719 // CHECK: (d0)[s0, s1] : ( 1720 // CHECK-DAG: d0 - s0 == 0 1721 // CHECK-DAG: s1 - 42 >= 0 1722 mlirIntegerSetDump(replaced); 1723 1724 if (mlirIntegerSetGetNumDims(set) != 2) 1725 return 3; 1726 if (mlirIntegerSetGetNumDims(replaced) != 1) 1727 return 4; 1728 1729 if (mlirIntegerSetGetNumSymbols(set) != 1) 1730 return 5; 1731 if (mlirIntegerSetGetNumSymbols(replaced) != 2) 1732 return 6; 1733 1734 if (mlirIntegerSetGetNumInputs(set) != 3) 1735 return 7; 1736 1737 if (mlirIntegerSetGetNumConstraints(set) != 2) 1738 return 8; 1739 1740 if (mlirIntegerSetGetNumEqualities(set) != 1) 1741 return 9; 1742 1743 if (mlirIntegerSetGetNumInequalities(set) != 1) 1744 return 10; 1745 1746 MlirAffineExpr cstr1 = mlirIntegerSetGetConstraint(set, 0); 1747 MlirAffineExpr cstr2 = mlirIntegerSetGetConstraint(set, 1); 1748 bool isEq1 = mlirIntegerSetIsConstraintEq(set, 0); 1749 bool isEq2 = mlirIntegerSetIsConstraintEq(set, 1); 1750 if (!mlirAffineExprEqual(cstr1, isEq1 ? d0minusS0 : d1minus42)) 1751 return 11; 1752 if (!mlirAffineExprEqual(cstr2, isEq2 ? d0minusS0 : d1minus42)) 1753 return 12; 1754 1755 return 0; 1756 } 1757 1758 int registerOnlyStd(void) { 1759 MlirContext ctx = mlirContextCreate(); 1760 // The built-in dialect is always loaded. 1761 if (mlirContextGetNumLoadedDialects(ctx) != 1) 1762 return 1; 1763 1764 MlirDialectHandle stdHandle = mlirGetDialectHandle__func__(); 1765 1766 MlirDialect std = mlirContextGetOrLoadDialect( 1767 ctx, mlirDialectHandleGetNamespace(stdHandle)); 1768 if (!mlirDialectIsNull(std)) 1769 return 2; 1770 1771 mlirDialectHandleRegisterDialect(stdHandle, ctx); 1772 1773 std = mlirContextGetOrLoadDialect(ctx, 1774 mlirDialectHandleGetNamespace(stdHandle)); 1775 if (mlirDialectIsNull(std)) 1776 return 3; 1777 1778 MlirDialect alsoStd = mlirDialectHandleLoadDialect(stdHandle, ctx); 1779 if (!mlirDialectEqual(std, alsoStd)) 1780 return 4; 1781 1782 MlirStringRef stdNs = mlirDialectGetNamespace(std); 1783 MlirStringRef alsoStdNs = mlirDialectHandleGetNamespace(stdHandle); 1784 if (stdNs.length != alsoStdNs.length || 1785 strncmp(stdNs.data, alsoStdNs.data, stdNs.length)) 1786 return 5; 1787 1788 fprintf(stderr, "@registration\n"); 1789 // CHECK-LABEL: @registration 1790 1791 // CHECK: func.call is_registered: 1 1792 fprintf(stderr, "func.call is_registered: %d\n", 1793 mlirContextIsRegisteredOperation( 1794 ctx, mlirStringRefCreateFromCString("func.call"))); 1795 1796 // CHECK: func.not_existing_op is_registered: 0 1797 fprintf(stderr, "func.not_existing_op is_registered: %d\n", 1798 mlirContextIsRegisteredOperation( 1799 ctx, mlirStringRefCreateFromCString("func.not_existing_op"))); 1800 1801 // CHECK: not_existing_dialect.not_existing_op is_registered: 0 1802 fprintf(stderr, "not_existing_dialect.not_existing_op is_registered: %d\n", 1803 mlirContextIsRegisteredOperation( 1804 ctx, mlirStringRefCreateFromCString( 1805 "not_existing_dialect.not_existing_op"))); 1806 1807 mlirContextDestroy(ctx); 1808 return 0; 1809 } 1810 1811 /// Tests backreference APIs 1812 static int testBackreferences(void) { 1813 fprintf(stderr, "@test_backreferences\n"); 1814 1815 MlirContext ctx = mlirContextCreate(); 1816 mlirContextSetAllowUnregisteredDialects(ctx, true); 1817 MlirLocation loc = mlirLocationUnknownGet(ctx); 1818 1819 MlirOperationState opState = 1820 mlirOperationStateGet(mlirStringRefCreateFromCString("invalid.op"), loc); 1821 MlirRegion region = mlirRegionCreate(); 1822 MlirBlock block = mlirBlockCreate(0, NULL, NULL); 1823 mlirRegionAppendOwnedBlock(region, block); 1824 mlirOperationStateAddOwnedRegions(&opState, 1, ®ion); 1825 MlirOperation op = mlirOperationCreate(&opState); 1826 MlirIdentifier ident = 1827 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("identifier")); 1828 1829 if (!mlirContextEqual(ctx, mlirOperationGetContext(op))) { 1830 fprintf(stderr, "ERROR: Getting context from operation failed\n"); 1831 return 1; 1832 } 1833 if (!mlirOperationEqual(op, mlirBlockGetParentOperation(block))) { 1834 fprintf(stderr, "ERROR: Getting parent operation from block failed\n"); 1835 return 2; 1836 } 1837 if (!mlirContextEqual(ctx, mlirIdentifierGetContext(ident))) { 1838 fprintf(stderr, "ERROR: Getting context from identifier failed\n"); 1839 return 3; 1840 } 1841 1842 mlirOperationDestroy(op); 1843 mlirContextDestroy(ctx); 1844 1845 // CHECK-LABEL: @test_backreferences 1846 return 0; 1847 } 1848 1849 /// Tests operand APIs. 1850 int testOperands(void) { 1851 fprintf(stderr, "@testOperands\n"); 1852 // CHECK-LABEL: @testOperands 1853 1854 MlirContext ctx = mlirContextCreate(); 1855 registerAllUpstreamDialects(ctx); 1856 1857 mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("arith")); 1858 mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("test")); 1859 MlirLocation loc = mlirLocationUnknownGet(ctx); 1860 MlirType indexType = mlirIndexTypeGet(ctx); 1861 1862 // Create some constants to use as operands. 1863 MlirAttribute indexZeroLiteral = 1864 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("0 : index")); 1865 MlirNamedAttribute indexZeroValueAttr = mlirNamedAttributeGet( 1866 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), 1867 indexZeroLiteral); 1868 MlirOperationState constZeroState = mlirOperationStateGet( 1869 mlirStringRefCreateFromCString("arith.constant"), loc); 1870 mlirOperationStateAddResults(&constZeroState, 1, &indexType); 1871 mlirOperationStateAddAttributes(&constZeroState, 1, &indexZeroValueAttr); 1872 MlirOperation constZero = mlirOperationCreate(&constZeroState); 1873 MlirValue constZeroValue = mlirOperationGetResult(constZero, 0); 1874 1875 MlirAttribute indexOneLiteral = 1876 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("1 : index")); 1877 MlirNamedAttribute indexOneValueAttr = mlirNamedAttributeGet( 1878 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), 1879 indexOneLiteral); 1880 MlirOperationState constOneState = mlirOperationStateGet( 1881 mlirStringRefCreateFromCString("arith.constant"), loc); 1882 mlirOperationStateAddResults(&constOneState, 1, &indexType); 1883 mlirOperationStateAddAttributes(&constOneState, 1, &indexOneValueAttr); 1884 MlirOperation constOne = mlirOperationCreate(&constOneState); 1885 MlirValue constOneValue = mlirOperationGetResult(constOne, 0); 1886 1887 // Create the operation under test. 1888 mlirContextSetAllowUnregisteredDialects(ctx, true); 1889 MlirOperationState opState = 1890 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op"), loc); 1891 MlirValue initialOperands[] = {constZeroValue}; 1892 mlirOperationStateAddOperands(&opState, 1, initialOperands); 1893 MlirOperation op = mlirOperationCreate(&opState); 1894 1895 // Test operand APIs. 1896 intptr_t numOperands = mlirOperationGetNumOperands(op); 1897 fprintf(stderr, "Num Operands: %" PRIdPTR "\n", numOperands); 1898 // CHECK: Num Operands: 1 1899 1900 MlirValue opOperand1 = mlirOperationGetOperand(op, 0); 1901 fprintf(stderr, "Original operand: "); 1902 mlirValuePrint(opOperand1, printToStderr, NULL); 1903 // CHECK: Original operand: {{.+}} arith.constant 0 : index 1904 1905 mlirOperationSetOperand(op, 0, constOneValue); 1906 MlirValue opOperand2 = mlirOperationGetOperand(op, 0); 1907 fprintf(stderr, "Updated operand: "); 1908 mlirValuePrint(opOperand2, printToStderr, NULL); 1909 // CHECK: Updated operand: {{.+}} arith.constant 1 : index 1910 1911 // Test op operand APIs. 1912 MlirOpOperand use1 = mlirValueGetFirstUse(opOperand1); 1913 if (!mlirOpOperandIsNull(use1)) { 1914 fprintf(stderr, "ERROR: Use should be null\n"); 1915 return 1; 1916 } 1917 1918 MlirOpOperand use2 = mlirValueGetFirstUse(opOperand2); 1919 if (mlirOpOperandIsNull(use2)) { 1920 fprintf(stderr, "ERROR: Use should not be null\n"); 1921 return 2; 1922 } 1923 1924 fprintf(stderr, "Use owner: "); 1925 mlirOperationPrint(mlirOpOperandGetOwner(use2), printToStderr, NULL); 1926 fprintf(stderr, "\n"); 1927 // CHECK: Use owner: "dummy.op" 1928 1929 fprintf(stderr, "Use operandNumber: %d\n", 1930 mlirOpOperandGetOperandNumber(use2)); 1931 // CHECK: Use operandNumber: 0 1932 1933 use2 = mlirOpOperandGetNextUse(use2); 1934 if (!mlirOpOperandIsNull(use2)) { 1935 fprintf(stderr, "ERROR: Next use should be null\n"); 1936 return 3; 1937 } 1938 1939 MlirOperationState op2State = 1940 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op2"), loc); 1941 MlirValue initialOperands2[] = {constOneValue}; 1942 mlirOperationStateAddOperands(&op2State, 1, initialOperands2); 1943 MlirOperation op2 = mlirOperationCreate(&op2State); 1944 1945 MlirOpOperand use3 = mlirValueGetFirstUse(constOneValue); 1946 fprintf(stderr, "First use owner: "); 1947 mlirOperationPrint(mlirOpOperandGetOwner(use3), printToStderr, NULL); 1948 fprintf(stderr, "\n"); 1949 // CHECK: First use owner: "dummy.op2" 1950 1951 use3 = mlirOpOperandGetNextUse(mlirValueGetFirstUse(constOneValue)); 1952 fprintf(stderr, "Second use owner: "); 1953 mlirOperationPrint(mlirOpOperandGetOwner(use3), printToStderr, NULL); 1954 fprintf(stderr, "\n"); 1955 // CHECK: Second use owner: "dummy.op" 1956 1957 MlirAttribute indexTwoLiteral = 1958 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("2 : index")); 1959 MlirNamedAttribute indexTwoValueAttr = mlirNamedAttributeGet( 1960 mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), 1961 indexTwoLiteral); 1962 MlirOperationState constTwoState = mlirOperationStateGet( 1963 mlirStringRefCreateFromCString("arith.constant"), loc); 1964 mlirOperationStateAddResults(&constTwoState, 1, &indexType); 1965 mlirOperationStateAddAttributes(&constTwoState, 1, &indexTwoValueAttr); 1966 MlirOperation constTwo = mlirOperationCreate(&constTwoState); 1967 MlirValue constTwoValue = mlirOperationGetResult(constTwo, 0); 1968 1969 mlirValueReplaceAllUsesOfWith(constOneValue, constTwoValue); 1970 1971 use3 = mlirValueGetFirstUse(constOneValue); 1972 if (!mlirOpOperandIsNull(use3)) { 1973 fprintf(stderr, "ERROR: Use should be null\n"); 1974 return 4; 1975 } 1976 1977 MlirOpOperand use4 = mlirValueGetFirstUse(constTwoValue); 1978 fprintf(stderr, "First replacement use owner: "); 1979 mlirOperationPrint(mlirOpOperandGetOwner(use4), printToStderr, NULL); 1980 fprintf(stderr, "\n"); 1981 // CHECK: First replacement use owner: "dummy.op" 1982 1983 use4 = mlirOpOperandGetNextUse(mlirValueGetFirstUse(constTwoValue)); 1984 fprintf(stderr, "Second replacement use owner: "); 1985 mlirOperationPrint(mlirOpOperandGetOwner(use4), printToStderr, NULL); 1986 fprintf(stderr, "\n"); 1987 // CHECK: Second replacement use owner: "dummy.op2" 1988 1989 MlirOpOperand use5 = mlirValueGetFirstUse(constTwoValue); 1990 MlirOpOperand use6 = mlirOpOperandGetNextUse(use5); 1991 if (!mlirValueEqual(mlirOpOperandGetValue(use5), 1992 mlirOpOperandGetValue(use6))) { 1993 fprintf(stderr, 1994 "ERROR: First and second operand should share the same value\n"); 1995 return 5; 1996 } 1997 1998 mlirOperationDestroy(op); 1999 mlirOperationDestroy(op2); 2000 mlirOperationDestroy(constZero); 2001 mlirOperationDestroy(constOne); 2002 mlirOperationDestroy(constTwo); 2003 mlirContextDestroy(ctx); 2004 2005 return 0; 2006 } 2007 2008 /// Tests clone APIs. 2009 int testClone(void) { 2010 fprintf(stderr, "@testClone\n"); 2011 // CHECK-LABEL: @testClone 2012 2013 MlirContext ctx = mlirContextCreate(); 2014 registerAllUpstreamDialects(ctx); 2015 2016 mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("func")); 2017 mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("arith")); 2018 MlirLocation loc = mlirLocationUnknownGet(ctx); 2019 MlirType indexType = mlirIndexTypeGet(ctx); 2020 MlirStringRef valueStringRef = mlirStringRefCreateFromCString("value"); 2021 2022 MlirAttribute indexZeroLiteral = 2023 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("0 : index")); 2024 MlirNamedAttribute indexZeroValueAttr = mlirNamedAttributeGet( 2025 mlirIdentifierGet(ctx, valueStringRef), indexZeroLiteral); 2026 MlirOperationState constZeroState = mlirOperationStateGet( 2027 mlirStringRefCreateFromCString("arith.constant"), loc); 2028 mlirOperationStateAddResults(&constZeroState, 1, &indexType); 2029 mlirOperationStateAddAttributes(&constZeroState, 1, &indexZeroValueAttr); 2030 MlirOperation constZero = mlirOperationCreate(&constZeroState); 2031 2032 MlirAttribute indexOneLiteral = 2033 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("1 : index")); 2034 MlirOperation constOne = mlirOperationClone(constZero); 2035 mlirOperationSetAttributeByName(constOne, valueStringRef, indexOneLiteral); 2036 2037 mlirOperationPrint(constZero, printToStderr, NULL); 2038 mlirOperationPrint(constOne, printToStderr, NULL); 2039 // CHECK: arith.constant 0 : index 2040 // CHECK: arith.constant 1 : index 2041 2042 mlirOperationDestroy(constZero); 2043 mlirOperationDestroy(constOne); 2044 mlirContextDestroy(ctx); 2045 return 0; 2046 } 2047 2048 // Wraps a diagnostic into additional text we can match against. 2049 MlirLogicalResult errorHandler(MlirDiagnostic diagnostic, void *userData) { 2050 fprintf(stderr, "processing diagnostic (userData: %" PRIdPTR ") <<\n", 2051 (intptr_t)userData); 2052 mlirDiagnosticPrint(diagnostic, printToStderr, NULL); 2053 fprintf(stderr, "\n"); 2054 MlirLocation loc = mlirDiagnosticGetLocation(diagnostic); 2055 mlirLocationPrint(loc, printToStderr, NULL); 2056 assert(mlirDiagnosticGetNumNotes(diagnostic) == 0); 2057 fprintf(stderr, "\n>> end of diagnostic (userData: %" PRIdPTR ")\n", 2058 (intptr_t)userData); 2059 return mlirLogicalResultSuccess(); 2060 } 2061 2062 // Logs when the delete user data callback is called 2063 static void deleteUserData(void *userData) { 2064 fprintf(stderr, "deleting user data (userData: %" PRIdPTR ")\n", 2065 (intptr_t)userData); 2066 } 2067 2068 int testTypeID(MlirContext ctx) { 2069 fprintf(stderr, "@testTypeID\n"); 2070 2071 // Test getting and comparing type and attribute type ids. 2072 MlirType i32 = mlirIntegerTypeGet(ctx, 32); 2073 MlirTypeID i32ID = mlirTypeGetTypeID(i32); 2074 MlirType ui32 = mlirIntegerTypeUnsignedGet(ctx, 32); 2075 MlirTypeID ui32ID = mlirTypeGetTypeID(ui32); 2076 MlirType f32 = mlirF32TypeGet(ctx); 2077 MlirTypeID f32ID = mlirTypeGetTypeID(f32); 2078 MlirAttribute i32Attr = mlirIntegerAttrGet(i32, 1); 2079 MlirTypeID i32AttrID = mlirAttributeGetTypeID(i32Attr); 2080 2081 if (mlirTypeIDIsNull(i32ID) || mlirTypeIDIsNull(ui32ID) || 2082 mlirTypeIDIsNull(f32ID) || mlirTypeIDIsNull(i32AttrID)) { 2083 fprintf(stderr, "ERROR: Expected type ids to be present\n"); 2084 return 1; 2085 } 2086 2087 if (!mlirTypeIDEqual(i32ID, ui32ID) || 2088 mlirTypeIDHashValue(i32ID) != mlirTypeIDHashValue(ui32ID)) { 2089 fprintf( 2090 stderr, 2091 "ERROR: Expected different integer types to have the same type id\n"); 2092 return 2; 2093 } 2094 2095 if (mlirTypeIDEqual(i32ID, f32ID)) { 2096 fprintf(stderr, 2097 "ERROR: Expected integer type id to not equal float type id\n"); 2098 return 3; 2099 } 2100 2101 if (mlirTypeIDEqual(i32ID, i32AttrID)) { 2102 fprintf(stderr, "ERROR: Expected integer type id to not equal integer " 2103 "attribute type id\n"); 2104 return 4; 2105 } 2106 2107 MlirLocation loc = mlirLocationUnknownGet(ctx); 2108 MlirType indexType = mlirIndexTypeGet(ctx); 2109 MlirStringRef valueStringRef = mlirStringRefCreateFromCString("value"); 2110 2111 // Create a registered operation, which should have a type id. 2112 MlirAttribute indexZeroLiteral = 2113 mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("0 : index")); 2114 MlirNamedAttribute indexZeroValueAttr = mlirNamedAttributeGet( 2115 mlirIdentifierGet(ctx, valueStringRef), indexZeroLiteral); 2116 MlirOperationState constZeroState = mlirOperationStateGet( 2117 mlirStringRefCreateFromCString("arith.constant"), loc); 2118 mlirOperationStateAddResults(&constZeroState, 1, &indexType); 2119 mlirOperationStateAddAttributes(&constZeroState, 1, &indexZeroValueAttr); 2120 MlirOperation constZero = mlirOperationCreate(&constZeroState); 2121 2122 if (!mlirOperationVerify(constZero)) { 2123 fprintf(stderr, "ERROR: Expected operation to verify correctly\n"); 2124 return 5; 2125 } 2126 2127 if (mlirOperationIsNull(constZero)) { 2128 fprintf(stderr, "ERROR: Expected registered operation to be present\n"); 2129 return 6; 2130 } 2131 2132 MlirTypeID registeredOpID = mlirOperationGetTypeID(constZero); 2133 2134 if (mlirTypeIDIsNull(registeredOpID)) { 2135 fprintf(stderr, 2136 "ERROR: Expected registered operation type id to be present\n"); 2137 return 7; 2138 } 2139 2140 // Create an unregistered operation, which should not have a type id. 2141 mlirContextSetAllowUnregisteredDialects(ctx, true); 2142 MlirOperationState opState = 2143 mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op"), loc); 2144 MlirOperation unregisteredOp = mlirOperationCreate(&opState); 2145 if (mlirOperationIsNull(unregisteredOp)) { 2146 fprintf(stderr, "ERROR: Expected unregistered operation to be present\n"); 2147 return 8; 2148 } 2149 2150 MlirTypeID unregisteredOpID = mlirOperationGetTypeID(unregisteredOp); 2151 2152 if (!mlirTypeIDIsNull(unregisteredOpID)) { 2153 fprintf(stderr, 2154 "ERROR: Expected unregistered operation type id to be null\n"); 2155 return 9; 2156 } 2157 2158 mlirOperationDestroy(constZero); 2159 mlirOperationDestroy(unregisteredOp); 2160 2161 return 0; 2162 } 2163 2164 int testSymbolTable(MlirContext ctx) { 2165 fprintf(stderr, "@testSymbolTable\n"); 2166 2167 const char *moduleString = "func.func private @foo()" 2168 "func.func private @bar()"; 2169 const char *otherModuleString = "func.func private @qux()" 2170 "func.func private @foo()"; 2171 2172 MlirModule module = 2173 mlirModuleCreateParse(ctx, mlirStringRefCreateFromCString(moduleString)); 2174 MlirModule otherModule = mlirModuleCreateParse( 2175 ctx, mlirStringRefCreateFromCString(otherModuleString)); 2176 2177 MlirSymbolTable symbolTable = 2178 mlirSymbolTableCreate(mlirModuleGetOperation(module)); 2179 2180 MlirOperation funcFoo = 2181 mlirSymbolTableLookup(symbolTable, mlirStringRefCreateFromCString("foo")); 2182 if (mlirOperationIsNull(funcFoo)) 2183 return 1; 2184 2185 MlirOperation funcBar = 2186 mlirSymbolTableLookup(symbolTable, mlirStringRefCreateFromCString("bar")); 2187 if (mlirOperationEqual(funcFoo, funcBar)) 2188 return 2; 2189 2190 MlirOperation missing = 2191 mlirSymbolTableLookup(symbolTable, mlirStringRefCreateFromCString("qux")); 2192 if (!mlirOperationIsNull(missing)) 2193 return 3; 2194 2195 MlirBlock moduleBody = mlirModuleGetBody(module); 2196 MlirBlock otherModuleBody = mlirModuleGetBody(otherModule); 2197 MlirOperation operation = mlirBlockGetFirstOperation(otherModuleBody); 2198 mlirOperationRemoveFromParent(operation); 2199 mlirBlockAppendOwnedOperation(moduleBody, operation); 2200 2201 // At this moment, the operation is still missing from the symbol table. 2202 MlirOperation stillMissing = 2203 mlirSymbolTableLookup(symbolTable, mlirStringRefCreateFromCString("qux")); 2204 if (!mlirOperationIsNull(stillMissing)) 2205 return 4; 2206 2207 // After it is added to the symbol table, and not only the operation with 2208 // which the table is associated, it can be looked up. 2209 mlirSymbolTableInsert(symbolTable, operation); 2210 MlirOperation funcQux = 2211 mlirSymbolTableLookup(symbolTable, mlirStringRefCreateFromCString("qux")); 2212 if (!mlirOperationEqual(operation, funcQux)) 2213 return 5; 2214 2215 // Erasing from the symbol table also removes the operation. 2216 mlirSymbolTableErase(symbolTable, funcBar); 2217 MlirOperation nowMissing = 2218 mlirSymbolTableLookup(symbolTable, mlirStringRefCreateFromCString("bar")); 2219 if (!mlirOperationIsNull(nowMissing)) 2220 return 6; 2221 2222 // Adding a symbol with the same name to the table should rename. 2223 MlirOperation duplicateNameOp = mlirBlockGetFirstOperation(otherModuleBody); 2224 mlirOperationRemoveFromParent(duplicateNameOp); 2225 mlirBlockAppendOwnedOperation(moduleBody, duplicateNameOp); 2226 MlirAttribute newName = mlirSymbolTableInsert(symbolTable, duplicateNameOp); 2227 MlirStringRef newNameStr = mlirStringAttrGetValue(newName); 2228 if (mlirStringRefEqual(newNameStr, mlirStringRefCreateFromCString("foo"))) 2229 return 7; 2230 MlirAttribute updatedName = mlirOperationGetAttributeByName( 2231 duplicateNameOp, mlirSymbolTableGetSymbolAttributeName()); 2232 if (!mlirAttributeEqual(updatedName, newName)) 2233 return 8; 2234 2235 mlirOperationDump(mlirModuleGetOperation(module)); 2236 mlirOperationDump(mlirModuleGetOperation(otherModule)); 2237 // clang-format off 2238 // CHECK-LABEL: @testSymbolTable 2239 // CHECK: module 2240 // CHECK: func private @foo 2241 // CHECK: func private @qux 2242 // CHECK: func private @foo{{.+}} 2243 // CHECK: module 2244 // CHECK-NOT: @qux 2245 // CHECK-NOT: @foo 2246 // clang-format on 2247 2248 mlirSymbolTableDestroy(symbolTable); 2249 mlirModuleDestroy(module); 2250 mlirModuleDestroy(otherModule); 2251 2252 return 0; 2253 } 2254 2255 typedef struct { 2256 const char *x; 2257 } callBackData; 2258 2259 MlirWalkResult walkCallBack(MlirOperation op, void *rootOpVoid) { 2260 fprintf(stderr, "%s: %s\n", ((callBackData *)(rootOpVoid))->x, 2261 mlirIdentifierStr(mlirOperationGetName(op)).data); 2262 return MlirWalkResultAdvance; 2263 } 2264 2265 MlirWalkResult walkCallBackTestWalkResult(MlirOperation op, void *rootOpVoid) { 2266 fprintf(stderr, "%s: %s\n", ((callBackData *)(rootOpVoid))->x, 2267 mlirIdentifierStr(mlirOperationGetName(op)).data); 2268 if (strcmp(mlirIdentifierStr(mlirOperationGetName(op)).data, "func.func") == 2269 0) 2270 return MlirWalkResultSkip; 2271 if (strcmp(mlirIdentifierStr(mlirOperationGetName(op)).data, "arith.addi") == 2272 0) 2273 return MlirWalkResultInterrupt; 2274 return MlirWalkResultAdvance; 2275 } 2276 2277 int testOperationWalk(MlirContext ctx) { 2278 // CHECK-LABEL: @testOperationWalk 2279 fprintf(stderr, "@testOperationWalk\n"); 2280 2281 const char *moduleString = "module {\n" 2282 " func.func @foo() {\n" 2283 " %1 = arith.constant 10: i32\n" 2284 " arith.addi %1, %1: i32\n" 2285 " return\n" 2286 " }\n" 2287 " func.func @bar() {\n" 2288 " return\n" 2289 " }\n" 2290 "}"; 2291 MlirModule module = 2292 mlirModuleCreateParse(ctx, mlirStringRefCreateFromCString(moduleString)); 2293 2294 callBackData data; 2295 data.x = "i love you"; 2296 2297 // CHECK-NEXT: i love you: arith.constant 2298 // CHECK-NEXT: i love you: arith.addi 2299 // CHECK-NEXT: i love you: func.return 2300 // CHECK-NEXT: i love you: func.func 2301 // CHECK-NEXT: i love you: func.return 2302 // CHECK-NEXT: i love you: func.func 2303 // CHECK-NEXT: i love you: builtin.module 2304 mlirOperationWalk(mlirModuleGetOperation(module), walkCallBack, 2305 (void *)(&data), MlirWalkPostOrder); 2306 2307 data.x = "i don't love you"; 2308 // CHECK-NEXT: i don't love you: builtin.module 2309 // CHECK-NEXT: i don't love you: func.func 2310 // CHECK-NEXT: i don't love you: arith.constant 2311 // CHECK-NEXT: i don't love you: arith.addi 2312 // CHECK-NEXT: i don't love you: func.return 2313 // CHECK-NEXT: i don't love you: func.func 2314 // CHECK-NEXT: i don't love you: func.return 2315 mlirOperationWalk(mlirModuleGetOperation(module), walkCallBack, 2316 (void *)(&data), MlirWalkPreOrder); 2317 2318 data.x = "interrupt"; 2319 // Interrupted at `arith.addi` 2320 // CHECK-NEXT: interrupt: arith.constant 2321 // CHECK-NEXT: interrupt: arith.addi 2322 mlirOperationWalk(mlirModuleGetOperation(module), walkCallBackTestWalkResult, 2323 (void *)(&data), MlirWalkPostOrder); 2324 2325 data.x = "skip"; 2326 // Skip at `func.func` 2327 // CHECK-NEXT: skip: builtin.module 2328 // CHECK-NEXT: skip: func.func 2329 // CHECK-NEXT: skip: func.func 2330 mlirOperationWalk(mlirModuleGetOperation(module), walkCallBackTestWalkResult, 2331 (void *)(&data), MlirWalkPreOrder); 2332 2333 mlirModuleDestroy(module); 2334 return 0; 2335 } 2336 2337 int testDialectRegistry(void) { 2338 fprintf(stderr, "@testDialectRegistry\n"); 2339 2340 MlirDialectRegistry registry = mlirDialectRegistryCreate(); 2341 if (mlirDialectRegistryIsNull(registry)) { 2342 fprintf(stderr, "ERROR: Expected registry to be present\n"); 2343 return 1; 2344 } 2345 2346 MlirDialectHandle stdHandle = mlirGetDialectHandle__func__(); 2347 mlirDialectHandleInsertDialect(stdHandle, registry); 2348 2349 MlirContext ctx = mlirContextCreate(); 2350 if (mlirContextGetNumRegisteredDialects(ctx) != 0) { 2351 fprintf(stderr, 2352 "ERROR: Expected no dialects to be registered to new context\n"); 2353 } 2354 2355 mlirContextAppendDialectRegistry(ctx, registry); 2356 if (mlirContextGetNumRegisteredDialects(ctx) != 1) { 2357 fprintf(stderr, "ERROR: Expected the dialect in the registry to be " 2358 "registered to the context\n"); 2359 } 2360 2361 mlirContextDestroy(ctx); 2362 mlirDialectRegistryDestroy(registry); 2363 2364 return 0; 2365 } 2366 2367 void testExplicitThreadPools(void) { 2368 MlirLlvmThreadPool threadPool = mlirLlvmThreadPoolCreate(); 2369 MlirDialectRegistry registry = mlirDialectRegistryCreate(); 2370 mlirRegisterAllDialects(registry); 2371 MlirContext context = 2372 mlirContextCreateWithRegistry(registry, /*threadingEnabled=*/false); 2373 mlirContextSetThreadPool(context, threadPool); 2374 mlirContextDestroy(context); 2375 mlirDialectRegistryDestroy(registry); 2376 mlirLlvmThreadPoolDestroy(threadPool); 2377 } 2378 2379 void testDiagnostics(void) { 2380 MlirContext ctx = mlirContextCreate(); 2381 MlirDiagnosticHandlerID id = mlirContextAttachDiagnosticHandler( 2382 ctx, errorHandler, (void *)42, deleteUserData); 2383 fprintf(stderr, "@test_diagnostics\n"); 2384 MlirLocation unknownLoc = mlirLocationUnknownGet(ctx); 2385 mlirEmitError(unknownLoc, "test diagnostics"); 2386 MlirAttribute unknownAttr = mlirLocationGetAttribute(unknownLoc); 2387 MlirLocation unknownClone = mlirLocationFromAttribute(unknownAttr); 2388 mlirEmitError(unknownClone, "test clone"); 2389 MlirLocation fileLineColLoc = mlirLocationFileLineColGet( 2390 ctx, mlirStringRefCreateFromCString("file.c"), 1, 2); 2391 mlirEmitError(fileLineColLoc, "test diagnostics"); 2392 MlirLocation fileLineColRange = mlirLocationFileLineColRangeGet( 2393 ctx, mlirStringRefCreateFromCString("other-file.c"), 1, 2, 3, 4); 2394 mlirEmitError(fileLineColRange, "test diagnostics"); 2395 MlirLocation callSiteLoc = mlirLocationCallSiteGet( 2396 mlirLocationFileLineColGet( 2397 ctx, mlirStringRefCreateFromCString("other-file.c"), 2, 3), 2398 fileLineColLoc); 2399 mlirEmitError(callSiteLoc, "test diagnostics"); 2400 MlirLocation null = {0}; 2401 MlirLocation nameLoc = 2402 mlirLocationNameGet(ctx, mlirStringRefCreateFromCString("named"), null); 2403 mlirEmitError(nameLoc, "test diagnostics"); 2404 MlirLocation locs[2] = {nameLoc, callSiteLoc}; 2405 MlirAttribute nullAttr = {0}; 2406 MlirLocation fusedLoc = mlirLocationFusedGet(ctx, 2, locs, nullAttr); 2407 mlirEmitError(fusedLoc, "test diagnostics"); 2408 mlirContextDetachDiagnosticHandler(ctx, id); 2409 mlirEmitError(unknownLoc, "more test diagnostics"); 2410 // CHECK-LABEL: @test_diagnostics 2411 // CHECK: processing diagnostic (userData: 42) << 2412 // CHECK: test diagnostics 2413 // CHECK: loc(unknown) 2414 // CHECK: processing diagnostic (userData: 42) << 2415 // CHECK: test clone 2416 // CHECK: loc(unknown) 2417 // CHECK: >> end of diagnostic (userData: 42) 2418 // CHECK: processing diagnostic (userData: 42) << 2419 // CHECK: test diagnostics 2420 // CHECK: loc("file.c":1:2) 2421 // CHECK: >> end of diagnostic (userData: 42) 2422 // CHECK: processing diagnostic (userData: 42) << 2423 // CHECK: test diagnostics 2424 // CHECK: loc("other-file.c":1:2 to 3:4) 2425 // CHECK: >> end of diagnostic (userData: 42) 2426 // CHECK: processing diagnostic (userData: 42) << 2427 // CHECK: test diagnostics 2428 // CHECK: loc(callsite("other-file.c":2:3 at "file.c":1:2)) 2429 // CHECK: >> end of diagnostic (userData: 42) 2430 // CHECK: processing diagnostic (userData: 42) << 2431 // CHECK: test diagnostics 2432 // CHECK: loc("named") 2433 // CHECK: >> end of diagnostic (userData: 42) 2434 // CHECK: processing diagnostic (userData: 42) << 2435 // CHECK: test diagnostics 2436 // CHECK: loc(fused["named", callsite("other-file.c":2:3 at "file.c":1:2)]) 2437 // CHECK: deleting user data (userData: 42) 2438 // CHECK-NOT: processing diagnostic 2439 // CHECK: more test diagnostics 2440 mlirContextDestroy(ctx); 2441 } 2442 2443 int main(void) { 2444 MlirContext ctx = mlirContextCreate(); 2445 registerAllUpstreamDialects(ctx); 2446 mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("func")); 2447 mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("memref")); 2448 mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("shape")); 2449 mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("scf")); 2450 2451 if (constructAndTraverseIr(ctx)) 2452 return 1; 2453 buildWithInsertionsAndPrint(ctx); 2454 if (createOperationWithTypeInference(ctx)) 2455 return 2; 2456 2457 if (printBuiltinTypes(ctx)) 2458 return 3; 2459 if (printBuiltinAttributes(ctx)) 2460 return 4; 2461 if (printAffineMap(ctx)) 2462 return 5; 2463 if (printAffineExpr(ctx)) 2464 return 6; 2465 if (affineMapFromExprs(ctx)) 2466 return 7; 2467 if (printIntegerSet(ctx)) 2468 return 8; 2469 if (registerOnlyStd()) 2470 return 9; 2471 if (testBackreferences()) 2472 return 10; 2473 if (testOperands()) 2474 return 11; 2475 if (testClone()) 2476 return 12; 2477 if (testTypeID(ctx)) 2478 return 13; 2479 if (testSymbolTable(ctx)) 2480 return 14; 2481 if (testDialectRegistry()) 2482 return 15; 2483 if (testOperationWalk(ctx)) 2484 return 16; 2485 2486 testExplicitThreadPools(); 2487 testDiagnostics(); 2488 2489 // CHECK: DESTROY MAIN CONTEXT 2490 // CHECK: reportResourceDelete: resource_i64_blob 2491 fprintf(stderr, "DESTROY MAIN CONTEXT\n"); 2492 mlirContextDestroy(ctx); 2493 2494 return 0; 2495 } 2496