Skip to content

Commit a4b5dd6

Browse files
authored
Merge pull request #3231 from stfc/3230_dof_kernel_vector
(Closes #3230) fix bugs in LFRicLoop.upper_bound_psyir() for field vectors.
2 parents d93892b + 8efbefd commit a4b5dd6

File tree

6 files changed

+185
-104
lines changed

6 files changed

+185
-104
lines changed

.github/workflows/python-package.yml

Lines changed: 76 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@ name: PSyclone tests and examples
4747

4848
on:
4949
push:
50-
branches: [ master ]
50+
branches: [master]
5151
pull_request:
52-
branches: [ master ]
52+
branches:
53+
- master
54+
- 'release_candidate_*'
5355
workflow_dispatch:
5456

5557
jobs:
@@ -60,82 +62,82 @@ jobs:
6062
env:
6163
GITHUB_PR_NUMBER: ${{ github.event.number }}
6264
steps:
63-
- uses: actions/checkout@v4
64-
- uses: actions/setup-python@v5
65-
with:
66-
python-version: '3.14'
67-
- run: sudo apt-get install -y graphviz doxygen
68-
- run: python -m pip install --upgrade pip
69-
- run: pip install .[doc]
70-
# Now we can check for warnings and broken links
71-
- run: cd doc; make html SPHINXOPTS="-W --keep-going"
72-
- run: cd doc; make linkcheck
73-
# TODO #2936: There are many doctest issues, so commenting out for now
74-
# - run: cd doc; make doctest
65+
- uses: actions/checkout@v4
66+
- uses: actions/setup-python@v5
67+
with:
68+
python-version: '3.14'
69+
- run: sudo apt-get install -y graphviz doxygen
70+
- run: python -m pip install --upgrade pip
71+
- run: pip install .[doc]
72+
# Now we can check for warnings and broken links
73+
- run: cd doc; make html SPHINXOPTS="-W --keep-going"
74+
- run: cd doc; make linkcheck
75+
# TODO #2936: There are many doctest issues, so commenting out for now
76+
# - run: cd doc; make doctest
7577
build:
7678
if: ${{ github.repository != 'stfc/PSyclone-mirror' }}
7779
runs-on: ubuntu-latest
7880
strategy:
7981
matrix:
8082
python-version: ['3.9', '3.14']
8183
steps:
82-
- uses: actions/checkout@v4
83-
with:
84-
submodules: recursive
85-
# This is required to get the commit history for merge commits for
86-
# the ci-skip check below.
87-
fetch-depth: '0'
88-
- name: Check for [skip ci] in commit message
89-
uses: mstachniuk/ci-skip@v1
90-
with:
91-
# This setting causes the tests to 'fail' if [skip ci] is specified
92-
fail-fast: true
93-
commit-filter: '[skip ci]'
94-
- name: Set up Python ${{ matrix.python-version }}
95-
uses: actions/setup-python@v4
96-
with:
97-
python-version: ${{ matrix.python-version }}
98-
- name: Install dependencies
99-
run: |
100-
python -m pip install --upgrade pip
101-
# Some of the examples use Jupyter.
102-
pip install jupyter
103-
# We need to install sphinx to get correct doc testing
104-
# Uncomment the below to use the submodule version of fparser rather
105-
# than the latest release from pypi.
106-
# pip install external/fparser
107-
pip install .[doc]
108-
pip install .[test]
109-
- name: Lint with flake8
110-
run: |
111-
# Stop the build if there are Python syntax errors or undefined names.
112-
# See PSyclone/setup.cfg for configuration of this check.
113-
flake8 --count --show-source --statistics .
114-
- name: Run examples
115-
run: |
116-
( make -j 2 -C examples transform > /dev/null )
117-
( make -C examples notebook )
118-
- name: Run tutorials
119-
run: |
120-
( make -C tutorial/practicals transform > /dev/null )
121-
# Jupyter notebooks are out-of-date
122-
# ( make -C tutorial/notebooks notebook )
123-
- name: Test with pytest
124-
if: ${{ !(matrix.python-version == '3.9') }}
125-
run: |
126-
locale
127-
pytest -n auto --cov=psyclone --cov-report=xml src/psyclone/tests
128-
- name: Test with pytest and C Locale
129-
if: ${{ matrix.python-version == '3.9' }}
130-
run: |
131-
locale
132-
pytest -n auto --cov=psyclone --cov-report=xml src/psyclone/tests
133-
env:
134-
LC_ALL: C
135-
LANG: C
136-
- name: Upload coverage to Codecov with GitHub Action
137-
uses: codecov/codecov-action@v4
138-
env:
139-
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
140-
with:
141-
verbose: true
84+
- uses: actions/checkout@v4
85+
with:
86+
submodules: recursive
87+
# This is required to get the commit history for merge commits for
88+
# the ci-skip check below.
89+
fetch-depth: '0'
90+
- name: Check for [skip ci] in commit message
91+
uses: mstachniuk/ci-skip@v1
92+
with:
93+
# This setting causes the tests to 'fail' if [skip ci] is specified
94+
fail-fast: true
95+
commit-filter: '[skip ci]'
96+
- name: Set up Python ${{ matrix.python-version }}
97+
uses: actions/setup-python@v4
98+
with:
99+
python-version: ${{ matrix.python-version }}
100+
- name: Install dependencies
101+
run: |
102+
python -m pip install --upgrade pip
103+
# Some of the examples use Jupyter.
104+
pip install jupyter
105+
# We need to install sphinx to get correct doc testing
106+
# Uncomment the below to use the submodule version of fparser rather
107+
# than the latest release from pypi.
108+
# pip install external/fparser
109+
pip install .[doc]
110+
pip install .[test]
111+
- name: Lint with flake8
112+
run: |
113+
# Stop the build if there are Python syntax errors or undefined names.
114+
# See PSyclone/setup.cfg for configuration of this check.
115+
flake8 --count --show-source --statistics .
116+
- name: Run examples
117+
run: |
118+
( make -j 2 -C examples transform > /dev/null )
119+
( make -C examples notebook )
120+
- name: Run tutorials
121+
run: |
122+
( make -C tutorial/practicals transform > /dev/null )
123+
# Jupyter notebooks are out-of-date
124+
# ( make -C tutorial/notebooks notebook )
125+
- name: Test with pytest
126+
if: ${{ !(matrix.python-version == '3.9') }}
127+
run: |
128+
locale
129+
pytest -n auto --cov=psyclone --cov-report=xml src/psyclone/tests
130+
- name: Test with pytest and C Locale
131+
if: ${{ matrix.python-version == '3.9' }}
132+
run: |
133+
locale
134+
pytest -n auto --cov=psyclone --cov-report=xml src/psyclone/tests
135+
env:
136+
LC_ALL: C
137+
LANG: C
138+
- name: Upload coverage to Codecov with GitHub Action
139+
uses: codecov/codecov-action@v4
140+
env:
141+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
142+
with:
143+
verbose: true

changelog

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
2) PR #3231 for #3230. Fixes a bug in upper_bound_psyir() for field vectors.
2+
13
1) PR #3229 for #3227. Fixes a bug with PSyAD where the wrong operator
24
space was being generated.
35

src/psyclone/domain/lfric/lfric_loop.py

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -566,18 +566,11 @@ def upper_bound_psyir(self) -> Node:
566566
if self._upper_bound_name in ["ndofs", "nannexed"]:
567567
if Config.get().distributed_memory:
568568
if self._upper_bound_name == "ndofs":
569-
method = "get_last_dof_owned"
570-
else:
571-
method = "get_last_dof_annexed"
572-
result = Call.create(
573-
StructureReference.create(
574-
sym_tab.lookup(self.field.proxy_name_indexed),
575-
[self.field.ref_name(), method]
576-
)
577-
)
578-
else:
579-
result = Reference(sym_tab.lookup(self._kern.undf_name))
580-
return result
569+
return self.field.generate_method_call(
570+
"get_last_dof_owned")
571+
return self.field.generate_method_call("get_last_dof_annexed")
572+
return Reference(sym_tab.lookup(self._kern.undf_name))
573+
581574
if self._upper_bound_name == "ncells":
582575
if Config.get().distributed_memory:
583576
result = Call.create(
@@ -605,12 +598,7 @@ def upper_bound_psyir(self) -> Node:
605598
"sequential/shared-memory code")
606599
if self._upper_bound_name == "dof_halo":
607600
if Config.get().distributed_memory:
608-
result = Call.create(
609-
StructureReference.create(
610-
sym_tab.lookup(self.field.proxy_name_indexed),
611-
[self.field.ref_name(), "get_last_dof_halo"]
612-
)
613-
)
601+
result = self.field.generate_method_call("get_last_dof_halo")
614602
if halo_index:
615603
result.addchild(halo_index.copy())
616604
return result

src/psyclone/tests/domain/lfric/dofkern_test.py

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -265,31 +265,51 @@ def test_multi_invoke_cell_dof_builtin(tmpdir, monkeypatch, annexed, dist_mem):
265265

266266
# Consistent declarations
267267
assert """
268+
type(field_type), dimension(3), intent(in) :: field_vec
268269
type(field_type), intent(in) :: f1
269270
type(field_type), intent(in) :: f2
270271
type(field_type), intent(in) :: f3
271272
type(field_type), intent(in) :: f4
272-
type(field_type), dimension(3), intent(in) :: field_vec
273273
real(kind=r_def), intent(in) :: scalar_arg
274274
real(kind=r_def), intent(in) :: a
275275
type(field_type), intent(in) :: m1
276276
type(field_type), intent(in) :: m2
277277
""" in code
278278
assert """
279+
real(kind=r_def), pointer, dimension(:) :: field_vec_1_data => null()
280+
real(kind=r_def), pointer, dimension(:) :: field_vec_2_data => null()
281+
real(kind=r_def), pointer, dimension(:) :: field_vec_3_data => null()
279282
real(kind=r_def), pointer, dimension(:) :: f1_data => null()
280283
real(kind=r_def), pointer, dimension(:) :: f2_data => null()
281284
real(kind=r_def), pointer, dimension(:) :: f3_data => null()
282285
real(kind=r_def), pointer, dimension(:) :: f4_data => null()
283-
real(kind=r_def), pointer, dimension(:) :: field_vec_1_data => null()
284-
real(kind=r_def), pointer, dimension(:) :: field_vec_2_data => null()
285-
real(kind=r_def), pointer, dimension(:) :: field_vec_3_data => null()
286286
real(kind=r_def), pointer, dimension(:) :: m1_data => null()
287287
real(kind=r_def), pointer, dimension(:) :: m2_data => null()
288288
""" in code
289289

290-
# Check that dof kernel is called correctly
290+
# Check loop bounds are set correctly for the dof kernel that updates
291+
# a field vector.
292+
if dist_mem:
293+
if annexed:
294+
assert ("loop0_stop = field_vec_proxy(1)%vspace%"
295+
"get_last_dof_annexed" in code)
296+
else:
297+
assert ("loop0_stop = field_vec_proxy(1)%vspace%"
298+
"get_last_dof_owned" in code)
299+
else:
300+
assert "loop0_stop = undf_w1" in code
301+
302+
# Check that dof kernels are called correctly
291303
output = (
292304
" do df = loop0_start, loop0_stop, 1\n"
305+
" call testkern_dofs_vector_write_code(field_vec_1_data(df), "
306+
"field_vec_2_data(df), field_vec_3_data(df))\n"
307+
" enddo\n"
308+
)
309+
assert output in code
310+
311+
output = (
312+
" do df = loop1_start, loop1_stop, 1\n"
293313
" call testkern_dofs_code(f1_data(df), f2_data(df), "
294314
"f3_data(df), f4_data(df), field_vec_1_data(df), "
295315
"field_vec_2_data(df), field_vec_3_data(df), scalar_arg)\n"
@@ -303,7 +323,7 @@ def test_multi_invoke_cell_dof_builtin(tmpdir, monkeypatch, annexed, dist_mem):
303323
if not annexed:
304324
# Check f1 field has halo exchange performed when annexed == False
305325
output = (
306-
" do df = loop0_start, loop0_stop, 1\n"
326+
" do df = loop1_start, loop1_stop, 1\n"
307327
" call testkern_dofs_code(f1_data(df), f2_data(df), "
308328
"f3_data(df), f4_data(df), field_vec_1_data(df), "
309329
"field_vec_2_data(df), field_vec_3_data(df), scalar_arg)\n"
@@ -317,7 +337,7 @@ def test_multi_invoke_cell_dof_builtin(tmpdir, monkeypatch, annexed, dist_mem):
317337
else:
318338
# Check f1 field is set dirty but no halo exchange is performed
319339
output = (
320-
" do df = loop0_start, loop0_stop, 1\n"
340+
" do df = loop1_start, loop1_stop, 1\n"
321341
" call testkern_dofs_code(f1_data(df), f2_data(df), "
322342
"f3_data(df), f4_data(df), field_vec_1_data(df), "
323343
"field_vec_2_data(df), field_vec_3_data(df), scalar_arg)\n"
@@ -340,15 +360,15 @@ def test_multi_invoke_cell_dof_builtin(tmpdir, monkeypatch, annexed, dist_mem):
340360
" if (m2_proxy%is_dirty(depth=1)) then\n"
341361
" call m2_proxy%halo_exchange(depth=1)\n"
342362
" end if\n"
343-
" do cell = loop1_start, loop1_stop, 1\n"
363+
" do cell = loop2_start, loop2_stop, 1\n"
344364
" call testkern_code"
345365
)
346366
output += common_halo_exchange_code # Append common
347367
assert output in code
348368

349369
# Check cell-column kern is called correctly
350370
output = (
351-
" do cell = loop1_start, loop1_stop, 1\n"
371+
" do cell = loop2_start, loop2_stop, 1\n"
352372
" call testkern_code(nlayers_f1, a, f1_data, f2_data, m1_data, "
353373
"m2_data, ndf_w1, undf_w1, map_w1(:,cell), ndf_w2, undf_w2, "
354374
"map_w2(:,cell), ndf_w3, undf_w3, map_w3(:,cell))\n"
@@ -358,7 +378,7 @@ def test_multi_invoke_cell_dof_builtin(tmpdir, monkeypatch, annexed, dist_mem):
358378

359379
# Check built-in is called correctly
360380
output = (
361-
" do df = loop2_start, loop2_stop, 1\n"
381+
" do df = loop3_start, loop3_stop, 1\n"
362382
" ! Built-in: inc_aX_plus_Y (real-valued fields)\n"
363383
" f1_data(df) = 0.5_r_def * f1_data(df) + f2_data(df)\n"
364384
" enddo\n"

src/psyclone/tests/test_files/lfric/4.17_multikernel_invokes_cell_dof_builtin.f90

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,13 @@
3636

3737
program multikernel_invokes_cell_dof_builtin
3838

39-
! Description: Two user-defined kernels operating over different domains
39+
! Description: Three user-defined kernels operating over different domains
4040
! ("cell-column" and "dof"), followed by an LFRic built-in kernel in the
4141
! same invoke.
4242
use constants_mod, only: r_def
4343
use field_mod, only: field_type
4444
use testkern_dofs_mod, only: testkern_dofs_type
45+
use testkern_dofs_vector_write_mod, only: testkern_dofs_vector_write_type
4546
use testkern_mod, only: testkern_type
4647

4748
implicit none
@@ -51,9 +52,10 @@ program multikernel_invokes_cell_dof_builtin
5152
real(kind=r_def) :: a, scalar_arg
5253

5354
call invoke( &
55+
testkern_dofs_vector_write_type(field_vec), &
5456
testkern_dofs_type(f1, f2, f3, f4, field_vec, scalar_arg), &
5557
testkern_type(a, f1, f2, m1, m2), &
5658
inc_aX_plus_Y(0.5_r_def, f1, f2) &
5759
)
5860

59-
end program multikernel_invokes_cell_dof_builtin
61+
end program multikernel_invokes_cell_dof_builtin

0 commit comments

Comments
 (0)