[OpenACC] apply seq par dims to reduction variables (#209261)
When the acc.parallel op is "effectively sequential" apply the correct par dims during recipe materialization of reduction variables
This commit is contained in:
1 parent
8748e5e3ac
commit
2e86804e61
3 files changed
+55
-6
No files matched your search
@@ -95,6 +95,19 @@ void updateParDimsAttr(Operation *op, GPUParallelDimsAttr attr);
|
||||
/// Copy parallel dimensions from \p from to \p to.
|
||||
void copyParDimsAttr(Operation *from, Operation *to);
|
||||
|
||||
/// Create a gang dim 1 GPUParallelDimsAttr based on the mapping policy.
|
||||
inline GPUParallelDimsAttr
|
||||
getGangDim1ParDimsAttr(MLIRContext *ctx, ACCToGPUMappingPolicy &policy) {
|
||||
return GPUParallelDimsAttr::get(
|
||||
ctx, {policy.gangDim(ctx, acc::ParLevel::gang_dim1)});
|
||||
}
|
||||
|
||||
/// Create a sequential GPUParallelDimsAttr based on the mapping policy.
|
||||
inline GPUParallelDimsAttr getSeqParDimsAttr(MLIRContext *ctx,
|
||||
ACCToGPUMappingPolicy &policy) {
|
||||
return GPUParallelDimsAttr::get(ctx, {policy.seqDim(ctx)});
|
||||
}
|
||||
|
||||
/// Tracks aligned byte consumption against a configurable shared memory cap.
|
||||
class SharedMemoryBudget {
|
||||
public:
|
||||
|
||||
@@ -383,25 +383,29 @@ LogicalResult ACCRecipeMaterialization::materialize(
|
||||
cloneRegionIntoAccRegion(&combinerRegion, &combineRegionOp.getRegion(),
|
||||
/*hasResult=*/false);
|
||||
|
||||
auto ctx = b.getContext();
|
||||
auto *ctx = b.getContext();
|
||||
|
||||
// For reductions that come from parallel constructs, explicitly set the
|
||||
// GPU parallel dimensions attribute to blockXDim since they will always be
|
||||
// gang private. GPU parallel dimensions cannot be determined for acc.loop
|
||||
// at this point.
|
||||
if constexpr (std::is_same_v<AccOpTy, acc::ParallelOp>) {
|
||||
auto parDimsAttr = acc::GPUParallelDimsAttr::get(
|
||||
ctx, {policy.gangDim(ctx, acc::ParLevel::gang_dim1)});
|
||||
acc::GPUParallelDimsAttr parDimsAttr;
|
||||
if (accOp.isEffectivelySerial()) {
|
||||
// If acc.serial has been lowered to a parallel op that is effectively
|
||||
// sequential
|
||||
parDimsAttr = acc::getSeqParDimsAttr(ctx, policy);
|
||||
} else {
|
||||
parDimsAttr = acc::getGangDim1ParDimsAttr(ctx, policy);
|
||||
}
|
||||
acc::setParDimsAttr(reductionOp, parDimsAttr);
|
||||
acc::setParDimsAttr(combineRegionOp, parDimsAttr);
|
||||
}
|
||||
|
||||
// Set sequential parallel dimensions attribute for loops in the recipe.
|
||||
auto seqParDimsAttr =
|
||||
acc::GPUParallelDimsAttr::get(ctx, {policy.seqDim(ctx)});
|
||||
auto setSeqParDimsForRecipeLoops = [&](Region *r) {
|
||||
r->walk([&](LoopLikeOpInterface loopLike) {
|
||||
acc::setParDimsAttr(loopLike, seqParDimsAttr);
|
||||
acc::setParDimsAttr(loopLike, acc::getSeqParDimsAttr(ctx, policy));
|
||||
});
|
||||
};
|
||||
setSeqParDimsForRecipeLoops(&reductionOp.getRegion());
|
||||
|
||||
@@ -51,3 +51,35 @@ func.func @par_reduction_clause_(%arg0: memref<f64>) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// CHECK-LABEL: func.func @par_reduction_clause_serial
|
||||
// CHECK: acc.parallel {{.*}} {
|
||||
// CHECK: [[PRIVATE:%.*]] = acc.reduction_init {{.*}} <add>
|
||||
// CHECK-NEXT: [[ZERO:%.*]] = arith.constant 0.000000e+00 : f64
|
||||
// CHECK-NEXT: [[ALLOCA:%.*]] = memref.alloca() : memref<f64>
|
||||
// CHECK-NEXT: memref.store [[ZERO]], [[ALLOCA]][]
|
||||
// CHECK-NEXT: acc.yield {{.*}}
|
||||
// CHECK: } {{.*}}acc.par_dims = #acc<par_dims[sequential]>, acc.var_name = #acc.var_name<"tmp">
|
||||
// CHECK: memref.load [[PRIVATE]][]
|
||||
// CHECK: memref.store {{.*}}, [[PRIVATE]][]
|
||||
// CHECK: acc.reduction_combine_region [[PRIVATE]] into [[REDUCVAR:%.*]] : memref<f64> {
|
||||
// CHECK: [[LOADVAR:%.*]] = memref.load [[REDUCVAR]][]
|
||||
// CHECK-NEXT: [[LOADPRIV:%.*]] = memref.load [[PRIVATE]][]
|
||||
// CHECK-NEXT: [[COMBINE:%.*]] = arith.addf [[LOADVAR]], [[LOADPRIV]]
|
||||
// CHECK-NEXT: memref.store [[COMBINE]], [[REDUCVAR]][]
|
||||
// CHECK-NEXT: } {acc.par_dims = #acc<par_dims[sequential]>}
|
||||
// CHECK-NEXT: memref.dealloc [[PRIVATE]] : memref<f64>
|
||||
// CHECK: acc.yield
|
||||
|
||||
func.func @par_reduction_clause_serial(%arg0: memref<f64>) {
|
||||
%c1_i32 = arith.constant 1 : i32
|
||||
%cst = arith.constant 1.000000e+00 : f64
|
||||
%red = acc.reduction varPtr(%arg0 : memref<f64>) recipe(@reduction_add_memref_f64) -> memref<f64> {name = "tmp"}
|
||||
acc.parallel num_gangs({%c1_i32 : i32}) num_workers(%c1_i32 : i32) vector_length(%c1_i32 : i32) reduction(%red : memref<f64>) {
|
||||
%3 = memref.load %red[] : memref<f64>
|
||||
%4 = arith.addf %3, %cst fastmath<contract> : f64
|
||||
memref.store %4, %red[] : memref<f64>
|
||||
acc.yield
|
||||
}
|
||||
return
|
||||
}
|
||||
Reference in new issue
Block a user