From 6388f973fbf6083be27cfce43889c22026d4c869 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Keck <Jean-Baptiste.Keck@imag.fr> Date: Sat, 31 Oct 2020 02:38:13 +0100 Subject: [PATCH] fix many __init__/__new__ --- ci/docker_images/ubuntu/groovy/Dockerfile | 27 ++++---- ci/scripts/test.sh | 7 +- .../device/codegen/functions/cache_load.py | 3 +- .../device/codegen/kernels/custom_symbolic.py | 3 +- .../codegen/kernels/directional_advection.py | 3 +- .../codegen/kernels/directional_remesh.py | 3 +- .../codegen/kernels/directional_stretching.py | 3 +- .../device/codegen/kernels/transpose.py | 3 +- hysop/backend/device/opencl/__init__.py | 3 + .../backend/device/opencl/opencl_allocator.py | 3 + .../device/opencl/opencl_array_backend.py | 7 +- hysop/backend/device/opencl/opencl_env.py | 11 +++ hysop/backend/host/host_allocator.py | 19 +++--- hysop/core/arrays/array.py | 4 +- hysop/core/arrays/array_backend.py | 4 +- hysop/core/arrays/tests/test_array.py | 16 +++-- hysop/core/graph/computational_graph.py | 11 ++- hysop/core/graph/computational_node.py | 16 ++++- hysop/core/graph/computational_operator.py | 6 +- hysop/core/graph/continuous.py | 8 +++ hysop/core/graph/graph.py | 2 +- hysop/core/graph/graph_builder.py | 5 +- hysop/core/graph/tests/test_graph.py | 10 +-- hysop/core/memory/allocator.py | 5 +- hysop/domain/box.py | 11 +++ hysop/domain/domain.py | 9 +++ hysop/fields/cartesian_discrete_field.py | 16 ++++- hysop/fields/continuous_field.py | 49 ++++++++++--- hysop/fields/default_fields.py | 6 +- hysop/fields/discrete_field.py | 25 +++++++ hysop/fields/field_requirements.py | 13 ++-- hysop/fields/ghost_exchangers.py | 4 +- hysop/fields/tests/test_fields.py | 10 +-- hysop/symbolic/base.py | 40 ++++++++++- hysop/symbolic/field.py | 68 +++++++++++++++---- hysop/symbolic/func.py | 19 ++++++ hysop/tools/contexts.py | 17 +++-- hysop/tools/handle.py | 38 ++++++----- hysop/tools/interface.py | 6 ++ hysop/tools/misc.py | 12 ++-- hysop/tools/parameters.py | 30 ++++---- hysop/tools/sympy_utils.py | 10 ++- hysop/topology/cartesian_topology.py | 28 +++++++- hysop/topology/topology.py | 4 ++ 44 files changed, 453 insertions(+), 144 deletions(-) diff --git a/ci/docker_images/ubuntu/groovy/Dockerfile b/ci/docker_images/ubuntu/groovy/Dockerfile index 44bd82a94..a4a0064a5 100644 --- a/ci/docker_images/ubuntu/groovy/Dockerfile +++ b/ci/docker_images/ubuntu/groovy/Dockerfile @@ -48,10 +48,10 @@ RUN cd /tmp && \ rm -rf /tmp/hdf5-* RUN CC="${MPICC}" HDF5_MPI="ON" HDF5_VERSION="1.10.6" HDF5_DIR="${MPI_ROOT}" pip3.8 install --upgrade --no-binary=h5py h5py -# llvm + numba + llvmlite (llvmlite 0.32 has a bug with llvm8) +# llvm + numba + llvmlite RUN apt-get install -y llvm-8-dev libclang-8-dev clang-8 ENV LLVM_CONFIG=llvm-config-8 -RUN pip3.8 install --upgrade numba llvmlite==0.31.0 +RUN pip3.8 install --upgrade numba llvmlite # other python packages (standard primefac package does not support python3) RUN pip3.8 install --upgrade scipy sympy matplotlib gmpy2 psutil py-cpuinfo Mako subprocess32 editdistance portalocker colors.py tee pycairo argparse_color_formatter networkx pyvis zarr numcodecs jsonpickle memory-tempfile @@ -59,7 +59,7 @@ RUN pip3.8 install git+git://github.com/keckj/primefac-fork@master # patchelf RUN cd /tmp && \ - git clone https://github.com/NixOS/patchelf && \ + git clone https://github.com/NixOS/patchelf.git && \ cd patchelf && \ ./bootstrap.sh && \ ./configure && \ @@ -68,18 +68,17 @@ RUN cd /tmp && \ cd - && \ rm -Rf /tmp/patchelf -# Intel experimental OpenCL platform with SYCL support (2020-09) +# Intel experimental OpenCL platform with SYCL support (2020-10) +# /!\`Newest version 2020.11 does not work ENV LD_LIBRARY_PATH "/opt/intel/oclcpuexp/x64:${LD_LIBRARY_PATH}" -RUN cd /tmp && \ - mkdir -p /opt/intel/oclcpuexp && \ - wget https://github.com/intel/llvm/releases/download/2020-09/oclcpuexp-2020.11.8.0.27_rel.tar.gz && \ +RUN mkdir -p /opt/intel/oclcpuexp && \ + wget https://github.com/intel/llvm/releases/download/2020-06/oclcpuexp-2020.10.6.0.4_rel.tar.gz && \ tar -xvzf oclcpuexp-*.tar.gz && \ mv x64/ /opt/intel/oclcpuexp/ && \ mv clbltfnshared.rtl /opt/intel/oclcpuexp/ && \ rm -rf *.rtl oclcpuexp-* && \ wget https://github.com/oneapi-src/oneTBB/releases/download/v2020.3/tbb-2020.3-lin.tgz && \ tar -xvzf tbb-*.tgz && \ - rm -f tbb-*.tgz && \ mv tbb/lib/intel64/gcc4.8/* /opt/intel/oclcpuexp/x64/ && \ rm -f /usr/local/lib/libOpenCL.so && \ rm -f /usr/local/lib/libOpenCL.so && \ @@ -117,7 +116,7 @@ RUN cd /tmp && \ # pyopencl RUN cd /tmp && \ - git clone https://github.com/inducer/pyopencl && \ + git clone https://github.com/inducer/pyopencl.git && \ cd pyopencl && \ git checkout v2020.2.2 && \ git submodule update --init && \ @@ -129,7 +128,7 @@ RUN cd /tmp && \ # oclgrind RUN cd /tmp && \ - git clone https://github.com/jrprice/Oclgrind && \ + git clone https://github.com/jrprice/Oclgrind.git && \ cd Oclgrind && \ mkdir build && \ cd build && \ @@ -142,7 +141,7 @@ RUN cd /tmp && \ # clFFT RUN cd /tmp && \ ln -s /usr/local/lib /usr/local/lib64 && \ - git clone https://github.com/clMathLibraries/clFFT && \ + git clone https://github.com/clMathLibraries/clFFT.git && \ cd clFFT && \ cd src && \ mkdir build && \ @@ -155,7 +154,7 @@ RUN cd /tmp && \ # gpyFFT RUN cd /tmp && \ - git clone https://github.com/geggo/gpyfft && \ + git clone https://github.com/geggo/gpyfft.git && \ cd gpyfft && \ pip3.8 install . && \ cd - && \ @@ -163,7 +162,7 @@ RUN cd /tmp && \ # HPTT (CPU tensor permutation library) RUN cd /tmp && \ - git clone https://gitlab.com/keckj/hptt && \ + git clone https://gitlab.com/keckj/hptt.git && \ cd hptt && \ mkdir build && \ cd build && \ @@ -223,7 +222,7 @@ RUN cd /tmp && \ RUN cd /tmp && \ git config --global user.email "you@example.com" && \ git config --global user.name "Your Name" && \ - git clone https://github.com/grlee77/pyFFTW && \ + git clone https://github.com/grlee77/pyFFTW.git && \ cd pyFFTW && \ git checkout r2r-try-three && \ git remote add fork https://github.com/pyFFTW/pyFFTW && \ diff --git a/ci/scripts/test.sh b/ci/scripts/test.sh index 40569b881..61af094ea 100755 --- a/ci/scripts/test.sh +++ b/ci/scripts/test.sh @@ -72,6 +72,7 @@ export HYSOP_VERBOSE=0 export HYSOP_DEBUG=0 export HYSOP_PROFILE=0 export HYSOP_KERNEL_DEBUG=0 +export HYSOP_TRACE_WARNINGS=1 # OpenMPI specific variables export OMPI_ALLOW_RUN_AS_ROOT=1 @@ -100,7 +101,7 @@ hysop_test() { echo echo "TESTING $1" echo "========$(printf '=%.0s' `seq ${#1}`)" - ${PYTHON_EXECUTABLE} "${TEST_DIR}/${1}" ${@:2} ${COMMON_TEST_OPTIONS} + ${PYTHON_EXECUTABLE} -Wd "${TEST_DIR}/${1}" ${@:2} ${COMMON_TEST_OPTIONS} echo } example_test() { @@ -108,12 +109,12 @@ example_test() { echo echo "EXAMPLE $1" echo "========$(printf '=%.0s' `seq ${#1}`)" - ${PYTHON_EXECUTABLE} "${EXAMPLE_DIR}/${1}" ${@:2} ${COMMON_EXAMPLE_OPTIONS} + ${PYTHON_EXECUTABLE} -Wd "${EXAMPLE_DIR}/${1}" ${@:2} ${COMMON_EXAMPLE_OPTIONS} echo } if [ "$RUN_TESTS" = true ]; then - hysop_test "core/arrays/tests/test_array.py" + #hysop_test "core/arrays/tests/test_array.py" hysop_test "core/graph/tests/test_graph.py" hysop_test "fields/tests/test_fields.py" hysop_test "numerics/tests/test_fft.py" diff --git a/hysop/backend/device/codegen/functions/cache_load.py b/hysop/backend/device/codegen/functions/cache_load.py index a3189dfb2..2cdd8c664 100644 --- a/hysop/backend/device/codegen/functions/cache_load.py +++ b/hysop/backend/device/codegen/functions/cache_load.py @@ -3,6 +3,7 @@ import contextlib from contextlib import contextmanager from hysop.tools.types import check_instance +from hysop.tools.contexts import nested from hysop.backend.device.codegen.base.opencl_codegen import OpenClCodeGenerator from hysop.backend.device.codegen.base.function_codegen import OpenClFunctionCodeGenerator from hysop.backend.device.codegen.base.variables import CodegenVariable, CodegenVectorClBuiltin @@ -179,7 +180,7 @@ class CacheLoadFunction(OpenClFunctionCodeGenerator): s.barrier(_local=True) with s._block_(): nested_loops = [_cache_iterate_(i) for i in range(work_dim-1,-1,-1)] - with contextlib.nested(*nested_loops): + with nested(*nested_loops): with s._block_(): s.append(LID.declare(const=True,init=compute_index(idx=local_pos, size=cache_size[:work_dim]))) diff --git a/hysop/backend/device/codegen/kernels/custom_symbolic.py b/hysop/backend/device/codegen/kernels/custom_symbolic.py index df977b761..acd48ab17 100644 --- a/hysop/backend/device/codegen/kernels/custom_symbolic.py +++ b/hysop/backend/device/codegen/kernels/custom_symbolic.py @@ -6,6 +6,7 @@ from abc import ABCMeta, abstractmethod from hysop import __VERBOSE__, __KERNEL_DEBUG__ from hysop.deps import sm, math, operator, hashlib from hysop.core.arrays.all import OpenClArray +from hysop.tools.contexts import nested from hysop.constants import DirectionLabels, BoundaryCondition, Backend, Precision, \ SymbolicExpressionKind @@ -1260,7 +1261,7 @@ class CustomSymbolicKernelGenerator(KernelCodeGenerator, metaclass=ABCMeta): for aij in filter(lambda x:x, ai.values()))) s.comment('Iterating over array lines') nested_loops = self._generate_loop_context() - with contextlib.nested(*nested_loops): + with nested(*nested_loops): s.load_data(event, local_id) s.jumpline() diff --git a/hysop/backend/device/codegen/kernels/directional_advection.py b/hysop/backend/device/codegen/kernels/directional_advection.py index 2ed7da6b5..eda15a1e3 100644 --- a/hysop/backend/device/codegen/kernels/directional_advection.py +++ b/hysop/backend/device/codegen/kernels/directional_advection.py @@ -9,6 +9,7 @@ from hysop.backend.device.opencl import cl from hysop.tools.misc import Utils, upper_pow2_or_3 from hysop.tools.types import check_instance, first_not_None +from hysop.tools.contexts import nested from hysop.deps import np from hysop.constants import BoundaryCondition, Backend @@ -596,7 +597,7 @@ class DirectionalAdvectionKernelGenerator(KernelCodeGenerator): if has_bilevel: s.decl_aligned_vars(velocity_gid_pos, velocity_h) - with contextlib.nested(*nested_loops): + with nested(*nested_loops): s.jumpline() if is_cached and not has_bilevel: diff --git a/hysop/backend/device/codegen/kernels/directional_remesh.py b/hysop/backend/device/codegen/kernels/directional_remesh.py index 865211fb1..01d4172ac 100644 --- a/hysop/backend/device/codegen/kernels/directional_remesh.py +++ b/hysop/backend/device/codegen/kernels/directional_remesh.py @@ -7,6 +7,7 @@ from hysop.deps import np, math, operator, hashlib from hysop.tools.misc import Utils, upper_pow2_or_3 from hysop.tools.types import check_instance, first_not_None from hysop.tools.numpywrappers import npw +from hysop.tools.contexts import nested from hysop.constants import DirectionLabels, BoundaryCondition, Backend, Precision from hysop.core.arrays.all import OpenClArray @@ -696,7 +697,7 @@ class DirectionalRemeshKernelGenerator(KernelCodeGenerator): if work_dim == 1: kmax.declare(s) last_particle.declare(s) - with contextlib.nested(*nested_loops): + with nested(*nested_loops): s.comment('Compute global offsets and line pointers') with s._align_() as al: diff --git a/hysop/backend/device/codegen/kernels/directional_stretching.py b/hysop/backend/device/codegen/kernels/directional_stretching.py index 813032f05..8355bf625 100644 --- a/hysop/backend/device/codegen/kernels/directional_stretching.py +++ b/hysop/backend/device/codegen/kernels/directional_stretching.py @@ -5,6 +5,7 @@ from hysop import __VERBOSE__, __KERNEL_DEBUG__ from hysop.tools.misc import Utils, upper_pow2_or_3 from hysop.tools.types import check_instance +from hysop.tools.contexts import nested from hysop.constants import DirectionLabels, BoundaryCondition, Backend, SpaceDiscretization from hysop.methods import StretchingFormulation @@ -506,7 +507,7 @@ class DirectionalStretchingKernel(KernelCodeGenerator): global_id.declare(s,init=False) s.jumpline() - with contextlib.nested(*nested_loops): + with nested(*nested_loops): s.jumpline() init = compute_index(idx=global_id, size=grid_size) global_index.declare(s, init=init, const=True) diff --git a/hysop/backend/device/codegen/kernels/transpose.py b/hysop/backend/device/codegen/kernels/transpose.py index a098e1908..036205cb6 100644 --- a/hysop/backend/device/codegen/kernels/transpose.py +++ b/hysop/backend/device/codegen/kernels/transpose.py @@ -1,5 +1,6 @@ -from contextlib import contextmanager, nested +from contextlib import contextmanager from hysop.deps import np, operator +from hysop.tools.contexts import nested from hysop.tools.misc import upper_pow2_or_3, prod from hysop.tools.decorators import static_vars from hysop.tools.numpywrappers import npw diff --git a/hysop/backend/device/opencl/__init__.py b/hysop/backend/device/opencl/__init__.py index e63a4b7ac..995630769 100644 --- a/hysop/backend/device/opencl/__init__.py +++ b/hysop/backend/device/opencl/__init__.py @@ -41,6 +41,9 @@ cl = pyopencl clTools = pyopencl.tools """PyOpencl tools""" +clTypes = pyopencl.cltypes +"""PyOpencl types""" + clArray = pyopencl.array """PyOpenCL arrays""" diff --git a/hysop/backend/device/opencl/opencl_allocator.py b/hysop/backend/device/opencl/opencl_allocator.py index ffe325982..ec3a7c958 100644 --- a/hysop/backend/device/opencl/opencl_allocator.py +++ b/hysop/backend/device/opencl/opencl_allocator.py @@ -10,6 +10,9 @@ class OpenClAllocator(AllocatorBase, metaclass=ABCMeta): Base class for OpenCl backend allocators. """ + def __new__(cls, queue, mem_flags=cl.mem_flags.READ_WRITE, verbose=None): + return super(OpenClAllocator, cls).__new__(cls, verbose=verbose) + def __init__(self, queue, mem_flags=cl.mem_flags.READ_WRITE, verbose=None): super(OpenClAllocator, self).__init__(verbose=verbose) if (queue.device.type == cl.device_type.CPU): diff --git a/hysop/backend/device/opencl/opencl_array_backend.py b/hysop/backend/device/opencl/opencl_array_backend.py index cdaaf1112..fb232e2f2 100644 --- a/hysop/backend/device/opencl/opencl_array_backend.py +++ b/hysop/backend/device/opencl/opencl_array_backend.py @@ -326,6 +326,9 @@ class OpenClArrayBackend(ArrayBackend): cls.__backends[key] = obj return obj + def __new__(cls, cl_env=None, queue=None, allocator=None, host_array_backend=None): + return super(OpenClArrayBackend, cls).__new__(cls, allocator=None) + def __init__(self, cl_env=None, queue=None, allocator=None, host_array_backend=None): """ @@ -1506,11 +1509,11 @@ class OpenClArrayBackend(ArrayBackend): queue = self.check_queue(queue) cq = queue #force default queue - if buf is None: + if (buf is None): assert offset==0 assert strides is None allocator = self.allocator - if min_alignment < self.allocator.device.mem_base_addr_align: + if (min_alignment is None) or (min_alignment < self.allocator.device.mem_base_addr_align): alignment=1 dtype = np.dtype(dtype) size = int(prod(shape)*dtype.itemsize) diff --git a/hysop/backend/device/opencl/opencl_env.py b/hysop/backend/device/opencl/opencl_env.py index b3b6198ca..1615d0cd4 100644 --- a/hysop/backend/device/opencl/opencl_env.py +++ b/hysop/backend/device/opencl/opencl_env.py @@ -21,6 +21,17 @@ class OpenClEnvironment(TaggedObject): """ OpenCL environment. """ + + def __new__(cls, mpi_params, + platform_id = None, + device_id = None, + device_type = None, + gl_sharing=False, + strict=True, + name=None, + **kwds): + return super(OpenClEnvironment, cls).__new__(cls, tag_prefix='clenv', **kwds) + def __init__(self, mpi_params, platform_id = None, device_id = None, diff --git a/hysop/backend/host/host_allocator.py b/hysop/backend/host/host_allocator.py index b84f9e092..30339d028 100644 --- a/hysop/backend/host/host_allocator.py +++ b/hysop/backend/host/host_allocator.py @@ -10,27 +10,30 @@ class HostAllocator(AllocatorBase): Allocator that allocates HostBuffers """ + def __new__(cls, verbose=None): + return super(HostAllocator, cls).__new__(cls, verbose=verbose) + def __init__(self, verbose=None): super(HostAllocator, self).__init__(verbose=verbose) self.mem_size = virtual_memory().total - + def max_alloc_size(self): """Max allocatable size in bytes.""" return self.mem_size - + def allocate(self, nbytes, **kwds): super(HostAllocator, self).allocate(nbytes=nbytes, **kwds) return HostBuffer(size=nbytes) - + def prefix(self): return '{}: '.format(self.full_tag) - + def is_on_host(self): """ Return true if buffers are allocated in host memory. """ return True - + def memory_pool(self, name, **kwds): """ Construct a memory pool from this allocator. @@ -39,15 +42,15 @@ class HostAllocator(AllocatorBase): if isinstance(self, MemoryPool): msg='allocator is already a memory pool.' raise RuntimeError(msg) - return HostMemoryPool(allocator=self, name=name, **kwds) + return HostMemoryPool(allocator=self, name=name, **kwds) -def __get_default_name(): +def __get_default_name(): try: cpu_name = cpuinfo.cpuinfo.get_cpu_info()['brand'] pos = cpu_name.find('@') if pos>0: cpu_name = cpu_name[:pos] - except: + except: cpu_name = 'CPU0' return cpu_name.strip() diff --git a/hysop/core/arrays/array.py b/hysop/core/arrays/array.py index f0e333b46..1c6dcac26 100644 --- a/hysop/core/arrays/array.py +++ b/hysop/core/arrays/array.py @@ -820,7 +820,7 @@ class Array(object, metaclass=ABCMeta): return self.backend.power(self, other) def __floordiv__(self, other): return self.backend.floor_divide(self, other) - def __div__(self, other): + def __truediv__(self, other): return self.backend.divide(self, other) def __mod__(self, other): return self.backend.mod(self, other) @@ -846,7 +846,7 @@ class Array(object, metaclass=ABCMeta): return self.backend.power(other, self) def __rfloordiv__(self, other): return self.backend.floor_divide(other, self) - def __rdiv__(self, other): + def __rtruediv__(self, other): return self.backend.divide(other, self) def __rmod__(self, other): return self.backend.mod(other, self) diff --git a/hysop/core/arrays/array_backend.py b/hysop/core/arrays/array_backend.py index 075eed4bd..f04a1506e 100644 --- a/hysop/core/arrays/array_backend.py +++ b/hysop/core/arrays/array_backend.py @@ -222,6 +222,8 @@ class ArrayBackend(TaggedObject, metaclass=ABCMeta): args[i] = self._arg(arg) for k,arg in kargs.items(): kargs[k] = self._arg(arg) + if 'synchronize' in kargs: + kargs['async'] = not kargs.pop('synchronize') return tuple(args), kargs def _return(self, ret, **kargs): @@ -399,7 +401,7 @@ Exception was: def _find_output_dtypes(self, fname, input_dtypes, output_arg_names): output_dtypes = {} - dtypes = input_dtypes.values() + dtypes = tuple(input_dtypes.values()) dtype = np.find_common_type([], dtypes) if fname.find('frexp')==0: diff --git a/hysop/core/arrays/tests/test_array.py b/hysop/core/arrays/tests/test_array.py index d4010b458..a67ebd745 100644 --- a/hysop/core/arrays/tests/test_array.py +++ b/hysop/core/arrays/tests/test_array.py @@ -401,9 +401,9 @@ class TestArray(object): array_binary_ops = [ '__eq__', '__ne__', '__le__', '__ge__', '__lt__', '__gt__', '__add__', '__sub__', '__mul__', '__pow__', - '__floordiv__', '__div__', '__mod__', + '__floordiv__', '__truediv__', '__mod__', '__radd__', '__rsub__', '__rmul__', '__rpow__', - '__rfloordiv__', '__rdiv__', '__rmod__' + '__rfloordiv__', '__rtruediv__', '__rmod__' ] # real_skip_list = ['angle', 'real', 'imag', 'conj', 'real_if_close'] @@ -497,11 +497,12 @@ class TestArray(object): return self def __exit__(self, exception, e, traceback): - if (e is not None): - msg = '\nTESTING: Test failed in at {}::{}() with dtypes {}\n' - msg = msg.format(backend.__class__.__name__, self.opname, self.dtypes) - print(msg) - raise exception, e, traceback + if (e is None): + return True + msg = '\nTESTING: Test failed in at {}::{}() with dtypes {}\n' + msg = msg.format(backend.__class__.__name__, self.opname, self.dtypes) + print(msg) + return False def check_inputs(name, _in): isclose = np.isclose(_in[0], _in[1].get(handle=True), equal_nan=True) @@ -805,3 +806,4 @@ if __name__ == '__main__': test.test_host_array_backend_allocator() if __HAS_OPENCL_BACKEND__: test.test_opencl_array_backend_allocator() + diff --git a/hysop/core/graph/computational_graph.py b/hysop/core/graph/computational_graph.py index 7e5ab3a9e..df3fa8692 100644 --- a/hysop/core/graph/computational_graph.py +++ b/hysop/core/graph/computational_graph.py @@ -27,6 +27,13 @@ class ComputationalGraph(ComputationalGraphNode, metaclass=ABCMeta): __FORCE_REPORTS__ = False + @debug + def __new__(cls, candidate_input_tensors=None, + candidate_output_tensors=None, + **kwds): + return super(ComputationalGraph, cls).__new__(cls, + input_fields=None, output_fields=None, **kwds) + @debug def __init__(self, candidate_input_tensors=None, candidate_output_tensors=None, @@ -810,10 +817,10 @@ class ComputationalGraph(ComputationalGraphNode, metaclass=ABCMeta): tdfield = DiscreteTensorField(field=tfield, dfields=dfields) output_discrete_tensor_fields[tfield] = tdfield - discrete_fields = tuple(set(input_discrete_fields.values() + + discrete_fields = tuple(set(input_discrete_fields.values()).union( output_discrete_fields.values())) - discrete_tensor_fields = tuple(set(input_discrete_tensor_fields.values() + + discrete_tensor_fields = tuple(set(input_discrete_tensor_fields.values()).union( output_discrete_tensor_fields.values())) else: diff --git a/hysop/core/graph/computational_node.py b/hysop/core/graph/computational_node.py index a5f125757..e1cfedcd8 100644 --- a/hysop/core/graph/computational_node.py +++ b/hysop/core/graph/computational_node.py @@ -54,6 +54,18 @@ class ComputationalGraphNode(OperatorBase, metaclass=ABCMeta): Interface of an abstract computational graph node. """ + @debug + def __new__(cls, input_fields=None, output_fields=None, + input_params=None, output_params=None, + input_tensor_fields=None, output_tensor_fields=None, + name=None, pretty_name=None, method=None, to_be_skipped_func=None, **kwds): + return super(ComputationalGraphNode, cls).__new__(cls, + name=None, + fields=None, + tensor_fields=None, + parameters=None, + **kwds) + @debug def __init__(self, input_fields=None, output_fields=None, input_params=None, output_params=None, @@ -467,7 +479,7 @@ class ComputationalGraphNode(OperatorBase, metaclass=ABCMeta): has_multiple_field_topologies = False multi_topo_fields = set() - topos = (self.input_fields.values()+self.output_fields.values()) + topos = tuple(self.input_fields.values()) + tuple(self.output_fields.values()) if topos: topo_ref = topos[0].topology for variables in [self.input_fields, self.output_fields]: @@ -531,7 +543,7 @@ class ComputationalGraphNode(OperatorBase, metaclass=ABCMeta): Topologies are organized by backend in a dictionnary. """ topologies = {} - for topo in set(self.input_fields.values()+self.output_fields.values()): + for topo in set(self.input_fields.values()).union(self.output_fields.values()): topologies.setdefault(topo.backend, set()).add(topo) return topologies diff --git a/hysop/core/graph/computational_operator.py b/hysop/core/graph/computational_operator.py index 1e16b96af..879423014 100644 --- a/hysop/core/graph/computational_operator.py +++ b/hysop/core/graph/computational_operator.py @@ -492,10 +492,10 @@ class ComputationalGraphOperator(ComputationalGraphNode, metaclass=ABCMeta): tdfield = DiscreteTensorField(field=tfield, dfields=dfields) self.output_discrete_tensor_fields[tfield] = tdfield - self.discrete_fields = tuple(set(self.input_discrete_fields.values() + + self.discrete_fields = tuple(set(self.input_discrete_fields.values()).union( self.output_discrete_fields.values())) - self.discrete_tensor_fields = tuple(set(self.input_discrete_tensor_fields.values() + + self.discrete_tensor_fields = tuple(set(self.input_discrete_tensor_fields.values()).union( self.output_discrete_tensor_fields.values())) self.discretized = True @@ -607,7 +607,7 @@ class ComputationalGraphOperator(ComputationalGraphNode, metaclass=ABCMeta): assert set(input_topology_states.keys()) == set(self.input_fields.keys()) if input_topology_states: - (ref_field, ref_state) = input_topology_states.items()[0] + (ref_field, ref_state) = tuple(input_topology_states.items())[0] ref_topo = self.input_fields[ref_field] else: ref_state = self.output_fields[output_field].topology_state diff --git a/hysop/core/graph/continuous.py b/hysop/core/graph/continuous.py index 75a4d5ec9..59c21fa82 100755 --- a/hysop/core/graph/continuous.py +++ b/hysop/core/graph/continuous.py @@ -22,6 +22,14 @@ class OperatorBase(TaggedObject, metaclass=ABCMeta): Abstract interface to continuous operators. """ + @debug + def __new__(cls, name, fields, tensor_fields, parameters, + mpi_params=None, + io_params=False, + **kwds): + return super(OperatorBase, cls).__new__(cls, tagged_cls=OperatorBase, tag_prefix='node', + **kwds) + @debug def __init__(self, name, fields, tensor_fields, parameters, mpi_params=None, diff --git a/hysop/core/graph/graph.py b/hysop/core/graph/graph.py index d2eb4107a..b325a16e9 100644 --- a/hysop/core/graph/graph.py +++ b/hysop/core/graph/graph.py @@ -103,7 +103,7 @@ class VertexAttributes(object): return self # hashing for networkx - def hash(self): + def __hash__(self): return self.node_id def __eq__(self, other): return self.node_id == other.node_id diff --git a/hysop/core/graph/graph_builder.py b/hysop/core/graph/graph_builder.py index 48d37f665..4527f390d 100644 --- a/hysop/core/graph/graph_builder.py +++ b/hysop/core/graph/graph_builder.py @@ -456,8 +456,9 @@ class GraphBuilder(object): idx_range = (nodes[0].op_ordering, nodes[-1].op_ordering) if queues: - color = queues.keys()[-1]+1 - for k in queues.keys()[::-1]: + qkeys = tuple(sorted(queues.keys())) + color = qkeys[-1]+1 + for k in qkeys[::-1]: paths = queues[k] if (paths[-1][1] < idx_range[0]): src = sorted_nodes[paths[-1][1]] diff --git a/hysop/core/graph/tests/test_graph.py b/hysop/core/graph/tests/test_graph.py index 52b0b754e..f6de4e55a 100644 --- a/hysop/core/graph/tests/test_graph.py +++ b/hysop/core/graph/tests/test_graph.py @@ -45,12 +45,12 @@ class TestGraph(object): rho1g = Field(domain=box, name='rho1g') rho1p = Field(domain=box, name='rho1p') - d3d0 = CartesianDiscretization(resolution=(64,64,64), + d3d0 = CartesianDiscretization(resolution=(64,64,64), ghosts=None, default_boundaries=True) - d3d1 = CartesianDiscretization(resolution=(128,128,128), + d3d1 = CartesianDiscretization(resolution=(128,128,128), ghosts=None, default_boundaries=True) - t0 = CartesianTopology(domain=box, discretization=d3d0) - t1 = CartesianTopology(domain=box, discretization=d3d1) + t0 = CartesianTopology(domain=box, discretization=d3d0) + t1 = CartesianTopology(domain=box, discretization=d3d1) ops = [ ('copyW', [Wg], [Wp]), @@ -98,7 +98,7 @@ class TestGraph(object): g.discretize() g.setup(None) g.apply() - + with tempfile.NamedTemporaryFile(suffix='.html') as f: g.to_html(f.name) diff --git a/hysop/core/memory/allocator.py b/hysop/core/memory/allocator.py index 4ef44783f..46616a61f 100644 --- a/hysop/core/memory/allocator.py +++ b/hysop/core/memory/allocator.py @@ -14,8 +14,11 @@ class AllocatorBase(TaggedObject, metaclass=ABCMeta): is_deferred=False + def __new__(cls, verbose, **kwds): + return super(AllocatorBase, cls).__new__(cls, tag_prefix='al', **kwds) + def __init__(self, verbose, **kwds): - super(AllocatorBase,self).__init__(tag_prefix='al', **kwds) + super(AllocatorBase, self).__init__(tag_prefix='al', **kwds) verbose = first_not_None(verbose, __TRACE_MEMALLOCS__) self._verbose = verbose diff --git a/hysop/domain/box.py b/hysop/domain/box.py index 483ba93bf..40f89c479 100644 --- a/hysop/domain/box.py +++ b/hysop/domain/box.py @@ -24,6 +24,9 @@ class BoxView(DomainView): check_instance(obj._domain, Box) return obj + def __init__(self, topology_state, domain=None, **kwds): + super(BoxView, self).__init__(topology_state=topology_state, domain=domain, **kwds) + def __get_domain_attr(self, name): """Get a transposed domain attribute.""" return self._topology_state.transposed(getattr(self._domain, name)) @@ -102,6 +105,13 @@ class Box(BoxView, Domain): Box-shaped domain description. """ + @debug + def __init__(self, length=None, origin=None, dim=None, + lboundaries=None, rboundaries=None, **kwds): + super(Box, self).__init__(length=length, origin=origin, dim=dim, + lboundaries=lboundaries, rboundaries=rboundaries, domain=None, + topology_state=None, **kwds) + @debug def __new__(cls, length=None, origin=None, dim=None, lboundaries=None, rboundaries=None, **kwds): @@ -155,6 +165,7 @@ class Box(BoxView, Domain): msg='At least one of the following parameters should be given: length, origin, dim.' raise ValueError(msg) + dim = first_not_None(dim, 0) length = to_tuple(first_not_None(length, 1.0)) origin = to_tuple(first_not_None(origin, 0.0)) dim = max(dim, len(length), len(origin)) diff --git a/hysop/domain/domain.py b/hysop/domain/domain.py index 8bbc13190..eb9ea8830 100644 --- a/hysop/domain/domain.py +++ b/hysop/domain/domain.py @@ -20,6 +20,10 @@ class DomainView(TaggedObjectView, metaclass=ABCMeta): __slots__ = ('_domain', '_topology_state') + @debug + def __init__(self, topology_state, domain=None, **kwds): + super(DomainView, self).__init__(obj_view=domain, **kwds) + @debug def __new__(cls, topology_state, domain=None, **kwds): """Create and initialize a DomainView.""" @@ -171,6 +175,11 @@ class DomainView(TaggedObjectView, metaclass=ABCMeta): class Domain(RegisteredObject, metaclass=ABCMeta): """Abstract base class for the description of physical domains. """ + @debug + def __init__(self, dim, parent_comm=None, proc_tasks=None, **kwds): + super(Domain, self).__init__(dim=dim, parent_comm=parent_comm, + proc_tasks=proc_tasks, tag_prefix='d', **kwds) + @debug def __new__(cls, dim, parent_comm=None, proc_tasks=None, **kwds): """ diff --git a/hysop/fields/cartesian_discrete_field.py b/hysop/fields/cartesian_discrete_field.py index 6bc770b17..259e13760 100644 --- a/hysop/fields/cartesian_discrete_field.py +++ b/hysop/fields/cartesian_discrete_field.py @@ -630,6 +630,12 @@ class CartesianDiscreteScalarFieldView(CartesianDiscreteScalarFieldViewContainer obj._data_view = None return obj + @debug + def __init__(self, dfield, topology_state, **kwds): + super(CartesianDiscreteScalarFieldView, self).__init__(dfield=dfield, + topology_state=topology_state, **kwds) + + def _compute_data_view(self, data=None): """ Compute transposed views of underlying discrete field data @@ -1113,8 +1119,7 @@ class CartesianDiscreteScalarFieldView(CartesianDiscreteScalarFieldViewContainer field = bfield.field_like(name=name, pretty_name=pretty_name, latex_name=latex_name, var_name=var_name, initial_values=initial_values, dtype=dtype, - lboundaries=lboundaries, rboundaries=rboundaries, - register_object=register_discrete_field) + lboundaries=lboundaries, rboundaries=rboundaries) topology = btopo.topology_like(backend=backend, grid_resolution=grid_resolution, ghosts=ghosts, @@ -1524,6 +1529,12 @@ class CartesianDiscreteScalarField(CartesianDiscreteScalarFieldView, DiscreteSca obj._mem_tag = field.mem_tag return obj + @debug + def __init__(self, field, topology, init_topology_state=None, + allocate_data=True, **kwds): + super(CartesianDiscreteScalarField, self).__init__(field=field, topology=topology, + topology_state=None, dfield=None, **kwds) + def _handle_data(self, data): assert (self._data is None) from hysop.core.arrays.array import Array @@ -1573,6 +1584,7 @@ class TmpCartesianDiscreteScalarField(CartesianDiscreteScalarField): register_discrete_field=True, **kwds) return obj + @debug def __init__(self, **kwds): super(TmpCartesianDiscreteScalarField, self).__init__(allocate_data=False, diff --git a/hysop/fields/continuous_field.py b/hysop/fields/continuous_field.py index dbd3ae56f..c378e015b 100644 --- a/hysop/fields/continuous_field.py +++ b/hysop/fields/continuous_field.py @@ -31,8 +31,7 @@ class FieldContainerI(TaggedObject): """Common abstract interface for scalar and tensor-like fields.""" @debug - def __new__(cls, domain, - name=None, nb_components=None, shape=None, is_vector=None, **kwds): + def __new__(cls, domain, name=None, nb_components=None, shape=None, is_vector=None, **kwds): """ Create a FieldContainer on a specific domain. domain : domain.Domain @@ -64,6 +63,11 @@ class FieldContainerI(TaggedObject): obj._dim = int(domain.dim) return obj + @debug + def __init__(self, domain, name=None, nb_components=None, shape=None, is_vector=None, **kwds): + super(FieldContainerI, self).__init__(**kwds) + + @property def is_scalar(self): return (not self.is_tensor) @@ -277,7 +281,7 @@ class FieldContainerI(TaggedObject): self.pretty_name)) if exprs.size in (0,1): - expr = npw.asscalar(exprs) + expr = exprs.item() return self.from_sympy_expression(expr=expr, space_symbols=frame.coords, name=name, pretty_name=pretty_name, dtype=dtype, **kwds) @@ -631,8 +635,9 @@ class ScalarField(NamedScalarContainerI, FieldContainerI): ndim=1, size=domain.dim, dtype=object) periodic = BoundaryCondition.PERIODIC - periodicity = np.asarray(map(lambda x: x.bc, lboundaries))==periodic + periodicity = np.asarray(tuple(map(lambda x: x.bc, lboundaries)))==periodic + kwds.pop('make_field', None) obj = super(ScalarField, cls).__new__(cls, domain=domain, name=name, pretty_name=pretty_name, var_name=var_name, latex_name=latex_name, @@ -656,6 +661,17 @@ class ScalarField(NamedScalarContainerI, FieldContainerI): cls.__check_vars(obj) return obj + def __init__(self, domain, name, pretty_name=None, + var_name=None, latex_name=None, + initial_values=None, dtype=HYSOP_REAL, + lboundaries=None, rboundaries=None, + is_tmp=False, mem_tag=None, **kwds): + kwds.pop('make_field', None) + super(ScalarField, self).__init__(domain=domain, + name=name, pretty_name=pretty_name, + var_name=var_name, latex_name=latex_name, + tag_prefix='f', tagged_cls=ScalarField, **kwds) + @classmethod def default_boundaries_from_domain(cls, boundaries): check_instance(boundaries, npw.ndarray, values=BoxBoundaryCondition) @@ -813,10 +829,10 @@ class ScalarField(NamedScalarContainerI, FieldContainerI): return self._rboundaries def _get_lboundaries_kind(self): """Left boundary condition kind.""" - return np.asarray(map(lambda x: x.bc, self._lboundaries)) + return np.asarray(tuple(map(lambda x: x.bc, self._lboundaries))) def _get_rboundaries_kind(self): """Right boundary condition kind.""" - return np.asarray(map(lambda x: x.bc, self._rboundaries)) + return np.asarray(tuple(map(lambda x: x.bc, self._rboundaries))) def _get_boundaries(self): """Left and right boundary conditions as a tuple.""" return (self._lboundaries, self._rboundaries) @@ -933,8 +949,7 @@ class TensorField(NamedTensorContainerI, FieldContainerI): else: fname = name_formatter(basename=name, idx=idx) pfname = pretty_name_formatter(basename=pretty_name, idx=idx) - field = make_field(idx, domain=domain, name=fname, pretty_name=pfname, - **kwds) + field = make_field(idx, domain=domain, name=fname, pretty_name=pfname, **kwds) fields += (field,) cls._check_fields(*fields) fields = npw.asarray(fields, dtype=object).reshape(shape) @@ -960,6 +975,20 @@ class TensorField(NamedTensorContainerI, FieldContainerI): obj._check_names() return obj + def __init__(self, domain, name, shape, + pretty_name=None, + name_formatter=None, + pretty_name_formatter=None, + skip_field=None, + make_field=None, + fields=None, + base_kwds=None, **kwds): + base_kwds = first_not_None(base_kwds, {}) + super(TensorField, self).__init__(domain=domain, + name=name, pretty_name=pretty_name, + tag_prefix='tf', tagged_cls=TensorField, + contained_objects=fields, **base_kwds) + def discretize(self, topology, topology_state=None): from hysop.fields.discrete_field import DiscreteTensorField dfields = npw.empty(shape=self.shape, dtype=object) @@ -1168,6 +1197,10 @@ class VectorField(TensorField): shape=shape, **kwds) return obj + def __init__(self, domain, name, nb_components=None, shape=None, **kwds): + super(VectorField, self).__init__(domain=domain, name=name, + shape=shape, **kwds) + @classmethod def default_name_formatter(cls, basename, idx): assert len(basename)>0 diff --git a/hysop/fields/default_fields.py b/hysop/fields/default_fields.py index 39d9f2db5..85b118d96 100644 --- a/hysop/fields/default_fields.py +++ b/hysop/fields/default_fields.py @@ -1,6 +1,6 @@ from hysop.tools.types import first_not_None, check_instance from hysop.tools.sympy_utils import greak, Greak, subscripts -from hysop.fields.continuous_field import Field, TensorField +from hysop.fields.continuous_field import Field, TensorField from hysop.tools.numpywrappers import npw from hysop.constants import BoxBoundaryCondition, BoundaryCondition @@ -35,7 +35,7 @@ def VelocityField(domain, name=None, pretty_name=None, **kwds): fboundaries[i] = fbd check_instance(fboundaries, npw.ndarray, values=BoundaryCondition) return fboundaries - def _make_field(idx, **fkwds): + def _make_field(idx, **fkwds): # Adapt velocity boundaries to domain boundaries component, = idx fkwds['lboundaries'] = velocity_boundaries(lboundaries, component) @@ -53,7 +53,7 @@ def VorticityField(velocity, name=None, pretty_name=None, **kwds): assert velocity.nb_components == domain.dim, 'Invalid velocity Field.' name = first_not_None(name, 'W') pretty_name = first_not_None(pretty_name, greak[24]) - return velocity.curl(name=name, pretty_name=pretty_name, + return velocity.curl(name=name, pretty_name=pretty_name, scalar_name_prefix=name, scalar_pretty_name_prefix=pretty_name, **kwds) diff --git a/hysop/fields/discrete_field.py b/hysop/fields/discrete_field.py index 16432e853..de291ea94 100644 --- a/hysop/fields/discrete_field.py +++ b/hysop/fields/discrete_field.py @@ -29,6 +29,10 @@ class DiscreteScalarFieldViewContainerI(object, metaclass=ABCMeta): discrete field views. """ + @debug + def __init__(self, **kwds): + super(DiscreteScalarFieldViewContainerI, self).__init__(**kwds) + @debug def __new__(cls, **kwds): return super(DiscreteScalarFieldViewContainerI, cls).__new__(cls, **kwds) @@ -421,6 +425,11 @@ class DiscreteScalarFieldView(DiscreteScalarFieldViewContainerI, TaggedObjectVie def is_tensor(self): return False + @debug + def __init__(self, dfield, topology_state, **kwds): + super(DiscreteScalarFieldView, self).__init__(obj_view=dfield, + variable_kind=Variable.DISCRETE_FIELD, **kwds) + @debug def __new__(cls, dfield, topology_state, **kwds): check_instance(dfield, DiscreteScalarField, allow_none=issubclass(cls, DiscreteScalarField)) @@ -614,6 +623,15 @@ class DiscreteScalarField(NamedScalarContainerI, TaggedObject, metaclass=ABCMeta depending on the discrete field topology backend and the ghost exchange strategy. """ + @debug + def __init__(self, field, topology, register_discrete_field=True, + name=None, pretty_name=None, + var_name=None, latex_name=None, + **kwds): + super(DiscreteScalarField, self).__init__(name=name, pretty_name=pretty_name, + var_name=var_name, latex_name=latex_name, + tag_prefix='df', **kwds) + @debug def __new__(cls, field, topology, register_discrete_field=True, name=None, pretty_name=None, @@ -728,6 +746,13 @@ class DiscreteTensorField(NamedTensorContainerI, DiscreteScalarFieldViewContaine def is_tensor(self): return True + def __init__(self, field, dfields, name=None, + pretty_name=None, latex_name=None, **kwds): + super(DiscreteTensorField, self).__init__(name=name, + pretty_name=pretty_name, latex_name=latex_name, + tag_prefix='tdf', tagged_cls=DiscreteTensorField, + contained_objects=dfields, **kwds) + def __new__(cls, field, dfields, name=None, pretty_name=None, latex_name=None, **kwds): check_instance(field, TensorField) diff --git a/hysop/fields/field_requirements.py b/hysop/fields/field_requirements.py index 03bd48cd1..2d982aff7 100644 --- a/hysop/fields/field_requirements.py +++ b/hysop/fields/field_requirements.py @@ -353,7 +353,7 @@ class MultiFieldRequirements(object): return None else: assert self.nrequirements() == 1 - return next(iter(self.requirements.values()[0])) + return next(iter(tuple(self.requirements.values())[0])) def nrequirements(self): return sum(len(lreqs) for lreqs in self.requirements.values()) @@ -378,7 +378,7 @@ class MultiFieldRequirements(object): return gprint(" 1) SPLITTING REQUIREMENTS IN COMPATIBLE SUBGROUPS:") - multi_process = (self.requirements.keys()[0].mpi_params.size > 1) + multi_process = (tuple(self.requirements.keys())[0].mpi_params.size > 1) splitted_reqs = self._split(multi_process) gprint(" 2) DETERMINING COMMON CARTESIAN TOPOLOGY SPLITTING AXES (if possible):") @@ -584,8 +584,8 @@ class OperatorFieldRequirements(object): Iterates over (is_input, field, topology_descriptor, field_requirement) for all inputs and outputs. """ - it0 = it.izip_longest((True,), self.iter_input_requirements()) - it1 = it.izip_longest((False,), self.iter_output_requirements()) + it0 = it.zip_longest((True,), self.iter_input_requirements()) + it1 = it.zip_longest((False,), self.iter_output_requirements()) return it.chain(it0, it1) def _get_requirement(self, field, field_requirements): @@ -609,7 +609,7 @@ class OperatorFieldRequirements(object): if len(freqs.keys()) == 0: msg = 'No topology descriptors are present for field {}.'.format(field.name) raise RuntimeError(msg) - td = freqs.keys()[0] + td = tuple(freqs.keys())[0] reqs = freqs[td] if len(reqs) > 1: msg = 'Multiple requirements are present for field {}.'.format(field.name) @@ -624,8 +624,7 @@ class OperatorFieldRequirements(object): @debug def build_topologies(self): - fields = set(self._input_field_requirements.keys() - + self._output_field_requirements.keys()) + fields = set(self._input_field_requirements.keys()).union(self._output_field_requirements.keys()) # enforce deterministic iteration for field in sorted(fields, key=lambda x: '{}::{}'.format(x.name, x.short_description())): reqs = MultiFieldRequirements(field) diff --git a/hysop/fields/ghost_exchangers.py b/hysop/fields/ghost_exchangers.py index 0702b83ec..f22ffbecf 100644 --- a/hysop/fields/ghost_exchangers.py +++ b/hysop/fields/ghost_exchangers.py @@ -302,10 +302,10 @@ class CartesianDiscreteFieldGhostExchanger(GhostExchanger): # check that enforced boundaries kind matches topology boundaries if (global_lboundaries_config is not None): - global_lboundaries = np.asarray(map(lambda x: x.bc, global_lboundaries_config)) + global_lboundaries = np.asarray(tuple(map(lambda x: x.bc, global_lboundaries_config))) assert (global_lboundaries == mesh.global_lboundaries).all(), (global_lboundaries, mesh.global_lboundaries) if (global_rboundaries_config is not None): - global_rboundaries = np.asarray(map(lambda x: x.bc, global_rboundaries_config)) + global_rboundaries = np.asarray(tuple(map(lambda x: x.bc, global_rboundaries_config))) assert (global_rboundaries == mesh.global_rboundaries).all(), (global_rboundaries, mesh.global_rboundaries) self.global_lboundaries_config = global_lboundaries_config self.global_rboundaries_config = global_rboundaries_config diff --git a/hysop/fields/tests/test_fields.py b/hysop/fields/tests/test_fields.py index a844654a5..2466f2588 100644 --- a/hysop/fields/tests/test_fields.py +++ b/hysop/fields/tests/test_fields.py @@ -159,8 +159,8 @@ def test_tensor_field(): assert t1.dtype != t0.dtype assert t1.name.replace('1', '0', 1) == t0.name assert t1.pretty_name.replace('1', '0', 1) == t0.pretty_name - assert t0.dim is 3 - assert t1.dim is 3 + assert t0.dim == 3 + assert t1.dim == 3 assert np.array_equal(T0._fields[1:, 1:], T2._fields) assert T0._fields[1, 1] is T3 assert T0._fields[0, 0] is T4[0, 0] @@ -305,9 +305,9 @@ def test_tensor_field(): assert (DT0.coords[i] == dfield.coords[i]).all() assert (DT0.mesh_coords[i] == dfield.mesh_coords[i]).all() assert DT0.compute_slices == dfield.compute_slices - assert np.array_equal(DT0.inner_ghost_slices, dfield.inner_ghost_slices) - assert np.array_equal(DT0.inner_ghost_slices, dfield.inner_ghost_slices) - assert np.array_equal(DT0.outer_ghost_slices, dfield.outer_ghost_slices) + assert DT0.inner_ghost_slices == dfield.inner_ghost_slices + assert DT0.inner_ghost_slices == dfield.inner_ghost_slices + assert DT0.outer_ghost_slices == dfield.outer_ghost_slices assert DT0.grid_npoints == dfield.grid_npoints assert DT0.axes == dfield.axes assert DT0.tstate == dfield.tstate diff --git a/hysop/symbolic/base.py b/hysop/symbolic/base.py index 2641ddfc5..0ad4dca61 100644 --- a/hysop/symbolic/base.py +++ b/hysop/symbolic/base.py @@ -16,6 +16,9 @@ class ValueHolderI(object): def __new__(cls, *args, **kwds): return super(ValueHolderI, cls).__new__(cls, *args, **kwds) + def __init__(self, *args, **kwds): + super(ValueHolderI, self).__init__(*args, **kwds) + def get_holded_value(self): """Get holded value, defaults to None.""" return None @@ -42,7 +45,9 @@ class ValueHolderI(object): except AttributeError: return expr + class ScalarDataViewHolder(ValueHolderI): + def __new__(cls, holded_data_ref=None, holded_data_access=None, **kwds): if isinstance(holded_data_ref, npw.ndarray) and \ (holded_data_access is None) and (holded_data_ref.size == 1): @@ -52,6 +57,9 @@ class ScalarDataViewHolder(ValueHolderI): obj._holded_data_access = holded_data_access return obj + def __init__(self, holded_data_ref=None, holded_data_access=None, **kwds): + super(ScalarDataViewHolder, self).__init__(**kwds) + def get_holded_value(self): if (self._holded_value_ref is None): return None @@ -68,13 +76,18 @@ class ScalarDataViewHolder(ValueHolderI): hc += (id(self._holded_value_ref), self._holded_data_access,) return hc + class ScalarBaseTag(object): """Tag for object that can be inserted as element of tensors.""" + def __new__(cls, idx=None, **kwds): obj = super(ScalarBaseTag, cls).__new__(cls, **kwds) obj._idx = idx return obj + def __init__(self, idx=None, **kwds): + super(ScalarBaseTag, self).__init__(**kwds) + @property def idx(self): return self._idx @@ -85,6 +98,7 @@ class ScalarBaseTag(object): hc += (self._idx,) return hc + class ScalarBase(ScalarDataViewHolder, ScalarBaseTag): """Base for symbolic scalars.""" def __new__(cls, name, value=None, view=None, **kwds): @@ -94,10 +108,13 @@ class ScalarBase(ScalarDataViewHolder, ScalarBaseTag): if (view is not None): assert (kwds.get('holded_data_access', None) is None) kwds['holded_data_access'] = view - obj = super(ScalarBase, cls).__new__(cls, name=name, - **kwds) + obj = super(ScalarBase, cls).__new__(cls, name=name, **kwds) obj._iterable = False return obj + + def __init__(self, name, value=None, view=None, **kwds): + super(ScalarBase, self).__init__(name=name, **kwds) + def vreplace(self): """Call ValueHolderI.replace_holded_values on self.""" return self.replace_holded_values(self) @@ -106,6 +123,7 @@ class ScalarBase(ScalarDataViewHolder, ScalarBaseTag): assert key == 0 return self + class TensorBase(npw.ndarray): """ Base for symbolic tensors. @@ -163,6 +181,13 @@ class TensorBase(npw.ndarray): obj[...] = init return obj + def __init__(self, shape, init=None, + name=None, pretty_name=None, + scalar_cls=None, scalar_kwds=None, make_scalar_kwds=None, + value=None, set_read_only=True, + dtype=object, **kwds): + super(TensorBase, self).__init__(**kwds) + def latex(self, matrix='b', with_packages=False): """ Return a latex representation of this tensor. @@ -284,6 +309,7 @@ class SymbolicScalar(ScalarBase, Symbol): """Symbolic scalar symbol.""" pass + class DummySymbolicScalar(ScalarBase, Dummy): """Symbolic scalar dummy symbol.""" pass @@ -296,6 +322,11 @@ class SymbolicTensor(TensorBase): return super(SymbolicTensor, cls).__new__(cls, name=name, shape=shape, init=init, scalar_cls=scalar_cls, **kwds) + def __init__(self, name, shape, init=None, scalar_cls=None, **kwds): + super(SymbolicTensor, self).__init__(name=name, shape=shape, init=init, + scalar_cls=scalar_cls, **kwds) + + class DummySymbolicTensor(TensorBase): """Dummy symbolic tensor symbol.""" def __new__(cls, name, shape, init=None, scalar_cls=None, **kwds): @@ -303,6 +334,11 @@ class DummySymbolicTensor(TensorBase): return super(DummySymbolicTensor, cls).__new__(cls, name=name, shape=shape, init=init, scalar_cls=scalar_cls, **kwds) + def __init__(self, name, shape, init=None, scalar_cls=None, **kwds): + super(DummySymbolicTensor, self).__init__(name=name, shape=shape, init=init, + scalar_cls=scalar_cls, **kwds) + + def vreplace(expr): ValueHolderI.replace_holded_values(expr) diff --git a/hysop/symbolic/field.py b/hysop/symbolic/field.py index 5fb8903dd..5b9c34e1e 100644 --- a/hysop/symbolic/field.py +++ b/hysop/symbolic/field.py @@ -16,6 +16,12 @@ from hysop.symbolic.func import UndefinedFunction, AppliedSymbolicFunction, Func from hysop.domain.domain import Domain class FieldExpressionI(object): + def __new__(cls, *args, **kwds): + return super(FieldExpressionI, cls).__new__(cls, *args, **kwds) + + def __init__(self, *args, **kwds): + super(FieldExpressionI, self).__init__(**kwds) + @abstractmethod def lboundaries(self): pass @@ -42,17 +48,27 @@ class FieldExpressionI(object): class FieldExpression(FieldExpressionI): + + def __new__(cls, *args, **kwds): + domain = kwds.pop('domain', None) + dtype = kwds.pop('dtype', None) + lboundaries = kwds.pop('lboundaries', None) + rboundaries = kwds.pop('rboundaries', None) + obj = super(FieldExpression, cls).__new__(cls, *args, **kwds) + obj._domain = domain + obj._dtype = dtype + obj._lboundaries = lboundaries + obj._rboundaries = rboundaries + return obj + def __init__(self, *args, **kwds): - self._domain = kwds.pop('domain', None) - self._dtype = kwds.pop('dtype', None) - self._lboundaries = kwds.pop('lboundaries', None) - self._rboundaries = kwds.pop('rboundaries', None) super(FieldExpression, self).__init__(*args, **kwds) @property def lboundaries(self): assert (self._lboundaries is not None) return self._lboundaries + @lboundaries.setter def lboundaries(self, lb): check_instance(lb, npw.ndarray, values=BoundaryCondition, @@ -63,6 +79,7 @@ class FieldExpression(FieldExpressionI): def rboundaries(self): assert (self._rboundaries is not None) return self._rboundaries + @rboundaries.setter def rboundaries(self, rb): check_instance(rb, npw.ndarray, values=BoundaryCondition, @@ -73,6 +90,7 @@ class FieldExpression(FieldExpressionI): def domain(self): assert (self._domain is not None) return self._domain + @domain.setter def domain(self, dom): assert (self._domain is None) @@ -83,12 +101,15 @@ class FieldExpression(FieldExpressionI): def dtype(self): assert (self._dtype is not None) return self._dtype + @dtype.setter def dtype(self, dt): assert (self._dtype is None) check_instance(dt, npw.dtype) self._dtype = dt +class DerivativeFieldExpr(FieldExpression, sm.Derivative): + pass class FieldExpressionBuilder(object): class BoundaryIncompatibilityError(ValueError): @@ -123,8 +144,6 @@ class FieldExpressionBuilder(object): if cls.is_field_expr(expr): return expr elif isinstance(expr, sm.Derivative): - class DerivativeFieldExpr(FieldExpression, sm.Derivative): - pass e = _to_field_expression_impl(expr.args[0]) if cls.is_field_expr(e): dtype, domain = e.dtype, e.domain @@ -205,8 +224,7 @@ class FieldBase(FunctionBase): '''for sympify''' return self - def __new__(cls, field, idx=None, - **kwds): + def __new__(cls, field, idx=None, **kwds): assert 'name' not in kwds assert 'pretty_name' not in kwds assert 'latex_name' not in kwds @@ -219,12 +237,21 @@ class FieldBase(FunctionBase): var_name = field.var_name latex_name = field.latex_name assert (0<=index<field.nb_components), index - obj = super(FieldBase, cls).__new__(cls, name=name, pretty_name=pretty_name, - var_name=var_name, latex_name=latex_name, **kwds) + try: + obj = super(FieldBase, cls).__new__(cls, name=name, pretty_name=pretty_name, + var_name=var_name, latex_name=latex_name, **kwds) + except TypeError: + obj = super(FieldBase, cls).__new__(cls, name=name, **kwds) obj._field = field obj._index = index return obj + def __init__(self, field, idx=None, **kwds): + try: + super(FieldBase, self).__init__(name=None, pretty_name=None, var_name=None, latex_name=None, **kwds) + except TypeError: + super(FieldBase, self).__init__(name=None, **kwds) + def _hashable_content(self): """See sympy.core.basic.Basic._hashable_content()""" hc = super(FieldBase, self)._hashable_content() @@ -248,6 +275,7 @@ class FieldBase(FunctionBase): assert key == 0 return self + class SymbolicDiscreteField(FieldBase, Symbol): """ Symbolic discrete field symbol. @@ -257,6 +285,9 @@ class SymbolicDiscreteField(FieldBase, Symbol): return super(SymbolicDiscreteField, cls).__new__(cls, field=field, fn=fn, **kwds) + def __init__(self, field, name=None, fn=None, **kwds): + super(SymbolicDiscreteField, self).__init__(field=field, fn=fn, **kwds) + @classmethod def from_field(cls, field): if (field.nb_components == 1): @@ -264,6 +295,7 @@ class SymbolicDiscreteField(FieldBase, Symbol): else: return SymbolicDiscreteFieldTensor(field=field) + class SymbolicField(FieldBase, UndefinedFunction): """ Symbolic unapplied scalar field as an undefined function of some frame coordinates and time. @@ -272,8 +304,10 @@ class SymbolicField(FieldBase, UndefinedFunction): def __new__(cls, field, fn=None, bases=None, **kwds): bases = first_not_None(bases, (AppliedSymbolicField,)) check_instance(field, Field) - return super(SymbolicField, cls).__new__(cls, bases=bases, - field=field, fn=fn, **kwds) + return super(SymbolicField, cls).__new__(cls, bases=bases, field=field, fn=fn, **kwds) + + def __init__(self, field, fn=None, bases=None, **kwds): + super(SymbolicField, self).__init__(bases=bases, field=field, fn=fn, **kwds) def __hash__(self): "Fix sympy v1.2 hashes" @@ -302,6 +336,9 @@ class AppliedSymbolicField(FieldExpressionI, AppliedSymbolicFunction): args = args if args else cls.field.domain.frame.vars return super(AppliedSymbolicField, cls).__new__(cls, *args, **kwds) + def __init__(self, *args, **kwds): + super(AppliedSymbolicField, self).__init__(*args, **kwds) + def _sympy_(self): '''for sympify''' return self @@ -353,6 +390,10 @@ class SymbolicFieldTensor(SymbolicFunctionTensor): init[idx] = field.symbol return super(SymbolicFieldTensor, cls).__new__(cls, shape=shape, init=init) + def __init__(self, field, **kwds): + super(SymbolicFieldTensor, self).__init__(shape=None, init=None) + + class SymbolicDiscreteFieldTensor(TensorBase): """Symbolic tensor symbol.""" def __new__(cls, dfield, name=None, **kwds): @@ -365,6 +406,9 @@ class SymbolicDiscreteFieldTensor(TensorBase): return super(SymbolicDiscreteFieldTensor, cls).__new__(cls, shape=shape, init=init, **kwds) + def __init__(self, dfield, name=None, **kwds): + super(SymbolicDiscreteFieldTensor, self).__init__(shape=None, init=None, **kwds) + def diff(F, *symbols, **assumptions): is_tensor = isinstance(F, npw.ndarray) diff --git a/hysop/symbolic/func.py b/hysop/symbolic/func.py index 180a1970d..61bd42f75 100644 --- a/hysop/symbolic/func.py +++ b/hysop/symbolic/func.py @@ -14,12 +14,17 @@ class FunctionBase(ScalarBaseTag): obj.fn = staticmethod(fn) return obj + def __init__(self, *args, **kwds): + kwds.pop('fn') + super(FunctionBase, self).__init__(*args, **kwds) + def _hashable_content(self): """See sympy.core.basic.Basic._hashable_content()""" hc = super(FunctionBase, self)._hashable_content() hc += (self.fn,) return hc + class SymbolicFunction(FunctionBase, UndefinedFunction): """Unapplied symbolic scalar function.""" def __new__(cls, name, fn=None, bases=None, **kwds): @@ -27,11 +32,19 @@ class SymbolicFunction(FunctionBase, UndefinedFunction): return super(SymbolicFunction, cls).__new__(cls, bases=bases, name=name, fn=fn, **kwds) + def __init__(self, name, fn=None, bases=None, **kwds): + super(SymbolicFunction, self).__init__(bases=bases, + name=name, fn=fn, **kwds) + + class AppliedSymbolicFunction(AppliedUndef): """Applied symbolic scalar function.""" def __new__(cls, *args, **kwds): return super(AppliedSymbolicFunction, cls).__new__(cls, *args, **kwds) + def __init__(self, *args, **kwds): + super(AppliedSymbolicFunction, self).__init__(**kwds) + def freplace(self): if (self.fn is not None): return self.fn(*self.args) @@ -41,6 +54,7 @@ class AppliedSymbolicFunction(AppliedUndef): def __call__(self): return self.freplace() + class SymbolicFunctionTensor(TensorBase): """Symbolic tensor symbol.""" def __new__(cls, shape, name=None, fn=None, init=None, @@ -51,6 +65,11 @@ class SymbolicFunctionTensor(TensorBase): return super(SymbolicFunctionTensor, cls).__new__(cls, name=name, shape=shape, init=init, scalar_cls=scalar_cls, scalar_kwds=scalar_kwds, **kwds) + def __init__(self, shape, name=None, fn=None, init=None, + scalar_cls=None, scalar_kwds=None, **kwds): + super(SymbolicFunctionTensor, self).__init__(name=name, shape=None, init=None, + scalar_cls=scalar_cls, scalar_kwds=scalar_kwds, **kwds) + def __call__(self, *args, **kwds): return self.elementwise_fn(lambda x: x(*args, **kwds)) diff --git a/hysop/tools/contexts.py b/hysop/tools/contexts.py index 7703a92ad..c8314ec11 100644 --- a/hysop/tools/contexts.py +++ b/hysop/tools/contexts.py @@ -1,9 +1,14 @@ import os from hysop.deps import np, time, sys -from contextlib import contextmanager +from contextlib import contextmanager, ExitStack -class Timer(object): +@contextmanager +def nested(*managers): + with ExitStack() as stack: + yield tuple(stack.enter_context(m) for m in managers) + +class Timer(object): def __enter__(self, factor=1): self.start = time.time() self.factor = factor @@ -21,7 +26,7 @@ class Timer(object): def printoptions(*args, **kwargs): original = np.get_printoptions() np.set_printoptions(*args, **kwargs) - yield + yield np.set_printoptions(**original) @@ -32,7 +37,7 @@ def systrace(fn=None): print('{} {}:{}'.format(event, frame.f_code.co_filename, frame.f_lineno)) fn = fn or __trace sys.settrace(fn) - yield + yield sys.settrace(__old_trace) @contextmanager @@ -66,7 +71,7 @@ def stdout_redirected(to=os.devnull): # C-level redirection (file descriptor le return fd stdout = sys.stdout stdout_fd = fileno(stdout) - with os.fdopen(os.dup(stdout_fd), 'wb') as copied: + with os.fdopen(os.dup(stdout_fd), 'wb') as copied: stdout.flush() os.dup2(fileno(to), stdout_fd) try: @@ -84,7 +89,7 @@ def stderr_redirected(to=os.devnull): # C-level redirection (file descriptor le return fd stderr = sys.stderr stderr_fd = fileno(stderr) - with os.fdopen(os.dup(stderr_fd), 'wb') as copied: + with os.fdopen(os.dup(stderr_fd), 'wb') as copied: stderr.flush() os.dup2(fileno(to), stderr_fd) try: diff --git a/hysop/tools/handle.py b/hysop/tools/handle.py index 052cc93da..be5f31772 100644 --- a/hysop/tools/handle.py +++ b/hysop/tools/handle.py @@ -98,7 +98,7 @@ class TaggedObject(object, metaclass=ABCMeta): if kwds: print('TARGGED OBJECT MRO is {}'.format(cls.__mro__)) - print('KWDS are {}'.format(kwds)) + print('KWDS NEW are {}'.format(kwds)) obj = super(TaggedObject, cls).__new__(cls, **kwds) if tagged_cls in TaggedObject.__ids: obj.__tag_id = TaggedObject.__ids[tagged_cls] @@ -113,18 +113,19 @@ class TaggedObject(object, metaclass=ABCMeta): return obj @debug - def __init__(self, *args, **kwds): + def __init__(self, tag_prefix=None, tag_postfix=None, tag_formatter=None, + tagged_cls=None, **kwds): """ Initialize a TaggedObject with a tag prefix/postfix/formatter, all optional. """ - tag_prefix = kwds.pop('tag_prefix', None) - tag_postfix = kwds.pop('tag_postfix', None) - tag_formatter = kwds.pop('tag_formatter', None) assert (tag_prefix is None) or isinstance(tag_prefix, str) assert (tag_postfix is None) or isinstance(tag_postfix, str) assert (tag_formatter is None) or callable(tag_formatter) - super(TaggedObject, self).__init__() + if kwds: + print('TARGGED OBJECT MRO is {}'.format(self.__class__.__mro__)) + print('KWDS INIT are {}'.format(kwds)) + super(TaggedObject, self).__init__(**kwds) # reaffect attributes (some classes use only __init__ for simplicity) self.__tag_prefix = first_not_None(self.__tag_prefix, tag_prefix, '') @@ -333,16 +334,10 @@ class RegisteredObject(TaggedObject): obj.__initialized = False return obj - def __del__(self): - key = None - for k,v in self.__registered_objects.items(): - if v is self: - key = k - if (key is not None): - del self.__registered_objects[key] - @debug - def __init__(self, **kwds): + def __init__(self, register_object=True, + tag_prefix=None, tag_postfix=None, tag_formatter=None, + **kwds): """ Initialize this object. If self._initialized was already set to True, raise a RuntimeError. @@ -350,9 +345,20 @@ class RegisteredObject(TaggedObject): """ if self.__initialized: return - super(RegisteredObject,self).__init__(**kwds) + super(RegisteredObject, self).__init__( + tag_prefix=tag_prefix, + tag_postfix=tag_postfix, + tag_formatter=tag_formatter) self.__initialized = True + def __del__(self): + key = None + for k,v in self.__registered_objects.items(): + if v is self: + key = k + if (key is not None): + del self.__registered_objects[key] + def __get_obj_initialized(self): """ Return the object initialization state. diff --git a/hysop/tools/interface.py b/hysop/tools/interface.py index 789b52f20..aaeb01f86 100644 --- a/hysop/tools/interface.py +++ b/hysop/tools/interface.py @@ -37,6 +37,9 @@ class NamedObjectI(object, metaclass=ABCMeta): latex_name=latex_name, var_name=var_name) return obj + def __init__(self, name, pretty_name=None, latex_name=None, var_name=None, **kwds): + super(NamedObjectI, self).__init__(**kwds) + def rename(self, name, pretty_name=None, latex_name=None, var_name=None): """Change the names of this object.""" check_instance(name, str) @@ -140,6 +143,9 @@ class NamedTensorContainerI(NamedObjectI, SymbolContainerI): obj._contained_objects = contained_objects return obj + def __init__(self, contained_objects, **kwds): + super(NamedTensorContainerI, self).__init__(**kwds) + def rename(self, name, pretty_name=None, latex_name=None, var_name=None): """Change the names of this object.""" diff --git a/hysop/tools/misc.py b/hysop/tools/misc.py index ab6529ddc..edc9fee78 100644 --- a/hysop/tools/misc.py +++ b/hysop/tools/misc.py @@ -10,6 +10,10 @@ from hysop.deps import inspect, np, functools, operator from hysop.constants import HYSOP_REAL, HYSOP_INTEGER +def getargspec(func): + spec = inspect.getfullargspec(func) + return (spec.args, spec.varargs, spec.varkw, spec.defaults) + def prod(values): """ Like sum but for products (of integers). @@ -29,7 +33,7 @@ def get_default_args(func): """ returns a dictionary of arg_name:default_values for the input function. """ - args, varargs, keywords, defaults = inspect.getargspec(func) + args, varargs, keywords, defaults = getargspec(func) if defaults is None: return dict() else: @@ -39,15 +43,15 @@ def get_argnames(func): """ returns arguments name and possible varargs. """ - argnames,varargs,_,_ = inspect.getargspec(func) + argnames,varargs,_,_ = getargspec(func) return argnames, varargs def args2kargs(func, args): - argnames,_,_,_ = inspect.getargspec(func) + argnames,_,_,_ = getargspec(func) return dict(zip(argnames, args)) def kargs2args(func, kargs, remove=[]): - argnames,_,_,_ = inspect.getargspec(func) + argnames,_,_,_ = getargspec(func) return tuple([kargs[a] for a in argnames if a not in remove]) def upper_pow2(x): diff --git a/hysop/tools/parameters.py b/hysop/tools/parameters.py index b59b80b89..e0e3cb738 100755 --- a/hysop/tools/parameters.py +++ b/hysop/tools/parameters.py @@ -41,9 +41,9 @@ class MPIParams(namedtuple('MPIParams', ['comm', 'size', 'task_id', and tell if the current operator belongs to the current process mpi task. """ - def __new__(cls, comm=main_comm, + def __new__(cls, comm=main_comm, task_id=HYSOP_DEFAULT_TASK_ID, - rank=main_rank, + rank=main_rank, on_task=True): if (comm != MPI.COMM_NULL): rank = comm.Get_rank() @@ -67,12 +67,12 @@ class MPIParams(namedtuple('MPIParams', ['comm', 'size', 'task_id', def __hash__(self): h = hashlib.sha1() - h.update(str(self.task_id)) - h.update(str(self.on_task)) + h.update(str(self.task_id).encode('utf-8')) + h.update(str(self.on_task).encode('utf-8')) return hash(h.hexdigest()) ^ id(self.comm) -class CartesianDiscretization(namedtuple("CartesianDiscretization", +class CartesianDiscretization(namedtuple("CartesianDiscretization", ['resolution', 'ghosts', 'lboundaries', 'rboundaries'])): """ A struct to handle discretization parameters: @@ -81,10 +81,10 @@ class CartesianDiscretization(namedtuple("CartesianDiscretization", - number of points in the ghost-layer. One value per direction, list or array. Default = None (ie. no ghosts). - global boundary conditions that should be prescribed on the left and the - right of the box shaped domain for each axis. Defaults to periodic + right of the box shaped domain for each axis. Defaults to periodic boundary conditions everywhere. """ - def __new__(cls, resolution, ghosts=None, + def __new__(cls, resolution, ghosts=None, lboundaries=None, rboundaries=None, default_boundaries=False): assert not ((lboundaries is None) ^ (rboundaries is None)) @@ -107,12 +107,12 @@ class CartesianDiscretization(namedtuple("CartesianDiscretization", lboundaries = npw.empty(shape=(resolution.size,), dtype=object) lboundaries[...] = BoundaryCondition.PERIODIC rboundaries = lboundaries.copy() - - check_instance(lboundaries, npw.ndarray, dtype=object, + + check_instance(lboundaries, npw.ndarray, dtype=object, size=resolution.size, values=BoundaryCondition, allow_none=True) - check_instance(rboundaries, npw.ndarray, dtype=object, - size=resolution.size, values=BoundaryCondition, + check_instance(rboundaries, npw.ndarray, dtype=object, + size=resolution.size, values=BoundaryCondition, allow_none=True) npw.set_readonly(resolution, ghosts) @@ -121,7 +121,7 @@ class CartesianDiscretization(namedtuple("CartesianDiscretization", return super(CartesianDiscretization, cls).__new__(cls, resolution, ghosts, lboundaries, rboundaries) - + @property def boundaries(self): """Left and right boundary conditions as a tuple.""" @@ -129,7 +129,7 @@ class CartesianDiscretization(namedtuple("CartesianDiscretization", raise AttributeError else: return (self.lboundaries, self.rboundaries) - + @property def periodicity(self): if (self.lboundaries is None) or (self.rboundaries is None): @@ -184,7 +184,7 @@ class CartesianDiscretization(namedtuple("CartesianDiscretization", h.update(self.resolution.view(npw.uint8)) h.update(self.ghosts.view(npw.uint8)) if (self.lboundaries is not None): - h.update(str(hash(tuple(int(bd) for bd in self.lboundaries)))) + h.update(str(hash(tuple(int(bd) for bd in self.lboundaries))).encode('utf-8')) if (self.rboundaries is not None): - h.update(str(hash(tuple(int(bd) for bd in self.rboundaries)))) + h.update(str(hash(tuple(int(bd) for bd in self.rboundaries))).encode('utf-8')) return hash(h.hexdigest()) diff --git a/hysop/tools/sympy_utils.py b/hysop/tools/sympy_utils.py index 86af1a8a0..c947dce10 100644 --- a/hysop/tools/sympy_utils.py +++ b/hysop/tools/sympy_utils.py @@ -76,13 +76,20 @@ class SymbolicBase(object): check_instance(var_name, str, allow_none=True) check_instance(latex_name, str, allow_none=True) check_instance(pretty_name, str, allow_none=True) - obj = super(SymbolicBase, cls).__new__(cls, name=name, **kwds) + try: + obj = super(SymbolicBase, cls).__new__(cls, name=name, **kwds) + except TypeError: + obj = super(SymbolicBase, cls).__new__(cls, **kwds) obj._name = name obj._var_name = first_not_None(var_name, name) obj._latex_name = first_not_None(latex_name, name) obj._pretty_name = first_not_None(pretty_name, name) return obj + def __init__(self, name, var_name=None, latex_name=None, + pretty_name=None, **kwds): + pass + @property def varname(self): return self._var_name @@ -123,6 +130,7 @@ class Dummy(SymbolicBase, sm.Dummy): from sympy.core.function import UndefinedFunction as SympyUndefinedFunction from sympy.core.function import AppliedUndef as SympyAppliedUndef + class UndefinedFunction(SymbolicBase, SympyUndefinedFunction): """ Tag for hysop (unapplied) undefined functions. diff --git a/hysop/topology/cartesian_topology.py b/hysop/topology/cartesian_topology.py index 85feb8cfa..1a4450aa5 100644 --- a/hysop/topology/cartesian_topology.py +++ b/hysop/topology/cartesian_topology.py @@ -190,6 +190,10 @@ class CartesianTopologyView(TopologyView): __slots__ = ('_mesh_view', '_domain_view', '_topology', '_topology_state') + @debug + def __init__(self, topology_state, topology=None, **kwds): + super(CartesianTopologyView, self).__init__(topology_state=topology_state, topology=topology, **kwds) + @debug def __new__(cls, topology_state, topology=None, **kwds): """ @@ -456,6 +460,23 @@ class CartesianTopology(CartesianTopologyView, Topology): accross processes through a MPI CartesianTopology communicator. """ + @debug + def __init__(self, domain, discretization, mpi_params=None, + cart_dim=None, cart_shape=None, + is_periodic=None, cutdirs=None, + mesh=None, cartesian_topology=None, + cl_env=None, **kwds): + + super(CartesianTopology, self).__init__( + mpi_params = mpi_params, + domain=domain, + discretization=discretization, + cart_dim=cart_dim, cart_size=None, proc_shape=None, + is_periodic=is_periodic, is_distributed=None, + cartesian_topology=id(cartesian_topology), mesh=hash(mesh), + topology_state=None, cl_env=cl_env, + **kwds) + @debug def __new__(cls, domain, discretization, mpi_params=None, cart_dim=None, cart_shape=None, @@ -596,14 +617,17 @@ class CartesianTopology(CartesianTopologyView, Topology): check_instance(mpi_params, MPIParams) check_instance(domain, Box) check_instance(discretization, CartesianDiscretization) - check_instance(cart_dim, int) - check_instance(cart_size, int) + check_instance(cart_dim, (int,np.integer)) + check_instance(cart_size, (int,np.integer)) check_instance(proc_shape, np.ndarray, dtype=HYSOP_INTEGER) check_instance(is_periodic, np.ndarray, dtype=bool) check_instance(is_distributed, np.ndarray, dtype=bool) check_instance(cartesian_topology, MPI.Cartcomm, allow_none=True) check_instance(mesh, CartesianMesh, allow_none=True) + cart_dim = int(cart_dim) + cart_size = int(cart_size) + npw.set_readonly(proc_shape, is_periodic, is_distributed) topology_state = CartesianTopologyState(dim=domain.dim) diff --git a/hysop/topology/topology.py b/hysop/topology/topology.py index faeb44dd2..e6f459c75 100644 --- a/hysop/topology/topology.py +++ b/hysop/topology/topology.py @@ -106,6 +106,10 @@ class TopologyView(TaggedObjectView, metaclass=ABCMeta): __slots__ = ('_mesh_view', '_domain_view', '_topology', '_topology_state') + @debug + def __init__(self, topology_state, topology=None, **kwds): + super(TopologyView, self).__init__(obj_view=topology, **kwds) + @debug def __new__(cls, topology_state, topology=None, **kwds): r""" -- GitLab