Skip to content

Disable script application to only iom_put#3429

Open
LonelyCat124 wants to merge 12 commits into
masterfrom
3412_nemo_script_improvement
Open

Disable script application to only iom_put#3429
LonelyCat124 wants to merge 12 commits into
masterfrom
3412_nemo_script_improvement

Conversation

@LonelyCat124
Copy link
Copy Markdown
Collaborator

No description provided.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 7, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.96%. Comparing base (ca8610a) to head (5cfcdeb).
⚠️ Report is 10 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #3429   +/-   ##
=======================================
  Coverage   99.96%   99.96%           
=======================================
  Files         391      391           
  Lines       54609    54674   +65     
=======================================
+ Hits        54590    54655   +65     
  Misses         19       19           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@LonelyCat124
Copy link
Copy Markdown
Collaborator Author

Some failures after this change can be resolved with a change to reference2arrayrange_trans:

            if not ((isinstance(node.parent, IntrinsicCall) and
                 node.parent.intrinsic in REDUCTION_INTRINSICS)
                or node.parent.is_elemental):
                return

instead of
if not node.parent.is_elemental
However, this still fails for stpctl.f90 for somer aeason, as we end up with an UnresolvedType in the gen_decls part of the backend, which is a bit confusing, I'm trying to track that down.

@LonelyCat124
Copy link
Copy Markdown
Collaborator Author

I'm trying building today and it just seems to work, I will test full integration and see if any others fail.

@LonelyCat124
Copy link
Copy Markdown
Collaborator Author

From discussion with sergi the previous direction has potential to produce incorrect code.

Instead we should change operation order:

  1. Do the array transformations that don't involve new temporaries
  2. Create new temporaries
  3. Reapply the array transformations.

@LonelyCat124
Copy link
Copy Markdown
Collaborator Author

Another option is to move the

  • convert_array_notation
  • loopify_array_intrinsics
  • convert_range_loops
  • hoist_argument_expressions
    parts of normalise_loops into a loopifyTrans metatransformation which I wanted to do for while, no individual enabling flags needed.
    Then the DataNodeToTempTrans apply can call this loopifyTrans on the extracted expression as it still have them inside the apply.

We don't have metatransformation support yet for this, but I'll make an issue for this as well.

@LonelyCat124 LonelyCat124 requested a review from sergisiso May 15, 2026 13:53
@LonelyCat124 LonelyCat124 marked this pull request as ready for review May 15, 2026 13:53
@LonelyCat124
Copy link
Copy Markdown
Collaborator Author

@sergisiso I think this is ready for a first look now.

Copy link
Copy Markdown
Collaborator

@sergisiso sergisiso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @LonelyCat124, its good to see it has passed all integration tests without making it exclusive for iom_put. Just some extra clarifications and testing needed.

Comment thread examples/nemo/scripts/utils.py Outdated
Comment on lines +224 to +226
except Exception as err:
print(reference, reference.parent.parent.debug_string())
raise err
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens here? Is this a leftover?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this was debugging.

Comment thread examples/nemo/scripts/utils.py Outdated
Comment on lines +282 to +285
# 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))
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now no longer limited to iom_put right? So the TODO can be removed and the method name updated?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment thread examples/nemo/scripts/utils.py Outdated
DataNodeToTempTrans().apply(arg, verbose=True)
except TransformationError:
pass
# if call.symbol.name == "iom_put":
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

Comment on lines +575 to +578
if (isinstance(dtype.elemental_type, ScalarType)
and dtype.elemental_type.intrinsic ==
ScalarType.Intrinsic.CHARACTER):
continue
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this an issue with the transformation? I am wondering if it should be inside the validation instead?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure - the transformation does it successfully but there was some error, I don't remember whether compiler or elsewhere in PSyclone. I can have a further look if you want, I just decided to skip it here for strings (not sure if there would be some other valid use case?)

Comment on lines +571 to +573
if (isinstance(dtype, ArrayType) and
(isinstance(arg, Operation) or
isinstance(arg, IntrinsicCall))):
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a comment explaining the condition: "Only extract expressions that can potentially be loopyfied (e.g. operations over arrays)"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

Comment on lines +146 to +148
def test_nemo5_transerror_case(fortran_reader):
'''Test that the transformation fails correctly if we have nested sums
as the reference can't be converted to an arrayreference.'''
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you change the name and description of the test to make it generic about the problem tested here, e.g. "the array reference is inside a non-elemental function and therefore won't be converted"?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

integer :: n, m
real , dimension(:, :) :: array

result = sum(sum(array, dim=2)) * array(n,m)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the validation counts ArrayReference, maybe test that expressions with other arrays like:
sum(sum(array + array(:,:), dim=2))
or
sum(sum(array, dim=dimensions(2)))

work as expected.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the first one already doesn't work as expected.

    code = """subroutine sum_test()
    integer :: n, m
    real, dimension(:, :) :: array
    result = sum(sum(array  + array(:,:), dim=2))
    end subroutine"""
    psyir = fortran_reader.psyir_from_source(code)
    intrinsic_node = psyir.children[0].children[0].rhs
    trans = Sum2LoopTrans()
    with pytest.raises(TransformationError) as err:
        trans.apply(intrinsic_node)
    print(fortran_writer(psyir))
    print(err.value)
    assert False

This outputs an error message on the fortran_writer stage, and the err.value is also different (if it were reached):

E           psyclone.psyir.backend.visitor.VisitorError: Visitor Error: The following symbols are not explicitly declared or imported from a module and there are no wildcard imports which could be bringing them into scope: 'result'

and

Transformation Error: ArrayAssignment2LoopsTrans could not convert the expression:
array(:,:) = SUM(array(:,:) + array(:,:), 2)

 into a loop because:
Transformation Error: ArrayAssignment2LoopsTrans does not support statements containing dependencies that would generate loop-carried dependencies when naively converting them to a loop, but found:
array(:,:) = SUM(array(:,:) + array(:,:), 2)

I'm not sure if this is the right place to fix this - I can make some xfailing tests and an issue?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sergisiso I've addressed the other comments but this one is still open if you have any time to let me know how to proceed before another full review.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both errors seem correct:

  • result is not declared in the example
  • And TransformationErrors are fine, what we don't want is to validate and then generate incorrect code.

So I would say no xfail needed?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah thats my mistake in the example, I was concerned the resulting code may be changed but I still get the input so thats fine. I'll check the other example you suggested as well.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested the other examples - the error messages are different, but the transformation does fail as expected.

dtrans.apply(assign.rhs.operands[1])
# Check the tmp symbol is at the routine scope.
routine = psyir.walk(Routine)[0]
assert routine.symbol_table.lookup("tmp") is not None
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert "tmp" in routine.symbol_table ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants