Skip to content
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

(Closes #2854) exclude char assignments from ACC KERNELS regions #2857

Merged
merged 9 commits into from
Jan 24, 2025
37 changes: 10 additions & 27 deletions src/psyclone/psyir/transformations/acc_kernels_trans.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@
from typing import List, Union

from psyclone import psyGen
from psyclone.errors import LazyString
from psyclone.psyir.nodes import (
ACCKernelsDirective, Assignment, Call, CodeBlock, Literal, Loop,
ACCKernelsDirective, Assignment, Call, CodeBlock, Loop,
Node, PSyDataNode, Reference, Return, Routine, Statement, WhileLoop)
from psyclone.psyir.symbols import ScalarType, UnsupportedFortranType
from psyclone.psyir.symbols import UnsupportedFortranType
from psyclone.psyir.transformations.arrayassignment2loops_trans import (
ArrayAssignment2LoopsTrans)
from psyclone.psyir.transformations.region_trans import RegionTrans
from psyclone.psyir.transformations.transformation_error import (
TransformationError)
Expand Down Expand Up @@ -161,10 +162,6 @@ def validate(self, nodes: Union[Node, List[Node]],
"GOcean InvokeSchedules")
super().validate(node_list, options)

# Any errors below this point will optionally log the resason, which
# at the moment means adding a comment in the output code
verbose = options.get("verbose", False)

# The regex we use to determine whether a character declaration is
# of assumed size ('LEN=*' or '*(*)').
# TODO #2612 - improve the fparser2 frontend support for character
Expand Down Expand Up @@ -200,27 +197,13 @@ def validate(self, nodes: Union[Node, List[Node]],
# Check there are no character assignments in the region as these
# cause various problems with (at least) NVHPC <= 24.5
if not options.get("allow_string", False):
message = (
f"{self.name} does not permit assignments involving "
f"character variables by default (use the 'allow_string' "
f"option to include them)")
for assign in node.walk(Assignment):
for child in assign.walk((Literal, Reference)):
try:
forbid = ScalarType.Intrinsic.CHARACTER
if (child.is_character(unknown_as=False) or
child.symbol.datatype.intrinsic == forbid):
message = (
f"{self.name} does not permit assignments "
f"involving character variables by default"
f" (use the 'allow_string' option to "
f"include them)")
if verbose:
assign.append_preceding_comment(message)
# pylint: disable=cell-var-from-loop
raise TransformationError(LazyString(
lambda: f"{message}, but found:"
f"\n{assign.debug_string()}"))
except (NotImplementedError, AttributeError):
# We cannot always get the datatype, we ignore this
# for now
pass
ArrayAssignment2LoopsTrans.validate_no_char(
assign, message, options)

# Check that any called routines are supported on the device.
for icall in node.walk(Call):
Expand Down
58 changes: 40 additions & 18 deletions src/psyclone/psyir/transformations/arrayassignment2loops_trans.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
from psyclone.errors import LazyString
from psyclone.psyGen import Transformation
from psyclone.psyir.nodes import (
Assignment, Call, IntrinsicCall, Loop, Literal, Range, Reference,
Assignment, Call, IntrinsicCall, Loop, Literal, Node, Range, Reference,
CodeBlock, Routine, BinaryOperation)
from psyclone.psyir.nodes.array_mixin import ArrayMixin
from psyclone.psyir.symbols import (
Expand Down Expand Up @@ -285,23 +285,10 @@ def validate(self, node, options=None):

# If we allow string arrays then we can skip the check.
if not options.get("allow_string", False):
for child in node.walk((Literal, Reference)):
try:
forbidden = ScalarType.Intrinsic.CHARACTER
if (child.is_character(unknown_as=False) or
(child.symbol.datatype.intrinsic == forbidden)):
message = (f"{self.name} does not expand ranges "
f"on character arrays by default (use the"
f"'allow_string' option to expand them)")
if verbose:
node.append_preceding_comment(message)
# pylint: disable=cell-var-from-loop
raise TransformationError(LazyString(
lambda: f"{message}, but found:"
f"\n{node.debug_string()}"))
except (NotImplementedError, AttributeError):
# We cannot always get the datatype, we ignore this for now
pass
message = (f"{self.name} does not expand ranges "
f"on character arrays by default (use the"
f"'allow_string' option to expand them)")
self.validate_no_char(node, message, options)

# We don't accept calls that are not guaranteed to be elemental
for call in node.rhs.walk(Call):
Expand Down Expand Up @@ -372,6 +359,41 @@ def validate(self, node, options=None):
raise TransformationError(LazyString(
lambda: f"{message} In:\n{node.debug_string()}"))

@staticmethod
def validate_no_char(node: Node, message: str, options: dict) -> None:
LonelyCat124 marked this conversation as resolved.
Show resolved Hide resolved
'''
Check that there is no character variable accessed in the sub-tree with
the supplied node at its root.

:param node: the root node to check for character assignments.
:param message: the message to use if a character assignment is found.
:param options: any options that apply to this check.
:param bool options["verbose"]: log the reason the validation failed,
at the moment with a comment in the provided PSyIR node.

:raises TransformationError: if the supplied node contains a
child of character type.

'''
# Whether or not to log the resason for raising an error. At the moment
# "logging" means adding a comment in the output code.
verbose = options.get("verbose", False)

for child in node.walk((Literal, Reference)):
try:
forbidden = ScalarType.Intrinsic.CHARACTER
if (child.is_character(unknown_as=False) or
(child.symbol.datatype.intrinsic == forbidden)):
if verbose:
node.append_preceding_comment(message)
# pylint: disable=cell-var-from-loop
raise TransformationError(LazyString(
lambda: f"{message}, but found:"
f"\n{node.debug_string()}"))
except (NotImplementedError, AttributeError):
# We cannot always get the datatype, we ignore this for now
pass


__all__ = [
'ArrayAssignment2LoopsTrans']
Loading