1 //===- OpenACCOpsTest.cpp - Unit tests for OpenACC ops --------------------===//
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
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"
18 using namespace mlir::acc
;
20 //===----------------------------------------------------------------------===//
22 //===----------------------------------------------------------------------===//
24 class OpenACCOpsTest
: public ::testing::Test
{
26 OpenACCOpsTest() : b(&context
), loc(UnknownLoc::get(&context
)) {
27 context
.loadDialect
<acc::OpenACCDialect
, arith::ArithDialect
,
28 memref::MemRefDialect
>();
34 llvm::SmallVector
<DeviceType
> dtypes
= {
35 DeviceType::None
, DeviceType::Star
, DeviceType::Multicore
,
36 DeviceType::Default
, DeviceType::Host
, DeviceType::Nvidia
,
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());
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
{});
84 EXPECT_EQ(op
->getAsyncValue(), empty
);
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(),
159 EXPECT_EQ(op
->getNumGangsValues(DeviceType::Default
).drop_front().front(),
161 EXPECT_EQ(op
->getNumGangsValues(DeviceType::Multicore
).front(),
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
{});
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(),
302 EXPECT_EQ(op
->getWaitValues(DeviceType::Multicore
).front(),
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(),
323 EXPECT_EQ(op
->getWaitValues(DeviceType::Multicore
).drop_front().front(),
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
));
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);
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
);