[mlir] Update Ch-2.md (#121379)
[llvm-project.git] / mlir / unittests / Dialect / OpenACC / OpenACCOpsTest.cpp
blobfbdada9309d32c6ac3d20f93a7b3233a9e3e7777
1 //===- OpenACCOpsTest.cpp - Unit tests for OpenACC ops --------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "mlir/Dialect/Arith/IR/Arith.h"
10 #include "mlir/Dialect/MemRef/IR/MemRef.h"
11 #include "mlir/Dialect/OpenACC/OpenACC.h"
12 #include "mlir/IR/Diagnostics.h"
13 #include "mlir/IR/MLIRContext.h"
14 #include "mlir/IR/OwningOpRef.h"
15 #include "gtest/gtest.h"
17 using namespace mlir;
18 using namespace mlir::acc;
20 //===----------------------------------------------------------------------===//
21 // Test Fixture
22 //===----------------------------------------------------------------------===//
24 class OpenACCOpsTest : public ::testing::Test {
25 protected:
26 OpenACCOpsTest() : b(&context), loc(UnknownLoc::get(&context)) {
27 context.loadDialect<acc::OpenACCDialect, arith::ArithDialect,
28 memref::MemRefDialect>();
31 MLIRContext context;
32 OpBuilder b;
33 Location loc;
34 llvm::SmallVector<DeviceType> dtypes = {
35 DeviceType::None, DeviceType::Star, DeviceType::Multicore,
36 DeviceType::Default, DeviceType::Host, DeviceType::Nvidia,
37 DeviceType::Radeon};
38 llvm::SmallVector<DeviceType> dtypesWithoutNone = {
39 DeviceType::Star, DeviceType::Multicore, DeviceType::Default,
40 DeviceType::Host, DeviceType::Nvidia, DeviceType::Radeon};
43 template <typename Op>
44 void testAsyncOnly(OpBuilder &b, MLIRContext &context, Location loc,
45 llvm::SmallVector<DeviceType> &dtypes) {
46 OwningOpRef<Op> op = b.create<Op>(loc, TypeRange{}, ValueRange{});
47 EXPECT_FALSE(op->hasAsyncOnly());
48 for (auto d : dtypes)
49 EXPECT_FALSE(op->hasAsyncOnly(d));
51 auto dtypeNone = DeviceTypeAttr::get(&context, DeviceType::None);
52 op->setAsyncOnlyAttr(b.getArrayAttr({dtypeNone}));
53 EXPECT_TRUE(op->hasAsyncOnly());
54 EXPECT_TRUE(op->hasAsyncOnly(DeviceType::None));
55 op->removeAsyncOnlyAttr();
57 auto dtypeHost = DeviceTypeAttr::get(&context, DeviceType::Host);
58 op->setAsyncOnlyAttr(b.getArrayAttr({dtypeHost}));
59 EXPECT_TRUE(op->hasAsyncOnly(DeviceType::Host));
60 EXPECT_FALSE(op->hasAsyncOnly());
61 op->removeAsyncOnlyAttr();
63 auto dtypeStar = DeviceTypeAttr::get(&context, DeviceType::Star);
64 op->setAsyncOnlyAttr(b.getArrayAttr({dtypeHost, dtypeStar}));
65 EXPECT_TRUE(op->hasAsyncOnly(DeviceType::Star));
66 EXPECT_TRUE(op->hasAsyncOnly(DeviceType::Host));
67 EXPECT_FALSE(op->hasAsyncOnly());
69 op->removeAsyncOnlyAttr();
72 TEST_F(OpenACCOpsTest, asyncOnlyTest) {
73 testAsyncOnly<ParallelOp>(b, context, loc, dtypes);
74 testAsyncOnly<KernelsOp>(b, context, loc, dtypes);
75 testAsyncOnly<SerialOp>(b, context, loc, dtypes);
78 template <typename Op>
79 void testAsyncValue(OpBuilder &b, MLIRContext &context, Location loc,
80 llvm::SmallVector<DeviceType> &dtypes) {
81 OwningOpRef<Op> op = b.create<Op>(loc, TypeRange{}, ValueRange{});
83 mlir::Value empty;
84 EXPECT_EQ(op->getAsyncValue(), empty);
85 for (auto d : dtypes)
86 EXPECT_EQ(op->getAsyncValue(d), empty);
88 OwningOpRef<arith::ConstantIndexOp> val =
89 b.create<arith::ConstantIndexOp>(loc, 1);
90 auto dtypeNvidia = DeviceTypeAttr::get(&context, DeviceType::Nvidia);
91 op->setAsyncOperandsDeviceTypeAttr(b.getArrayAttr({dtypeNvidia}));
92 op->getAsyncOperandsMutable().assign(val->getResult());
93 EXPECT_EQ(op->getAsyncValue(), empty);
94 EXPECT_EQ(op->getAsyncValue(DeviceType::Nvidia), val->getResult());
96 op->getAsyncOperandsMutable().clear();
97 op->removeAsyncOperandsDeviceTypeAttr();
100 TEST_F(OpenACCOpsTest, asyncValueTest) {
101 testAsyncValue<ParallelOp>(b, context, loc, dtypes);
102 testAsyncValue<KernelsOp>(b, context, loc, dtypes);
103 testAsyncValue<SerialOp>(b, context, loc, dtypes);
106 template <typename Op>
107 void testNumGangsValues(OpBuilder &b, MLIRContext &context, Location loc,
108 llvm::SmallVector<DeviceType> &dtypes,
109 llvm::SmallVector<DeviceType> &dtypesWithoutNone) {
110 OwningOpRef<Op> op = b.create<Op>(loc, TypeRange{}, ValueRange{});
111 EXPECT_EQ(op->getNumGangsValues().begin(), op->getNumGangsValues().end());
113 OwningOpRef<arith::ConstantIndexOp> val1 =
114 b.create<arith::ConstantIndexOp>(loc, 1);
115 OwningOpRef<arith::ConstantIndexOp> val2 =
116 b.create<arith::ConstantIndexOp>(loc, 4);
117 auto dtypeNone = DeviceTypeAttr::get(&context, DeviceType::None);
118 op->getNumGangsMutable().assign(val1->getResult());
119 op->setNumGangsDeviceTypeAttr(b.getArrayAttr({dtypeNone}));
120 op->setNumGangsSegments(b.getDenseI32ArrayAttr({1}));
121 EXPECT_EQ(op->getNumGangsValues().front(), val1->getResult());
122 for (auto d : dtypesWithoutNone)
123 EXPECT_EQ(op->getNumGangsValues(d).begin(), op->getNumGangsValues(d).end());
125 op->getNumGangsMutable().clear();
126 op->removeNumGangsDeviceTypeAttr();
127 op->removeNumGangsSegmentsAttr();
128 for (auto d : dtypes)
129 EXPECT_EQ(op->getNumGangsValues(d).begin(), op->getNumGangsValues(d).end());
131 op->getNumGangsMutable().append(val1->getResult());
132 op->getNumGangsMutable().append(val2->getResult());
133 op->setNumGangsDeviceTypeAttr(
134 b.getArrayAttr({DeviceTypeAttr::get(&context, DeviceType::Host),
135 DeviceTypeAttr::get(&context, DeviceType::Star)}));
136 op->setNumGangsSegments(b.getDenseI32ArrayAttr({1, 1}));
137 EXPECT_EQ(op->getNumGangsValues(DeviceType::None).begin(),
138 op->getNumGangsValues(DeviceType::None).end());
139 EXPECT_EQ(op->getNumGangsValues(DeviceType::Host).front(), val1->getResult());
140 EXPECT_EQ(op->getNumGangsValues(DeviceType::Star).front(), val2->getResult());
142 op->getNumGangsMutable().clear();
143 op->removeNumGangsDeviceTypeAttr();
144 op->removeNumGangsSegmentsAttr();
145 for (auto d : dtypes)
146 EXPECT_EQ(op->getNumGangsValues(d).begin(), op->getNumGangsValues(d).end());
148 op->getNumGangsMutable().append(val1->getResult());
149 op->getNumGangsMutable().append(val2->getResult());
150 op->getNumGangsMutable().append(val1->getResult());
151 op->setNumGangsDeviceTypeAttr(
152 b.getArrayAttr({DeviceTypeAttr::get(&context, DeviceType::Default),
153 DeviceTypeAttr::get(&context, DeviceType::Multicore)}));
154 op->setNumGangsSegments(b.getDenseI32ArrayAttr({2, 1}));
155 EXPECT_EQ(op->getNumGangsValues(DeviceType::None).begin(),
156 op->getNumGangsValues(DeviceType::None).end());
157 EXPECT_EQ(op->getNumGangsValues(DeviceType::Default).front(),
158 val1->getResult());
159 EXPECT_EQ(op->getNumGangsValues(DeviceType::Default).drop_front().front(),
160 val2->getResult());
161 EXPECT_EQ(op->getNumGangsValues(DeviceType::Multicore).front(),
162 val1->getResult());
164 op->getNumGangsMutable().clear();
165 op->removeNumGangsDeviceTypeAttr();
166 op->removeNumGangsSegmentsAttr();
169 TEST_F(OpenACCOpsTest, numGangsValuesTest) {
170 testNumGangsValues<ParallelOp>(b, context, loc, dtypes, dtypesWithoutNone);
171 testNumGangsValues<KernelsOp>(b, context, loc, dtypes, dtypesWithoutNone);
174 template <typename Op>
175 void testVectorLength(OpBuilder &b, MLIRContext &context, Location loc,
176 llvm::SmallVector<DeviceType> &dtypes) {
177 OwningOpRef<Op> op = b.create<Op>(loc, TypeRange{}, ValueRange{});
179 mlir::Value empty;
180 EXPECT_EQ(op->getVectorLengthValue(), empty);
181 for (auto d : dtypes)
182 EXPECT_EQ(op->getVectorLengthValue(d), empty);
184 OwningOpRef<arith::ConstantIndexOp> val =
185 b.create<arith::ConstantIndexOp>(loc, 1);
186 auto dtypeNvidia = DeviceTypeAttr::get(&context, DeviceType::Nvidia);
187 op->setVectorLengthDeviceTypeAttr(b.getArrayAttr({dtypeNvidia}));
188 op->getVectorLengthMutable().assign(val->getResult());
189 EXPECT_EQ(op->getVectorLengthValue(), empty);
190 EXPECT_EQ(op->getVectorLengthValue(DeviceType::Nvidia), val->getResult());
192 op->getVectorLengthMutable().clear();
193 op->removeVectorLengthDeviceTypeAttr();
196 TEST_F(OpenACCOpsTest, vectorLengthTest) {
197 testVectorLength<ParallelOp>(b, context, loc, dtypes);
198 testVectorLength<KernelsOp>(b, context, loc, dtypes);
201 template <typename Op>
202 void testWaitOnly(OpBuilder &b, MLIRContext &context, Location loc,
203 llvm::SmallVector<DeviceType> &dtypes,
204 llvm::SmallVector<DeviceType> &dtypesWithoutNone) {
205 OwningOpRef<Op> op = b.create<Op>(loc, TypeRange{}, ValueRange{});
206 EXPECT_FALSE(op->hasWaitOnly());
207 for (auto d : dtypes)
208 EXPECT_FALSE(op->hasWaitOnly(d));
210 auto dtypeNone = DeviceTypeAttr::get(&context, DeviceType::None);
211 op->setWaitOnlyAttr(b.getArrayAttr({dtypeNone}));
212 EXPECT_TRUE(op->hasWaitOnly());
213 EXPECT_TRUE(op->hasWaitOnly(DeviceType::None));
214 for (auto d : dtypesWithoutNone)
215 EXPECT_FALSE(op->hasWaitOnly(d));
216 op->removeWaitOnlyAttr();
218 auto dtypeHost = DeviceTypeAttr::get(&context, DeviceType::Host);
219 op->setWaitOnlyAttr(b.getArrayAttr({dtypeHost}));
220 EXPECT_TRUE(op->hasWaitOnly(DeviceType::Host));
221 EXPECT_FALSE(op->hasWaitOnly());
222 op->removeWaitOnlyAttr();
224 auto dtypeStar = DeviceTypeAttr::get(&context, DeviceType::Star);
225 op->setWaitOnlyAttr(b.getArrayAttr({dtypeHost, dtypeStar}));
226 EXPECT_TRUE(op->hasWaitOnly(DeviceType::Star));
227 EXPECT_TRUE(op->hasWaitOnly(DeviceType::Host));
228 EXPECT_FALSE(op->hasWaitOnly());
230 op->removeWaitOnlyAttr();
233 TEST_F(OpenACCOpsTest, waitOnlyTest) {
234 testWaitOnly<ParallelOp>(b, context, loc, dtypes, dtypesWithoutNone);
235 testWaitOnly<KernelsOp>(b, context, loc, dtypes, dtypesWithoutNone);
236 testWaitOnly<SerialOp>(b, context, loc, dtypes, dtypesWithoutNone);
237 testWaitOnly<UpdateOp>(b, context, loc, dtypes, dtypesWithoutNone);
238 testWaitOnly<DataOp>(b, context, loc, dtypes, dtypesWithoutNone);
241 template <typename Op>
242 void testWaitValues(OpBuilder &b, MLIRContext &context, Location loc,
243 llvm::SmallVector<DeviceType> &dtypes,
244 llvm::SmallVector<DeviceType> &dtypesWithoutNone) {
245 OwningOpRef<Op> op = b.create<Op>(loc, TypeRange{}, ValueRange{});
246 EXPECT_EQ(op->getWaitValues().begin(), op->getWaitValues().end());
248 OwningOpRef<arith::ConstantIndexOp> val1 =
249 b.create<arith::ConstantIndexOp>(loc, 1);
250 OwningOpRef<arith::ConstantIndexOp> val2 =
251 b.create<arith::ConstantIndexOp>(loc, 4);
252 OwningOpRef<arith::ConstantIndexOp> val3 =
253 b.create<arith::ConstantIndexOp>(loc, 5);
254 auto dtypeNone = DeviceTypeAttr::get(&context, DeviceType::None);
255 op->getWaitOperandsMutable().assign(val1->getResult());
256 op->setWaitOperandsDeviceTypeAttr(b.getArrayAttr({dtypeNone}));
257 op->setWaitOperandsSegments(b.getDenseI32ArrayAttr({1}));
258 op->setHasWaitDevnumAttr(b.getBoolArrayAttr({false}));
259 EXPECT_EQ(op->getWaitValues().front(), val1->getResult());
260 for (auto d : dtypesWithoutNone)
261 EXPECT_TRUE(op->getWaitValues(d).empty());
263 op->getWaitOperandsMutable().clear();
264 op->removeWaitOperandsDeviceTypeAttr();
265 op->removeWaitOperandsSegmentsAttr();
266 op->removeHasWaitDevnumAttr();
267 for (auto d : dtypes)
268 EXPECT_TRUE(op->getWaitValues(d).empty());
270 op->getWaitOperandsMutable().append(val1->getResult());
271 op->getWaitOperandsMutable().append(val2->getResult());
272 op->setWaitOperandsDeviceTypeAttr(
273 b.getArrayAttr({DeviceTypeAttr::get(&context, DeviceType::Host),
274 DeviceTypeAttr::get(&context, DeviceType::Star)}));
275 op->setWaitOperandsSegments(b.getDenseI32ArrayAttr({1, 1}));
276 op->setHasWaitDevnumAttr(b.getBoolArrayAttr({false, false}));
277 EXPECT_EQ(op->getWaitValues(DeviceType::None).begin(),
278 op->getWaitValues(DeviceType::None).end());
279 EXPECT_EQ(op->getWaitValues(DeviceType::Host).front(), val1->getResult());
280 EXPECT_EQ(op->getWaitValues(DeviceType::Star).front(), val2->getResult());
282 op->getWaitOperandsMutable().clear();
283 op->removeWaitOperandsDeviceTypeAttr();
284 op->removeWaitOperandsSegmentsAttr();
285 op->removeHasWaitDevnumAttr();
286 for (auto d : dtypes)
287 EXPECT_TRUE(op->getWaitValues(d).empty());
289 op->getWaitOperandsMutable().append(val1->getResult());
290 op->getWaitOperandsMutable().append(val2->getResult());
291 op->getWaitOperandsMutable().append(val1->getResult());
292 op->setWaitOperandsDeviceTypeAttr(
293 b.getArrayAttr({DeviceTypeAttr::get(&context, DeviceType::Default),
294 DeviceTypeAttr::get(&context, DeviceType::Multicore)}));
295 op->setWaitOperandsSegments(b.getDenseI32ArrayAttr({2, 1}));
296 op->setHasWaitDevnumAttr(b.getBoolArrayAttr({false, false}));
297 EXPECT_EQ(op->getWaitValues(DeviceType::None).begin(),
298 op->getWaitValues(DeviceType::None).end());
299 EXPECT_EQ(op->getWaitValues(DeviceType::Default).front(), val1->getResult());
300 EXPECT_EQ(op->getWaitValues(DeviceType::Default).drop_front().front(),
301 val2->getResult());
302 EXPECT_EQ(op->getWaitValues(DeviceType::Multicore).front(),
303 val1->getResult());
305 op->getWaitOperandsMutable().clear();
306 op->removeWaitOperandsDeviceTypeAttr();
307 op->removeWaitOperandsSegmentsAttr();
309 op->getWaitOperandsMutable().append(val3->getResult());
310 op->getWaitOperandsMutable().append(val2->getResult());
311 op->getWaitOperandsMutable().append(val1->getResult());
312 op->setWaitOperandsDeviceTypeAttr(
313 b.getArrayAttr({DeviceTypeAttr::get(&context, DeviceType::Multicore)}));
314 op->setHasWaitDevnumAttr(b.getBoolArrayAttr({true}));
315 op->setWaitOperandsSegments(b.getDenseI32ArrayAttr({3}));
316 EXPECT_EQ(op->getWaitValues(DeviceType::None).begin(),
317 op->getWaitValues(DeviceType::None).end());
318 EXPECT_FALSE(op->getWaitDevnum());
320 EXPECT_EQ(op->getWaitDevnum(DeviceType::Multicore), val3->getResult());
321 EXPECT_EQ(op->getWaitValues(DeviceType::Multicore).front(),
322 val2->getResult());
323 EXPECT_EQ(op->getWaitValues(DeviceType::Multicore).drop_front().front(),
324 val1->getResult());
326 op->getWaitOperandsMutable().clear();
327 op->removeWaitOperandsDeviceTypeAttr();
328 op->removeWaitOperandsSegmentsAttr();
329 op->removeHasWaitDevnumAttr();
332 TEST_F(OpenACCOpsTest, waitValuesTest) {
333 testWaitValues<KernelsOp>(b, context, loc, dtypes, dtypesWithoutNone);
334 testWaitValues<ParallelOp>(b, context, loc, dtypes, dtypesWithoutNone);
335 testWaitValues<SerialOp>(b, context, loc, dtypes, dtypesWithoutNone);
338 TEST_F(OpenACCOpsTest, loopOpGangVectorWorkerTest) {
339 OwningOpRef<LoopOp> op = b.create<LoopOp>(loc, TypeRange{}, ValueRange{});
340 EXPECT_FALSE(op->hasGang());
341 EXPECT_FALSE(op->hasVector());
342 EXPECT_FALSE(op->hasWorker());
343 for (auto d : dtypes) {
344 EXPECT_FALSE(op->hasGang(d));
345 EXPECT_FALSE(op->hasVector(d));
346 EXPECT_FALSE(op->hasWorker(d));
349 auto dtypeNone = DeviceTypeAttr::get(&context, DeviceType::None);
350 op->setGangAttr(b.getArrayAttr({dtypeNone}));
351 EXPECT_TRUE(op->hasGang());
352 EXPECT_TRUE(op->hasGang(DeviceType::None));
353 for (auto d : dtypesWithoutNone)
354 EXPECT_FALSE(op->hasGang(d));
355 for (auto d : dtypes) {
356 EXPECT_FALSE(op->hasVector(d));
357 EXPECT_FALSE(op->hasWorker(d));
359 op->removeGangAttr();
361 op->setWorkerAttr(b.getArrayAttr({dtypeNone}));
362 EXPECT_TRUE(op->hasWorker());
363 EXPECT_TRUE(op->hasWorker(DeviceType::None));
364 for (auto d : dtypesWithoutNone)
365 EXPECT_FALSE(op->hasWorker(d));
366 for (auto d : dtypes) {
367 EXPECT_FALSE(op->hasGang(d));
368 EXPECT_FALSE(op->hasVector(d));
370 op->removeWorkerAttr();
372 op->setVectorAttr(b.getArrayAttr({dtypeNone}));
373 EXPECT_TRUE(op->hasVector());
374 EXPECT_TRUE(op->hasVector(DeviceType::None));
375 for (auto d : dtypesWithoutNone)
376 EXPECT_FALSE(op->hasVector(d));
377 for (auto d : dtypes) {
378 EXPECT_FALSE(op->hasGang(d));
379 EXPECT_FALSE(op->hasWorker(d));
381 op->removeVectorAttr();
384 TEST_F(OpenACCOpsTest, routineOpTest) {
385 OwningOpRef<RoutineOp> op =
386 b.create<RoutineOp>(loc, TypeRange{}, ValueRange{});
388 EXPECT_FALSE(op->hasSeq());
389 EXPECT_FALSE(op->hasVector());
390 EXPECT_FALSE(op->hasWorker());
392 for (auto d : dtypes) {
393 EXPECT_FALSE(op->hasSeq(d));
394 EXPECT_FALSE(op->hasVector(d));
395 EXPECT_FALSE(op->hasWorker(d));
398 auto dtypeNone = DeviceTypeAttr::get(&context, DeviceType::None);
399 op->setSeqAttr(b.getArrayAttr({dtypeNone}));
400 EXPECT_TRUE(op->hasSeq());
401 for (auto d : dtypesWithoutNone)
402 EXPECT_FALSE(op->hasSeq(d));
403 op->removeSeqAttr();
405 op->setVectorAttr(b.getArrayAttr({dtypeNone}));
406 EXPECT_TRUE(op->hasVector());
407 for (auto d : dtypesWithoutNone)
408 EXPECT_FALSE(op->hasVector(d));
409 op->removeVectorAttr();
411 op->setWorkerAttr(b.getArrayAttr({dtypeNone}));
412 EXPECT_TRUE(op->hasWorker());
413 for (auto d : dtypesWithoutNone)
414 EXPECT_FALSE(op->hasWorker(d));
415 op->removeWorkerAttr();
417 op->setGangAttr(b.getArrayAttr({dtypeNone}));
418 EXPECT_TRUE(op->hasGang());
419 for (auto d : dtypesWithoutNone)
420 EXPECT_FALSE(op->hasGang(d));
421 op->removeGangAttr();
423 op->setGangDimDeviceTypeAttr(b.getArrayAttr({dtypeNone}));
424 op->setGangDimAttr(b.getArrayAttr({b.getIntegerAttr(b.getI64Type(), 8)}));
425 EXPECT_TRUE(op->getGangDimValue().has_value());
426 EXPECT_EQ(op->getGangDimValue().value(), 8);
427 for (auto d : dtypesWithoutNone)
428 EXPECT_FALSE(op->getGangDimValue(d).has_value());
429 op->removeGangDimDeviceTypeAttr();
430 op->removeGangDimAttr();
432 op->setBindNameDeviceTypeAttr(b.getArrayAttr({dtypeNone}));
433 op->setBindNameAttr(b.getArrayAttr({b.getStringAttr("fname")}));
434 EXPECT_TRUE(op->getBindNameValue().has_value());
435 EXPECT_EQ(op->getBindNameValue().value(), "fname");
436 for (auto d : dtypesWithoutNone)
437 EXPECT_FALSE(op->getBindNameValue(d).has_value());
438 op->removeBindNameDeviceTypeAttr();
439 op->removeBindNameAttr();
442 template <typename Op>
443 void testShortDataEntryOpBuilders(OpBuilder &b, MLIRContext &context,
444 Location loc, DataClause dataClause) {
445 auto memrefTy = MemRefType::get({}, b.getI32Type());
446 OwningOpRef<memref::AllocaOp> varPtrOp =
447 b.create<memref::AllocaOp>(loc, memrefTy);
449 OwningOpRef<Op> op = b.create<Op>(loc, varPtrOp->getResult(),
450 /*structured=*/true, /*implicit=*/true);
452 EXPECT_EQ(op->getVarPtr(), varPtrOp->getResult());
453 EXPECT_EQ(op->getType(), memrefTy);
454 EXPECT_EQ(op->getDataClause(), dataClause);
455 EXPECT_TRUE(op->getImplicit());
456 EXPECT_TRUE(op->getStructured());
457 EXPECT_TRUE(op->getBounds().empty());
458 EXPECT_FALSE(op->getVarPtrPtr());
460 OwningOpRef<Op> op2 = b.create<Op>(loc, varPtrOp->getResult(),
461 /*structured=*/false, /*implicit=*/false);
462 EXPECT_FALSE(op2->getImplicit());
463 EXPECT_FALSE(op2->getStructured());
465 OwningOpRef<arith::ConstantIndexOp> extent =
466 b.create<arith::ConstantIndexOp>(loc, 1);
467 OwningOpRef<DataBoundsOp> bounds =
468 b.create<DataBoundsOp>(loc, extent->getResult());
469 OwningOpRef<Op> opWithBounds =
470 b.create<Op>(loc, varPtrOp->getResult(),
471 /*structured=*/true, /*implicit=*/true, bounds->getResult());
472 EXPECT_FALSE(opWithBounds->getBounds().empty());
473 EXPECT_EQ(opWithBounds->getBounds().back(), bounds->getResult());
475 OwningOpRef<Op> opWithName =
476 b.create<Op>(loc, varPtrOp->getResult(),
477 /*structured=*/true, /*implicit=*/true, "varName");
478 EXPECT_EQ(opWithName->getNameAttr().str(), "varName");
481 TEST_F(OpenACCOpsTest, shortDataEntryOpBuilder) {
482 testShortDataEntryOpBuilders<PrivateOp>(b, context, loc,
483 DataClause::acc_private);
484 testShortDataEntryOpBuilders<FirstprivateOp>(b, context, loc,
485 DataClause::acc_firstprivate);
486 testShortDataEntryOpBuilders<ReductionOp>(b, context, loc,
487 DataClause::acc_reduction);
488 testShortDataEntryOpBuilders<DevicePtrOp>(b, context, loc,
489 DataClause::acc_deviceptr);
490 testShortDataEntryOpBuilders<PresentOp>(b, context, loc,
491 DataClause::acc_present);
492 testShortDataEntryOpBuilders<CopyinOp>(b, context, loc,
493 DataClause::acc_copyin);
494 testShortDataEntryOpBuilders<CreateOp>(b, context, loc,
495 DataClause::acc_create);
496 testShortDataEntryOpBuilders<NoCreateOp>(b, context, loc,
497 DataClause::acc_no_create);
498 testShortDataEntryOpBuilders<AttachOp>(b, context, loc,
499 DataClause::acc_attach);
500 testShortDataEntryOpBuilders<GetDevicePtrOp>(b, context, loc,
501 DataClause::acc_getdeviceptr);
502 testShortDataEntryOpBuilders<UpdateDeviceOp>(b, context, loc,
503 DataClause::acc_update_device);
504 testShortDataEntryOpBuilders<UseDeviceOp>(b, context, loc,
505 DataClause::acc_use_device);
506 testShortDataEntryOpBuilders<DeclareDeviceResidentOp>(
507 b, context, loc, DataClause::acc_declare_device_resident);
508 testShortDataEntryOpBuilders<DeclareLinkOp>(b, context, loc,
509 DataClause::acc_declare_link);
510 testShortDataEntryOpBuilders<CacheOp>(b, context, loc, DataClause::acc_cache);
513 template <typename Op>
514 void testShortDataExitOpBuilders(OpBuilder &b, MLIRContext &context,
515 Location loc, DataClause dataClause) {
516 auto memrefTy = MemRefType::get({}, b.getI32Type());
517 OwningOpRef<memref::AllocaOp> varPtrOp =
518 b.create<memref::AllocaOp>(loc, memrefTy);
519 OwningOpRef<GetDevicePtrOp> accPtrOp = b.create<GetDevicePtrOp>(
520 loc, varPtrOp->getResult(), /*structured=*/true, /*implicit=*/true);
522 OwningOpRef<Op> op =
523 b.create<Op>(loc, accPtrOp->getResult(), varPtrOp->getResult(),
524 /*structured=*/true, /*implicit=*/true);
526 EXPECT_EQ(op->getVarPtr(), varPtrOp->getResult());
527 EXPECT_EQ(op->getAccPtr(), accPtrOp->getResult());
528 EXPECT_EQ(op->getDataClause(), dataClause);
529 EXPECT_TRUE(op->getImplicit());
530 EXPECT_TRUE(op->getStructured());
531 EXPECT_TRUE(op->getBounds().empty());
533 OwningOpRef<Op> op2 =
534 b.create<Op>(loc, accPtrOp->getResult(), varPtrOp->getResult(),
535 /*structured=*/false, /*implicit=*/false);
536 EXPECT_FALSE(op2->getImplicit());
537 EXPECT_FALSE(op2->getStructured());
539 OwningOpRef<arith::ConstantIndexOp> extent =
540 b.create<arith::ConstantIndexOp>(loc, 1);
541 OwningOpRef<DataBoundsOp> bounds =
542 b.create<DataBoundsOp>(loc, extent->getResult());
543 OwningOpRef<Op> opWithBounds =
544 b.create<Op>(loc, accPtrOp->getResult(), varPtrOp->getResult(),
545 /*structured=*/true, /*implicit=*/true, bounds->getResult());
546 EXPECT_FALSE(opWithBounds->getBounds().empty());
547 EXPECT_EQ(opWithBounds->getBounds().back(), bounds->getResult());
549 OwningOpRef<Op> opWithName =
550 b.create<Op>(loc, accPtrOp->getResult(), varPtrOp->getResult(),
551 /*structured=*/true, /*implicit=*/true, "varName");
552 EXPECT_EQ(opWithName->getNameAttr().str(), "varName");
555 TEST_F(OpenACCOpsTest, shortDataExitOpBuilder) {
556 testShortDataExitOpBuilders<CopyoutOp>(b, context, loc,
557 DataClause::acc_copyout);
558 testShortDataExitOpBuilders<UpdateHostOp>(b, context, loc,
559 DataClause::acc_update_host);
562 template <typename Op>
563 void testShortDataExitNoVarPtrOpBuilders(OpBuilder &b, MLIRContext &context,
564 Location loc, DataClause dataClause) {
565 auto memrefTy = MemRefType::get({}, b.getI32Type());
566 OwningOpRef<memref::AllocaOp> varPtrOp =
567 b.create<memref::AllocaOp>(loc, memrefTy);
568 OwningOpRef<GetDevicePtrOp> accPtrOp = b.create<GetDevicePtrOp>(
569 loc, varPtrOp->getResult(), /*structured=*/true, /*implicit=*/true);
571 OwningOpRef<Op> op = b.create<Op>(loc, accPtrOp->getResult(),
572 /*structured=*/true, /*implicit=*/true);
574 EXPECT_EQ(op->getAccPtr(), accPtrOp->getResult());
575 EXPECT_EQ(op->getDataClause(), dataClause);
576 EXPECT_TRUE(op->getImplicit());
577 EXPECT_TRUE(op->getStructured());
578 EXPECT_TRUE(op->getBounds().empty());
580 OwningOpRef<Op> op2 = b.create<Op>(loc, accPtrOp->getResult(),
581 /*structured=*/false, /*implicit=*/false);
582 EXPECT_FALSE(op2->getImplicit());
583 EXPECT_FALSE(op2->getStructured());
585 OwningOpRef<arith::ConstantIndexOp> extent =
586 b.create<arith::ConstantIndexOp>(loc, 1);
587 OwningOpRef<DataBoundsOp> bounds =
588 b.create<DataBoundsOp>(loc, extent->getResult());
589 OwningOpRef<Op> opWithBounds =
590 b.create<Op>(loc, accPtrOp->getResult(),
591 /*structured=*/true, /*implicit=*/true, bounds->getResult());
592 EXPECT_FALSE(opWithBounds->getBounds().empty());
593 EXPECT_EQ(opWithBounds->getBounds().back(), bounds->getResult());
595 OwningOpRef<Op> opWithName =
596 b.create<Op>(loc, accPtrOp->getResult(),
597 /*structured=*/true, /*implicit=*/true, "varName");
598 EXPECT_EQ(opWithName->getNameAttr().str(), "varName");
601 TEST_F(OpenACCOpsTest, shortDataExitOpNoVarPtrBuilder) {
602 testShortDataExitNoVarPtrOpBuilders<DeleteOp>(b, context, loc,
603 DataClause::acc_delete);
604 testShortDataExitNoVarPtrOpBuilders<DetachOp>(b, context, loc,
605 DataClause::acc_detach);