PSyclone icon indicating copy to clipboard operation
PSyclone copied to clipboard

[InlineTrans] TypeError: The stop value of a Range must be a sub-class of Node but got: Extent (similar to #2776)

Open hbrunie opened this issue 1 year ago • 2 comments

Executing this code snippet:

def test_inline_with_array_in_call_upper_ATTRIBUTE():
    code = """module dummy
    implicit none
    contains 
    subroutine callee(logc, scr_rope)
    integer, dimension(3), intent(in) :: logc
    integer, dimension(3) :: limits
    integer, parameter :: init=1
    real, dimension(logc(1):,:), intent(in) :: scr_rope
    call called(logc, limits, scr_rope(:,:))
    end subroutine callee
    
    subroutine called(logc, limits, scr_rope)
  integer, dimension(3), intent(in) :: logc
  integer, dimension(3), intent(in) :: limits
  real, dimension(logc(1):,:), intent(in) :: scr_rope
  integer :: i
  real, dimension(5) :: fstar

  fstar = 0
  do i = logc(1), limits(3), 1
     fstar(:) = scr_rope(:,i)
  enddo

end subroutine called
end module"""
    reader = FortranReader()
    psyir_tree: psyir_nodes.Node = reader.psyir_from_source(code)
    # writer = FortranWriter()
    # print(writer(psyir_tree))
    routine: Routine = psyir_tree.walk(psyir_nodes.Call)[0]
    from psyclone.psyir.transformations import InlineTrans

    trans = InlineTrans()
    trans.apply(routine)

I got an error during the Inline transformation

 test_inline_with_array_in_call_upper_ATTRIBUTE
    trans.apply(routine)
../../psyclone/psyclone/src/psyclone/psyir/transformations/inline_trans.py:184: in apply
    self._replace_formal_arg(ref, node, formal_args)
../../psyclone/psyclone/src/psyclone/psyir/transformations/inline_trans.py:331: in _replace_formal_arg
    new_ref = self._replace_formal_struc_arg(actual_arg, ref, call_node,
../../psyclone/psyclone/src/psyclone/psyir/transformations/inline_trans.py:548: in _replace_formal_struc_arg
    new_indices = self._update_actual_indices(
../../psyclone/psyclone/src/psyclone/psyir/transformations/inline_trans.py:470: in _update_actual_indices
    local_shape.upper.copy())
E   AttributeError: 'Extent' object has no attribute 'copy'
=========================================================================== short test summary info ===========================================================================
ERROR test_psyclone_limits.py - AttributeError: 'Extent' object has no attribute 'copy'

It looks like the InlineTransformation tries to copy a bound that is not possible to copy (Enum).

The inlined code should look like

```python
module dummy
    implicit none
    contains 
    subroutine callee(logc, scr_rope)
    integer, dimension(3), intent(in) :: logc
    integer, dimension(3) :: limits
    integer, parameter :: init=1
    real, dimension(logc(1):,:), intent(in) :: scr_rope 

    ! INLINED call called(logc, limits, scr_rope(:,:))
    integer :: i
    real, dimension(5) :: fstar

    fstar = 0
    do i = logc(1), limits(3), 1
       fstar(:) = scr_rope(:,i)
    enddo
    end subroutine callee
    ! subroutine called code removed for simplicity
end module

hbrunie avatar Oct 03 '24 15:10 hbrunie

A patch to solve this issue:

 >> cat 0001-InlineTrans-Fix-2735.patch 
From b3c54743fe930787bef936f6b0564ff1b4d4e9de Mon Sep 17 00:00:00 2001
From: Hugo Brunie <[email protected]>
Date: Thu, 3 Oct 2024 17:34:48 +0200
Subject: [PATCH] [InlineTrans] Fix 2735

---
 .gitignore                                     |  2 ++
 .../psyir/transformations/inline_trans.py      | 18 ++++++++++++++++--
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/.gitignore b/.gitignore
index a5562a65a..af820da8d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,5 @@ src/*.egg-info
 .idea
 .rtx.toml
 .venv
+venv
+.vscode
\ No newline at end of file
diff --git a/src/psyclone/psyir/transformations/inline_trans.py b/src/psyclone/psyir/transformations/inline_trans.py
index 1b8c8927f..a3941ce20 100644
--- a/src/psyclone/psyir/transformations/inline_trans.py
+++ b/src/psyclone/psyir/transformations/inline_trans.py
@@ -466,8 +466,22 @@ class InlineTrans(Transformation):
                 # less than that supplied. In general we're not going to know
                 # that so we have to be conservative.
                 if local_shape:
-                    new = Range.create(local_shape.lower.copy(),
-                                       local_shape.upper.copy())
+                    symbol = local_ref.symbol
+                    if isinstance(local_shape.upper, Reference):
+                        upper_bound =local_shape.upper.copy()
+                    else:
+                        upper_bound = IntrinsicCall.create(
+                                IntrinsicCall.Intrinsic.UBOUND,
+                                [Reference(symbol), ("dim", Literal(str(local_idx_posn+1), INTEGER_TYPE))])
+                    if isinstance(local_shape.lower, Reference):
+                        lower_bound =local_shape.lower.copy()
+                    else:
+                        lower_bound = IntrinsicCall.create(
+                                IntrinsicCall.Intrinsic.LBOUND,
+                                [Reference(symbol), ("dim", Literal(str(local_idx_posn+1), INTEGER_TYPE))])
+
+                    new = Range.create(lower_bound,
+                                       upper_bound)
                     new_indices[pos] = self._create_inlined_idx(
                         call_node, formal_args,
                         new, local_decln_start, actual_start)
-- 
2.34.1

hbrunie avatar Oct 03 '24 15:10 hbrunie

With the last version of psyclone, commit dd3500065286e05756250f47ec9913f3ffd0a4e5:

The error is now:

../../psyclone/psyclone/src/psyclone/psyir/transformations/inline_trans.py:185: in apply
    self._replace_formal_arg(ref, node, formal_args)
../../psyclone/psyclone/src/psyclone/psyir/transformations/inline_trans.py:300: in _replace_formal_arg
    new_ref = self._replace_formal_struc_arg(actual_arg, ref, call_node,
../../psyclone/psyclone/src/psyclone/psyir/transformations/inline_trans.py:523: in _replace_formal_struc_arg
    new_indices = self._update_actual_indices(
../../psyclone/psyclone/src/psyclone/psyir/transformations/inline_trans.py:444: in _update_actual_indices
    new = Range.create(local_shape.lower.copy(),
../../psyclone/psyclone/src/psyclone/psyir/nodes/ranges.py:130: in create
    erange.stop = stop
../../psyclone/psyclone/src/psyclone/psyir/nodes/ranges.py:222: in stop
    self._check_valid_input(value, "stop")
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

value = <Extent.ATTRIBUTE: 2>, name = 'stop'

    @staticmethod
    def _check_valid_input(value, name):
        '''
        Perform checks that the supplied value is valid as a child of a
        Range node.
    
        :param object value: entity to check.
        :param str name: the name of the quantity for which this value has \
                         been supplied.
    
        :raises TypeError: if the supplied value is not a sub-class of Node.
        :raises TypeError: if the supplied value is a Literal but is not of \
                           INTEGER type.
        '''
        if not isinstance(value, Node):
>           raise TypeError(
                f"The {name} value of a Range must be a sub-class of "
                f"Node but got: {type(value).__name__}")
E           TypeError: The stop value of a Range must be a sub-class of Node but got: Extent

../../psyclone/psyclone/src/psyclone/psyir/nodes/ranges.py:153: TypeError

hbrunie avatar Oct 07 '24 08:10 hbrunie

Hopefully #3018 might address this.

LonelyCat124 avatar Jun 11 '25 12:06 LonelyCat124