2020-11-05 02:08:34 +08:00
|
|
|
//===- ir.c - Simple test of C APIs ---------------------------------------===//
|
|
|
|
//
|
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM
|
|
|
|
// Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2020-08-05 20:36:16 +08:00
|
|
|
|
|
|
|
/* RUN: mlir-capi-ir-test 2>&1 | FileCheck %s
|
|
|
|
*/
|
|
|
|
|
2020-10-21 14:20:04 +08:00
|
|
|
#include "mlir-c/IR.h"
|
2020-10-21 15:32:01 +08:00
|
|
|
#include "mlir-c/AffineExpr.h"
|
2020-09-28 22:28:04 +08:00
|
|
|
#include "mlir-c/AffineMap.h"
|
2020-12-04 09:22:57 +08:00
|
|
|
#include "mlir-c/BuiltinAttributes.h"
|
2020-12-04 09:22:29 +08:00
|
|
|
#include "mlir-c/BuiltinTypes.h"
|
2020-10-07 20:38:10 +08:00
|
|
|
#include "mlir-c/Diagnostics.h"
|
2021-01-10 11:01:39 +08:00
|
|
|
#include "mlir-c/Dialect/Standard.h"
|
2021-01-26 00:12:35 +08:00
|
|
|
#include "mlir-c/IntegerSet.h"
|
2020-08-05 20:36:16 +08:00
|
|
|
#include "mlir-c/Registration.h"
|
|
|
|
|
|
|
|
#include <assert.h>
|
2020-08-20 00:38:56 +08:00
|
|
|
#include <math.h>
|
2020-08-05 20:36:16 +08:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2020-08-20 00:38:56 +08:00
|
|
|
#include <string.h>
|
2020-08-05 20:36:16 +08:00
|
|
|
|
|
|
|
void populateLoopBody(MlirContext ctx, MlirBlock loopBody,
|
|
|
|
MlirLocation location, MlirBlock funcBody) {
|
|
|
|
MlirValue iv = mlirBlockGetArgument(loopBody, 0);
|
|
|
|
MlirValue funcArg0 = mlirBlockGetArgument(funcBody, 0);
|
|
|
|
MlirValue funcArg1 = mlirBlockGetArgument(funcBody, 1);
|
2020-11-24 05:08:00 +08:00
|
|
|
MlirType f32Type =
|
|
|
|
mlirTypeParseGet(ctx, mlirStringRefCreateFromCString("f32"));
|
2020-08-05 20:36:16 +08:00
|
|
|
|
2020-11-24 05:08:00 +08:00
|
|
|
MlirOperationState loadLHSState = mlirOperationStateGet(
|
|
|
|
mlirStringRefCreateFromCString("std.load"), location);
|
2020-08-05 20:36:16 +08:00
|
|
|
MlirValue loadLHSOperands[] = {funcArg0, iv};
|
|
|
|
mlirOperationStateAddOperands(&loadLHSState, 2, loadLHSOperands);
|
|
|
|
mlirOperationStateAddResults(&loadLHSState, 1, &f32Type);
|
|
|
|
MlirOperation loadLHS = mlirOperationCreate(&loadLHSState);
|
|
|
|
mlirBlockAppendOwnedOperation(loopBody, loadLHS);
|
|
|
|
|
2020-11-24 05:08:00 +08:00
|
|
|
MlirOperationState loadRHSState = mlirOperationStateGet(
|
|
|
|
mlirStringRefCreateFromCString("std.load"), location);
|
2020-08-05 20:36:16 +08:00
|
|
|
MlirValue loadRHSOperands[] = {funcArg1, iv};
|
|
|
|
mlirOperationStateAddOperands(&loadRHSState, 2, loadRHSOperands);
|
|
|
|
mlirOperationStateAddResults(&loadRHSState, 1, &f32Type);
|
|
|
|
MlirOperation loadRHS = mlirOperationCreate(&loadRHSState);
|
|
|
|
mlirBlockAppendOwnedOperation(loopBody, loadRHS);
|
|
|
|
|
2020-11-24 05:08:00 +08:00
|
|
|
MlirOperationState addState = mlirOperationStateGet(
|
|
|
|
mlirStringRefCreateFromCString("std.addf"), location);
|
2020-08-05 20:36:16 +08:00
|
|
|
MlirValue addOperands[] = {mlirOperationGetResult(loadLHS, 0),
|
|
|
|
mlirOperationGetResult(loadRHS, 0)};
|
|
|
|
mlirOperationStateAddOperands(&addState, 2, addOperands);
|
|
|
|
mlirOperationStateAddResults(&addState, 1, &f32Type);
|
|
|
|
MlirOperation add = mlirOperationCreate(&addState);
|
|
|
|
mlirBlockAppendOwnedOperation(loopBody, add);
|
|
|
|
|
2020-11-24 05:08:00 +08:00
|
|
|
MlirOperationState storeState = mlirOperationStateGet(
|
|
|
|
mlirStringRefCreateFromCString("std.store"), location);
|
2020-08-05 20:36:16 +08:00
|
|
|
MlirValue storeOperands[] = {mlirOperationGetResult(add, 0), funcArg0, iv};
|
|
|
|
mlirOperationStateAddOperands(&storeState, 3, storeOperands);
|
|
|
|
MlirOperation store = mlirOperationCreate(&storeState);
|
|
|
|
mlirBlockAppendOwnedOperation(loopBody, store);
|
|
|
|
|
2020-11-24 05:08:00 +08:00
|
|
|
MlirOperationState yieldState = mlirOperationStateGet(
|
|
|
|
mlirStringRefCreateFromCString("scf.yield"), location);
|
2020-08-05 20:36:16 +08:00
|
|
|
MlirOperation yield = mlirOperationCreate(&yieldState);
|
|
|
|
mlirBlockAppendOwnedOperation(loopBody, yield);
|
|
|
|
}
|
|
|
|
|
2020-11-04 17:30:00 +08:00
|
|
|
MlirModule makeAndDumpAdd(MlirContext ctx, MlirLocation location) {
|
2020-08-05 20:36:16 +08:00
|
|
|
MlirModule moduleOp = mlirModuleCreateEmpty(location);
|
2020-10-28 13:57:17 +08:00
|
|
|
MlirBlock moduleBody = mlirModuleGetBody(moduleOp);
|
2020-08-05 20:36:16 +08:00
|
|
|
|
2020-11-24 05:08:00 +08:00
|
|
|
MlirType memrefType =
|
|
|
|
mlirTypeParseGet(ctx, mlirStringRefCreateFromCString("memref<?xf32>"));
|
2020-08-05 20:36:16 +08:00
|
|
|
MlirType funcBodyArgTypes[] = {memrefType, memrefType};
|
|
|
|
MlirRegion funcBodyRegion = mlirRegionCreate();
|
|
|
|
MlirBlock funcBody = mlirBlockCreate(
|
|
|
|
sizeof(funcBodyArgTypes) / sizeof(MlirType), funcBodyArgTypes);
|
|
|
|
mlirRegionAppendOwnedBlock(funcBodyRegion, funcBody);
|
|
|
|
|
2020-11-24 05:08:00 +08:00
|
|
|
MlirAttribute funcTypeAttr = mlirAttributeParseGet(
|
|
|
|
ctx,
|
|
|
|
mlirStringRefCreateFromCString("(memref<?xf32>, memref<?xf32>) -> ()"));
|
|
|
|
MlirAttribute funcNameAttr =
|
|
|
|
mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("\"add\""));
|
2020-08-05 20:36:16 +08:00
|
|
|
MlirNamedAttribute funcAttrs[] = {
|
2020-12-12 02:50:04 +08:00
|
|
|
mlirNamedAttributeGet(
|
|
|
|
mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("type")),
|
|
|
|
funcTypeAttr),
|
|
|
|
mlirNamedAttributeGet(
|
|
|
|
mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("sym_name")),
|
|
|
|
funcNameAttr)};
|
2020-11-24 05:08:00 +08:00
|
|
|
MlirOperationState funcState =
|
|
|
|
mlirOperationStateGet(mlirStringRefCreateFromCString("func"), location);
|
2020-08-05 20:36:16 +08:00
|
|
|
mlirOperationStateAddAttributes(&funcState, 2, funcAttrs);
|
|
|
|
mlirOperationStateAddOwnedRegions(&funcState, 1, &funcBodyRegion);
|
|
|
|
MlirOperation func = mlirOperationCreate(&funcState);
|
|
|
|
mlirBlockInsertOwnedOperation(moduleBody, 0, func);
|
|
|
|
|
2020-11-24 05:08:00 +08:00
|
|
|
MlirType indexType =
|
|
|
|
mlirTypeParseGet(ctx, mlirStringRefCreateFromCString("index"));
|
|
|
|
MlirAttribute indexZeroLiteral =
|
|
|
|
mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("0 : index"));
|
|
|
|
MlirNamedAttribute indexZeroValueAttr = mlirNamedAttributeGet(
|
2020-12-12 02:50:04 +08:00
|
|
|
mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")),
|
|
|
|
indexZeroLiteral);
|
2020-11-24 05:08:00 +08:00
|
|
|
MlirOperationState constZeroState = mlirOperationStateGet(
|
|
|
|
mlirStringRefCreateFromCString("std.constant"), location);
|
2020-08-05 20:36:16 +08:00
|
|
|
mlirOperationStateAddResults(&constZeroState, 1, &indexType);
|
|
|
|
mlirOperationStateAddAttributes(&constZeroState, 1, &indexZeroValueAttr);
|
|
|
|
MlirOperation constZero = mlirOperationCreate(&constZeroState);
|
|
|
|
mlirBlockAppendOwnedOperation(funcBody, constZero);
|
|
|
|
|
|
|
|
MlirValue funcArg0 = mlirBlockGetArgument(funcBody, 0);
|
|
|
|
MlirValue constZeroValue = mlirOperationGetResult(constZero, 0);
|
|
|
|
MlirValue dimOperands[] = {funcArg0, constZeroValue};
|
2020-11-24 05:08:00 +08:00
|
|
|
MlirOperationState dimState = mlirOperationStateGet(
|
|
|
|
mlirStringRefCreateFromCString("std.dim"), location);
|
2020-08-05 20:36:16 +08:00
|
|
|
mlirOperationStateAddOperands(&dimState, 2, dimOperands);
|
|
|
|
mlirOperationStateAddResults(&dimState, 1, &indexType);
|
|
|
|
MlirOperation dim = mlirOperationCreate(&dimState);
|
|
|
|
mlirBlockAppendOwnedOperation(funcBody, dim);
|
|
|
|
|
|
|
|
MlirRegion loopBodyRegion = mlirRegionCreate();
|
2021-02-04 04:34:29 +08:00
|
|
|
MlirBlock loopBody = mlirBlockCreate(0, NULL);
|
|
|
|
mlirBlockAddArgument(loopBody, indexType);
|
2020-08-05 20:36:16 +08:00
|
|
|
mlirRegionAppendOwnedBlock(loopBodyRegion, loopBody);
|
|
|
|
|
2020-11-24 05:08:00 +08:00
|
|
|
MlirAttribute indexOneLiteral =
|
|
|
|
mlirAttributeParseGet(ctx, mlirStringRefCreateFromCString("1 : index"));
|
|
|
|
MlirNamedAttribute indexOneValueAttr = mlirNamedAttributeGet(
|
2020-12-12 02:50:04 +08:00
|
|
|
mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")),
|
|
|
|
indexOneLiteral);
|
2020-11-24 05:08:00 +08:00
|
|
|
MlirOperationState constOneState = mlirOperationStateGet(
|
|
|
|
mlirStringRefCreateFromCString("std.constant"), location);
|
2020-08-05 20:36:16 +08:00
|
|
|
mlirOperationStateAddResults(&constOneState, 1, &indexType);
|
|
|
|
mlirOperationStateAddAttributes(&constOneState, 1, &indexOneValueAttr);
|
|
|
|
MlirOperation constOne = mlirOperationCreate(&constOneState);
|
|
|
|
mlirBlockAppendOwnedOperation(funcBody, constOne);
|
|
|
|
|
|
|
|
MlirValue dimValue = mlirOperationGetResult(dim, 0);
|
|
|
|
MlirValue constOneValue = mlirOperationGetResult(constOne, 0);
|
|
|
|
MlirValue loopOperands[] = {constZeroValue, dimValue, constOneValue};
|
2020-11-24 05:08:00 +08:00
|
|
|
MlirOperationState loopState = mlirOperationStateGet(
|
|
|
|
mlirStringRefCreateFromCString("scf.for"), location);
|
2020-08-05 20:36:16 +08:00
|
|
|
mlirOperationStateAddOperands(&loopState, 3, loopOperands);
|
|
|
|
mlirOperationStateAddOwnedRegions(&loopState, 1, &loopBodyRegion);
|
|
|
|
MlirOperation loop = mlirOperationCreate(&loopState);
|
|
|
|
mlirBlockAppendOwnedOperation(funcBody, loop);
|
|
|
|
|
|
|
|
populateLoopBody(ctx, loopBody, location, funcBody);
|
|
|
|
|
2020-11-24 05:08:00 +08:00
|
|
|
MlirOperationState retState = mlirOperationStateGet(
|
|
|
|
mlirStringRefCreateFromCString("std.return"), location);
|
2020-08-05 20:36:16 +08:00
|
|
|
MlirOperation ret = mlirOperationCreate(&retState);
|
|
|
|
mlirBlockAppendOwnedOperation(funcBody, ret);
|
|
|
|
|
2020-11-04 17:30:00 +08:00
|
|
|
MlirOperation module = mlirModuleGetOperation(moduleOp);
|
|
|
|
mlirOperationDump(module);
|
|
|
|
// clang-format off
|
|
|
|
// CHECK: module {
|
|
|
|
// CHECK: func @add(%[[ARG0:.*]]: memref<?xf32>, %[[ARG1:.*]]: memref<?xf32>) {
|
|
|
|
// CHECK: %[[C0:.*]] = constant 0 : index
|
|
|
|
// CHECK: %[[DIM:.*]] = dim %[[ARG0]], %[[C0]] : memref<?xf32>
|
|
|
|
// CHECK: %[[C1:.*]] = constant 1 : index
|
|
|
|
// CHECK: scf.for %[[I:.*]] = %[[C0]] to %[[DIM]] step %[[C1]] {
|
|
|
|
// CHECK: %[[LHS:.*]] = load %[[ARG0]][%[[I]]] : memref<?xf32>
|
|
|
|
// CHECK: %[[RHS:.*]] = load %[[ARG1]][%[[I]]] : memref<?xf32>
|
|
|
|
// CHECK: %[[SUM:.*]] = addf %[[LHS]], %[[RHS]] : f32
|
|
|
|
// CHECK: store %[[SUM]], %[[ARG0]][%[[I]]] : memref<?xf32>
|
|
|
|
// CHECK: }
|
|
|
|
// CHECK: return
|
|
|
|
// CHECK: }
|
|
|
|
// CHECK: }
|
|
|
|
// clang-format on
|
|
|
|
|
2020-08-05 20:36:16 +08:00
|
|
|
return moduleOp;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct OpListNode {
|
|
|
|
MlirOperation op;
|
|
|
|
struct OpListNode *next;
|
|
|
|
};
|
|
|
|
typedef struct OpListNode OpListNode;
|
|
|
|
|
|
|
|
struct ModuleStats {
|
|
|
|
unsigned numOperations;
|
|
|
|
unsigned numAttributes;
|
|
|
|
unsigned numBlocks;
|
|
|
|
unsigned numRegions;
|
|
|
|
unsigned numValues;
|
2020-10-20 01:17:51 +08:00
|
|
|
unsigned numBlockArguments;
|
|
|
|
unsigned numOpResults;
|
2020-08-05 20:36:16 +08:00
|
|
|
};
|
|
|
|
typedef struct ModuleStats ModuleStats;
|
|
|
|
|
2020-10-20 01:17:51 +08:00
|
|
|
int collectStatsSingle(OpListNode *head, ModuleStats *stats) {
|
2020-08-05 20:36:16 +08:00
|
|
|
MlirOperation operation = head->op;
|
|
|
|
stats->numOperations += 1;
|
|
|
|
stats->numValues += mlirOperationGetNumResults(operation);
|
|
|
|
stats->numAttributes += mlirOperationGetNumAttributes(operation);
|
|
|
|
|
|
|
|
unsigned numRegions = mlirOperationGetNumRegions(operation);
|
|
|
|
|
|
|
|
stats->numRegions += numRegions;
|
|
|
|
|
2020-10-20 01:17:51 +08:00
|
|
|
intptr_t numResults = mlirOperationGetNumResults(operation);
|
|
|
|
for (intptr_t i = 0; i < numResults; ++i) {
|
|
|
|
MlirValue result = mlirOperationGetResult(operation, i);
|
|
|
|
if (!mlirValueIsAOpResult(result))
|
|
|
|
return 1;
|
|
|
|
if (mlirValueIsABlockArgument(result))
|
|
|
|
return 2;
|
|
|
|
if (!mlirOperationEqual(operation, mlirOpResultGetOwner(result)))
|
|
|
|
return 3;
|
|
|
|
if (i != mlirOpResultGetResultNumber(result))
|
|
|
|
return 4;
|
|
|
|
++stats->numOpResults;
|
|
|
|
}
|
|
|
|
|
2020-08-05 20:36:16 +08:00
|
|
|
for (unsigned i = 0; i < numRegions; ++i) {
|
|
|
|
MlirRegion region = mlirOperationGetRegion(operation, i);
|
|
|
|
for (MlirBlock block = mlirRegionGetFirstBlock(region);
|
|
|
|
!mlirBlockIsNull(block); block = mlirBlockGetNextInRegion(block)) {
|
|
|
|
++stats->numBlocks;
|
2020-10-20 01:17:51 +08:00
|
|
|
intptr_t numArgs = mlirBlockGetNumArguments(block);
|
|
|
|
stats->numValues += numArgs;
|
|
|
|
for (intptr_t j = 0; j < numArgs; ++j) {
|
|
|
|
MlirValue arg = mlirBlockGetArgument(block, j);
|
|
|
|
if (!mlirValueIsABlockArgument(arg))
|
|
|
|
return 5;
|
|
|
|
if (mlirValueIsAOpResult(arg))
|
|
|
|
return 6;
|
|
|
|
if (!mlirBlockEqual(block, mlirBlockArgumentGetOwner(arg)))
|
|
|
|
return 7;
|
|
|
|
if (j != mlirBlockArgumentGetArgNumber(arg))
|
|
|
|
return 8;
|
|
|
|
++stats->numBlockArguments;
|
|
|
|
}
|
2020-08-05 20:36:16 +08:00
|
|
|
|
|
|
|
for (MlirOperation child = mlirBlockGetFirstOperation(block);
|
|
|
|
!mlirOperationIsNull(child);
|
|
|
|
child = mlirOperationGetNextInBlock(child)) {
|
|
|
|
OpListNode *node = malloc(sizeof(OpListNode));
|
|
|
|
node->op = child;
|
|
|
|
node->next = head->next;
|
|
|
|
head->next = node;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-10-20 01:17:51 +08:00
|
|
|
return 0;
|
2020-08-05 20:36:16 +08:00
|
|
|
}
|
|
|
|
|
2020-10-20 01:17:51 +08:00
|
|
|
int collectStats(MlirOperation operation) {
|
2020-08-05 20:36:16 +08:00
|
|
|
OpListNode *head = malloc(sizeof(OpListNode));
|
|
|
|
head->op = operation;
|
|
|
|
head->next = NULL;
|
|
|
|
|
|
|
|
ModuleStats stats;
|
|
|
|
stats.numOperations = 0;
|
|
|
|
stats.numAttributes = 0;
|
|
|
|
stats.numBlocks = 0;
|
|
|
|
stats.numRegions = 0;
|
|
|
|
stats.numValues = 0;
|
2020-10-20 01:17:51 +08:00
|
|
|
stats.numBlockArguments = 0;
|
|
|
|
stats.numOpResults = 0;
|
2020-08-05 20:36:16 +08:00
|
|
|
|
|
|
|
do {
|
2020-10-20 01:17:51 +08:00
|
|
|
int retval = collectStatsSingle(head, &stats);
|
|
|
|
if (retval)
|
|
|
|
return retval;
|
2020-08-05 20:36:16 +08:00
|
|
|
OpListNode *next = head->next;
|
|
|
|
free(head);
|
|
|
|
head = next;
|
|
|
|
} while (head);
|
|
|
|
|
2020-11-04 17:30:00 +08:00
|
|
|
if (stats.numValues != stats.numBlockArguments + stats.numOpResults)
|
|
|
|
return 100;
|
|
|
|
|
|
|
|
fprintf(stderr, "@stats\n");
|
2020-08-12 00:25:09 +08:00
|
|
|
fprintf(stderr, "Number of operations: %u\n", stats.numOperations);
|
|
|
|
fprintf(stderr, "Number of attributes: %u\n", stats.numAttributes);
|
|
|
|
fprintf(stderr, "Number of blocks: %u\n", stats.numBlocks);
|
|
|
|
fprintf(stderr, "Number of regions: %u\n", stats.numRegions);
|
|
|
|
fprintf(stderr, "Number of values: %u\n", stats.numValues);
|
2020-10-20 01:17:51 +08:00
|
|
|
fprintf(stderr, "Number of block arguments: %u\n", stats.numBlockArguments);
|
|
|
|
fprintf(stderr, "Number of op results: %u\n", stats.numOpResults);
|
2020-11-04 17:30:00 +08:00
|
|
|
// clang-format off
|
|
|
|
// CHECK-LABEL: @stats
|
|
|
|
// CHECK: Number of operations: 13
|
|
|
|
// CHECK: Number of attributes: 4
|
|
|
|
// CHECK: Number of blocks: 3
|
|
|
|
// CHECK: Number of regions: 3
|
|
|
|
// CHECK: Number of values: 9
|
|
|
|
// CHECK: Number of block arguments: 3
|
|
|
|
// CHECK: Number of op results: 6
|
|
|
|
// clang-format on
|
2020-10-20 01:17:51 +08:00
|
|
|
return 0;
|
2020-08-12 00:25:09 +08:00
|
|
|
}
|
|
|
|
|
2020-11-24 05:08:00 +08:00
|
|
|
static void printToStderr(MlirStringRef str, void *userData) {
|
2020-08-12 00:25:09 +08:00
|
|
|
(void)userData;
|
2020-11-24 05:08:00 +08:00
|
|
|
fwrite(str.data, 1, str.length, stderr);
|
2020-08-12 00:25:09 +08:00
|
|
|
}
|
|
|
|
|
2020-10-07 14:01:20 +08:00
|
|
|
static void printFirstOfEach(MlirContext ctx, MlirOperation operation) {
|
2020-08-12 00:25:09 +08:00
|
|
|
// Assuming we are given a module, go to the first operation of the first
|
|
|
|
// function.
|
|
|
|
MlirRegion region = mlirOperationGetRegion(operation, 0);
|
|
|
|
MlirBlock block = mlirRegionGetFirstBlock(region);
|
|
|
|
operation = mlirBlockGetFirstOperation(block);
|
|
|
|
region = mlirOperationGetRegion(operation, 0);
|
2020-10-29 14:16:36 +08:00
|
|
|
MlirOperation parentOperation = operation;
|
2020-08-12 00:25:09 +08:00
|
|
|
block = mlirRegionGetFirstBlock(region);
|
|
|
|
operation = mlirBlockGetFirstOperation(block);
|
|
|
|
|
2020-10-29 14:16:36 +08:00
|
|
|
// Verify that parent operation and block report correctly.
|
|
|
|
fprintf(stderr, "Parent operation eq: %d\n",
|
|
|
|
mlirOperationEqual(mlirOperationGetParentOperation(operation),
|
|
|
|
parentOperation));
|
|
|
|
fprintf(stderr, "Block eq: %d\n",
|
|
|
|
mlirBlockEqual(mlirOperationGetBlock(operation), block));
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: Parent operation eq: 1
|
|
|
|
// CHECK: Block eq: 1
|
2020-10-29 14:16:36 +08:00
|
|
|
|
|
|
|
// In the module we created, the first operation of the first function is
|
|
|
|
// an "std.dim", which has an attribute and a single result that we can
|
|
|
|
// use to test the printing mechanism.
|
2020-08-12 00:25:09 +08:00
|
|
|
mlirBlockPrint(block, printToStderr, NULL);
|
|
|
|
fprintf(stderr, "\n");
|
2020-10-07 14:01:20 +08:00
|
|
|
fprintf(stderr, "First operation: ");
|
2020-08-12 00:25:09 +08:00
|
|
|
mlirOperationPrint(operation, printToStderr, NULL);
|
|
|
|
fprintf(stderr, "\n");
|
2020-11-04 17:30:00 +08:00
|
|
|
// clang-format off
|
|
|
|
// CHECK: %[[C0:.*]] = constant 0 : index
|
|
|
|
// CHECK: %[[DIM:.*]] = dim %{{.*}}, %[[C0]] : memref<?xf32>
|
|
|
|
// CHECK: %[[C1:.*]] = constant 1 : index
|
|
|
|
// CHECK: scf.for %[[I:.*]] = %[[C0]] to %[[DIM]] step %[[C1]] {
|
|
|
|
// CHECK: %[[LHS:.*]] = load %{{.*}}[%[[I]]] : memref<?xf32>
|
|
|
|
// CHECK: %[[RHS:.*]] = load %{{.*}}[%[[I]]] : memref<?xf32>
|
|
|
|
// CHECK: %[[SUM:.*]] = addf %[[LHS]], %[[RHS]] : f32
|
|
|
|
// CHECK: store %[[SUM]], %{{.*}}[%[[I]]] : memref<?xf32>
|
|
|
|
// CHECK: }
|
|
|
|
// CHECK: return
|
|
|
|
// CHECK: First operation: {{.*}} = constant 0 : index
|
|
|
|
// clang-format on
|
2020-08-12 00:25:09 +08:00
|
|
|
|
2020-11-03 02:26:38 +08:00
|
|
|
// Get the operation name and print it.
|
|
|
|
MlirIdentifier ident = mlirOperationGetName(operation);
|
|
|
|
MlirStringRef identStr = mlirIdentifierStr(ident);
|
|
|
|
fprintf(stderr, "Operation name: '");
|
|
|
|
for (size_t i = 0; i < identStr.length; ++i)
|
|
|
|
fputc(identStr.data[i], stderr);
|
|
|
|
fprintf(stderr, "'\n");
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: Operation name: 'std.constant'
|
2020-11-03 02:26:38 +08:00
|
|
|
|
|
|
|
// Get the identifier again and verify equal.
|
|
|
|
MlirIdentifier identAgain = mlirIdentifierGet(ctx, identStr);
|
|
|
|
fprintf(stderr, "Identifier equal: %d\n",
|
|
|
|
mlirIdentifierEqual(ident, identAgain));
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: Identifier equal: 1
|
2020-11-03 02:26:38 +08:00
|
|
|
|
2020-10-29 14:16:36 +08:00
|
|
|
// Get the block terminator and print it.
|
|
|
|
MlirOperation terminator = mlirBlockGetTerminator(block);
|
|
|
|
fprintf(stderr, "Terminator: ");
|
|
|
|
mlirOperationPrint(terminator, printToStderr, NULL);
|
|
|
|
fprintf(stderr, "\n");
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: Terminator: return
|
2020-10-29 14:16:36 +08:00
|
|
|
|
2020-10-07 14:01:20 +08:00
|
|
|
// Get the attribute by index.
|
|
|
|
MlirNamedAttribute namedAttr0 = mlirOperationGetAttribute(operation, 0);
|
|
|
|
fprintf(stderr, "Get attr 0: ");
|
|
|
|
mlirAttributePrint(namedAttr0.attribute, printToStderr, NULL);
|
2020-08-12 00:25:09 +08:00
|
|
|
fprintf(stderr, "\n");
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: Get attr 0: 0 : index
|
2020-08-12 00:25:09 +08:00
|
|
|
|
2020-10-07 14:01:20 +08:00
|
|
|
// Now re-get the attribute by name.
|
2020-12-12 02:50:04 +08:00
|
|
|
MlirAttribute attr0ByName = mlirOperationGetAttributeByName(
|
|
|
|
operation, mlirIdentifierStr(namedAttr0.name));
|
2020-10-07 14:01:20 +08:00
|
|
|
fprintf(stderr, "Get attr 0 by name: ");
|
|
|
|
mlirAttributePrint(attr0ByName, printToStderr, NULL);
|
|
|
|
fprintf(stderr, "\n");
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: Get attr 0 by name: 0 : index
|
2020-10-07 14:01:20 +08:00
|
|
|
|
|
|
|
// Get a non-existing attribute and assert that it is null (sanity).
|
|
|
|
fprintf(stderr, "does_not_exist is null: %d\n",
|
2020-11-24 05:08:00 +08:00
|
|
|
mlirAttributeIsNull(mlirOperationGetAttributeByName(
|
|
|
|
operation, mlirStringRefCreateFromCString("does_not_exist"))));
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: does_not_exist is null: 1
|
2020-10-07 14:01:20 +08:00
|
|
|
|
|
|
|
// Get result 0 and its type.
|
2020-08-12 00:25:09 +08:00
|
|
|
MlirValue value = mlirOperationGetResult(operation, 0);
|
2020-10-07 14:01:20 +08:00
|
|
|
fprintf(stderr, "Result 0: ");
|
2020-08-12 00:25:09 +08:00
|
|
|
mlirValuePrint(value, printToStderr, NULL);
|
|
|
|
fprintf(stderr, "\n");
|
2020-10-07 14:01:20 +08:00
|
|
|
fprintf(stderr, "Value is null: %d\n", mlirValueIsNull(value));
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: Result 0: {{.*}} = constant 0 : index
|
|
|
|
// CHECK: Value is null: 0
|
2020-08-12 00:25:09 +08:00
|
|
|
|
|
|
|
MlirType type = mlirValueGetType(value);
|
2020-10-07 14:01:20 +08:00
|
|
|
fprintf(stderr, "Result 0 type: ");
|
2020-08-12 00:25:09 +08:00
|
|
|
mlirTypePrint(type, printToStderr, NULL);
|
|
|
|
fprintf(stderr, "\n");
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: Result 0 type: index
|
2020-10-07 14:01:20 +08:00
|
|
|
|
|
|
|
// Set a custom attribute.
|
2020-11-24 05:08:00 +08:00
|
|
|
mlirOperationSetAttributeByName(operation,
|
|
|
|
mlirStringRefCreateFromCString("custom_attr"),
|
2020-10-07 14:01:20 +08:00
|
|
|
mlirBoolAttrGet(ctx, 1));
|
|
|
|
fprintf(stderr, "Op with set attr: ");
|
|
|
|
mlirOperationPrint(operation, printToStderr, NULL);
|
|
|
|
fprintf(stderr, "\n");
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: Op with set attr: {{.*}} {custom_attr = true}
|
2020-10-07 14:01:20 +08:00
|
|
|
|
|
|
|
// Remove the attribute.
|
|
|
|
fprintf(stderr, "Remove attr: %d\n",
|
2020-11-24 05:08:00 +08:00
|
|
|
mlirOperationRemoveAttributeByName(
|
|
|
|
operation, mlirStringRefCreateFromCString("custom_attr")));
|
2020-10-07 14:01:20 +08:00
|
|
|
fprintf(stderr, "Remove attr again: %d\n",
|
2020-11-24 05:08:00 +08:00
|
|
|
mlirOperationRemoveAttributeByName(
|
|
|
|
operation, mlirStringRefCreateFromCString("custom_attr")));
|
2020-10-07 14:01:20 +08:00
|
|
|
fprintf(stderr, "Removed attr is null: %d\n",
|
2020-11-24 05:08:00 +08:00
|
|
|
mlirAttributeIsNull(mlirOperationGetAttributeByName(
|
|
|
|
operation, mlirStringRefCreateFromCString("custom_attr"))));
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: Remove attr: 1
|
|
|
|
// CHECK: Remove attr again: 0
|
|
|
|
// CHECK: Removed attr is null: 1
|
2020-10-21 14:20:04 +08:00
|
|
|
|
|
|
|
// Add a large attribute to verify printing flags.
|
|
|
|
int64_t eltsShape[] = {4};
|
|
|
|
int32_t eltsData[] = {1, 2, 3, 4};
|
|
|
|
mlirOperationSetAttributeByName(
|
2020-11-24 05:08:00 +08:00
|
|
|
operation, mlirStringRefCreateFromCString("elts"),
|
2020-10-21 14:20:04 +08:00
|
|
|
mlirDenseElementsAttrInt32Get(
|
|
|
|
mlirRankedTensorTypeGet(1, eltsShape, mlirIntegerTypeGet(ctx, 32)), 4,
|
|
|
|
eltsData));
|
|
|
|
MlirOpPrintingFlags flags = mlirOpPrintingFlagsCreate();
|
|
|
|
mlirOpPrintingFlagsElideLargeElementsAttrs(flags, 2);
|
|
|
|
mlirOpPrintingFlagsPrintGenericOpForm(flags);
|
|
|
|
mlirOpPrintingFlagsEnableDebugInfo(flags, /*prettyForm=*/0);
|
|
|
|
mlirOpPrintingFlagsUseLocalScope(flags);
|
|
|
|
fprintf(stderr, "Op print with all flags: ");
|
|
|
|
mlirOperationPrintWithFlags(operation, flags, printToStderr, NULL);
|
|
|
|
fprintf(stderr, "\n");
|
2020-11-24 05:08:00 +08:00
|
|
|
// clang-format off
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: Op print with all flags: %{{.*}} = "std.constant"() {elts = opaque<"", "0xDEADBEEF"> : tensor<4xi32>, value = 0 : index} : () -> index loc(unknown)
|
2020-11-24 05:08:00 +08:00
|
|
|
// clang-format on
|
2020-10-21 14:20:04 +08:00
|
|
|
|
|
|
|
mlirOpPrintingFlagsDestroy(flags);
|
2020-08-05 20:36:16 +08:00
|
|
|
}
|
|
|
|
|
2020-11-04 17:30:00 +08:00
|
|
|
static int constructAndTraverseIr(MlirContext ctx) {
|
|
|
|
MlirLocation location = mlirLocationUnknownGet(ctx);
|
|
|
|
|
|
|
|
MlirModule moduleOp = makeAndDumpAdd(ctx, location);
|
|
|
|
MlirOperation module = mlirModuleGetOperation(moduleOp);
|
|
|
|
|
|
|
|
int errcode = collectStats(module);
|
|
|
|
if (errcode)
|
|
|
|
return errcode;
|
|
|
|
|
|
|
|
printFirstOfEach(ctx, module);
|
|
|
|
|
|
|
|
mlirModuleDestroy(moduleOp);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-09-23 21:02:47 +08:00
|
|
|
/// Creates an operation with a region containing multiple blocks with
|
|
|
|
/// operations and dumps it. The blocks and operations are inserted using
|
|
|
|
/// block/operation-relative API and their final order is checked.
|
|
|
|
static void buildWithInsertionsAndPrint(MlirContext ctx) {
|
|
|
|
MlirLocation loc = mlirLocationUnknownGet(ctx);
|
|
|
|
|
|
|
|
MlirRegion owningRegion = mlirRegionCreate();
|
|
|
|
MlirBlock nullBlock = mlirRegionGetFirstBlock(owningRegion);
|
2020-11-24 05:08:00 +08:00
|
|
|
MlirOperationState state = mlirOperationStateGet(
|
|
|
|
mlirStringRefCreateFromCString("insertion.order.test"), loc);
|
2020-09-23 21:02:47 +08:00
|
|
|
mlirOperationStateAddOwnedRegions(&state, 1, &owningRegion);
|
|
|
|
MlirOperation op = mlirOperationCreate(&state);
|
|
|
|
MlirRegion region = mlirOperationGetRegion(op, 0);
|
|
|
|
|
|
|
|
// Use integer types of different bitwidth as block arguments in order to
|
|
|
|
// differentiate blocks.
|
|
|
|
MlirType i1 = mlirIntegerTypeGet(ctx, 1);
|
|
|
|
MlirType i2 = mlirIntegerTypeGet(ctx, 2);
|
|
|
|
MlirType i3 = mlirIntegerTypeGet(ctx, 3);
|
|
|
|
MlirType i4 = mlirIntegerTypeGet(ctx, 4);
|
|
|
|
MlirBlock block1 = mlirBlockCreate(1, &i1);
|
|
|
|
MlirBlock block2 = mlirBlockCreate(1, &i2);
|
|
|
|
MlirBlock block3 = mlirBlockCreate(1, &i3);
|
|
|
|
MlirBlock block4 = mlirBlockCreate(1, &i4);
|
|
|
|
// Insert blocks so as to obtain the 1-2-3-4 order,
|
|
|
|
mlirRegionInsertOwnedBlockBefore(region, nullBlock, block3);
|
|
|
|
mlirRegionInsertOwnedBlockBefore(region, block3, block2);
|
|
|
|
mlirRegionInsertOwnedBlockAfter(region, nullBlock, block1);
|
|
|
|
mlirRegionInsertOwnedBlockAfter(region, block3, block4);
|
|
|
|
|
2020-11-24 05:08:00 +08:00
|
|
|
MlirOperationState op1State =
|
|
|
|
mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op1"), loc);
|
|
|
|
MlirOperationState op2State =
|
|
|
|
mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op2"), loc);
|
|
|
|
MlirOperationState op3State =
|
|
|
|
mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op3"), loc);
|
|
|
|
MlirOperationState op4State =
|
|
|
|
mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op4"), loc);
|
|
|
|
MlirOperationState op5State =
|
|
|
|
mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op5"), loc);
|
|
|
|
MlirOperationState op6State =
|
|
|
|
mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op6"), loc);
|
|
|
|
MlirOperationState op7State =
|
|
|
|
mlirOperationStateGet(mlirStringRefCreateFromCString("dummy.op7"), loc);
|
2020-09-23 21:02:47 +08:00
|
|
|
MlirOperation op1 = mlirOperationCreate(&op1State);
|
|
|
|
MlirOperation op2 = mlirOperationCreate(&op2State);
|
|
|
|
MlirOperation op3 = mlirOperationCreate(&op3State);
|
|
|
|
MlirOperation op4 = mlirOperationCreate(&op4State);
|
|
|
|
MlirOperation op5 = mlirOperationCreate(&op5State);
|
|
|
|
MlirOperation op6 = mlirOperationCreate(&op6State);
|
|
|
|
MlirOperation op7 = mlirOperationCreate(&op7State);
|
|
|
|
|
|
|
|
// Insert operations in the first block so as to obtain the 1-2-3-4 order.
|
|
|
|
MlirOperation nullOperation = mlirBlockGetFirstOperation(block1);
|
|
|
|
assert(mlirOperationIsNull(nullOperation));
|
|
|
|
mlirBlockInsertOwnedOperationBefore(block1, nullOperation, op3);
|
|
|
|
mlirBlockInsertOwnedOperationBefore(block1, op3, op2);
|
|
|
|
mlirBlockInsertOwnedOperationAfter(block1, nullOperation, op1);
|
|
|
|
mlirBlockInsertOwnedOperationAfter(block1, op3, op4);
|
|
|
|
|
|
|
|
// Append operations to the rest of blocks to make them non-empty and thus
|
|
|
|
// printable.
|
|
|
|
mlirBlockAppendOwnedOperation(block2, op5);
|
|
|
|
mlirBlockAppendOwnedOperation(block3, op6);
|
|
|
|
mlirBlockAppendOwnedOperation(block4, op7);
|
|
|
|
|
|
|
|
mlirOperationDump(op);
|
|
|
|
mlirOperationDestroy(op);
|
2020-11-04 17:30:00 +08:00
|
|
|
// clang-format off
|
|
|
|
// CHECK-LABEL: "insertion.order.test"
|
|
|
|
// CHECK: ^{{.*}}(%{{.*}}: i1
|
|
|
|
// CHECK: "dummy.op1"
|
|
|
|
// CHECK-NEXT: "dummy.op2"
|
|
|
|
// CHECK-NEXT: "dummy.op3"
|
|
|
|
// CHECK-NEXT: "dummy.op4"
|
|
|
|
// CHECK: ^{{.*}}(%{{.*}}: i2
|
|
|
|
// CHECK: "dummy.op5"
|
|
|
|
// CHECK: ^{{.*}}(%{{.*}}: i3
|
|
|
|
// CHECK: "dummy.op6"
|
|
|
|
// CHECK: ^{{.*}}(%{{.*}}: i4
|
|
|
|
// CHECK: "dummy.op7"
|
|
|
|
// clang-format on
|
2020-09-23 21:02:47 +08:00
|
|
|
}
|
|
|
|
|
2021-01-23 10:43:50 +08:00
|
|
|
/// Creates operations with type inference and tests various failure modes.
|
|
|
|
static int createOperationWithTypeInference(MlirContext ctx) {
|
|
|
|
MlirLocation loc = mlirLocationUnknownGet(ctx);
|
|
|
|
MlirAttribute iAttr = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 32), 4);
|
|
|
|
|
|
|
|
// The shape.const_size op implements result type inference and is only used
|
|
|
|
// for that reason.
|
|
|
|
MlirOperationState state = mlirOperationStateGet(
|
|
|
|
mlirStringRefCreateFromCString("shape.const_size"), loc);
|
|
|
|
MlirNamedAttribute valueAttr = mlirNamedAttributeGet(
|
|
|
|
mlirIdentifierGet(ctx, mlirStringRefCreateFromCString("value")), iAttr);
|
|
|
|
mlirOperationStateAddAttributes(&state, 1, &valueAttr);
|
|
|
|
mlirOperationStateEnableResultTypeInference(&state);
|
|
|
|
|
|
|
|
// Expect result type inference to succeed.
|
|
|
|
MlirOperation op = mlirOperationCreate(&state);
|
|
|
|
if (mlirOperationIsNull(op)) {
|
|
|
|
fprintf(stderr, "ERROR: Result type inference unexpectedly failed");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK: RESULT_TYPE_INFERENCE: !shape.size
|
|
|
|
fprintf(stderr, "RESULT_TYPE_INFERENCE: ");
|
|
|
|
mlirTypeDump(mlirValueGetType(mlirOperationGetResult(op, 0)));
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
mlirOperationDestroy(op);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-12-04 09:22:29 +08:00
|
|
|
/// Dumps instances of all builtin types to check that C API works correctly.
|
|
|
|
/// Additionally, performs simple identity checks that a builtin type
|
2020-08-18 16:26:30 +08:00
|
|
|
/// constructed with C API can be inspected and has the expected type. The
|
2020-12-04 09:22:29 +08:00
|
|
|
/// latter achieves full coverage of C API for builtin types. Returns 0 on
|
2020-08-18 16:26:30 +08:00
|
|
|
/// success and a non-zero error code on failure.
|
2020-12-04 09:22:29 +08:00
|
|
|
static int printBuiltinTypes(MlirContext ctx) {
|
2020-08-18 16:26:30 +08:00
|
|
|
// Integer types.
|
|
|
|
MlirType i32 = mlirIntegerTypeGet(ctx, 32);
|
|
|
|
MlirType si32 = mlirIntegerTypeSignedGet(ctx, 32);
|
|
|
|
MlirType ui32 = mlirIntegerTypeUnsignedGet(ctx, 32);
|
|
|
|
if (!mlirTypeIsAInteger(i32) || mlirTypeIsAF32(i32))
|
|
|
|
return 1;
|
|
|
|
if (!mlirTypeIsAInteger(si32) || !mlirIntegerTypeIsSigned(si32))
|
|
|
|
return 2;
|
|
|
|
if (!mlirTypeIsAInteger(ui32) || !mlirIntegerTypeIsUnsigned(ui32))
|
|
|
|
return 3;
|
|
|
|
if (mlirTypeEqual(i32, ui32) || mlirTypeEqual(i32, si32))
|
|
|
|
return 4;
|
|
|
|
if (mlirIntegerTypeGetWidth(i32) != mlirIntegerTypeGetWidth(si32))
|
|
|
|
return 5;
|
2020-11-04 17:30:00 +08:00
|
|
|
fprintf(stderr, "@types\n");
|
2020-08-18 16:26:30 +08:00
|
|
|
mlirTypeDump(i32);
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
mlirTypeDump(si32);
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
mlirTypeDump(ui32);
|
|
|
|
fprintf(stderr, "\n");
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK-LABEL: @types
|
|
|
|
// CHECK: i32
|
|
|
|
// CHECK: si32
|
|
|
|
// CHECK: ui32
|
2020-08-18 16:26:30 +08:00
|
|
|
|
|
|
|
// Index type.
|
|
|
|
MlirType index = mlirIndexTypeGet(ctx);
|
|
|
|
if (!mlirTypeIsAIndex(index))
|
|
|
|
return 6;
|
|
|
|
mlirTypeDump(index);
|
|
|
|
fprintf(stderr, "\n");
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: index
|
2020-08-18 16:26:30 +08:00
|
|
|
|
|
|
|
// Floating-point types.
|
|
|
|
MlirType bf16 = mlirBF16TypeGet(ctx);
|
|
|
|
MlirType f16 = mlirF16TypeGet(ctx);
|
|
|
|
MlirType f32 = mlirF32TypeGet(ctx);
|
|
|
|
MlirType f64 = mlirF64TypeGet(ctx);
|
|
|
|
if (!mlirTypeIsABF16(bf16))
|
|
|
|
return 7;
|
|
|
|
if (!mlirTypeIsAF16(f16))
|
|
|
|
return 9;
|
|
|
|
if (!mlirTypeIsAF32(f32))
|
|
|
|
return 10;
|
|
|
|
if (!mlirTypeIsAF64(f64))
|
|
|
|
return 11;
|
|
|
|
mlirTypeDump(bf16);
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
mlirTypeDump(f16);
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
mlirTypeDump(f32);
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
mlirTypeDump(f64);
|
|
|
|
fprintf(stderr, "\n");
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: bf16
|
|
|
|
// CHECK: f16
|
|
|
|
// CHECK: f32
|
|
|
|
// CHECK: f64
|
2020-08-18 16:26:30 +08:00
|
|
|
|
|
|
|
// None type.
|
|
|
|
MlirType none = mlirNoneTypeGet(ctx);
|
|
|
|
if (!mlirTypeIsANone(none))
|
|
|
|
return 12;
|
|
|
|
mlirTypeDump(none);
|
|
|
|
fprintf(stderr, "\n");
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: none
|
2020-08-18 16:26:30 +08:00
|
|
|
|
|
|
|
// Complex type.
|
|
|
|
MlirType cplx = mlirComplexTypeGet(f32);
|
|
|
|
if (!mlirTypeIsAComplex(cplx) ||
|
|
|
|
!mlirTypeEqual(mlirComplexTypeGetElementType(cplx), f32))
|
|
|
|
return 13;
|
|
|
|
mlirTypeDump(cplx);
|
|
|
|
fprintf(stderr, "\n");
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: complex<f32>
|
2020-08-18 16:26:30 +08:00
|
|
|
|
|
|
|
// Vector (and Shaped) type. ShapedType is a common base class for vectors,
|
|
|
|
// memrefs and tensors, one cannot create instances of this class so it is
|
|
|
|
// tested on an instance of vector type.
|
|
|
|
int64_t shape[] = {2, 3};
|
|
|
|
MlirType vector =
|
|
|
|
mlirVectorTypeGet(sizeof(shape) / sizeof(int64_t), shape, f32);
|
|
|
|
if (!mlirTypeIsAVector(vector) || !mlirTypeIsAShaped(vector))
|
|
|
|
return 14;
|
|
|
|
if (!mlirTypeEqual(mlirShapedTypeGetElementType(vector), f32) ||
|
|
|
|
!mlirShapedTypeHasRank(vector) || mlirShapedTypeGetRank(vector) != 2 ||
|
|
|
|
mlirShapedTypeGetDimSize(vector, 0) != 2 ||
|
|
|
|
mlirShapedTypeIsDynamicDim(vector, 0) ||
|
|
|
|
mlirShapedTypeGetDimSize(vector, 1) != 3 ||
|
|
|
|
!mlirShapedTypeHasStaticShape(vector))
|
|
|
|
return 15;
|
|
|
|
mlirTypeDump(vector);
|
|
|
|
fprintf(stderr, "\n");
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: vector<2x3xf32>
|
2020-08-18 16:26:30 +08:00
|
|
|
|
|
|
|
// Ranked tensor type.
|
|
|
|
MlirType rankedTensor =
|
|
|
|
mlirRankedTensorTypeGet(sizeof(shape) / sizeof(int64_t), shape, f32);
|
|
|
|
if (!mlirTypeIsATensor(rankedTensor) ||
|
|
|
|
!mlirTypeIsARankedTensor(rankedTensor))
|
|
|
|
return 16;
|
|
|
|
mlirTypeDump(rankedTensor);
|
|
|
|
fprintf(stderr, "\n");
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: tensor<2x3xf32>
|
2020-08-18 16:26:30 +08:00
|
|
|
|
|
|
|
// Unranked tensor type.
|
|
|
|
MlirType unrankedTensor = mlirUnrankedTensorTypeGet(f32);
|
|
|
|
if (!mlirTypeIsATensor(unrankedTensor) ||
|
|
|
|
!mlirTypeIsAUnrankedTensor(unrankedTensor) ||
|
|
|
|
mlirShapedTypeHasRank(unrankedTensor))
|
|
|
|
return 17;
|
|
|
|
mlirTypeDump(unrankedTensor);
|
|
|
|
fprintf(stderr, "\n");
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: tensor<*xf32>
|
2020-08-18 16:26:30 +08:00
|
|
|
|
|
|
|
// MemRef type.
|
|
|
|
MlirType memRef = mlirMemRefTypeContiguousGet(
|
|
|
|
f32, sizeof(shape) / sizeof(int64_t), shape, 2);
|
|
|
|
if (!mlirTypeIsAMemRef(memRef) ||
|
|
|
|
mlirMemRefTypeGetNumAffineMaps(memRef) != 0 ||
|
|
|
|
mlirMemRefTypeGetMemorySpace(memRef) != 2)
|
|
|
|
return 18;
|
|
|
|
mlirTypeDump(memRef);
|
|
|
|
fprintf(stderr, "\n");
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: memref<2x3xf32, 2>
|
2020-08-18 16:26:30 +08:00
|
|
|
|
|
|
|
// Unranked MemRef type.
|
|
|
|
MlirType unrankedMemRef = mlirUnrankedMemRefTypeGet(f32, 4);
|
|
|
|
if (!mlirTypeIsAUnrankedMemRef(unrankedMemRef) ||
|
|
|
|
mlirTypeIsAMemRef(unrankedMemRef) ||
|
|
|
|
mlirUnrankedMemrefGetMemorySpace(unrankedMemRef) != 4)
|
|
|
|
return 19;
|
|
|
|
mlirTypeDump(unrankedMemRef);
|
|
|
|
fprintf(stderr, "\n");
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: memref<*xf32, 4>
|
2020-08-18 16:26:30 +08:00
|
|
|
|
|
|
|
// Tuple type.
|
|
|
|
MlirType types[] = {unrankedMemRef, f32};
|
|
|
|
MlirType tuple = mlirTupleTypeGet(ctx, 2, types);
|
|
|
|
if (!mlirTypeIsATuple(tuple) || mlirTupleTypeGetNumTypes(tuple) != 2 ||
|
|
|
|
!mlirTypeEqual(mlirTupleTypeGetType(tuple, 0), unrankedMemRef) ||
|
|
|
|
!mlirTypeEqual(mlirTupleTypeGetType(tuple, 1), f32))
|
|
|
|
return 20;
|
|
|
|
mlirTypeDump(tuple);
|
|
|
|
fprintf(stderr, "\n");
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: tuple<memref<*xf32, 4>, f32>
|
2020-08-18 16:26:30 +08:00
|
|
|
|
2020-09-28 22:28:04 +08:00
|
|
|
// Function type.
|
|
|
|
MlirType funcInputs[2] = {mlirIndexTypeGet(ctx), mlirIntegerTypeGet(ctx, 1)};
|
|
|
|
MlirType funcResults[3] = {mlirIntegerTypeGet(ctx, 16),
|
|
|
|
mlirIntegerTypeGet(ctx, 32),
|
|
|
|
mlirIntegerTypeGet(ctx, 64)};
|
|
|
|
MlirType funcType = mlirFunctionTypeGet(ctx, 2, funcInputs, 3, funcResults);
|
|
|
|
if (mlirFunctionTypeGetNumInputs(funcType) != 2)
|
|
|
|
return 21;
|
|
|
|
if (mlirFunctionTypeGetNumResults(funcType) != 3)
|
|
|
|
return 22;
|
|
|
|
if (!mlirTypeEqual(funcInputs[0], mlirFunctionTypeGetInput(funcType, 0)) ||
|
|
|
|
!mlirTypeEqual(funcInputs[1], mlirFunctionTypeGetInput(funcType, 1)))
|
|
|
|
return 23;
|
|
|
|
if (!mlirTypeEqual(funcResults[0], mlirFunctionTypeGetResult(funcType, 0)) ||
|
|
|
|
!mlirTypeEqual(funcResults[1], mlirFunctionTypeGetResult(funcType, 1)) ||
|
|
|
|
!mlirTypeEqual(funcResults[2], mlirFunctionTypeGetResult(funcType, 2)))
|
|
|
|
return 24;
|
|
|
|
mlirTypeDump(funcType);
|
|
|
|
fprintf(stderr, "\n");
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: (index, i1) -> (i16, i32, i64)
|
2020-09-28 22:28:04 +08:00
|
|
|
|
2020-08-18 16:26:30 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-08-20 00:38:56 +08:00
|
|
|
void callbackSetFixedLengthString(const char *data, intptr_t len,
|
|
|
|
void *userData) {
|
|
|
|
strncpy(userData, data, len);
|
|
|
|
}
|
|
|
|
|
2020-12-04 08:01:32 +08:00
|
|
|
bool stringIsEqual(const char *lhs, MlirStringRef rhs) {
|
|
|
|
if (strlen(lhs) != rhs.length) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return !strncmp(lhs, rhs.data, rhs.length);
|
|
|
|
}
|
|
|
|
|
2020-12-04 09:22:57 +08:00
|
|
|
int printBuiltinAttributes(MlirContext ctx) {
|
2020-08-20 00:38:56 +08:00
|
|
|
MlirAttribute floating =
|
|
|
|
mlirFloatAttrDoubleGet(ctx, mlirF64TypeGet(ctx), 2.0);
|
|
|
|
if (!mlirAttributeIsAFloat(floating) ||
|
|
|
|
fabs(mlirFloatAttrGetValueDouble(floating) - 2.0) > 1E-6)
|
|
|
|
return 1;
|
2020-11-04 17:30:00 +08:00
|
|
|
fprintf(stderr, "@attrs\n");
|
2020-08-20 00:38:56 +08:00
|
|
|
mlirAttributeDump(floating);
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK-LABEL: @attrs
|
|
|
|
// CHECK: 2.000000e+00 : f64
|
2020-08-20 00:38:56 +08:00
|
|
|
|
2020-10-16 08:31:31 +08:00
|
|
|
// Exercise mlirAttributeGetType() just for the first one.
|
|
|
|
MlirType floatingType = mlirAttributeGetType(floating);
|
|
|
|
mlirTypeDump(floatingType);
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: f64
|
2020-10-16 08:31:31 +08:00
|
|
|
|
2020-08-20 00:38:56 +08:00
|
|
|
MlirAttribute integer = mlirIntegerAttrGet(mlirIntegerTypeGet(ctx, 32), 42);
|
|
|
|
if (!mlirAttributeIsAInteger(integer) ||
|
|
|
|
mlirIntegerAttrGetValueInt(integer) != 42)
|
|
|
|
return 2;
|
|
|
|
mlirAttributeDump(integer);
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: 42 : i32
|
2020-08-20 00:38:56 +08:00
|
|
|
|
|
|
|
MlirAttribute boolean = mlirBoolAttrGet(ctx, 1);
|
|
|
|
if (!mlirAttributeIsABool(boolean) || !mlirBoolAttrGetValue(boolean))
|
|
|
|
return 3;
|
|
|
|
mlirAttributeDump(boolean);
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: true
|
2020-08-20 00:38:56 +08:00
|
|
|
|
|
|
|
const char data[] = "abcdefghijklmnopqestuvwxyz";
|
|
|
|
MlirAttribute opaque =
|
2020-12-04 08:01:32 +08:00
|
|
|
mlirOpaqueAttrGet(ctx, mlirStringRefCreateFromCString("std"), 3, data,
|
|
|
|
mlirNoneTypeGet(ctx));
|
2020-08-20 00:38:56 +08:00
|
|
|
if (!mlirAttributeIsAOpaque(opaque) ||
|
2020-12-04 08:01:32 +08:00
|
|
|
!stringIsEqual("std", mlirOpaqueAttrGetDialectNamespace(opaque)))
|
2020-08-20 00:38:56 +08:00
|
|
|
return 4;
|
2020-09-15 18:04:59 +08:00
|
|
|
|
|
|
|
MlirStringRef opaqueData = mlirOpaqueAttrGetData(opaque);
|
|
|
|
if (opaqueData.length != 3 ||
|
|
|
|
strncmp(data, opaqueData.data, opaqueData.length))
|
2020-08-20 00:38:56 +08:00
|
|
|
return 5;
|
|
|
|
mlirAttributeDump(opaque);
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: #std.abc
|
2020-08-20 00:38:56 +08:00
|
|
|
|
2020-12-04 08:01:32 +08:00
|
|
|
MlirAttribute string =
|
|
|
|
mlirStringAttrGet(ctx, mlirStringRefCreate(data + 3, 2));
|
2020-08-20 00:38:56 +08:00
|
|
|
if (!mlirAttributeIsAString(string))
|
|
|
|
return 6;
|
2020-09-15 18:04:59 +08:00
|
|
|
|
|
|
|
MlirStringRef stringValue = mlirStringAttrGetValue(string);
|
|
|
|
if (stringValue.length != 2 ||
|
|
|
|
strncmp(data + 3, stringValue.data, stringValue.length))
|
2020-08-20 00:38:56 +08:00
|
|
|
return 7;
|
|
|
|
mlirAttributeDump(string);
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: "de"
|
2020-08-20 00:38:56 +08:00
|
|
|
|
2020-12-04 08:01:32 +08:00
|
|
|
MlirAttribute flatSymbolRef =
|
|
|
|
mlirFlatSymbolRefAttrGet(ctx, mlirStringRefCreate(data + 5, 3));
|
2020-08-20 00:38:56 +08:00
|
|
|
if (!mlirAttributeIsAFlatSymbolRef(flatSymbolRef))
|
|
|
|
return 8;
|
2020-09-15 18:04:59 +08:00
|
|
|
|
|
|
|
MlirStringRef flatSymbolRefValue =
|
|
|
|
mlirFlatSymbolRefAttrGetValue(flatSymbolRef);
|
|
|
|
if (flatSymbolRefValue.length != 3 ||
|
|
|
|
strncmp(data + 5, flatSymbolRefValue.data, flatSymbolRefValue.length))
|
2020-08-20 00:38:56 +08:00
|
|
|
return 9;
|
|
|
|
mlirAttributeDump(flatSymbolRef);
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: @fgh
|
2020-08-20 00:38:56 +08:00
|
|
|
|
|
|
|
MlirAttribute symbols[] = {flatSymbolRef, flatSymbolRef};
|
2020-12-04 08:01:32 +08:00
|
|
|
MlirAttribute symbolRef =
|
|
|
|
mlirSymbolRefAttrGet(ctx, mlirStringRefCreate(data + 8, 2), 2, symbols);
|
2020-08-20 00:38:56 +08:00
|
|
|
if (!mlirAttributeIsASymbolRef(symbolRef) ||
|
|
|
|
mlirSymbolRefAttrGetNumNestedReferences(symbolRef) != 2 ||
|
|
|
|
!mlirAttributeEqual(mlirSymbolRefAttrGetNestedReference(symbolRef, 0),
|
|
|
|
flatSymbolRef) ||
|
|
|
|
!mlirAttributeEqual(mlirSymbolRefAttrGetNestedReference(symbolRef, 1),
|
|
|
|
flatSymbolRef))
|
|
|
|
return 10;
|
2020-09-15 18:04:59 +08:00
|
|
|
|
|
|
|
MlirStringRef symbolRefLeaf = mlirSymbolRefAttrGetLeafReference(symbolRef);
|
|
|
|
MlirStringRef symbolRefRoot = mlirSymbolRefAttrGetRootReference(symbolRef);
|
|
|
|
if (symbolRefLeaf.length != 3 ||
|
|
|
|
strncmp(data + 5, symbolRefLeaf.data, symbolRefLeaf.length) ||
|
|
|
|
symbolRefRoot.length != 2 ||
|
|
|
|
strncmp(data + 8, symbolRefRoot.data, symbolRefRoot.length))
|
2020-08-20 00:38:56 +08:00
|
|
|
return 11;
|
|
|
|
mlirAttributeDump(symbolRef);
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: @ij::@fgh::@fgh
|
2020-08-20 00:38:56 +08:00
|
|
|
|
|
|
|
MlirAttribute type = mlirTypeAttrGet(mlirF32TypeGet(ctx));
|
|
|
|
if (!mlirAttributeIsAType(type) ||
|
|
|
|
!mlirTypeEqual(mlirF32TypeGet(ctx), mlirTypeAttrGetValue(type)))
|
|
|
|
return 12;
|
|
|
|
mlirAttributeDump(type);
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: f32
|
2020-08-20 00:38:56 +08:00
|
|
|
|
|
|
|
MlirAttribute unit = mlirUnitAttrGet(ctx);
|
|
|
|
if (!mlirAttributeIsAUnit(unit))
|
|
|
|
return 13;
|
|
|
|
mlirAttributeDump(unit);
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: unit
|
2020-08-20 00:38:56 +08:00
|
|
|
|
|
|
|
int64_t shape[] = {1, 2};
|
|
|
|
|
|
|
|
int bools[] = {0, 1};
|
|
|
|
uint32_t uints32[] = {0u, 1u};
|
|
|
|
int32_t ints32[] = {0, 1};
|
|
|
|
uint64_t uints64[] = {0u, 1u};
|
|
|
|
int64_t ints64[] = {0, 1};
|
|
|
|
float floats[] = {0.0f, 1.0f};
|
|
|
|
double doubles[] = {0.0, 1.0};
|
|
|
|
MlirAttribute boolElements = mlirDenseElementsAttrBoolGet(
|
|
|
|
mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 1)), 2, bools);
|
|
|
|
MlirAttribute uint32Elements = mlirDenseElementsAttrUInt32Get(
|
|
|
|
mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 32)), 2,
|
|
|
|
uints32);
|
|
|
|
MlirAttribute int32Elements = mlirDenseElementsAttrInt32Get(
|
|
|
|
mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 32)), 2,
|
|
|
|
ints32);
|
|
|
|
MlirAttribute uint64Elements = mlirDenseElementsAttrUInt64Get(
|
|
|
|
mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeUnsignedGet(ctx, 64)), 2,
|
|
|
|
uints64);
|
|
|
|
MlirAttribute int64Elements = mlirDenseElementsAttrInt64Get(
|
|
|
|
mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64)), 2,
|
|
|
|
ints64);
|
|
|
|
MlirAttribute floatElements = mlirDenseElementsAttrFloatGet(
|
|
|
|
mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx)), 2, floats);
|
|
|
|
MlirAttribute doubleElements = mlirDenseElementsAttrDoubleGet(
|
|
|
|
mlirRankedTensorTypeGet(2, shape, mlirF64TypeGet(ctx)), 2, doubles);
|
|
|
|
|
|
|
|
if (!mlirAttributeIsADenseElements(boolElements) ||
|
|
|
|
!mlirAttributeIsADenseElements(uint32Elements) ||
|
|
|
|
!mlirAttributeIsADenseElements(int32Elements) ||
|
|
|
|
!mlirAttributeIsADenseElements(uint64Elements) ||
|
|
|
|
!mlirAttributeIsADenseElements(int64Elements) ||
|
|
|
|
!mlirAttributeIsADenseElements(floatElements) ||
|
|
|
|
!mlirAttributeIsADenseElements(doubleElements))
|
|
|
|
return 14;
|
|
|
|
|
|
|
|
if (mlirDenseElementsAttrGetBoolValue(boolElements, 1) != 1 ||
|
|
|
|
mlirDenseElementsAttrGetUInt32Value(uint32Elements, 1) != 1 ||
|
|
|
|
mlirDenseElementsAttrGetInt32Value(int32Elements, 1) != 1 ||
|
|
|
|
mlirDenseElementsAttrGetUInt64Value(uint64Elements, 1) != 1 ||
|
|
|
|
mlirDenseElementsAttrGetInt64Value(int64Elements, 1) != 1 ||
|
|
|
|
fabsf(mlirDenseElementsAttrGetFloatValue(floatElements, 1) - 1.0f) >
|
|
|
|
1E-6f ||
|
|
|
|
fabs(mlirDenseElementsAttrGetDoubleValue(doubleElements, 1) - 1.0) > 1E-6)
|
|
|
|
return 15;
|
|
|
|
|
|
|
|
mlirAttributeDump(boolElements);
|
|
|
|
mlirAttributeDump(uint32Elements);
|
|
|
|
mlirAttributeDump(int32Elements);
|
|
|
|
mlirAttributeDump(uint64Elements);
|
|
|
|
mlirAttributeDump(int64Elements);
|
|
|
|
mlirAttributeDump(floatElements);
|
|
|
|
mlirAttributeDump(doubleElements);
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: dense<{{\[}}[false, true]]> : tensor<1x2xi1>
|
|
|
|
// CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xui32>
|
|
|
|
// CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xi32>
|
|
|
|
// CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xui64>
|
|
|
|
// CHECK: dense<{{\[}}[0, 1]]> : tensor<1x2xi64>
|
|
|
|
// CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xf32>
|
|
|
|
// CHECK: dense<{{\[}}[0.000000e+00, 1.000000e+00]]> : tensor<1x2xf64>
|
2020-08-20 00:38:56 +08:00
|
|
|
|
|
|
|
MlirAttribute splatBool = mlirDenseElementsAttrBoolSplatGet(
|
|
|
|
mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 1)), 1);
|
|
|
|
MlirAttribute splatUInt32 = mlirDenseElementsAttrUInt32SplatGet(
|
|
|
|
mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 32)), 1);
|
|
|
|
MlirAttribute splatInt32 = mlirDenseElementsAttrInt32SplatGet(
|
|
|
|
mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 32)), 1);
|
|
|
|
MlirAttribute splatUInt64 = mlirDenseElementsAttrUInt64SplatGet(
|
|
|
|
mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64)), 1);
|
|
|
|
MlirAttribute splatInt64 = mlirDenseElementsAttrInt64SplatGet(
|
|
|
|
mlirRankedTensorTypeGet(2, shape, mlirIntegerTypeGet(ctx, 64)), 1);
|
|
|
|
MlirAttribute splatFloat = mlirDenseElementsAttrFloatSplatGet(
|
|
|
|
mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx)), 1.0f);
|
|
|
|
MlirAttribute splatDouble = mlirDenseElementsAttrDoubleSplatGet(
|
|
|
|
mlirRankedTensorTypeGet(2, shape, mlirF64TypeGet(ctx)), 1.0);
|
|
|
|
|
|
|
|
if (!mlirAttributeIsADenseElements(splatBool) ||
|
|
|
|
!mlirDenseElementsAttrIsSplat(splatBool) ||
|
|
|
|
!mlirAttributeIsADenseElements(splatUInt32) ||
|
|
|
|
!mlirDenseElementsAttrIsSplat(splatUInt32) ||
|
|
|
|
!mlirAttributeIsADenseElements(splatInt32) ||
|
|
|
|
!mlirDenseElementsAttrIsSplat(splatInt32) ||
|
|
|
|
!mlirAttributeIsADenseElements(splatUInt64) ||
|
|
|
|
!mlirDenseElementsAttrIsSplat(splatUInt64) ||
|
|
|
|
!mlirAttributeIsADenseElements(splatInt64) ||
|
|
|
|
!mlirDenseElementsAttrIsSplat(splatInt64) ||
|
|
|
|
!mlirAttributeIsADenseElements(splatFloat) ||
|
|
|
|
!mlirDenseElementsAttrIsSplat(splatFloat) ||
|
|
|
|
!mlirAttributeIsADenseElements(splatDouble) ||
|
|
|
|
!mlirDenseElementsAttrIsSplat(splatDouble))
|
|
|
|
return 16;
|
|
|
|
|
|
|
|
if (mlirDenseElementsAttrGetBoolSplatValue(splatBool) != 1 ||
|
|
|
|
mlirDenseElementsAttrGetUInt32SplatValue(splatUInt32) != 1 ||
|
|
|
|
mlirDenseElementsAttrGetInt32SplatValue(splatInt32) != 1 ||
|
|
|
|
mlirDenseElementsAttrGetUInt64SplatValue(splatUInt64) != 1 ||
|
|
|
|
mlirDenseElementsAttrGetInt64SplatValue(splatInt64) != 1 ||
|
|
|
|
fabsf(mlirDenseElementsAttrGetFloatSplatValue(splatFloat) - 1.0f) >
|
|
|
|
1E-6f ||
|
|
|
|
fabs(mlirDenseElementsAttrGetDoubleSplatValue(splatDouble) - 1.0) > 1E-6)
|
|
|
|
return 17;
|
|
|
|
|
2020-11-08 09:28:35 +08:00
|
|
|
uint32_t *uint32RawData =
|
|
|
|
(uint32_t *)mlirDenseElementsAttrGetRawData(uint32Elements);
|
|
|
|
int32_t *int32RawData =
|
|
|
|
(int32_t *)mlirDenseElementsAttrGetRawData(int32Elements);
|
|
|
|
uint64_t *uint64RawData =
|
|
|
|
(uint64_t *)mlirDenseElementsAttrGetRawData(uint64Elements);
|
|
|
|
int64_t *int64RawData =
|
|
|
|
(int64_t *)mlirDenseElementsAttrGetRawData(int64Elements);
|
2021-01-23 10:43:50 +08:00
|
|
|
float *floatRawData = (float *)mlirDenseElementsAttrGetRawData(floatElements);
|
2020-11-08 09:28:35 +08:00
|
|
|
double *doubleRawData =
|
|
|
|
(double *)mlirDenseElementsAttrGetRawData(doubleElements);
|
|
|
|
if (uint32RawData[0] != 0u || uint32RawData[1] != 1u ||
|
2021-01-23 10:43:50 +08:00
|
|
|
int32RawData[0] != 0 || int32RawData[1] != 1 || uint64RawData[0] != 0u ||
|
|
|
|
uint64RawData[1] != 1u || int64RawData[0] != 0 || int64RawData[1] != 1 ||
|
2020-11-08 09:28:35 +08:00
|
|
|
floatRawData[0] != 0.0f || floatRawData[1] != 1.0f ||
|
|
|
|
doubleRawData[0] != 0.0 || doubleRawData[1] != 1.0)
|
|
|
|
return 18;
|
|
|
|
|
2020-08-20 00:38:56 +08:00
|
|
|
mlirAttributeDump(splatBool);
|
|
|
|
mlirAttributeDump(splatUInt32);
|
|
|
|
mlirAttributeDump(splatInt32);
|
|
|
|
mlirAttributeDump(splatUInt64);
|
|
|
|
mlirAttributeDump(splatInt64);
|
|
|
|
mlirAttributeDump(splatFloat);
|
|
|
|
mlirAttributeDump(splatDouble);
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: dense<true> : tensor<1x2xi1>
|
|
|
|
// CHECK: dense<1> : tensor<1x2xi32>
|
|
|
|
// CHECK: dense<1> : tensor<1x2xi32>
|
|
|
|
// CHECK: dense<1> : tensor<1x2xi64>
|
|
|
|
// CHECK: dense<1> : tensor<1x2xi64>
|
|
|
|
// CHECK: dense<1.000000e+00> : tensor<1x2xf32>
|
|
|
|
// CHECK: dense<1.000000e+00> : tensor<1x2xf64>
|
2020-08-20 00:38:56 +08:00
|
|
|
|
|
|
|
mlirAttributeDump(mlirElementsAttrGetValue(floatElements, 2, uints64));
|
|
|
|
mlirAttributeDump(mlirElementsAttrGetValue(doubleElements, 2, uints64));
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: 1.000000e+00 : f32
|
|
|
|
// CHECK: 1.000000e+00 : f64
|
2020-08-20 00:38:56 +08:00
|
|
|
|
|
|
|
int64_t indices[] = {4, 7};
|
|
|
|
int64_t two = 2;
|
|
|
|
MlirAttribute indicesAttr = mlirDenseElementsAttrInt64Get(
|
|
|
|
mlirRankedTensorTypeGet(1, &two, mlirIntegerTypeGet(ctx, 64)), 2,
|
|
|
|
indices);
|
|
|
|
MlirAttribute valuesAttr = mlirDenseElementsAttrFloatGet(
|
|
|
|
mlirRankedTensorTypeGet(1, &two, mlirF32TypeGet(ctx)), 2, floats);
|
|
|
|
MlirAttribute sparseAttr = mlirSparseElementsAttribute(
|
|
|
|
mlirRankedTensorTypeGet(2, shape, mlirF32TypeGet(ctx)), indicesAttr,
|
|
|
|
valuesAttr);
|
|
|
|
mlirAttributeDump(sparseAttr);
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: sparse<[4, 7], [0.000000e+00, 1.000000e+00]> : tensor<1x2xf32>
|
2020-08-20 00:38:56 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-09-14 22:52:22 +08:00
|
|
|
int printAffineMap(MlirContext ctx) {
|
|
|
|
MlirAffineMap emptyAffineMap = mlirAffineMapEmptyGet(ctx);
|
2021-01-08 20:36:27 +08:00
|
|
|
MlirAffineMap affineMap = mlirAffineMapZeroResultGet(ctx, 3, 2);
|
2020-09-14 22:52:22 +08:00
|
|
|
MlirAffineMap constAffineMap = mlirAffineMapConstantGet(ctx, 2);
|
|
|
|
MlirAffineMap multiDimIdentityAffineMap =
|
|
|
|
mlirAffineMapMultiDimIdentityGet(ctx, 3);
|
|
|
|
MlirAffineMap minorIdentityAffineMap =
|
|
|
|
mlirAffineMapMinorIdentityGet(ctx, 3, 2);
|
|
|
|
unsigned permutation[] = {1, 2, 0};
|
|
|
|
MlirAffineMap permutationAffineMap = mlirAffineMapPermutationGet(
|
|
|
|
ctx, sizeof(permutation) / sizeof(unsigned), permutation);
|
|
|
|
|
2020-11-04 17:30:00 +08:00
|
|
|
fprintf(stderr, "@affineMap\n");
|
2020-09-14 22:52:22 +08:00
|
|
|
mlirAffineMapDump(emptyAffineMap);
|
|
|
|
mlirAffineMapDump(affineMap);
|
|
|
|
mlirAffineMapDump(constAffineMap);
|
|
|
|
mlirAffineMapDump(multiDimIdentityAffineMap);
|
|
|
|
mlirAffineMapDump(minorIdentityAffineMap);
|
|
|
|
mlirAffineMapDump(permutationAffineMap);
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK-LABEL: @affineMap
|
|
|
|
// CHECK: () -> ()
|
|
|
|
// CHECK: (d0, d1, d2)[s0, s1] -> ()
|
|
|
|
// CHECK: () -> (2)
|
|
|
|
// CHECK: (d0, d1, d2) -> (d0, d1, d2)
|
|
|
|
// CHECK: (d0, d1, d2) -> (d1, d2)
|
|
|
|
// CHECK: (d0, d1, d2) -> (d1, d2, d0)
|
2020-09-14 22:52:22 +08:00
|
|
|
|
|
|
|
if (!mlirAffineMapIsIdentity(emptyAffineMap) ||
|
|
|
|
mlirAffineMapIsIdentity(affineMap) ||
|
|
|
|
mlirAffineMapIsIdentity(constAffineMap) ||
|
|
|
|
!mlirAffineMapIsIdentity(multiDimIdentityAffineMap) ||
|
|
|
|
mlirAffineMapIsIdentity(minorIdentityAffineMap) ||
|
|
|
|
mlirAffineMapIsIdentity(permutationAffineMap))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (!mlirAffineMapIsMinorIdentity(emptyAffineMap) ||
|
|
|
|
mlirAffineMapIsMinorIdentity(affineMap) ||
|
|
|
|
!mlirAffineMapIsMinorIdentity(multiDimIdentityAffineMap) ||
|
|
|
|
!mlirAffineMapIsMinorIdentity(minorIdentityAffineMap) ||
|
|
|
|
mlirAffineMapIsMinorIdentity(permutationAffineMap))
|
|
|
|
return 2;
|
|
|
|
|
|
|
|
if (!mlirAffineMapIsEmpty(emptyAffineMap) ||
|
2020-09-28 22:28:04 +08:00
|
|
|
mlirAffineMapIsEmpty(affineMap) || mlirAffineMapIsEmpty(constAffineMap) ||
|
2020-09-14 22:52:22 +08:00
|
|
|
mlirAffineMapIsEmpty(multiDimIdentityAffineMap) ||
|
|
|
|
mlirAffineMapIsEmpty(minorIdentityAffineMap) ||
|
|
|
|
mlirAffineMapIsEmpty(permutationAffineMap))
|
|
|
|
return 3;
|
|
|
|
|
|
|
|
if (mlirAffineMapIsSingleConstant(emptyAffineMap) ||
|
|
|
|
mlirAffineMapIsSingleConstant(affineMap) ||
|
|
|
|
!mlirAffineMapIsSingleConstant(constAffineMap) ||
|
|
|
|
mlirAffineMapIsSingleConstant(multiDimIdentityAffineMap) ||
|
|
|
|
mlirAffineMapIsSingleConstant(minorIdentityAffineMap) ||
|
|
|
|
mlirAffineMapIsSingleConstant(permutationAffineMap))
|
|
|
|
return 4;
|
|
|
|
|
|
|
|
if (mlirAffineMapGetSingleConstantResult(constAffineMap) != 2)
|
|
|
|
return 5;
|
|
|
|
|
|
|
|
if (mlirAffineMapGetNumDims(emptyAffineMap) != 0 ||
|
|
|
|
mlirAffineMapGetNumDims(affineMap) != 3 ||
|
|
|
|
mlirAffineMapGetNumDims(constAffineMap) != 0 ||
|
|
|
|
mlirAffineMapGetNumDims(multiDimIdentityAffineMap) != 3 ||
|
|
|
|
mlirAffineMapGetNumDims(minorIdentityAffineMap) != 3 ||
|
|
|
|
mlirAffineMapGetNumDims(permutationAffineMap) != 3)
|
|
|
|
return 6;
|
|
|
|
|
|
|
|
if (mlirAffineMapGetNumSymbols(emptyAffineMap) != 0 ||
|
|
|
|
mlirAffineMapGetNumSymbols(affineMap) != 2 ||
|
|
|
|
mlirAffineMapGetNumSymbols(constAffineMap) != 0 ||
|
|
|
|
mlirAffineMapGetNumSymbols(multiDimIdentityAffineMap) != 0 ||
|
|
|
|
mlirAffineMapGetNumSymbols(minorIdentityAffineMap) != 0 ||
|
|
|
|
mlirAffineMapGetNumSymbols(permutationAffineMap) != 0)
|
|
|
|
return 7;
|
|
|
|
|
|
|
|
if (mlirAffineMapGetNumResults(emptyAffineMap) != 0 ||
|
|
|
|
mlirAffineMapGetNumResults(affineMap) != 0 ||
|
|
|
|
mlirAffineMapGetNumResults(constAffineMap) != 1 ||
|
|
|
|
mlirAffineMapGetNumResults(multiDimIdentityAffineMap) != 3 ||
|
|
|
|
mlirAffineMapGetNumResults(minorIdentityAffineMap) != 2 ||
|
|
|
|
mlirAffineMapGetNumResults(permutationAffineMap) != 3)
|
|
|
|
return 8;
|
|
|
|
|
|
|
|
if (mlirAffineMapGetNumInputs(emptyAffineMap) != 0 ||
|
|
|
|
mlirAffineMapGetNumInputs(affineMap) != 5 ||
|
|
|
|
mlirAffineMapGetNumInputs(constAffineMap) != 0 ||
|
|
|
|
mlirAffineMapGetNumInputs(multiDimIdentityAffineMap) != 3 ||
|
|
|
|
mlirAffineMapGetNumInputs(minorIdentityAffineMap) != 3 ||
|
|
|
|
mlirAffineMapGetNumInputs(permutationAffineMap) != 3)
|
|
|
|
return 9;
|
|
|
|
|
|
|
|
if (!mlirAffineMapIsProjectedPermutation(emptyAffineMap) ||
|
|
|
|
!mlirAffineMapIsPermutation(emptyAffineMap) ||
|
|
|
|
mlirAffineMapIsProjectedPermutation(affineMap) ||
|
|
|
|
mlirAffineMapIsPermutation(affineMap) ||
|
|
|
|
mlirAffineMapIsProjectedPermutation(constAffineMap) ||
|
|
|
|
mlirAffineMapIsPermutation(constAffineMap) ||
|
|
|
|
!mlirAffineMapIsProjectedPermutation(multiDimIdentityAffineMap) ||
|
|
|
|
!mlirAffineMapIsPermutation(multiDimIdentityAffineMap) ||
|
|
|
|
!mlirAffineMapIsProjectedPermutation(minorIdentityAffineMap) ||
|
|
|
|
mlirAffineMapIsPermutation(minorIdentityAffineMap) ||
|
|
|
|
!mlirAffineMapIsProjectedPermutation(permutationAffineMap) ||
|
|
|
|
!mlirAffineMapIsPermutation(permutationAffineMap))
|
|
|
|
return 10;
|
|
|
|
|
|
|
|
intptr_t sub[] = {1};
|
|
|
|
|
|
|
|
MlirAffineMap subMap = mlirAffineMapGetSubMap(
|
|
|
|
multiDimIdentityAffineMap, sizeof(sub) / sizeof(intptr_t), sub);
|
|
|
|
MlirAffineMap majorSubMap =
|
|
|
|
mlirAffineMapGetMajorSubMap(multiDimIdentityAffineMap, 1);
|
|
|
|
MlirAffineMap minorSubMap =
|
|
|
|
mlirAffineMapGetMinorSubMap(multiDimIdentityAffineMap, 1);
|
|
|
|
|
|
|
|
mlirAffineMapDump(subMap);
|
|
|
|
mlirAffineMapDump(majorSubMap);
|
|
|
|
mlirAffineMapDump(minorSubMap);
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: (d0, d1, d2) -> (d1)
|
|
|
|
// CHECK: (d0, d1, d2) -> (d0)
|
|
|
|
// CHECK: (d0, d1, d2) -> (d2)
|
2020-09-14 22:52:22 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-10-21 15:32:01 +08:00
|
|
|
int printAffineExpr(MlirContext ctx) {
|
|
|
|
MlirAffineExpr affineDimExpr = mlirAffineDimExprGet(ctx, 5);
|
|
|
|
MlirAffineExpr affineSymbolExpr = mlirAffineSymbolExprGet(ctx, 5);
|
|
|
|
MlirAffineExpr affineConstantExpr = mlirAffineConstantExprGet(ctx, 5);
|
|
|
|
MlirAffineExpr affineAddExpr =
|
|
|
|
mlirAffineAddExprGet(affineDimExpr, affineSymbolExpr);
|
|
|
|
MlirAffineExpr affineMulExpr =
|
|
|
|
mlirAffineMulExprGet(affineDimExpr, affineSymbolExpr);
|
|
|
|
MlirAffineExpr affineModExpr =
|
|
|
|
mlirAffineModExprGet(affineDimExpr, affineSymbolExpr);
|
|
|
|
MlirAffineExpr affineFloorDivExpr =
|
|
|
|
mlirAffineFloorDivExprGet(affineDimExpr, affineSymbolExpr);
|
|
|
|
MlirAffineExpr affineCeilDivExpr =
|
|
|
|
mlirAffineCeilDivExprGet(affineDimExpr, affineSymbolExpr);
|
|
|
|
|
|
|
|
// Tests mlirAffineExprDump.
|
2020-11-04 17:30:00 +08:00
|
|
|
fprintf(stderr, "@affineExpr\n");
|
2020-10-21 15:32:01 +08:00
|
|
|
mlirAffineExprDump(affineDimExpr);
|
|
|
|
mlirAffineExprDump(affineSymbolExpr);
|
|
|
|
mlirAffineExprDump(affineConstantExpr);
|
|
|
|
mlirAffineExprDump(affineAddExpr);
|
|
|
|
mlirAffineExprDump(affineMulExpr);
|
|
|
|
mlirAffineExprDump(affineModExpr);
|
|
|
|
mlirAffineExprDump(affineFloorDivExpr);
|
|
|
|
mlirAffineExprDump(affineCeilDivExpr);
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK-LABEL: @affineExpr
|
|
|
|
// CHECK: d5
|
|
|
|
// CHECK: s5
|
|
|
|
// CHECK: 5
|
|
|
|
// CHECK: d5 + s5
|
|
|
|
// CHECK: d5 * s5
|
|
|
|
// CHECK: d5 mod s5
|
|
|
|
// CHECK: d5 floordiv s5
|
|
|
|
// CHECK: d5 ceildiv s5
|
2020-10-21 15:32:01 +08:00
|
|
|
|
|
|
|
// Tests methods of affine binary operation expression, takes add expression
|
|
|
|
// as an example.
|
|
|
|
mlirAffineExprDump(mlirAffineBinaryOpExprGetLHS(affineAddExpr));
|
|
|
|
mlirAffineExprDump(mlirAffineBinaryOpExprGetRHS(affineAddExpr));
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: d5
|
|
|
|
// CHECK: s5
|
2020-10-21 15:32:01 +08:00
|
|
|
|
|
|
|
// Tests methods of affine dimension expression.
|
|
|
|
if (mlirAffineDimExprGetPosition(affineDimExpr) != 5)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
// Tests methods of affine symbol expression.
|
|
|
|
if (mlirAffineSymbolExprGetPosition(affineSymbolExpr) != 5)
|
|
|
|
return 2;
|
|
|
|
|
|
|
|
// Tests methods of affine constant expression.
|
|
|
|
if (mlirAffineConstantExprGetValue(affineConstantExpr) != 5)
|
|
|
|
return 3;
|
|
|
|
|
|
|
|
// Tests methods of affine expression.
|
|
|
|
if (mlirAffineExprIsSymbolicOrConstant(affineDimExpr) ||
|
|
|
|
!mlirAffineExprIsSymbolicOrConstant(affineSymbolExpr) ||
|
|
|
|
!mlirAffineExprIsSymbolicOrConstant(affineConstantExpr) ||
|
|
|
|
mlirAffineExprIsSymbolicOrConstant(affineAddExpr) ||
|
|
|
|
mlirAffineExprIsSymbolicOrConstant(affineMulExpr) ||
|
|
|
|
mlirAffineExprIsSymbolicOrConstant(affineModExpr) ||
|
|
|
|
mlirAffineExprIsSymbolicOrConstant(affineFloorDivExpr) ||
|
|
|
|
mlirAffineExprIsSymbolicOrConstant(affineCeilDivExpr))
|
|
|
|
return 4;
|
|
|
|
|
|
|
|
if (!mlirAffineExprIsPureAffine(affineDimExpr) ||
|
|
|
|
!mlirAffineExprIsPureAffine(affineSymbolExpr) ||
|
|
|
|
!mlirAffineExprIsPureAffine(affineConstantExpr) ||
|
|
|
|
!mlirAffineExprIsPureAffine(affineAddExpr) ||
|
|
|
|
mlirAffineExprIsPureAffine(affineMulExpr) ||
|
|
|
|
mlirAffineExprIsPureAffine(affineModExpr) ||
|
|
|
|
mlirAffineExprIsPureAffine(affineFloorDivExpr) ||
|
|
|
|
mlirAffineExprIsPureAffine(affineCeilDivExpr))
|
|
|
|
return 5;
|
|
|
|
|
|
|
|
if (mlirAffineExprGetLargestKnownDivisor(affineDimExpr) != 1 ||
|
|
|
|
mlirAffineExprGetLargestKnownDivisor(affineSymbolExpr) != 1 ||
|
|
|
|
mlirAffineExprGetLargestKnownDivisor(affineConstantExpr) != 5 ||
|
|
|
|
mlirAffineExprGetLargestKnownDivisor(affineAddExpr) != 1 ||
|
|
|
|
mlirAffineExprGetLargestKnownDivisor(affineMulExpr) != 1 ||
|
|
|
|
mlirAffineExprGetLargestKnownDivisor(affineModExpr) != 1 ||
|
|
|
|
mlirAffineExprGetLargestKnownDivisor(affineFloorDivExpr) != 1 ||
|
|
|
|
mlirAffineExprGetLargestKnownDivisor(affineCeilDivExpr) != 1)
|
|
|
|
return 6;
|
|
|
|
|
|
|
|
if (!mlirAffineExprIsMultipleOf(affineDimExpr, 1) ||
|
|
|
|
!mlirAffineExprIsMultipleOf(affineSymbolExpr, 1) ||
|
|
|
|
!mlirAffineExprIsMultipleOf(affineConstantExpr, 5) ||
|
|
|
|
!mlirAffineExprIsMultipleOf(affineAddExpr, 1) ||
|
|
|
|
!mlirAffineExprIsMultipleOf(affineMulExpr, 1) ||
|
|
|
|
!mlirAffineExprIsMultipleOf(affineModExpr, 1) ||
|
|
|
|
!mlirAffineExprIsMultipleOf(affineFloorDivExpr, 1) ||
|
|
|
|
!mlirAffineExprIsMultipleOf(affineCeilDivExpr, 1))
|
|
|
|
return 7;
|
|
|
|
|
|
|
|
if (!mlirAffineExprIsFunctionOfDim(affineDimExpr, 5) ||
|
|
|
|
mlirAffineExprIsFunctionOfDim(affineSymbolExpr, 5) ||
|
|
|
|
mlirAffineExprIsFunctionOfDim(affineConstantExpr, 5) ||
|
|
|
|
!mlirAffineExprIsFunctionOfDim(affineAddExpr, 5) ||
|
|
|
|
!mlirAffineExprIsFunctionOfDim(affineMulExpr, 5) ||
|
|
|
|
!mlirAffineExprIsFunctionOfDim(affineModExpr, 5) ||
|
|
|
|
!mlirAffineExprIsFunctionOfDim(affineFloorDivExpr, 5) ||
|
|
|
|
!mlirAffineExprIsFunctionOfDim(affineCeilDivExpr, 5))
|
|
|
|
return 8;
|
|
|
|
|
2020-10-29 03:03:15 +08:00
|
|
|
// Tests 'IsA' methods of affine binary operation expression.
|
2020-10-21 15:32:01 +08:00
|
|
|
if (!mlirAffineExprIsAAdd(affineAddExpr))
|
|
|
|
return 9;
|
|
|
|
|
|
|
|
if (!mlirAffineExprIsAMul(affineMulExpr))
|
|
|
|
return 10;
|
|
|
|
|
|
|
|
if (!mlirAffineExprIsAMod(affineModExpr))
|
|
|
|
return 11;
|
|
|
|
|
|
|
|
if (!mlirAffineExprIsAFloorDiv(affineFloorDivExpr))
|
|
|
|
return 12;
|
|
|
|
|
|
|
|
if (!mlirAffineExprIsACeilDiv(affineCeilDivExpr))
|
|
|
|
return 13;
|
|
|
|
|
2021-01-07 18:09:09 +08:00
|
|
|
if (!mlirAffineExprIsABinary(affineAddExpr))
|
|
|
|
return 14;
|
|
|
|
|
|
|
|
// Test other 'IsA' method on affine expressions.
|
|
|
|
if (!mlirAffineExprIsAConstant(affineConstantExpr))
|
|
|
|
return 15;
|
|
|
|
|
|
|
|
if (!mlirAffineExprIsADim(affineDimExpr))
|
|
|
|
return 16;
|
|
|
|
|
|
|
|
if (!mlirAffineExprIsASymbol(affineSymbolExpr))
|
|
|
|
return 17;
|
|
|
|
|
|
|
|
// Test equality and nullity.
|
|
|
|
MlirAffineExpr otherDimExpr = mlirAffineDimExprGet(ctx, 5);
|
|
|
|
if (!mlirAffineExprEqual(affineDimExpr, otherDimExpr))
|
|
|
|
return 18;
|
|
|
|
|
|
|
|
if (mlirAffineExprIsNull(affineDimExpr))
|
|
|
|
return 19;
|
|
|
|
|
2020-10-21 15:32:01 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-01-08 20:36:27 +08:00
|
|
|
int affineMapFromExprs(MlirContext ctx) {
|
|
|
|
MlirAffineExpr affineDimExpr = mlirAffineDimExprGet(ctx, 0);
|
|
|
|
MlirAffineExpr affineSymbolExpr = mlirAffineSymbolExprGet(ctx, 1);
|
|
|
|
MlirAffineExpr exprs[] = {affineDimExpr, affineSymbolExpr};
|
|
|
|
MlirAffineMap map = mlirAffineMapGet(ctx, 3, 3, 2, exprs);
|
|
|
|
|
|
|
|
// CHECK-LABEL: @affineMapFromExprs
|
|
|
|
fprintf(stderr, "@affineMapFromExprs");
|
|
|
|
// CHECK: (d0, d1, d2)[s0, s1, s2] -> (d0, s1)
|
|
|
|
mlirAffineMapDump(map);
|
|
|
|
|
|
|
|
if (mlirAffineMapGetNumResults(map) != 2)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (!mlirAffineExprEqual(mlirAffineMapGetResult(map, 0), affineDimExpr))
|
|
|
|
return 2;
|
|
|
|
|
|
|
|
if (!mlirAffineExprEqual(mlirAffineMapGetResult(map, 1), affineSymbolExpr))
|
|
|
|
return 3;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-01-26 00:12:35 +08:00
|
|
|
int printIntegerSet(MlirContext ctx) {
|
|
|
|
MlirIntegerSet emptySet = mlirIntegerSetEmptyGet(ctx, 2, 1);
|
|
|
|
|
|
|
|
// CHECK-LABEL: @printIntegerSet
|
|
|
|
fprintf(stderr, "@printIntegerSet");
|
|
|
|
|
|
|
|
// CHECK: (d0, d1)[s0] : (1 == 0)
|
|
|
|
mlirIntegerSetDump(emptySet);
|
|
|
|
|
|
|
|
if (!mlirIntegerSetIsCanonicalEmpty(emptySet))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
MlirIntegerSet anotherEmptySet = mlirIntegerSetEmptyGet(ctx, 2, 1);
|
|
|
|
if (!mlirIntegerSetEqual(emptySet, anotherEmptySet))
|
|
|
|
return 2;
|
|
|
|
|
|
|
|
// Construct a set constrained by:
|
|
|
|
// d0 - s0 == 0,
|
|
|
|
// d1 - 42 >= 0.
|
|
|
|
MlirAffineExpr negOne = mlirAffineConstantExprGet(ctx, -1);
|
|
|
|
MlirAffineExpr negFortyTwo = mlirAffineConstantExprGet(ctx, -42);
|
|
|
|
MlirAffineExpr d0 = mlirAffineDimExprGet(ctx, 0);
|
|
|
|
MlirAffineExpr d1 = mlirAffineDimExprGet(ctx, 1);
|
|
|
|
MlirAffineExpr s0 = mlirAffineSymbolExprGet(ctx, 0);
|
|
|
|
MlirAffineExpr negS0 = mlirAffineMulExprGet(negOne, s0);
|
|
|
|
MlirAffineExpr d0minusS0 = mlirAffineAddExprGet(d0, negS0);
|
|
|
|
MlirAffineExpr d1minus42 = mlirAffineAddExprGet(d1, negFortyTwo);
|
|
|
|
MlirAffineExpr constraints[] = {d0minusS0, d1minus42};
|
|
|
|
bool flags[] = {true, false};
|
|
|
|
|
|
|
|
MlirIntegerSet set = mlirIntegerSetGet(ctx, 2, 1, 2, constraints, flags);
|
|
|
|
// CHECK: (d0, d1)[s0] : (
|
|
|
|
// CHECK-DAG: d0 - s0 == 0
|
|
|
|
// CHECK-DAG: d1 - 42 >= 0
|
|
|
|
mlirIntegerSetDump(set);
|
|
|
|
|
|
|
|
// Transform d1 into s0.
|
|
|
|
MlirAffineExpr s1 = mlirAffineSymbolExprGet(ctx, 1);
|
|
|
|
MlirAffineExpr repl[] = {d0, s1};
|
|
|
|
MlirIntegerSet replaced = mlirIntegerSetReplaceGet(set, repl, &s0, 1, 2);
|
|
|
|
// CHECK: (d0)[s0, s1] : (
|
|
|
|
// CHECK-DAG: d0 - s0 == 0
|
|
|
|
// CHECK-DAG: s1 - 42 >= 0
|
|
|
|
mlirIntegerSetDump(replaced);
|
|
|
|
|
|
|
|
if (mlirIntegerSetGetNumDims(set) != 2)
|
|
|
|
return 3;
|
|
|
|
if (mlirIntegerSetGetNumDims(replaced) != 1)
|
|
|
|
return 4;
|
|
|
|
|
|
|
|
if (mlirIntegerSetGetNumSymbols(set) != 1)
|
|
|
|
return 5;
|
|
|
|
if (mlirIntegerSetGetNumSymbols(replaced) != 2)
|
|
|
|
return 6;
|
|
|
|
|
|
|
|
if (mlirIntegerSetGetNumInputs(set) != 3)
|
|
|
|
return 7;
|
|
|
|
|
|
|
|
if (mlirIntegerSetGetNumConstraints(set) != 2)
|
|
|
|
return 8;
|
|
|
|
|
|
|
|
if (mlirIntegerSetGetNumEqualities(set) != 1)
|
|
|
|
return 9;
|
|
|
|
|
|
|
|
if (mlirIntegerSetGetNumInequalities(set) != 1)
|
|
|
|
return 10;
|
|
|
|
|
|
|
|
MlirAffineExpr cstr1 = mlirIntegerSetGetConstraint(set, 0);
|
|
|
|
MlirAffineExpr cstr2 = mlirIntegerSetGetConstraint(set, 1);
|
|
|
|
bool isEq1 = mlirIntegerSetIsConstraintEq(set, 0);
|
|
|
|
bool isEq2 = mlirIntegerSetIsConstraintEq(set, 1);
|
|
|
|
if (!mlirAffineExprEqual(cstr1, isEq1 ? d0minusS0 : d1minus42))
|
|
|
|
return 11;
|
|
|
|
if (!mlirAffineExprEqual(cstr2, isEq2 ? d0minusS0 : d1minus42))
|
|
|
|
return 12;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-09-29 22:23:02 +08:00
|
|
|
int registerOnlyStd() {
|
|
|
|
MlirContext ctx = mlirContextCreate();
|
|
|
|
// The built-in dialect is always loaded.
|
|
|
|
if (mlirContextGetNumLoadedDialects(ctx) != 1)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
MlirDialect std =
|
|
|
|
mlirContextGetOrLoadDialect(ctx, mlirStandardDialectGetNamespace());
|
|
|
|
if (!mlirDialectIsNull(std))
|
|
|
|
return 2;
|
|
|
|
|
|
|
|
mlirContextRegisterStandardDialect(ctx);
|
|
|
|
|
|
|
|
std = mlirContextGetOrLoadDialect(ctx, mlirStandardDialectGetNamespace());
|
|
|
|
if (mlirDialectIsNull(std))
|
2020-12-12 06:20:03 +08:00
|
|
|
return 3;
|
2020-09-29 22:23:02 +08:00
|
|
|
|
|
|
|
MlirDialect alsoStd = mlirContextLoadStandardDialect(ctx);
|
|
|
|
if (!mlirDialectEqual(std, alsoStd))
|
2020-12-12 06:20:03 +08:00
|
|
|
return 4;
|
2020-09-29 22:23:02 +08:00
|
|
|
|
|
|
|
MlirStringRef stdNs = mlirDialectGetNamespace(std);
|
|
|
|
MlirStringRef alsoStdNs = mlirStandardDialectGetNamespace();
|
|
|
|
if (stdNs.length != alsoStdNs.length ||
|
|
|
|
strncmp(stdNs.data, alsoStdNs.data, stdNs.length))
|
2020-12-12 06:20:03 +08:00
|
|
|
return 5;
|
2020-09-29 22:23:02 +08:00
|
|
|
|
2020-11-04 17:30:00 +08:00
|
|
|
fprintf(stderr, "@registration\n");
|
|
|
|
// CHECK-LABEL: @registration
|
|
|
|
|
2020-09-29 22:23:02 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-02-09 11:54:19 +08:00
|
|
|
/// Tests backreference APIs
|
|
|
|
static int testBackreferences() {
|
|
|
|
fprintf(stderr, "@test_backreferences\n");
|
|
|
|
|
|
|
|
MlirContext ctx = mlirContextCreate();
|
|
|
|
mlirContextSetAllowUnregisteredDialects(ctx, true);
|
|
|
|
MlirLocation loc = mlirLocationUnknownGet(ctx);
|
|
|
|
|
|
|
|
MlirOperationState opState = mlirOperationStateGet(mlirStringRefCreateFromCString("invalid.op"), loc);
|
|
|
|
MlirRegion region = mlirRegionCreate();
|
|
|
|
MlirBlock block = mlirBlockCreate(0, NULL);
|
|
|
|
mlirRegionAppendOwnedBlock(region, block);
|
|
|
|
mlirOperationStateAddOwnedRegions(&opState, 1, ®ion);
|
|
|
|
MlirOperation op = mlirOperationCreate(&opState);
|
|
|
|
|
|
|
|
if (!mlirContextEqual(ctx, mlirOperationGetContext(op))) {
|
|
|
|
fprintf(stderr, "ERROR: Getting context from operation failed\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (!mlirOperationEqual(op, mlirBlockGetParentOperation(block))) {
|
|
|
|
fprintf(stderr, "ERROR: Getting parent operation from block failed\n");
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
mlirOperationDestroy(op);
|
|
|
|
mlirContextDestroy(ctx);
|
|
|
|
|
|
|
|
// CHECK-LABEL: @test_backreferences
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-10-07 20:38:10 +08:00
|
|
|
// Wraps a diagnostic into additional text we can match against.
|
2020-11-24 01:52:17 +08:00
|
|
|
MlirLogicalResult errorHandler(MlirDiagnostic diagnostic, void *userData) {
|
2020-12-04 05:08:57 +08:00
|
|
|
fprintf(stderr, "processing diagnostic (userData: %ld) <<\n", (long)userData);
|
2020-10-07 20:38:10 +08:00
|
|
|
mlirDiagnosticPrint(diagnostic, printToStderr, NULL);
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
MlirLocation loc = mlirDiagnosticGetLocation(diagnostic);
|
|
|
|
mlirLocationPrint(loc, printToStderr, NULL);
|
|
|
|
assert(mlirDiagnosticGetNumNotes(diagnostic) == 0);
|
2020-12-18 01:27:17 +08:00
|
|
|
fprintf(stderr, "\n>> end of diagnostic (userData: %ld)\n", (long)userData);
|
2020-10-07 20:38:10 +08:00
|
|
|
return mlirLogicalResultSuccess();
|
|
|
|
}
|
|
|
|
|
2020-11-24 01:52:17 +08:00
|
|
|
// Logs when the delete user data callback is called
|
|
|
|
static void deleteUserData(void *userData) {
|
2020-12-04 05:08:57 +08:00
|
|
|
fprintf(stderr, "deleting user data (userData: %ld)\n", (long)userData);
|
2020-11-24 01:52:17 +08:00
|
|
|
}
|
|
|
|
|
2020-10-07 20:38:10 +08:00
|
|
|
void testDiagnostics() {
|
|
|
|
MlirContext ctx = mlirContextCreate();
|
2020-11-24 01:52:17 +08:00
|
|
|
MlirDiagnosticHandlerID id = mlirContextAttachDiagnosticHandler(
|
|
|
|
ctx, errorHandler, (void *)42, deleteUserData);
|
2020-11-04 17:30:00 +08:00
|
|
|
fprintf(stderr, "@test_diagnostics\n");
|
2020-12-18 01:27:17 +08:00
|
|
|
MlirLocation unknownLoc = mlirLocationUnknownGet(ctx);
|
|
|
|
mlirEmitError(unknownLoc, "test diagnostics");
|
|
|
|
MlirLocation fileLineColLoc = mlirLocationFileLineColGet(
|
|
|
|
ctx, mlirStringRefCreateFromCString("file.c"), 1, 2);
|
|
|
|
mlirEmitError(fileLineColLoc, "test diagnostics");
|
|
|
|
MlirLocation callSiteLoc = mlirLocationCallSiteGet(
|
|
|
|
mlirLocationFileLineColGet(
|
|
|
|
ctx, mlirStringRefCreateFromCString("other-file.c"), 2, 3),
|
|
|
|
fileLineColLoc);
|
|
|
|
mlirEmitError(callSiteLoc, "test diagnostics");
|
2020-10-07 20:38:10 +08:00
|
|
|
mlirContextDetachDiagnosticHandler(ctx, id);
|
2020-12-18 01:27:17 +08:00
|
|
|
mlirEmitError(unknownLoc, "more test diagnostics");
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK-LABEL: @test_diagnostics
|
2020-11-24 01:52:17 +08:00
|
|
|
// CHECK: processing diagnostic (userData: 42) <<
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK: test diagnostics
|
|
|
|
// CHECK: loc(unknown)
|
2020-11-24 01:52:17 +08:00
|
|
|
// CHECK: >> end of diagnostic (userData: 42)
|
2020-12-18 01:27:17 +08:00
|
|
|
// CHECK: processing diagnostic (userData: 42) <<
|
|
|
|
// CHECK: test diagnostics
|
|
|
|
// CHECK: loc("file.c":1:2)
|
|
|
|
// CHECK: >> end of diagnostic (userData: 42)
|
|
|
|
// CHECK: processing diagnostic (userData: 42) <<
|
|
|
|
// CHECK: test diagnostics
|
|
|
|
// CHECK: loc(callsite("other-file.c":2:3 at "file.c":1:2))
|
|
|
|
// CHECK: >> end of diagnostic (userData: 42)
|
2020-11-24 01:52:17 +08:00
|
|
|
// CHECK: deleting user data (userData: 42)
|
2020-11-04 17:30:00 +08:00
|
|
|
// CHECK-NOT: processing diagnostic
|
|
|
|
// CHECK: more test diagnostics
|
2020-10-07 20:38:10 +08:00
|
|
|
}
|
|
|
|
|
2020-08-05 20:36:16 +08:00
|
|
|
int main() {
|
|
|
|
MlirContext ctx = mlirContextCreate();
|
Separate the Registration from Loading dialects in the Context
This changes the behavior of constructing MLIRContext to no longer load globally
registered dialects on construction. Instead Dialects are only loaded explicitly
on demand:
- the Parser is lazily loading Dialects in the context as it encounters them
during parsing. This is the only purpose for registering dialects and not load
them in the context.
- Passes are expected to declare the dialects they will create entity from
(Operations, Attributes, or Types), and the PassManager is loading Dialects into
the Context when starting a pipeline.
This changes simplifies the configuration of the registration: a compiler only
need to load the dialect for the IR it will emit, and the optimizer is
self-contained and load the required Dialects. For example in the Toy tutorial,
the compiler only needs to load the Toy dialect in the Context, all the others
(linalg, affine, std, LLVM, ...) are automatically loaded depending on the
optimization pipeline enabled.
To adjust to this change, stop using the existing dialect registration: the
global registry will be removed soon.
1) For passes, you need to override the method:
virtual void getDependentDialects(DialectRegistry ®istry) const {}
and registery on the provided registry any dialect that this pass can produce.
Passes defined in TableGen can provide this list in the dependentDialects list
field.
2) For dialects, on construction you can register dependent dialects using the
provided MLIRContext: `context.getOrLoadDialect<DialectName>()`
This is useful if a dialect may canonicalize or have interfaces involving
another dialect.
3) For loading IR, dialect that can be in the input file must be explicitly
registered with the context. `MlirOptMain()` is taking an explicit registry for
this purpose. See how the standalone-opt.cpp example is setup:
mlir::DialectRegistry registry;
registry.insert<mlir::standalone::StandaloneDialect>();
registry.insert<mlir::StandardOpsDialect>();
Only operations from these two dialects can be in the input file. To include all
of the dialects in MLIR Core, you can populate the registry this way:
mlir::registerAllDialects(registry);
4) For `mlir-translate` callback, as well as frontend, Dialects can be loaded in
the context before emitting the IR: context.getOrLoadDialect<ToyDialect>()
Differential Revision: https://reviews.llvm.org/D85622
2020-08-19 04:01:19 +08:00
|
|
|
mlirRegisterAllDialects(ctx);
|
2020-11-04 17:30:00 +08:00
|
|
|
if (constructAndTraverseIr(ctx))
|
|
|
|
return 1;
|
2020-09-23 21:02:47 +08:00
|
|
|
buildWithInsertionsAndPrint(ctx);
|
2021-01-23 10:43:50 +08:00
|
|
|
if (createOperationWithTypeInference(ctx))
|
|
|
|
return 2;
|
2020-09-23 21:02:47 +08:00
|
|
|
|
2020-12-04 09:22:29 +08:00
|
|
|
if (printBuiltinTypes(ctx))
|
2020-11-04 17:30:00 +08:00
|
|
|
return 3;
|
2021-01-23 10:43:50 +08:00
|
|
|
if (printBuiltinAttributes(ctx))
|
2020-11-04 17:30:00 +08:00
|
|
|
return 4;
|
2021-01-23 10:43:50 +08:00
|
|
|
if (printAffineMap(ctx))
|
2020-11-04 17:30:00 +08:00
|
|
|
return 5;
|
2021-01-23 10:43:50 +08:00
|
|
|
if (printAffineExpr(ctx))
|
2020-11-04 17:30:00 +08:00
|
|
|
return 6;
|
2021-01-23 10:43:50 +08:00
|
|
|
if (affineMapFromExprs(ctx))
|
2021-01-08 20:36:27 +08:00
|
|
|
return 7;
|
2021-01-26 00:12:35 +08:00
|
|
|
if (printIntegerSet(ctx))
|
2021-01-23 10:43:50 +08:00
|
|
|
return 8;
|
2021-01-26 00:12:35 +08:00
|
|
|
if (registerOnlyStd())
|
|
|
|
return 9;
|
2021-02-09 11:54:19 +08:00
|
|
|
if (testBackreferences())
|
|
|
|
return 10;
|
2020-09-29 22:23:02 +08:00
|
|
|
|
2020-08-05 20:36:16 +08:00
|
|
|
mlirContextDestroy(ctx);
|
|
|
|
|
2020-10-07 20:38:10 +08:00
|
|
|
testDiagnostics();
|
2020-08-05 20:36:16 +08:00
|
|
|
return 0;
|
|
|
|
}
|