Skip to content

Commit 876310b

Browse files
authored
Merge pull request #2730 from devitocodes/locarray
misc: Miscellaneous corner cases fixes
2 parents 379c77d + edeb3b6 commit 876310b

19 files changed

Lines changed: 339 additions & 75 deletions

File tree

.github/workflows/docker-bases.yml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ on:
1818
inputs:
1919
cpu:
2020
type: boolean
21-
default: false
21+
default: true
2222
nvidia:
2323
type: boolean
24-
default: false
24+
default: true
2525
amd:
2626
type: boolean
27-
default: false
27+
default: true
2828
intel:
2929
type: boolean
30-
default: false
30+
default: true
3131

3232
tags:
3333
description: "Build compiler bases"
@@ -227,7 +227,9 @@ jobs:
227227
push: true
228228
target: "nvc"
229229
platforms: ${{ matrix.platform }}
230-
build-args: "arch=nvc"
230+
build-args: |
231+
arch=nvc
232+
ver=nvhpc-25-7
231233
# Label (not tag) with runner name for traceability without changing image tags
232234
labels: builder-runner=${{ runner.name }}
233235
tags: "devitocodes/bases:nvidia-nvc-${{ matrix.arch }}"
@@ -240,7 +242,9 @@ jobs:
240242
push: true
241243
target: "nvcc"
242244
platforms: ${{ matrix.platform }}
243-
build-args: "arch=nvcc"
245+
build-args: |
246+
arch=nvcc
247+
ver=nvhpc-25-7
244248
labels: builder-runner=${{ runner.name }}
245249
tags: "devitocodes/bases:nvidia-nvcc-${{ matrix.arch }}"
246250

@@ -252,7 +256,9 @@ jobs:
252256
push: true
253257
target: "nvc-host"
254258
platforms: ${{ matrix.platform }}
255-
build-args: "arch=nvc-host"
259+
build-args: |
260+
arch=nvc-host
261+
ver=nvhpc-25-7
256262
labels: builder-runner=${{ runner.name }}
257263
tags: "devitocodes/bases:cpu-nvc-${{ matrix.arch }}"
258264

.github/workflows/docker-devito.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ jobs:
215215
echo "No tags generated, skipping"
216216
exit 0
217217
fi
218-
for tag in $TAGS; do
218+
echo "$TAGS" | while read -r tag; do
219219
refs=""
220220
for arch in $ARCHES; do
221221
refs="$refs devitocodes/devito:${tag}-${arch}"

conftest.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def skipif(items, whole_module=False):
3535
accepted.update({'device', 'device-C', 'device-openmp', 'device-openacc',
3636
'device-aomp', 'cpu64-icc', 'cpu64-icx', 'cpu64-nvc',
3737
'noadvisor', 'cpu64-arm', 'cpu64-icpx', 'chkpnt'})
38-
accepted.update({'nodevice'})
38+
accepted.update({'nodevice', 'noomp'})
3939
unknown = sorted(set(items) - accepted)
4040
if unknown:
4141
raise ValueError("Illegal skipif argument(s) `%s`" % unknown)
@@ -86,6 +86,10 @@ def skipif(items, whole_module=False):
8686
not get_advisor_path()):
8787
skipit = "Only `icx+advisor` should be tested here"
8888
break
89+
# Slip if not using openmp
90+
if i == 'noomp' and 'openmp' not in configuration['language']:
91+
skipit = "Must use openmp"
92+
break
8993
# Skip if it won't run on Arm
9094
if i == 'cpu64-arm' and isinstance(configuration['platform'], Arm):
9195
skipit = "Arm doesn't support x86-specific instructions"

devito/arch/archinfo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ def get_advisor_path():
577577
@memoized_func
578578
def get_hip_path():
579579
# *** First try: via commonly used environment variables
580-
for i in ['HIP_HOME']:
580+
for i in ['HIP_HOME', 'ROCM_HOME']:
581581
hip_home = os.environ.get(i)
582582
if hip_home:
583583
return hip_home

devito/ir/cgen/printer.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,8 @@ def _print_ListInitializer(self, expr):
349349
return f"{{{', '.join(self._print(i) for i in expr.params)}}}"
350350

351351
def _print_IndexedPointer(self, expr):
352-
return f"{expr.base}{''.join(f'[{self._print(i)}]' for i in expr.index)}"
352+
base = self._print(expr.base)
353+
return f"{base}{''.join(f'[{self._print(i)}]' for i in expr.index)}"
353354

354355
def _print_IntDiv(self, expr):
355356
lhs = self._print(expr.lhs)

devito/ir/iet/visitors.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,10 @@ def _gen_rettype(self, obj):
353353
elif isinstance(obj, (FieldFromComposite, FieldFromPointer)):
354354
return self._gen_value(obj.function.base, 0).typename
355355
else:
356-
return None
356+
try:
357+
return obj._type_.__name__
358+
except AttributeError:
359+
return None
357360

358361
def _args_decl(self, args):
359362
"""Generate cgen declarations from an iterable of symbols and expressions."""

devito/mpi/distributed.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
def cleanup():
4141
devito_mpi_finalize()
4242
atexit.register(cleanup)
43-
except ImportError as e:
43+
except (RuntimeError, ImportError) as e:
4444
# Dummy fallback in case mpi4py/MPI aren't available
4545
class NoneMetaclass(type):
4646
def __getattr__(self, name):

devito/mpi/routines.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,7 +1395,7 @@ def _arg_values(self, args=None, **kwargs):
13951395
class AllreduceCall(Call):
13961396

13971397
def __init__(self, arguments, **kwargs):
1398-
super().__init__('MPI_Allreduce', arguments)
1398+
super().__init__('MPI_Allreduce', arguments, **kwargs)
13991399

14001400

14011401
class ReductionBuilder(object):
@@ -1422,6 +1422,6 @@ def make(self, dr):
14221422
op = self.mapper[dr.op]
14231423

14241424
arguments = [inplace, Byref(f), Integer(1), mpitype, op, comm]
1425-
allreduce = AllreduceCall(arguments)
1425+
allreduce = AllreduceCall(arguments, writes=f)
14261426

14271427
return allreduce

devito/passes/clusters/buffering.py

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -403,8 +403,13 @@ def generate_buffers(clusters, key, sregistry, options, **kwargs):
403403
# Finally create the actual buffer
404404
cls = callback or Array
405405
name = sregistry.make_name(prefix='%sb' % f.name)
406+
# We specify the padding to match the input Function's one, so that
407+
# the array can be used in place of the Function with valid strides
408+
# Plain Array do not track mapped so we default to no padding
409+
padding = 0 if cls is Array else f.padding
406410
mapper[f] = cls(name=name, dimensions=dimensions, dtype=f.dtype,
407-
grid=f.grid, halo=f.halo, space='mapped', mapped=f, f=f)
411+
padding=padding, grid=f.grid, halo=f.halo,
412+
space='mapped', mapped=f, f=f)
408413

409414
return mapper
410415

@@ -436,25 +441,6 @@ def __init__(self, f, b, clusters):
436441

437442
self.indices = extract_indices(f, self.dim, clusters)
438443

439-
# The IterationSpace within which the buffer will be accessed
440-
# NOTE: The `key` is to avoid Clusters including `f` but not directly
441-
# using it in an expression, such as HaloTouch Clusters
442-
key = lambda c: any(i in c.ispace.dimensions for i in self.bdims)
443-
ispaces = {c.ispace for c in clusters if key(c)}
444-
445-
if len(ispaces) > 1:
446-
# Best effort to make buffering work in the presence of multiple
447-
# IterationSpaces
448-
stamp = Stamp()
449-
ispaces = {i.lift(self.bdims, v=stamp) for i in ispaces}
450-
451-
if len(ispaces) > 1:
452-
raise CompilationError("Unsupported `buffering` over different "
453-
"IterationSpaces")
454-
455-
assert len(ispaces) == 1, "Unexpected form of `buffering`"
456-
self.ispace = ispaces.pop()
457-
458444
def __repr__(self):
459445
return "Descriptor[%s -> %s]" % (self.f, self.b)
460446

@@ -474,6 +460,47 @@ def itdims(self):
474460
"""
475461
return (self.xd, self.dim.root)
476462

463+
@cached_property
464+
def ispace(self):
465+
# The IterationSpace within which the buffer will be accessed
466+
467+
# NOTE: The `key` is to avoid Clusters including `f` but not directly
468+
# using it in an expression, such as HaloTouch Clusters
469+
def key(c):
470+
bufferdim = any(i in c.ispace.dimensions for i in self.bdims)
471+
xd_only = all(d._defines & self.xd._defines for d in c.ispace.dimensions)
472+
return bufferdim or xd_only
473+
474+
ispaces = set()
475+
for c in self.clusters:
476+
if not key(c):
477+
continue
478+
479+
# Skip wild clusters (e.g. HaloTouch Clusters)
480+
if c.is_wild:
481+
continue
482+
483+
# Iterations space and buffering dims
484+
edims = [d for d in self.bdims if d not in c.ispace.dimensions]
485+
if not edims:
486+
ispaces.add(c.ispace)
487+
else:
488+
# Add all missing buffering dimensions and reorder to
489+
# avoid duplicates with different ordering
490+
ispaces.add(c.ispace.insert(self.dim, edims).reorder())
491+
492+
if len(ispaces) > 1:
493+
# Best effort to make buffering work in the presence of multiple
494+
# IterationSpaces
495+
stamp = Stamp()
496+
ispaces = {i.lift(self.bdims, v=stamp) for i in ispaces}
497+
498+
if len(ispaces) > 1:
499+
raise CompilationError("Unsupported `buffering` over different "
500+
"IterationSpaces")
501+
502+
return ispaces.pop()
503+
477504
@cached_property
478505
def subdims_mapper(self):
479506
return {d.root: d for d in self.ispace.itdims if d.is_AbstractSub}

devito/passes/iet/languages/C.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,40 @@
55
from devito.passes.iet.definitions import DataManager
66
from devito.passes.iet.orchestration import Orchestrator
77
from devito.passes.iet.langbase import LangBB
8+
from devito.passes.iet.languages.utils import _atomic_add_split
89
from devito.symbolics import c_complex, c_double_complex
10+
from devito.symbolics.extended_sympy import UnaryOp
911
from devito.tools import dtype_to_cstr
1012

1113
__all__ = ['CBB', 'CDataManager', 'COrchestrator']
1214

1315

16+
class RealExt(UnaryOp):
17+
18+
_op = '__real__ '
19+
20+
21+
class ImagExt(UnaryOp):
22+
23+
_op = '__imag__ '
24+
25+
26+
def atomic_add(i, pragmas, split=False):
27+
# Base case, real reduction
28+
if not split:
29+
return i._rebuild(pragmas=pragmas)
30+
31+
# Complex reduction, split using a temp pointer
32+
# Transforms lhs += rhs into
33+
# {
34+
# pragmas
35+
# __real__ lhs += __real__ rhs;
36+
# pragmas
37+
# __imag__ lhs += __imag__ rhs;
38+
# }
39+
return _atomic_add_split(i, pragmas, RealExt, ImagExt)
40+
41+
1442
class CBB(LangBB):
1543

1644
mapper = {
@@ -29,7 +57,7 @@ class CBB(LangBB):
2957
'host-free-pin': lambda i:
3058
Call('free', (i,)),
3159
'alloc-global-symbol': lambda i, j, k:
32-
Call('memcpy', (i, j, k)),
60+
Call('memcpy', (i, j, k))
3361
}
3462

3563

0 commit comments

Comments
 (0)