Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
52b962a
Changes to OpenMP scripts to extract arguments from iom_put
LonelyCat124 Mar 13, 2026
dae4e86
transformation can't always work so catch exception
LonelyCat124 Mar 13, 2026
34aeaac
Merge branch 'master' into iom_put_to_temp_
LonelyCat124 Mar 13, 2026
a95ece0
fix to datanode to temp tarns to handle case sensitivity correctly vi…
LonelyCat124 Mar 16, 2026
d79fae1
Merge branch 'iom_put_to_temp_' of github.com:stfc/PSyclone into iom_…
LonelyCat124 Mar 16, 2026
46d6dfa
Merge branch 'master' into iom_put_to_temp_
LonelyCat124 Mar 16, 2026
6339e55
Merge branch 'master' into iom_put_to_temp_
LonelyCat124 Mar 17, 2026
6ce8a38
Try extending the iom_put transformation
LonelyCat124 Mar 17, 2026
7c98fd4
Merge branch 'iom_put_to_temp_' of github.com:stfc/PSyclone into iom_…
LonelyCat124 Mar 17, 2026
dd3e62a
fix
LonelyCat124 Mar 17, 2026
e06176b
Fix datanodetotemptrans for ifblock statements and similar
LonelyCat124 Mar 17, 2026
ed69361
Use elemental_type in intrinsic_call
LonelyCat124 Mar 17, 2026
af9ea3d
Merge master and fix intrinsic call change
LonelyCat124 Apr 1, 2026
a912e88
Fixed the TypeError branch
LonelyCat124 Apr 2, 2026
78127da
Changed the InternalError to be a fallthrough
LonelyCat124 Apr 2, 2026
c3804eb
Store the error to fallthrough to internal error correctly
LonelyCat124 Apr 2, 2026
0420aa4
precision handling for the TypeError
LonelyCat124 Apr 2, 2026
470ed98
Added an if allocated test and check that we don't block potential lo…
LonelyCat124 Apr 7, 2026
cf4947e
[skip-ci] Some changes to add test (that fails) for the datanode_to_t…
LonelyCat124 Apr 7, 2026
c6c718c
Don't try to move the allocate statement which wasn't very feasible f…
LonelyCat124 Apr 7, 2026
03e0ffa
Hoist the allocate statement if we think its safe
LonelyCat124 Apr 8, 2026
93d814c
Merge branch 'master' into iom_put_to_temp_
LonelyCat124 Apr 8, 2026
f147e94
updated script error
LonelyCat124 Apr 8, 2026
339f8b4
Revert to only apply to iom_put
LonelyCat124 Apr 16, 2026
d9cced4
Merge branch 'master' into iom_put_to_temp_
LonelyCat124 Apr 16, 2026
51f5e71
Merge branch 'master' into iom_put_to_temp_
LonelyCat124 Apr 21, 2026
4fb5d7b
Remaining test coverage and fixed a missing fstring in fparser2 frontend
LonelyCat124 Apr 21, 2026
65fa992
Merg master
LonelyCat124 Apr 21, 2026
19d77ef
Merge branch 'master' into iom_put_to_temp_
LonelyCat124 Apr 21, 2026
fa35a58
Some changes towards review
LonelyCat124 Apr 23, 2026
78b4345
Revert changes due to issue with structure reference's datatype
LonelyCat124 Apr 24, 2026
93c0b20
linting
LonelyCat124 Apr 24, 2026
51c250a
DataNodeToTempTrans will sometimes not make an allocatable if the com…
LonelyCat124 Apr 24, 2026
5ad2f3e
Merge branch 'master' into iom_put_to_temp_
LonelyCat124 Apr 24, 2026
18dae4e
Changes for review
LonelyCat124 Apr 27, 2026
b89289f
changes for review
LonelyCat124 Apr 27, 2026
2fb2364
Merge branch 'master' into iom_put_to_temp_
sergisiso Apr 28, 2026
20ba60a
#3412 Update changelog
sergisiso Apr 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
13) PR #3373 towards #3412. Extract argument expressions from NEMO iom_put
calls in order to parallelise/offload their implicit loops.

12) PR #3408 for #2812. Updates the Min/Max to code transformations so
that they use the datatype of their arguments rather than assuming real.
Also skips treesitter tests for Python < 3.10.
Expand Down
3 changes: 2 additions & 1 deletion examples/nemo/scripts/omp_cpu_trans.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ def trans(psyir):
loopify_array_intrinsics=True,
convert_range_loops=True,
hoist_expressions=False,
scalarise_loops=False
scalarise_loops=False,
hoist_argument_expressions=True
)

if psyir.name not in PARALLELISATION_ISSUES:
Expand Down
3 changes: 2 additions & 1 deletion examples/nemo/scripts/omp_gpu_trans.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ def trans(psyir):
loopify_array_intrinsics=True,
convert_range_loops=True,
increase_array_ranks=not NEMOV4,
hoist_expressions=True
hoist_expressions=True,
hoist_argument_expressions=True,
)
# Perform module-inlining of called routines.
if INLINING_ENABLED:
Expand Down
38 changes: 34 additions & 4 deletions examples/nemo/scripts/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@
from psyclone.domain.common.transformations import KernelModuleInlineTrans
from psyclone.psyir.nodes import (
Assignment, Loop, Directive, Node, Reference, CodeBlock, Call,
Routine, Schedule, IntrinsicCall, StructureReference, IfBlock)
from psyclone.psyir.symbols import DataSymbol
Routine, Schedule, IntrinsicCall, StructureReference, IfBlock,
Operation)
from psyclone.psyir.symbols import DataSymbol, ArrayType
from psyclone.psyir.transformations import (
ArrayAssignment2LoopsTrans, HoistLoopBoundExprTrans, HoistLocalArraysTrans,
HoistTrans, InlineTrans, Maxval2LoopTrans, Sum2LoopTrans, Minval2LoopTrans,
Product2LoopTrans, ProfileTrans, OMPMinimiseSyncTrans,
Reference2ArrayRangeTrans, ScalarisationTrans, IncreaseRankLoopArraysTrans,
MaximalRegionTrans)
from psyclone.transformations import TransformationError
MaximalRegionTrans, TransformationError, DataNodeToTempTrans)

# USE statements to chase to gather additional symbol information.
NEMO_MODULES_TO_IMPORT = [
Expand Down Expand Up @@ -181,6 +181,7 @@ def normalise_loops(
scalarise_loops: bool = False,
increase_array_ranks: bool = False,
hoist_expressions: bool = True,
hoist_argument_expressions: bool = True,
):
''' Normalise all loops in the given schedule so that they are in an
appropriate form for the Parallelisation transformations to analyse
Expand All @@ -201,7 +202,14 @@ def normalise_loops(
arrays.
:param hoist_expressions: whether to hoist bounds and loop invariant
statements out of the loop nest.
:param hoist_argument_expressions: whether to hoist array expressions
out of the containing Call.
'''
# TODO #3412: This is currently limited to iom_put, we want to expand it
# throughout the code
if hoist_argument_expressions:
iom_put_argument_to_temporary(schedule.walk(Call))

if hoist_local_arrays and schedule.name not in CONTAINS_STMT_FUNCTIONS:
# Apply the HoistLocalArraysTrans when possible, it cannot be applied
# to files with statement functions because it will attempt to put the
Expand Down Expand Up @@ -530,3 +538,25 @@ def _satisfies_minimum_region_rules(self, region: list[Node]) -> bool:
routine_name = parent_routine.name if parent_routine else ""
if routine_name not in PROFILING_IGNORE:
MaximalProfilingOutsideDirectivesTrans().apply(children)


def iom_put_argument_to_temporary(calls: list[Call]):
Comment thread
sergisiso marked this conversation as resolved.
'''Extracts the second argument of all iom_put calls and puts them
in a temporary if they are an Operation with an array datatype.

:param calls: The list of calls in a subroutine whose arguments
may be moved into temporary storage to allow additional potential
parallelisation.

'''
for call in calls:
if call.symbol.name == "iom_put":
for arg in call.arguments:
dtype = arg.datatype
if (isinstance(dtype, ArrayType) and
(isinstance(arg, Operation) or
isinstance(arg, IntrinsicCall))):
try:
DataNodeToTempTrans().apply(arg, verbose=True)
except TransformationError:
pass
4 changes: 2 additions & 2 deletions src/psyclone/psyir/frontend/fparser2.py
Original file line number Diff line number Diff line change
Expand Up @@ -1112,8 +1112,8 @@ def _fparser2_tree_from_fparser2_reader(
except (FortranSyntaxError, NoMatchError) as err:
raise ValueError(
f"Failed to parse the provided source code:\n{source_code}"
"\nError was: {err}\nIs the input valid Fortran (note that"
f" CPP directives must be handled by a pre-processor)?"
f"\nError was: {err}\nIs the input valid Fortran (note "
f"that CPP directives must be handled by a pre-processor)?"
) from err
try:
# If it reaches this point a partial_code was provided, attempt
Expand Down
45 changes: 34 additions & 11 deletions src/psyclone/psyir/nodes/intrinsic_call.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,8 @@ def _iparity_return_type(node: IntrinsicCall) -> DataType:

:returns: the computed datatype for the IntrinsicCall.
"""
# TODO #3415: Replace with _type_of_named_arg_accounting_for_dim_arg(
# node, "array").
dtype = ScalarType(
node.argument_by_name("array").datatype.intrinsic,
node.argument_by_name("array").datatype.precision,
Expand Down Expand Up @@ -565,8 +567,13 @@ def _maxval_return_type(node: IntrinsicCall) -> DataType:

:returns: the computed datatype for the IntrinsicCall.
"""
# TODO #3415: Replace with _type_of_named_arg_accounting_for_dim_arg(
# node, "array").
dtype = ScalarType(
Comment thread
sergisiso marked this conversation as resolved.
node.argument_by_name("array").datatype.intrinsic,
node.argument_by_name("array").datatype.precision
)
arg = node.argument_by_name("array")
dtype = arg.datatype.elemental_type
if "dim" not in node.argument_names:
return dtype
# We have a dimension specified. We don't know the resultant shape
Expand All @@ -588,8 +595,8 @@ def _dot_product_return_type(node: IntrinsicCall) -> DataType:
from psyclone.psyir.tools.type_info_computation import (
compute_scalar_type
)
veca_datatype = node.argument_by_name("vector_a").datatype
vecb_datatype = node.argument_by_name("vector_b").datatype
veca_datatype = node.argument_by_name("vector_a").datatype.elemental_type
Comment thread
sergisiso marked this conversation as resolved.
vecb_datatype = node.argument_by_name("vector_b").datatype.elemental_type
return compute_scalar_type(
[ScalarType(
veca_datatype.intrinsic, veca_datatype.precision
Expand Down Expand Up @@ -3215,7 +3222,8 @@ class Intrinsic(IAttr, Enum):
optional_args={"kind": DataNode},
return_type=lambda node: (
_type_of_scalar_with_optional_kind(
node, node.argument_by_name("l").datatype.intrinsic,
node,
node.argument_by_name("l").datatype.intrinsic,
"kind",
) if "kind" in node.argument_names else
_type_of_named_argument(node, "l")
Expand Down Expand Up @@ -4897,7 +4905,20 @@ def datatype(self) -> DataType:
if isinstance(self.intrinsic.return_type, Callable):
try:
return self.intrinsic.return_type(self)
except TypeError as err:
Comment thread
sergisiso marked this conversation as resolved.
# If we get an invalid argument to a ScalarType constructor it
# means we attempted to pass either an UnresolvedType into the
# datatype
if ("ScalarType expected 'intrinsic' argument to be of type "
in str(err)
or "ScalarType expected 'precision' argument to be of "
"type " in str(err)):
return UnresolvedType()
# This should never happen, propogate as an InternalError.
outerr = err
except AttributeError as err:
# This is to handle when we call .intrinsic or
# .precision on an UnresolvedType
# If we get an attribute error, and its because of attempting
# to lookup the precision or intrinsic, then it is likely
# due to looking up the datatype elements of an Unresolved
Expand All @@ -4908,13 +4929,15 @@ def datatype(self) -> DataType:
and "NoneType" not in
str(err)):
return UnresolvedType()
# Can't use debug string due to this being a potentially
# incomplete IntrinsicCall
raise InternalError(
f"Failed to compute the datatype of a "
f"'{self.intrinsic.name}' intrinsic. This is likely due "
f"to not fully initialising the intrinsic correctly."
) from err
outerr = err
# Fall through to the internalerror.
# Can't use debug string due to this being a potentially
# incomplete IntrinsicCall
raise InternalError(
f"Failed to compute the datatype of a "
f"'{self.intrinsic.name}' intrinsic. This is likely due "
f"to not fully initialising the intrinsic correctly."
) from outerr
else:
return self.intrinsic.return_type

Expand Down
Loading
Loading