[Mlir-commits] [mlir] [mlir][openacc] Restore unit tests for device_type functions (PR #77122)
Valentin Clement バレンタイン クレメン
llvmlistbot at llvm.org
Fri Jan 5 10:10:25 PST 2024
https://github.com/clementval created https://github.com/llvm/llvm-project/pull/77122
These tests were initially pushed together with https://github.com/llvm/llvm-project/pull/75864 but they were triggering some buildbot failure (sanitizers). They now make use of the `OwningOpRef` so all the resources are correctly destroyed at the end of each tests.
They will be extended to includes all the extra getter functions added with device_type support.
>From d3efffee795626eb21317ce229ab7f7e708776e4 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Thu, 7 Dec 2023 14:04:54 -0800
Subject: [PATCH] [mlir][openacc] Restore unit tests for device_type functions
---
mlir/unittests/Dialect/CMakeLists.txt | 1 +
mlir/unittests/Dialect/OpenACC/CMakeLists.txt | 8 +
.../Dialect/OpenACC/OpenACCOpsTest.cpp | 349 ++++++++++++++++++
3 files changed, 358 insertions(+)
create mode 100644 mlir/unittests/Dialect/OpenACC/CMakeLists.txt
create mode 100644 mlir/unittests/Dialect/OpenACC/OpenACCOpsTest.cpp
diff --git a/mlir/unittests/Dialect/CMakeLists.txt b/mlir/unittests/Dialect/CMakeLists.txt
index 2dec4ba3c001e8..13393569f36fe7 100644
--- a/mlir/unittests/Dialect/CMakeLists.txt
+++ b/mlir/unittests/Dialect/CMakeLists.txt
@@ -10,6 +10,7 @@ add_subdirectory(ArmSME)
add_subdirectory(Index)
add_subdirectory(LLVMIR)
add_subdirectory(MemRef)
+add_subdirectory(OpenACC)
add_subdirectory(SCF)
add_subdirectory(SparseTensor)
add_subdirectory(SPIRV)
diff --git a/mlir/unittests/Dialect/OpenACC/CMakeLists.txt b/mlir/unittests/Dialect/OpenACC/CMakeLists.txt
new file mode 100644
index 00000000000000..5133d7fc38296c
--- /dev/null
+++ b/mlir/unittests/Dialect/OpenACC/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_mlir_unittest(MLIROpenACCTests
+ OpenACCOpsTest.cpp
+)
+target_link_libraries(MLIROpenACCTests
+ PRIVATE
+ MLIRIR
+ MLIROpenACCDialect
+)
diff --git a/mlir/unittests/Dialect/OpenACC/OpenACCOpsTest.cpp b/mlir/unittests/Dialect/OpenACC/OpenACCOpsTest.cpp
new file mode 100644
index 00000000000000..d78d7b0fdf6769
--- /dev/null
+++ b/mlir/unittests/Dialect/OpenACC/OpenACCOpsTest.cpp
@@ -0,0 +1,349 @@
+//===- OpenACCOpsTest.cpp - OpenACC ops extra functiosn Tests -------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/IR/Diagnostics.h"
+#include "mlir/IR/MLIRContext.h"
+#include "mlir/IR/OwningOpRef.h"
+#include "gtest/gtest.h"
+
+using namespace mlir;
+using namespace mlir::acc;
+
+//===----------------------------------------------------------------------===//
+// Test Fixture
+//===----------------------------------------------------------------------===//
+
+class OpenACCOpsTest : public ::testing::Test {
+protected:
+ OpenACCOpsTest() : b(&context), loc(UnknownLoc::get(&context)) {
+ context.loadDialect<acc::OpenACCDialect, arith::ArithDialect>();
+ }
+
+ MLIRContext context;
+ OpBuilder b;
+ Location loc;
+ llvm::SmallVector<DeviceType> dtypes = {
+ DeviceType::None, DeviceType::Star, DeviceType::Multicore,
+ DeviceType::Default, DeviceType::Host, DeviceType::Nvidia,
+ DeviceType::Radeon};
+ llvm::SmallVector<DeviceType> dtypesWithoutNone = {
+ DeviceType::Star, DeviceType::Multicore, DeviceType::Default,
+ DeviceType::Host, DeviceType::Nvidia, DeviceType::Radeon};
+};
+
+template <typename Op>
+void testAsyncOnly(OpBuilder &b, MLIRContext &context, Location loc,
+ llvm::SmallVector<DeviceType> &dtypes) {
+ OwningOpRef<Op> op = b.create<Op>(loc, TypeRange{}, ValueRange{});
+ EXPECT_FALSE(op->hasAsyncOnly());
+ for (auto d : dtypes)
+ EXPECT_FALSE(op->hasAsyncOnly(d));
+
+ auto dtypeNone = DeviceTypeAttr::get(&context, DeviceType::None);
+ op->setAsyncOnlyAttr(b.getArrayAttr({dtypeNone}));
+ EXPECT_TRUE(op->hasAsyncOnly());
+ EXPECT_TRUE(op->hasAsyncOnly(DeviceType::None));
+ op->removeAsyncOnlyAttr();
+
+ auto dtypeHost = DeviceTypeAttr::get(&context, DeviceType::Host);
+ op->setAsyncOnlyAttr(b.getArrayAttr({dtypeHost}));
+ EXPECT_TRUE(op->hasAsyncOnly(DeviceType::Host));
+ EXPECT_FALSE(op->hasAsyncOnly());
+ op->removeAsyncOnlyAttr();
+
+ auto dtypeStar = DeviceTypeAttr::get(&context, DeviceType::Star);
+ op->setAsyncOnlyAttr(b.getArrayAttr({dtypeHost, dtypeStar}));
+ EXPECT_TRUE(op->hasAsyncOnly(DeviceType::Star));
+ EXPECT_TRUE(op->hasAsyncOnly(DeviceType::Host));
+ EXPECT_FALSE(op->hasAsyncOnly());
+
+ op->removeAsyncOnlyAttr();
+}
+
+TEST_F(OpenACCOpsTest, asyncOnlyTest) {
+ testAsyncOnly<ParallelOp>(b, context, loc, dtypes);
+ testAsyncOnly<KernelsOp>(b, context, loc, dtypes);
+ testAsyncOnly<SerialOp>(b, context, loc, dtypes);
+}
+
+template <typename Op>
+void testAsyncValue(OpBuilder &b, MLIRContext &context, Location loc,
+ llvm::SmallVector<DeviceType> &dtypes) {
+ OwningOpRef<Op> op = b.create<Op>(loc, TypeRange{}, ValueRange{});
+
+ mlir::Value empty;
+ EXPECT_EQ(op->getAsyncValue(), empty);
+ for (auto d : dtypes)
+ EXPECT_EQ(op->getAsyncValue(d), empty);
+
+ OwningOpRef<arith::ConstantIndexOp> val =
+ b.create<arith::ConstantIndexOp>(loc, 1);
+ auto dtypeNvidia = DeviceTypeAttr::get(&context, DeviceType::Nvidia);
+ op->setAsyncDeviceTypeAttr(b.getArrayAttr({dtypeNvidia}));
+ op->getAsyncMutable().assign(val->getResult());
+ EXPECT_EQ(op->getAsyncValue(), empty);
+ EXPECT_EQ(op->getAsyncValue(DeviceType::Nvidia), val->getResult());
+
+ op->getAsyncMutable().clear();
+ op->removeAsyncDeviceTypeAttr();
+}
+
+TEST_F(OpenACCOpsTest, asyncValueTest) {
+ testAsyncValue<ParallelOp>(b, context, loc, dtypes);
+ testAsyncValue<KernelsOp>(b, context, loc, dtypes);
+ testAsyncValue<SerialOp>(b, context, loc, dtypes);
+}
+
+template <typename Op>
+void testNumGangsValues(OpBuilder &b, MLIRContext &context, Location loc,
+ llvm::SmallVector<DeviceType> &dtypes,
+ llvm::SmallVector<DeviceType> &dtypesWithoutNone) {
+ OwningOpRef<Op> op = b.create<Op>(loc, TypeRange{}, ValueRange{});
+ EXPECT_EQ(op->getNumGangsValues().begin(), op->getNumGangsValues().end());
+
+ OwningOpRef<arith::ConstantIndexOp> val1 =
+ b.create<arith::ConstantIndexOp>(loc, 1);
+ OwningOpRef<arith::ConstantIndexOp> val2 =
+ b.create<arith::ConstantIndexOp>(loc, 4);
+ auto dtypeNone = DeviceTypeAttr::get(&context, DeviceType::None);
+ op->getNumGangsMutable().assign(val1->getResult());
+ op->setNumGangsDeviceTypeAttr(b.getArrayAttr({dtypeNone}));
+ op->setNumGangsSegments(b.getDenseI32ArrayAttr({1}));
+ EXPECT_EQ(op->getNumGangsValues().front(), val1->getResult());
+ for (auto d : dtypesWithoutNone)
+ EXPECT_EQ(op->getNumGangsValues(d).begin(), op->getNumGangsValues(d).end());
+
+ op->getNumGangsMutable().clear();
+ op->removeNumGangsDeviceTypeAttr();
+ op->removeNumGangsSegmentsAttr();
+ for (auto d : dtypes)
+ EXPECT_EQ(op->getNumGangsValues(d).begin(), op->getNumGangsValues(d).end());
+
+ op->getNumGangsMutable().append(val1->getResult());
+ op->getNumGangsMutable().append(val2->getResult());
+ op->setNumGangsDeviceTypeAttr(
+ b.getArrayAttr({DeviceTypeAttr::get(&context, DeviceType::Host),
+ DeviceTypeAttr::get(&context, DeviceType::Star)}));
+ op->setNumGangsSegments(b.getDenseI32ArrayAttr({1, 1}));
+ EXPECT_EQ(op->getNumGangsValues(DeviceType::None).begin(),
+ op->getNumGangsValues(DeviceType::None).end());
+ EXPECT_EQ(op->getNumGangsValues(DeviceType::Host).front(), val1->getResult());
+ EXPECT_EQ(op->getNumGangsValues(DeviceType::Star).front(), val2->getResult());
+
+ op->getNumGangsMutable().clear();
+ op->removeNumGangsDeviceTypeAttr();
+ op->removeNumGangsSegmentsAttr();
+ for (auto d : dtypes)
+ EXPECT_EQ(op->getNumGangsValues(d).begin(), op->getNumGangsValues(d).end());
+
+ op->getNumGangsMutable().append(val1->getResult());
+ op->getNumGangsMutable().append(val2->getResult());
+ op->getNumGangsMutable().append(val1->getResult());
+ op->setNumGangsDeviceTypeAttr(
+ b.getArrayAttr({DeviceTypeAttr::get(&context, DeviceType::Default),
+ DeviceTypeAttr::get(&context, DeviceType::Multicore)}));
+ op->setNumGangsSegments(b.getDenseI32ArrayAttr({2, 1}));
+ EXPECT_EQ(op->getNumGangsValues(DeviceType::None).begin(),
+ op->getNumGangsValues(DeviceType::None).end());
+ EXPECT_EQ(op->getNumGangsValues(DeviceType::Default).front(),
+ val1->getResult());
+ EXPECT_EQ(op->getNumGangsValues(DeviceType::Default).drop_front().front(),
+ val2->getResult());
+ EXPECT_EQ(op->getNumGangsValues(DeviceType::Multicore).front(),
+ val1->getResult());
+
+ op->getNumGangsMutable().clear();
+ op->removeNumGangsDeviceTypeAttr();
+ op->removeNumGangsSegmentsAttr();
+}
+
+TEST_F(OpenACCOpsTest, numGangsValuesTest) {
+ testNumGangsValues<ParallelOp>(b, context, loc, dtypes, dtypesWithoutNone);
+ testNumGangsValues<KernelsOp>(b, context, loc, dtypes, dtypesWithoutNone);
+}
+
+template <typename Op>
+void testVectorLength(OpBuilder &b, MLIRContext &context, Location loc,
+ llvm::SmallVector<DeviceType> &dtypes) {
+ OwningOpRef<Op> op = b.create<Op>(loc, TypeRange{}, ValueRange{});
+
+ mlir::Value empty;
+ EXPECT_EQ(op->getVectorLengthValue(), empty);
+ for (auto d : dtypes)
+ EXPECT_EQ(op->getVectorLengthValue(d), empty);
+
+ OwningOpRef<arith::ConstantIndexOp> val =
+ b.create<arith::ConstantIndexOp>(loc, 1);
+ auto dtypeNvidia = DeviceTypeAttr::get(&context, DeviceType::Nvidia);
+ op->setVectorLengthDeviceTypeAttr(b.getArrayAttr({dtypeNvidia}));
+ op->getVectorLengthMutable().assign(val->getResult());
+ EXPECT_EQ(op->getVectorLengthValue(), empty);
+ EXPECT_EQ(op->getVectorLengthValue(DeviceType::Nvidia), val->getResult());
+
+ op->getVectorLengthMutable().clear();
+ op->removeVectorLengthDeviceTypeAttr();
+}
+
+TEST_F(OpenACCOpsTest, vectorLengthTest) {
+ testVectorLength<ParallelOp>(b, context, loc, dtypes);
+ testVectorLength<KernelsOp>(b, context, loc, dtypes);
+}
+
+template <typename Op>
+void testWaitOnly(OpBuilder &b, MLIRContext &context, Location loc,
+ llvm::SmallVector<DeviceType> &dtypes,
+ llvm::SmallVector<DeviceType> &dtypesWithoutNone) {
+ OwningOpRef<Op> op = b.create<Op>(loc, TypeRange{}, ValueRange{});
+ EXPECT_FALSE(op->hasWaitOnly());
+ for (auto d : dtypes)
+ EXPECT_FALSE(op->hasWaitOnly(d));
+
+ auto dtypeNone = DeviceTypeAttr::get(&context, DeviceType::None);
+ op->setWaitOnlyAttr(b.getArrayAttr({dtypeNone}));
+ EXPECT_TRUE(op->hasWaitOnly());
+ EXPECT_TRUE(op->hasWaitOnly(DeviceType::None));
+ for (auto d : dtypesWithoutNone)
+ EXPECT_FALSE(op->hasWaitOnly(d));
+ op->removeWaitOnlyAttr();
+
+ auto dtypeHost = DeviceTypeAttr::get(&context, DeviceType::Host);
+ op->setWaitOnlyAttr(b.getArrayAttr({dtypeHost}));
+ EXPECT_TRUE(op->hasWaitOnly(DeviceType::Host));
+ EXPECT_FALSE(op->hasWaitOnly());
+ op->removeWaitOnlyAttr();
+
+ auto dtypeStar = DeviceTypeAttr::get(&context, DeviceType::Star);
+ op->setWaitOnlyAttr(b.getArrayAttr({dtypeHost, dtypeStar}));
+ EXPECT_TRUE(op->hasWaitOnly(DeviceType::Star));
+ EXPECT_TRUE(op->hasWaitOnly(DeviceType::Host));
+ EXPECT_FALSE(op->hasWaitOnly());
+
+ op->removeWaitOnlyAttr();
+}
+
+TEST_F(OpenACCOpsTest, waitOnlyTest) {
+ testWaitOnly<ParallelOp>(b, context, loc, dtypes, dtypesWithoutNone);
+ testWaitOnly<KernelsOp>(b, context, loc, dtypes, dtypesWithoutNone);
+ testWaitOnly<SerialOp>(b, context, loc, dtypes, dtypesWithoutNone);
+}
+
+template <typename Op>
+void testWaitValues(OpBuilder &b, MLIRContext &context, Location loc,
+ llvm::SmallVector<DeviceType> &dtypes,
+ llvm::SmallVector<DeviceType> &dtypesWithoutNone) {
+ OwningOpRef<Op> op = b.create<Op>(loc, TypeRange{}, ValueRange{});
+ EXPECT_EQ(op->getWaitValues().begin(), op->getWaitValues().end());
+
+ OwningOpRef<arith::ConstantIndexOp> val1 =
+ b.create<arith::ConstantIndexOp>(loc, 1);
+ OwningOpRef<arith::ConstantIndexOp> val2 =
+ b.create<arith::ConstantIndexOp>(loc, 4);
+ auto dtypeNone = DeviceTypeAttr::get(&context, DeviceType::None);
+ op->getWaitOperandsMutable().assign(val1->getResult());
+ op->setWaitOperandsDeviceTypeAttr(b.getArrayAttr({dtypeNone}));
+ op->setWaitOperandsSegments(b.getDenseI32ArrayAttr({1}));
+ EXPECT_EQ(op->getWaitValues().front(), val1->getResult());
+ for (auto d : dtypesWithoutNone)
+ EXPECT_EQ(op->getWaitValues(d).begin(), op->getWaitValues(d).end());
+
+ op->getWaitOperandsMutable().clear();
+ op->removeWaitOperandsDeviceTypeAttr();
+ op->removeWaitOperandsSegmentsAttr();
+ for (auto d : dtypes)
+ EXPECT_EQ(op->getWaitValues(d).begin(), op->getWaitValues(d).end());
+
+ op->getWaitOperandsMutable().append(val1->getResult());
+ op->getWaitOperandsMutable().append(val2->getResult());
+ op->setWaitOperandsDeviceTypeAttr(
+ b.getArrayAttr({DeviceTypeAttr::get(&context, DeviceType::Host),
+ DeviceTypeAttr::get(&context, DeviceType::Star)}));
+ op->setWaitOperandsSegments(b.getDenseI32ArrayAttr({1, 1}));
+ EXPECT_EQ(op->getWaitValues(DeviceType::None).begin(),
+ op->getWaitValues(DeviceType::None).end());
+ EXPECT_EQ(op->getWaitValues(DeviceType::Host).front(), val1->getResult());
+ EXPECT_EQ(op->getWaitValues(DeviceType::Star).front(), val2->getResult());
+
+ op->getWaitOperandsMutable().clear();
+ op->removeWaitOperandsDeviceTypeAttr();
+ op->removeWaitOperandsSegmentsAttr();
+ for (auto d : dtypes)
+ EXPECT_EQ(op->getWaitValues(d).begin(), op->getWaitValues(d).end());
+
+ op->getWaitOperandsMutable().append(val1->getResult());
+ op->getWaitOperandsMutable().append(val2->getResult());
+ op->getWaitOperandsMutable().append(val1->getResult());
+ op->setWaitOperandsDeviceTypeAttr(
+ b.getArrayAttr({DeviceTypeAttr::get(&context, DeviceType::Default),
+ DeviceTypeAttr::get(&context, DeviceType::Multicore)}));
+ op->setWaitOperandsSegments(b.getDenseI32ArrayAttr({2, 1}));
+ EXPECT_EQ(op->getWaitValues(DeviceType::None).begin(),
+ op->getWaitValues(DeviceType::None).end());
+ EXPECT_EQ(op->getWaitValues(DeviceType::Default).front(), val1->getResult());
+ EXPECT_EQ(op->getWaitValues(DeviceType::Default).drop_front().front(),
+ val2->getResult());
+ EXPECT_EQ(op->getWaitValues(DeviceType::Multicore).front(),
+ val1->getResult());
+
+ op->getWaitOperandsMutable().clear();
+ op->removeWaitOperandsDeviceTypeAttr();
+ op->removeWaitOperandsSegmentsAttr();
+}
+
+TEST_F(OpenACCOpsTest, waitValuesTest) {
+ testWaitValues<KernelsOp>(b, context, loc, dtypes, dtypesWithoutNone);
+ testWaitValues<ParallelOp>(b, context, loc, dtypes, dtypesWithoutNone);
+ testWaitValues<SerialOp>(b, context, loc, dtypes, dtypesWithoutNone);
+}
+
+TEST_F(OpenACCOpsTest, loopOpGangVectorWorkerTest) {
+ OwningOpRef<LoopOp> op = b.create<LoopOp>(loc, TypeRange{}, ValueRange{});
+ EXPECT_FALSE(op->hasGang());
+ EXPECT_FALSE(op->hasVector());
+ EXPECT_FALSE(op->hasWorker());
+ for (auto d : dtypes) {
+ EXPECT_FALSE(op->hasGang(d));
+ EXPECT_FALSE(op->hasVector(d));
+ EXPECT_FALSE(op->hasWorker(d));
+ }
+
+ auto dtypeNone = DeviceTypeAttr::get(&context, DeviceType::None);
+ op->setGangAttr(b.getArrayAttr({dtypeNone}));
+ EXPECT_TRUE(op->hasGang());
+ EXPECT_TRUE(op->hasGang(DeviceType::None));
+ for (auto d : dtypesWithoutNone)
+ EXPECT_FALSE(op->hasGang(d));
+ for (auto d : dtypes) {
+ EXPECT_FALSE(op->hasVector(d));
+ EXPECT_FALSE(op->hasWorker(d));
+ }
+ op->removeGangAttr();
+
+ op->setWorkerAttr(b.getArrayAttr({dtypeNone}));
+ EXPECT_TRUE(op->hasWorker());
+ EXPECT_TRUE(op->hasWorker(DeviceType::None));
+ for (auto d : dtypesWithoutNone)
+ EXPECT_FALSE(op->hasWorker(d));
+ for (auto d : dtypes) {
+ EXPECT_FALSE(op->hasGang(d));
+ EXPECT_FALSE(op->hasVector(d));
+ }
+ op->removeWorkerAttr();
+
+ op->setVectorAttr(b.getArrayAttr({dtypeNone}));
+ EXPECT_TRUE(op->hasVector());
+ EXPECT_TRUE(op->hasVector(DeviceType::None));
+ for (auto d : dtypesWithoutNone)
+ EXPECT_FALSE(op->hasVector(d));
+ for (auto d : dtypes) {
+ EXPECT_FALSE(op->hasGang(d));
+ EXPECT_FALSE(op->hasWorker(d));
+ }
+ op->removeVectorAttr();
+}
More information about the Mlir-commits
mailing list