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 144 let verifier = ?; 145} 146 147//===----------------------------------------------------------------------===// 148// 2.6.5 data Construct 149//===----------------------------------------------------------------------===// 150 151def OpenACC_DataOp : OpenACC_Op<"data", 152 [AttrSizedOperandSegments]> { 153 let summary = "data construct"; 154 155 let description = [{ 156 The "acc.data" operation represents a data construct. It defines vars to 157 be allocated in the current device memory for the duration of the region, 158 whether data should be copied from local memory to the current device 159 memory upon region entry , and copied from device memory to local memory 160 upon region exit. 161 162 Example: 163 164 ```mlir 165 acc.data present(%a: memref<10x10xf32>, %b: memref<10x10xf32>, 166 %c: memref<10xf32>, %d: memref<10xf32>) { 167 // data region 168 } 169 ``` 170 }]; 171 172 173 let arguments = (ins Optional<I1>:$ifCond, 174 Variadic<AnyType>:$copyOperands, 175 Variadic<AnyType>:$copyinOperands, 176 Variadic<AnyType>:$copyinReadonlyOperands, 177 Variadic<AnyType>:$copyoutOperands, 178 Variadic<AnyType>:$copyoutZeroOperands, 179 Variadic<AnyType>:$createOperands, 180 Variadic<AnyType>:$createZeroOperands, 181 Variadic<AnyType>:$noCreateOperands, 182 Variadic<AnyType>:$presentOperands, 183 Variadic<AnyType>:$deviceptrOperands, 184 Variadic<AnyType>:$attachOperands, 185 OptionalAttr<DefaultValue>:$defaultAttr); 186 187 let regions = (region AnyRegion:$region); 188 189 let assemblyFormat = [{ 190 ( `if` `(` $ifCond^ `)` )? 191 ( `copy` `(` $copyOperands^ `:` type($copyOperands) `)` )? 192 ( `copyin` `(` $copyinOperands^ `:` type($copyinOperands) `)` )? 193 ( `copyin_readonly` `(` $copyinReadonlyOperands^ `:` 194 type($copyinReadonlyOperands) `)` )? 195 ( `copyout` `(` $copyoutOperands^ `:` type($copyoutOperands) `)` )? 196 ( `copyout_zero` `(` $copyoutZeroOperands^ `:` 197 type($copyoutZeroOperands) `)` )? 198 ( `create` `(` $createOperands^ `:` type($createOperands) `)` )? 199 ( `create_zero` `(` $createZeroOperands^ `:` 200 type($createZeroOperands) `)` )? 201 ( `no_create` `(` $noCreateOperands^ `:` type($noCreateOperands) `)` )? 202 ( `present` `(` $presentOperands^ `:` type($presentOperands) `)` )? 203 ( `deviceptr` `(` $deviceptrOperands^ `:` type($deviceptrOperands) `)` )? 204 ( `attach` `(` $attachOperands^ `:` type($attachOperands) `)` )? 205 $region attr-dict-with-keyword 206 }]; 207} 208 209def OpenACC_TerminatorOp : OpenACC_Op<"terminator", [Terminator]> { 210 let summary = "Generic terminator for OpenACC regions"; 211 212 let description = [{ 213 A terminator operation for regions that appear in the body of OpenACC 214 operation. Generic OpenACC construct regions are not expected to return any 215 value so the terminator takes no operands. The terminator op returns control 216 to the enclosing op. 217 }]; 218 219 let verifier = ?; 220 221 let assemblyFormat = "attr-dict"; 222} 223 224//===----------------------------------------------------------------------===// 225// 2.6.6 Enter Data Directive 226//===----------------------------------------------------------------------===// 227 228def OpenACC_EnterDataOp : OpenACC_Op<"enter_data", [AttrSizedOperandSegments]> { 229 let summary = "enter data operation"; 230 231 let description = [{ 232 The "acc.enter_data" operation represents the OpenACC enter data directive. 233 234 Example: 235 236 ```mlir 237 acc.enter_data create(%d1 : memref<10xf32>) attributes {async} 238 ``` 239 }]; 240 241 let arguments = (ins Optional<I1>:$ifCond, 242 Optional<IntOrIndex>:$asyncOperand, 243 UnitAttr:$async, 244 Optional<IntOrIndex>:$waitDevnum, 245 Variadic<IntOrIndex>:$waitOperands, 246 UnitAttr:$wait, 247 Variadic<AnyType>:$copyinOperands, 248 Variadic<AnyType>:$createOperands, 249 Variadic<AnyType>:$createZeroOperands, 250 Variadic<AnyType>:$attachOperands); 251 252 let assemblyFormat = [{ 253 ( `if` `(` $ifCond^ `)` )? 254 ( `async` `(` $asyncOperand^ `:` type($asyncOperand) `)` )? 255 ( `wait_devnum` `(` $waitDevnum^ `:` type($waitDevnum) `)` )? 256 ( `wait` `(` $waitOperands^ `:` type($waitOperands) `)` )? 257 ( `copyin` `(` $copyinOperands^ `:` type($copyinOperands) `)` )? 258 ( `create` `(` $createOperands^ `:` type($createOperands) `)` )? 259 ( `create_zero` `(` $createZeroOperands^ `:` 260 type($createZeroOperands) `)` )? 261 ( `attach` `(` $attachOperands^ `:` type($attachOperands) `)` )? 262 attr-dict-with-keyword 263 }]; 264} 265 266//===----------------------------------------------------------------------===// 267// 2.6.6 Exit Data Directive 268//===----------------------------------------------------------------------===// 269 270def OpenACC_ExitDataOp : OpenACC_Op<"exit_data", [AttrSizedOperandSegments]> { 271 let summary = "exit data operation"; 272 273 let description = [{ 274 The "acc.exit_data" operation represents the OpenACC exit data directive. 275 276 Example: 277 278 ```mlir 279 acc.exit_data delete(%d1 : memref<10xf32>) attributes {async} 280 ``` 281 }]; 282 283 let arguments = (ins Optional<I1>:$ifCond, 284 Optional<IntOrIndex>:$asyncOperand, 285 UnitAttr:$async, 286 Optional<IntOrIndex>:$waitDevnum, 287 Variadic<IntOrIndex>:$waitOperands, 288 UnitAttr:$wait, 289 Variadic<AnyType>:$copyoutOperands, 290 Variadic<AnyType>:$deleteOperands, 291 Variadic<AnyType>:$detachOperands, 292 UnitAttr:$finalize); 293 294 let assemblyFormat = [{ 295 ( `if` `(` $ifCond^ `)` )? 296 ( `async` `(` $asyncOperand^ `:` type($asyncOperand) `)` )? 297 ( `wait_devnum` `(` $waitDevnum^ `:` type($waitDevnum) `)` )? 298 ( `wait` `(` $waitOperands^ `:` type($waitOperands) `)` )? 299 ( `copyout` `(` $copyoutOperands^ `:` type($copyoutOperands) `)` )? 300 ( `delete` `(` $deleteOperands^ `:` type($deleteOperands) `)` )? 301 ( `detach` `(` $detachOperands^ `:` type($detachOperands) `)` )? 302 attr-dict-with-keyword 303 }]; 304} 305 306//===----------------------------------------------------------------------===// 307// 2.9 loop Construct 308//===----------------------------------------------------------------------===// 309 310def OpenACC_LoopOp : OpenACC_Op<"loop", 311 [AttrSizedOperandSegments, 312 SingleBlockImplicitTerminator<"acc::YieldOp">]> { 313 let summary = "loop construct"; 314 315 let description = [{ 316 The "acc.loop" operation represents the OpenACC loop construct. 317 318 Example: 319 320 ```mlir 321 acc.loop gang vector { 322 scf.for %arg3 = %c0 to %c10 step %c1 { 323 scf.for %arg4 = %c0 to %c10 step %c1 { 324 scf.for %arg5 = %c0 to %c10 step %c1 { 325 // ... body 326 } 327 } 328 } 329 acc.yield 330 } attributes { collapse = 3 } 331 ``` 332 }]; 333 334 335 let arguments = (ins OptionalAttr<I64Attr>:$collapse, 336 Optional<IntOrIndex>:$gangNum, 337 Optional<IntOrIndex>:$gangStatic, 338 Optional<IntOrIndex>:$workerNum, 339 Optional<IntOrIndex>:$vectorLength, 340 UnitAttr:$seq, 341 UnitAttr:$independent, 342 UnitAttr:$auto_, 343 Variadic<IntOrIndex>:$tileOperands, 344 Variadic<AnyType>:$privateOperands, 345 OptionalAttr<OpenACC_ReductionOpAttr>:$reductionOp, 346 Variadic<AnyType>:$reductionOperands, 347 DefaultValuedAttr<I64Attr, "0">:$exec_mapping); 348 349 let results = (outs Variadic<AnyType>:$results); 350 351 let regions = (region AnyRegion:$region); 352 353 let extraClassDeclaration = [{ 354 static StringRef getCollapseAttrName() { return "collapse"; } 355 static StringRef getSeqAttrName() { return "seq"; } 356 static StringRef getIndependentAttrName() { return "independent"; } 357 static StringRef getAutoAttrName() { return "auto"; } 358 static StringRef getExecutionMappingAttrName() { return "exec_mapping"; } 359 static StringRef getGangKeyword() { return "gang"; } 360 static StringRef getGangNumKeyword() { return "num"; } 361 static StringRef getGangStaticKeyword() { return "static"; } 362 static StringRef getVectorKeyword() { return "vector"; } 363 static StringRef getWorkerKeyword() { return "worker"; } 364 static StringRef getTileKeyword() { return "tile"; } 365 static StringRef getPrivateKeyword() { return "private"; } 366 static StringRef getReductionKeyword() { return "reduction"; } 367 }]; 368 369 let verifier = [{ return ::verifyLoopOp(*this); }]; 370} 371 372// Yield operation for the acc.loop and acc.parallel operations. 373def OpenACC_YieldOp : OpenACC_Op<"yield", [Terminator, 374 ParentOneOf<["ParallelOp, LoopOp"]>]> { 375 let summary = "Acc yield and termination operation"; 376 377 let description = [{ 378 `acc.yield` is a special terminator operation for block inside regions in 379 acc ops (parallel and loop). It returns values to the immediately enclosing 380 acc op. 381 }]; 382 383 let arguments = (ins Variadic<AnyType>:$operands); 384 385 let builders = [OpBuilderDAG<(ins), [{ /* nothing to do */ }]>]; 386 387 let verifier = ?; 388 389 let assemblyFormat = "attr-dict ($operands^ `:` type($operands))?"; 390} 391 392//===----------------------------------------------------------------------===// 393// 2.14.1. Init Directive 394//===----------------------------------------------------------------------===// 395 396def OpenACC_InitOp : OpenACC_Op<"init", [AttrSizedOperandSegments]> { 397 let summary = "init operation"; 398 399 let description = [{ 400 The "acc.init" operation represents the OpenACC init executable 401 directive. 402 403 Example: 404 405 ```mlir 406 acc.init 407 acc.init device_num(%dev1 : i32) 408 ``` 409 }]; 410 411 let arguments = (ins Variadic<AnyInteger>:$deviceTypeOperands, 412 Optional<IntOrIndex>:$deviceNumOperand, 413 Optional<I1>:$ifCond); 414 415 let assemblyFormat = [{ 416 ( `device_type` `(` $deviceTypeOperands^ `:` type($deviceTypeOperands) `)` )? 417 ( `device_num` `(` $deviceNumOperand^ `:` type($deviceNumOperand) `)` )? 418 ( `if` `(` $ifCond^ `)` )? attr-dict-with-keyword 419 }]; 420} 421 422//===----------------------------------------------------------------------===// 423// 2.14.2. Shutdown 424//===----------------------------------------------------------------------===// 425 426def OpenACC_ShutdownOp : OpenACC_Op<"shutdown", [AttrSizedOperandSegments]> { 427 let summary = "shutdown operation"; 428 429 let description = [{ 430 The "acc.shutdown" operation represents the OpenACC shutdown executable 431 directive. 432 433 Example: 434 435 ```mlir 436 acc.shutdown 437 acc.shutdown device_num(%dev1 : i32) 438 ``` 439 }]; 440 441 let arguments = (ins Variadic<AnyInteger>:$deviceTypeOperands, 442 Optional<IntOrIndex>:$deviceNumOperand, 443 Optional<I1>:$ifCond); 444 445 let assemblyFormat = [{ 446 ( `device_type` `(` $deviceTypeOperands^ `:` type($deviceTypeOperands) `)` )? 447 ( `device_num` `(` $deviceNumOperand^ `:` type($deviceNumOperand) `)` )? 448 ( `if` `(` $ifCond^ `)` )? attr-dict-with-keyword 449 }]; 450} 451 452//===----------------------------------------------------------------------===// 453// 2.14.4. Update Directive 454//===----------------------------------------------------------------------===// 455 456def OpenACC_UpdateOp : OpenACC_Op<"update", [AttrSizedOperandSegments]> { 457 let summary = "update operation"; 458 459 let description = [{ 460 The "acc.udpate" operation represents the OpenACC update executable 461 directive. 462 As host and self clauses are synonyms, any operands for host and self are 463 add to $hostOperands. 464 465 Example: 466 467 ```mlir 468 acc.update device(%d1 : memref<10xf32>) attributes {async} 469 ``` 470 }]; 471 472 let arguments = (ins Optional<IntOrIndex>:$asyncOperand, 473 Optional<IntOrIndex>:$waitDevnum, 474 Variadic<IntOrIndex>:$waitOperands, 475 UnitAttr:$async, 476 UnitAttr:$wait, 477 Variadic<IntOrIndex>:$deviceTypeOperands, 478 Optional<I1>:$ifCond, 479 Variadic<AnyType>:$hostOperands, 480 Variadic<AnyType>:$deviceOperands, 481 UnitAttr:$ifPresent); 482 483 let assemblyFormat = [{ 484 ( `if` `(` $ifCond^ `)` )? 485 ( `async` `(` $asyncOperand^ `:` type($asyncOperand) `)` )? 486 ( `wait_devnum` `(` $waitDevnum^ `:` type($waitDevnum) `)` )? 487 ( `device_type` `(` $deviceTypeOperands^ `:` 488 type($deviceTypeOperands) `)` )? 489 ( `wait` `(` $waitOperands^ `:` type($waitOperands) `)` )? 490 ( `host` `(` $hostOperands^ `:` type($hostOperands) `)` )? 491 ( `device` `(` $deviceOperands^ `:` type($deviceOperands) `)` )? 492 attr-dict-with-keyword 493 }]; 494} 495 496//===----------------------------------------------------------------------===// 497// 2.16.3. Wait Directive 498//===----------------------------------------------------------------------===// 499 500def OpenACC_WaitOp : OpenACC_Op<"wait", [AttrSizedOperandSegments]> { 501 let summary = "wait operation"; 502 503 let description = [{ 504 The "acc.wait" operation represents the OpenACC wait executable 505 directive. 506 507 Example: 508 509 ```mlir 510 acc.wait(%value1: index) 511 acc.wait() async(%async1: i32) 512 ``` 513 }]; 514 515 let arguments = (ins Variadic<IntOrIndex>:$waitOperands, 516 Optional<IntOrIndex>:$asyncOperand, 517 Optional<IntOrIndex>:$waitDevnum, 518 UnitAttr:$async, 519 Optional<I1>:$ifCond); 520 521 let assemblyFormat = [{ 522 ( `(` $waitOperands^ `:` type($waitOperands) `)` )? 523 ( `async` `(` $asyncOperand^ `:` type($asyncOperand) `)` )? 524 ( `wait_devnum` `(` $waitDevnum^ `:` type($waitDevnum) `)` )? 525 ( `if` `(` $ifCond^ `)` )? attr-dict-with-keyword 526 }]; 527} 528 529#endif // OPENACC_OPS 530