-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[flang][Lower] Add Lowering for CO_{BROADCAST, MAX, MIN, SUM} to PRIF #154770
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-flang-fir-hlfir Author: Jean-Didier PAILLEUX (JDPailleux) ChangesIn relation to the approval and merge of the #76088 specification about multi-image features in Flang. Patch is 46.15 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/154770.diff 8 Files Affected:
diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
index 88c3ada3ff64f..84ed16c088e00 100644
--- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
+++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
@@ -225,6 +225,10 @@ struct IntrinsicLibrary {
fir::ExtendedValue genCharacterCompare(mlir::Type,
llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genCmplx(mlir::Type, llvm::ArrayRef<mlir::Value>);
+ void genCoBroadcast(llvm::ArrayRef<fir::ExtendedValue>);
+ void genCoMax(llvm::ArrayRef<fir::ExtendedValue>);
+ void genCoMin(llvm::ArrayRef<fir::ExtendedValue>);
+ void genCoSum(llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genConjg(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genCount(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
void genCpuTime(llvm::ArrayRef<fir::ExtendedValue>);
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h b/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h
index 23bb378c30838..10ed503a485a3 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Coarray.h
@@ -34,6 +34,11 @@ namespace fir::runtime {
return fir::NameUniquer::doProcedure({"prif"}, {}, oss.str()); \
}()
+#define PRIF_STAT_TYPE builder.getRefType(builder.getI32Type())
+#define PRIF_ERRMSG_TYPE \
+ fir::BoxType::get(fir::CharacterType::get(builder.getContext(), 1, \
+ fir::CharacterType::unknownLen()))
+
/// Generate Call to runtime prif_init
mlir::Value genInitCoarray(fir::FirOpBuilder &builder, mlir::Location loc);
@@ -49,5 +54,22 @@ mlir::Value getNumImagesWithTeam(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value getThisImage(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value team = {});
+/// Generate call to runtime subroutine prif_co_broadcast
+void genCoBroadcast(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value A, mlir::Value sourceImage, mlir::Value stat,
+ mlir::Value errmsg);
+
+/// Generate call to runtime subroutine prif_co_max and prif_co_max_character
+void genCoMax(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value A,
+ mlir::Value resultImage, mlir::Value stat, mlir::Value errmsg);
+
+/// Generate call to runtime subroutine prif_co_min or prif_co_min_character
+void genCoMin(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value A,
+ mlir::Value resultImage, mlir::Value stat, mlir::Value errmsg);
+
+/// Generate call to runtime subroutine prif_co_sum
+void genCoSum(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value A,
+ mlir::Value resultImage, mlir::Value stat, mlir::Value errmsg);
+
} // namespace fir::runtime
#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_COARRAY_H
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 8aacdb1815e3b..d5b4b77f8cb98 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -397,6 +397,34 @@ static constexpr IntrinsicHandler handlers[]{
{"cmplx",
&I::genCmplx,
{{{"x", asValue}, {"y", asValue, handleDynamicOptional}}}},
+ {"co_broadcast",
+ &I::genCoBroadcast,
+ {{{"a", asBox},
+ {"source_image", asAddr, handleDynamicOptional},
+ {"stat", asAddr, handleDynamicOptional},
+ {"errmsg", asBox, handleDynamicOptional}}},
+ /*isElemental*/ false},
+ {"co_max",
+ &I::genCoMax,
+ {{{"a", asBox},
+ {"result_image", asAddr, handleDynamicOptional},
+ {"stat", asAddr, handleDynamicOptional},
+ {"errmsg", asBox, handleDynamicOptional}}},
+ /*isElemental*/ false},
+ {"co_min",
+ &I::genCoMin,
+ {{{"a", asBox},
+ {"result_image", asAddr, handleDynamicOptional},
+ {"stat", asAddr, handleDynamicOptional},
+ {"errmsg", asBox, handleDynamicOptional}}},
+ /*isElemental*/ false},
+ {"co_sum",
+ &I::genCoSum,
+ {{{"a", asBox},
+ {"result_image", asAddr, handleDynamicOptional},
+ {"stat", asAddr, handleDynamicOptional},
+ {"errmsg", asBox, handleDynamicOptional}}},
+ /*isElemental*/ false},
{"command_argument_count", &I::genCommandArgumentCount},
{"conjg", &I::genConjg},
{"cosd", &I::genCosd},
@@ -3649,6 +3677,86 @@ mlir::Value IntrinsicLibrary::genCmplx(mlir::Type resultType,
imag);
}
+// CO_BROADCAST
+void IntrinsicLibrary::genCoBroadcast(llvm::ArrayRef<fir::ExtendedValue> args) {
+ checkCoarrayEnabled();
+ assert(args.size() == 4);
+ mlir::Value refNone =
+ builder
+ .create<fir::AbsentOp>(loc, builder.getRefType(builder.getI32Type()))
+ .getResult();
+ mlir::Value sourceImage =
+ isStaticallyAbsent(args[1]) ? refNone : fir::getBase(args[1]);
+ mlir::Value status =
+ isStaticallyAbsent(args[2]) ? refNone : fir::getBase(args[2]);
+ mlir::Value errmsg =
+ isStaticallyAbsent(args[3])
+ ? builder.create<fir::AbsentOp>(loc, PRIF_ERRMSG_TYPE).getResult()
+ : fir::getBase(args[3]);
+ fir::runtime::genCoBroadcast(builder, loc, fir::getBase(args[0]), sourceImage,
+ status, errmsg);
+}
+
+// CO_MAX
+void IntrinsicLibrary::genCoMax(llvm::ArrayRef<fir::ExtendedValue> args) {
+ checkCoarrayEnabled();
+ assert(args.size() == 4);
+ mlir::Value refNone =
+ builder
+ .create<fir::AbsentOp>(loc, builder.getRefType(builder.getI32Type()))
+ .getResult();
+ mlir::Value remoteImage =
+ isStaticallyAbsent(args[1]) ? refNone : fir::getBase(args[1]);
+ mlir::Value status =
+ isStaticallyAbsent(args[2]) ? refNone : fir::getBase(args[2]);
+ mlir::Value errmsg =
+ isStaticallyAbsent(args[3])
+ ? builder.create<fir::AbsentOp>(loc, PRIF_ERRMSG_TYPE).getResult()
+ : fir::getBase(args[3]);
+ fir::runtime::genCoMax(builder, loc, fir::getBase(args[0]), remoteImage,
+ status, errmsg);
+}
+
+// CO_MIN
+void IntrinsicLibrary::genCoMin(llvm::ArrayRef<fir::ExtendedValue> args) {
+ checkCoarrayEnabled();
+ assert(args.size() == 4);
+ mlir::Value refNone =
+ builder
+ .create<fir::AbsentOp>(loc, builder.getRefType(builder.getI32Type()))
+ .getResult();
+ mlir::Value remoteImage =
+ isStaticallyAbsent(args[1]) ? refNone : fir::getBase(args[1]);
+ mlir::Value status =
+ isStaticallyAbsent(args[2]) ? refNone : fir::getBase(args[2]);
+ mlir::Value errmsg =
+ isStaticallyAbsent(args[3])
+ ? builder.create<fir::AbsentOp>(loc, PRIF_ERRMSG_TYPE).getResult()
+ : fir::getBase(args[3]);
+ fir::runtime::genCoMin(builder, loc, fir::getBase(args[0]), remoteImage,
+ status, errmsg);
+}
+
+// CO_SUM
+void IntrinsicLibrary::genCoSum(llvm::ArrayRef<fir::ExtendedValue> args) {
+ checkCoarrayEnabled();
+ assert(args.size() == 4);
+ mlir::Value absentInt =
+ builder
+ .create<fir::AbsentOp>(loc, builder.getRefType(builder.getI32Type()))
+ .getResult();
+ mlir::Value remoteImage =
+ isStaticallyAbsent(args[1]) ? absentInt : fir::getBase(args[1]);
+ mlir::Value status =
+ isStaticallyAbsent(args[2]) ? absentInt : fir::getBase(args[2]);
+ mlir::Value errmsg =
+ isStaticallyAbsent(args[3])
+ ? builder.create<fir::AbsentOp>(loc, PRIF_ERRMSG_TYPE).getResult()
+ : fir::getBase(args[3]);
+ fir::runtime::genCoSum(builder, loc, fir::getBase(args[0]), remoteImage,
+ status, errmsg);
+}
+
// COMMAND_ARGUMENT_COUNT
fir::ExtendedValue IntrinsicLibrary::genCommandArgumentCount(
mlir::Type resultType, llvm::ArrayRef<fir::ExtendedValue> args) {
diff --git a/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp b/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp
index fb72fc2089e23..ca3052d9206a5 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Coarray.cpp
@@ -14,6 +14,24 @@
using namespace Fortran::runtime;
using namespace Fortran::semantics;
+// Most PRIF functions take `errmsg` and `errmsg_alloc` as two optional
+// arguments of intent (out). One is allocatable, the other is not.
+// It is the responsibility of the compiler to ensure that the appropriate
+// optional argument is passed, and at most one must be provided in a given
+// call.
+// Depending on the type of `errmsg`, this function will return the pair
+// corresponding to (`errmsg`, `errmsg_alloc`).
+static std::pair<mlir::Value, mlir::Value>
+genErrmsgPRIF(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value errmsg) {
+ bool isAllocatableErrmsg = fir::isAllocatableType(errmsg.getType());
+
+ mlir::Value absent = builder.create<fir::AbsentOp>(loc, PRIF_ERRMSG_TYPE);
+ mlir::Value errMsg = isAllocatableErrmsg ? absent : errmsg;
+ mlir::Value errMsgAlloc = isAllocatableErrmsg ? errmsg : absent;
+ return {errMsg, errMsgAlloc};
+}
+
/// Generate Call to runtime prif_init
mlir::Value fir::runtime::genInitCoarray(fir::FirOpBuilder &builder,
mlir::Location loc) {
@@ -84,3 +102,66 @@ mlir::Value fir::runtime::getThisImage(fir::FirOpBuilder &builder,
builder.create<fir::CallOp>(loc, funcOp, args);
return builder.create<fir::LoadOp>(loc, result);
}
+
+/// Generate call to collective subroutines except co_reduce
+/// A must be lowered as a box
+void genCollectiveSubroutine(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value A, mlir::Value sourceImage,
+ mlir::Value stat, mlir::Value errmsg,
+ std::string coName) {
+ mlir::Type boxTy = fir::BoxType::get(builder.getNoneType());
+ mlir::FunctionType ftype =
+ PRIF_FUNCTYPE(boxTy, builder.getRefType(builder.getI32Type()),
+ PRIF_STAT_TYPE, PRIF_ERRMSG_TYPE, PRIF_ERRMSG_TYPE);
+ mlir::func::FuncOp funcOp = builder.createFunction(loc, coName, ftype);
+
+ auto [errmsgArg, errmsgAllocArg] = genErrmsgPRIF(builder, loc, errmsg);
+ llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
+ builder, loc, ftype, A, sourceImage, stat, errmsgArg, errmsgAllocArg);
+ builder.create<fir::CallOp>(loc, funcOp, args);
+}
+
+/// Generate call to runtime subroutine prif_co_broadcast
+void fir::runtime::genCoBroadcast(fir::FirOpBuilder &builder,
+ mlir::Location loc, mlir::Value A,
+ mlir::Value sourceImage, mlir::Value stat,
+ mlir::Value errmsg) {
+ genCollectiveSubroutine(builder, loc, A, sourceImage, stat, errmsg,
+ PRIFNAME_SUB("co_broadcast"));
+}
+
+/// Generate call to runtime subroutine prif_co_max or prif_co_max_character
+void fir::runtime::genCoMax(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value A, mlir::Value resultImage,
+ mlir::Value stat, mlir::Value errmsg) {
+ mlir::Type argTy =
+ fir::unwrapSequenceType(fir::unwrapPassByRefType(A.getType()));
+ if (mlir::isa<fir::CharacterType>(argTy))
+ genCollectiveSubroutine(builder, loc, A, resultImage, stat, errmsg,
+ PRIFNAME_SUB("co_max_character"));
+ else
+ genCollectiveSubroutine(builder, loc, A, resultImage, stat, errmsg,
+ PRIFNAME_SUB("co_max"));
+}
+
+/// Generate call to runtime subroutine prif_co_min or prif_co_min_character
+void fir::runtime::genCoMin(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value A, mlir::Value resultImage,
+ mlir::Value stat, mlir::Value errmsg) {
+ mlir::Type argTy =
+ fir::unwrapSequenceType(fir::unwrapPassByRefType(A.getType()));
+ if (mlir::isa<fir::CharacterType>(argTy))
+ genCollectiveSubroutine(builder, loc, A, resultImage, stat, errmsg,
+ PRIFNAME_SUB("co_min_character"));
+ else
+ genCollectiveSubroutine(builder, loc, A, resultImage, stat, errmsg,
+ PRIFNAME_SUB("co_min"));
+}
+
+/// Generate call to runtime subroutine prif_co_sum
+void fir::runtime::genCoSum(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value A, mlir::Value resultImage,
+ mlir::Value stat, mlir::Value errmsg) {
+ genCollectiveSubroutine(builder, loc, A, resultImage, stat, errmsg,
+ PRIFNAME_SUB("co_sum"));
+}
diff --git a/flang/test/Lower/Coarray/co_broadcast.f90 b/flang/test/Lower/Coarray/co_broadcast.f90
new file mode 100644
index 0000000000000..be7fdcb99252c
--- /dev/null
+++ b/flang/test/Lower/Coarray/co_broadcast.f90
@@ -0,0 +1,92 @@
+! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
+
+program test_co_broadcast
+ integer :: i, array_i(2), status
+ real :: r, array_r(2)
+ double precision :: d, array_d(2)
+ complex :: c, array_c(2)
+ character(len=1) :: message
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_I:.*]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
+ ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<i32>) -> !fir.box<none>
+ ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+ call co_broadcast(i, source_image=1)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_C:.*]]#0 : (!fir.ref<complex<f32>>) -> !fir.box<complex<f32>>
+ ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ ! CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<complex<f32>>) -> !fir.box<none>
+ ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS:.*]], %[[V2]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+ call co_broadcast(c, source_image=1, stat=status)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_D:.*]]#0 : (!fir.ref<f64>) -> !fir.box<f64>
+ ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE:.*]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f64>) -> !fir.box<none>
+ ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+ call co_broadcast(d, source_image=1, stat=status, errmsg=message)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[V1:.*]] = fir.embox %[[VAR_R:.*]]#0 : (!fir.ref<f32>) -> !fir.box<f32>
+ ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<f32>) -> !fir.box<none>
+ ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+ call co_broadcast(r, source_image=1, stat=status, errmsg=message)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_I:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+ ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xi32>>) -> !fir.box<none>
+ ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+ call co_broadcast(array_i, source_image=1)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xcomplex<f32>>>, !fir.shape<1>) -> !fir.box<!fir.array<2xcomplex<f32>>>
+ ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ ! CHECK: %[[V2:.*]] = fir.absent !fir.ref<i32>
+ ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! CHECK: %[[V4:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! CHECK: %[[V5:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xcomplex<f32>>>) -> !fir.box<none>
+ ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V5]], %[[IMAGE_RESULT]], %[[V2]], %[[V3]], %[[V4]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+ call co_broadcast(array_c, source_image=1)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_D:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf64>>
+ ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ ! CHECK: %[[V2:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf64>>) -> !fir.box<none>
+ ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V2]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+ call co_broadcast(array_d, source_image=1, stat=status)
+
+ ! CHECK: %[[C1_i32:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[C2_2:.*]] : (index) -> !fir.shape<1>
+ ! CHECK: %[[V1:.*]] = fir.embox %[[ARRAY_C:.*]]#0(%[[SHAPE_2]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+ ! CHECK: fir.store %[[C1_i32]] to %[[IMAGE_RESULT:.*]] : !fir.ref<i32>
+ ! CHECK: %[[V2:.*]] = fir.embox %[[MESSAGE]]#0 : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.char<1>>
+ ! CHECK: %[[V3:.*]] = fir.absent !fir.box<!fir.char<1,?>>
+ ! CHECK: %[[V4:.*]] = fir.convert %[[V1]] : (!fir.box<!fir.array<2xf32>>) -> !fir.box<none>
+ ! CHECK: %[[V5:.*]] = fir.convert %[[V2]] : (!fir.box<!fir.char<1>>) -> !fir.box<!fir.char<1,?>>
+ ! CHECK: fir.call @_QMprifPprif_co_broadcast(%[[V4]], %[[IMAGE_RESULT]], %[[STATUS]], %[[V5]], %[[V3]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i32>, !fir.ref<i32>, !fir.box<!fir.char<1,?>>, !fir.box<!fir.char<1,?>>) -> ()
+ call co_broadcast(array_r, source_image=1, stat= status, errmsg=message)
+
+end program
diff --git a/flang/test/Lower/Coarray/co_max.f90 b/flang/test/Lower/Coarray/co_max.f90
new file mode 100644
index 0000000000000..56d863389d02b
--- /dev/null...
[truncated]
|
@JDPailleux Hi! I'm really looking forward to this coarray work but the implementation is surprising me a little. @jeanPerier told me to expect an intermediate lowering of coarray calls to "prif" MLIR instead of directly to PRIF runtime calls. Also, where can we find an implementation of PRIF to test out this work. We can take this discussion to discourse or slack. |
Hello @sscalpone, yes we have had discussions about a dialect. To facilitate this broader discussion around PRIF lowering in Flang, let’s take this conversation to Slack, as you suggested. The #prif-implementation channel in the flang Slack workspace seems appropriate and Jean-Didier and others are already in this channel. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @JDPailleux for this PR!
The code seems well-structured, and the tests provide good coverage to exercise the valid use cases.
I've added a few suggestions for minor improvements.
Co-authored-by: Dan Bonachea <[email protected]>
Co-authored-by: Dan Bonachea <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates. LGTM.
…llvm#154770) In relation to the approval and merge of the llvm#76088 specification about multi-image features in Flang. Here is a PR on adding support of the collectives CO_BROADCAST, CO_SUM, CO_MIN and CO_MAX in conformance with the PRIF specification. --------- Co-authored-by: Dan Bonachea <[email protected]>
In relation to the approval and merge of the #76088 specification about multi-image features in Flang.
Here is a PR on adding support of the collectives CO_BROADCAST, CO_SUM, CO_MIN and CO_MAX in conformance with the PRIF specification.