mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-30 09:01:19 +00:00
[mlir][flang][openacc] Support device_type on loop construct (#76892)
This is adding support for `device_type` clause representation in the OpenACC MLIR dialect on the acc.loop operation and adjust flang to lower correctly to the new representation. Each "value" that can be impacted by a `device_type` clause is now associated with an array attribute that carry this information. This includes: - `worker` clause information - `gang` clause information - `vector` clause information - `collapse` clause information - `tile` clause information The representation of the `gang` clause information has been updated and all values are now carried in a single operand segment. This segment is then subdivided by `device_type`. Each value in a segment is also associated with a `GangArgType` so it can be differentiated (num/dim/static). This simplify the handling of gang values an limit the number of new attributes needed. When the clause can be associated with the operation without any value (`gang`, `vector`, `worker`). These are represented by a dedicated attributes with device_type information. Extra getter functions are provided to make it easier to retrieve a value based on a device_type.
This commit is contained in:
parent
71ec30132b
commit
e456689fb3
@ -1593,67 +1593,89 @@ createLoopOp(Fortran::lower::AbstractConverter &converter,
|
||||
const Fortran::parser::AccClauseList &accClauseList,
|
||||
bool needEarlyReturnHandling = false) {
|
||||
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
|
||||
|
||||
mlir::Value workerNum;
|
||||
mlir::Value vectorNum;
|
||||
mlir::Value gangNum;
|
||||
mlir::Value gangDim;
|
||||
mlir::Value gangStatic;
|
||||
llvm::SmallVector<mlir::Value> tileOperands, privateOperands,
|
||||
reductionOperands, cacheOperands;
|
||||
reductionOperands, cacheOperands, vectorOperands, workerNumOperands,
|
||||
gangOperands;
|
||||
llvm::SmallVector<mlir::Attribute> privatizations, reductionRecipes;
|
||||
bool hasGang = false, hasVector = false, hasWorker = false;
|
||||
llvm::SmallVector<int32_t> tileOperandsSegments, gangOperandsSegments;
|
||||
llvm::SmallVector<int64_t> collapseValues;
|
||||
|
||||
llvm::SmallVector<mlir::Attribute> gangArgTypes;
|
||||
llvm::SmallVector<mlir::Attribute> seqDeviceTypes, independentDeviceTypes,
|
||||
autoDeviceTypes, vectorOperandsDeviceTypes, workerNumOperandsDeviceTypes,
|
||||
vectorDeviceTypes, workerNumDeviceTypes, tileOperandsDeviceTypes,
|
||||
collapseDeviceTypes, gangDeviceTypes, gangOperandsDeviceTypes;
|
||||
|
||||
// device_type attribute is set to `none` until a device_type clause is
|
||||
// encountered.
|
||||
auto crtDeviceTypeAttr = mlir::acc::DeviceTypeAttr::get(
|
||||
builder.getContext(), mlir::acc::DeviceType::None);
|
||||
|
||||
for (const Fortran::parser::AccClause &clause : accClauseList.v) {
|
||||
mlir::Location clauseLocation = converter.genLocation(clause.source);
|
||||
if (const auto *gangClause =
|
||||
std::get_if<Fortran::parser::AccClause::Gang>(&clause.u)) {
|
||||
if (gangClause->v) {
|
||||
auto crtGangOperands = gangOperands.size();
|
||||
const Fortran::parser::AccGangArgList &x = *gangClause->v;
|
||||
for (const Fortran::parser::AccGangArg &gangArg : x.v) {
|
||||
if (const auto *num =
|
||||
std::get_if<Fortran::parser::AccGangArg::Num>(&gangArg.u)) {
|
||||
gangNum = fir::getBase(converter.genExprValue(
|
||||
*Fortran::semantics::GetExpr(num->v), stmtCtx));
|
||||
gangOperands.push_back(fir::getBase(converter.genExprValue(
|
||||
*Fortran::semantics::GetExpr(num->v), stmtCtx)));
|
||||
gangArgTypes.push_back(mlir::acc::GangArgTypeAttr::get(
|
||||
builder.getContext(), mlir::acc::GangArgType::Num));
|
||||
} else if (const auto *staticArg =
|
||||
std::get_if<Fortran::parser::AccGangArg::Static>(
|
||||
&gangArg.u)) {
|
||||
const Fortran::parser::AccSizeExpr &sizeExpr = staticArg->v;
|
||||
if (sizeExpr.v) {
|
||||
gangStatic = fir::getBase(converter.genExprValue(
|
||||
*Fortran::semantics::GetExpr(*sizeExpr.v), stmtCtx));
|
||||
gangOperands.push_back(fir::getBase(converter.genExprValue(
|
||||
*Fortran::semantics::GetExpr(*sizeExpr.v), stmtCtx)));
|
||||
} else {
|
||||
// * was passed as value and will be represented as a special
|
||||
// constant.
|
||||
gangStatic = builder.createIntegerConstant(
|
||||
clauseLocation, builder.getIndexType(), starCst);
|
||||
gangOperands.push_back(builder.createIntegerConstant(
|
||||
clauseLocation, builder.getIndexType(), starCst));
|
||||
}
|
||||
gangArgTypes.push_back(mlir::acc::GangArgTypeAttr::get(
|
||||
builder.getContext(), mlir::acc::GangArgType::Static));
|
||||
} else if (const auto *dim =
|
||||
std::get_if<Fortran::parser::AccGangArg::Dim>(
|
||||
&gangArg.u)) {
|
||||
gangDim = fir::getBase(converter.genExprValue(
|
||||
*Fortran::semantics::GetExpr(dim->v), stmtCtx));
|
||||
gangOperands.push_back(fir::getBase(converter.genExprValue(
|
||||
*Fortran::semantics::GetExpr(dim->v), stmtCtx)));
|
||||
gangArgTypes.push_back(mlir::acc::GangArgTypeAttr::get(
|
||||
builder.getContext(), mlir::acc::GangArgType::Dim));
|
||||
}
|
||||
}
|
||||
gangOperandsSegments.push_back(gangOperands.size() - crtGangOperands);
|
||||
gangOperandsDeviceTypes.push_back(crtDeviceTypeAttr);
|
||||
} else {
|
||||
gangDeviceTypes.push_back(crtDeviceTypeAttr);
|
||||
}
|
||||
hasGang = true;
|
||||
} else if (const auto *workerClause =
|
||||
std::get_if<Fortran::parser::AccClause::Worker>(&clause.u)) {
|
||||
if (workerClause->v) {
|
||||
workerNum = fir::getBase(converter.genExprValue(
|
||||
*Fortran::semantics::GetExpr(*workerClause->v), stmtCtx));
|
||||
workerNumOperands.push_back(fir::getBase(converter.genExprValue(
|
||||
*Fortran::semantics::GetExpr(*workerClause->v), stmtCtx)));
|
||||
workerNumOperandsDeviceTypes.push_back(crtDeviceTypeAttr);
|
||||
} else {
|
||||
workerNumDeviceTypes.push_back(crtDeviceTypeAttr);
|
||||
}
|
||||
hasWorker = true;
|
||||
} else if (const auto *vectorClause =
|
||||
std::get_if<Fortran::parser::AccClause::Vector>(&clause.u)) {
|
||||
if (vectorClause->v) {
|
||||
vectorNum = fir::getBase(converter.genExprValue(
|
||||
*Fortran::semantics::GetExpr(*vectorClause->v), stmtCtx));
|
||||
vectorOperands.push_back(fir::getBase(converter.genExprValue(
|
||||
*Fortran::semantics::GetExpr(*vectorClause->v), stmtCtx)));
|
||||
vectorOperandsDeviceTypes.push_back(crtDeviceTypeAttr);
|
||||
} else {
|
||||
vectorDeviceTypes.push_back(crtDeviceTypeAttr);
|
||||
}
|
||||
hasVector = true;
|
||||
} else if (const auto *tileClause =
|
||||
std::get_if<Fortran::parser::AccClause::Tile>(&clause.u)) {
|
||||
const Fortran::parser::AccTileExprList &accTileExprList = tileClause->v;
|
||||
auto crtTileOperands = tileOperands.size();
|
||||
for (const auto &accTileExpr : accTileExprList.v) {
|
||||
const auto &expr =
|
||||
std::get<std::optional<Fortran::parser::ScalarIntConstantExpr>>(
|
||||
@ -1669,6 +1691,8 @@ createLoopOp(Fortran::lower::AbstractConverter &converter,
|
||||
tileOperands.push_back(tileStar);
|
||||
}
|
||||
}
|
||||
tileOperandsDeviceTypes.push_back(crtDeviceTypeAttr);
|
||||
tileOperandsSegments.push_back(tileOperands.size() - crtTileOperands);
|
||||
} else if (const auto *privateClause =
|
||||
std::get_if<Fortran::parser::AccClause::Private>(
|
||||
&clause.u)) {
|
||||
@ -1680,17 +1704,46 @@ createLoopOp(Fortran::lower::AbstractConverter &converter,
|
||||
&clause.u)) {
|
||||
genReductions(reductionClause->v, converter, semanticsContext, stmtCtx,
|
||||
reductionOperands, reductionRecipes);
|
||||
} else if (std::get_if<Fortran::parser::AccClause::Seq>(&clause.u)) {
|
||||
seqDeviceTypes.push_back(crtDeviceTypeAttr);
|
||||
} else if (std::get_if<Fortran::parser::AccClause::Independent>(
|
||||
&clause.u)) {
|
||||
independentDeviceTypes.push_back(crtDeviceTypeAttr);
|
||||
} else if (std::get_if<Fortran::parser::AccClause::Auto>(&clause.u)) {
|
||||
autoDeviceTypes.push_back(crtDeviceTypeAttr);
|
||||
} else if (const auto *deviceTypeClause =
|
||||
std::get_if<Fortran::parser::AccClause::DeviceType>(
|
||||
&clause.u)) {
|
||||
const Fortran::parser::AccDeviceTypeExprList &deviceTypeExprList =
|
||||
deviceTypeClause->v;
|
||||
assert(deviceTypeExprList.v.size() == 1 &&
|
||||
"expect only one device_type expr");
|
||||
crtDeviceTypeAttr = mlir::acc::DeviceTypeAttr::get(
|
||||
builder.getContext(), getDeviceType(deviceTypeExprList.v.front().v));
|
||||
} else if (const auto *collapseClause =
|
||||
std::get_if<Fortran::parser::AccClause::Collapse>(
|
||||
&clause.u)) {
|
||||
const Fortran::parser::AccCollapseArg &arg = collapseClause->v;
|
||||
const auto &force = std::get<bool>(arg.t);
|
||||
if (force)
|
||||
TODO(clauseLocation, "OpenACC collapse force modifier");
|
||||
const auto &intExpr =
|
||||
std::get<Fortran::parser::ScalarIntConstantExpr>(arg.t);
|
||||
const auto *expr = Fortran::semantics::GetExpr(intExpr);
|
||||
const std::optional<int64_t> collapseValue =
|
||||
Fortran::evaluate::ToInt64(*expr);
|
||||
assert(collapseValue && "expect integer value for the collapse clause");
|
||||
collapseValues.push_back(*collapseValue);
|
||||
collapseDeviceTypes.push_back(crtDeviceTypeAttr);
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare the operand segment size attribute and the operands value range.
|
||||
llvm::SmallVector<mlir::Value> operands;
|
||||
llvm::SmallVector<int32_t> operandSegments;
|
||||
addOperand(operands, operandSegments, gangNum);
|
||||
addOperand(operands, operandSegments, gangDim);
|
||||
addOperand(operands, operandSegments, gangStatic);
|
||||
addOperand(operands, operandSegments, workerNum);
|
||||
addOperand(operands, operandSegments, vectorNum);
|
||||
addOperands(operands, operandSegments, gangOperands);
|
||||
addOperands(operands, operandSegments, workerNumOperands);
|
||||
addOperands(operands, operandSegments, vectorOperands);
|
||||
addOperands(operands, operandSegments, tileOperands);
|
||||
addOperands(operands, operandSegments, cacheOperands);
|
||||
addOperands(operands, operandSegments, privateOperands);
|
||||
@ -1708,12 +1761,42 @@ createLoopOp(Fortran::lower::AbstractConverter &converter,
|
||||
builder, currentLocation, eval, operands, operandSegments,
|
||||
/*outerCombined=*/false, retTy, yieldValue);
|
||||
|
||||
if (hasGang)
|
||||
loopOp.setHasGangAttr(builder.getUnitAttr());
|
||||
if (hasWorker)
|
||||
loopOp.setHasWorkerAttr(builder.getUnitAttr());
|
||||
if (hasVector)
|
||||
loopOp.setHasVectorAttr(builder.getUnitAttr());
|
||||
if (!gangDeviceTypes.empty())
|
||||
loopOp.setGangAttr(builder.getArrayAttr(gangDeviceTypes));
|
||||
if (!gangArgTypes.empty())
|
||||
loopOp.setGangOperandsArgTypeAttr(builder.getArrayAttr(gangArgTypes));
|
||||
if (!gangOperandsSegments.empty())
|
||||
loopOp.setGangOperandsSegmentsAttr(
|
||||
builder.getDenseI32ArrayAttr(gangOperandsSegments));
|
||||
if (!gangOperandsDeviceTypes.empty())
|
||||
loopOp.setGangOperandsDeviceTypeAttr(
|
||||
builder.getArrayAttr(gangOperandsDeviceTypes));
|
||||
|
||||
if (!workerNumDeviceTypes.empty())
|
||||
loopOp.setWorkerAttr(builder.getArrayAttr(workerNumDeviceTypes));
|
||||
if (!workerNumOperandsDeviceTypes.empty())
|
||||
loopOp.setWorkerNumOperandsDeviceTypeAttr(
|
||||
builder.getArrayAttr(workerNumOperandsDeviceTypes));
|
||||
|
||||
if (!vectorDeviceTypes.empty())
|
||||
loopOp.setVectorAttr(builder.getArrayAttr(vectorDeviceTypes));
|
||||
if (!vectorOperandsDeviceTypes.empty())
|
||||
loopOp.setVectorOperandsDeviceTypeAttr(
|
||||
builder.getArrayAttr(vectorOperandsDeviceTypes));
|
||||
|
||||
if (!tileOperandsDeviceTypes.empty())
|
||||
loopOp.setTileOperandsDeviceTypeAttr(
|
||||
builder.getArrayAttr(tileOperandsDeviceTypes));
|
||||
if (!tileOperandsSegments.empty())
|
||||
loopOp.setTileOperandsSegmentsAttr(
|
||||
builder.getDenseI32ArrayAttr(tileOperandsSegments));
|
||||
|
||||
if (!seqDeviceTypes.empty())
|
||||
loopOp.setSeqAttr(builder.getArrayAttr(seqDeviceTypes));
|
||||
if (!independentDeviceTypes.empty())
|
||||
loopOp.setIndependentAttr(builder.getArrayAttr(independentDeviceTypes));
|
||||
if (!autoDeviceTypes.empty())
|
||||
loopOp.setAuto_Attr(builder.getArrayAttr(autoDeviceTypes));
|
||||
|
||||
if (!privatizations.empty())
|
||||
loopOp.setPrivatizationsAttr(
|
||||
@ -1723,33 +1806,11 @@ createLoopOp(Fortran::lower::AbstractConverter &converter,
|
||||
loopOp.setReductionRecipesAttr(
|
||||
mlir::ArrayAttr::get(builder.getContext(), reductionRecipes));
|
||||
|
||||
// Lower clauses mapped to attributes
|
||||
for (const Fortran::parser::AccClause &clause : accClauseList.v) {
|
||||
mlir::Location clauseLocation = converter.genLocation(clause.source);
|
||||
if (const auto *collapseClause =
|
||||
std::get_if<Fortran::parser::AccClause::Collapse>(&clause.u)) {
|
||||
const Fortran::parser::AccCollapseArg &arg = collapseClause->v;
|
||||
const auto &force = std::get<bool>(arg.t);
|
||||
if (force)
|
||||
TODO(clauseLocation, "OpenACC collapse force modifier");
|
||||
const auto &intExpr =
|
||||
std::get<Fortran::parser::ScalarIntConstantExpr>(arg.t);
|
||||
const auto *expr = Fortran::semantics::GetExpr(intExpr);
|
||||
const std::optional<int64_t> collapseValue =
|
||||
Fortran::evaluate::ToInt64(*expr);
|
||||
if (collapseValue) {
|
||||
loopOp.setCollapseAttr(builder.getI64IntegerAttr(*collapseValue));
|
||||
}
|
||||
} else if (std::get_if<Fortran::parser::AccClause::Seq>(&clause.u)) {
|
||||
loopOp.setSeqAttr(builder.getUnitAttr());
|
||||
} else if (std::get_if<Fortran::parser::AccClause::Independent>(
|
||||
&clause.u)) {
|
||||
loopOp.setIndependentAttr(builder.getUnitAttr());
|
||||
} else if (std::get_if<Fortran::parser::AccClause::Auto>(&clause.u)) {
|
||||
loopOp->setAttr(mlir::acc::LoopOp::getAutoAttrStrName(),
|
||||
builder.getUnitAttr());
|
||||
}
|
||||
}
|
||||
if (!collapseValues.empty())
|
||||
loopOp.setCollapseAttr(builder.getI64ArrayAttr(collapseValues));
|
||||
if (!collapseDeviceTypes.empty())
|
||||
loopOp.setCollapseDeviceTypeAttr(builder.getArrayAttr(collapseDeviceTypes));
|
||||
|
||||
return loopOp;
|
||||
}
|
||||
|
||||
|
@ -461,7 +461,7 @@ subroutine acc_kernels_loop
|
||||
! CHECK: acc.loop {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: } attributes {seq}
|
||||
! CHECK-NEXT: } attributes {seq = [#acc.device_type<none>]}
|
||||
! CHECK: acc.terminator
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -474,7 +474,7 @@ subroutine acc_kernels_loop
|
||||
! CHECK: acc.loop {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: } attributes {auto}
|
||||
! CHECK-NEXT: } attributes {auto_ = [#acc.device_type<none>]}
|
||||
! CHECK: acc.terminator
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -487,7 +487,7 @@ subroutine acc_kernels_loop
|
||||
! CHECK: acc.loop {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: } attributes {independent}
|
||||
! CHECK-NEXT: } attributes {independent = [#acc.device_type<none>]}
|
||||
! CHECK: acc.terminator
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -497,10 +497,10 @@ subroutine acc_kernels_loop
|
||||
END DO
|
||||
|
||||
! CHECK: acc.kernels {
|
||||
! CHECK: acc.loop gang {
|
||||
! CHECK: acc.loop {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
! CHECK-NEXT: } attributes {gang = [#acc.device_type<none>]}{{$}}
|
||||
! CHECK: acc.terminator
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -511,7 +511,7 @@ subroutine acc_kernels_loop
|
||||
|
||||
! CHECK: acc.kernels {
|
||||
! CHECK: [[GANGNUM1:%.*]] = arith.constant 8 : i32
|
||||
! CHECK-NEXT: acc.loop gang(num=[[GANGNUM1]] : i32) {
|
||||
! CHECK-NEXT: acc.loop gang({num=[[GANGNUM1]] : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -525,7 +525,7 @@ subroutine acc_kernels_loop
|
||||
|
||||
! CHECK: acc.kernels {
|
||||
! CHECK: [[GANGNUM2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
|
||||
! CHECK-NEXT: acc.loop gang(num=[[GANGNUM2]] : i32) {
|
||||
! CHECK-NEXT: acc.loop gang({num=[[GANGNUM2]] : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -538,7 +538,7 @@ subroutine acc_kernels_loop
|
||||
END DO
|
||||
|
||||
! CHECK: acc.kernels {
|
||||
! CHECK: acc.loop gang(num=%{{.*}} : i32, static=%{{.*}} : i32) {
|
||||
! CHECK: acc.loop gang({num=%{{.*}} : i32, static=%{{.*}} : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -550,10 +550,10 @@ subroutine acc_kernels_loop
|
||||
a(i) = b(i)
|
||||
END DO
|
||||
! CHECK: acc.kernels {
|
||||
! CHECK: acc.loop vector {
|
||||
! CHECK: acc.loop {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
! CHECK-NEXT: } attributes {vector = [#acc.device_type<none>]}{{$}}
|
||||
! CHECK: acc.terminator
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -591,10 +591,10 @@ subroutine acc_kernels_loop
|
||||
END DO
|
||||
|
||||
! CHECK: acc.kernels {
|
||||
! CHECK: acc.loop worker {
|
||||
! CHECK: acc.loop {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
! CHECK-NEXT: } attributes {worker = [#acc.device_type<none>]}{{$}}
|
||||
! CHECK: acc.terminator
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -624,7 +624,7 @@ subroutine acc_kernels_loop
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: } attributes {collapse = 2 : i64}
|
||||
! CHECK-NEXT: } attributes {collapse = [2], collapseDeviceType = [#acc.device_type<none>]}
|
||||
! CHECK: acc.terminator
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -655,7 +655,7 @@ subroutine acc_kernels_loop
|
||||
|
||||
! CHECK: acc.kernels {
|
||||
! CHECK: [[TILESIZE:%.*]] = arith.constant 2 : i32
|
||||
! CHECK: acc.loop tile([[TILESIZE]] : i32) {
|
||||
! CHECK: acc.loop tile({[[TILESIZE]] : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -669,7 +669,7 @@ subroutine acc_kernels_loop
|
||||
|
||||
! CHECK: acc.kernels {
|
||||
! CHECK: [[TILESIZEM1:%.*]] = arith.constant -1 : i32
|
||||
! CHECK: acc.loop tile([[TILESIZEM1]] : i32) {
|
||||
! CHECK: acc.loop tile({[[TILESIZEM1]] : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -686,7 +686,7 @@ subroutine acc_kernels_loop
|
||||
! CHECK: acc.kernels {
|
||||
! CHECK: [[TILESIZE1:%.*]] = arith.constant 2 : i32
|
||||
! CHECK: [[TILESIZE2:%.*]] = arith.constant 2 : i32
|
||||
! CHECK: acc.loop tile([[TILESIZE1]], [[TILESIZE2]] : i32, i32) {
|
||||
! CHECK: acc.loop tile({[[TILESIZE1]] : i32, [[TILESIZE2]] : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -699,7 +699,7 @@ subroutine acc_kernels_loop
|
||||
END DO
|
||||
|
||||
! CHECK: acc.kernels {
|
||||
! CHECK: acc.loop tile(%{{.*}} : i32) {
|
||||
! CHECK: acc.loop tile({%{{.*}} : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -714,7 +714,7 @@ subroutine acc_kernels_loop
|
||||
END DO
|
||||
|
||||
! CHECK: acc.kernels {
|
||||
! CHECK: acc.loop tile(%{{.*}}, %{{.*}} : i32, i32) {
|
||||
! CHECK: acc.loop tile({%{{.*}} : i32, %{{.*}} : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
@ -1,6 +1,5 @@
|
||||
! This test checks lowering of OpenACC loop directive.
|
||||
|
||||
! RUN: bbc -fopenacc -emit-fir -hlfir=false %s -o - | FileCheck %s
|
||||
! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s
|
||||
|
||||
! CHECK-LABEL: acc.private.recipe @privatization_ref_10x10xf32 : !fir.ref<!fir.array<10x10xf32>> init {
|
||||
@ -41,7 +40,7 @@ program acc_loop
|
||||
!CHECK: acc.loop {
|
||||
!CHECK: fir.do_loop
|
||||
!CHECK: acc.yield
|
||||
!CHECK-NEXT: } attributes {seq}
|
||||
!CHECK-NEXT: } attributes {seq = [#acc.device_type<none>]}
|
||||
|
||||
!$acc loop auto
|
||||
DO i = 1, n
|
||||
@ -51,7 +50,7 @@ program acc_loop
|
||||
!CHECK: acc.loop {
|
||||
!CHECK: fir.do_loop
|
||||
!CHECK: acc.yield
|
||||
!CHECK-NEXT: } attributes {auto}
|
||||
!CHECK-NEXT: } attributes {auto_ = [#acc.device_type<none>]}
|
||||
|
||||
!$acc loop independent
|
||||
DO i = 1, n
|
||||
@ -61,17 +60,17 @@ program acc_loop
|
||||
!CHECK: acc.loop {
|
||||
!CHECK: fir.do_loop
|
||||
!CHECK: acc.yield
|
||||
!CHECK-NEXT: } attributes {independent}
|
||||
!CHECK-NEXT: } attributes {independent = [#acc.device_type<none>]}
|
||||
|
||||
!$acc loop gang
|
||||
DO i = 1, n
|
||||
a(i) = b(i)
|
||||
END DO
|
||||
|
||||
!CHECK: acc.loop gang {
|
||||
!CHECK: acc.loop {
|
||||
!CHECK: fir.do_loop
|
||||
!CHECK: acc.yield
|
||||
!CHECK-NEXT: }{{$}}
|
||||
!CHECK-NEXT: } attributes {gang = [#acc.device_type<none>]}{{$}}
|
||||
|
||||
!$acc loop gang(num: 8)
|
||||
DO i = 1, n
|
||||
@ -79,7 +78,7 @@ program acc_loop
|
||||
END DO
|
||||
|
||||
!CHECK: [[GANGNUM1:%.*]] = arith.constant 8 : i32
|
||||
!CHECK-NEXT: acc.loop gang(num=[[GANGNUM1]] : i32) {
|
||||
!CHECK-NEXT: acc.loop gang({num=[[GANGNUM1]] : i32}) {
|
||||
!CHECK: fir.do_loop
|
||||
!CHECK: acc.yield
|
||||
!CHECK-NEXT: }{{$}}
|
||||
@ -90,7 +89,7 @@ program acc_loop
|
||||
END DO
|
||||
|
||||
!CHECK: [[GANGNUM2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
|
||||
!CHECK-NEXT: acc.loop gang(num=[[GANGNUM2]] : i32) {
|
||||
!CHECK-NEXT: acc.loop gang({num=[[GANGNUM2]] : i32}) {
|
||||
!CHECK: fir.do_loop
|
||||
!CHECK: acc.yield
|
||||
!CHECK-NEXT: }{{$}}
|
||||
@ -100,7 +99,7 @@ program acc_loop
|
||||
a(i) = b(i)
|
||||
END DO
|
||||
|
||||
!CHECK: acc.loop gang(num=%{{.*}} : i32, static=%{{.*}} : i32) {
|
||||
!CHECK: acc.loop gang({num=%{{.*}} : i32, static=%{{.*}} : i32}) {
|
||||
!CHECK: fir.do_loop
|
||||
!CHECK: acc.yield
|
||||
!CHECK-NEXT: }{{$}}
|
||||
@ -110,10 +109,10 @@ program acc_loop
|
||||
a(i) = b(i)
|
||||
END DO
|
||||
|
||||
!CHECK: acc.loop vector {
|
||||
!CHECK: acc.loop {
|
||||
!CHECK: fir.do_loop
|
||||
!CHECK: acc.yield
|
||||
!CHECK-NEXT: }{{$}}
|
||||
!CHECK-NEXT: } attributes {vector = [#acc.device_type<none>]}{{$}}
|
||||
|
||||
!$acc loop vector(128)
|
||||
DO i = 1, n
|
||||
@ -142,10 +141,10 @@ program acc_loop
|
||||
a(i) = b(i)
|
||||
END DO
|
||||
|
||||
!CHECK: acc.loop worker {
|
||||
!CHECK: acc.loop {
|
||||
!CHECK: fir.do_loop
|
||||
!CHECK: acc.yield
|
||||
!CHECK-NEXT: }{{$}}
|
||||
!CHECK-NEXT: } attributes {worker = [#acc.device_type<none>]}{{$}}
|
||||
|
||||
!$acc loop worker(128)
|
||||
DO i = 1, n
|
||||
@ -193,7 +192,7 @@ program acc_loop
|
||||
a(i) = b(i)
|
||||
END DO
|
||||
!CHECK: [[TILESIZE:%.*]] = arith.constant 2 : i32
|
||||
!CHECK: acc.loop tile([[TILESIZE]] : i32) {
|
||||
!CHECK: acc.loop tile({[[TILESIZE]] : i32}) {
|
||||
!CHECK: fir.do_loop
|
||||
!CHECK: acc.yield
|
||||
!CHECK-NEXT: }{{$}}
|
||||
@ -203,7 +202,7 @@ program acc_loop
|
||||
a(i) = b(i)
|
||||
END DO
|
||||
!CHECK: [[TILESIZEM1:%.*]] = arith.constant -1 : i32
|
||||
!CHECK: acc.loop tile([[TILESIZEM1]] : i32) {
|
||||
!CHECK: acc.loop tile({[[TILESIZEM1]] : i32}) {
|
||||
!CHECK: fir.do_loop
|
||||
!CHECK: acc.yield
|
||||
!CHECK-NEXT: }{{$}}
|
||||
@ -217,7 +216,7 @@ program acc_loop
|
||||
|
||||
!CHECK: [[TILESIZE1:%.*]] = arith.constant 2 : i32
|
||||
!CHECK: [[TILESIZE2:%.*]] = arith.constant 2 : i32
|
||||
!CHECK: acc.loop tile([[TILESIZE1]], [[TILESIZE2]] : i32, i32) {
|
||||
!CHECK: acc.loop tile({[[TILESIZE1]] : i32, [[TILESIZE2]] : i32}) {
|
||||
!CHECK: fir.do_loop
|
||||
!CHECK: acc.yield
|
||||
!CHECK-NEXT: }{{$}}
|
||||
@ -227,7 +226,7 @@ program acc_loop
|
||||
a(i) = b(i)
|
||||
END DO
|
||||
|
||||
!CHECK: acc.loop tile(%{{.*}} : i32) {
|
||||
!CHECK: acc.loop tile({%{{.*}} : i32}) {
|
||||
!CHECK: fir.do_loop
|
||||
!CHECK: acc.yield
|
||||
!CHECK-NEXT: }{{$}}
|
||||
@ -239,7 +238,7 @@ program acc_loop
|
||||
END DO
|
||||
END DO
|
||||
|
||||
!CHECK: acc.loop tile(%{{.*}}, %{{.*}} : i32, i32) {
|
||||
!CHECK: acc.loop tile({%{{.*}} : i32, %{{.*}} : i32}) {
|
||||
!CHECK: fir.do_loop
|
||||
!CHECK: acc.yield
|
||||
!CHECK-NEXT: }{{$}}
|
||||
@ -255,7 +254,7 @@ program acc_loop
|
||||
!CHECK: fir.do_loop
|
||||
!CHECK: fir.do_loop
|
||||
!CHECK: acc.yield
|
||||
!CHECK-NEXT: } attributes {collapse = 2 : i64}
|
||||
!CHECK-NEXT: } attributes {collapse = [2], collapseDeviceType = [#acc.device_type<none>]}
|
||||
|
||||
!$acc loop
|
||||
DO i = 1, n
|
||||
@ -290,7 +289,7 @@ program acc_loop
|
||||
a(i) = b(i)
|
||||
END DO
|
||||
|
||||
!CHECK: acc.loop gang(dim=%{{.*}}, static=%{{.*}} : i32) {
|
||||
!CHECK: acc.loop gang({dim=%{{.*}}, static=%{{.*}} : i32}) {
|
||||
!CHECK: fir.do_loop
|
||||
!CHECK: acc.yield
|
||||
!CHECK-NEXT: }{{$}}
|
||||
@ -301,7 +300,7 @@ program acc_loop
|
||||
END DO
|
||||
|
||||
!CHECK: [[GANGDIM1:%.*]] = arith.constant 1 : i32
|
||||
!CHECK-NEXT: acc.loop gang(dim=[[GANGDIM1]] : i32) {
|
||||
!CHECK-NEXT: acc.loop gang({dim=[[GANGDIM1]] : i32}) {
|
||||
!CHECK: fir.do_loop
|
||||
!CHECK: acc.yield
|
||||
!CHECK-NEXT: }{{$}}
|
||||
|
@ -476,7 +476,7 @@ subroutine acc_parallel_loop
|
||||
! CHECK: acc.loop {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: } attributes {seq}
|
||||
! CHECK-NEXT: } attributes {seq = [#acc.device_type<none>]}
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -489,7 +489,7 @@ subroutine acc_parallel_loop
|
||||
! CHECK: acc.loop {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: } attributes {auto}
|
||||
! CHECK-NEXT: } attributes {auto_ = [#acc.device_type<none>]}
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -502,7 +502,7 @@ subroutine acc_parallel_loop
|
||||
! CHECK: acc.loop {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: } attributes {independent}
|
||||
! CHECK-NEXT: } attributes {independent = [#acc.device_type<none>]}
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -512,10 +512,10 @@ subroutine acc_parallel_loop
|
||||
END DO
|
||||
|
||||
! CHECK: acc.parallel {
|
||||
! CHECK: acc.loop gang {
|
||||
! CHECK: acc.loop {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
! CHECK-NEXT: } attributes {gang = [#acc.device_type<none>]}{{$}}
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -526,7 +526,7 @@ subroutine acc_parallel_loop
|
||||
|
||||
! CHECK: acc.parallel {
|
||||
! CHECK: [[GANGNUM1:%.*]] = arith.constant 8 : i32
|
||||
! CHECK-NEXT: acc.loop gang(num=[[GANGNUM1]] : i32) {
|
||||
! CHECK-NEXT: acc.loop gang({num=[[GANGNUM1]] : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -540,7 +540,7 @@ subroutine acc_parallel_loop
|
||||
|
||||
! CHECK: acc.parallel {
|
||||
! CHECK: [[GANGNUM2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
|
||||
! CHECK-NEXT: acc.loop gang(num=[[GANGNUM2]] : i32) {
|
||||
! CHECK-NEXT: acc.loop gang({num=[[GANGNUM2]] : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -553,7 +553,7 @@ subroutine acc_parallel_loop
|
||||
END DO
|
||||
|
||||
! CHECK: acc.parallel {
|
||||
! CHECK: acc.loop gang(num=%{{.*}} : i32, static=%{{.*}} : i32) {
|
||||
! CHECK: acc.loop gang({num=%{{.*}} : i32, static=%{{.*}} : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -565,10 +565,10 @@ subroutine acc_parallel_loop
|
||||
a(i) = b(i)
|
||||
END DO
|
||||
! CHECK: acc.parallel {
|
||||
! CHECK: acc.loop vector {
|
||||
! CHECK: acc.loop {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
! CHECK-NEXT: } attributes {vector = [#acc.device_type<none>]}{{$}}
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -606,10 +606,10 @@ subroutine acc_parallel_loop
|
||||
END DO
|
||||
|
||||
! CHECK: acc.parallel {
|
||||
! CHECK: acc.loop worker {
|
||||
! CHECK: acc.loop {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
! CHECK-NEXT: } attributes {worker = [#acc.device_type<none>]}{{$}}
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -639,7 +639,7 @@ subroutine acc_parallel_loop
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: } attributes {collapse = 2 : i64}
|
||||
! CHECK-NEXT: } attributes {collapse = [2], collapseDeviceType = [#acc.device_type<none>]}
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -670,7 +670,7 @@ subroutine acc_parallel_loop
|
||||
|
||||
! CHECK: acc.parallel {
|
||||
! CHECK: [[TILESIZE:%.*]] = arith.constant 2 : i32
|
||||
! CHECK: acc.loop tile([[TILESIZE]] : i32) {
|
||||
! CHECK: acc.loop tile({[[TILESIZE]] : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -684,7 +684,7 @@ subroutine acc_parallel_loop
|
||||
|
||||
! CHECK: acc.parallel {
|
||||
! CHECK: [[TILESIZEM1:%.*]] = arith.constant -1 : i32
|
||||
! CHECK: acc.loop tile([[TILESIZEM1]] : i32) {
|
||||
! CHECK: acc.loop tile({[[TILESIZEM1]] : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -701,7 +701,7 @@ subroutine acc_parallel_loop
|
||||
! CHECK: acc.parallel {
|
||||
! CHECK: [[TILESIZE1:%.*]] = arith.constant 2 : i32
|
||||
! CHECK: [[TILESIZE2:%.*]] = arith.constant 2 : i32
|
||||
! CHECK: acc.loop tile([[TILESIZE1]], [[TILESIZE2]] : i32, i32) {
|
||||
! CHECK: acc.loop tile({[[TILESIZE1]] : i32, [[TILESIZE2]] : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -714,7 +714,7 @@ subroutine acc_parallel_loop
|
||||
END DO
|
||||
|
||||
! CHECK: acc.parallel {
|
||||
! CHECK: acc.loop tile(%{{.*}} : i32) {
|
||||
! CHECK: acc.loop tile({%{{.*}} : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -729,7 +729,7 @@ subroutine acc_parallel_loop
|
||||
END DO
|
||||
|
||||
! CHECK: acc.parallel {
|
||||
! CHECK: acc.loop tile(%{{.*}}, %{{.*}} : i32, i32) {
|
||||
! CHECK: acc.loop tile({%{{.*}} : i32, %{{.*}} : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
@ -743,7 +743,7 @@ end subroutine
|
||||
! FIR: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[ARG1]] : !fir.ref<!fir.array<100x10xi32>>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref<!fir.array<100x10xi32>> {name = "b"}
|
||||
! HLFIR: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[DECLARG1]]#1 : !fir.ref<!fir.array<100x10xi32>>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref<!fir.array<100x10xi32>> {name = "b"}
|
||||
! CHECK: acc.loop reduction(@reduction_add_section_ext100xext10_ref_100x10xi32 -> %[[RED_ARG1]] : !fir.ref<!fir.array<100x10xi32>>) {
|
||||
! CHECK: } attributes {collapse = 2 : i64}
|
||||
! CHECK: } attributes {collapse = [2], collapseDeviceType = [#acc.device_type<none>]}
|
||||
|
||||
subroutine acc_reduction_add_int_array_3d(a, b)
|
||||
integer :: a(100, 10, 2), b(100, 10, 2)
|
||||
@ -765,7 +765,7 @@ end subroutine
|
||||
! FIR: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[ARG1]] : !fir.ref<!fir.array<100x10x2xi32>>) bounds(%{{.*}}, %{{.*}}, %{{.*}}) -> !fir.ref<!fir.array<100x10x2xi32>> {name = "b"}
|
||||
! HLFIR: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[DECLARG1]]#1 : !fir.ref<!fir.array<100x10x2xi32>>) bounds(%{{.*}}, %{{.*}}, %{{.*}}) -> !fir.ref<!fir.array<100x10x2xi32>> {name = "b"}
|
||||
! CHECK: acc.loop reduction(@reduction_add_section_ext100xext10xext2_ref_100x10x2xi32 -> %[[RED_ARG1]] : !fir.ref<!fir.array<100x10x2xi32>>)
|
||||
! CHECK: } attributes {collapse = 3 : i64}
|
||||
! CHECK: } attributes {collapse = [3], collapseDeviceType = [#acc.device_type<none>]}
|
||||
|
||||
subroutine acc_reduction_add_float(a, b)
|
||||
real :: a(100), b
|
||||
@ -938,7 +938,7 @@ end subroutine
|
||||
! FIR: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[ARG1]] : !fir.ref<!fir.array<100x10xf32>>) bounds(%3, %5) -> !fir.ref<!fir.array<100x10xf32>> {name = "b"}
|
||||
! HLFIR: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[DECLARG1]]#1 : !fir.ref<!fir.array<100x10xf32>>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref<!fir.array<100x10xf32>> {name = "b"}
|
||||
! CHECK: acc.loop reduction(@reduction_min_section_ext100xext10_ref_100x10xf32 -> %[[RED_ARG1]] : !fir.ref<!fir.array<100x10xf32>>)
|
||||
! CHECK: attributes {collapse = 2 : i64}
|
||||
! CHECK: attributes {collapse = [2], collapseDeviceType = [#acc.device_type<none>]}
|
||||
|
||||
subroutine acc_reduction_max_int(a, b)
|
||||
integer :: a(100)
|
||||
|
@ -411,7 +411,7 @@ subroutine acc_serial_loop
|
||||
! CHECK: acc.loop {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: } attributes {seq}
|
||||
! CHECK-NEXT: } attributes {seq = [#acc.device_type<none>]}
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -424,7 +424,7 @@ subroutine acc_serial_loop
|
||||
! CHECK: acc.loop {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: } attributes {auto}
|
||||
! CHECK-NEXT: } attributes {auto_ = [#acc.device_type<none>]}
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -437,7 +437,7 @@ subroutine acc_serial_loop
|
||||
! CHECK: acc.loop {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: } attributes {independent}
|
||||
! CHECK-NEXT: } attributes {independent = [#acc.device_type<none>]}
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -447,10 +447,10 @@ subroutine acc_serial_loop
|
||||
END DO
|
||||
|
||||
! CHECK: acc.serial {
|
||||
! CHECK: acc.loop gang {
|
||||
! CHECK: acc.loop {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
! CHECK-NEXT: } attributes {gang = [#acc.device_type<none>]}{{$}}
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -461,7 +461,7 @@ subroutine acc_serial_loop
|
||||
|
||||
! CHECK: acc.serial {
|
||||
! CHECK: [[GANGNUM1:%.*]] = arith.constant 8 : i32
|
||||
! CHECK-NEXT: acc.loop gang(num=[[GANGNUM1]] : i32) {
|
||||
! CHECK-NEXT: acc.loop gang({num=[[GANGNUM1]] : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -475,7 +475,7 @@ subroutine acc_serial_loop
|
||||
|
||||
! CHECK: acc.serial {
|
||||
! CHECK: [[GANGNUM2:%.*]] = fir.load %{{.*}} : !fir.ref<i32>
|
||||
! CHECK-NEXT: acc.loop gang(num=[[GANGNUM2]] : i32) {
|
||||
! CHECK-NEXT: acc.loop gang({num=[[GANGNUM2]] : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -488,7 +488,7 @@ subroutine acc_serial_loop
|
||||
END DO
|
||||
|
||||
! CHECK: acc.serial {
|
||||
! CHECK: acc.loop gang(num=%{{.*}} : i32, static=%{{.*}} : i32) {
|
||||
! CHECK: acc.loop gang({num=%{{.*}} : i32, static=%{{.*}} : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -500,10 +500,10 @@ subroutine acc_serial_loop
|
||||
a(i) = b(i)
|
||||
END DO
|
||||
! CHECK: acc.serial {
|
||||
! CHECK: acc.loop vector {
|
||||
! CHECK: acc.loop {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
! CHECK-NEXT: } attributes {vector = [#acc.device_type<none>]}{{$}}
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -541,10 +541,10 @@ subroutine acc_serial_loop
|
||||
END DO
|
||||
|
||||
! CHECK: acc.serial {
|
||||
! CHECK: acc.loop worker {
|
||||
! CHECK: acc.loop {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
! CHECK-NEXT: } attributes {worker = [#acc.device_type<none>]}{{$}}
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -574,7 +574,7 @@ subroutine acc_serial_loop
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: } attributes {collapse = 2 : i64}
|
||||
! CHECK-NEXT: } attributes {collapse = [2], collapseDeviceType = [#acc.device_type<none>]}
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
||||
@ -605,7 +605,7 @@ subroutine acc_serial_loop
|
||||
|
||||
! CHECK: acc.serial {
|
||||
! CHECK: [[TILESIZE:%.*]] = arith.constant 2 : i32
|
||||
! CHECK: acc.loop tile([[TILESIZE]] : i32) {
|
||||
! CHECK: acc.loop tile({[[TILESIZE]] : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -619,7 +619,7 @@ subroutine acc_serial_loop
|
||||
|
||||
! CHECK: acc.serial {
|
||||
! CHECK: [[TILESIZEM1:%.*]] = arith.constant -1 : i32
|
||||
! CHECK: acc.loop tile([[TILESIZEM1]] : i32) {
|
||||
! CHECK: acc.loop tile({[[TILESIZEM1]] : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -636,7 +636,7 @@ subroutine acc_serial_loop
|
||||
! CHECK: acc.serial {
|
||||
! CHECK: [[TILESIZE1:%.*]] = arith.constant 2 : i32
|
||||
! CHECK: [[TILESIZE2:%.*]] = arith.constant 2 : i32
|
||||
! CHECK: acc.loop tile([[TILESIZE1]], [[TILESIZE2]] : i32, i32) {
|
||||
! CHECK: acc.loop tile({[[TILESIZE1]] : i32, [[TILESIZE2]] : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -649,7 +649,7 @@ subroutine acc_serial_loop
|
||||
END DO
|
||||
|
||||
! CHECK: acc.serial {
|
||||
! CHECK: acc.loop tile(%{{.*}} : i32) {
|
||||
! CHECK: acc.loop tile({%{{.*}} : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
@ -664,7 +664,7 @@ subroutine acc_serial_loop
|
||||
END DO
|
||||
|
||||
! CHECK: acc.serial {
|
||||
! CHECK: acc.loop tile(%{{.*}}, %{{.*}} : i32, i32) {
|
||||
! CHECK: acc.loop tile({%{{.*}} : i32, %{{.*}} : i32}) {
|
||||
! CHECK: fir.do_loop
|
||||
! CHECK: acc.yield
|
||||
! CHECK-NEXT: }{{$}}
|
||||
|
@ -196,6 +196,27 @@ def DeviceTypeArrayAttr :
|
||||
let constBuilderCall = ?;
|
||||
}
|
||||
|
||||
// Gang arg type enumeration
|
||||
def OpenACC_GangArgNum : I32EnumAttrCase<"Num", 0, "Num">;
|
||||
def OpenACC_GangArgDim : I32EnumAttrCase<"Dim", 1, "Dim">;
|
||||
def OpenACC_GangArgStatic : I32EnumAttrCase<"Static", 2, "Static">;
|
||||
|
||||
def OpenACC_GangArgType : I32EnumAttr<"GangArgType",
|
||||
"Differentiate the different gang arg values",
|
||||
[OpenACC_GangArgNum, OpenACC_GangArgDim, OpenACC_GangArgStatic]> {
|
||||
let genSpecializedAttr = 0;
|
||||
let cppNamespace = "::mlir::acc";
|
||||
}
|
||||
def OpenACC_GangArgTypeAttr : EnumAttr<OpenACC_Dialect,
|
||||
OpenACC_GangArgType,
|
||||
"gang_arg_type"> {
|
||||
let assemblyFormat = [{ ```<` $value `>` }];
|
||||
}
|
||||
def GangArgTypeArrayAttr :
|
||||
TypedArrayAttrBase<OpenACC_GangArgTypeAttr, "gang arg type array attribute"> {
|
||||
let constBuilderCall = ?;
|
||||
}
|
||||
|
||||
// Define a resource for the OpenACC runtime counters.
|
||||
def OpenACC_RuntimeCounters : Resource<"::mlir::acc::RuntimeCounters">;
|
||||
|
||||
@ -1462,7 +1483,7 @@ def OpenACC_LoopOp : OpenACC_Op<"loop",
|
||||
Example:
|
||||
|
||||
```mlir
|
||||
acc.loop gang vector {
|
||||
acc.loop {
|
||||
scf.for %arg3 = %c0 to %c10 step %c1 {
|
||||
scf.for %arg4 = %c0 to %c10 step %c1 {
|
||||
scf.for %arg5 = %c0 to %c10 step %c1 {
|
||||
@ -1471,23 +1492,33 @@ def OpenACC_LoopOp : OpenACC_Op<"loop",
|
||||
}
|
||||
}
|
||||
acc.yield
|
||||
} attributes { collapse = 3 }
|
||||
} attributes {
|
||||
collapse = [3], gang = [#acc.device_type<none>],
|
||||
vector = [#acc.device_type<none>]
|
||||
}
|
||||
```
|
||||
}];
|
||||
|
||||
let arguments = (ins OptionalAttr<I64Attr>:$collapse,
|
||||
Optional<IntOrIndex>:$gangNum,
|
||||
Optional<IntOrIndex>:$gangDim,
|
||||
Optional<IntOrIndex>:$gangStatic,
|
||||
Optional<IntOrIndex>:$workerNum,
|
||||
Optional<IntOrIndex>:$vectorLength,
|
||||
UnitAttr:$seq,
|
||||
UnitAttr:$independent,
|
||||
UnitAttr:$auto_,
|
||||
UnitAttr:$hasGang,
|
||||
UnitAttr:$hasWorker,
|
||||
UnitAttr:$hasVector,
|
||||
let arguments = (ins
|
||||
OptionalAttr<I64ArrayAttr>:$collapse,
|
||||
OptionalAttr<DeviceTypeArrayAttr>:$collapseDeviceType,
|
||||
Variadic<IntOrIndex>:$gangOperands,
|
||||
OptionalAttr<GangArgTypeArrayAttr>:$gangOperandsArgType,
|
||||
OptionalAttr<DenseI32ArrayAttr>:$gangOperandsSegments,
|
||||
OptionalAttr<DeviceTypeArrayAttr>:$gangOperandsDeviceType,
|
||||
Variadic<IntOrIndex>:$workerNumOperands,
|
||||
OptionalAttr<DeviceTypeArrayAttr>:$workerNumOperandsDeviceType,
|
||||
Variadic<IntOrIndex>:$vectorOperands,
|
||||
OptionalAttr<DeviceTypeArrayAttr>:$vectorOperandsDeviceType,
|
||||
OptionalAttr<DeviceTypeArrayAttr>:$seq,
|
||||
OptionalAttr<DeviceTypeArrayAttr>:$independent,
|
||||
OptionalAttr<DeviceTypeArrayAttr>:$auto_,
|
||||
OptionalAttr<DeviceTypeArrayAttr>:$gang,
|
||||
OptionalAttr<DeviceTypeArrayAttr>:$worker,
|
||||
OptionalAttr<DeviceTypeArrayAttr>:$vector,
|
||||
Variadic<IntOrIndex>:$tileOperands,
|
||||
OptionalAttr<DenseI32ArrayAttr>:$tileOperandsSegments,
|
||||
OptionalAttr<DeviceTypeArrayAttr>:$tileOperandsDeviceType,
|
||||
Variadic<OpenACC_PointerLikeTypeInterface>:$cacheOperands,
|
||||
Variadic<OpenACC_PointerLikeTypeInterface>:$privateOperands,
|
||||
OptionalAttr<SymbolRefArrayAttr>:$privatizations,
|
||||
@ -1510,18 +1541,90 @@ def OpenACC_LoopOp : OpenACC_Op<"loop",
|
||||
|
||||
/// The i-th data operand passed.
|
||||
Value getDataOperand(unsigned i);
|
||||
|
||||
/// Return true if the op has the auto attribute for the
|
||||
/// mlir::acc::DeviceType::None device_type.
|
||||
bool hasAuto();
|
||||
/// Return true if the op has the auto attribute for the given device_type.
|
||||
bool hasAuto(mlir::acc::DeviceType deviceType);
|
||||
/// Return true if the op has the independent attribute for the
|
||||
/// mlir::acc::DeviceType::None device_type.
|
||||
bool hasIndependent();
|
||||
/// Return true if the op has the independent attribute for the given
|
||||
/// device_type.
|
||||
bool hasIndependent(mlir::acc::DeviceType deviceType);
|
||||
/// Return true if the op has the seq attribute for the
|
||||
/// mlir::acc::DeviceType::None device_type.
|
||||
bool hasSeq();
|
||||
/// Return true if the op has the seq attribute for the given device_type.
|
||||
bool hasSeq(mlir::acc::DeviceType deviceType);
|
||||
|
||||
/// Return the value of the vector clause if present.
|
||||
mlir::Value getVectorValue();
|
||||
/// Return the value of the vector clause for the given device_type
|
||||
/// if present.
|
||||
mlir::Value getVectorValue(mlir::acc::DeviceType deviceType);
|
||||
/// Return true if the op has the vector attribute for the
|
||||
/// mlir::acc::DeviceType::None device_type.
|
||||
bool hasVector();
|
||||
/// Return true if the op has the vector attribute for the given
|
||||
/// device_type.
|
||||
bool hasVector(mlir::acc::DeviceType deviceType);
|
||||
|
||||
/// Return the value of the worker clause if present.
|
||||
mlir::Value getWorkerValue();
|
||||
/// Return the value of the worker clause for the given device_type
|
||||
/// if present.
|
||||
mlir::Value getWorkerValue(mlir::acc::DeviceType deviceType);
|
||||
/// Return true if the op has the worker attribute for the
|
||||
/// mlir::acc::DeviceType::None device_type.
|
||||
bool hasWorker();
|
||||
/// Return true if the op has the worker attribute for the given
|
||||
/// device_type.
|
||||
bool hasWorker(mlir::acc::DeviceType deviceType);
|
||||
|
||||
/// Return the values of the tile clause if present.
|
||||
mlir::Operation::operand_range getTileValues();
|
||||
/// Return the values of the tile clause for the given device_type if
|
||||
/// present.
|
||||
mlir::Operation::operand_range
|
||||
getTileValues(mlir::acc::DeviceType deviceType);
|
||||
|
||||
/// Return the value of the collapse clause if present.
|
||||
std::optional<int64_t> getCollapseValue();
|
||||
/// Return the value of the collapse clause for the given device_type
|
||||
/// if present.
|
||||
std::optional<int64_t> getCollapseValue(mlir::acc::DeviceType deviceType);
|
||||
|
||||
/// Return true if the op has the gang attribute for the
|
||||
/// mlir::acc::DeviceType::None device_type.
|
||||
bool hasGang();
|
||||
/// Return true if the op has the gang attribute for the given
|
||||
/// device_type.
|
||||
bool hasGang(mlir::acc::DeviceType deviceType);
|
||||
|
||||
/// Return the value of the worker clause if present.
|
||||
mlir::Value getGangValue(mlir::acc::GangArgType gangArgType);
|
||||
/// Return the value of the worker clause for the given device_type
|
||||
/// if present.
|
||||
mlir::Value getGangValue(mlir::acc::GangArgType gangArgType, mlir::acc::DeviceType deviceType);
|
||||
}];
|
||||
|
||||
let hasCustomAssemblyFormat = 1;
|
||||
let assemblyFormat = [{
|
||||
oilist(
|
||||
`gang` `` custom<GangClause>($gangNum, type($gangNum), $gangDim, type($gangDim), $gangStatic, type($gangStatic), $hasGang)
|
||||
| `worker` `` custom<WorkerClause>($workerNum, type($workerNum), $hasWorker)
|
||||
| `vector` `` custom<VectorClause>($vectorLength, type($vectorLength), $hasVector)
|
||||
`gang` `` `(` custom<GangClause>($gangOperands, type($gangOperands),
|
||||
$gangOperandsArgType, $gangOperandsDeviceType,
|
||||
$gangOperandsSegments) `)`
|
||||
| `worker` `` `(` custom<DeviceTypeOperands>($workerNumOperands,
|
||||
type($workerNumOperands), $workerNumOperandsDeviceType) `)`
|
||||
| `vector` `` `(` custom<DeviceTypeOperands>($vectorOperands,
|
||||
type($vectorOperands), $vectorOperandsDeviceType) `)`
|
||||
| `private` `(` custom<SymOperandList>(
|
||||
$privateOperands, type($privateOperands), $privatizations)
|
||||
$privateOperands, type($privateOperands), $privatizations) `)`
|
||||
| `tile` `(` custom<DeviceTypeOperandsWithSegment>($tileOperands,
|
||||
type($tileOperands), $tileOperandsDeviceType, $tileOperandsSegments)
|
||||
`)`
|
||||
| `tile` `(` $tileOperands `:` type($tileOperands) `)`
|
||||
| `reduction` `(` custom<SymOperandList>(
|
||||
$reductionOperands, type($reductionOperands), $reductionRecipes)
|
||||
`)`
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "mlir/IR/Matchers.h"
|
||||
#include "mlir/IR/OpImplementation.h"
|
||||
#include "mlir/Transforms/DialectConversion.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/TypeSwitch.h"
|
||||
|
||||
using namespace mlir;
|
||||
@ -886,6 +887,8 @@ static ParseResult parseDeviceTypeOperandsWithSegment(
|
||||
if (failed(parser.parseLBrace()))
|
||||
return failure();
|
||||
|
||||
int32_t crtOperandsSize = operands.size();
|
||||
|
||||
if (failed(parser.parseCommaSeparatedList(
|
||||
mlir::AsmParser::Delimiter::None, [&]() {
|
||||
if (parser.parseOperand(operands.emplace_back()) ||
|
||||
@ -895,7 +898,7 @@ static ParseResult parseDeviceTypeOperandsWithSegment(
|
||||
})))
|
||||
return failure();
|
||||
|
||||
seg.push_back(operands.size());
|
||||
seg.push_back(operands.size() - crtOperandsSize);
|
||||
|
||||
if (failed(parser.parseRBrace()))
|
||||
return failure();
|
||||
@ -1207,16 +1210,19 @@ void acc::HostDataOp::getCanonicalizationPatterns(RewritePatternSet &results,
|
||||
// LoopOp
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static ParseResult
|
||||
parseGangValue(OpAsmParser &parser, llvm::StringRef keyword,
|
||||
std::optional<OpAsmParser::UnresolvedOperand> &value,
|
||||
Type &valueType, bool &needComa, bool &newValue) {
|
||||
static ParseResult parseGangValue(
|
||||
OpAsmParser &parser, llvm::StringRef keyword,
|
||||
llvm::SmallVectorImpl<mlir::OpAsmParser::UnresolvedOperand> &operands,
|
||||
llvm::SmallVectorImpl<Type> &types,
|
||||
llvm::SmallVector<GangArgTypeAttr> &attributes, GangArgTypeAttr gangArgType,
|
||||
bool &needComa, bool &newValue) {
|
||||
if (succeeded(parser.parseOptionalKeyword(keyword))) {
|
||||
if (parser.parseEqual())
|
||||
return failure();
|
||||
value = OpAsmParser::UnresolvedOperand{};
|
||||
if (parser.parseOperand(*value) || parser.parseColonType(valueType))
|
||||
if (parser.parseOperand(operands.emplace_back()) ||
|
||||
parser.parseColonType(types.emplace_back()))
|
||||
return failure();
|
||||
attributes.push_back(gangArgType);
|
||||
needComa = true;
|
||||
newValue = true;
|
||||
}
|
||||
@ -1224,19 +1230,27 @@ parseGangValue(OpAsmParser &parser, llvm::StringRef keyword,
|
||||
}
|
||||
|
||||
static ParseResult parseGangClause(
|
||||
OpAsmParser &parser, std::optional<OpAsmParser::UnresolvedOperand> &gangNum,
|
||||
Type &gangNumType, std::optional<OpAsmParser::UnresolvedOperand> &gangDim,
|
||||
Type &gangDimType,
|
||||
std::optional<OpAsmParser::UnresolvedOperand> &gangStatic,
|
||||
Type &gangStaticType, UnitAttr &hasGang) {
|
||||
hasGang = UnitAttr::get(parser.getBuilder().getContext());
|
||||
gangNum = std::nullopt;
|
||||
gangDim = std::nullopt;
|
||||
gangStatic = std::nullopt;
|
||||
OpAsmParser &parser,
|
||||
llvm::SmallVectorImpl<mlir::OpAsmParser::UnresolvedOperand> &gangOperands,
|
||||
llvm::SmallVectorImpl<Type> &gangOperandsType, mlir::ArrayAttr &gangArgType,
|
||||
mlir::ArrayAttr &deviceType, mlir::DenseI32ArrayAttr &segments) {
|
||||
llvm::SmallVector<GangArgTypeAttr> attributes;
|
||||
llvm::SmallVector<DeviceTypeAttr> deviceTypeAttributes;
|
||||
llvm::SmallVector<int32_t> seg;
|
||||
bool needComa = false;
|
||||
|
||||
// optional gang operands
|
||||
if (succeeded(parser.parseOptionalLParen())) {
|
||||
auto argNum = mlir::acc::GangArgTypeAttr::get(parser.getContext(),
|
||||
mlir::acc::GangArgType::Num);
|
||||
auto argDim = mlir::acc::GangArgTypeAttr::get(parser.getContext(),
|
||||
mlir::acc::GangArgType::Dim);
|
||||
auto argStatic = mlir::acc::GangArgTypeAttr::get(
|
||||
parser.getContext(), mlir::acc::GangArgType::Static);
|
||||
|
||||
do {
|
||||
if (failed(parser.parseLBrace()))
|
||||
return failure();
|
||||
|
||||
int32_t crtOperandsSize = gangOperands.size();
|
||||
while (true) {
|
||||
bool newValue = false;
|
||||
bool needValue = false;
|
||||
@ -1247,15 +1261,17 @@ static ParseResult parseGangClause(
|
||||
break;
|
||||
}
|
||||
|
||||
if (failed(parseGangValue(parser, LoopOp::getGangNumKeyword(), gangNum,
|
||||
gangNumType, needComa, newValue)))
|
||||
if (failed(parseGangValue(parser, LoopOp::getGangNumKeyword(),
|
||||
gangOperands, gangOperandsType, attributes,
|
||||
argNum, needComa, newValue)))
|
||||
return failure();
|
||||
if (failed(parseGangValue(parser, LoopOp::getGangDimKeyword(), gangDim,
|
||||
gangDimType, needComa, newValue)))
|
||||
if (failed(parseGangValue(parser, LoopOp::getGangDimKeyword(),
|
||||
gangOperands, gangOperandsType, attributes,
|
||||
argDim, needComa, newValue)))
|
||||
return failure();
|
||||
if (failed(parseGangValue(parser, LoopOp::getGangStaticKeyword(),
|
||||
gangStatic, gangStaticType, needComa,
|
||||
newValue)))
|
||||
gangOperands, gangOperandsType, attributes,
|
||||
argStatic, needComa, newValue)))
|
||||
return failure();
|
||||
|
||||
if (!newValue && needValue) {
|
||||
@ -1268,86 +1284,168 @@ static ParseResult parseGangClause(
|
||||
break;
|
||||
}
|
||||
|
||||
if (!gangNum && !gangDim && !gangStatic) {
|
||||
parser.emitError(parser.getCurrentLocation(),
|
||||
"expect at least one of num, dim or static values");
|
||||
if (gangOperands.empty())
|
||||
return parser.emitError(
|
||||
parser.getCurrentLocation(),
|
||||
"expect at least one of num, dim or static values");
|
||||
|
||||
if (failed(parser.parseRBrace()))
|
||||
return failure();
|
||||
|
||||
if (succeeded(parser.parseOptionalLSquare())) {
|
||||
if (parser.parseAttribute(deviceTypeAttributes.emplace_back()) ||
|
||||
parser.parseRSquare())
|
||||
return failure();
|
||||
} else {
|
||||
deviceTypeAttributes.push_back(mlir::acc::DeviceTypeAttr::get(
|
||||
parser.getContext(), mlir::acc::DeviceType::None));
|
||||
}
|
||||
|
||||
if (failed(parser.parseRParen()))
|
||||
return failure();
|
||||
}
|
||||
seg.push_back(gangOperands.size() - crtOperandsSize);
|
||||
|
||||
} while (succeeded(parser.parseOptionalComma()));
|
||||
|
||||
llvm::SmallVector<mlir::Attribute> arrayAttr(attributes.begin(),
|
||||
attributes.end());
|
||||
gangArgType = ArrayAttr::get(parser.getContext(), arrayAttr);
|
||||
|
||||
llvm::SmallVector<mlir::Attribute> deviceTypeAttr(
|
||||
deviceTypeAttributes.begin(), deviceTypeAttributes.end());
|
||||
deviceType = ArrayAttr::get(parser.getContext(), deviceTypeAttr);
|
||||
segments = DenseI32ArrayAttr::get(parser.getContext(), seg);
|
||||
return success();
|
||||
}
|
||||
|
||||
void printGangClause(OpAsmPrinter &p, Operation *op, Value gangNum,
|
||||
Type gangNumType, Value gangDim, Type gangDimType,
|
||||
Value gangStatic, Type gangStaticType, UnitAttr hasGang) {
|
||||
if (gangNum || gangStatic || gangDim) {
|
||||
p << "(";
|
||||
if (gangNum) {
|
||||
p << LoopOp::getGangNumKeyword() << "=" << gangNum << " : "
|
||||
<< gangNumType;
|
||||
if (gangStatic || gangDim)
|
||||
void printGangClause(OpAsmPrinter &p, Operation *op,
|
||||
mlir::OperandRange operands, mlir::TypeRange types,
|
||||
std::optional<mlir::ArrayAttr> gangArgTypes,
|
||||
std::optional<mlir::ArrayAttr> deviceTypes,
|
||||
std::optional<mlir::DenseI32ArrayAttr> segments) {
|
||||
unsigned opIdx = 0;
|
||||
for (unsigned i = 0; i < deviceTypes->size(); ++i) {
|
||||
if (i != 0)
|
||||
p << ", ";
|
||||
p << "{";
|
||||
for (int32_t j = 0; j < (*segments)[i]; ++j) {
|
||||
if (j != 0)
|
||||
p << ", ";
|
||||
auto gangArgTypeAttr =
|
||||
mlir::dyn_cast<mlir::acc::GangArgTypeAttr>((*gangArgTypes)[opIdx]);
|
||||
if (gangArgTypeAttr.getValue() == mlir::acc::GangArgType::Num)
|
||||
p << LoopOp::getGangNumKeyword();
|
||||
else if (gangArgTypeAttr.getValue() == mlir::acc::GangArgType::Dim)
|
||||
p << LoopOp::getGangDimKeyword();
|
||||
else if (gangArgTypeAttr.getValue() == mlir::acc::GangArgType::Static)
|
||||
p << LoopOp::getGangStaticKeyword();
|
||||
p << "=" << operands[opIdx] << " : " << operands[opIdx].getType();
|
||||
++opIdx;
|
||||
}
|
||||
if (gangDim) {
|
||||
p << LoopOp::getGangDimKeyword() << "=" << gangDim << " : "
|
||||
<< gangDimType;
|
||||
if (gangStatic)
|
||||
p << ", ";
|
||||
}
|
||||
if (gangStatic)
|
||||
p << LoopOp::getGangStaticKeyword() << "=" << gangStatic << " : "
|
||||
<< gangStaticType;
|
||||
p << ")";
|
||||
|
||||
p << "}";
|
||||
auto deviceTypeAttr =
|
||||
mlir::dyn_cast<mlir::acc::DeviceTypeAttr>((*deviceTypes)[i]);
|
||||
if (deviceTypeAttr.getValue() != mlir::acc::DeviceType::None)
|
||||
p << " [" << (*deviceTypes)[i] << "]";
|
||||
}
|
||||
}
|
||||
|
||||
static ParseResult
|
||||
parseWorkerClause(OpAsmParser &parser,
|
||||
std::optional<OpAsmParser::UnresolvedOperand> &workerNum,
|
||||
Type &workerNumType, UnitAttr &hasWorker) {
|
||||
hasWorker = UnitAttr::get(parser.getBuilder().getContext());
|
||||
if (succeeded(parser.parseOptionalLParen())) {
|
||||
workerNum = OpAsmParser::UnresolvedOperand{};
|
||||
if (parser.parseOperand(*workerNum) ||
|
||||
parser.parseColonType(workerNumType) || parser.parseRParen())
|
||||
bool hasDuplicateDeviceTypes(
|
||||
std::optional<mlir::ArrayAttr> segments,
|
||||
llvm::SmallSet<mlir::acc::DeviceType, 3> &deviceTypes) {
|
||||
if (!segments)
|
||||
return false;
|
||||
for (auto attr : *segments) {
|
||||
auto deviceTypeAttr = mlir::dyn_cast<mlir::acc::DeviceTypeAttr>(attr);
|
||||
if (deviceTypes.contains(deviceTypeAttr.getValue()))
|
||||
return true;
|
||||
deviceTypes.insert(deviceTypeAttr.getValue());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Check for duplicates in the DeviceType array attribute.
|
||||
LogicalResult checkDeviceTypes(mlir::ArrayAttr deviceTypes) {
|
||||
llvm::SmallSet<mlir::acc::DeviceType, 3> crtDeviceTypes;
|
||||
if (!deviceTypes)
|
||||
return success();
|
||||
for (auto attr : deviceTypes) {
|
||||
auto deviceTypeAttr =
|
||||
mlir::dyn_cast_or_null<mlir::acc::DeviceTypeAttr>(attr);
|
||||
if (!deviceTypeAttr)
|
||||
return failure();
|
||||
if (crtDeviceTypes.contains(deviceTypeAttr.getValue()))
|
||||
return failure();
|
||||
crtDeviceTypes.insert(deviceTypeAttr.getValue());
|
||||
}
|
||||
return success();
|
||||
}
|
||||
|
||||
void printWorkerClause(OpAsmPrinter &p, Operation *op, Value workerNum,
|
||||
Type workerNumType, UnitAttr hasWorker) {
|
||||
if (workerNum)
|
||||
p << "(" << workerNum << " : " << workerNumType << ")";
|
||||
}
|
||||
|
||||
static ParseResult
|
||||
parseVectorClause(OpAsmParser &parser,
|
||||
std::optional<OpAsmParser::UnresolvedOperand> &vectorLength,
|
||||
Type &vectorLengthType, UnitAttr &hasVector) {
|
||||
hasVector = UnitAttr::get(parser.getBuilder().getContext());
|
||||
if (succeeded(parser.parseOptionalLParen())) {
|
||||
vectorLength = OpAsmParser::UnresolvedOperand{};
|
||||
if (parser.parseOperand(*vectorLength) ||
|
||||
parser.parseColonType(vectorLengthType) || parser.parseRParen())
|
||||
return failure();
|
||||
}
|
||||
return success();
|
||||
}
|
||||
|
||||
void printVectorClause(OpAsmPrinter &p, Operation *op, Value vectorLength,
|
||||
Type vectorLengthType, UnitAttr hasVector) {
|
||||
if (vectorLength)
|
||||
p << "(" << vectorLength << " : " << vectorLengthType << ")";
|
||||
}
|
||||
|
||||
LogicalResult acc::LoopOp::verify() {
|
||||
// Check collapse
|
||||
if (getCollapseAttr() && !getCollapseDeviceTypeAttr())
|
||||
return emitOpError() << "collapse device_type attr must be define when"
|
||||
<< " collapse attr is present";
|
||||
|
||||
if (getCollapseAttr() && getCollapseDeviceTypeAttr() &&
|
||||
getCollapseAttr().getValue().size() !=
|
||||
getCollapseDeviceTypeAttr().getValue().size())
|
||||
return emitOpError() << "collapse attribute count must match collapse"
|
||||
<< " device_type count";
|
||||
if (failed(checkDeviceTypes(getCollapseDeviceTypeAttr())))
|
||||
return emitOpError()
|
||||
<< "duplicate device_type found in collapseDeviceType attribute";
|
||||
|
||||
// Check gang
|
||||
if (!getGangOperands().empty()) {
|
||||
if (!getGangOperandsArgType())
|
||||
return emitOpError() << "gangOperandsArgType attribute must be defined"
|
||||
<< " when gang operands are present";
|
||||
|
||||
if (getGangOperands().size() !=
|
||||
getGangOperandsArgTypeAttr().getValue().size())
|
||||
return emitOpError() << "gangOperandsArgType attribute count must match"
|
||||
<< " gangOperands count";
|
||||
}
|
||||
if (getGangAttr() && failed(checkDeviceTypes(getGangAttr())))
|
||||
return emitOpError() << "duplicate device_type found in gang attribute";
|
||||
|
||||
if (failed(verifyDeviceTypeAndSegmentCountMatch(
|
||||
*this, getGangOperands(), getGangOperandsSegmentsAttr(),
|
||||
getGangOperandsDeviceTypeAttr(), "gang")))
|
||||
return failure();
|
||||
|
||||
// Check worker
|
||||
if (failed(checkDeviceTypes(getWorkerAttr())))
|
||||
return emitOpError() << "duplicate device_type found in worker attribute";
|
||||
if (failed(checkDeviceTypes(getWorkerNumOperandsDeviceTypeAttr())))
|
||||
return emitOpError() << "duplicate device_type found in "
|
||||
"workerNumOperandsDeviceType attribute";
|
||||
if (failed(verifyDeviceTypeCountMatch(*this, getWorkerNumOperands(),
|
||||
getWorkerNumOperandsDeviceTypeAttr(),
|
||||
"worker")))
|
||||
return failure();
|
||||
|
||||
// Check vector
|
||||
if (failed(checkDeviceTypes(getVectorAttr())))
|
||||
return emitOpError() << "duplicate device_type found in vector attribute";
|
||||
if (failed(checkDeviceTypes(getVectorOperandsDeviceTypeAttr())))
|
||||
return emitOpError() << "duplicate device_type found in "
|
||||
"vectorOperandsDeviceType attribute";
|
||||
if (failed(verifyDeviceTypeCountMatch(*this, getVectorOperands(),
|
||||
getVectorOperandsDeviceTypeAttr(),
|
||||
"vector")))
|
||||
return failure();
|
||||
|
||||
if (failed(verifyDeviceTypeAndSegmentCountMatch(
|
||||
*this, getTileOperands(), getTileOperandsSegmentsAttr(),
|
||||
getTileOperandsDeviceTypeAttr(), "tile")))
|
||||
return failure();
|
||||
|
||||
// auto, independent and seq attribute are mutually exclusive.
|
||||
if ((getAuto_() && (getIndependent() || getSeq())) ||
|
||||
(getIndependent() && getSeq())) {
|
||||
llvm::SmallSet<mlir::acc::DeviceType, 3> deviceTypes;
|
||||
if (hasDuplicateDeviceTypes(getAuto_(), deviceTypes) ||
|
||||
hasDuplicateDeviceTypes(getIndependent(), deviceTypes) ||
|
||||
hasDuplicateDeviceTypes(getSeq(), deviceTypes)) {
|
||||
return emitError() << "only one of \"" << acc::LoopOp::getAutoAttrStrName()
|
||||
<< "\", " << getIndependentAttrName() << ", "
|
||||
<< getSeqAttrName()
|
||||
@ -1355,8 +1453,24 @@ LogicalResult acc::LoopOp::verify() {
|
||||
}
|
||||
|
||||
// Gang, worker and vector are incompatible with seq.
|
||||
if (getSeq() && (getHasGang() || getHasWorker() || getHasVector()))
|
||||
return emitError("gang, worker or vector cannot appear with the seq attr");
|
||||
if (getSeqAttr()) {
|
||||
for (auto attr : getSeqAttr()) {
|
||||
auto deviceTypeAttr = mlir::dyn_cast<mlir::acc::DeviceTypeAttr>(attr);
|
||||
if (hasVector(deviceTypeAttr.getValue()) ||
|
||||
getVectorValue(deviceTypeAttr.getValue()) ||
|
||||
hasWorker(deviceTypeAttr.getValue()) ||
|
||||
getWorkerValue(deviceTypeAttr.getValue()) ||
|
||||
hasGang(deviceTypeAttr.getValue()) ||
|
||||
getGangValue(mlir::acc::GangArgType::Num,
|
||||
deviceTypeAttr.getValue()) ||
|
||||
getGangValue(mlir::acc::GangArgType::Dim,
|
||||
deviceTypeAttr.getValue()) ||
|
||||
getGangValue(mlir::acc::GangArgType::Static,
|
||||
deviceTypeAttr.getValue()))
|
||||
return emitError()
|
||||
<< "gang, worker or vector cannot appear with the seq attr";
|
||||
}
|
||||
}
|
||||
|
||||
if (failed(checkSymOperandList<mlir::acc::PrivateRecipeOp>(
|
||||
*this, getPrivatizations(), getPrivateOperands(), "private",
|
||||
@ -1380,16 +1494,149 @@ unsigned LoopOp::getNumDataOperands() {
|
||||
}
|
||||
|
||||
Value LoopOp::getDataOperand(unsigned i) {
|
||||
unsigned numOptional = getGangNum() ? 1 : 0;
|
||||
numOptional += getGangDim() ? 1 : 0;
|
||||
numOptional += getGangStatic() ? 1 : 0;
|
||||
numOptional += getVectorLength() ? 1 : 0;
|
||||
numOptional += getWorkerNum() ? 1 : 0;
|
||||
unsigned numOptional = getGangOperands().size();
|
||||
numOptional += getVectorOperands().size();
|
||||
numOptional += getWorkerNumOperands().size();
|
||||
numOptional += getTileOperands().size();
|
||||
numOptional += getCacheOperands().size();
|
||||
return getOperand(numOptional + i);
|
||||
}
|
||||
|
||||
bool LoopOp::hasAuto() { return hasAuto(mlir::acc::DeviceType::None); }
|
||||
|
||||
bool LoopOp::hasAuto(mlir::acc::DeviceType deviceType) {
|
||||
if (auto arrayAttr = getAuto_()) {
|
||||
if (findSegment(*arrayAttr, deviceType))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LoopOp::hasIndependent() {
|
||||
return hasIndependent(mlir::acc::DeviceType::None);
|
||||
}
|
||||
|
||||
bool LoopOp::hasIndependent(mlir::acc::DeviceType deviceType) {
|
||||
if (auto arrayAttr = getIndependent()) {
|
||||
if (findSegment(*arrayAttr, deviceType))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LoopOp::hasSeq() { return hasSeq(mlir::acc::DeviceType::None); }
|
||||
|
||||
bool LoopOp::hasSeq(mlir::acc::DeviceType deviceType) {
|
||||
if (auto arrayAttr = getSeq()) {
|
||||
if (findSegment(*arrayAttr, deviceType))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
mlir::Value LoopOp::getVectorValue() {
|
||||
return getVectorValue(mlir::acc::DeviceType::None);
|
||||
}
|
||||
|
||||
mlir::Value LoopOp::getVectorValue(mlir::acc::DeviceType deviceType) {
|
||||
return getValueInDeviceTypeSegment(getVectorOperandsDeviceType(),
|
||||
getVectorOperands(), deviceType);
|
||||
}
|
||||
|
||||
bool LoopOp::hasVector() { return hasVector(mlir::acc::DeviceType::None); }
|
||||
|
||||
bool LoopOp::hasVector(mlir::acc::DeviceType deviceType) {
|
||||
if (auto arrayAttr = getVector()) {
|
||||
if (findSegment(*arrayAttr, deviceType))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
mlir::Value LoopOp::getWorkerValue() {
|
||||
return getWorkerValue(mlir::acc::DeviceType::None);
|
||||
}
|
||||
|
||||
mlir::Value LoopOp::getWorkerValue(mlir::acc::DeviceType deviceType) {
|
||||
return getValueInDeviceTypeSegment(getWorkerNumOperandsDeviceType(),
|
||||
getWorkerNumOperands(), deviceType);
|
||||
}
|
||||
|
||||
bool LoopOp::hasWorker() { return hasWorker(mlir::acc::DeviceType::None); }
|
||||
|
||||
bool LoopOp::hasWorker(mlir::acc::DeviceType deviceType) {
|
||||
if (auto arrayAttr = getWorker()) {
|
||||
if (findSegment(*arrayAttr, deviceType))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
mlir::Operation::operand_range LoopOp::getTileValues() {
|
||||
return getTileValues(mlir::acc::DeviceType::None);
|
||||
}
|
||||
|
||||
mlir::Operation::operand_range
|
||||
LoopOp::getTileValues(mlir::acc::DeviceType deviceType) {
|
||||
return getValuesFromSegments(getTileOperandsDeviceType(), getTileOperands(),
|
||||
getTileOperandsSegments(), deviceType);
|
||||
}
|
||||
|
||||
std::optional<int64_t> LoopOp::getCollapseValue() {
|
||||
return getCollapseValue(mlir::acc::DeviceType::None);
|
||||
}
|
||||
|
||||
std::optional<int64_t>
|
||||
LoopOp::getCollapseValue(mlir::acc::DeviceType deviceType) {
|
||||
if (!getCollapseAttr())
|
||||
return std::nullopt;
|
||||
if (auto pos = findSegment(getCollapseDeviceTypeAttr(), deviceType)) {
|
||||
auto intAttr =
|
||||
mlir::dyn_cast<IntegerAttr>(getCollapseAttr().getValue()[*pos]);
|
||||
return intAttr.getValue().getZExtValue();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
mlir::Value LoopOp::getGangValue(mlir::acc::GangArgType gangArgType) {
|
||||
return getGangValue(gangArgType, mlir::acc::DeviceType::None);
|
||||
}
|
||||
|
||||
mlir::Value LoopOp::getGangValue(mlir::acc::GangArgType gangArgType,
|
||||
mlir::acc::DeviceType deviceType) {
|
||||
if (getGangOperands().empty())
|
||||
return {};
|
||||
if (auto pos = findSegment(*getGangOperandsDeviceType(), deviceType)) {
|
||||
int32_t nbOperandsBefore = 0;
|
||||
for (unsigned i = 0; i < *pos; ++i)
|
||||
nbOperandsBefore += (*getGangOperandsSegments())[i];
|
||||
mlir::Operation::operand_range values =
|
||||
getGangOperands()
|
||||
.drop_front(nbOperandsBefore)
|
||||
.take_front((*getGangOperandsSegments())[*pos]);
|
||||
|
||||
int32_t argTypeIdx = nbOperandsBefore;
|
||||
for (auto value : values) {
|
||||
auto gangArgTypeAttr = mlir::dyn_cast<mlir::acc::GangArgTypeAttr>(
|
||||
(*getGangOperandsArgType())[argTypeIdx]);
|
||||
if (gangArgTypeAttr.getValue() == gangArgType)
|
||||
return value;
|
||||
++argTypeIdx;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool LoopOp::hasGang() { return hasGang(mlir::acc::DeviceType::None); }
|
||||
|
||||
bool LoopOp::hasGang(mlir::acc::DeviceType deviceType) {
|
||||
if (auto arrayAttr = getGang()) {
|
||||
if (findSegment(*arrayAttr, deviceType))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// DataOp
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -1,58 +1,58 @@
|
||||
// RUN: mlir-opt -split-input-file -verify-diagnostics %s
|
||||
|
||||
// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
|
||||
acc.loop gang {
|
||||
acc.loop {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
} attributes {seq}
|
||||
} attributes {seq = [#acc.device_type<none>], gang = [#acc.device_type<none>]}
|
||||
|
||||
// -----
|
||||
|
||||
// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
|
||||
acc.loop worker {
|
||||
acc.loop {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
} attributes {seq}
|
||||
} attributes {seq = [#acc.device_type<none>], worker = [#acc.device_type<none>]}
|
||||
|
||||
// -----
|
||||
|
||||
// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
|
||||
acc.loop vector {
|
||||
acc.loop {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
} attributes {seq}
|
||||
} attributes {seq = [#acc.device_type<none>], vector = [#acc.device_type<none>]}
|
||||
|
||||
// -----
|
||||
|
||||
// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
|
||||
acc.loop gang worker {
|
||||
acc.loop {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
} attributes {seq}
|
||||
} attributes {seq = [#acc.device_type<none>], worker = [#acc.device_type<none>], gang = [#acc.device_type<none>]}
|
||||
|
||||
// -----
|
||||
|
||||
// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
|
||||
acc.loop gang vector {
|
||||
acc.loop {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
} attributes {seq}
|
||||
} attributes {seq = [#acc.device_type<none>], vector = [#acc.device_type<none>], gang = [#acc.device_type<none>]}
|
||||
|
||||
// -----
|
||||
|
||||
// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
|
||||
acc.loop worker vector {
|
||||
acc.loop {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
} attributes {seq}
|
||||
} attributes {seq = [#acc.device_type<none>], vector = [#acc.device_type<none>], worker = [#acc.device_type<none>]}
|
||||
|
||||
// -----
|
||||
|
||||
// expected-error@+1 {{gang, worker or vector cannot appear with the seq attr}}
|
||||
acc.loop gang worker vector {
|
||||
acc.loop {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
} attributes {seq}
|
||||
} attributes {seq = [#acc.device_type<none>], vector = [#acc.device_type<none>], worker = [#acc.device_type<none>], gang = [#acc.device_type<none>]}
|
||||
|
||||
// -----
|
||||
|
||||
@ -62,10 +62,31 @@ acc.loop {
|
||||
|
||||
// -----
|
||||
|
||||
// expected-error@+1 {{'acc.loop' op duplicate device_type found in gang attribute}}
|
||||
acc.loop {
|
||||
acc.yield
|
||||
} attributes {gang = [#acc.device_type<none>, #acc.device_type<none>]}
|
||||
|
||||
// -----
|
||||
|
||||
// expected-error@+1 {{'acc.loop' op duplicate device_type found in worker attribute}}
|
||||
acc.loop {
|
||||
acc.yield
|
||||
} attributes {worker = [#acc.device_type<none>, #acc.device_type<none>]}
|
||||
|
||||
// -----
|
||||
|
||||
// expected-error@+1 {{'acc.loop' op duplicate device_type found in vector attribute}}
|
||||
acc.loop {
|
||||
acc.yield
|
||||
} attributes {vector = [#acc.device_type<none>, #acc.device_type<none>]}
|
||||
|
||||
// -----
|
||||
|
||||
// expected-error@+1 {{only one of "auto", "independent", "seq" can be present at the same time}}
|
||||
acc.loop {
|
||||
acc.yield
|
||||
} attributes {auto_, seq}
|
||||
} attributes {auto_ = [#acc.device_type<none>], seq = [#acc.device_type<none>]}
|
||||
|
||||
// -----
|
||||
|
||||
@ -368,7 +389,7 @@ acc.firstprivate.recipe @privatization_i32 : i32 init {
|
||||
// -----
|
||||
|
||||
// expected-error@+1 {{expected ')'}}
|
||||
acc.loop gang(static=%i64Value: i64, num=%i64Value: i64 {
|
||||
acc.loop gang({static=%i64Value: i64, num=%i64Value: i64} {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
}
|
||||
@ -437,7 +458,7 @@ acc.reduction.recipe @reduction_i64 : i64 reduction_operator<add> init {
|
||||
// -----
|
||||
|
||||
// expected-error@+1 {{new value expected after comma}}
|
||||
acc.loop gang(static=%i64Value: i64, ) {
|
||||
acc.loop gang({static=%i64Value: i64, ) {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
}
|
||||
@ -454,7 +475,7 @@ func.func @fct1(%0 : !llvm.ptr) -> () {
|
||||
// -----
|
||||
|
||||
// expected-error@+1 {{expect at least one of num, dim or static values}}
|
||||
acc.loop gang() {
|
||||
acc.loop gang({}) {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ func.func @compute1(%A: memref<10x10xf32>, %B: memref<10x10xf32>, %C: memref<10x
|
||||
%async = arith.constant 1 : i64
|
||||
|
||||
acc.parallel async(%async: i64) {
|
||||
acc.loop gang vector {
|
||||
acc.loop {
|
||||
scf.for %arg3 = %c0 to %c10 step %c1 {
|
||||
scf.for %arg4 = %c0 to %c10 step %c1 {
|
||||
scf.for %arg5 = %c0 to %c10 step %c1 {
|
||||
@ -25,7 +25,7 @@ func.func @compute1(%A: memref<10x10xf32>, %B: memref<10x10xf32>, %C: memref<10x
|
||||
}
|
||||
}
|
||||
acc.yield
|
||||
} attributes { collapse = 3 }
|
||||
} attributes { collapse = [3], collapseDeviceType = [#acc.device_type<none>], vector = [#acc.device_type<none>], gang = [#acc.device_type<none>]}
|
||||
acc.yield
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ func.func @compute1(%A: memref<10x10xf32>, %B: memref<10x10xf32>, %C: memref<10x
|
||||
// CHECK-NEXT: %{{.*}} = arith.constant 1 : index
|
||||
// CHECK-NEXT: [[ASYNC:%.*]] = arith.constant 1 : i64
|
||||
// CHECK-NEXT: acc.parallel async([[ASYNC]] : i64) {
|
||||
// CHECK-NEXT: acc.loop gang vector {
|
||||
// CHECK-NEXT: acc.loop {
|
||||
// CHECK-NEXT: scf.for %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {
|
||||
// CHECK-NEXT: scf.for %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {
|
||||
// CHECK-NEXT: scf.for %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {
|
||||
@ -52,7 +52,7 @@ func.func @compute1(%A: memref<10x10xf32>, %B: memref<10x10xf32>, %C: memref<10x
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: } attributes {collapse = 3 : i64}
|
||||
// CHECK-NEXT: } attributes {collapse = [3], collapseDeviceType = [#acc.device_type<none>], gang = [#acc.device_type<none>], vector = [#acc.device_type<none>]}
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: return %{{.*}} : memref<10x10xf32>
|
||||
@ -80,7 +80,7 @@ func.func @compute2(%A: memref<10x10xf32>, %B: memref<10x10xf32>, %C: memref<10x
|
||||
}
|
||||
}
|
||||
acc.yield
|
||||
} attributes {seq}
|
||||
} attributes {seq = [#acc.device_type<none>]}
|
||||
acc.yield
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ func.func @compute2(%A: memref<10x10xf32>, %B: memref<10x10xf32>, %C: memref<10x
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: } attributes {seq}
|
||||
// CHECK-NEXT: } attributes {seq = [#acc.device_type<none>]}
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: return %{{.*}} : memref<10x10xf32>
|
||||
@ -138,9 +138,9 @@ func.func @compute3(%a: memref<10x10xf32>, %b: memref<10x10xf32>, %c: memref<10x
|
||||
acc.data dataOperands(%pa, %pb, %pc, %pd: memref<10x10xf32>, memref<10x10xf32>, memref<10xf32>, memref<10xf32>) {
|
||||
%private = acc.private varPtr(%c : memref<10xf32>) -> memref<10xf32>
|
||||
acc.parallel num_gangs({%numGangs: i64}) num_workers(%numWorkers: i64 [#acc.device_type<nvidia>]) private(@privatization_memref_10_f32 -> %private : memref<10xf32>) {
|
||||
acc.loop gang {
|
||||
acc.loop {
|
||||
scf.for %x = %lb to %c10 step %st {
|
||||
acc.loop worker {
|
||||
acc.loop {
|
||||
scf.for %y = %lb to %c10 step %st {
|
||||
%axy = memref.load %a[%x, %y] : memref<10x10xf32>
|
||||
%bxy = memref.load %b[%x, %y] : memref<10x10xf32>
|
||||
@ -148,7 +148,7 @@ func.func @compute3(%a: memref<10x10xf32>, %b: memref<10x10xf32>, %c: memref<10x
|
||||
memref.store %tmp, %c[%y] : memref<10xf32>
|
||||
}
|
||||
acc.yield
|
||||
}
|
||||
} attributes {worker = [#acc.device_type<none>]}
|
||||
|
||||
acc.loop {
|
||||
// for i = 0 to 10 step 1
|
||||
@ -160,10 +160,10 @@ func.func @compute3(%a: memref<10x10xf32>, %b: memref<10x10xf32>, %c: memref<10x
|
||||
memref.store %z, %d[%x] : memref<10xf32>
|
||||
}
|
||||
acc.yield
|
||||
} attributes {seq}
|
||||
} attributes {seq = [#acc.device_type<none>]}
|
||||
}
|
||||
acc.yield
|
||||
}
|
||||
} attributes {gang = [#acc.device_type<none>]}
|
||||
acc.yield
|
||||
}
|
||||
acc.terminator
|
||||
@ -181,9 +181,9 @@ func.func @compute3(%a: memref<10x10xf32>, %b: memref<10x10xf32>, %c: memref<10x
|
||||
// CHECK: acc.data dataOperands(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : memref<10x10xf32>, memref<10x10xf32>, memref<10xf32>, memref<10xf32>) {
|
||||
// CHECK-NEXT: %[[P_ARG2:.*]] = acc.private varPtr([[ARG2]] : memref<10xf32>) -> memref<10xf32>
|
||||
// CHECK-NEXT: acc.parallel num_gangs({[[NUMGANG]] : i64}) num_workers([[NUMWORKERS]] : i64 [#acc.device_type<nvidia>]) private(@privatization_memref_10_f32 -> %[[P_ARG2]] : memref<10xf32>) {
|
||||
// CHECK-NEXT: acc.loop gang {
|
||||
// CHECK-NEXT: acc.loop {
|
||||
// CHECK-NEXT: scf.for %{{.*}} = [[C0]] to [[C10]] step [[C1]] {
|
||||
// CHECK-NEXT: acc.loop worker {
|
||||
// CHECK-NEXT: acc.loop {
|
||||
// CHECK-NEXT: scf.for %{{.*}} = [[C0]] to [[C10]] step [[C1]] {
|
||||
// CHECK-NEXT: %{{.*}} = memref.load %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>
|
||||
// CHECK-NEXT: %{{.*}} = memref.load %{{.*}}[%{{.*}}, %{{.*}}] : memref<10x10xf32>
|
||||
@ -191,7 +191,7 @@ func.func @compute3(%a: memref<10x10xf32>, %b: memref<10x10xf32>, %c: memref<10x
|
||||
// CHECK-NEXT: memref.store %{{.*}}, %{{.*}}[%{{.*}}] : memref<10xf32>
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: } attributes {worker = [#acc.device_type<none>]}
|
||||
// CHECK-NEXT: acc.loop {
|
||||
// CHECK-NEXT: scf.for %{{.*}} = [[C0]] to [[C10]] step [[C1]] {
|
||||
// CHECK-NEXT: %{{.*}} = memref.load %{{.*}}[%{{.*}}] : memref<10xf32>
|
||||
@ -200,10 +200,10 @@ func.func @compute3(%a: memref<10x10xf32>, %b: memref<10x10xf32>, %c: memref<10x
|
||||
// CHECK-NEXT: memref.store %{{.*}}, %{{.*}}[%{{.*}}] : memref<10xf32>
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: } attributes {seq}
|
||||
// CHECK-NEXT: } attributes {seq = [#acc.device_type<none>]}
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: } attributes {gang = [#acc.device_type<none>]}
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: acc.terminator
|
||||
@ -218,15 +218,15 @@ func.func @testloopop(%a : memref<10xf32>) -> () {
|
||||
%i32Value = arith.constant 128 : i32
|
||||
%idxValue = arith.constant 8 : index
|
||||
|
||||
acc.loop gang worker vector {
|
||||
acc.loop {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
} attributes {vector = [#acc.device_type<none>], worker = [#acc.device_type<none>], gang = [#acc.device_type<none>]}
|
||||
acc.loop gang({num=%i64Value: i64}) {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
}
|
||||
acc.loop gang(num=%i64Value: i64) {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
}
|
||||
acc.loop gang(static=%i64Value: i64) {
|
||||
acc.loop gang({static=%i64Value: i64}) {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
}
|
||||
@ -254,31 +254,31 @@ func.func @testloopop(%a : memref<10xf32>) -> () {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
}
|
||||
acc.loop gang(num=%i64Value: i64) worker vector {
|
||||
acc.loop gang({num=%i64Value: i64}) {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
} attributes {vector = [#acc.device_type<none>], worker = [#acc.device_type<none>]}
|
||||
acc.loop gang({num=%i64Value: i64, static=%i64Value: i64}) worker(%i64Value: i64) vector(%i64Value: i64) {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
}
|
||||
acc.loop gang(num=%i64Value: i64, static=%i64Value: i64) worker(%i64Value: i64) vector(%i64Value: i64) {
|
||||
acc.loop gang({num=%i32Value: i32, static=%idxValue: index}) {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
}
|
||||
acc.loop gang(num=%i32Value: i32, static=%idxValue: index) {
|
||||
acc.loop tile({%i64Value : i64, %i64Value : i64}) {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
}
|
||||
acc.loop tile(%i64Value, %i64Value : i64, i64) {
|
||||
acc.loop tile({%i32Value : i32, %i32Value : i32}) {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
}
|
||||
acc.loop tile(%i32Value, %i32Value : i32, i32) {
|
||||
acc.loop gang({static=%i64Value: i64, num=%i64Value: i64}) {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
}
|
||||
acc.loop gang(static=%i64Value: i64, num=%i64Value: i64) {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
}
|
||||
acc.loop gang(dim=%i64Value : i64, static=%i64Value: i64) {
|
||||
acc.loop gang({dim=%i64Value : i64, static=%i64Value: i64}) {
|
||||
"test.openacc_dummy_op"() : () -> ()
|
||||
acc.yield
|
||||
}
|
||||
@ -293,15 +293,15 @@ func.func @testloopop(%a : memref<10xf32>) -> () {
|
||||
// CHECK: [[I64VALUE:%.*]] = arith.constant 1 : i64
|
||||
// CHECK-NEXT: [[I32VALUE:%.*]] = arith.constant 128 : i32
|
||||
// CHECK-NEXT: [[IDXVALUE:%.*]] = arith.constant 8 : index
|
||||
// CHECK: acc.loop gang worker vector {
|
||||
// CHECK: acc.loop {
|
||||
// CHECK-NEXT: "test.openacc_dummy_op"() : () -> ()
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: } attributes {gang = [#acc.device_type<none>], vector = [#acc.device_type<none>], worker = [#acc.device_type<none>]}
|
||||
// CHECK: acc.loop gang({num=[[I64VALUE]] : i64}) {
|
||||
// CHECK-NEXT: "test.openacc_dummy_op"() : () -> ()
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: }
|
||||
// CHECK: acc.loop gang(num=[[I64VALUE]] : i64) {
|
||||
// CHECK-NEXT: "test.openacc_dummy_op"() : () -> ()
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: }
|
||||
// CHECK: acc.loop gang(static=[[I64VALUE]] : i64) {
|
||||
// CHECK: acc.loop gang({static=[[I64VALUE]] : i64}) {
|
||||
// CHECK-NEXT: "test.openacc_dummy_op"() : () -> ()
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: }
|
||||
@ -329,31 +329,31 @@ func.func @testloopop(%a : memref<10xf32>) -> () {
|
||||
// CHECK-NEXT: "test.openacc_dummy_op"() : () -> ()
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: }
|
||||
// CHECK: acc.loop gang(num=[[I64VALUE]] : i64) worker vector {
|
||||
// CHECK: acc.loop gang({num=[[I64VALUE]] : i64}) {
|
||||
// CHECK-NEXT: "test.openacc_dummy_op"() : () -> ()
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: } attributes {vector = [#acc.device_type<none>], worker = [#acc.device_type<none>]}
|
||||
// CHECK: acc.loop gang({num=[[I64VALUE]] : i64, static=[[I64VALUE]] : i64}) worker([[I64VALUE]] : i64) vector([[I64VALUE]] : i64) {
|
||||
// CHECK-NEXT: "test.openacc_dummy_op"() : () -> ()
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: }
|
||||
// CHECK: acc.loop gang(num=[[I64VALUE]] : i64, static=[[I64VALUE]] : i64) worker([[I64VALUE]] : i64) vector([[I64VALUE]] : i64) {
|
||||
// CHECK: acc.loop gang({num=[[I32VALUE]] : i32, static=[[IDXVALUE]] : index}) {
|
||||
// CHECK-NEXT: "test.openacc_dummy_op"() : () -> ()
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: }
|
||||
// CHECK: acc.loop gang(num=[[I32VALUE]] : i32, static=[[IDXVALUE]] : index) {
|
||||
// CHECK: acc.loop tile({[[I64VALUE]] : i64, [[I64VALUE]] : i64}) {
|
||||
// CHECK-NEXT: "test.openacc_dummy_op"() : () -> ()
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: }
|
||||
// CHECK: acc.loop tile([[I64VALUE]], [[I64VALUE]] : i64, i64) {
|
||||
// CHECK: acc.loop tile({[[I32VALUE]] : i32, [[I32VALUE]] : i32}) {
|
||||
// CHECK-NEXT: "test.openacc_dummy_op"() : () -> ()
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: }
|
||||
// CHECK: acc.loop tile([[I32VALUE]], [[I32VALUE]] : i32, i32) {
|
||||
// CHECK: acc.loop gang({static=[[I64VALUE]] : i64, num=[[I64VALUE]] : i64}) {
|
||||
// CHECK-NEXT: "test.openacc_dummy_op"() : () -> ()
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: }
|
||||
// CHECK: acc.loop gang(num=[[I64VALUE]] : i64, static=[[I64VALUE]] : i64) {
|
||||
// CHECK-NEXT: "test.openacc_dummy_op"() : () -> ()
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: }
|
||||
// CHECK: acc.loop gang(dim=[[I64VALUE]] : i64, static=[[I64VALUE]] : i64) {
|
||||
// CHECK: acc.loop gang({dim=[[I64VALUE]] : i64, static=[[I64VALUE]] : i64}) {
|
||||
// CHECK-NEXT: "test.openacc_dummy_op"() : () -> ()
|
||||
// CHECK-NEXT: acc.yield
|
||||
// CHECK-NEXT: }
|
||||
|
Loading…
Reference in New Issue
Block a user