Skip to content

Commit e4334af

Browse files
authored
[flang] Add support of THIS_IMAGE and NUM_IMAGES with PRIF (#154081)
In relation to the approval and merge of the #76088 specification about multi-image features in Flang. Here is a PR on adding support for `THIS_IMAGE` and `NUM_IMAGES` in conformance with the PRIF specification. For `THIS_IMAGE`, the lowering to the subroutine containing the coarray argument is not present in this PR, and will be in a future one.
1 parent a872c4c commit e4334af

File tree

6 files changed

+159
-0
lines changed

6 files changed

+159
-0
lines changed

flang/include/flang/Optimizer/Builder/IntrinsicCall.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,8 @@ struct IntrinsicLibrary {
378378
fir::ExtendedValue genNorm2(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
379379
mlir::Value genNot(mlir::Type, llvm::ArrayRef<mlir::Value>);
380380
fir::ExtendedValue genNull(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
381+
fir::ExtendedValue genNumImages(mlir::Type,
382+
llvm::ArrayRef<fir::ExtendedValue>);
381383
template <typename OpTy>
382384
mlir::Value genNVVMTime(mlir::Type, llvm::ArrayRef<mlir::Value>);
383385
fir::ExtendedValue genPack(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
@@ -449,6 +451,8 @@ struct IntrinsicLibrary {
449451
fir::ExtendedValue genTranspose(mlir::Type,
450452
llvm::ArrayRef<fir::ExtendedValue>);
451453
mlir::Value genThisGrid(mlir::Type, llvm::ArrayRef<mlir::Value>);
454+
fir::ExtendedValue genThisImage(mlir::Type,
455+
llvm::ArrayRef<fir::ExtendedValue>);
452456
mlir::Value genThisThreadBlock(mlir::Type, llvm::ArrayRef<mlir::Value>);
453457
mlir::Value genThisWarp(mlir::Type, llvm::ArrayRef<mlir::Value>);
454458
void genThreadFence(llvm::ArrayRef<fir::ExtendedValue>);
@@ -563,6 +567,15 @@ struct IntrinsicLibrary {
563567

564568
void setResultMustBeFreed() { resultMustBeFreed = true; }
565569

570+
// Check support of coarray features
571+
void checkCoarrayEnabled() {
572+
if (converter &&
573+
!converter->getFoldingContext().languageFeatures().IsEnabled(
574+
Fortran::common::LanguageFeature::Coarray))
575+
fir::emitFatalError(loc, "Coarrays disabled, use '-fcoarray' to enable.",
576+
false);
577+
}
578+
566579
fir::FirOpBuilder &builder;
567580
mlir::Location loc;
568581
bool resultMustBeFreed = false;

flang/include/flang/Optimizer/Builder/Runtime/Coarray.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,17 @@ namespace fir::runtime {
3737
/// Generate Call to runtime prif_init
3838
mlir::Value genInitCoarray(fir::FirOpBuilder &builder, mlir::Location loc);
3939

40+
/// Generate Call to runtime prif_num_images
41+
mlir::Value getNumImages(fir::FirOpBuilder &builder, mlir::Location loc);
42+
43+
/// Generate Call to runtime prif_num_images_with_team or
44+
/// prif_num_images_with_team_number
45+
mlir::Value getNumImagesWithTeam(fir::FirOpBuilder &builder, mlir::Location loc,
46+
mlir::Value team);
47+
48+
/// Generate Call to runtime prif_this_image_no_coarray
49+
mlir::Value getThisImage(fir::FirOpBuilder &builder, mlir::Location loc,
50+
mlir::Value team = {});
51+
4052
} // namespace fir::runtime
4153
#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_COARRAY_H

flang/lib/Optimizer/Builder/IntrinsicCall.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "flang/Optimizer/Builder/Runtime/Allocatable.h"
2626
#include "flang/Optimizer/Builder/Runtime/CUDA/Descriptor.h"
2727
#include "flang/Optimizer/Builder/Runtime/Character.h"
28+
#include "flang/Optimizer/Builder/Runtime/Coarray.h"
2829
#include "flang/Optimizer/Builder/Runtime/Command.h"
2930
#include "flang/Optimizer/Builder/Runtime/Derived.h"
3031
#include "flang/Optimizer/Builder/Runtime/Exceptions.h"
@@ -778,6 +779,10 @@ static constexpr IntrinsicHandler handlers[]{
778779
/*isElemental=*/false},
779780
{"not", &I::genNot},
780781
{"null", &I::genNull, {{{"mold", asInquired}}}, /*isElemental=*/false},
782+
{"num_images",
783+
&I::genNumImages,
784+
{{{"team", asAddr}, {"team_number", asAddr}}},
785+
/*isElemental*/ false},
781786
{"pack",
782787
&I::genPack,
783788
{{{"array", asBox},
@@ -947,6 +952,12 @@ static constexpr IntrinsicHandler handlers[]{
947952
{"tand", &I::genTand},
948953
{"tanpi", &I::genTanpi},
949954
{"this_grid", &I::genThisGrid, {}, /*isElemental=*/false},
955+
{"this_image",
956+
&I::genThisImage,
957+
{{{"coarray", asBox},
958+
{"dim", asAddr},
959+
{"team", asBox, handleDynamicOptional}}},
960+
/*isElemental=*/false},
950961
{"this_thread_block", &I::genThisThreadBlock, {}, /*isElemental=*/false},
951962
{"this_warp", &I::genThisWarp, {}, /*isElemental=*/false},
952963
{"threadfence", &I::genThreadFence, {}, /*isElemental=*/false},
@@ -7279,6 +7290,19 @@ IntrinsicLibrary::genNull(mlir::Type, llvm::ArrayRef<fir::ExtendedValue> args) {
72797290
return fir::MutableBoxValue(boxStorage, mold->nonDeferredLenParams(), {});
72807291
}
72817292

7293+
// NUM_IMAGES
7294+
fir::ExtendedValue
7295+
IntrinsicLibrary::genNumImages(mlir::Type resultType,
7296+
llvm::ArrayRef<fir::ExtendedValue> args) {
7297+
checkCoarrayEnabled();
7298+
assert(args.size() == 0 || args.size() == 1);
7299+
7300+
if (args.size())
7301+
return fir::runtime::getNumImagesWithTeam(builder, loc,
7302+
fir::getBase(args[0]));
7303+
return fir::runtime::getNumImages(builder, loc);
7304+
}
7305+
72827306
// CLOCK, CLOCK64, GLOBALTIMER
72837307
template <typename OpTy>
72847308
mlir::Value IntrinsicLibrary::genNVVMTime(mlir::Type resultType,
@@ -8329,6 +8353,27 @@ mlir::Value IntrinsicLibrary::genThisGrid(mlir::Type resultType,
83298353
return res;
83308354
}
83318355

8356+
// THIS_IMAGE
8357+
fir::ExtendedValue
8358+
IntrinsicLibrary::genThisImage(mlir::Type resultType,
8359+
llvm::ArrayRef<fir::ExtendedValue> args) {
8360+
checkCoarrayEnabled();
8361+
assert(args.size() >= 1 && args.size() <= 3);
8362+
const bool coarrayIsAbsent = args.size() == 1;
8363+
mlir::Value team =
8364+
!isStaticallyAbsent(args, args.size() - 1)
8365+
? fir::getBase(args[args.size() - 1])
8366+
: builder
8367+
.create<fir::AbsentOp>(loc,
8368+
fir::BoxType::get(builder.getNoneType()))
8369+
.getResult();
8370+
8371+
if (!coarrayIsAbsent)
8372+
TODO(loc, "this_image with coarray argument.");
8373+
mlir::Value res = fir::runtime::getThisImage(builder, loc, team);
8374+
return builder.createConvert(loc, resultType, res);
8375+
}
8376+
83328377
// THIS_THREAD_BLOCK
83338378
mlir::Value
83348379
IntrinsicLibrary::genThisThreadBlock(mlir::Type resultType,

flang/lib/Optimizer/Builder/Runtime/Coarray.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,60 @@ mlir::Value fir::runtime::genInitCoarray(fir::FirOpBuilder &builder,
2727
builder.create<fir::CallOp>(loc, funcOp, args);
2828
return builder.create<fir::LoadOp>(loc, result);
2929
}
30+
31+
/// Generate Call to runtime prif_num_images
32+
mlir::Value fir::runtime::getNumImages(fir::FirOpBuilder &builder,
33+
mlir::Location loc) {
34+
mlir::Value result = builder.createTemporary(loc, builder.getI32Type());
35+
mlir::FunctionType ftype =
36+
PRIF_FUNCTYPE(builder.getRefType(builder.getI32Type()));
37+
mlir::func::FuncOp funcOp =
38+
builder.createFunction(loc, PRIFNAME_SUB("num_images"), ftype);
39+
llvm::SmallVector<mlir::Value> args =
40+
fir::runtime::createArguments(builder, loc, ftype, result);
41+
builder.create<fir::CallOp>(loc, funcOp, args);
42+
return builder.create<fir::LoadOp>(loc, result);
43+
}
44+
45+
/// Generate Call to runtime prif_num_images_with_{team|team_number}
46+
mlir::Value fir::runtime::getNumImagesWithTeam(fir::FirOpBuilder &builder,
47+
mlir::Location loc,
48+
mlir::Value team) {
49+
bool isTeamNumber = fir::unwrapPassByRefType(team.getType()).isInteger();
50+
std::string numImagesName = isTeamNumber
51+
? PRIFNAME_SUB("num_images_with_team_number")
52+
: PRIFNAME_SUB("num_images_with_team");
53+
54+
mlir::Value result = builder.createTemporary(loc, builder.getI32Type());
55+
mlir::Type refTy = builder.getRefType(builder.getI32Type());
56+
mlir::FunctionType ftype =
57+
isTeamNumber
58+
? PRIF_FUNCTYPE(builder.getRefType(builder.getI64Type()), refTy)
59+
: PRIF_FUNCTYPE(fir::BoxType::get(builder.getNoneType()), refTy);
60+
mlir::func::FuncOp funcOp = builder.createFunction(loc, numImagesName, ftype);
61+
62+
if (!isTeamNumber)
63+
team = builder.createBox(loc, team);
64+
llvm::SmallVector<mlir::Value> args =
65+
fir::runtime::createArguments(builder, loc, ftype, team, result);
66+
builder.create<fir::CallOp>(loc, funcOp, args);
67+
return builder.create<fir::LoadOp>(loc, result);
68+
}
69+
70+
/// Generate Call to runtime prif_this_image_no_coarray
71+
mlir::Value fir::runtime::getThisImage(fir::FirOpBuilder &builder,
72+
mlir::Location loc, mlir::Value team) {
73+
mlir::Type refTy = builder.getRefType(builder.getI32Type());
74+
mlir::Type boxTy = fir::BoxType::get(builder.getNoneType());
75+
mlir::FunctionType ftype = PRIF_FUNCTYPE(boxTy, refTy);
76+
mlir::func::FuncOp funcOp =
77+
builder.createFunction(loc, PRIFNAME_SUB("this_image_no_coarray"), ftype);
78+
79+
mlir::Value result = builder.createTemporary(loc, builder.getI32Type());
80+
mlir::Value teamArg =
81+
!team ? builder.create<fir::AbsentOp>(loc, boxTy) : team;
82+
llvm::SmallVector<mlir::Value> args =
83+
fir::runtime::createArguments(builder, loc, ftype, teamArg, result);
84+
builder.create<fir::CallOp>(loc, funcOp, args);
85+
return builder.create<fir::LoadOp>(loc, result);
86+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
2+
3+
program test
4+
use iso_fortran_env
5+
integer :: i
6+
integer :: team_number
7+
type(team_type) :: team
8+
9+
! CHECK: fir.call @_QMprifPprif_num_images
10+
i = num_images()
11+
12+
! CHECK: fir.call @_QMprifPprif_num_images_with_team_number
13+
i = num_images(TEAM_NUMBER=team_number)
14+
15+
! CHECK: fir.call @_QMprifPprif_num_images_with_team
16+
i = num_images(TEAM=team)
17+
18+
end program
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s
2+
3+
program test
4+
use iso_fortran_env
5+
integer :: i
6+
type(team_type) :: team
7+
8+
! CHECK: fir.call @_QMprifPprif_this_image_no_coarray
9+
i = this_image()
10+
11+
! CHECK: fir.call @_QMprifPprif_this_image_no_coarray
12+
i = this_image(TEAM=team)
13+
14+
end program

0 commit comments

Comments
 (0)