1//===- OpenACC.td - OpenACC operation definitions ----------*- tablegen -*-===// 2// 3// Part of the MLIR 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// ============================================================================= 8// 9// Defines MLIR OpenACC operations. 10// 11//===----------------------------------------------------------------------===// 12 13#ifndef OPENACC_OPS 14#define OPENACC_OPS 15 16include "mlir/IR/OpBase.td" 17include "mlir/Dialect/OpenACC/AccCommon.td" 18 19def OpenACC_Dialect : Dialect { 20 let name = "acc"; 21 22 let summary = "An OpenACC dialect for MLIR."; 23 24 let description = [{ 25 This dialect models the construct from the OpenACC 3.1 directive language. 26 }]; 27 28 let cppNamespace = "::mlir::acc"; 29} 30 31// Base class for OpenACC dialect ops. 32class OpenACC_Op<string mnemonic, list<OpTrait> traits = []> : 33 Op<OpenACC_Dialect, mnemonic, traits> { 34 35 let printer = [{ return ::print(p, *this); }]; 36 let verifier = [{ return ::verify(*this); }]; 37 let parser = [{ return ::parse$cppClass(parser, result); }]; 38} 39 40// Reduction operation enumeration. 41def OpenACC_ReductionOpAdd : StrEnumAttrCase<"redop_add">; 42def OpenACC_ReductionOpMul : StrEnumAttrCase<"redop_mul">; 43def OpenACC_ReductionOpMax : StrEnumAttrCase<"redop_max">; 44def OpenACC_ReductionOpMin : StrEnumAttrCase<"redop_min">; 45def OpenACC_ReductionOpAnd : StrEnumAttrCase<"redop_and">; 46def OpenACC_ReductionOpOr : StrEnumAttrCase<"redop_or">; 47def OpenACC_ReductionOpXor : StrEnumAttrCase<"redop_xor">; 48def OpenACC_ReductionOpLogEqv : StrEnumAttrCase<"redop_leqv">; 49def OpenACC_ReductionOpLogNeqv : StrEnumAttrCase<"redop_lneqv">; 50def OpenACC_ReductionOpLogAnd : StrEnumAttrCase<"redop_land">; 51def OpenACC_ReductionOpLogOr : StrEnumAttrCase<"redop_lor">; 52 53def OpenACC_ReductionOpAttr : StrEnumAttr<"ReductionOpAttr", 54 "built-in reduction operations supported by OpenACC", 55 [OpenACC_ReductionOpAdd, OpenACC_ReductionOpMul, OpenACC_ReductionOpMax, 56 OpenACC_ReductionOpMin, OpenACC_ReductionOpAnd, OpenACC_ReductionOpOr, 57 OpenACC_ReductionOpXor, OpenACC_ReductionOpLogEqv, 58 OpenACC_ReductionOpLogNeqv, OpenACC_ReductionOpLogAnd, 59 OpenACC_ReductionOpLogOr 60 ]> { 61 let cppNamespace = "::mlir::acc"; 62} 63 64// Type used in operation below. 65def IntOrIndex : AnyTypeOf<[AnyInteger, Index]>; 66 67//===----------------------------------------------------------------------===// 68// 2.5.1 parallel Construct 69//===----------------------------------------------------------------------===// 70 71def OpenACC_ParallelOp : OpenACC_Op<"parallel", 72 [AttrSizedOperandSegments]> { 73 let summary = "parallel construct"; 74 let description = [{ 75 The "acc.parallel" operation represents a parallel construct block. It has 76 one region to be executed in parallel on the current device. 77 78 Example: 79 80 ```mlir 81 acc.parallel num_gangs(%c10) num_workers(%c10) 82 private(%c : memref<10xf32>) { 83 // parallel region 84 } 85 ``` 86 }]; 87 88 let arguments = (ins Optional<IntOrIndex>:$async, 89 UnitAttr:$asyncAttr, 90 Variadic<IntOrIndex>:$waitOperands, 91 UnitAttr:$waitAttr, 92 Optional<IntOrIndex>:$numGangs, 93 Optional<IntOrIndex>:$numWorkers, 94 Optional<IntOrIndex>:$vectorLength, 95 Optional<I1>:$ifCond, 96 Optional<I1>:$selfCond, 97 UnitAttr:$selfAttr, 98 OptionalAttr<OpenACC_ReductionOpAttr>:$reductionOp, 99 Variadic<AnyType>:$reductionOperands, 100 Variadic<AnyType>:$copyOperands, 101 Variadic<AnyType>:$copyinOperands, 102 Variadic<AnyType>:$copyinReadonlyOperands, 103 Variadic<AnyType>:$copyoutOperands, 104 Variadic<AnyType>:$copyoutZeroOperands, 105 Variadic<AnyType>:$createOperands, 106 Variadic<AnyType>:$createZeroOperands, 107 Variadic<AnyType>:$noCreateOperands, 108 Variadic<AnyType>:$presentOperands, 109 Variadic<AnyType>:$devicePtrOperands, 110 Variadic<AnyType>:$attachOperands, 111 Variadic<AnyType>:$gangPrivateOperands, 112 Variadic<AnyType>:$gangFirstPrivateOperands, 113 OptionalAttr<DefaultValue>:$defaultAttr); 114 115 let regions = (region AnyRegion:$region); 116 117 let extraClassDeclaration = [{ 118 static StringRef getAsyncKeyword() { return "async"; } 119 static StringRef getAsyncAttrName() { return "asyncAttr"; } 120 static StringRef getWaitKeyword() { return "wait"; } 121 static StringRef getWaitAttrName() { return "waitAttr"; } 122 static StringRef getNumGangsKeyword() { return "num_gangs"; } 123 static StringRef getNumWorkersKeyword() { return "num_workers"; } 124 static StringRef getVectorLengthKeyword() { return "vector_length"; } 125 static StringRef getIfKeyword() { return "if"; } 126 static StringRef getSelfKeyword() { return "self"; } 127 static StringRef getSelfAttrName() { return "selfAttr"; } 128 static StringRef getReductionKeyword() { return "reduction"; } 129 static StringRef getCopyKeyword() { return "copy"; } 130 static StringRef getCopyinKeyword() { return "copyin"; } 131 static StringRef getCopyinReadonlyKeyword() { return "copyin_readonly"; } 132 static StringRef getCopyoutKeyword() { return "copyout"; } 133 static StringRef getCopyoutZeroKeyword() { return "copyout_zero"; } 134 static StringRef getCreateKeyword() { return "create"; } 135 static StringRef getCreateZeroKeyword() { return "create_zero"; } 136 static StringRef getNoCreateKeyword() { return "no_create"; } 137 static StringRef getPresentKeyword() { return "present"; } 138 static StringRef getDevicePtrKeyword() { return "deviceptr"; } 139 static StringRef getAttachKeyword() { return "attach"; } 140 static StringRef getPrivateKeyword() { return "private"; } 141 static StringRef getFirstPrivateKeyword() { return "firstprivate"; } 142 143 /// The number of data operands. 144 unsigned getNumDataOperands(); 145 146 /// The i-th data operand passed. 147 Value getDataOperand(unsigned i); 148 }]; 149 150 let verifier = ?; 151} 152 153//===----------------------------------------------------------------------===// 154// 2.6.5 data Construct 155//===----------------------------------------------------------------------===// 156 157def OpenACC_DataOp : OpenACC_Op<"data", 158 [AttrSizedOperandSegments]> { 159 let summary = "data construct"; 160 161 let description = [{ 162 The "acc.data" operation represents a data construct. It defines vars to 163 be allocated in the current device memory for the duration of the region, 164 whether data should be copied from local memory to the current device 165 memory upon region entry , and copied from device memory to local memory 166 upon region exit. 167 168 Example: 169 170 ```mlir 171 acc.data present(%a: memref<10x10xf32>, %b: memref<10x10xf32>, 172 %c: memref<10xf32>, %d: memref<10xf32>) { 173 // data region 174 } 175 ``` 176 }]; 177 178 179 let arguments = (ins Optional<I1>:$ifCond, 180 Variadic<AnyType>:$copyOperands, 181 Variadic<AnyType>:$copyinOperands, 182 Variadic<AnyType>:$copyinReadonlyOperands, 183 Variadic<AnyType>:$copyoutOperands, 184 Variadic<AnyType>:$copyoutZeroOperands, 185 Variadic<AnyType>:$createOperands, 186 Variadic<AnyType>:$createZeroOperands, 187 Variadic<AnyType>:$noCreateOperands, 188 Variadic<AnyType>:$presentOperands, 189 Variadic<AnyType>:$deviceptrOperands, 190 Variadic<AnyType>:$attachOperands, 191 OptionalAttr<DefaultValue>:$defaultAttr); 192 193 let regions = (region AnyRegion:$region); 194 195 let extraClassDeclaration = [{ 196 /// The number of data operands. 197 unsigned getNumDataOperands(); 198 199 /// The i-th data operand passed. 200 Value getDataOperand(unsigned i); 201 }]; 202 203 let assemblyFormat = [{ 204 ( `if` `(` $ifCond^ `)` )? 205 ( `copy` `(` $copyOperands^ `:` type($copyOperands) `)` )? 206 ( `copyin` `(` $copyinOperands^ `:` type($copyinOperands) `)` )? 207 ( `copyin_readonly` `(` $copyinReadonlyOperands^ `:` 208 type($copyinReadonlyOperands) `)` )? 209 ( `copyout` `(` $copyoutOperands^ `:` type($copyoutOperands) `)` )? 210 ( `copyout_zero` `(` $copyoutZeroOperands^ `:` 211 type($copyoutZeroOperands) `)` )? 212 ( `create` `(` $createOperands^ `:` type($createOperands) `)` )? 213 ( `create_zero` `(` $createZeroOperands^ `:` 214 type($createZeroOperands) `)` )? 215 ( `no_create` `(` $noCreateOperands^ `:` type($noCreateOperands) `)` )? 216 ( `present` `(` $presentOperands^ `:` type($presentOperands) `)` )? 217 ( `deviceptr` `(` $deviceptrOperands^ `:` type($deviceptrOperands) `)` )? 218 ( `attach` `(` $attachOperands^ `:` type($attachOperands) `)` )? 219 $region attr-dict-with-keyword 220 }]; 221} 222 223def OpenACC_TerminatorOp : OpenACC_Op<"terminator", [Terminator]> { 224 let summary = "Generic terminator for OpenACC regions"; 225 226 let description = [{ 227 A terminator operation for regions that appear in the body of OpenACC 228 operation. Generic OpenACC construct regions are not expected to return any 229 value so the terminator takes no operands. The terminator op returns control 230 to the enclosing op. 231 }]; 232 233 let verifier = ?; 234 235 let assemblyFormat = "attr-dict"; 236} 237 238//===----------------------------------------------------------------------===// 239// 2.6.6 Enter Data Directive 240//===----------------------------------------------------------------------===// 241 242def OpenACC_EnterDataOp : OpenACC_Op<"enter_data", [AttrSizedOperandSegments]> { 243 let summary = "enter data operation"; 244 245 let description = [{ 246 The "acc.enter_data" operation represents the OpenACC enter data directive. 247 248 Example: 249 250 ```mlir 251 acc.enter_data create(%d1 : memref<10xf32>) attributes {async} 252 ``` 253 }]; 254 255 let arguments = (ins Optional<I1>:$ifCond, 256 Optional<IntOrIndex>:$asyncOperand, 257 UnitAttr:$async, 258 Optional<IntOrIndex>:$waitDevnum, 259 Variadic<IntOrIndex>:$waitOperands, 260 UnitAttr:$wait, 261 Variadic<AnyType>:$copyinOperands, 262 Variadic<AnyType>:$createOperands, 263 Variadic<AnyType>:$createZeroOperands, 264 Variadic<AnyType>:$attachOperands); 265 266 let extraClassDeclaration = [{ 267 /// The number of data operands. 268 unsigned getNumDataOperands(); 269 270 /// The i-th data operand passed. 271 Value getDataOperand(unsigned i); 272 }]; 273 274 let assemblyFormat = [{ 275 ( `if` `(` $ifCond^ `)` )? 276 ( `async` `(` $asyncOperand^ `:` type($asyncOperand) `)` )? 277 ( `wait_devnum` `(` $waitDevnum^ `:` type($waitDevnum) `)` )? 278 ( `wait` `(` $waitOperands^ `:` type($waitOperands) `)` )? 279 ( `copyin` `(` $copyinOperands^ `:` type($copyinOperands) `)` )? 280 ( `create` `(` $createOperands^ `:` type($createOperands) `)` )? 281 ( `create_zero` `(` $createZeroOperands^ `:` 282 type($createZeroOperands) `)` )? 283 ( `attach` `(` $attachOperands^ `:` type($attachOperands) `)` )? 284 attr-dict-with-keyword 285 }]; 286 287 let hasCanonicalizer = 1; 288} 289 290//===----------------------------------------------------------------------===// 291// 2.6.6 Exit Data Directive 292//===----------------------------------------------------------------------===// 293 294def OpenACC_ExitDataOp : OpenACC_Op<"exit_data", [AttrSizedOperandSegments]> { 295 let summary = "exit data operation"; 296 297 let description = [{ 298 The "acc.exit_data" operation represents the OpenACC exit data directive. 299 300 Example: 301 302 ```mlir 303 acc.exit_data delete(%d1 : memref<10xf32>) attributes {async} 304 ``` 305 }]; 306 307 let arguments = (ins Optional<I1>:$ifCond, 308 Optional<IntOrIndex>:$asyncOperand, 309 UnitAttr:$async, 310 Optional<IntOrIndex>:$waitDevnum, 311 Variadic<IntOrIndex>:$waitOperands, 312 UnitAttr:$wait, 313 Variadic<AnyType>:$copyoutOperands, 314 Variadic<AnyType>:$deleteOperands, 315 Variadic<AnyType>:$detachOperands, 316 UnitAttr:$finalize); 317 318 let extraClassDeclaration = [{ 319 /// The number of data operands. 320 unsigned getNumDataOperands(); 321 322 /// The i-th data operand passed. 323 Value getDataOperand(unsigned i); 324 }]; 325 326 let assemblyFormat = [{ 327 ( `if` `(` $ifCond^ `)` )? 328 ( `async` `(` $asyncOperand^ `:` type($asyncOperand) `)` )? 329 ( `wait_devnum` `(` $waitDevnum^ `:` type($waitDevnum) `)` )? 330 ( `wait` `(` $waitOperands^ `:` type($waitOperands) `)` )? 331 ( `copyout` `(` $copyoutOperands^ `:` type($copyoutOperands) `)` )? 332 ( `delete` `(` $deleteOperands^ `:` type($deleteOperands) `)` )? 333 ( `detach` `(` $detachOperands^ `:` type($detachOperands) `)` )? 334 attr-dict-with-keyword 335 }]; 336 337 let hasCanonicalizer = 1; 338} 339 340//===----------------------------------------------------------------------===// 341// 2.9 loop Construct 342//===----------------------------------------------------------------------===// 343 344def OpenACC_LoopOp : OpenACC_Op<"loop", 345 [AttrSizedOperandSegments, 346 SingleBlockImplicitTerminator<"acc::YieldOp">]> { 347 let summary = "loop construct"; 348 349 let description = [{ 350 The "acc.loop" operation represents the OpenACC loop construct. 351 352 Example: 353 354 ```mlir 355 acc.loop gang vector { 356 scf.for %arg3 = %c0 to %c10 step %c1 { 357 scf.for %arg4 = %c0 to %c10 step %c1 { 358 scf.for %arg5 = %c0 to %c10 step %c1 { 359 // ... body 360 } 361 } 362 } 363 acc.yield 364 } attributes { collapse = 3 } 365 ``` 366 }]; 367 368 369 let arguments = (ins OptionalAttr<I64Attr>:$collapse, 370 Optional<IntOrIndex>:$gangNum, 371 Optional<IntOrIndex>:$gangStatic, 372 Optional<IntOrIndex>:$workerNum, 373 Optional<IntOrIndex>:$vectorLength, 374 UnitAttr:$seq, 375 UnitAttr:$independent, 376 UnitAttr:$auto_, 377 Variadic<IntOrIndex>:$tileOperands, 378 Variadic<AnyType>:$privateOperands, 379 OptionalAttr<OpenACC_ReductionOpAttr>:$reductionOp, 380 Variadic<AnyType>:$reductionOperands, 381 DefaultValuedAttr<I64Attr, "0">:$exec_mapping); 382 383 let results = (outs Variadic<AnyType>:$results); 384 385 let regions = (region AnyRegion:$region); 386 387 let extraClassDeclaration = [{ 388 static StringRef getCollapseAttrName() { return "collapse"; } 389 static StringRef getSeqAttrName() { return "seq"; } 390 static StringRef getIndependentAttrName() { return "independent"; } 391 static StringRef getAutoAttrName() { return "auto"; } 392 static StringRef getExecutionMappingAttrName() { return "exec_mapping"; } 393 static StringRef getGangKeyword() { return "gang"; } 394 static StringRef getGangNumKeyword() { return "num"; } 395 static StringRef getGangStaticKeyword() { return "static"; } 396 static StringRef getVectorKeyword() { return "vector"; } 397 static StringRef getWorkerKeyword() { return "worker"; } 398 static StringRef getTileKeyword() { return "tile"; } 399 static StringRef getPrivateKeyword() { return "private"; } 400 static StringRef getReductionKeyword() { return "reduction"; } 401 }]; 402 403 let verifier = [{ return ::verifyLoopOp(*this); }]; 404} 405 406// Yield operation for the acc.loop and acc.parallel operations. 407def OpenACC_YieldOp : OpenACC_Op<"yield", [Terminator, 408 ParentOneOf<["ParallelOp, LoopOp"]>]> { 409 let summary = "Acc yield and termination operation"; 410 411 let description = [{ 412 `acc.yield` is a special terminator operation for block inside regions in 413 acc ops (parallel and loop). It returns values to the immediately enclosing 414 acc op. 415 }]; 416 417 let arguments = (ins Variadic<AnyType>:$operands); 418 419 let builders = [OpBuilder<(ins), [{ /* nothing to do */ }]>]; 420 421 let verifier = ?; 422 423 let assemblyFormat = "attr-dict ($operands^ `:` type($operands))?"; 424} 425 426//===----------------------------------------------------------------------===// 427// 2.14.1. Init Directive 428//===----------------------------------------------------------------------===// 429 430def OpenACC_InitOp : OpenACC_Op<"init", [AttrSizedOperandSegments]> { 431 let summary = "init operation"; 432 433 let description = [{ 434 The "acc.init" operation represents the OpenACC init executable 435 directive. 436 437 Example: 438 439 ```mlir 440 acc.init 441 acc.init device_num(%dev1 : i32) 442 ``` 443 }]; 444 445 let arguments = (ins Variadic<AnyInteger>:$deviceTypeOperands, 446 Optional<IntOrIndex>:$deviceNumOperand, 447 Optional<I1>:$ifCond); 448 449 let assemblyFormat = [{ 450 ( `device_type` `(` $deviceTypeOperands^ `:` type($deviceTypeOperands) `)` )? 451 ( `device_num` `(` $deviceNumOperand^ `:` type($deviceNumOperand) `)` )? 452 ( `if` `(` $ifCond^ `)` )? attr-dict-with-keyword 453 }]; 454} 455 456//===----------------------------------------------------------------------===// 457// 2.14.2. Shutdown 458//===----------------------------------------------------------------------===// 459 460def OpenACC_ShutdownOp : OpenACC_Op<"shutdown", [AttrSizedOperandSegments]> { 461 let summary = "shutdown operation"; 462 463 let description = [{ 464 The "acc.shutdown" operation represents the OpenACC shutdown executable 465 directive. 466 467 Example: 468 469 ```mlir 470 acc.shutdown 471 acc.shutdown device_num(%dev1 : i32) 472 ``` 473 }]; 474 475 let arguments = (ins Variadic<AnyInteger>:$deviceTypeOperands, 476 Optional<IntOrIndex>:$deviceNumOperand, 477 Optional<I1>:$ifCond); 478 479 let assemblyFormat = [{ 480 ( `device_type` `(` $deviceTypeOperands^ `:` type($deviceTypeOperands) `)` )? 481 ( `device_num` `(` $deviceNumOperand^ `:` type($deviceNumOperand) `)` )? 482 ( `if` `(` $ifCond^ `)` )? attr-dict-with-keyword 483 }]; 484} 485 486//===----------------------------------------------------------------------===// 487// 2.14.4. Update Directive 488//===----------------------------------------------------------------------===// 489 490def OpenACC_UpdateOp : OpenACC_Op<"update", [AttrSizedOperandSegments]> { 491 let summary = "update operation"; 492 493 let description = [{ 494 The "acc.udpate" operation represents the OpenACC update executable 495 directive. 496 As host and self clauses are synonyms, any operands for host and self are 497 add to $hostOperands. 498 499 Example: 500 501 ```mlir 502 acc.update device(%d1 : memref<10xf32>) attributes {async} 503 ``` 504 }]; 505 506 let arguments = (ins Optional<I1>:$ifCond, 507 Optional<IntOrIndex>:$asyncOperand, 508 Optional<IntOrIndex>:$waitDevnum, 509 Variadic<IntOrIndex>:$waitOperands, 510 UnitAttr:$async, 511 UnitAttr:$wait, 512 Variadic<IntOrIndex>:$deviceTypeOperands, 513 Variadic<AnyType>:$hostOperands, 514 Variadic<AnyType>:$deviceOperands, 515 UnitAttr:$ifPresent); 516 517 let extraClassDeclaration = [{ 518 /// The number of data operands. 519 unsigned getNumDataOperands(); 520 521 /// The i-th data operand passed. 522 Value getDataOperand(unsigned i); 523 }]; 524 525 let assemblyFormat = [{ 526 ( `if` `(` $ifCond^ `)` )? 527 ( `async` `(` $asyncOperand^ `:` type($asyncOperand) `)` )? 528 ( `wait_devnum` `(` $waitDevnum^ `:` type($waitDevnum) `)` )? 529 ( `device_type` `(` $deviceTypeOperands^ `:` 530 type($deviceTypeOperands) `)` )? 531 ( `wait` `(` $waitOperands^ `:` type($waitOperands) `)` )? 532 ( `host` `(` $hostOperands^ `:` type($hostOperands) `)` )? 533 ( `device` `(` $deviceOperands^ `:` type($deviceOperands) `)` )? 534 attr-dict-with-keyword 535 }]; 536 537 let hasCanonicalizer = 1; 538} 539 540//===----------------------------------------------------------------------===// 541// 2.16.3. Wait Directive 542//===----------------------------------------------------------------------===// 543 544def OpenACC_WaitOp : OpenACC_Op<"wait", [AttrSizedOperandSegments]> { 545 let summary = "wait operation"; 546 547 let description = [{ 548 The "acc.wait" operation represents the OpenACC wait executable 549 directive. 550 551 Example: 552 553 ```mlir 554 acc.wait(%value1: index) 555 acc.wait() async(%async1: i32) 556 ``` 557 }]; 558 559 let arguments = (ins Variadic<IntOrIndex>:$waitOperands, 560 Optional<IntOrIndex>:$asyncOperand, 561 Optional<IntOrIndex>:$waitDevnum, 562 UnitAttr:$async, 563 Optional<I1>:$ifCond); 564 565 let assemblyFormat = [{ 566 ( `(` $waitOperands^ `:` type($waitOperands) `)` )? 567 ( `async` `(` $asyncOperand^ `:` type($asyncOperand) `)` )? 568 ( `wait_devnum` `(` $waitDevnum^ `:` type($waitDevnum) `)` )? 569 ( `if` `(` $ifCond^ `)` )? attr-dict-with-keyword 570 }]; 571} 572 573#endif // OPENACC_OPS 574