From 3fef2355aa72e85fe8acfd26cc3cec1acfbf0350 Mon Sep 17 00:00:00 2001 From: Jean-Didier Pailleux Date: Thu, 15 May 2025 16:50:54 +0200 Subject: [PATCH 1/4] [DRAFT][flang] Dialect Multi-Image Fortran (MIF) operations --- .../flang/Optimizer/Dialect/FIRTypes.td | 4 + .../flang/Optimizer/Dialect/MIF/MIFDialect.td | 38 + .../flang/Optimizer/Dialect/MIF/MIFOps.td | 822 ++++++++++++++++++ 3 files changed, 864 insertions(+) create mode 100644 flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.td create mode 100644 flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td diff --git a/flang/include/flang/Optimizer/Dialect/FIRTypes.td b/flang/include/flang/Optimizer/Dialect/FIRTypes.td index 6fad77dffd9bc..16585bd11b544 100644 --- a/flang/include/flang/Optimizer/Dialect/FIRTypes.td +++ b/flang/include/flang/Optimizer/Dialect/FIRTypes.td @@ -676,4 +676,8 @@ def AnyBoxedArray : TypeConstraint, "any boxed array">; +def ArrayOrIntegerType : TypeConstraint, + "fir.array or any integer">; + #endif // FIR_DIALECT_FIR_TYPES diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.td new file mode 100644 index 0000000000000..f8be6a86a79fe --- /dev/null +++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFDialect.td @@ -0,0 +1,38 @@ +//===-- MIFDialect.td - MIF dialect base definitions - tablegen ---------*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Definition of the Multi-Image Fortran (MIF) dialect +/// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_DIALECT_MIF_MIFDIALECT +#define FORTRAN_DIALECT_MIF_MIFDIALECT + +include "mlir/IR/AttrTypeBase.td" +include "mlir/IR/EnumAttr.td" +include "mlir/IR/OpBase.td" + +def MIFDialect : Dialect { + let name = "mif"; + + let summary = "Multi-Image Fortran dialect"; + + let description = [{ + The "MIF" dialect is designed to contain the basic coarray operations + in Fortran and all multi image operations as descibed in the standard. + This includes synchronization operations, atomic operations, + image queries, teams, criticals, etc. The MIF dialect operations use + the FIR types and are tightly coupled with FIR and HLFIR. + }]; + + let cppNamespace = "::mif"; + let dependentDialects = ["fir::FIROpsDialect"]; +} + +#endif // FORTRAN_DIALECT_MIF_MIFDIALECT diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td new file mode 100644 index 0000000000000..d902bfdef4638 --- /dev/null +++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td @@ -0,0 +1,822 @@ +//===-- MIFOps.td - MIF operation definitions ------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Definition of the MIF dialect operations +/// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_DIALECT_MIF_MIF_OPS +#define FORTRAN_DIALECT_MIF_MIF_OPS + +include "flang/Optimizer/Dialect/MIF/MIFDialect.td" +include "flang/Optimizer/Dialect/FIRTypes.td" +include "flang/Optimizer/Dialect/FIRAttr.td" +include "mlir/Dialect/LLVMIR/LLVMAttrDefs.td" +include "mlir/Dialect/LLVMIR/LLVMOpBase.td" +include "mlir/Interfaces/LoopLikeInterface.td" +include "mlir/IR/BuiltinAttributes.td" + +class mif_Op traits> + : Op; + +//===----------------------------------------------------------------------===// +// Initialization and Finalization +//===----------------------------------------------------------------------===// + +def mif_InitOp : mif_Op<"init", []> { + let summary = "Initialize the parallel environment"; + let description = [{This operation will initialize the parallel environment}]; + + let arguments = (ins AnyIntegerType:$stat); +} + +def mif_StopOp : mif_Op<"stop", [AttrSizedOperandSegments]> { + let summary = "Operation that synchronizes all execution images, clean up the" + "parallel runtime environment, and terminates the program."; + let description = [{ + This operation synchronizes all executing images, cleans up the parallel + runtime environment, and terminates the program. Calls to this operation do + not return. This operation supports both normal termination at the end of a + program, as well as any STOP statements from the user source code. + }]; + + let arguments = (ins Optional:$quiet, + Optional:$stop_code_int, + Arg, "", [MemWrite]>:$stop_code_char, + UnitAttr:$is_error); + + let hasVerifier = 1; +} + +def mif_FailImageOp : mif_Op<"fail_image", [NoMemoryEffect]> { + let summary = + "Causes the executing image to cease participating in program execution"; +} + +//===----------------------------------------------------------------------===// +// Image Queries +//===----------------------------------------------------------------------===// + +def mif_NumImagesOp + : mif_Op<"num_images", [NoMemoryEffect, AttrSizedOperandSegments]> { + let summary = "Query the number of images in the specified or current team"; + let description = [{ + This operation query the number of images in the specified or current + team and can be called with 3 differents way : + - `num_images()` + - `num_images(team)` + - `num_images(team_number)` + + Argumemnts: + - `team` : Shall be a scalar of type `team_type` from the `ISO_FORTRAN_ENV` + module with a value that identifies the current or ancestor team. + - `team_number` : Shall be an integer scalar. It shall identify the + initial team or a sibling team of the current team. + + Result Value: The number of images in the specified team, or in the current + team if no team is specified. + }]; + + let arguments = (ins Optional:$team_number, + Optional:$team); + let results = (outs AnyIntegerType); + + let skipDefaultBuilders = 1; + let builders = [ + OpBuilder<(ins CArg<"mlir::Value", "{}">:$team_number, + CArg<"mlir::Value", "{}">:$team), + [{ return build($_builder, $_state, team_number, team); }]> + ]; + + let hasVerifier = 1; +} + +def mif_ThisImageOp : mif_Op<"this_image", [AttrSizedOperandSegments]> { + let summary = "Determine the image index of the current image"; + let description = [{ + Arguments: + - `coarray` : Shall be a coarray of any type. + - `dim` : Shall be an integer scalar. Its value shall be in the range of + 1 <= DIM <= N, where N is the corank of the coarray. + - `team`(optional) : Shall be a scalar of type `team_type` from + ISO_FORTRAN_ENV. If the `coarray` is present, it shall be + established in that team. + + Results: + - Case(1) : The result of `this_image([team])` is a scalar with a value + equal to the index of the image in the current or specified team. + - Case(2) : The result of `this_image(coarray [,team])` is the sequence of + cosubscript vales for `coarray`. + - Case(3) : The result of `this_image(coarray, dim [,team])` is the value of + cosubscript `dim` in the sequence of cosubscript values for `coarray`. + + Example: + ```fortran + REAL :: A[10, 0:9, 0:*] + ``` + If we take a look on the example and we are on image 5, `this_image` has the + value 5, `this_image(A)` has the value [5, 0, 0]. + }]; + + let arguments = (ins Optional:$coarray, + Optional:$dim, Optional:$team); + let results = (outs ArrayOrIntegerType); + + let skipDefaultBuilders = 1; + let builders = [OpBuilder<(ins "mlir::Value":$coarray, "int32_t":$dim, + CArg<"mlir::Value", "{}">:$team)>, + OpBuilder<(ins "mlir::Value":$coarray, "mlir::Value":$dim, + CArg<"mlir::Value", "{}">:$team)>, + OpBuilder<(ins "mlir::Value":$coarray, + CArg<"mlir::Value", "{}">:$team)>, + OpBuilder<(ins CArg<"mlir::Value", "{}">:$team)>]; + + let hasVerifier = 1; +} + +def mif_FailedImagesOp : mif_Op<"failed_images", []> { + let summary = "Indices of failed images."; + let description = [{ + Argument: `team`(optional) : Shall be a scalar of type `team_type` from + ISO_FORTRAN_ENV. + Result: The values of the image indices of the known failed images + in the specified team, in numerically increasing order. + }]; + + let arguments = (ins Optional:$team); + let results = (outs fir_SequenceType); +} + +def mif_StoppedImagesOp : mif_Op<"stopped_images", []> { + let summary = "Indices of stopped images."; + let description = [{ + Argument: `team`(optional) : Shall be a scalar of type `team_type` from + ISO_FORTRAN_ENV. + Result: The values of the image indices of the known stopped images + in the specified team, in numerically increasing order. + }]; + + let arguments = (ins Optional:$team); + let results = (outs fir_SequenceType); +} + +def mif_ImageStatusOp : mif_Op<"image_status", []> { + let summary = "Image execution state."; + let description = [{ + Arguments: + - `image`: Its value shall positive and less than or equal to the number + of images in the specified `team`. + - `team`(optional) : Shall be a scalar of type `team_type` from + ISO_FORTRAN_ENV. If `team` is absent, the team specified is the + current team. + Result: The values of the image indices of the known stopped images + in the specified team, in numerically increasing order. + }]; + + let arguments = (ins Optional:$team); + let results = (outs fir_SequenceType); +} + +//===----------------------------------------------------------------------===// +// MIF Queries +//===----------------------------------------------------------------------===// + +def mif_ImageIndexOp : mif_Op<"image_index", [AttrSizedOperandSegments]> { + let summary = "Image index from cosubscripts."; + let description = [{ + Arguments: + - `coarray`: Shall be a coarray of any type. + - `sub`: rank-one integer array of size equal to the corank of `coarray`. + Shall be a valid sequence of cosubscripts for `coarray` in the team + specified by `team` or `team_number`, or in the current team. + - `team`: Shall be a scalar of type `team_type` from ISO_FORTRAN_ENV. + - `team_number`: It shall identify the initial team or a sibling team + of the current team. + + Usage: + - Case(1) : `call image_index(coarray, sub)` + - Case(2) : `call image_index(coarray, sub, team)` + - Case(3) : `call image_index(coarray, sub, team_number)` + + Result: Return an integer scalar which represent the image index from `sub` + for `coarray`. + }]; + + let arguments = (ins fir_BoxType:$coarray, + fir_BoxType:$sub, + Optional:$team, + Optional:$team_number); + + let results = (outs AnyIntegerType); +} + +def mif_LcoboundOp : mif_Op<"lcobound", [NoMemoryEffect]> { + let summary = "Returns the lower cobound(s) associated with a coarray."; + let description = [{ + This operation returns the lower cobound(s) associated with a coarray. + Arguments: + - `coarray`: Shall be a coarray of any type. + - `dim` : Shall be an integer scalar. Its value shall be in the range of + `1 <= DIM <= N`, where `N` is the corank of the coarray. + Results: + - Case(1): If `dim` is present, the result is an integer scalar equal to + the lower cobound for codimension `dim`. + - Case(2): `dim` is absent, so the result is an array whose size matches + the corank of the indicated coarray. + }]; + + let arguments = (ins fir_BoxType:$coarray); + let results = (outs fir_SequenceType); +} + +def mif_UcoboundOp : mif_Op<"ucobound", [NoMemoryEffect]> { + let summary = "Returns the upper cobound(s) associated with a coarray."; + let description = [{ + This operation returns the upper cobound(s) associated with a coarray. + Arguments: + - `coarray`: Shall be a coarray of any type. + - `dim` : Shall be an integer scalar. Its value shall be in the range of + `1 <= DIM <= N`, where `N` is the corank of the coarray. + Results: + - Case(1): If `dim` is present, the result is an integer scalar equal to + the upper cobound for codimension `dim`. + - Case(2): `dim` is absent, so the result is an array whose size matches + the corank of the indicated coarray. + }]; + + let arguments = (ins fir_BoxType:$coarray); + let results = (outs fir_SequenceType); +} + +def mif_CoshapeOp : mif_Op<"coshape", [NoMemoryEffect]> { + let summary = "Return the sizes of codimensions of a coarray."; + let description = [{ + Argument: `coarray`: Shall be a coarray of any type. + Result : Is an array whose size matches the corank of the indicated coarray and + returns `UCOBOUND - LCOBOUND + 1`. + }]; + + let arguments = (ins fir_BoxType:$coarray); + let results = (outs fir_SequenceType); +} + +//===----------------------------------------------------------------------===// +// Allocation and Deallocation +//===----------------------------------------------------------------------===// + +def mif_AllocateOp + : mif_Op<"allocate", [MemoryEffects<[MemAlloc]>]> { + let summary = "Perform the allocation of a coarray and provide a " + "corresponding coarray descriptor"; + + let description = [{ + This operation allocates a coarray and provides a handle referencing a + corresponding coarray descriptor. This call is collective over the + current team. + }]; + + let arguments = (ins fir_SequenceType:$lcobounds, + fir_SequenceType:$ucobound, + I64:$size_in_bytes, + FuncType:$final_func, + Arg:$coarray_desc, + Arg:$allocated_memory, + Arg, "", [MemWrite]>:$errmsg); + + let results = (outs AnyIntegerType:$stat); + + let hasVerifier = 1; +} + +def mif_DeallocateOp + : mif_Op<"deallocate", [MemoryEffects<[MemFree]>]> { + let summary = "Perform the deallocation of a coarray"; + let description = [{ + The coarray.deallocate will releases memory allocated of an allocatable + coarray. + }]; + let arguments = (ins Arg:$coarray, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); + + let hasVerifier = 1; +} + +def mif_AliasCreateOp : mif_Op<"alias_create", []> { + let summary = "Create a new coarray descriptor aliased."; + + let arguments = (ins AnyRefOrBoxType:$coarray_desc, + fir_SequenceType:$lcobounds, + fir_SequenceType:$ucobound); + let results = (outs fir_BoxType); +} + +def mif_AliasDestroyOp : mif_Op<"alias_destroy", []> { + let summary = "Delete an alias descriptor."; + + let arguments = (ins AnyRefOrBoxType:$coarray_desc, + fir_SequenceType:$lcobounds, + fir_SequenceType:$ucobound); + let results = (outs fir_BoxType); +} + +//===----------------------------------------------------------------------===// +// Synchronization +//===----------------------------------------------------------------------===// + +def mif_SyncAllOp : mif_Op<"sync_all", []> { + let summary = + "Performs a collective synchronization of all images in the current team"; + + let arguments = (ins Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_SyncImagesOp : mif_Op<"sync_images", []> { + let summary = "Performs a synchronization of image with each of the other " + "images in the `image_set`"; + + let arguments = (ins fir_SequenceType:$image_set, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); + let hasVerifier = 1; +} + +def mif_SyncMemoryOp : mif_Op<"sync_memory", []> { + let summary = "Operation that ends one segment and begins another."; + let description = [{ + Operation that ends one segment and begins another; Those two segments can + be ordered by user-defined way with respect to segments on other images. + }]; + + let arguments = (ins Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_SyncTeamOp : mif_Op<"sync_team", []> { + let summary = + "Performs a synchronization of the team, identified by `team_value`"; + + let arguments = (ins Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +//===----------------------------------------------------------------------===// +// Locks +//===----------------------------------------------------------------------===// + +def mif_LockOp : mif_Op<"lock", [AttrSizedOperandSegments]> { + let summary = + "Wait until an identified lock variable is unlocked and then locks."; + let description = [{ + A lock variable is defined atomically by a LOCK or UNLOCK statement. + This opearation on multiple images attempt to acquire a lock, one will + succeed and the others will either fail if `acquired_lock` is present, + or will wait until the lock is later released if `acquired_lock` does not + appear. + + Arguments: + - `image_num`: Shall be an integer that correspond to the image index of + the lock variable to be locked. + - `lock_var` : Shall be a coarray of type LOCK_TYPE from the intrinsic + module ISO_FORTRAN_ENV. + - `acquired_lock (optional)` : Shall be a logical scalar variable. + }]; + + let arguments = (ins AnyIntegerType:$image_num, fir_BoxType:$lock_var, + Optional:$acquired_lock, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_UnlockOp : mif_Op<"unlock", []> { + let summary = "The lock variable become unlocked."; + let description = [{ + A lock variable is defined atomically by a LOCK or UNLOCK statement. + This operation, for an identified lock variable, will unlock the the variable. + + Arguments: + - `image_num`: Shall be an integer that correspond to the image index of + the lock variable to be locked. + - `lock_var` : Shall be a coarray of type LOCK_TYPE from the intrinsic + module ISO_FORTRAN_ENV. + }]; + + let arguments = (ins AnyIntegerType:$image_num, fir_BoxType:$lock_var, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +//===----------------------------------------------------------------------===// +// Critical +//===----------------------------------------------------------------------===// + +def mif_CriticalOp : mif_Op<"critical", []> { + let summary = "Reprensent the CRITICAL statement on a specific coarray."; + let description = [{ + Fortran provide CRITICAL construct to limits execution of block to one + image at time. The compiler shall define a coarray and establish it in + the initial team. + }]; + + let arguments = (ins fir_BoxType:$coarray, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_EndCriticalOp : mif_Op<"end_critical", []> { + let summary = "Reprensent the END CRITICAL statement on a specific coarray."; + let description = [{ + Fortran provide CRITICAL construct to limits execution of block to one + image at time. The compiler shall define a coarray and establish it in + the initial team. + END CRITICAL statement will completes execution of the CRITICAL construct + associated to `coarray`. + }]; + + let arguments = (ins fir_BoxType:$coarray, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +//===----------------------------------------------------------------------===// +// Events and Notifications +//===----------------------------------------------------------------------===// + +def mif_EventPostOp : mif_Op<"event_post", []> { + let summary = "Posts an event."; + let description = [{ + Arguments: + - `image_num`: Shall be an integer that correspond to the image index of + the event variable. + - `event_var`: Shall be a coarray of type EVENT_TYPE from the intrinsic + module ISO_FORTRAN_ENV. + }]; + + let arguments = (ins AnyIntegerType:$image_num, fir_BoxType:$event_var, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_EventWaitOp : mif_Op<"event_wait", [AttrSizedOperandSegments]> { + let summary = "Waits until an event is posted."; + let description = [{ + Arguments: + - `event_var`: Shall be a coarray of type EVENT_TYPE from the intrinsic + module ISO_FORTRAN_ENV. + - `until_count` : Shall be an integer scalar and indicate the count of + the given event variable to be waited for. + }]; + + let arguments = (ins fir_BoxType:$event_var, + Optional:$until_count, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_EventQueryOp : mif_Op<"event_query", []> { + let summary = "Query the count of an event on the calling image."; + let description = [{ + Argument: `event_var` shall be a coarray of type EVENT_TYPE from the intrinsic + module ISO_FORTRAN_ENV. + Result: `count` shall be an integer scalar and indicate the current count + of event variables. + }]; + + let arguments = (ins fir_BoxType:$event_var); + let results = (outs AnyIntegerType:$count, AnyIntegerType:$stat); +} + +def mif_NotifyWaitOp : mif_Op<"notify_wait", [AttrSizedOperandSegments]> { + let summary = "Wait on notification of an incoming put operation."; + let description = [{ + Arguments: + - `event_var`: Shall be a coarray of type EVENT_TYPE from the intrinsic + module ISO_FORTRAN_ENV. + - `until_count` : Shall be an integer scalar and indicate the count of + the given event variable to be waited for. + }]; + + let arguments = (ins fir_BoxType:$event_var, + Optional:$until_count, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +//===----------------------------------------------------------------------===// +// Teams +//===----------------------------------------------------------------------===// + +def mif_FormTeamOp : mif_Op<"form_team", [AttrSizedOperandSegments]> { + let summary = + "Create a set of sibling teams whose parent team is the current team."; + let description = [{ + Create a new team for each unique `team_number` value specified. + Each executing image will belong to the team whose `team_number` is equal + to the value of team-number on that image, and `team_var` becomes defined + with a value that identifies that team. + + If `new_index` is specified, the image index of the executing image will take + this index in its new team. Otherwise, the new image index is processor + dependent. + + Arguments: + - `team_number`: Shall be a positive integer. + - `team_var` : Shall be a coarray of type TEAM_TYPE from the intrinsic + module ISO_FORTRAN_ENV. + - `new_index`: Shall be an integer that correspond to the index that + the calling image will have in the new team. + }]; + + let arguments = (ins AnyIntegerType:$team_number, + Arg:$team_var, + Optional:$new_index, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_ChangeTeamOp : mif_Op<"change_team", []> { + let summary = "Changes the current team."; + let description = [{ + Fortran provide CHANGE TEAM construct to changes the current team and + CHAND TEAM operation will change the current team to the specified new + team. + }]; + + let arguments = (ins fir_BoxType:$team, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_EndTeamOp : mif_Op<"end_team", []> { + let summary = "Changes the current team to the parent team."; + let description = [{ + Fortran provide CHANGE TEAM construct to changes the current team. + Executing END TEAM operation restores the current team to the original team + that was current for the CHANGE TEAM operation. + }]; + + let arguments = (ins Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_GetTeamOp : mif_Op<"get_team", []> { + let summary = "Get the team value for the current or ancestor team."; + let description = [{ + This operation get the team value for the current or ancestor team. + If `level` isn't present or has the value `CURRENT_TEAM` the returned + value is the current team. + `level` cane take one of the following constants : `INITIAL_TEAM`, + `PARENT_TEAM` or `CURRENT_TEAM` from the module ISO_FORTRAN_ENV. + }]; + + let arguments = (ins Optional:$level); + let results = (outs fir_BoxType:$team); +} + +def mif_TeamNumberOp : mif_Op<"team_number", []> { + let summary = "Get the team number"; + let description = [{ + Argument: `team` is optional and shall be a scalar of type TEAM_TYPE from + module ISO_FORTRAN_ENV and the vlaue idenfies the current or an ancestor team. + If `team` is absent, the team specified is the current team. + }]; + + let arguments = (ins Optional:$team); + let results = (outs AnyIntegerType); +} + +//===----------------------------------------------------------------------===// +// Atomic Operations +//===----------------------------------------------------------------------===// + +def mif_AtomicAddOp : mif_Op<"atomic_add", []> { + let summary = "Atomic addition"; + let description = [{ + Arguments: + - `image_num`: Shall be an integer that correspond to the image index of + `atom` where the operation need to be performed. + - `atom` and `value`: Shall be a coarray of type integer with kind ATOMIC_INT_KIND + from module ISO_FORTRAN_ENV. + }]; + + let arguments = (ins AnyIntegerType:$image_num, + fir_BoxType:$atom, + Arg:$value, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_AtomicAndOp : mif_Op<"atomic_and", []> { + let summary = "Atomic bitwise AND"; + let description = [{ + Arguments: + - `image_num`: Shall be an integer that correspond to the image index of + `atom` where the operation need to be performed. + - `atom` and `value`: Shall be a coarray of type integer with kind ATOMIC_INT_KIND + from module ISO_FORTRAN_ENV. + }]; + + let arguments = (ins AnyIntegerType:$image_num, + fir_BoxType:$atom, + Arg:$value, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_AtomicOrOp : mif_Op<"atomic_or", []> { + let summary = "Atomic bitwise OR"; + let description = [{ + Arguments: + - `image_num`: Shall be an integer that correspond to the image index of + `atom` where the operation need to be performed. + - `atom` and `value`: Shall be a coarray of type integer with kind ATOMIC_INT_KIND + from module ISO_FORTRAN_ENV. + }]; + + let arguments = (ins AnyIntegerType:$image_num, + fir_BoxType:$atom, + Arg:$value, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_AtomicXorOp : mif_Op<"atomic_xor", []> { + let summary = "Atomic bitwise XOR"; + let description = [{ + Arguments: + - `image_num`: Shall be an integer that correspond to the image index of + `atom` where the operation need to be performed. + - `atom` and `value`: Shall be a coarray of type integer with kind ATOMIC_INT_KIND + from module ISO_FORTRAN_ENV. + }]; + + let arguments = (ins AnyIntegerType:$image_num, + fir_BoxType:$atom, + Arg:$value, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_AtomicCasOp : mif_Op<"atomic_cas", []> { + let summary = "Atomic compare and swap"; + let description = [{ + Arguments: + - `image_num`: Shall be an integer that correspond to the image index of + `atom` where the operation need to be performed. + - `atom`, `old`, `new` and `compared`: Shall be a coarray of type integer with kind + ATOMIC_INT_KIND or ATOMIC_LOGICAL_KIND from module ISO_FORTRAN_ENV. They need to + have the same type and kind. + }]; + + let arguments = (ins AnyIntegerType:$image_num, + fir_BoxType:$atom, + Arg:$old, + Arg:$compare, + Arg:$new_val, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_AtomicDefineOp : mif_Op<"atomic_define", []> { + let summary = "Define a variable atomically"; + let description = [{ + Arguments: + - `image_num`: Shall be an integer that correspond to the image index of + `atom` where the operation need to be performed. + - `atom` and `value`: Shall be a coarray of type integer with kind ATOMIC_INT_KIND + or ATOMIC_LOGICAL_KIND from module ISO_FORTRAN_ENV. + }]; + + let arguments = (ins AnyIntegerType:$image_num, + fir_BoxType:$atom, + Arg:$value, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_AtomicRefOp : mif_Op<"atomic_ref", []> { + let summary = "Reference a variable atomically"; + let description = [{ + Arguments: + - `image_num`: Shall be an integer that correspond to the image index of + `atom` where the operation need to be performed. + - `atom` and `value`: Shall be a coarray of type integer with kind ATOMIC_INT_KIND + or ATOMIC_LOGICAL_KIND from module ISO_FORTRAN_ENV. + }]; + + let arguments = (ins AnyIntegerType:$image_num, + fir_BoxType:$atom, + Arg:$value, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +//===----------------------------------------------------------------------===// +// Collective Operations +//===----------------------------------------------------------------------===// + +def mif_CoBroadcastOp : mif_Op<"co_broadcast", [AttrSizedOperandSegments]> { + let summary = "Broadcast value to images."; + let description = [{ + The coarray.co_broadcast operation performs the computation of the sum + across images. + }]; + + let arguments = (ins fir_BoxType:$a, + Optional:$source_image, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_CoMaxOp : mif_Op<"co_max", [AttrSizedOperandSegments]> { + let summary = "Compute maximum value across images."; + let description = [{ + The coarray.co_max operation performs the computation of the maximum + across images. + }]; + + let arguments = (ins fir_BoxType:$a, + Optional:$result_image, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_CoMinOp : mif_Op<"co_min", [AttrSizedOperandSegments]> { + let summary = "Compute minimum value across images."; + let description = [{ + The coarray.co_min operation performs the computation of the minimum + across images. + }]; + + let arguments = (ins fir_BoxType:$a, + Optional:$result_image, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_CoReduceOp : mif_Op<"co_reduce", [AttrSizedOperandSegments]> { + let summary = "Generalized reduction across images."; + let description = [{ + The coarray.co_sum operation performs the reduction across images. + The `operation` argument shall be a function with exactly two arguments. + Each arguments and the result shall be scalar, nonallocatable, noncoarray, + nonpointer, nonpolymorphic data and with the same type and kind as the + argument `a` of the operation coarray.co_reduce. + }]; + + let arguments = (ins fir_BoxType:$a, + FuncType:$operation_arg, + Optional:$result_image, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_CoSumOp : mif_Op<"co_sum", [AttrSizedOperandSegments]> { + let summary = "Compute sum across images."; + let description = [{ + The coarray.co_sum operation performs the computation of the sum + across images. + }]; + + let arguments = (ins fir_BoxType:$a, + Optional:$result_image, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +//===----------------------------------------------------------------------===// +// Coarray Access Operations +//===----------------------------------------------------------------------===// + +def mif_GetOp : mif_Op<"get", []> { + let summary = "Fetch data in a coarray from an image number"; + + let arguments = (ins AnyIntegerType:$image_num, + Arg:$coarray, + I64:$offset, + I64:$size_in_bytes, + Arg:$dest, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +def mif_PutOp : mif_Op<"put", []> { + let summary = "Assign data to a coarray to an image number"; + + let arguments = (ins AnyIntegerType:$image_num, + Arg:$coarray, + I64:$offset, + I64:$size_in_bytes, + Arg:$src, + Arg, "", [MemWrite]>:$errmsg); + let results = (outs AnyIntegerType:$stat); +} + +#endif // FORTRAN_DIALECT_MIF_MIF_OPS From d701fcc2de2ea1fb61a612465badbfc82f878bf2 Mon Sep 17 00:00:00 2001 From: Jean-Didier Pailleux Date: Tue, 5 Aug 2025 15:36:30 +0200 Subject: [PATCH 2/4] [flang][MIF] Fix small mistakes in the MIF Operations file --- .../flang/Optimizer/Dialect/MIF/MIFOps.td | 172 ++++++++++-------- 1 file changed, 93 insertions(+), 79 deletions(-) diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td index d902bfdef4638..1f514192f7dc2 100644 --- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td +++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td @@ -48,7 +48,7 @@ def mif_StopOp : mif_Op<"stop", [AttrSizedOperandSegments]> { let arguments = (ins Optional:$quiet, Optional:$stop_code_int, - Arg, "", [MemWrite]>:$stop_code_char, + Optional:$stop_code_char, UnitAttr:$is_error); let hasVerifier = 1; @@ -73,7 +73,7 @@ def mif_NumImagesOp - `num_images(team)` - `num_images(team_number)` - Argumemnts: + Arguments: - `team` : Shall be a scalar of type `team_type` from the `ISO_FORTRAN_ENV` module with a value that identifies the current or ancestor team. - `team_number` : Shall be an integer scalar. It shall identify the @@ -112,7 +112,7 @@ def mif_ThisImageOp : mif_Op<"this_image", [AttrSizedOperandSegments]> { - Case(1) : The result of `this_image([team])` is a scalar with a value equal to the index of the image in the current or specified team. - Case(2) : The result of `this_image(coarray [,team])` is the sequence of - cosubscript vales for `coarray`. + cosubscript values for `coarray`. - Case(3) : The result of `this_image(coarray, dim [,team])` is the value of cosubscript `dim` in the sequence of cosubscript values for `coarray`. @@ -175,12 +175,14 @@ def mif_ImageStatusOp : mif_Op<"image_status", []> { - `team`(optional) : Shall be a scalar of type `team_type` from ISO_FORTRAN_ENV. If `team` is absent, the team specified is the current team. - Result: The values of the image indices of the known stopped images - in the specified team, in numerically increasing order. + Result: The result value is STAT_FAILED_IMAGE from the intrinsic module ISO_FORTRAN_ENV + if the specified image is known to has failed, STAT_STOPPED_IMAGE from the intrinsic + module ISO_FORTRAN_ENV if that image is known to have initiated normal termination, + and zero otherwise. }]; let arguments = (ins Optional:$team); - let results = (outs fir_SequenceType); + let results = (outs AnyIntegerType); } //===----------------------------------------------------------------------===// @@ -193,8 +195,6 @@ def mif_ImageIndexOp : mif_Op<"image_index", [AttrSizedOperandSegments]> { Arguments: - `coarray`: Shall be a coarray of any type. - `sub`: rank-one integer array of size equal to the corank of `coarray`. - Shall be a valid sequence of cosubscripts for `coarray` in the team - specified by `team` or `team_number`, or in the current team. - `team`: Shall be a scalar of type `team_type` from ISO_FORTRAN_ENV. - `team_number`: It shall identify the initial team or a sibling team of the current team. @@ -204,8 +204,10 @@ def mif_ImageIndexOp : mif_Op<"image_index", [AttrSizedOperandSegments]> { - Case(2) : `call image_index(coarray, sub, team)` - Case(3) : `call image_index(coarray, sub, team_number)` - Result: Return an integer scalar which represent the image index from `sub` - for `coarray`. + Result: If the value of `sub` is a valid sequence of cosubscripts for `coarray` in the + team specified by `team` or `team_number`, or the current team if neither `team` nor + `team_number` appears, the result is the index of the corresponding image in that team. + Otherwise, the result is zero. }]; let arguments = (ins fir_BoxType:$coarray, @@ -222,7 +224,7 @@ def mif_LcoboundOp : mif_Op<"lcobound", [NoMemoryEffect]> { This operation returns the lower cobound(s) associated with a coarray. Arguments: - `coarray`: Shall be a coarray of any type. - - `dim` : Shall be an integer scalar. Its value shall be in the range of + - `dim`(optional) : Shall be an integer scalar. Its value shall be in the range of `1 <= DIM <= N`, where `N` is the corank of the coarray. Results: - Case(1): If `dim` is present, the result is an integer scalar equal to @@ -231,7 +233,8 @@ def mif_LcoboundOp : mif_Op<"lcobound", [NoMemoryEffect]> { the corank of the indicated coarray. }]; - let arguments = (ins fir_BoxType:$coarray); + let arguments = (ins fir_BoxType:$coarray, + Optional:$dim); let results = (outs fir_SequenceType); } @@ -241,7 +244,7 @@ def mif_UcoboundOp : mif_Op<"ucobound", [NoMemoryEffect]> { This operation returns the upper cobound(s) associated with a coarray. Arguments: - `coarray`: Shall be a coarray of any type. - - `dim` : Shall be an integer scalar. Its value shall be in the range of + - `dim`(optional) : Shall be an integer scalar. Its value shall be in the range of `1 <= DIM <= N`, where `N` is the corank of the coarray. Results: - Case(1): If `dim` is present, the result is an integer scalar equal to @@ -250,7 +253,8 @@ def mif_UcoboundOp : mif_Op<"ucobound", [NoMemoryEffect]> { the corank of the indicated coarray. }]; - let arguments = (ins fir_BoxType:$coarray); + let arguments = (ins fir_BoxType:$coarray, + Optional:$dim); let results = (outs fir_SequenceType); } @@ -285,11 +289,11 @@ def mif_AllocateOp fir_SequenceType:$ucobound, I64:$size_in_bytes, FuncType:$final_func, - Arg:$coarray_desc, - Arg:$allocated_memory, Arg, "", [MemWrite]>:$errmsg); - let results = (outs AnyIntegerType:$stat); + let results = (outs fir_BoxType:$coarray_desc, + AnyRefOrBoxType:$allocated_memory, + AnyIntegerType:$stat); let hasVerifier = 1; } @@ -298,11 +302,10 @@ def mif_DeallocateOp : mif_Op<"deallocate", [MemoryEffects<[MemFree]>]> { let summary = "Perform the deallocation of a coarray"; let description = [{ - The coarray.deallocate will releases memory allocated of an allocatable - coarray. + This call releases memory allocated by `mif_AllocateOp` for a coarray. }]; let arguments = (ins Arg:$coarray, - Arg, "", [MemWrite]>:$errmsg); + Arg, "", [MemWrite]>:$errmsg); let results = (outs AnyIntegerType:$stat); let hasVerifier = 1; @@ -310,20 +313,24 @@ def mif_DeallocateOp def mif_AliasCreateOp : mif_Op<"alias_create", []> { let summary = "Create a new coarray descriptor aliased."; + let description = [{ + Arguments: + `alias_lcobounds` and `alias_ucobounds` are the new cobounds to be used + for the new alias. + Result : Is a new coarray that aliases the data in the existing coarray + in argument. + }]; - let arguments = (ins AnyRefOrBoxType:$coarray_desc, - fir_SequenceType:$lcobounds, - fir_SequenceType:$ucobound); + let arguments = (ins AnyRefOrBoxType:$coarray, + fir_SequenceType:$alias_lcobounds, + fir_SequenceType:$alias_ucobound); let results = (outs fir_BoxType); } def mif_AliasDestroyOp : mif_Op<"alias_destroy", []> { let summary = "Delete an alias descriptor."; - let arguments = (ins AnyRefOrBoxType:$coarray_desc, - fir_SequenceType:$lcobounds, - fir_SequenceType:$ucobound); - let results = (outs fir_BoxType); + let arguments = (ins AnyRefOrBoxType:$coarray); } //===----------------------------------------------------------------------===// @@ -363,7 +370,8 @@ def mif_SyncTeamOp : mif_Op<"sync_team", []> { let summary = "Performs a synchronization of the team, identified by `team_value`"; - let arguments = (ins Arg, "", [MemWrite]>:$errmsg); + let arguments = (ins fir_BoxType:$team, + ins Arg, "", [MemWrite]>:$errmsg); let results = (outs AnyIntegerType:$stat); } @@ -390,7 +398,7 @@ def mif_LockOp : mif_Op<"lock", [AttrSizedOperandSegments]> { }]; let arguments = (ins AnyIntegerType:$image_num, fir_BoxType:$lock_var, - Optional:$acquired_lock, + Arg, "", [MemWrite]>:$acquired_lock, Arg, "", [MemWrite]>:$errmsg); let results = (outs AnyIntegerType:$stat); } @@ -470,7 +478,7 @@ def mif_EventWaitOp : mif_Op<"event_wait", [AttrSizedOperandSegments]> { Arguments: - `event_var`: Shall be a coarray of type EVENT_TYPE from the intrinsic module ISO_FORTRAN_ENV. - - `until_count` : Shall be an integer scalar and indicate the count of + - `until_count`(optional) : Shall be an integer scalar and indicate the count of the given event variable to be waited for. }]; @@ -497,13 +505,13 @@ def mif_NotifyWaitOp : mif_Op<"notify_wait", [AttrSizedOperandSegments]> { let summary = "Wait on notification of an incoming put operation."; let description = [{ Arguments: - - `event_var`: Shall be a coarray of type EVENT_TYPE from the intrinsic + - `notify_var`: Shall be a coarray of type NOTIFY_TYPE from the intrinsic module ISO_FORTRAN_ENV. - - `until_count` : Shall be an integer scalar and indicate the count of - the given event variable to be waited for. + - `until_count`(optional) : Shall be an integer scalar and indicate the count of + the given notify variable to be waited for. }]; - let arguments = (ins fir_BoxType:$event_var, + let arguments = (ins fir_BoxType:$notify_var, Optional:$until_count, Arg, "", [MemWrite]>:$errmsg); let results = (outs AnyIntegerType:$stat); @@ -528,9 +536,9 @@ def mif_FormTeamOp : mif_Op<"form_team", [AttrSizedOperandSegments]> { Arguments: - `team_number`: Shall be a positive integer. - - `team_var` : Shall be a coarray of type TEAM_TYPE from the intrinsic + - `team_var` : Shall be a variable of type TEAM_TYPE from the intrinsic module ISO_FORTRAN_ENV. - - `new_index`: Shall be an integer that correspond to the index that + - `new_index`(optional): Shall be an integer that correspond to the index that the calling image will have in the new team. }]; @@ -544,9 +552,8 @@ def mif_FormTeamOp : mif_Op<"form_team", [AttrSizedOperandSegments]> { def mif_ChangeTeamOp : mif_Op<"change_team", []> { let summary = "Changes the current team."; let description = [{ - Fortran provide CHANGE TEAM construct to changes the current team and - CHAND TEAM operation will change the current team to the specified new - team. + The CHANGE TEAM construct changes the current team to the specified new + team, which must be a child team of the current team. }]; let arguments = (ins fir_BoxType:$team, @@ -557,9 +564,9 @@ def mif_ChangeTeamOp : mif_Op<"change_team", []> { def mif_EndTeamOp : mif_Op<"end_team", []> { let summary = "Changes the current team to the parent team."; let description = [{ - Fortran provide CHANGE TEAM construct to changes the current team. - Executing END TEAM operation restores the current team to the original team - that was current for the CHANGE TEAM operation. + The END TEAM operation completes the CHANGE TEAM construct and + restores the current team to the team that was current before + the CHANGE TEAM construct. }]; let arguments = (ins Arg, "", [MemWrite]>:$errmsg); @@ -569,11 +576,11 @@ def mif_EndTeamOp : mif_Op<"end_team", []> { def mif_GetTeamOp : mif_Op<"get_team", []> { let summary = "Get the team value for the current or ancestor team."; let description = [{ - This operation get the team value for the current or ancestor team. + This operation gets the team value for the current or an ancestor team. + `level`(optional): If provided, must equal one of the following constants : + `INITIAL_TEAM`, `PARENT_TEAM` or `CURRENT_TEAM` from the module ISO_FORTRAN_ENV. If `level` isn't present or has the value `CURRENT_TEAM` the returned - value is the current team. - `level` cane take one of the following constants : `INITIAL_TEAM`, - `PARENT_TEAM` or `CURRENT_TEAM` from the module ISO_FORTRAN_ENV. + value is the current team. }]; let arguments = (ins Optional:$level); @@ -584,7 +591,7 @@ def mif_TeamNumberOp : mif_Op<"team_number", []> { let summary = "Get the team number"; let description = [{ Argument: `team` is optional and shall be a scalar of type TEAM_TYPE from - module ISO_FORTRAN_ENV and the vlaue idenfies the current or an ancestor team. + module ISO_FORTRAN_ENV and the value identifies the current or an ancestor team. If `team` is absent, the team specified is the current team. }]; @@ -602,13 +609,14 @@ def mif_AtomicAddOp : mif_Op<"atomic_add", []> { Arguments: - `image_num`: Shall be an integer that correspond to the image index of `atom` where the operation need to be performed. - - `atom` and `value`: Shall be a coarray of type integer with kind ATOMIC_INT_KIND + - `atom`: Shall be a coarray of type integer with kind ATOMIC_INT_KIND from module ISO_FORTRAN_ENV. + - `value`: Shall be a scalar integer with kind ATOMIC_INT_KIND. }]; let arguments = (ins AnyIntegerType:$image_num, - fir_BoxType:$atom, - Arg:$value, + AnyIntegerType:$atom, + Arg:$value, Arg, "", [MemWrite]>:$errmsg); let results = (outs AnyIntegerType:$stat); } @@ -619,13 +627,14 @@ def mif_AtomicAndOp : mif_Op<"atomic_and", []> { Arguments: - `image_num`: Shall be an integer that correspond to the image index of `atom` where the operation need to be performed. - - `atom` and `value`: Shall be a coarray of type integer with kind ATOMIC_INT_KIND + - `atom`: Shall be a coarray of type integer with kind ATOMIC_INT_KIND from module ISO_FORTRAN_ENV. + - `value`: Shall be a scalar integer with kind ATOMIC_INT_KIND. }]; let arguments = (ins AnyIntegerType:$image_num, - fir_BoxType:$atom, - Arg:$value, + AnyIntegerType:$atom, + Arg:$value, Arg, "", [MemWrite]>:$errmsg); let results = (outs AnyIntegerType:$stat); } @@ -636,13 +645,14 @@ def mif_AtomicOrOp : mif_Op<"atomic_or", []> { Arguments: - `image_num`: Shall be an integer that correspond to the image index of `atom` where the operation need to be performed. - - `atom` and `value`: Shall be a coarray of type integer with kind ATOMIC_INT_KIND + - `atom`: Shall be a coarray of type integer with kind ATOMIC_INT_KIND from module ISO_FORTRAN_ENV. + - `value`: Shall be a scalar integer with kind ATOMIC_INT_KIND. }]; let arguments = (ins AnyIntegerType:$image_num, - fir_BoxType:$atom, - Arg:$value, + AnyIntegerType:$atom, + Arg:$value, Arg, "", [MemWrite]>:$errmsg); let results = (outs AnyIntegerType:$stat); } @@ -653,13 +663,14 @@ def mif_AtomicXorOp : mif_Op<"atomic_xor", []> { Arguments: - `image_num`: Shall be an integer that correspond to the image index of `atom` where the operation need to be performed. - - `atom` and `value`: Shall be a coarray of type integer with kind ATOMIC_INT_KIND + - `atom`: Shall be a coarray of type integer with kind ATOMIC_INT_KIND from module ISO_FORTRAN_ENV. + - `value`: Shall be a scalar integer with kind ATOMIC_INT_KIND. }]; let arguments = (ins AnyIntegerType:$image_num, - fir_BoxType:$atom, - Arg:$value, + AnyIntegerType:$atom, + Arg:$value, Arg, "", [MemWrite]>:$errmsg); let results = (outs AnyIntegerType:$stat); } @@ -670,16 +681,17 @@ def mif_AtomicCasOp : mif_Op<"atomic_cas", []> { Arguments: - `image_num`: Shall be an integer that correspond to the image index of `atom` where the operation need to be performed. - - `atom`, `old`, `new` and `compared`: Shall be a coarray of type integer with kind - ATOMIC_INT_KIND or ATOMIC_LOGICAL_KIND from module ISO_FORTRAN_ENV. They need to - have the same type and kind. + - `atom`: Shall be a coarray of type integer with kind + ATOMIC_INT_KIND or ATOMIC_LOGICAL_KIND from module ISO_FORTRAN_ENV + - `old`, `new` and `compared`: Shall be a scalar integer with kind ATOMIC_LOGICAL_KIND. + They need to have the same type and kind as `atom`. }]; let arguments = (ins AnyIntegerType:$image_num, - fir_BoxType:$atom, - Arg:$old, - Arg:$compare, - Arg:$new_val, + AnyIntegerType:$atom, + Arg:$old, + Arg:$compare, + Arg:$new_val, Arg, "", [MemWrite]>:$errmsg); let results = (outs AnyIntegerType:$stat); } @@ -690,13 +702,14 @@ def mif_AtomicDefineOp : mif_Op<"atomic_define", []> { Arguments: - `image_num`: Shall be an integer that correspond to the image index of `atom` where the operation need to be performed. - - `atom` and `value`: Shall be a coarray of type integer with kind ATOMIC_INT_KIND + - `atom`: Shall be a coarray of type integer with kind ATOMIC_INT_KIND + - `value`: Shall be a scalar integer with kind ATOMIC_INT_KIND or ATOMIC_LOGICAL_KIND from module ISO_FORTRAN_ENV. }]; let arguments = (ins AnyIntegerType:$image_num, - fir_BoxType:$atom, - Arg:$value, + AnyIntegerType:$atom, + Arg:$value, Arg, "", [MemWrite]>:$errmsg); let results = (outs AnyIntegerType:$stat); } @@ -707,13 +720,14 @@ def mif_AtomicRefOp : mif_Op<"atomic_ref", []> { Arguments: - `image_num`: Shall be an integer that correspond to the image index of `atom` where the operation need to be performed. - - `atom` and `value`: Shall be a coarray of type integer with kind ATOMIC_INT_KIND + - `atom`: Shall be a coarray of type integer with kind ATOMIC_INT_KIND + - `value`: Shall be a scalar integer with kind ATOMIC_INT_KIND or ATOMIC_LOGICAL_KIND from module ISO_FORTRAN_ENV. }]; let arguments = (ins AnyIntegerType:$image_num, - fir_BoxType:$atom, - Arg:$value, + AnyIntegerType:$atom, + Arg:$value, Arg, "", [MemWrite]>:$errmsg); let results = (outs AnyIntegerType:$stat); } @@ -725,12 +739,12 @@ def mif_AtomicRefOp : mif_Op<"atomic_ref", []> { def mif_CoBroadcastOp : mif_Op<"co_broadcast", [AttrSizedOperandSegments]> { let summary = "Broadcast value to images."; let description = [{ - The coarray.co_broadcast operation performs the computation of the sum + The co_broadcast operation performs the computation of the sum across images. }]; let arguments = (ins fir_BoxType:$a, - Optional:$source_image, + AnyIntegerType:$source_image, Arg, "", [MemWrite]>:$errmsg); let results = (outs AnyIntegerType:$stat); } @@ -738,7 +752,7 @@ def mif_CoBroadcastOp : mif_Op<"co_broadcast", [AttrSizedOperandSegments]> { def mif_CoMaxOp : mif_Op<"co_max", [AttrSizedOperandSegments]> { let summary = "Compute maximum value across images."; let description = [{ - The coarray.co_max operation performs the computation of the maximum + The co_max operation performs the computation of the maximum across images. }]; @@ -751,7 +765,7 @@ def mif_CoMaxOp : mif_Op<"co_max", [AttrSizedOperandSegments]> { def mif_CoMinOp : mif_Op<"co_min", [AttrSizedOperandSegments]> { let summary = "Compute minimum value across images."; let description = [{ - The coarray.co_min operation performs the computation of the minimum + The co_min operation performs the computation of the minimum across images. }]; @@ -764,11 +778,11 @@ def mif_CoMinOp : mif_Op<"co_min", [AttrSizedOperandSegments]> { def mif_CoReduceOp : mif_Op<"co_reduce", [AttrSizedOperandSegments]> { let summary = "Generalized reduction across images."; let description = [{ - The coarray.co_sum operation performs the reduction across images. + The co_sum operation performs the reduction across images. The `operation` argument shall be a function with exactly two arguments. Each arguments and the result shall be scalar, nonallocatable, noncoarray, nonpointer, nonpolymorphic data and with the same type and kind as the - argument `a` of the operation coarray.co_reduce. + argument `a` of the operation co_reduce. }]; let arguments = (ins fir_BoxType:$a, @@ -781,7 +795,7 @@ def mif_CoReduceOp : mif_Op<"co_reduce", [AttrSizedOperandSegments]> { def mif_CoSumOp : mif_Op<"co_sum", [AttrSizedOperandSegments]> { let summary = "Compute sum across images."; let description = [{ - The coarray.co_sum operation performs the computation of the sum + The co_sum operation performs the computation of the sum across images. }]; From d8da4ec4e110ebd6d060158ec18302c7a0f05eb9 Mon Sep 17 00:00:00 2001 From: Jean-Didier PAILLEUX Date: Fri, 22 Aug 2025 08:15:20 +0200 Subject: [PATCH 3/4] Update flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td Co-authored-by: Dan Bonachea --- .../flang/Optimizer/Dialect/MIF/MIFOps.td | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td index 1f514192f7dc2..45ff0348c4c3e 100644 --- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td +++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td @@ -37,13 +37,21 @@ def mif_InitOp : mif_Op<"init", []> { } def mif_StopOp : mif_Op<"stop", [AttrSizedOperandSegments]> { - let summary = "Operation that synchronizes all execution images, clean up the" - "parallel runtime environment, and terminates the program."; - let description = [{ - This operation synchronizes all executing images, cleans up the parallel - runtime environment, and terminates the program. Calls to this operation do - not return. This operation supports both normal termination at the end of a - program, as well as any STOP statements from the user source code. + let summary = "Initiates normal or error termination of the prorgram"; + let description = [{ + When `is_error` is false: + This operation initiates normal termination for the calling image. + It synchronizes all executing images, cleans up the parallel runtime environment, + and then terminates the program. + Calls to this operation do not return. + This operation supports both normal termination at the end of a + program, as well as any STOP statements from the user source code. + When `is_error` is true: + This operation initiates error termination for all images. + This operation immediately terminates the program. + Calls to this operation do not return. + This operation supports error termination, such as from any + ERROR STOP statements in the user program. }]; let arguments = (ins Optional:$quiet, From 857debcb579f26f4c28f408a6655ff9d9bf14004 Mon Sep 17 00:00:00 2001 From: Jean-Didier PAILLEUX Date: Fri, 22 Aug 2025 08:16:30 +0200 Subject: [PATCH 4/4] Update flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td Co-authored-by: Dan Bonachea --- flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td index 45ff0348c4c3e..06d929a3543a6 100644 --- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td +++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td @@ -376,7 +376,7 @@ def mif_SyncMemoryOp : mif_Op<"sync_memory", []> { def mif_SyncTeamOp : mif_Op<"sync_team", []> { let summary = - "Performs a synchronization of the team, identified by `team_value`"; + "Performs a synchronization of the team, identified by `team`"; let arguments = (ins fir_BoxType:$team, ins Arg, "", [MemWrite]>:$errmsg);