Skip to content

(closes #2936, #1220, #2088) Fix doctests and add CI tests#3441

Open
sergisiso wants to merge 25 commits into
masterfrom
fix_doctests
Open

(closes #2936, #1220, #2088) Fix doctests and add CI tests#3441
sergisiso wants to merge 25 commits into
masterfrom
fix_doctests

Conversation

@sergisiso

Copy link
Copy Markdown
Collaborator

No description provided.

Base automatically changed from scalartype_constructors to master May 26, 2026 14:11
@codecov

codecov Bot commented Jun 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (a7ea7cc) to head (ce724c4).

Additional details and impacted files
@@            Coverage Diff            @@
##            master     #3441   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          393       393           
  Lines        55067     55046   -21     
=========================================
- Hits         55067     55046   -21     

☔ View full report in Codecov by Harness.
📢 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.

@sergisiso

sergisiso commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator Author

@arporter @LonelyCat124 This PR fixes the doctests using both:
cd docs; make doctest
and
pytest -n auto --doctest-modules src/psyclone/

And enables both as checks in CI (We need both because there isn't a complete overlap between both sets and their working dir is different, so we need to be sure that paths have been normalised).

There are some doctests that didn't work, for example because they used non-existing example files. In this cases I converted the >>> to ... code-block :: which is not tested, and we can bringing them back to doctests over time.

It is ready for review.

@arporter arporter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good job Sergi, it's great to have this working and the PR wasn't quite as big as I feared :-)
Only significant quibble is with the new utility method - I'm not sure it buys us much over get_invoke and wonder whether the two can be merged?

Comment thread doc/developer_guide/module_manager.rst Outdated

.. testoutput::

.. The snippet above fails a `.. testcode ::` block, but if it didn't we

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why does it fail? Is it because the file doesn't exist or is it because of the relative path given to the module manager?

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.

It failed because some of the module files where moved to ../external/lfric_infrastructure/ and this was not updated. Fixed now.

(Hopefully these are the things that enabling doc-tests back will avoid)

Comment thread src/psyclone/tests/utilities.py Outdated
config.api = api

_, info = parse(filepath, api=api)
psy = PSyFactory(api, distributed_memory=dist_mem).create(info)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This could be simplified a lot if you used get_invoke. In fact, I'm not sure that this new method brings much benefit over the latter?

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 have now one calling the other, so the code is not duplicated.

One of the reasons that I prefered the new method is because all examples had the "invoke.schedule" before and this is not user-facing infrastructure. It's not what they have to do in the trans script and think this could be unecessarely confusing.


class GOceanExtractTrans(ExtractTrans):
''' GOcean1.0 API application of ExtractTrans transformation \
''' GOcean1.0 API application of ExtractTrans transformation

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just "GOcean" now please.

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

''' LFRic API application of ExtractTrans transformation
to extract code into a stand-alone program. For example:

>>> from psyclone.parse.algorithm import parse

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How come you've removed this? Also, the paragraph above still ends with "For example:..."

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.

The filename does not exist: find . -name solver_alg.x90 returns nothing.

Removed "For example:"

>>> # Uncomment the following line to see a text view of the schedule
>>> # print(schedule.view())
>>> kernels = schedule.children[9]
>>> kernels = schedule.children[26]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This could be a bit fragile. Could we make it a little better by walking over Loops?

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.

Note that a lot of doctests like this one are currently not very interesting, they only show how to apply a transformation (which a python user should already know). What is more interesting is to show the before and after of the associated code. I suppose this was the idea behing the print(schedule.view()) but these are too lang and hard to read and they where commented in the documentation anyway (so not checked nor shown in docs).

My idea is to make a second chosing snippets of fortran that demonstrate each transformation, but it became too much for this PR. So for now I just wanted to enable the automatic testing and then we should make them apply and showcase more relevant inout/output nodes/strings.

class OMPParallelLoopTrans(OMPLoopTrans):
''' Adds an OpenMP PARALLEL DO directive to a loop.

For example:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It seems a shame to lose this. Is it possible to keep a version?

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.

As mention, I didn't find these very valuable as they were because:

  1. the psyfactory/invoke should not be exposed to the user
  2. the trans.apply is trivial and doesn't need a example imo
  3. the input file does not exist, so it was not possible to see the behaviour (which is the interesting part).

But since you asked I redid this example as I think we should be doing them.


'''
Profiler.set_options([Profiler.INVOKES], api="nemo")
Profiler.set_options([Profiler.INVOKES], api="gocean")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This implies Profiler was missing a check on the validity of the API string? Have you fixed that?

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.

This didn't use the api value, and it feels it is not the right place to validate api strings. So I changed it to a boolean "is_psykal"

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.

(btw, I initially changed that because I did a grep for remaining api="nemo", not because it failed)

Comment thread src/psyclone/tests/exceptions_test.py Outdated
assert issubclass(psy_except, PSycloneError)
# Check if the exception inherits PSycloneError (we don't use
# issubclass because the import_modules used in this test re-imports
# already loaded modules and create two super classes PSycloneError)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Does that mean we should be monkeypatching or something or are those changes local to this test?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

(Well done on fixing this BTW - presumably this was the test error we see occasionally?)

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.

Yes, this was not isolated. But under further inspection I think we were overcomplicating a lot this test. I updated to something much simpler. Let me know what you think.

>>> from psyclone.parse.algorithm import parse
>>> from psyclone.psyGen import PSyFactory
>>> api = "lfric"
>>> ast, invokeInfo = parse("file.f90", api=api)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is it possible to recover this one? If not, please update the docstring above.

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.

Updated docstring.

@sergisiso

Copy link
Copy Markdown
Collaborator Author

@arporter This is ready for another look, I provided in the comments some more explanation about why I did certain additions/deletetions in the PR that were missing for context.

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