diff --git a/CMakeLists.txt b/CMakeLists.txt index 766202db64021d550b87f1bd93d8d1bd4575a89a..25e5e54b022aa6ddb33b5991e2d3d1062d593941 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,7 @@ option(PROFILE "Enable profiling mode for HySoP. 0:disabled, 1: enabled. Default option(OPTIM "To allow python -OO run, some packages must be deactivated. Set this option to 'ON' to do so. Default = OFF" OFF) option(WITH_MPI_TESTS "Enable mpi tests. Default = ON if USE_MPI is ON." ON) option(WITH_GOOGLE_TESTS "Enable google tests (c++). Default = OFF." OFF) -option(FORTRAN_LAYOUT "Choose default data layout ('fortran', column-major or 'C' order, row-major) for arrays. Default = column-major." ON) +option(FORTRAN_LAYOUT "Choose default data layout ('fortran', column-major or 'C' order, row-major) for arrays. Default = column-major." OFF) option(WITH_DOCUMENTATION "Build Documentation. Default = OFF" OFF) option(ENABLE_LONG_TESTS "Enable tests that may run for long time with important memory print. Default = OFF." OFF) option(DEV_MODE "Enable devel mode (aggressive checking of warnings ..). Default = ON." ON) diff --git a/hysop/__init__.py b/hysop/__init__.py index 0501895e8d3475908dda017a9b36a709217bbd14..de2e02cf7dbd8ec8ef499d1c6dddb5d65d9bea91 100644 --- a/hysop/__init__.py +++ b/hysop/__init__.py @@ -10,25 +10,26 @@ package_name = "hysop" version = "2.0.0" # Compilation flags -__MPI_ENABLED__ = "ON" is "ON" -__GPU_ENABLED__ = "ON" is "ON" -__FFTW_ENABLED__ = "ON" is "ON" +__MPI_ENABLED__ = "ON" is "ON" +__GPU_ENABLED__ = "ON" is "ON" +__FFTW_ENABLED__ = "ON" is "ON" __SCALES_ENABLED__ = "ON" is "ON" __OPTIMIZE__ = not __debug__ -__VERBOSE__ = True -__DEBUG__ = False +__VERBOSE__ = "ON" in ["1", "3"] +__DEBUG__ = "ON" in ["2", "3"] __TRACE__ = False -__TRACE_WARNINGS_ = False +__TRACE_WARNINGS__ = False __KERNEL_DEBUG__ = False __PROFILE__ = True -__ENABLE_LONG_TESTS__ = False +__ENABLE_LONG_TESTS__ = "OFF" is "ON" # OpenCL __DEFAULT_PLATFORM_ID__ = 0 __DEFAULT_DEVICE_ID__ = 0 + if __MPI_ENABLED__: from hysop.core.mpi import MPI, main_rank, main_size, \ host_rank, interhost_size, \ @@ -59,7 +60,7 @@ def sprint(*args, **kargs): """prints only shared memory master rank 0""" if (shm_rank==0): vprint(*args, **kargs) - + def reset(): """Reset hysop state (registered objects).""" from hysop.tools.handle import RegisteredObject @@ -68,8 +69,8 @@ def reset(): # override warning printer __formatwarning = warnings.formatwarning def __new_formatwarning(message, category, filename, lineno, line=None): - #if __DEBUG__: - #traceback.print_stack() + if __TRACE_WARNINGS__: + traceback.print_stack() return __formatwarning(message, category, filename, lineno, line='') warnings.formatwarning = __new_formatwarning diff --git a/hysop/__init__.py.in b/hysop/__init__.py.in index c4d4acee5fd5e51a169b22aeb9e73efafd198e37..1a7bd799e2c874ef17bb64e939dba42a170db50e 100644 --- a/hysop/__init__.py.in +++ b/hysop/__init__.py.in @@ -19,7 +19,7 @@ __OPTIMIZE__ = not __debug__ __VERBOSE__ = "@DEBUG@" in ["1", "3"] __DEBUG__ = "@DEBUG@" in ["2", "3"] __TRACE__ = False -__TRACE_WARNINGS_ = False +__TRACE_WARNINGS__ = False __KERNEL_DEBUG__ = False __PROFILE__ = True diff --git a/hysop/backend/device/opencl/opencl_array.py b/hysop/backend/device/opencl/opencl_array.py index 28bfc1944d328aadeaa464fa70e35105a1b91dc3..7b4fc690d7c9b731087b5745e955f71aaf041c0e 100644 --- a/hysop/backend/device/opencl/opencl_array.py +++ b/hysop/backend/device/opencl/opencl_array.py @@ -54,10 +54,10 @@ class OpenClArray(Array): offset = self.offset bdata = self.base_data alignment = self.backend.device.mem_base_addr_align - # print 'INT_PTR', bdata.int_ptr, bdata.int_ptr % alignment - # print 'OFFSET', offset - # print 'ALIGNMENT', alignment - # print 'INT_PTR+OFFSET % ALIGNMENT', (bdata.int_ptr+offset)%alignment + print 'INT_PTR', bdata.int_ptr, bdata.int_ptr % alignment + print 'OFFSET', offset + print 'ALIGNMENT', alignment + print 'INT_PTR+OFFSET % ALIGNMENT', (bdata.int_ptr+offset)%alignment if (offset % alignment) == 0: # try to return a subbuffer buf = self.base_data.buf[offset:] diff --git a/hysop/constants.py b/hysop/constants.py index 008b778866aa4f630760767bff6755de53c2f5d0..f244bbf023bc41f8739c77b492666b12d12e07d6 100644 --- a/hysop/constants.py +++ b/hysop/constants.py @@ -66,7 +66,7 @@ if __MPI_ENABLED__: HYSOP_MPI_INTEGER = MPI.INT """integer type used in MPI""" - HYSOP_MPI_ORDER = MPI.ORDER_F + HYSOP_MPI_ORDER = MPI.ORDER_C """Default array layout for MPI""" HYSOP_DEFAULT_TASK_ID = 999 @@ -178,6 +178,7 @@ Default HySoP memory ordering for array allocations. if HYSOP_ORDER == 'F': default_order = MemoryOrdering.FORTRAN_CONTIGUOUS + raise RuntimeError('Fortran ordering is unsupported yet, codebase needs to be reviewed.') elif HYSOP_ORDER == 'C': default_order = MemoryOrdering.C_CONTIGUOUS else: diff --git a/hysop/constants.py.in b/hysop/constants.py.in index a6a7ec046797bf4a015ca1f055f27af279fb208e..13d8a48574a322af63d820d50e73e086262f8bb7 100644 --- a/hysop/constants.py.in +++ b/hysop/constants.py.in @@ -80,6 +80,7 @@ System type enum. Basis = EnumFactory.create('Basis', ['NATURAL', 'FOURIER', 'CHEBYSHEV']) +Basis.default = Basis.NATURAL """Basis""" Backend = EnumFactory.create('Backend', @@ -177,48 +178,13 @@ Default HySoP memory ordering for array allocations. if HYSOP_ORDER == 'F': default_order = MemoryOrdering.FORTRAN_CONTIGUOUS + raise RuntimeError('Fortran ordering is unsupported yet, codebase needs to be reviewed.') elif HYSOP_ORDER == 'C': default_order = MemoryOrdering.C_CONTIGUOUS else: msg='HYSOP_ORDER should be \'F\' or \'C\' (got {}).' raise ValueError(msg.format(HYSOP_ORDER)) -def __generate_tstates(): - transposition_states = {} - for i in xrange(1,len(DirectionLabels)): - labels = DirectionLabels[:i] - entries = it.permutations(labels, i) - entries = [''.join(x) for x in entries] - cls = EnumFactory.create('TranspositionState{}D'.format(i), entries) - default = entries[0] - if HYSOP_ORDER == 'F': - default = default[::-1] - cls.default = cls(default) - transposition_states[i] = cls - del entries - del cls - del default - del labels - return transposition_states - -transposition_states = __generate_tstates() -"""Dictionnary containing transposition states enums up to 5D.""" - -TranspositionState1D = transposition_states[1] -"""1D memory layout (transposition state) enum""" - -TranspositionState2D = transposition_states[2] -"""2D memory layout (transposition state) enum""" - -TranspositionState3D = transposition_states[3] -"""3D memory layout (transposition state) enum""" - -def axes_to_tstate(axes): - dim = len(axes) - if dim>=len(DirectionLabels): - return None - else: - tstates = transposition_states[dim] - return getattr(tstates, ''.join((DirectionLabels[i] for i in axes))) - - +from hysop.tools.transposition_states import TranspositionState, \ + TranspositionState1D, TranspositionState2D, TranspositionState3D, \ + DirectionLabels diff --git a/hysop/core/graph/graph_builder.py b/hysop/core/graph/graph_builder.py index 10f6bab5e5899b151ad30712a2082abae0a44699..4fa00ddb91221b441be214f4191b5cb1f18f2193 100644 --- a/hysop/core/graph/graph_builder.py +++ b/hysop/core/graph/graph_builder.py @@ -4,7 +4,7 @@ from hysop.deps import np from hysop.tools.types import check_instance from hysop.tools.io_utils import IOParams -from hysop.constants import TranspositionState +from hysop.tools.transposition_states import TranspositionState from hysop.constants import Basis from hysop.parameters.parameter import Parameter diff --git a/hysop/fields/field_requirements.py b/hysop/fields/field_requirements.py index feaadacabbfb93127848d4f2d85a3fdc5a0b170c..122990d15312a745731388fb8f0ffabe63f5eeaa 100644 --- a/hysop/fields/field_requirements.py +++ b/hysop/fields/field_requirements.py @@ -2,7 +2,7 @@ from hysop import __DEBUG__ from hysop.deps import np, it from hysop.constants import Basis -from hysop.constants import TranspositionState +from hysop.tools.transposition_states import TranspositionState from hysop.tools.types import to_list, to_tuple, check_instance from hysop.tools.numpywrappers import npw from hysop.tools.decorators import debug diff --git a/hysop/operator/base/transpose_operator.py b/hysop/operator/base/transpose_operator.py index a828caf8d32cbfe6e9a682dd3ac8321222b5b026..28e6ffa0960911c1c4249c1dd83348ae022b055d 100644 --- a/hysop/operator/base/transpose_operator.py +++ b/hysop/operator/base/transpose_operator.py @@ -119,7 +119,7 @@ class TransposeOperatorBase(object): If some permutation can reset the field to its default transposition state it is returned instead. """ - from hysop.constants import TranspositionState + from hysop.tools.transposition_states import TranspositionState assert candidate_axes, 'candidate axes is None or empty.' dim = len(candidate_axes.keys()[0]) tstates = TranspositionState[dim] diff --git a/hysop/operator/tests/test_directional_advection.py b/hysop/operator/tests/test_directional_advection.py index f624720ddbf1352432769ed364a367d1c5ab8dee..23bad1b5fffc26f4be1432920a8487a63710e65a 100644 --- a/hysop/operator/tests/test_directional_advection.py +++ b/hysop/operator/tests/test_directional_advection.py @@ -121,7 +121,6 @@ class TestDirectionalAdvectionOperator(object): if impl is Implementation.PYTHON: yield 'default', DirectionalAdvection(**base_kwds) elif impl is Implementation.OPENCL_CODEGEN: - return for cl_env in iter_clenv(): msg='platform {}, device {}'.format(cl_env.platform.name, cl_env.device.name) diff --git a/hysop/operator/transpose.py b/hysop/operator/transpose.py index f4e3af6ab6a65ea21d2ed30115f30c2a03f18016..894b0492b7553ecaeffa0fe26046653000ba7071 100644 --- a/hysop/operator/transpose.py +++ b/hysop/operator/transpose.py @@ -4,9 +4,10 @@ Transposition related operators. """ -from hysop.constants import Implementation, Backend, DirectionLabels, TranspositionState +from hysop.constants import Implementation, Backend, DirectionLabels from hysop.tools.types import check_instance, to_tuple from hysop.tools.decorators import debug +from hysop.tools.transposition_states import TranspositionState from hysop.fields.continuous_field import Field from hysop.topology.cartesian_descriptor import CartesianTopologyDescriptors diff --git a/hysop/topology/cartesian_topology.py b/hysop/topology/cartesian_topology.py index 04e6200aa8cb08b89fc232face176b89329271f6..368b58924356a00ce71a13bee6cf3cfe560dd752 100644 --- a/hysop/topology/cartesian_topology.py +++ b/hysop/topology/cartesian_topology.py @@ -10,7 +10,7 @@ from hysop.topology.topology import Topology, TopologyState, TopologyView, Topol from hysop.constants import np, math, Backend, Basis from hysop.constants import HYSOP_ORDER, BoundaryCondition, HYSOP_INTEGER from hysop.constants import HYSOP_MPI_REAL, HYSOP_MPI_ORDER -from hysop.constants import TranspositionState +from hysop.tools.transposition_states import TranspositionState from hysop.domain.box import Box, BoxView from hysop.core.mpi import MPI from hysop.tools.types import check_instance, to_tuple, first_not_None @@ -596,16 +596,35 @@ class CartesianTopology(CartesianTopologyView, Topology): return obj - def topology_like(self, backend=None, global_resolution=None, ghosts=None, **kwds): + def topology_like(self, backend=None, global_resolution=None, ghosts=None, + mpi_params=None, **kwds): """Return a topology like this object, possibly altered.""" global_resolution = first_not_None(global_resolution, self._discretization.resolution) ghosts = first_not_None(ghosts, self._discretization.ghosts) backend = first_not_None(backend, self._backend) discretization = Discretization(resolution=global_resolution, ghosts=ghosts) - return CartesianTopology(domain=self._domain, - discretization=discretization, backend=backend, - cart_dim=self.cart_dim, cart_shape=self.cart_shape, - is_periodic=self.is_periodic, cartesian_topology=self.cart_comm, **kwds) + + # find out the target mpi_params + from hysop.core.arrays.all import OpenClArrayBackend + if isinstance(backend, OpenClArrayBackend): + if (mpi_params is not None) and (mpi_params != backend.cl_env.mpi_params): + msg='Backend mpi params mismatch.' + raise RuntimeError(msg) + mpi_params = backend.cl_env.mpi_params + mpi_params = first_not_None(mpi_params, self.mpi_params) + + if (mpi_params == self.mpi_params): + # we can use the same cartesian communicator + return CartesianTopology(domain=self._domain, mpi_params=mpi_params, + discretization=discretization, backend=backend, + cart_dim=self.cart_dim, cart_shape=self.cart_shape, + is_periodic=self.is_periodic, cartesian_topology=self.cart_comm, **kwds) + else: + # we need to create a new cartesian communicator with the same shape + return CartesianTopology(domain=self._domain, mpi_params=mpi_params, + discretization=discretization, backend=backend, + cart_dim=self.cart_dim, cart_shape=self.cart_shape, + is_periodic=self.is_periodic, cartesian_topology=None, **kwds) def __initialize(self, domain, discretization, cart_dim, cart_size, proc_shape, diff --git a/hysop/topology/topology.py b/hysop/topology/topology.py index 4e51ed74afdde219d108702ce4edfb0925e4e310..f5e36b4308fbd3dac471891d1652261193598405 100644 --- a/hysop/topology/topology.py +++ b/hysop/topology/topology.py @@ -351,6 +351,7 @@ class Topology(RegisteredObject): cl_env = cl_env or get_or_create_opencl_env(mpi_params) assert cl_env.mpi_params == mpi_params backend = OpenClArrayBackend(cl_env=cl_env, queue=queue, allocator=allocator) + assert backend.cl_env.mpi_params == mpi_params else: msg = 'Unsupported backend {}.'.format(backend) raise ValueError(msg)