forked from OSchip/llvm-project
[mlir][openacc] Add update operation
This patch introduce the update operation that represent the OpenACC update directive. Reviewed By: ftynse Differential Revision: https://reviews.llvm.org/D88102
This commit is contained in:
parent
6b649570cb
commit
ecc9978071
|
@ -318,4 +318,44 @@ def OpenACC_YieldOp : OpenACC_Op<"yield", [Terminator,
|
||||||
let assemblyFormat = "attr-dict ($operands^ `:` type($operands))?";
|
let assemblyFormat = "attr-dict ($operands^ `:` type($operands))?";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// 2.14.4. Update Directive
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
def OpenACC_UpdateOp : OpenACC_Op<"update", [AttrSizedOperandSegments]> {
|
||||||
|
let summary = "update operation";
|
||||||
|
|
||||||
|
let description = [{
|
||||||
|
The "acc.udpate" operation represents the OpenACC update executable
|
||||||
|
directive.
|
||||||
|
As host and self clauses are synonyms, any operands for host and self are
|
||||||
|
add to $hostOperands.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```mlir
|
||||||
|
acc.update device(%d1 : memref<10xf32>) attributes {async}
|
||||||
|
```
|
||||||
|
}];
|
||||||
|
|
||||||
|
let arguments = (ins Optional<IntOrIndex>:$asyncOperand,
|
||||||
|
Optional<IntOrIndex>:$waitDevnum,
|
||||||
|
Variadic<IntOrIndex>:$waitOperands,
|
||||||
|
UnitAttr:$async,
|
||||||
|
UnitAttr:$wait,
|
||||||
|
Variadic<AnyType>:$hostOperands,
|
||||||
|
Variadic<AnyType>:$deviceOperands,
|
||||||
|
UnitAttr:$ifPresent);
|
||||||
|
|
||||||
|
let assemblyFormat = [{
|
||||||
|
( `async` `(` $asyncOperand^ `:` type($asyncOperand) `)` )?
|
||||||
|
( `wait_devnum` `(` $waitDevnum^ `:` type($waitDevnum) `)` )?
|
||||||
|
( `wait` `(` $waitOperands^ `:` type($waitOperands) `)` )?
|
||||||
|
( `host` `(` $hostOperands^ `:` type($hostOperands) `)` )?
|
||||||
|
( `device` `(` $deviceOperands^ `:` type($deviceOperands) `)` )?
|
||||||
|
attr-dict-with-keyword
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // OPENACC_OPS
|
#endif // OPENACC_OPS
|
||||||
|
|
|
@ -645,6 +645,33 @@ static LogicalResult verify(acc::DataOp dataOp) {
|
||||||
if (dataOp.getOperands().size() == 0 && !dataOp.defaultAttr())
|
if (dataOp.getOperands().size() == 0 && !dataOp.defaultAttr())
|
||||||
return dataOp.emitError("at least one operand or the default attribute "
|
return dataOp.emitError("at least one operand or the default attribute "
|
||||||
"must appear on the data operation");
|
"must appear on the data operation");
|
||||||
|
return success();
|
||||||
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// UpdateOp
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
static LogicalResult verify(acc::UpdateOp updateOp) {
|
||||||
|
// At least one of host or device should have a value.
|
||||||
|
if (updateOp.hostOperands().size() == 0 &&
|
||||||
|
updateOp.deviceOperands().size() == 0)
|
||||||
|
return updateOp.emitError("at least one value must be present in"
|
||||||
|
" hostOperands or deviceOperands");
|
||||||
|
|
||||||
|
// The async attribute represent the async clause without value. Therefore the
|
||||||
|
// attribute and operand cannot appear at the same time.
|
||||||
|
if (updateOp.asyncOperand() && updateOp.async())
|
||||||
|
return updateOp.emitError("async attribute cannot appear with "
|
||||||
|
" asyncOperand");
|
||||||
|
|
||||||
|
// The wait attribute represent the wait clause without values. Therefore the
|
||||||
|
// attribute and operands cannot appear at the same time.
|
||||||
|
if (updateOp.waitOperands().size() > 0 && updateOp.wait())
|
||||||
|
return updateOp.emitError("wait attribute cannot appear with waitOperands");
|
||||||
|
|
||||||
|
if (updateOp.waitDevnum() && updateOp.waitOperands().size() == 0)
|
||||||
|
return updateOp.emitError("wait_devnum cannot appear without waitOperands");
|
||||||
|
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,3 +75,26 @@ acc.data {
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----
|
// -----
|
||||||
|
// expected-error@+1 {{at least one value must be present in hostOperands or deviceOperands}}
|
||||||
|
acc.update
|
||||||
|
|
||||||
|
// -----
|
||||||
|
|
||||||
|
%cst = constant 1 : index
|
||||||
|
%value = alloc() : memref<10xf32>
|
||||||
|
// expected-error@+1 {{wait_devnum cannot appear without waitOperands}}
|
||||||
|
acc.update wait_devnum(%cst: index) host(%value: memref<10xf32>)
|
||||||
|
|
||||||
|
// -----
|
||||||
|
|
||||||
|
%cst = constant 1 : index
|
||||||
|
%value = alloc() : memref<10xf32>
|
||||||
|
// expected-error@+1 {{async attribute cannot appear with asyncOperand}}
|
||||||
|
acc.update async(%cst: index) host(%value: memref<10xf32>) attributes {async}
|
||||||
|
|
||||||
|
// -----
|
||||||
|
|
||||||
|
%cst = constant 1 : index
|
||||||
|
%value = alloc() : memref<10xf32>
|
||||||
|
// expected-error@+1 {{wait attribute cannot appear with waitOperands}}
|
||||||
|
acc.update wait(%cst: index) host(%value: memref<10xf32>) attributes {wait}
|
||||||
|
|
|
@ -524,3 +524,33 @@ func @testdataop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>)
|
||||||
// CHECK-NEXT: } attributes {defaultAttr = "present"}
|
// CHECK-NEXT: } attributes {defaultAttr = "present"}
|
||||||
// CHECK: acc.data {
|
// CHECK: acc.data {
|
||||||
// CHECK-NEXT: } attributes {defaultAttr = "none"}
|
// CHECK-NEXT: } attributes {defaultAttr = "none"}
|
||||||
|
|
||||||
|
// -----
|
||||||
|
|
||||||
|
func @testupdateop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) -> () {
|
||||||
|
%i64Value = constant 1 : i64
|
||||||
|
%i32Value = constant 1 : i32
|
||||||
|
%idxValue = constant 1 : index
|
||||||
|
acc.update async(%i64Value: i64) host(%a: memref<10xf32>)
|
||||||
|
acc.update async(%i32Value: i32) host(%a: memref<10xf32>)
|
||||||
|
acc.update async(%idxValue: index) host(%a: memref<10xf32>)
|
||||||
|
acc.update wait_devnum(%i64Value: i64) wait(%i32Value, %idxValue : i32, index) host(%a: memref<10xf32>)
|
||||||
|
acc.update host(%a: memref<10xf32>) device(%b, %c : memref<10xf32>, memref<10x10xf32>)
|
||||||
|
acc.update host(%a: memref<10xf32>) device(%b, %c : memref<10xf32>, memref<10x10xf32>) attributes {async}
|
||||||
|
acc.update host(%a: memref<10xf32>) device(%b, %c : memref<10xf32>, memref<10x10xf32>) attributes {wait}
|
||||||
|
acc.update host(%a: memref<10xf32>) device(%b, %c : memref<10xf32>, memref<10x10xf32>) attributes {ifPresent}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK: func @testupdateop([[ARGA:%.*]]: memref<10xf32>, [[ARGB:%.*]]: memref<10xf32>, [[ARGC:%.*]]: memref<10x10xf32>) {
|
||||||
|
// CHECK: [[I64VALUE:%.*]] = constant 1 : i64
|
||||||
|
// CHECK: [[I32VALUE:%.*]] = constant 1 : i32
|
||||||
|
// CHECK: [[IDXVALUE:%.*]] = constant 1 : index
|
||||||
|
// CHECK: acc.update async([[I64VALUE]] : i64) host([[ARGA]] : memref<10xf32>)
|
||||||
|
// CHECK: acc.update async([[I32VALUE]] : i32) host([[ARGA]] : memref<10xf32>)
|
||||||
|
// CHECK: acc.update async([[IDXVALUE]] : index) host([[ARGA]] : memref<10xf32>)
|
||||||
|
// CHECK: acc.update wait_devnum([[I64VALUE]] : i64) wait([[I32VALUE]], [[IDXVALUE]] : i32, index) host([[ARGA]] : memref<10xf32>)
|
||||||
|
// CHECK: acc.update host([[ARGA]] : memref<10xf32>) device([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>)
|
||||||
|
// CHECK: acc.update host([[ARGA]] : memref<10xf32>) device([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>) attributes {async}
|
||||||
|
// CHECK: acc.update host([[ARGA]] : memref<10xf32>) device([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>) attributes {wait}
|
||||||
|
// CHECK: acc.update host([[ARGA]] : memref<10xf32>) device([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>) attributes {ifPresent}
|
||||||
|
|
Loading…
Reference in New Issue