From c0e8499ee0872a1beab47fa739b46c055fe8854b Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Keck <Jean-Baptiste.Keck@imag.fr> Date: Fri, 30 Oct 2020 16:43:18 +0100 Subject: [PATCH] remove hysop++ and long --- .gitlab-ci.yml | 28 +- ci/docker_images/ubuntu/groovy/Dockerfile | 64 +- cmake/FindPythonFull.cmake | 2 +- .../flow_around_sphere/flow_around_sphere.py | 286 ------- hysop/backend/device/autotunable_kernel.py | 4 +- hysop/backend/device/codegen/base/codegen.py | 2 +- .../backend/device/codegen/base/variables.py | 4 +- .../functions/custom_symbolic_function.py | 2 +- hysop/backend/device/kernel_statistics.py | 8 +- .../backend/device/opencl/opencl_allocator.py | 4 +- hysop/backend/device/opencl/opencl_device.py | 168 ++-- hysop/backend/device/opencl/opencl_types.py | 6 +- hysop/backend/host/host_mempool.py | 7 +- hysop/core/arrays/array.py | 4 - hysop/core/arrays/array_backend.py | 2 +- hysop/core/memory/memory_request.py | 6 +- hysop/core/memory/mempool.py | 6 +- hysop/domain/box.py | 68 +- hysop/domain/domain.py | 2 +- hysop/fields/cartesian_discrete_field.py | 4 +- hysop/fields/ghost_exchangers.py | 2 +- hysop/mesh/cartesian_mesh.py | 4 +- hysop/numerics/stencil/stencil_generator.py | 6 +- hysop/operator/adapt_timestep.py | 2 +- .../operator/base/custom_symbolic_operator.py | 12 +- hysop/operator/base/spectral_operator.py | 6 +- hysop/operator/base/transpose_operator.py | 2 +- hysop/operator/directional/diffusion_dir.py | 64 +- hysop/operator/directional/directional.py | 4 +- hysop/operator/spatial_filtering.py | 26 +- hysop/operator/transpose.py | 4 +- hysop/parameters/scalar_parameter.py | 13 +- hysop/parameters/tensor_parameter.py | 4 +- hysop/symbolic/array.py | 4 +- hysop/tools/debug_dumper.py | 2 +- hysop/tools/enum.py | 4 +- hysop/tools/handle.py | 11 +- hysop/tools/io_utils.py | 10 +- hysop/tools/numba_utils.py | 3 +- hysop/tools/numerics.py | 4 +- hysop/tools/numpywrappers.py | 2 +- hysop/tools/spectral_utils.py | 2 +- hysop/tools/sympy_utils.py | 6 +- hysop/tools/types.py | 2 +- hysop/tools/units.py | 6 +- hysop_examples/example_utils.py | 7 +- .../examples/taylor_green/taylor_green.py | 12 +- requirements.txt | 4 +- src/hysop++/main/diffSolver.cpp | 237 ------ src/hysop++/main/planner.cpp | 197 ----- src/hysop++/main/poissonSolver.cpp | 213 ----- src/hysop++/src/data/accumulatorIndex.h | 65 -- src/hysop++/src/data/index.h | 125 --- src/hysop++/src/data/memory/fftwAllocator.h | 53 -- .../src/data/memory/minimalAllocator.h | 52 -- src/hysop++/src/data/multi_array/< | 352 --------- .../data/multi_array/const_multi_array_ref.h | 53 -- .../data/multi_array/const_multi_array_view.h | 53 -- .../src/data/multi_array/multi_array.h | 52 -- .../src/data/multi_array/multi_array_clean.h | 47 -- .../data/multi_array/multi_array_defines.h | 366 --------- .../src/data/multi_array/multi_array_ext.h | 247 ------ .../src/data/multi_array/multi_array_impl.h | 192 ----- .../src/data/multi_array/multi_array_ref.h | 70 -- .../src/data/multi_array/multi_array_view.h | 72 -- src/hysop++/src/detail/index_seq.h | 42 - src/hysop++/src/domain/boundary.cpp | 26 - src/hysop++/src/domain/boundary.h | 23 - src/hysop++/src/domain/domain.h | 154 ---- src/hysop++/src/domain/domainConfiguration.h | 100 --- src/hysop++/src/fft/extension.cpp | 24 - src/hysop++/src/fft/extension.h | 23 - src/hysop++/src/fft/fftDomainConfiguration.h | 114 --- src/hysop++/src/fft/fftw3.cpp | 40 - src/hysop++/src/fft/fftw3.h | 534 ------------- src/hysop++/src/fft/fftwComplex.h | 87 -- src/hysop++/src/fft/planner.h | 747 ------------------ src/hysop++/src/fft/transform.cpp | 14 - src/hysop++/src/fft/transform.h | 188 ----- src/hysop++/src/maths/polynomial.h | 428 ---------- src/hysop++/src/maths/quad_maths.h | 299 ------- src/hysop++/src/solver/diffSolver.h | 29 - src/hysop++/src/solver/fftDiffSolver.h | 191 ----- src/hysop++/src/solver/fftPoissonSolver.h | 206 ----- src/hysop++/src/solver/poissonSolver.h | 27 - src/hysop++/src/utils/constants.h | 22 - src/hysop++/src/utils/default.h | 20 - src/hysop++/src/utils/defines.h | 46 -- src/hysop++/src/utils/types.h | 63 -- src/hysop++/src/utils/utils.cpp | 17 - src/hysop++/src/utils/utils.h | 197 ----- src/hysop++/tests/CMakeLists.txt | 7 - .../tests/testDiffSolver/CMakeLists.txt | 14 - src/hysop++/tests/testDiffSolver/main.cpp | 10 - .../tests/testDiffSolver/testDiffSolver.cpp | 243 ------ .../tests/testDiffSolver/testDiffSolver.h | 14 - src/hysop++/tests/testPlanner/CMakeLists.txt | 14 - src/hysop++/tests/testPlanner/main.cpp | 10 - src/hysop++/tests/testPlanner/testPlanner.cpp | 200 ----- src/hysop++/tests/testPlanner/testPlanner.h | 20 - .../tests/testPoissonSolver/CMakeLists.txt | 14 - src/hysop++/tests/testPoissonSolver/main.cpp | 10 - .../testPoissonSolver/testPoissonSolver.cpp | 208 ----- .../testPoissonSolver/testPoissonSolver.h | 14 - src/hysop++/tests/testPolynoms/CMakeLists.txt | 14 - src/hysop++/tests/testPolynoms/main.cpp | 10 - .../tests/testPolynoms/testPolynoms.cpp | 115 --- src/hysop++/tests/testPolynoms/testPolynoms.h | 13 - 108 files changed, 311 insertions(+), 7631 deletions(-) delete mode 100644 examples/flow_around_sphere/flow_around_sphere.py delete mode 100644 src/hysop++/main/diffSolver.cpp delete mode 100644 src/hysop++/main/planner.cpp delete mode 100644 src/hysop++/main/poissonSolver.cpp delete mode 100644 src/hysop++/src/data/accumulatorIndex.h delete mode 100644 src/hysop++/src/data/index.h delete mode 100644 src/hysop++/src/data/memory/fftwAllocator.h delete mode 100644 src/hysop++/src/data/memory/minimalAllocator.h delete mode 100644 src/hysop++/src/data/multi_array/< delete mode 100644 src/hysop++/src/data/multi_array/const_multi_array_ref.h delete mode 100644 src/hysop++/src/data/multi_array/const_multi_array_view.h delete mode 100644 src/hysop++/src/data/multi_array/multi_array.h delete mode 100644 src/hysop++/src/data/multi_array/multi_array_clean.h delete mode 100644 src/hysop++/src/data/multi_array/multi_array_defines.h delete mode 100644 src/hysop++/src/data/multi_array/multi_array_ext.h delete mode 100644 src/hysop++/src/data/multi_array/multi_array_impl.h delete mode 100644 src/hysop++/src/data/multi_array/multi_array_ref.h delete mode 100644 src/hysop++/src/data/multi_array/multi_array_view.h delete mode 100644 src/hysop++/src/detail/index_seq.h delete mode 100644 src/hysop++/src/domain/boundary.cpp delete mode 100644 src/hysop++/src/domain/boundary.h delete mode 100644 src/hysop++/src/domain/domain.h delete mode 100644 src/hysop++/src/domain/domainConfiguration.h delete mode 100644 src/hysop++/src/fft/extension.cpp delete mode 100644 src/hysop++/src/fft/extension.h delete mode 100644 src/hysop++/src/fft/fftDomainConfiguration.h delete mode 100644 src/hysop++/src/fft/fftw3.cpp delete mode 100644 src/hysop++/src/fft/fftw3.h delete mode 100644 src/hysop++/src/fft/fftwComplex.h delete mode 100644 src/hysop++/src/fft/planner.h delete mode 100644 src/hysop++/src/fft/transform.cpp delete mode 100644 src/hysop++/src/fft/transform.h delete mode 100644 src/hysop++/src/maths/polynomial.h delete mode 100644 src/hysop++/src/maths/quad_maths.h delete mode 100644 src/hysop++/src/solver/diffSolver.h delete mode 100644 src/hysop++/src/solver/fftDiffSolver.h delete mode 100644 src/hysop++/src/solver/fftPoissonSolver.h delete mode 100644 src/hysop++/src/solver/poissonSolver.h delete mode 100644 src/hysop++/src/utils/constants.h delete mode 100644 src/hysop++/src/utils/default.h delete mode 100644 src/hysop++/src/utils/defines.h delete mode 100644 src/hysop++/src/utils/types.h delete mode 100644 src/hysop++/src/utils/utils.cpp delete mode 100644 src/hysop++/src/utils/utils.h delete mode 100644 src/hysop++/tests/CMakeLists.txt delete mode 100644 src/hysop++/tests/testDiffSolver/CMakeLists.txt delete mode 100644 src/hysop++/tests/testDiffSolver/main.cpp delete mode 100644 src/hysop++/tests/testDiffSolver/testDiffSolver.cpp delete mode 100644 src/hysop++/tests/testDiffSolver/testDiffSolver.h delete mode 100644 src/hysop++/tests/testPlanner/CMakeLists.txt delete mode 100644 src/hysop++/tests/testPlanner/main.cpp delete mode 100644 src/hysop++/tests/testPlanner/testPlanner.cpp delete mode 100644 src/hysop++/tests/testPlanner/testPlanner.h delete mode 100644 src/hysop++/tests/testPoissonSolver/CMakeLists.txt delete mode 100644 src/hysop++/tests/testPoissonSolver/main.cpp delete mode 100644 src/hysop++/tests/testPoissonSolver/testPoissonSolver.cpp delete mode 100644 src/hysop++/tests/testPoissonSolver/testPoissonSolver.h delete mode 100644 src/hysop++/tests/testPolynoms/CMakeLists.txt delete mode 100644 src/hysop++/tests/testPolynoms/main.cpp delete mode 100644 src/hysop++/tests/testPolynoms/testPolynoms.cpp delete mode 100644 src/hysop++/tests/testPolynoms/testPolynoms.h diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ca4908181..cfa18e65b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,54 +7,54 @@ stages: - install - test -env:focal: - image: keckj/hysop:focal +env:groovy: + image: keckj/hysop:groovy stage: env script: - "bash ci/scripts/version.sh" -config:focal: - image: keckj/hysop:focal +config:groovy: + image: keckj/hysop:groovy stage: configure script: - "bash ci/scripts/config.sh $CI_PROJECT_DIR/build/gcc $CI_PROJECT_DIR/install/gcc gcc g++ gfortran" - "bash ci/scripts/config.sh $CI_PROJECT_DIR/build/clang-8 $CI_PROJECT_DIR/install/clang-8 clang-8 clang++-8 gfortran" dependencies: - - env:focal + - env:groovy artifacts: paths: - $CI_PROJECT_DIR/build -build:focal: - image: keckj/hysop:focal +build:groovy: + image: keckj/hysop:groovy stage: build script: - "bash ci/scripts/build.sh $CI_PROJECT_DIR/build/gcc gcc g++ gfortran" - "bash ci/scripts/build.sh $CI_PROJECT_DIR/build/clang-8 clang-8 clang++-8 gfortran" dependencies: - - config:focal + - config:groovy artifacts: paths: - $CI_PROJECT_DIR/build -install:focal: - image: keckj/hysop:focal +install:groovy: + image: keckj/hysop:groovy stage: install script: - "bash ci/scripts/install.sh $CI_PROJECT_DIR/build/gcc $CI_PROJECT_DIR/install/gcc" dependencies: - - build:focal + - build:groovy artifacts: paths: - $CI_PROJECT_DIR/install -test:focal: - image: keckj/hysop:focal +test:groovy: + image: keckj/hysop:groovy stage: test script: - "bash ci/scripts/test.sh $CI_PROJECT_DIR/install/gcc $CI_PROJECT_DIR/hysop $CI_PROJECT_DIR/cache" dependencies: - - install:focal + - install:groovy cache: paths: - $CI_PROJECT_DIR/cache diff --git a/ci/docker_images/ubuntu/groovy/Dockerfile b/ci/docker_images/ubuntu/groovy/Dockerfile index 8d23b561a..44bd82a94 100644 --- a/ci/docker_images/ubuntu/groovy/Dockerfile +++ b/ci/docker_images/ubuntu/groovy/Dockerfile @@ -8,11 +8,10 @@ ENV MAKEFLAGS "-j${NTHREADS}" # upgrade initial image ENV DEBIAN_FRONTEND noninteractive -RUN apt-get update -RUN apt-get full-upgrade -y +RUN apt-get update && apt-get full-upgrade -y # get build tools and required libraries -RUN apt-get install -y --no-install-recommends expat unzip xz-utils automake libtool pkg-config cmake rsync git vim ssh curl wget ca-certificates gcc g++ gfortran lsb-core cpio libnuma1 libpciaccess0 libreadline-dev libblas-dev liblapack-dev libgcc-9-dev libgfortran-9-dev libgmp-dev libmpfr-dev libmpc-dev python3.8-dev opencl-headers swig libgmp-dev libmpfr-dev libmpc-dev libcairo-dev libcairomm-1.0-dev python3.8-tk +RUN apt-get update && apt-get install -y --no-install-recommends expat unzip xz-utils automake libtool pkg-config cmake rsync git vim ssh curl wget ca-certificates gcc g++ gfortran lsb-core cpio libnuma1 libpciaccess0 libreadline-dev libblas-dev liblapack-dev libgcc-10-dev libgfortran-10-dev libgmp-dev libmpfr-dev libmpc-dev python3.8-dev opencl-headers swig libgmp-dev libmpfr-dev libmpc-dev libcairo-dev libcairomm-1.0-dev python3.8-tk # python packages using pip3.8 RUN cd /tmp && \ @@ -30,7 +29,7 @@ RUN cd /tmp && \ rm -f openmpi-*.tar.gz && \ cd openmpi-* && \ ./configure --enable-shared --disable-static --with-threads=posix --enable-ipv6 --prefix="${MPI_ROOT}" --with-hwloc=internal --with-libevent=internal --enable-mpi1-compatibility && \ - make -j$(nproc) && \ + make && \ make install && \ rm -rf /tmp/openmpi-* @@ -44,7 +43,7 @@ RUN cd /tmp && \ rm -rf hdf5-*.tar.gz && \ cd hdf5-* && \ CC="${MPICC}" ./configure --prefix="${MPI_ROOT}" --enable-parallel --enable-shared=yes --enable-static=no && \ - make -j$(nproc) && \ + make && \ make install && \ 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 @@ -54,8 +53,9 @@ 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 -# other python packages -RUN pip3.8 install --upgrade scipy sympy matplotlib gmpy2 psutil py-cpuinfo Mako subprocess32 editdistance portalocker colors.py tee primefac pycairo argparse_color_formatter networkx pyvis zarr numcodecs jsonpickle memory-tempfile +# 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 +RUN pip3.8 install git+git://github.com/keckj/primefac-fork@master # patchelf RUN cd /tmp && \ @@ -119,8 +119,8 @@ RUN cd /tmp && \ RUN cd /tmp && \ git clone https://github.com/inducer/pyopencl && \ cd pyopencl && \ + git checkout v2020.2.2 && \ git submodule update --init && \ - git checkout v2020.1 && \ python3.8 configure.py && \ make && \ pip3.8 install --upgrade . && \ @@ -176,46 +176,47 @@ RUN cd /tmp && \ rm -Rf /tmp/hptt # python flint (FLINT2 + ARB + python-flint) -RUN cd /tmp \ - && wget https://github.com/wbhart/flint2/archive/v2.6.1.tar.gz \ - && tar -xvzf v2.6.1.tar.gz \ - && cd flint2-2.6.1 \ - && ./configure \ - && make -j$(nproc) \ - && make install \ - && cd - \ - && rm -rf flint2-2.6.1 -RUN cd /tmp \ - && wget https://github.com/fredrik-johansson/arb/archive/2.18.1.tar.gz \ - && tar -xvzf 2.18.1.tar.gz \ - && cd arb-2.18.1 \ - && ./configure \ - && make -j$(nproc) \ - && make install \ - && cd - \ - && rm -rf arb-2.18.1 +RUN cd /tmp && \ + wget https://github.com/wbhart/flint2/archive/v2.6.3.tar.gz && \ + tar -xvzf v*.tar.gz && \ + rm -f v*.tar.gz && \ + cd flint2-* && \ + ./configure && \ + make && \ + make install && \ + cd - && \ + rm -rf flint2-* +RUN cd /tmp && \ + wget https://github.com/fredrik-johansson/arb/archive/2.18.1.tar.gz && \ + tar -xvzf *.tar.gz && \ + rm -f *.tar.gz && \ + cd arb-* && \ + ./configure && \ + make && \ + make install && \ + cd - && \ + rm -rf arb-* RUN pip3.8 install --upgrade python-flint # static fftw + pyfftw (with R2R transforms) # Weird pyfftw bug : not passing -O2 explicitely during build causes a segfault on import... # See https://bugs.gentoo.org/548776 ENV FFTW_ROOT="/usr/local" -ADD ci/patch/pyfftw.patch /tmp/pyfftw.patch RUN cd /tmp && \ wget http://www.fftw.org/fftw-3.3.8.tar.gz && \ tar -xvzf fftw-*.tar.gz && \ rm -f fftw-*.tar.gz && \ cd fftw-* && \ ./configure --enable-openmp --enable-threads --enable-mpi --enable-static --with-pic --prefix="${FFTW_ROOT}" --enable-single && \ - make -j$(nproc) && \ + make && \ make install && \ make clean && \ ./configure --enable-openmp --enable-threads --enable-mpi --enable-static --with-pic --prefix="${FFTW_ROOT}" && \ - make -j8 && \ + make && \ make install && \ make clean && \ ./configure --enable-openmp --enable-threads --enable-mpi --enable-static --with-pic --prefix="${FFTW_ROOT}" --enable-long-double && \ - make -j8 && \ + make && \ make install && \ rm -rf /tmp/fftw-* @@ -232,9 +233,6 @@ RUN cd /tmp && \ pip3.8 install --upgrade . && \ rm -rf /tmp/pyFFTW -RUN pip3.8 uninstall --yes primefac && \ - pip3.8 install git+git://github.com/elliptic-shiho/primefac-fork@master - # ensure all libraries are known by the runtime linker RUN ldconfig diff --git a/cmake/FindPythonFull.cmake b/cmake/FindPythonFull.cmake index aabb1a719..ea4146b9c 100644 --- a/cmake/FindPythonFull.cmake +++ b/cmake/FindPythonFull.cmake @@ -32,7 +32,7 @@ if(EXISTS "${PYTHON_INCLUDE_DIRS}" AND EXISTS "${PYTHON_LIBRARY}" AND EXISTS "${ else() set(PYTHON_FOUND FALSE) # --- Find python interpreter - set(Python_ADDITIONAL_VERSIONS 2.7) + set(Python_ADDITIONAL_VERSIONS 3.9 3.8) find_package(PythonInterp) # --- Use distutils to explore python configuration corresponding to diff --git a/examples/flow_around_sphere/flow_around_sphere.py b/examples/flow_around_sphere/flow_around_sphere.py deleted file mode 100644 index 005fc8843..000000000 --- a/examples/flow_around_sphere/flow_around_sphere.py +++ /dev/null @@ -1,286 +0,0 @@ -import os -import numpy as np - -from hysop import Box, Simulation, Problem, MPIParams, Field -from hysop.defaults import VelocityField, VorticityField, \ - EnstrophyParameter, TimeParameters -from hysop.parameters.tensor_parameter import TensorParameter -from hysop.constants import Implementation, AdvectionCriteria, HYSOP_REAL, \ - StretchingFormulation, StretchingCriteria -from hysop.operators import Advection, StaticDirectionalStretching, Diffusion, \ - PoissonCurl, AdaptiveTimeStep, \ - Enstrophy, MinMaxFieldStatistics, StrangSplitting, \ - ParameterPlotter, PenalizeVorticity, FlowRateCorrection, \ - VorticityAbsorption, CustomOperator -from hysop.numerics.odesolvers.runge_kutta import RK2 -from hysop.methods import SpaceDiscretization, Remesh, TimeIntegrator, \ - ComputeGranularity, Interpolation, StrangOrder -from hysop.topology.cartesian_topology import CartesianTopology -from hysop.tools.parameters import CartesianDiscretization - - -pi = np.pi -cos = np.cos -sin = np.sin - - -# Define the domain -dim = 3 -npts = (32,32,64) -box = Box(dim=dim, - origin=[-2.56, -2.56, -2.56], - length=[5.12, 5.12, 10.24]) -cfl = 0.5 -lcfl = 0.125 -uinf = 1.0 -viscosity = 1. / 250. -outfreq = 10 -dt0 = 0.0125 - -# Get default MPI Parameters from domain (even for serial jobs) -mpi_params = MPIParams(comm=box.task_comm, - task_id=box.current_task()) - -# Setup usual implementation specific variables -impl = None -extra_op_kwds = {'mpi_params': mpi_params} - - -# ====== Sphere inside the domain ====== -RADIUS = 0.5 -pos = [0., 0., 0.] -def computeSphere(data, coords): - (x, y, z) = coords[0] - dx = x[0,0,1] - x[0,0,0] - dy = y[0,1,0] - y[0,0,0] - dz = z[1,0,0] - z[0,0,0] - data[0][...] = 0. - chi = lambda x,y,z: np.sqrt((x-pos[0])*(x-pos[0])+(y-pos[1])*(y-pos[1])+(z-pos[2])*(z-pos[2]))<=RADIUS - data[0][chi(x,y,z)] = 1. - - # Smooth the sphere surface with a Volume-of-fluid fraction - vof = 5 # number of points in the subgrid - front_z = np.where(np.abs(data[0][0:-1,:,:]-data[0][1:,:,:])>0.1) - front_z = (np.concatenate((front_z[0],front_z[0]+1)), - np.concatenate((front_z[1],front_z[1])), - np.concatenate((front_z[2],front_z[2]))) - front_y = np.where(np.abs(data[0][:,0:-1,:]-data[0][:,1:,:])>0.1) - front_y = (np.concatenate((front_y[0],front_y[0])), - np.concatenate((front_y[1],front_y[1]+1)), - np.concatenate((front_y[2],front_y[2]))) - front = (np.concatenate((front_z[0],front_y[0])), - np.concatenate((front_z[1],front_y[1])), - np.concatenate((front_z[2],front_y[2]))) - front_x = np.where(np.abs(data[0][:,:,0:-1]-data[0][:,:,1:])>0.1) - front_x = (np.concatenate((front_x[0],front_x[0])), - np.concatenate((front_x[1],front_x[1])), - np.concatenate((front_x[2],front_x[2]+1))) - front = (np.concatenate((front[0],front_x[0])), - np.concatenate((front[1],front_x[1])), - np.concatenate((front[2],front_x[2]))) - - for k,j,i in zip(*front): - sx = np.linspace(x[0,0,i]-dx/2,x[0,0,i]+dx/2,vof)[np.newaxis,np.newaxis,:] - sy = np.linspace(y[0,j,0]-dy/2,y[0,j,0]+dy/2,vof)[np.newaxis,:,np.newaxis] - sz = np.linspace(z[k,0,0]-dz/2,z[k,0,0]+dz/2,vof)[:,np.newaxis,np.newaxis] - data[0][k,j,i] = 1.*(np.sum(chi(sx, sy, sz))/(1.0*vof**3)) - - return data - - -# ======= Function to compute initial velocity ======= -def computeVel(data, coords): - data[0][...] = uinf - data[1][...] = 0. - data[2][...] = 0. - return data - - -# ======= Function to compute initial vorticity ======= -def computeVort(data, coords): - data[0][...] = 0. - data[1][...] = 0. - data[2][...] = 0. - return data - - - -method = {} - -# Define parameters and field (time, timestep, velocity, vorticity, enstrophy) -t, dt = TimeParameters(dtype=HYSOP_REAL) -velo = VelocityField(domain=box, dtype=HYSOP_REAL) -vorti = VorticityField(velocity=velo, dtype=HYSOP_REAL) -sphere = Field(domain=box, name="Sphere", is_vector=False, dtype=HYSOP_REAL) -wdotw = Field(domain=box, dtype=HYSOP_REAL, is_vector=False, name="WdotW") -enstrophy = EnstrophyParameter(dtype=HYSOP_REAL) -flowrate = TensorParameter(name="flowrate", dtype=HYSOP_REAL, shape=(3, ), - initial_value=[0., 0., uinf * box.length[1] * box.length[0]]) - - -# Topologies -topo_nogh = CartesianTopology(domain=box, - discretization=CartesianDiscretization(npts, - default_boundaries=True), - mpi_params=mpi_params, - cutdirs=[False, False, True]) -topo_gh = CartesianTopology(domain=box, - discretization=CartesianDiscretization(npts, - ghosts=(4, 4, 4), default_boundaries=True), - mpi_params=mpi_params, - cutdirs=[False, False, True]) - - -### Build the directional operators -#> Directional advection -advec = Advection( - implementation=Implementation.FORTRAN, - name='advec', - velocity=velo, - advected_fields=(vorti,), - variables={velo: topo_nogh, vorti: topo_nogh}, - dt=dt, **extra_op_kwds) -#> Directional stretching + diffusion -stretch = StaticDirectionalStretching( - implementation=Implementation.PYTHON, - name='stretch', - formulation=StretchingFormulation.CONSERVATIVE, - velocity=velo, - vorticity=vorti, - variables={velo: topo_gh, vorti: topo_gh}, - dt=dt, **extra_op_kwds) -#> Directional splitting operator subgraph -splitting = StrangSplitting(splitting_dim=dim, - order=StrangOrder.STRANG_FIRST_ORDER) -splitting.push_operators(stretch) -#> Penalization -penal = PenalizeVorticity( - implementation=Implementation.PYTHON, - name='penalization', - velocity=velo, vorticity=vorti, - variables={velo: topo_gh, vorti: topo_gh, sphere: topo_gh}, - obstacles=[sphere, ], coeff=1e8, - dt=dt, **extra_op_kwds) -#> Diffusion operator -diffuse = Diffusion( - implementation=Implementation.FORTRAN, - name='diffuse', - nu=viscosity, - Fin=vorti, - variables={vorti: topo_nogh}, - dt=dt, **extra_op_kwds) -#> Vorticity absorption -absorption = VorticityAbsorption( - implementation=Implementation.PYTHON, - velocity=velo, vorticity=vorti, - start_coord=6.68, - flowrate=flowrate, - name="absorption", - variables={velo: topo_nogh, vorti: topo_nogh}, - dt=dt, **extra_op_kwds) -#> Poisson operator to recover the velocity from the vorticity -poisson = PoissonCurl( - implementation=Implementation.FORTRAN, - name='poisson', - velocity=velo, - vorticity=vorti, - variables={velo: topo_nogh, vorti: topo_nogh}, - projection=None, - **extra_op_kwds) -#> Flowrate correction operator to adjust velocity with prescribed flowrate -def computeFlowrate(t, flowrate): - fr = np.zeros(3) - fr[0] = uinf * box.length[1] * box.length[0] - Tstart=3.0 - if t() >= Tstart and t() <= Tstart + 1.0: - fr[1] = sin(pi * (t() - Tstart)) * \ - box.length[1] * box.length[0] - flowrate.value = fr -computeFlowrate = CustomOperator(func=computeFlowrate, - invars=(t, ), - outvars=(flowrate, )) -correctFlowrate = FlowRateCorrection( - implementation=Implementation.PYTHON, - name="flowrate_correction", - velocity=velo, vorticity=vorti, - flowrate=flowrate, - dt=dt, - variables={velo: topo_nogh, vorti: topo_nogh}, - **extra_op_kwds) - -#> outputs -#penal.dump_inputs(fields=(sphere, ), frequency=outfrea) -correctFlowrate.dump_inputs(fields=(vorti, ), frequency=outfreq) -correctFlowrate.dump_outputs(fields=(velo,), frequency=outfreq) - -#> Operator to compute the infinite norm of the velocity -min_max_U = MinMaxFieldStatistics(name='min_max_U', field=velo, - Finf=True, implementation=Implementation.PYTHON, variables={velo:npts}, - **extra_op_kwds) -#> Operator to compute the infinite norm of the vorticity -min_max_W = MinMaxFieldStatistics(name='min_max_W', field=vorti, - Finf=True, implementation=Implementation.PYTHON, variables={vorti:npts}, - **extra_op_kwds) -#> Operator to compute the enstrophy -enstrophy_op = Enstrophy( - name='enstrophy', - vorticity=vorti, enstrophy=enstrophy, WdotW=wdotw, - variables={vorti:topo_nogh, wdotw: topo_nogh}, - implementation=Implementation.PYTHON, **extra_op_kwds) - -### Adaptive timestep operator -#TODO:move advection to GRAD_U -#TODO:add stretching criteria, based on a gradient -adapt_dt = AdaptiveTimeStep(dt, equivalent_CFL=True, - start_time=10*dt0) # start adapting timestep at t=10*dt0 -dt_cfl = adapt_dt.push_cfl_criteria(cfl=cfl, - Finf=min_max_U.Finf, - equivalent_CFL=True) -dt_advec = adapt_dt.push_advection_criteria(lcfl=lcfl, - Finf=min_max_W.Finf, - criteria=AdvectionCriteria.W_INF) - #criteria=AdvectionCriteria.GRAD_U) -# dt_advec = adapt_dt.push_stretching_criteria(lcfl=lcfl, -# gradFinf=grad_W.Finf, -# criteria=StretchingCriteria.GRAD_U) - -## Create the problem we want to solve and insert our -# directional splitting subgraph and the standard operators. -# The method dictionnary passed to this graph will be dispatched -# accross all operators contained in the graph. -method.update({SpaceDiscretization: 4, - TimeIntegrator: RK2, - Remesh: Remesh.L4_2, - Interpolation: Interpolation.LINEAR}) -problem = Problem(method=method) -problem.insert( - computeFlowrate, - penal, - splitting, - diffuse, - advec, - absorption, - poisson, - correctFlowrate, - enstrophy_op, min_max_U, min_max_W, - adapt_dt -) -problem.build() - -# # Create a simulation -# # (do not forget to specify the t and dt parameters here) -simu = Simulation(start=0., end=10.0, - dt0=dt0, t=t, dt=dt) -simu.write_parameters(t, dt_cfl, dt_advec, dt, enstrophy, flowrate, - min_max_U.Finf, min_max_W.Finf, adapt_dt.equivalent_CFL, - filename='parameters.txt', precision=8) - -problem.initialize_field(vorti, formula=computeVort) -problem.initialize_field(velo, formula=computeVel) -problem.initialize_field(sphere, formula=computeSphere) - -# Finally solve the problem -problem.solve(simu) - -# Finalize -problem.finalize() diff --git a/hysop/backend/device/autotunable_kernel.py b/hysop/backend/device/autotunable_kernel.py index 0bec40f40..f63236a61 100644 --- a/hysop/backend/device/autotunable_kernel.py +++ b/hysop/backend/device/autotunable_kernel.py @@ -227,8 +227,8 @@ class AutotunableKernel(object, metaclass=ABCMeta): Configure work_bounds (work_dim, work_size, max_work_load). Return a WorkBoundsConfiguration object. """ - check_instance(max_kernel_work_group_size, (int,long)) - check_instance(preferred_work_group_size_multiple, (int, long)) + check_instance(max_kernel_work_group_size, int) + check_instance(preferred_work_group_size_multiple, int) check_instance(extra_parameters, dict, keys=str) check_instance(extra_kwds, dict, keys=str) assert (max_kernel_work_group_size>0), max_kernel_work_group_size diff --git a/hysop/backend/device/codegen/base/codegen.py b/hysop/backend/device/codegen/base/codegen.py index 2cd55caa1..e2c844801 100644 --- a/hysop/backend/device/codegen/base/codegen.py +++ b/hysop/backend/device/codegen/base/codegen.py @@ -557,7 +557,7 @@ class CodeGenerator(object): if (unroll is not None) and (unroll is not False): if unroll is True: header_prefix = '#pragma unroll\n{}'.format(header_prefix) - elif isinstance(unroll, (int,long)): + elif isinstance(unroll, int): header_prefix = '#pragma unroll {}\n{}'.format(unroll, header_prefix) with self._block_(header_prefix=header_prefix,compact=compact) as b: yield b diff --git a/hysop/backend/device/codegen/base/variables.py b/hysop/backend/device/codegen/base/variables.py index d226baf0a..0beac4671 100644 --- a/hysop/backend/device/codegen/base/variables.py +++ b/hysop/backend/device/codegen/base/variables.py @@ -135,7 +135,7 @@ class CodegenVariable(object): is_ptr = ptr ptr_level = int(ptr) else: - check_instance(ptr, (int, long)) + check_instance(ptr, int) is_ptr = True ptr_level = ptr del ptr @@ -851,7 +851,7 @@ class CodegenVectorClBuiltin(CodegenVector): value = [self.svalue[i] for i in key] return '({})({})'.format(ctype, ','.join(value)) return access - elif isinstance(key, (int,long)) : + elif isinstance(key, int) : if key<0: key += dim if key<0 or key>=dim: diff --git a/hysop/backend/device/codegen/symbolic/functions/custom_symbolic_function.py b/hysop/backend/device/codegen/symbolic/functions/custom_symbolic_function.py index 20f969e6d..437ae5fdc 100644 --- a/hysop/backend/device/codegen/symbolic/functions/custom_symbolic_function.py +++ b/hysop/backend/device/codegen/symbolic/functions/custom_symbolic_function.py @@ -178,7 +178,7 @@ class CustomSymbolicFunction(OpenClFunctionCodeGenerator): def parse_expr(self, csc, name, expr, args, reqs): pexpr = None - if isinstance(expr, (int,long,sm.Integer)): + if isinstance(expr, (int,sm.Integer)): pexpr = IntegerConstant('int', expr) elif isinstance(expr, (float, sm.Rational, sm.Float)): pexpr = FloatingPointConstant(csc.typegen.fbtype, expr) diff --git a/hysop/backend/device/kernel_statistics.py b/hysop/backend/device/kernel_statistics.py index b37105488..47072398d 100644 --- a/hysop/backend/device/kernel_statistics.py +++ b/hysop/backend/device/kernel_statistics.py @@ -13,10 +13,10 @@ class KernelStatistics(object): Statistics should be given in nanoseconds. """ super(KernelStatistics, self).__init__(**kwds) - check_instance(min_, (int,long), allow_none=True) - check_instance(max_, (int,long), allow_none=True) - check_instance(total, (int,long), allow_none=True) - check_instance(nruns, (int,long)) + check_instance(min_, int, allow_none=True) + check_instance(max_, int, allow_none=True) + check_instance(total, int, allow_none=True) + check_instance(nruns, int) check_instance(data, (list,tuple), allow_none=True) self._min = min_ self._max = max_ diff --git a/hysop/backend/device/opencl/opencl_allocator.py b/hysop/backend/device/opencl/opencl_allocator.py index e44b2a0f4..ffe325982 100644 --- a/hysop/backend/device/opencl/opencl_allocator.py +++ b/hysop/backend/device/opencl/opencl_allocator.py @@ -70,7 +70,7 @@ class OpenClDeferredAllocator(OpenClAllocator): is_deferred = True def _allocate_impl(self, nbytes): - assert isinstance(nbytes, (long,int)) + assert isinstance(nbytes, int) return OpenClBuffer(context=self.context, mem_flags=self.mem_flags, size=nbytes) @@ -83,7 +83,7 @@ class OpenClImmediateAllocator(OpenClAllocator): _zero = np.array([0, 0, 0, 0], dtype=np.int8) def _allocate_impl(self, nbytes): - assert isinstance(nbytes, (long,int)) + assert isinstance(nbytes, int) buf = OpenClBuffer(context=self.context, mem_flags=self.mem_flags, size=nbytes) try: diff --git a/hysop/backend/device/opencl/opencl_device.py b/hysop/backend/device/opencl/opencl_device.py index cdd329047..aea54a9e8 100644 --- a/hysop/backend/device/opencl/opencl_device.py +++ b/hysop/backend/device/opencl/opencl_device.py @@ -23,7 +23,7 @@ def opencl_version_atleast(major, minor, returned=UnknownDeviceAttribute()): return returned return wrap return decorator - + def cl2hysop_device_type(cl_dev_type): entries = { cl.device_type.ACCELERATOR: DeviceType.ACCELERATOR, @@ -36,7 +36,7 @@ def cl2hysop_device_type(cl_dev_type): entries[cl.device_type.CUSTOM] = DeviceType.CUSTOM if (cl_dev_type not in entries): - msg = 'Unknown opencl device type {}.'.format(cl_dev_type) + msg = 'Unknown opencl device type {}.'.format(cl_dev_type) raise ValueError(msg) return entries[cl_dev_type] @@ -47,7 +47,7 @@ def cl2hysop_mem_type(cl_mem_type): elif cl_mem_type == cl.device_local_mem_type.GLOBAL: return MemoryType.GLOBAL_MEMORY else: - msg = 'Unknown memory type {}.'.format(cl_mem_type) + msg = 'Unknown memory type {}.'.format(cl_mem_type) raise ValueError(msg) def cl2hysop_cache_type(cl_cache_type): @@ -59,7 +59,7 @@ def cl2hysop_cache_type(cl_cache_type): elif cl_cache_type == ct.READ_WRITE_CACHE: return CacheType.READ_WRITE_CACHE else: - msg = 'Unknown cache type {}.'.format(cl_cache_type) + msg = 'Unknown cache type {}.'.format(cl_cache_type) raise ValueError(msg) def cl2hysop_fpconfig(cl_fpconfig): @@ -84,42 +84,42 @@ class OpenClDevice(LogicalDevice): __attrs = ( 'version', 'opencl_c_version', 'spir_versions', 'driver_version', 'il_version', - 'name', 'type', 'vendor', 'vendor_id', - 'extensions', 'built_in_kernels', - 'available', 'compiler_available', 'linker_available', - 'host_unified_memory', 'svm_capabilities', - 'partition_max_sub_devices', 'partition_properties', - 'partition_affinity_domain', 'partition_type', + 'name', 'type', 'vendor', 'vendor_id', + 'extensions', 'built_in_kernels', + 'available', 'compiler_available', 'linker_available', + 'host_unified_memory', 'svm_capabilities', + 'partition_max_sub_devices', 'partition_properties', + 'partition_affinity_domain', 'partition_type', 'pipe_max_active_reservations', 'pipe_max_packet_size', 'max_pipe_args', 'queue_properties', - 'queue_on_device_max_size', 'queue_on_device_preferred_size', + 'queue_on_device_max_size', 'queue_on_device_preferred_size', 'queue_on_host_properties', 'queue_on_device_properties', - 'max_on_device_events', 'max_on_device_queues', - 'max_global_variable_size', 'max_parameter_size', 'max_clock_frequency', - 'sub_group_independent_forward_progress', 'max_num_sub_groups', + 'max_on_device_events', 'max_on_device_queues', + 'max_global_variable_size', 'max_parameter_size', 'max_clock_frequency', + 'sub_group_independent_forward_progress', 'max_num_sub_groups', 'address_bits', 'endian_little', 'error_correction_support', 'execution_capabilities', - 'max_work_item_dimensions', 'max_work_item_sizes', 'max_work_group_size', - 'mem_base_addr_align', 'max_constant_args', 'max_constant_buffer_size', - 'global_mem_size', 'global_mem_cache_size', - 'global_mem_cacheline_size', 'global_mem_cache_type', - 'max_mem_alloc_size', 'local_mem_size', 'local_mem_type', - 'half_fp_config', 'single_fp_config', 'double_fp_config', + 'max_work_item_dimensions', 'max_work_item_sizes', 'max_work_group_size', + 'mem_base_addr_align', 'max_constant_args', 'max_constant_buffer_size', + 'global_mem_size', 'global_mem_cache_size', + 'global_mem_cacheline_size', 'global_mem_cache_type', + 'max_mem_alloc_size', 'local_mem_size', 'local_mem_type', + 'half_fp_config', 'single_fp_config', 'double_fp_config', 'image_support', 'max_samplers', 'image_max_array_size', 'image_max_buffer_size', - 'max_read_image_args', 'max_write_image_args', 'max_read_write_image_args', - 'image2d_max_width', 'image2d_max_height', - 'image3d_max_depth', 'image3d_max_height', 'image3d_max_width', - 'image_max_buffer_size', - 'preferred_platform_atomic_alignment', 'preferred_local_atomic_alignment', - 'preferred_global_atomic_alignment', + 'max_read_image_args', 'max_write_image_args', 'max_read_write_image_args', + 'image2d_max_width', 'image2d_max_height', + 'image3d_max_depth', 'image3d_max_height', 'image3d_max_width', + 'image_max_buffer_size', + 'preferred_platform_atomic_alignment', 'preferred_local_atomic_alignment', + 'preferred_global_atomic_alignment', 'preferred_interop_user_sync', - 'profiling_timer_resolution', 'printf_buffer_size', + 'profiling_timer_resolution', 'printf_buffer_size', 'min_data_type_align_size', - 'native_vector_width_char', 'native_vector_width_short', 'native_vector_width_int', - 'native_vector_width_long', 'native_vector_width_float', 'native_vector_width_double', - 'native_vector_width_half', - 'preferred_vector_width_char', 'preferred_vector_width_short', - 'preferred_vector_width_int', 'preferred_vector_width_long', - 'preferred_vector_width_half', 'preferred_vector_width_float', + 'native_vector_width_char', 'native_vector_width_short', 'native_vector_width_int', + 'native_vector_width_long', 'native_vector_width_float', 'native_vector_width_double', + 'native_vector_width_half', + 'preferred_vector_width_char', 'preferred_vector_width_short', + 'preferred_vector_width_int', 'preferred_vector_width_long', + 'preferred_vector_width_half', 'preferred_vector_width_float', 'preferred_vector_width_double', 'pci_bus_id_nv', 'pci_slot_id_nv', 'attribute_async_engine_count_nv', 'compute_capability_major_nv', 'compute_capability_minor_nv', 'gpu_overlap_nv', @@ -138,10 +138,10 @@ class OpenClDevice(LogicalDevice): ) __all_attrs = __attrs + ('_simd_lane_size', '_usable_local_mem_size', '_real_name') - - def __init__(self, platform, platform_handle, device_id, + + def __init__(self, platform, platform_handle, device_id, device_handle, hardware_topo, **kwds): - + # we do not keep a reference to platform_handle or device_handle as we # need to pickle this object self._cl_version = self._extract_cl_version(device_handle) @@ -164,13 +164,13 @@ class OpenClDevice(LogicalDevice): self._simd_lane_size = cl.characterize.get_simd_group_size(device_handle, np.int32) self._usable_local_mem_size = cl.characterize.usable_local_mem_size(device_handle) self._real_name = device_handle.name - + super(OpenClDevice,self).__init__( - platform=platform, platform_handle=platform_handle, - device_id=device_id, device_handle=device_handle, + platform=platform, platform_handle=platform_handle, + device_id=device_id, device_handle=device_handle, hardware_topo=hardware_topo, **kwds) - + def _determine_performance_and_affinity(self, hardware_topo): # test device bandwidth using clpeak global memory bandwidth statistics @@ -182,7 +182,7 @@ class OpenClDevice(LogicalDevice): device_id=self.device_id, is_cpu=(self.type()==DeviceType.CPU)) self._clpeak_info = info - + def _extract_cl_version(self, device_handle): version = device_handle.version regexp = re.compile('OpenCL ([0-9]+)\.([0-9]+)') @@ -190,7 +190,7 @@ class OpenClDevice(LogicalDevice): assert match, 'Could not match opencl version from \'{}\'.'.format(version) (major, minor) = int(match.group(1)), int(match.group(2)) return (major, minor) - + def _match_physical_devices(self, hardware_topo): if (self.type() == DeviceType.CPU): return hardware_topo.cpu_packages() @@ -206,7 +206,7 @@ class OpenClDevice(LogicalDevice): msg=msg.format(self.name(), device.pci_busid()) vprint(msg) return device - # else we may try to look to pci bus id + # else we may try to look to pci bus id # at this time, this is only available for nvidia and amd via opencl extensions else: pci_bus_id = self.pci_bus_id() @@ -214,7 +214,7 @@ class OpenClDevice(LogicalDevice): if not isinstance(pci_bus_id, str): msg='Could not get opencl pci device bus id.' vprint(msg) - return None + return None elif pci_bus_id not in pci_devices.keys(): msg='Could get opencl pci device bus id ({}), but it did not match ' msg='any in hardware topology.' @@ -249,7 +249,7 @@ bytes2str(self.global_mem_size()), bytes2str(self.max_global_alloc_size()), bytes2str(self.local_mem_size(), decimal=False), 'yes, up to {} subdevices'.format(self.max_subdevices()) if self.has_device_partition_support() \ - else 'no', 'no match', ind=ind, inc=inc) + else 'no', 'no match', ind=ind, inc=inc) msg += '\n'+self.clpeak_info_summary(indent=indent, increment=increment) return msg @@ -295,7 +295,7 @@ bytes2str(self.local_mem_size(), decimal=False), if failed: ss += ['{s}>Error: All clpeak commands failed.'] return '\n'.join(ss).format(s=(ind+inc+inc+' |-')) - + def device_summary(self, indent=0, increment=2): ind=' '*indent inc=' '*increment @@ -306,7 +306,7 @@ bytes2str(self.local_mem_size(), decimal=False), {ind}{inc}{inc}*device type: {} {ind}{inc}{inc}*opencl version: {} {ind}{inc}{inc}*opencl C version: {} - + {ind}{inc}{inc}*address bits: {}bit {ind}{inc}{inc}*little endian: {} {ind}{inc}{inc}*ECC enabled: {} @@ -322,9 +322,9 @@ self.vendor(), self.vendor_id(), self.type(), self.version(), self.opencl_c_version(), self.address_bits(), self.little_endian(), -self.error_correction_support(), +self.error_correction_support(), freq2str(self.max_clock_frequency)(), -self.available(), self.compiler_available(), +self.available(), self.compiler_available(), self.linker_available(), self.has_spir_support(), ind=ind, inc=inc) return msg @@ -385,7 +385,7 @@ ind=ind, inc=inc) def fp_support_summary(self, indent=0, increment=2): ind=' '*indent inc=' '*increment - + def fmt(bits, has_fp, get_fp_flags): if not has_fp: support = '\n{ind}{inc}{inc}*fp{} support: None'.format(bits, inc=inc, ind=ind) @@ -417,7 +417,7 @@ ind=ind, inc=inc) msg=\ ''' {ind}{inc}Vector sizes (preferred{}): -{ind}{inc}{inc}*char: {}{} +{ind}{inc}{inc}*char: {}{} {ind}{inc}{inc}*short: {}{} {ind}{inc}{inc}*int: {}{} {ind}{inc}{inc}*long: {}{} @@ -481,11 +481,11 @@ ind=ind, inc=inc) self.max_image_args(), self.max_write_image_args(), self.max_samplers(), - fmt(self.has_1d_image_support(), self.has_1d_image_write_support(), + fmt(self.has_1d_image_support(), self.has_1d_image_write_support(), self.max_1d_image_size()), - fmt(self.has_2d_image_support(), self.has_2d_image_write_support(), + fmt(self.has_2d_image_support(), self.has_2d_image_write_support(), self.max_2d_image_size()), - fmt(self.has_3d_image_support(), self.has_3d_image_write_support(), + fmt(self.has_3d_image_support(), self.has_3d_image_write_support(), self.max_3d_image_size()), fmt_array(self.has_1d_image_array_support(), self.max_1d_image_array_size()), fmt_array(self.has_2d_image_array_support(), self.max_2d_image_array_size()), @@ -494,7 +494,7 @@ ind=ind, inc=inc) self.has_3d_image_from_buffer_support(), ind=ind, inc=inc) return msg - + def atomics_summary(self, indent=0, increment=2): ind=' '*indent inc=' '*increment @@ -507,29 +507,29 @@ ind=ind, inc=inc) {ind}{inc}{inc}*int64/uint64: {} {ind}{inc}{inc}*float32: {} {ind}{inc}{inc}*float64: {} - + {ind}{inc}{inc}*int32 hardware counters: {} {ind}{inc}{inc}*int64 hardware counters: {} '''.format( - fmt(self.has_global_int32_atomics(), self.has_local_int32_atomics(), + fmt(self.has_global_int32_atomics(), self.has_local_int32_atomics(), self.has_mixed_int32_atomics()), - fmt(self.has_global_int64_atomics(), self.has_local_int64_atomics(), + fmt(self.has_global_int64_atomics(), self.has_local_int64_atomics(), self.has_mixed_int64_atomics()), - fmt(self.has_global_float32_atomics(), self.has_local_float32_atomics(), + fmt(self.has_global_float32_atomics(), self.has_local_float32_atomics(), self.has_mixed_float32_atomics()), - fmt(self.has_global_float64_atomics(), self.has_local_float64_atomics(), + fmt(self.has_global_float64_atomics(), self.has_local_float64_atomics(), self.has_mixed_float64_atomics()), self.has_int32_hardware_atomic_counters(), self.has_int64_hardware_atomic_counters(), ind=ind, inc=inc) return msg - + def misc_summary(self, indent=0, increment=2): ind=' '*indent inc=' '*increment if self.has_printf_support: pbs = self.printf_buffer_size() - pbs = 'up to {}'.format(bytes2str(pbs)) if isinstance(pbs,(int,long)) \ + pbs = 'up to {}'.format(bytes2str(pbs)) if isinstance(pbs,int) \ else 'unknown buffer size' msg=\ ''' @@ -562,7 +562,7 @@ ind=ind, inc=inc) if short: return \ '''{ind}*Device {}:\n{}'''.format( - self.device_id, + self.device_id, self.short_device_summary(indent=indent, increment=increment), ind=ind) else: @@ -572,7 +572,7 @@ ind=ind, inc=inc) {}{}{}{}{}{}{}{}{} '''.format( self.device_id, self.name(), - self.device_summary(indent=indent, increment=increment), + self.device_summary(indent=indent, increment=increment), self.memory_summary(indent=indent, increment=increment), self.kernel_summary(indent=indent, increment=increment), self.fp_support_summary(indent=indent, increment=increment), @@ -605,7 +605,7 @@ ind=ind, inc=inc) if self.has_extension('cl_nv_device_attribute_query'): bus_id = self._pci_bus_id_nv slot_id = self._pci_slot_id_nv - dev_id = (slot_id >> 3) + dev_id = (slot_id >> 3) fn_id = (slot_id & 0x07) bus_id0 = (bus_id >> 8 ) # not sure if usefull bus_id1 = (bus_id & 0xff) @@ -620,7 +620,7 @@ ind=ind, inc=inc) return '{:04x}:{:02x}:{:02x}.{:01x}'.format(bus_id0,bus_id1,dev_id,fn_id) else: return UnknownDeviceAttribute() - + def extensions(self): return [ext.strip() for ext in self._extensions.split(' ') if ext.strip() != ''] @@ -654,7 +654,7 @@ ind=ind, inc=inc) @opencl_version_atleast(1,1) def native_vector_width_half(self): return self._native_vector_width_half - + @opencl_version_atleast(1,2) def built_in_kernels(self): return self._built_in_kernels @@ -732,13 +732,13 @@ ind=ind, inc=inc) def max_threads_per_block(self): return self._max_work_group_size def simd_lane_size(self): - return self._simd_lane_size + return self._simd_lane_size def max_constant_args(self): return self._max_constant_args def max_constant_buffer_size(self): return self._max_constant_buffer_size - + #MEMORY def global_mem_size(self): return self._global_mem_size @@ -752,7 +752,7 @@ ind=ind, inc=inc) return self._max_mem_alloc_size def mem_base_addr_align(self): return self._mem_base_addr_align - + def local_mem_size(self): return self._local_mem_size def local_mem_type(self): @@ -792,7 +792,7 @@ ind=ind, inc=inc) def fp64_config(self): assert self.has_fp64 return cl2hysop_fpconfig(self._double_fp_config) - + #IMAGES def has_image_support(self): return bool(self._image_support) @@ -808,14 +808,14 @@ ind=ind, inc=inc) def max_samplers(self): assert self.has_image_support return self._max_samplers - + def has_1d_image_support(self): return self.has_image_support def has_2d_image_support(self): return self.has_image_support def has_3d_image_support(self): return self.has_image_support - + def has_1d_image_write_support(self): return (self.max_write_image_args>0) def has_2d_image_write_support(self): @@ -830,12 +830,12 @@ ind=ind, inc=inc) @opencl_version_atleast(1,2,False) def has_2d_image_array_support(self): return self.has_image_support - + def image_max_array_size(self): assert self.has_1d_image_array_support or \ self.has_2d_image_array_support return self._image_max_array_size - + def max_1d_image_size(self): assert self.has_1d_image_support return np.asarray([self._image2d_max_width]) @@ -860,10 +860,10 @@ ind=ind, inc=inc) def max_3d_image_size(self): assert self.has_3d_image_support return np.asarray([ - self._image3d_max_depth, + self._image3d_max_depth, self._image3d_max_height, self._image3d_max_width]) - + @opencl_version_atleast(1,2,False) def has_1d_image_from_buffer_support(self): return self.has_image_support() @@ -873,10 +873,10 @@ ind=ind, inc=inc) return self.has_image_support() else: return self.has_extension('cl_khr_image2d_from_buffer') - + def has_3d_image_from_buffer_support(self): return False - + @opencl_version_atleast(2,0,False) def has_2d_image_from_image_support(self): return self.has_image_support @@ -890,7 +890,7 @@ ind=ind, inc=inc) return self._image_pitch_alignment - + #ATOMICS def has_global_int32_atomics(self): if self.opencl_version() == (1,0): @@ -903,7 +903,7 @@ ind=ind, inc=inc) return (self.opencl_version()[0] >= 2) def has_global_float64_atomics(self): return (self.opencl_version()[0] >= 2) - + def has_local_int32_atomics(self): if self.opencl_version() == (1,0): return self.has_extension('cl_khr_local_int32_base_atomics') @@ -915,7 +915,7 @@ ind=ind, inc=inc) return (self.opencl_version()[0] >= 2) def has_local_float64_atomics(self): return (self.opencl_version()[0] >= 2) - + def has_mixed_int32_atomics(self): return False def has_mixed_int64_atomics(self): @@ -1009,7 +1009,7 @@ class OpenClDeviceStatistics(HardwareStatistics): self._global_mem_size += [device._global_mem_size] self._type = device.type() self._clpeak_stats = device._clpeak_info.stats() - + def __iadd__(self, other): if (other is None): return self @@ -1035,6 +1035,6 @@ class OpenClDeviceStatistics(HardwareStatistics): ind = ' '*indent inc = ' '*increment ss = ['{{ind}}{:^4} {:^10} {:^10} {} {}'.format(self._counter, self._type, - bytes2str(np.mean(self._global_mem_size)), + bytes2str(np.mean(self._global_mem_size)), self._clpeak_stats, self._name)] return '\n'.join(s.format(ind=ind, inc=inc) for s in ss) diff --git a/hysop/backend/device/opencl/opencl_types.py b/hysop/backend/device/opencl/opencl_types.py index 203d6e5df..b2575fa94 100644 --- a/hysop/backend/device/opencl/opencl_types.py +++ b/hysop/backend/device/opencl/opencl_types.py @@ -265,7 +265,7 @@ class TypeGen(object): if isinstance(val, (float,np.floating,MPFR,sm.Float)): sval = self.float_to_str(val, self.fbtype) return '({})'.format(sval) - elif isinstance(val, (np.integer,int,long,MPZ,sm.Integer)): + elif isinstance(val, (np.integer,int,MPZ,sm.Integer)): suffix = '' if isinstance(val, np.unsignedinteger): suffix+='u' @@ -318,13 +318,15 @@ class TypeGen(object): if isinstance(val, (float,np.floating,MPFR,sm.Float)): return self.fbtype - elif isinstance(val, (np.integer,int,long,MPZ,sm.Integer)): + elif isinstance(val, (np.integer,int,MPZ,sm.Integer)): if isinstance(val, (np.int64, MPZ)): return 'long' elif isinstance(val, np.uint64): return 'ulong' elif isinstance(val, np.unsignedinteger): return 'uint' + elif isinstance(val, int): + return 'long' else: return 'int' elif isinstance(val, (bool,np.bool_)): diff --git a/hysop/backend/host/host_mempool.py b/hysop/backend/host/host_mempool.py index 44c05fff3..8d3b99114 100644 --- a/hysop/backend/host/host_mempool.py +++ b/hysop/backend/host/host_mempool.py @@ -5,11 +5,14 @@ from hysop.backend.host.host_buffer import HostPooledBuffer from hysop.core.memory.mempool import MemoryPool class HostMemoryPool(MemoryPool, HostAllocator): - + + def __new__(cls, allocator, **kwds): + return super(HostMemoryPool, cls).__new__(cls, allocator=allocator, **kwds) + def __init__(self, allocator, **kwds): check_instance(allocator, HostAllocator) super(HostMemoryPool,self).__init__(allocator=allocator, **kwds) def _wrap_buffer(self, buf, alloc_sz, size, alignment): - return HostPooledBuffer(pool=self, buf=buf, alloc_sz=alloc_sz, + return HostPooledBuffer(pool=self, buf=buf, alloc_sz=alloc_sz, size=size, alignment=alignment) diff --git a/hysop/core/arrays/array.py b/hysop/core/arrays/array.py index a837463bd..f0e333b46 100644 --- a/hysop/core/arrays/array.py +++ b/hysop/core/arrays/array.py @@ -90,10 +90,6 @@ class Array(object, metaclass=ABCMeta): """Return scalar value as an int.""" assert self.size==1 return int(self.get()) - def __long__(self): - """Return scalar value as a long.""" - assert self.size==1 - return long(self.get()) def __float__(self): assert self.size==1 """Return scalar value as a float.""" diff --git a/hysop/core/arrays/array_backend.py b/hysop/core/arrays/array_backend.py index fa1009d3b..075eed4bd 100644 --- a/hysop/core/arrays/array_backend.py +++ b/hysop/core/arrays/array_backend.py @@ -273,7 +273,7 @@ class ArrayBackend(TaggedObject, metaclass=ABCMeta): else: name = val if hasattr(val,'__class__') and \ - val.__class__ in [type,int,long,float,np.dtype,list,tuple,set]: + val.__class__ in [type,int,float,np.dtype,list,tuple,set]: name += ' = {}'.format(val) return name diff --git a/hysop/core/memory/memory_request.py b/hysop/core/memory/memory_request.py index e14a85c3d..9b80a06a9 100644 --- a/hysop/core/memory/memory_request.py +++ b/hysop/core/memory/memory_request.py @@ -33,9 +33,9 @@ class MemoryRequest(object): dtype = HYSOP_BOOL check_instance(backend, ArrayBackend) - check_instance(size, (int,long,np.integer), allow_none=True) - check_instance(alignment, (int,long,np.integer), allow_none=True) - check_instance(nb_components, (int,long,np.integer), allow_none=True) + check_instance(size, (int,np.integer), allow_none=True) + check_instance(alignment, (int,np.integer), allow_none=True) + check_instance(nb_components, (int,np.integer), allow_none=True) check_instance(shape, (tuple,list,np.ndarray), allow_none=True) if (dtype is None): diff --git a/hysop/core/memory/mempool.py b/hysop/core/memory/mempool.py index 8521b5896..2401a77c4 100644 --- a/hysop/core/memory/mempool.py +++ b/hysop/core/memory/mempool.py @@ -29,6 +29,10 @@ class MemoryPool(object, metaclass=ABCMeta): pyopencl/pycuda like memory pool extended to be compatible for all backends. """ + def __new__(cls, name, allocator, max_alloc_bytes=None, + mantissa_bits=4, verbose=None, **kwds): + return super(MemoryPool, cls).__new__(cls, **kwds) + def __init__(self, name, allocator, max_alloc_bytes=None, mantissa_bits=4, verbose=None, **kwds): """ @@ -78,7 +82,7 @@ class MemoryPool(object, metaclass=ABCMeta): check_instance(name, str) check_instance(mantissa_bits, int) - check_instance(max_alloc_bytes,(int,long), allow_none=True) + check_instance(max_alloc_bytes, int, allow_none=True) check_instance(verbose, bool) self.name = name.strip() diff --git a/hysop/domain/box.py b/hysop/domain/box.py index c68787201..483ba93bf 100644 --- a/hysop/domain/box.py +++ b/hysop/domain/box.py @@ -10,16 +10,16 @@ from hysop.tools.types import check_instance, first_not_None, to_tuple from hysop.tools.warning import HysopWarning class BoxView(DomainView): - + __slots__ = ('_domain', '_topology_state') - + @debug def __new__(cls, topology_state, domain=None, **kwds): """Create and initialize a BoxView.""" from hysop.topology.cartesian_topology import CartesianTopologyState check_instance(topology_state, CartesianTopologyState) check_instance(domain, Box, allow_none=True) - obj = super(BoxView, cls).__new__(cls, topology_state=topology_state, + obj = super(BoxView, cls).__new__(cls, topology_state=topology_state, domain=domain, **kwds) check_instance(obj._domain, Box) return obj @@ -27,7 +27,7 @@ class BoxView(DomainView): def __get_domain_attr(self, name): """Get a transposed domain attribute.""" return self._topology_state.transposed(getattr(self._domain, name)) - + def _get_length(self): """Box sides lengthes.""" return self.__get_domain_attr('_length') @@ -46,9 +46,9 @@ class BoxView(DomainView): return self.__get_domain_attr('_rboundaries') def _get_boundaries(self): """Left and right boundary conditions as a tuple.""" - return (self.__get_domain_attr('_lboundaries'), + return (self.__get_domain_attr('_lboundaries'), self.__get_domain_attr('_rboundaries'),) - + def _get_periodicity(self): """Numpy array mask, True is axis is periodic, else False.""" periodic = BoxBoundaryCondition.PERIODIC @@ -66,14 +66,14 @@ class BoxView(DomainView): """ s= '{} | {}D rectangular box domain:'.format(self.full_tag, self.dim) s+= '\n *origin: {}'.format(self.origin) - s+= '\n *max_pos: {}'.format(self.end) + s+= '\n *max_pos: {}'.format(self.end) s+= '\n *length: {}'.format(self.length) s+= '\n *left boundary conditions: {}'.format(self.lboundaries.tolist()) s+= '\n *right boundary conditions: {}'.format(self.rboundaries.tolist()) s+= '\n' return s - def short_description(self): + def short_description(self): """ Return a short description of this Box as a string. """ @@ -83,11 +83,11 @@ class BoxView(DomainView): ','.join(('{:1.1f}'.format(val) for val in self.length)), self.format_boundaries(), self.current_task()) - + def format_boundaries(self): return ','.join(('{}/{}'.format(str(lb),str(rb)) for (lb,rb) in \ zip(*self.boundaries))) - + length = property(_get_length) origin = property(_get_origin) end = property(_get_end) @@ -98,12 +98,12 @@ class BoxView(DomainView): class Box(BoxView, Domain): - """ + """ Box-shaped domain description. """ - + @debug - def __new__(cls, length=None, origin=None, dim=None, + def __new__(cls, length=None, origin=None, dim=None, lboundaries=None, rboundaries=None, **kwds): """ Create or get an existing Box from a dimension, length and origin with specified @@ -129,9 +129,9 @@ class Box(BoxView, Domain): length : np.ndarray of HYSOP_REAL Box sides lengthes. origin: np.ndarray of HYSOP_REAL - Position of the lowest point of the box. + Position of the lowest point of the box. end: np.ndarray of HYSOP_REAL - Position of the greatest point of the box. + Position of the greatest point of the box. lboundaries: np.ndarray of BoxBoundaryCondition Left boundary conditions. rboundaries: np.ndarray of BoxBoundaryCondition @@ -142,19 +142,19 @@ class Box(BoxView, Domain): Numpy array mask, True is axis is periodic, else False. """ from hysop.topology.cartesian_topology import CartesianTopologyState - - check_instance(dim, (int,long), minval=1, allow_none=True) - check_instance(length, (np.ndarray,list,tuple), values=(int,long,float), allow_none=True) - check_instance(origin, (np.ndarray,list,tuple), values=(int,long,float), allow_none=True) - check_instance(lboundaries, (np.ndarray,list,tuple), values=BoxBoundaryCondition, + + check_instance(dim, int, minval=1, allow_none=True) + check_instance(length, (np.ndarray,list,tuple), values=(int,float), allow_none=True) + check_instance(origin, (np.ndarray,list,tuple), values=(int,float), allow_none=True) + check_instance(lboundaries, (np.ndarray,list,tuple), values=BoxBoundaryCondition, allow_none=True) - check_instance(rboundaries, (np.ndarray,list,tuple), values=BoxBoundaryCondition, + check_instance(rboundaries, (np.ndarray,list,tuple), values=BoxBoundaryCondition, allow_none=True) if (length is None) and (origin is None) and (dim is None): msg='At least one of the following parameters should be given: length, origin, dim.' raise ValueError(msg) - + 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)) @@ -169,13 +169,13 @@ class Box(BoxView, Domain): check_instance(origin, np.ndarray, size=dim) assert (length>=0.0).all(), 'length < 0' - lboundaries = npw.asarray( first_not_None(lboundaries, + lboundaries = npw.asarray( first_not_None(lboundaries, (BoxBoundaryCondition.PERIODIC,)*dim ) ) - rboundaries = npw.asarray( first_not_None(rboundaries, + rboundaries = npw.asarray( first_not_None(rboundaries, (BoxBoundaryCondition.PERIODIC,)*dim ) ) assert lboundaries.size == rboundaries.size == dim - + for i,(lb,rb) in enumerate(zip(lboundaries,rboundaries)): if (lb==BoxBoundaryCondition.PERIODIC) ^ (rb==BoxBoundaryCondition.PERIODIC): msg='FATAL ERROR: Periodic BoxBoundaryCondition mismatch on axis {}.'.format(i) @@ -194,32 +194,32 @@ class Box(BoxView, Domain): msg+='\n *lboundaries: {}'.format(lboundaries) msg+='\n *rboundaries: {}'.format(rboundaries) warnings.warn(msg, HysopWarning) - + # double check types, to be sure RegisteredObject will work as expected check_instance(dim, int) check_instance(length, np.ndarray, dtype=HYSOP_REAL) check_instance(origin, np.ndarray, dtype=HYSOP_REAL) check_instance(lboundaries, np.ndarray, dtype=object) check_instance(rboundaries, np.ndarray, dtype=object) - + npw.set_readonly(length, origin, lboundaries, rboundaries) - + topology_state = CartesianTopologyState(dim) - - obj = super(Box,cls).__new__(cls, + + obj = super(Box,cls).__new__(cls, length=length, origin=origin, dim=dim, - lboundaries=lboundaries, rboundaries=rboundaries, + lboundaries=lboundaries, rboundaries=rboundaries, domain=None, topology_state=topology_state, **kwds) - if not obj.obj_initialized: + if not obj.obj_initialized: obj._length = length obj._origin = origin obj._lboundaries = lboundaries obj._rboundaries = rboundaries return obj - + def view(self, topology_state): """Return a view of this domain altered by some topology_state.""" - return BoxView(domain=self, topology_state=topology_state) + return BoxView(domain=self, topology_state=topology_state) diff --git a/hysop/domain/domain.py b/hysop/domain/domain.py index a7f696db4..9bd77042e 100644 --- a/hysop/domain/domain.py +++ b/hysop/domain/domain.py @@ -110,7 +110,7 @@ class DomainView(TaggedObjectView, metaclass=ABCMeta): """Test if the current process corresponds to param task.""" if isinstance(params, MPIParams): task_id = params.task_id - elif isinstance(params, (int, long, npw.integer)): + elif isinstance(params, (int, npw.integer)): task_id = params else: msg = 'Could not extract task_id from type {}.' diff --git a/hysop/fields/cartesian_discrete_field.py b/hysop/fields/cartesian_discrete_field.py index b98a72703..6bc770b17 100644 --- a/hysop/fields/cartesian_discrete_field.py +++ b/hysop/fields/cartesian_discrete_field.py @@ -1266,7 +1266,7 @@ class CartesianDiscreteScalarFieldView(CartesianDiscreteScalarFieldViewContainer """ assert ('data' not in kwds) msg = 'Passing ghosts as an integer is not supported anymore, use a tuple of size dim instead.' - if isinstance(ghosts, (int, long)): + if isinstance(ghosts, int): raise RuntimeError(msg) directions = to_tuple(first_not_None(directions, range(self.dim)), cast=int) @@ -1318,7 +1318,7 @@ class CartesianDiscreteScalarFieldView(CartesianDiscreteScalarFieldViewContainer Build a ghost exchanger for cartesian discrete fields, possibly on different data. """ msg = 'Passing ghosts as an integer is not supported anymore, use a tuple of size dim instead.' - if isinstance(ghosts, (int, long)): + if isinstance(ghosts, int): raise RuntimeError(msg) ghost_op = first_not_None(ghost_op, GhostOperation.EXCHANGE) diff --git a/hysop/fields/ghost_exchangers.py b/hysop/fields/ghost_exchangers.py index 014c3e6ba..0702b83ec 100644 --- a/hysop/fields/ghost_exchangers.py +++ b/hysop/fields/ghost_exchangers.py @@ -430,7 +430,7 @@ class CartesianDiscreteFieldGhostExchanger(GhostExchanger): elif (bc is BoundaryCondition.HOMOGENEOUS_NEUMANN): if isinstance(boundary, BoundaryConditionConfig) and (boundary.data is not None): # allow to force boundary ghosts to a specific scalar value - if isinstance(boundary.data, (int,long,float,np.number)): + if isinstance(boundary.data, (int,float,np.number)): fn = LocalBoundaryExchanger.build_scalar_exchanger(value=boundary.data, shape=shape, direction=d, to_left=to_left) else: diff --git a/hysop/mesh/cartesian_mesh.py b/hysop/mesh/cartesian_mesh.py index 79086012f..9249db90e 100644 --- a/hysop/mesh/cartesian_mesh.py +++ b/hysop/mesh/cartesian_mesh.py @@ -1074,9 +1074,9 @@ class CartesianMesh(CartesianMeshView, Mesh): # domain. These variables do not depend on the mpi distribution. from hysop.topology.cartesian_topology import CartesianTopology check_instance(topology, CartesianTopology) - check_instance(local_resolution, (list,tuple,np.ndarray), values=(int,long,np.integer), + check_instance(local_resolution, (list,tuple,np.ndarray), values=(int,np.integer), minval=1) - check_instance(global_start, (list,tuple,np.ndarray), values=(int,long,np.integer), + check_instance(global_start, (list,tuple,np.ndarray), values=(int,np.integer), minval=0) super(CartesianMesh, self).__init__(topology=topology, diff --git a/hysop/numerics/stencil/stencil_generator.py b/hysop/numerics/stencil/stencil_generator.py index 220bda6b1..8bc242389 100644 --- a/hysop/numerics/stencil/stencil_generator.py +++ b/hysop/numerics/stencil/stencil_generator.py @@ -361,9 +361,9 @@ class StencilGenerator(object): A = np.empty((N,N),dtype=solve_dtype) b = np.empty(N,dtype=solve_dtype) for i in range(N): - b[i] = solve_dtype(long(i==k)) + b[i] = solve_dtype(int(i==k)) for j in range(N): - A[i,j] = solve_dtype(long((j-origin)**i)) + A[i,j] = solve_dtype(int((j-origin)**i)) try: if has_flint: @@ -386,7 +386,7 @@ class StencilGenerator(object): if target_dtype in [np.float16, np.float32, np.float64]: if has_flint and (actual_dtype is flint.fmpq): def convert(x): - return target_dtype(float(long(x.p)) / float(long(x.q))) + return target_dtype(float(int(x.p)) / float(int(x.q))) S = np.vectorize(convert)(S) else: S = S.astype(target_dtype) diff --git a/hysop/operator/adapt_timestep.py b/hysop/operator/adapt_timestep.py index 65e91de33..a019fe773 100755 --- a/hysop/operator/adapt_timestep.py +++ b/hysop/operator/adapt_timestep.py @@ -120,7 +120,7 @@ class ConstantTimestepCriteria(TimestepCriteria): kwds: dict Base class arguments. """ - if isinstance(cst, (int, long)): + if isinstance(cst, int): cst = float(cst) assert (cst > 0.0), 'negative cst factor.' check_instance(cst, (float, npw.ndarray, list, tuple)) diff --git a/hysop/operator/base/custom_symbolic_operator.py b/hysop/operator/base/custom_symbolic_operator.py index bba8012df..720ae413f 100644 --- a/hysop/operator/base/custom_symbolic_operator.py +++ b/hysop/operator/base/custom_symbolic_operator.py @@ -245,7 +245,7 @@ class SymbolicExpressionInfo(object): self._dim = None else: compute_resolution = to_tuple(compute_resolution) - check_instance(compute_resolution, tuple, values=(int,long)) + check_instance(compute_resolution, tuple, values=int) self._dim = len(compute_resolution) self.compute_resolution = compute_resolution @@ -656,7 +656,7 @@ class SymbolicExpressionParser(object): assert expr.ndim == 0, expr expr = expr.tolist() - if isinstance(expr, (str, int,long,float,complex,npw.number)): + if isinstance(expr, (str,int,float,complex,npw.number)): return elif isinstance(expr, (AppliedSymbolicField, SymbolicScalarParameter, SymbolicArray)): cls.read(variables, info, expr) @@ -959,7 +959,7 @@ class SymbolicExpressionParser(object): assert expr.ndim == 0 expr = expr.tolist() - if isinstance(expr, (int, long, sm.Integer, float, complex, sm.Rational, sm.Float, npw.number)): + if isinstance(expr, (int, sm.Integer, float, complex, sm.Rational, sm.Float, npw.number)): return {} elif isinstance(expr, Cast): return cls._extract_obj_requirements(info, expr.expr) @@ -1135,7 +1135,7 @@ class SymbolicExpressionParser(object): else: expr = list(E) return expr, di - elif isinstance(expr, (int,long,float,complex,npw.number)): + elif isinstance(expr, (int,float,complex,npw.number)): return expr, di elif cls.should_transpose_expr(info, expr): expr = cls.transpose_expr(info, expr) @@ -1345,8 +1345,8 @@ class CustomSymbolicOperatorBase(DirectionalOperatorBase, metaclass=ABCMeta): """ check_instance(variables, dict, keys=Field, values=CartesianTopologyDescriptors) check_instance(exprs, tuple, values=ValidExpressions, minsize=1) - check_instance(splitting_direction, (int,long), allow_none=True) - check_instance(splitting_dim, (int,long), allow_none=True) + check_instance(splitting_direction, int, allow_none=True) + check_instance(splitting_dim, int, allow_none=True) check_instance(dt_coeff, float, allow_none=True) check_instance(dt, ScalarParameter, allow_none=True) diff --git a/hysop/operator/base/spectral_operator.py b/hysop/operator/base/spectral_operator.py index 3fea604ef..e5adba837 100644 --- a/hysop/operator/base/spectral_operator.py +++ b/hysop/operator/base/spectral_operator.py @@ -229,7 +229,7 @@ class SpectralOperatorBase(object): requests = super(SpectralOperatorBase, self).get_work_properties(**kwds) for ((k, backend), v) in self.get_mem_requests(**kwds).items(): check_instance(k, str) - check_instance(v, (int, long)) + check_instance(v, int) if (v > 0): mrequest = MemoryRequest(backend=backend, size=v, alignment=self.min_fft_alignment) @@ -549,7 +549,7 @@ class SpectralTransformGroup(object): memory_requests = {} for fwd in self.forward_transforms.values(): mem_requests = fwd.get_mem_requests(**kwds) - check_instance(mem_requests, dict, keys=str, values=(int, long)) + check_instance(mem_requests, dict, keys=str, values=int) for (k, v) in mem_requests.items(): if k in memory_requests: memory_requests[k] = max(memory_requests[k], v) @@ -557,7 +557,7 @@ class SpectralTransformGroup(object): memory_requests[k] = v for bwd in self.backward_transforms.values(): mem_requests = bwd.get_mem_requests(**kwds) - check_instance(mem_requests, dict, keys=str, values=(int, long)) + check_instance(mem_requests, dict, keys=str, values=int) for (k, v) in mem_requests.items(): if k in memory_requests: memory_requests[k] = max(memory_requests[k], v) diff --git a/hysop/operator/base/transpose_operator.py b/hysop/operator/base/transpose_operator.py index 905b7f4c2..867b0cb01 100644 --- a/hysop/operator/base/transpose_operator.py +++ b/hysop/operator/base/transpose_operator.py @@ -39,7 +39,7 @@ class TransposeOperatorBase(object, metaclass=ABCMeta): check_instance(input_field, ScalarField) check_instance(output_field, ScalarField) check_instance(variables, dict, keys=ScalarField, values=CartesianTopologyDescriptors) - check_instance(axes, (list,tuple), values=(int,long)) + check_instance(axes, (list,tuple), values=int) assert set((input_field,output_field)) == set(variables.keys()) assert input_field.domain is output_field.domain diff --git a/hysop/operator/directional/diffusion_dir.py b/hysop/operator/directional/diffusion_dir.py index 984827719..993dc4ee4 100644 --- a/hysop/operator/directional/diffusion_dir.py +++ b/hysop/operator/directional/diffusion_dir.py @@ -20,34 +20,34 @@ class DirectionalDiffusion(DirectionalSymbolic): """ Directional diffusion using the symbolic code generation framework. """ - + @debug - def __init__(self, fields, coeffs, variables, dt, + def __init__(self, fields, coeffs, variables, dt, laplacian_formulation=True, name=None, implementation=None, base_kwds=None, **kwds): """ Initialize directional diffusion frontend. - Diffusion is the net movement of regions of high concentration to neighbour regions of lower + Diffusion is the net movement of regions of high concentration to neighbour regions of lower concentration, ie the evolution of a field down its gradient. - - Solves + + Solves dFi/dt = Di * laplacian(Fi) - or - dFi/dt = div( Di * grad(Fi) ) + or + dFi/dt = div( Di * grad(Fi) ) for multiple fields Fi, where * represents elementwise multiplication, using a given time integrator, inplace. - + Di can be a scalar, a vector or a matrix, see Notes. - + Parameters ---------- fields: array like of continuous fields. The fields Fi that will be diffused. coeffs: array like of coefficients The diffusion coefficients Di can be scalar or tensor like (ie. possibly anisotropic). - Contained values should be numerical coefficients, parameters or symbolic + Contained values should be numerical coefficients, parameters or symbolic expressions such that Di*grad(Fi) is directionally splittable. variables: dict Dictionary of fields as keys and topology descriptors as values. @@ -64,25 +64,25 @@ class DirectionalDiffusion(DirectionalSymbolic): Base class keywords arguments. If None, an empty dict will be passed. kwds: - Keywords arguments that will be passed towards implementation + Keywords arguments that will be passed towards implementation operator __init__. - + Notes ----- Solves dFi/dt = div( Di * grad(Fi) ) with the following notations: - - Fi = (Fi0(x0,...,xMi), - Fi1(x0,...,xMi), - ... + + Fi = (Fi0(x0,...,xMi), + Fi1(x0,...,xMi), + ... FiNi(x0,...,xMi)) - Mi = Fi.dim - 1 + Mi = Fi.dim - 1 Ni = Fi.nb_components - 1 - - grad(Fi) = (dFi0/dx0, ..., dFi0/dxM), - (dFi1/dx0, ..., dFi1/dxM), + + grad(Fi) = (dFi0/dx0, ..., dFi0/dxM), + (dFi1/dx0, ..., dFi1/dxM), ... - (dFiNi/dx0, ..., dFiNi/dxM) + (dFiNi/dx0, ..., dFiNi/dxM) (d00, ..., d0Ni) ( . . . ) @@ -90,16 +90,16 @@ class DirectionalDiffusion(DirectionalSymbolic): ( . . . ) (dNi0, ..., dNiNi) - if Di.ndim is 1, Di[:,None] will be used ie: - + if Di.ndim is 1, Di[:,None] will be used ie: + (d0, ..., d0) ( . . . ) Di = ( . . . ) ( . . . ) (dNi, ..., dNi) - - if Di.ndim is 0, Di[None,None] will be used ie: - + + if Di.ndim is 0, Di[None,None] will be used ie: + (d0, ..., d0) (. . .) Di = (. . .) @@ -124,26 +124,26 @@ class DirectionalDiffusion(DirectionalSymbolic): check_instance(base_kwds, dict, keys=str) check_instance(name, str) check_instance(fields, (tuple,), values=Field) - check_instance(coeffs, (tuple,), values=(int,long,float,npw.ndarray,sm.Basic), size=len(fields)) + check_instance(coeffs, (tuple,), values=(int,float,npw.ndarray,sm.Basic), size=len(fields)) check_instance(laplacian_formulation, bool) - + exprs = self._gen_expressions(fields, coeffs, laplacian_formulation) super(DirectionalDiffusion, self).__init__(name=name, variables=variables, dt=dt, - base_kwds=base_kwds, implementation=implementation, exprs=exprs, + base_kwds=base_kwds, implementation=implementation, exprs=exprs, candidate_input_tensors=fields, candidate_output_tensors=fields, **kwds) - + from hysop.operator.base.custom_symbolic_operator import CustomSymbolicOperatorBase if not issubclass(self._operator, CustomSymbolicOperatorBase): msg='Class {} does not inherit from the directional operator interface ' msg+='({}).' msg=msg.format(self._operator, CustomSymbolicOperatorBase) raise TypeError(msg) - + self.coeffs = coeffs - + def _gen_expressions(self, fields, coeffs, laplacian_formulation): from hysop.symbolic.field import div, grad, laplacian exprs = () diff --git a/hysop/operator/directional/directional.py b/hysop/operator/directional/directional.py index 96d6e53f6..26cd6648f 100644 --- a/hysop/operator/directional/directional.py +++ b/hysop/operator/directional/directional.py @@ -35,8 +35,8 @@ class DirectionalOperatorBase(object): dt_coeff: float Coefficient that should be applied on simulation timestep. """ - check_instance(splitting_dim, (int,long)) - check_instance(splitting_direction, (int,long)) + check_instance(splitting_dim, int) + check_instance(splitting_direction, int) check_instance(dt_coeff, float) dim = splitting_dim diff --git a/hysop/operator/spatial_filtering.py b/hysop/operator/spatial_filtering.py index 7facb047c..2ec022e1d 100644 --- a/hysop/operator/spatial_filtering.py +++ b/hysop/operator/spatial_filtering.py @@ -18,7 +18,7 @@ FilteringMethod = EnumFactory.create('FilteringMethod', class SpatialFilterFrontend(MultiComputationalGraphNodeFrontend): def __init__(self, input_variable, output_variable, - filtering_method, implementation=None, + filtering_method, implementation=None, base_kwds=None, **kwds): """ @@ -61,7 +61,7 @@ class SpatialFilterFrontend(MultiComputationalGraphNodeFrontend): super(SpatialFilterFrontend, self).__init__(input_field=input_field, input_topo=input_topo, output_field=output_field, output_topo=output_topo, implementation_key=filtering_method, - implementation=implementation, + implementation=implementation, base_kwds=base_kwds, **kwds) @@ -139,7 +139,7 @@ class InterpolationFilterFrontend(SpatialFilterFrontend): FilteringMethod.POLYNOMIAL: Implementation.PYTHON, } return adi - + class SpatialFilter(ComputationalGraphNodeGenerator): """ @@ -196,7 +196,7 @@ class SpatialFilter(ComputationalGraphNodeGenerator): candidate_input_tensors=None, candidate_output_tensors=None, **base_kwds) - + self._input_fields = input_fields self._output_fields = output_fields self._input_variables = input_variables @@ -211,32 +211,32 @@ class SpatialFilter(ComputationalGraphNodeGenerator): for (ifield, ofield) in zip(self._input_fields, self._output_fields): stopo = ComputationalGraphNode.get_topo_discretization(self._input_variables, ifield) ttopo = ComputationalGraphNode.get_topo_discretization(self._output_variables, ofield) - check_instance(stopo, tuple, values=(int,long)) - check_instance(ttopo, tuple, values=(int,long)) + check_instance(stopo, tuple, values=int) + check_instance(ttopo, tuple, values=int) assert len(stopo)==len(ttopo) fm = self._fm impl = self._impl kwds = self._kwds.copy() - + # if source topology is destination topology there is nothing to be done if (ttopo == stopo): continue - elif all(ns <= nt for (ns, nt) in zip(stopo, ttopo)): + elif all(ns <= nt for (ns, nt) in zip(stopo, ttopo)): # here we build an interpolation filter operator node = InterpolationFilterFrontend( input_variable=(ifield,stopo), - output_variable=(ofield,ttopo), + output_variable=(ofield,ttopo), filtering_method=fm, - implementation=impl, + implementation=impl, **kwds) - elif all(ns >= nt for (ns, nt) in zip(stopo, ttopo)): + elif all(ns >= nt for (ns, nt) in zip(stopo, ttopo)): # here we build a restriction filter operator node = RestrictionFilterFrontend( input_variable=(ifield,stopo), - output_variable=(ofield,ttopo), + output_variable=(ofield,ttopo), filtering_method=fm, - implementation=impl, + implementation=impl, **kwds) else: msg='Inconsistant topology descriptors {} and {} for field {} and {}, ' diff --git a/hysop/operator/transpose.py b/hysop/operator/transpose.py index 961b8f3cb..26a2232b4 100644 --- a/hysop/operator/transpose.py +++ b/hysop/operator/transpose.py @@ -243,7 +243,7 @@ class Transpose(ComputationalGraphNodeGenerator): if isinstance(axes, dict): candidate_axes = axes elif isinstance(axes, (list,tuple,set,frozenset)): - if isinstance(axes[0], (int,long)): + if isinstance(axes[0], int): msg='Axes should be ordered but got a set.' assert not isinstance(axes, (set,frozenset)), msg candidate_axes = (tuple(axes),) @@ -258,7 +258,7 @@ class Transpose(ComputationalGraphNodeGenerator): check_instance(candidate_axes, dict, keys=tuple) for (axes, target_tstate) in candidate_axes.items(): - check_instance(axes, tuple, values=(int,long)) + check_instance(axes, tuple, values=int) check_instance(target_tstate, TranspositionState[dim], allow_none=True) if len(axes)!=dim: msg='All axes should have the dimension of the transposed fields {} ' diff --git a/hysop/parameters/scalar_parameter.py b/hysop/parameters/scalar_parameter.py index 98b3b62af..ff71bf8a1 100644 --- a/hysop/parameters/scalar_parameter.py +++ b/hysop/parameters/scalar_parameter.py @@ -6,8 +6,8 @@ from hysop.parameters.tensor_parameter import TensorParameter class ScalarParameter(TensorParameter): """ - A scalar parameter is TensorParameter with its shape - set to (1,). A parameter is a value that may change + A scalar parameter is TensorParameter with its shape + set to (1,). A parameter is a value that may change as simulation advances. """ @@ -15,7 +15,7 @@ class ScalarParameter(TensorParameter): assert 'shape' not in kwds, 'Cannot specify shape for a scalar parameter.' obj = super(ScalarParameter,cls).__new__(cls, name, shape=(1,), **kwds) return obj - + def iterviews(self): """Iterate over all parameters views to yield scalarparameters.""" yield (None,self) @@ -37,16 +37,13 @@ class ScalarParameter(TensorParameter): def __int__(self): """Return value as an int.""" return int(self.value) - def __long__(self): - """Return value as a long.""" - return long(self.value) def __float__(self): """Return value as a float.""" return float(self.value) def __complex__(self): """Return value as a complex.""" return complex(self.value) - + def long_description(self): ss = '''\ ScalarParameter[name={}] @@ -60,7 +57,7 @@ ScalarParameter[name={}] self.min_value, self.max_value, self.ignore_nans, self.value) return ss - + def short_description(self): attrs=('name', 'dtype', 'value') info = [] diff --git a/hysop/parameters/tensor_parameter.py b/hysop/parameters/tensor_parameter.py index f7a2f59eb..895716d8e 100644 --- a/hysop/parameters/tensor_parameter.py +++ b/hysop/parameters/tensor_parameter.py @@ -71,13 +71,13 @@ class TensorParameter(Parameter): pretty_name = first_not_None(pretty_name, name) check_instance(name, str) check_instance(pretty_name, str) - check_instance(shape, (list,tuple), values=(int,long,np.integer), allow_none=True) + check_instance(shape, (list,tuple), values=(int,np.integer), allow_none=True) check_instance(ignore_nans, bool) assert (min_value is None) or (max_value is None) or (min_value <= max_value) parameter_types = (np.ndarray,) if is_signed(dtype): - parameter_types += ( np.int8, np.int16, np.int32, np.int64, int, long ) + parameter_types += ( np.int8, np.int16, np.int32, np.int64, int) elif is_unsigned(dtype): parameter_types += ( np.uint8, np.uint16, np.uint32, np.uint64 ) elif is_fp(dtype): diff --git a/hysop/symbolic/array.py b/hysop/symbolic/array.py index 067d0efd8..2fadf2989 100644 --- a/hysop/symbolic/array.py +++ b/hysop/symbolic/array.py @@ -231,7 +231,7 @@ class SymbolicNdBuffer(SymbolicBuffer): assert (dtype is not None), 'Could not determine dtype from memory_object.' itemsize = dtype.itemsize strides = to_tuple(strides) - check_instance(strides, tuple, values=(int,long), size=self._dim) + check_instance(strides, tuple, values=int, size=self._dim) for ss,si in zip(self._symbolic_strides, strides): assert si%itemsize == 0 ss.bind_value(si//itemsize, force=force) @@ -239,7 +239,7 @@ class SymbolicNdBuffer(SymbolicBuffer): ghosts = first_not_None(ghosts, getattr(memory_object, 'ghosts', None)) assert (ghosts is not None), 'Could not determine ghosts from memory_object.' ghosts = to_tuple(ghosts) - check_instance(ghosts, tuple, values=(int,long), size=self._dim) + check_instance(ghosts, tuple, values=int, size=self._dim) for sg,gi in zip(self._symbolic_ghosts, ghosts): sg.bind_value(gi, force=force) diff --git a/hysop/tools/debug_dumper.py b/hysop/tools/debug_dumper.py index 868179b3f..3592cf40d 100644 --- a/hysop/tools/debug_dumper.py +++ b/hysop/tools/debug_dumper.py @@ -117,7 +117,7 @@ class DebugDumper(object): _max = comm.allreduce(float(np.nanmax(d)), op=MPI.MAX) mean = comm.allreduce(float(np.nanmean(d))) / comm_size variance = comm.allreduce(float(np.nansum((d-mean)**2))) / \ - float(comm.allreduce(long(d.size))) + float(comm.allreduce(int(d.size))) entry = '\n'+self.lformat(id_, iteration, time, tag_, _min, _max, mean, variance, dtype, shape, description_, self.dump_precision) diff --git a/hysop/tools/enum.py b/hysop/tools/enum.py index 5dabce092..ccf4eb5d1 100644 --- a/hysop/tools/enum.py +++ b/hysop/tools/enum.py @@ -176,9 +176,9 @@ class EnumFactory(object): CodegenVariable, CodegenArray assert vals is not None size = len(vals) - value = [getattr(cls,cls.svalue(v)) if isinstance(v, (int,long)) + value = [getattr(cls,cls.svalue(v)) if isinstance(v, int) else v for v in vals] - svalue = [cls.svalue(v) if isinstance(v, (int,long)) else str(v) for v in vals] + svalue = [cls.svalue(v) if isinstance(v, int) else str(v) for v in vals] if len(vals)==1: return CodegenVariable(name=name,typegen=typegen,ctype=dtype_to_ctype(cls.dtype), value=value[0],svalue=svalue[0],**kwds) diff --git a/hysop/tools/handle.py b/hysop/tools/handle.py index 4a148a5e8..c560df833 100644 --- a/hysop/tools/handle.py +++ b/hysop/tools/handle.py @@ -96,6 +96,9 @@ class TaggedObject(object, metaclass=ABCMeta): assert (tag_formatter is None) or callable(tag_formatter) tagged_cls = first_not_None(tagged_cls, cls) + if kwds: + print('TARGGED OBJECT MRO is {}'.format(cls.__mro__)) + print('KWDS are {}'.format(kwds)) obj = super(TaggedObject, cls).__new__(cls, **kwds) if tagged_cls in TaggedObject.__ids: obj.__tag_id = TaggedObject.__ids[tagged_cls] @@ -114,9 +117,9 @@ class TaggedObject(object, metaclass=ABCMeta): """ Initialize a TaggedObject with a tag prefix/postfix/formatter, all optional. """ - tag_prefix = kwds.get('tag_prefix', None) - tag_postfix = kwds.get('tag_postfix', None) - tag_formatter = kwds.get('tag_formatter', None) + 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) @@ -257,7 +260,7 @@ class RegisteredObject(TaggedObject): def __new__(cls, register_object=True, tag_prefix=None, tag_postfix=None, tag_formatter=None, **kwds): - """ + r""" Creates and return a RegisteredObject and assign a unique id if and only if a previous object was not already created with the exact same keywords arguments (modulo hashing). diff --git a/hysop/tools/io_utils.py b/hysop/tools/io_utils.py index f7ae6cb17..58ebce4c2 100755 --- a/hysop/tools/io_utils.py +++ b/hysop/tools/io_utils.py @@ -312,12 +312,12 @@ class IOParams(namedtuple("IOParams", ['filename', 'filepath', check_instance(filename, str, allow_none=True) check_instance(filepath, str, allow_none=True) - check_instance(frequency, (int, long)) + check_instance(frequency, int) check_instance(dump_times, tuple, values=(float, np.float64)) - check_instance(dump_tstart, (int, long, float, np.float64)) - check_instance(dump_tend, (int, long, float, np.float64)) - check_instance(io_leader, (int, long)) - check_instance(visu_leader, (int, long)) + check_instance(dump_tstart, (int, float, np.float64)) + check_instance(dump_tend, (int, float, np.float64)) + check_instance(io_leader, int) + check_instance(visu_leader, int) check_instance(with_last, bool) check_instance(enable_ram_fs, bool) check_instance(force_ram_fs, bool) diff --git a/hysop/tools/numba_utils.py b/hysop/tools/numba_utils.py index fd236fb13..7c5bc6bbb 100644 --- a/hysop/tools/numba_utils.py +++ b/hysop/tools/numba_utils.py @@ -16,8 +16,7 @@ def make_numba_signature(*args, **kwds): msg='Unknown kwds {}.'.forma(kwds.keys()) raise RuntimeError(kwds) dtype_to_ntype = { - int: nb.int32, - long: nb.int64, + int: nb.int64, float: nb.float64, np.int8: nb.int8, diff --git a/hysop/tools/numerics.py b/hysop/tools/numerics.py index f4dcd832c..3b9ee9637 100644 --- a/hysop/tools/numerics.py +++ b/hysop/tools/numerics.py @@ -9,7 +9,7 @@ MPFR = mpfr(0).__class__ F2Q = f2q(0).__class__ def _mpqize(x): - if isinstance(x, int) or isinstance(x, long): + if isinstance(x, int): return mpq(x,1) elif isinstance(x, float): return f2q(x) @@ -27,7 +27,7 @@ def get_dtype(x): return x else: return x.dtype - elif isinstance(x, int) or isinstance(x, long): + elif isinstance(x, int): return np.int64 elif isinstance(x, float): return np.float64 diff --git a/hysop/tools/numpywrappers.py b/hysop/tools/numpywrappers.py index 58ed78a1c..7ef697a08 100644 --- a/hysop/tools/numpywrappers.py +++ b/hysop/tools/numpywrappers.py @@ -127,7 +127,7 @@ def slices_empty(slices, shape): if slices is Ellipsis: return False from hysop.core.arrays.array import Array - if isinstance(slices, (int,long,npw.integer,npw.ndarray,Array)): + if isinstance(slices, (int,npw.integer,npw.ndarray,Array)): return slices = (slices,) if isinstance(slices,slice) else slices diff --git a/hysop/tools/spectral_utils.py b/hysop/tools/spectral_utils.py index d6ca0fb8b..045b24eec 100644 --- a/hysop/tools/spectral_utils.py +++ b/hysop/tools/spectral_utils.py @@ -200,7 +200,7 @@ class SpectralTransformUtils(object): elif replace_pows and \ isinstance(expr, sm.Pow) and \ isinstance(expr.args[0], WaveNumber) and \ - isinstance(expr.args[1], (int,long,np.integer,sm.Integer)): + isinstance(expr.args[1], (int,np.integer,sm.Integer)): wn = expr.args[0].pow(int(expr.args[1])) wave_numbers.add(wn) return wn diff --git a/hysop/tools/sympy_utils.py b/hysop/tools/sympy_utils.py index 442367c88..86af1a8a0 100644 --- a/hysop/tools/sympy_utils.py +++ b/hysop/tools/sympy_utils.py @@ -121,14 +121,16 @@ class Dummy(SymbolicBase, sm.Dummy): """Tag for hysop dummy symbolic variables.""" pass -class UndefinedFunction(SymbolicBase, sm.function.UndefinedFunction): +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. This is a metaclass. """ pass -class AppliedUndef(sm.function.AppliedUndef): +class AppliedUndef(SympyAppliedUndef): """Tag for hysop applied undefined functions.""" def _latex(self, printer): diff --git a/hysop/tools/types.py b/hysop/tools/types.py index a9cd5dcbf..58655a459 100644 --- a/hysop/tools/types.py +++ b/hysop/tools/types.py @@ -1,5 +1,5 @@ from hysop.deps import np -from collections import Iterable +from collections.abc import Iterable class InstanceOf(object): def __init__(self, cls): diff --git a/hysop/tools/units.py b/hysop/tools/units.py index f32b73145..f1341b559 100644 --- a/hysop/tools/units.py +++ b/hysop/tools/units.py @@ -23,10 +23,10 @@ def decimal_unit2str(b,unit,rounded): return '{}{}{}'.format(round(b/10.0**(3*i),rounded),prefix[i],unit) except: return '{}{}'.format(b,unit) - + def unit2str(b,unit,decimal,rounded=2): - if not isinstance(b, (int,long,float,np.integer,np.floating)): + if not isinstance(b, (int,float,np.integer,np.floating)): return b if decimal: @@ -51,7 +51,7 @@ def freq2str(freq,decimal=True,rounded=2): def time2str(t, on_zero=None, on_none=None): - if not isinstance(t, (float,int,long,np.dtype)): + if not isinstance(t, (float,int,np.dtype)): return t if t is None: return (on_none or '{:5d}'.format(-1)) diff --git a/hysop_examples/example_utils.py b/hysop_examples/example_utils.py index a1c340411..cf67e6a98 100644 --- a/hysop_examples/example_utils.py +++ b/hysop_examples/example_utils.py @@ -50,7 +50,8 @@ class SplitAppendAction(argparse._AppendAction): msg='Could not convert values \'{}\' to tuple for parameter {}.'.format(values, self.dest) parser.error(msg) if self._append: - items = argparse._ensure_value(namespace, self.dest, self._container()) + items = getattr(namespace, self.dest, None) + items = self._container() if (items is None) else items else: items = self._container() if (self._container is list): @@ -364,7 +365,7 @@ class HysopArgParser(argparse.ArgumentParser): stream_filters = [self._null_filter] self._mkdir(args.stdout) - with StdoutTee(args.stdout, mode='a', + with StdoutTee(args.stdout, mode='a', buff=-1, file_filters=file_filters, stream_filters=stream_filters): yield @@ -380,7 +381,7 @@ class HysopArgParser(argparse.ArgumentParser): stream_filters = [self._null_filter] self._mkdir(args.stderr) - with StderrTee(args.stderr, mode='a', + with StderrTee(args.stderr, mode='a', buff=-1, file_filters=file_filters, stream_filters=stream_filters): yield diff --git a/hysop_examples/examples/taylor_green/taylor_green.py b/hysop_examples/examples/taylor_green/taylor_green.py index cc51ec1ec..c5fe8819e 100644 --- a/hysop_examples/examples/taylor_green/taylor_green.py +++ b/hysop_examples/examples/taylor_green/taylor_green.py @@ -68,7 +68,7 @@ def compute(args): from hysop.backend.device.opencl.opencl_tools import get_or_create_opencl_env, get_device_number cl_env = get_or_create_opencl_env( mpi_params=mpi_params, - platform_id=args.cl_platform_id, + platform_id=args.cl_platform_id, device_id=box.machine_rank%get_device_number() if args.cl_device_id is None else None) # Configure OpenCL kernel generation and tuning (already done by HysopArgParser) @@ -140,7 +140,7 @@ def compute(args): enforce_implementation=args.enforce_implementation, implementation=impl, **extra_op_kwds) #> We ask to dump the outputs of this operator - dump_fields = HDF_Writer(name='fields', + dump_fields = HDF_Writer(name='fields', io_params=args.io_params.clone(filename='fields'), force_backend=backend, variables={velo: npts, vorti: npts}, **extra_op_kwds) @@ -208,7 +208,7 @@ def compute(args): parameters[axe1] = {dt_lcfl0.name: dt_lcfl0, dt_lcfl1.name: dt_lcfl1, dt_lcfl2.name: dt_lcfl2, - dt_cfl.name: dt_cfl, + dt_cfl.name: dt_cfl, dt_stretch.name: dt_stretch} parameters[axe2] = {'CFL*': adapt_dt.equivalent_CFL } else: @@ -223,7 +223,7 @@ def compute(args): snpts, config), fontweight='bold') axe0.set_title('Integrated Enstrophy') axe0.set_xlabel('Non-dimensional time', fontweight='bold') - axe0.set_ylabel('$\zeta$', + axe0.set_ylabel(r'$\zeta$', rotation=0, fontweight='bold') axe0.set_xlim(args.tstart, args.tend) axe0.set_ylim(0, 26) @@ -289,7 +289,7 @@ def compute(args): t=t, dt=dt) params = (t, dt, enstrophy,) if args.variable_timestep: - params += (dt_cfl, dt_stretch, dt_lcfl0, dt_lcfl1, dt_lcfl2, + params += (dt_cfl, dt_stretch, dt_lcfl0, dt_lcfl1, dt_lcfl2, min_max_U.Finf, min_max_W.Finf, min_max_gradU.Finf, adapt_dt.equivalent_CFL) simu.write_parameters(*params, filename='parameters.txt', precision=8) @@ -297,7 +297,7 @@ def compute(args): problem.initialize_field(vorti, formula=init_vorticity) # Finally solve the problem - problem.solve(simu, dry_run=args.dry_run, + problem.solve(simu, dry_run=args.dry_run, debug_dumper=args.debug_dumper, checkpoint_handler=args.checkpoint_handler) diff --git a/requirements.txt b/requirements.txt index 163c660c8..962592003 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,6 @@ portalocker tee ansicolors argparse_color_formatter -primefac pybind11 pyopencl pyfftw @@ -20,10 +19,9 @@ mpi4py matplotlib numba configparser -backports.tempfile -backports.weakref networkx pyvis zarr numcodecs jsonpickle +pytest diff --git a/src/hysop++/main/diffSolver.cpp b/src/hysop++/main/diffSolver.cpp deleted file mode 100644 index 3d0316e3f..000000000 --- a/src/hysop++/main/diffSolver.cpp +++ /dev/null @@ -1,237 +0,0 @@ - -#include <cstdlib> - -#include "domain/domain.h" -#include "solver/fftDiffSolver.h" -#include "data/multi_array/multi_array.h" -#include "utils/constants.h" -#include "fft/extension.h" -#include "maths/quad_maths.h" - -using namespace hysop; -using namespace hysop::domain; - -static constexpr std::size_t nExtensions = 4 ; -static constexpr std::size_t nExtensionsPair = 7 ; -static constexpr fft::Extension ext[nExtensions] = -{ fft::Extension::NONE, fft::Extension::ODD, fft::Extension::EVEN, fft::Extension::PERIODIC }; -static constexpr std::pair<fft::Extension,fft::Extension> pext[nExtensionsPair] { - std::make_pair(ext[3],ext[3]), //periodic-periodic - std::make_pair(ext[3],ext[3]), //periodic-periodic - std::make_pair(ext[2],ext[1]), //even-odd - std::make_pair(ext[1],ext[2]), //odd-even - std::make_pair(ext[2],ext[2]), //even-even - std::make_pair(ext[1],ext[1]), //odd-odd - std::make_pair(ext[0],ext[0]), //none-none -}; - -#ifdef HAS_QUADMATHS - static constexpr __float128 freqs[6] = { 1.0Q, 1.0Q, 0.75Q, 0.75Q, 0.50Q, 0.50Q }; -#else - static constexpr long double freqs[6] = { 1.0L, 1.0L, 0.75L, 0.75L, 0.50L, 0.50L }; -#endif - -template <typename T> -std::function<T(T)> func(std::size_t k) { - switch(k) { - case 0: return [=](T x) {return std::cos(T(freqs[0])*x);}; - case 1: return [=](T x) {return std::sin(T(freqs[1])*x);}; - case 2: return [=](T x) {return std::cos(T(freqs[2])*x);}; - case 3: return [=](T x) {return std::sin(T(freqs[3])*x);}; - case 4: return [=](T x) {return std::cos(T(freqs[4])*x);}; - case 5: return [=](T x) {return std::sin(T(freqs[5])*x);}; - default: return[=](T x) { return T(1); }; - } -} - -template <typename T> -std::function<T(T)> derivative(std::size_t k, int order) { - bool even = (k%2==0); - std::size_t p, offset; - T sign, coeff; - if(k>5) { - if(order != 0) - throw std::runtime_error("Non zero order !"); - return func<T>(k); - } - else if(even) { /* cos func */ - p = (order%2==0 ? k : k+1); - sign = std::pow(T(-1),(order+1)/2); - coeff = std::pow(freqs[k], order); - } - else { /* sin func */ - p = (order%2==0 ? k : k-1); - sign = std::pow(T(-1),order/2); - coeff = std::pow(freqs[k], order); - } - return [=](T x) { return sign*coeff*(func<T>(p)(x)); }; -} - -template <typename T, std::size_t Dim, bool verbose=false> -void test(std::size_t p_maxOrder, bool includePeriodicBds=false) { - typename Shape<Dim>::type shape; - typename Domain<T,Dim>::DomainSize domainSize; - Domain<T,Dim> ref, inBuffer, outBuffer; - - Domain<T,Dim>& in = inBuffer; - Domain<T,Dim>& out = outBuffer; - - std::array<int,Dim> order; - - shape.fill(8); - domainSize.fill(2*hysop::constants::pi); - - T eps = std::numeric_limits<T>::epsilon(); - const std::size_t N = std::accumulate(shape.begin(), shape.end(), 1, std::multiplies<std::size_t>()); - - ref.resize(domainSize).reshape(shape); - in = ref; - out = ref; - - typename Shape<Dim>::type maxOrder, testCases; - maxOrder.fill(p_maxOrder+1); - testCases.fill(nExtensionsPair); - Index<Dim> orderId(maxOrder); - Index<Dim> testCaseId; - std::size_t testCaseCount; - while(!(++orderId).atMaxId()) { - std::cout << " ::Order::" << orderId.ids() << (verbose ? "\n" : ""); - - std::array<T,3> meanDists; - meanDists.fill(0); - testCaseId.reset(testCases); - testCaseCount = testCaseId.maxId(); - while(!testCaseId.atMaxId()) { - std::copy(orderId.ids().begin(),orderId.ids().end(), order.begin()); - - /* generate transform configuration */ - std::array<std::pair<fft::Extension,fft::Extension>, Dim> extConfig; - for (std::size_t k=0; k<Dim; k++) { - std::size_t id = testCaseId[k]; - extConfig[k] = pext[id]; - if(pext[id].first==fft::Extension::NONE) - order[k] = 0; - } - fft::FftDomainConfiguration<Dim> domainConfig(extConfig, includePeriodicBds); - - const std::size_t orderSum = std::accumulate(order.begin(), order.end(), 0); - if(orderSum == 0) { - testCaseCount--; - ++testCaseId; - continue; - } - T orderPow = std::pow(T(10),T(orderSum)); - if(std::is_same<T,long double>::value) /* just in case long doubles are not hardware supported... */ - orderPow *= 1e3; - const auto criteria = std::make_tuple(orderPow*eps*N,orderPow*eps*sqrt(N),2*orderPow*eps); - - const auto f = [&](const typename Domain<T,Dim>::SpaceVariable &x) { - T val = func<T>(testCaseId[0])(x[0]); - for (std::size_t d=1; d < Dim; d++) - val *= func<T>(testCaseId[d])(x[d]); - return val; - }; - const auto d = [&](const typename Domain<T,Dim>::SpaceVariable &x) { - T val = derivative<T>(testCaseId[0],order[0])(x[0]); - for (std::size_t d=1; d < Dim; d++) - val *= derivative<T>(testCaseId[d],order[d])(x[d]); - return val; - }; - { - ref.resetDomainConfiguration(domainConfig.boundariesConfiguration()); - in = ref; - out = ref; - - in.apply(f); - ref.apply(d); - out.data().apply([](T& v){ v=T(0);}); - } - - solver::FftDiffSolver<T,Dim> solver(domainSize, domainConfig, FFTW_MEASURE, includePeriodicBds, includePeriodicBds); - solver.apply(in.data(), out.data(), order); - - std::stringstream ss; - ss << "["; - for (std::size_t k=0; k<Dim-1; k++) - ss << extConfig[k].first << "/" << extConfig[k].second << ","; - ss << extConfig[Dim-1].first << "/" << extConfig[Dim-1].second; - ss << "]"; - - const auto dist = out.distance(ref); - const bool pass = (std::get<0>(dist) < std::get<0>(criteria)) - && (std::get<1>(dist) < std::get<1>(criteria)) - && (std::get<2>(dist) < std::get<2>(criteria)); - - if((pass && verbose) || !pass) { - std::cout << (pass ? GREEN : RED); - std::cout << "\t" << std::setw(Dim*15) << ss.str() << " => " << (pass ? "OK" : "KO") - << " " << RESET << std::scientific << std::setprecision(2) << dist << std::endl; - } - if(!pass) { - //in.print("IN"); - //ref.print("REF"); - //out.print("OUT"); - std::cout << criteria << std::endl; - exit(EXIT_FAILURE); - } - - meanDists[0] += std::get<0>(dist); - meanDists[1] += std::get<1>(dist); - meanDists[2] += std::get<2>(dist); - - ++testCaseId; - } - for (std::size_t k = 0; k < 3; k++) - meanDists[k] /= T(testCaseCount); - std::cout << "=> mean distances over " << std::scientific << std::setprecision(1) << std::setw(4) - << testCaseCount << " testcases: " << meanDists; - for (std::size_t k = 0; k < 3; k++) - meanDists[k] = std::round(meanDists[k]/eps); - std::cout << " ~= " << std::fixed << std::setprecision(0) << meanDists << " eps" << std::endl; - } -} - -int main(int argc, const char *argv[]) { - -#ifdef FFTW_HAS_FFTW3F - std::cout << "== TEST 1D - float ==" << std::endl; - test<float,1,false>(5); - std::cout << "== TEST 2D - float ==" << std::endl; - test<float,2,false>(3); - std::cout << "== TEST 3D - float ==" << std::endl; - test<float,3,false>(1); - std::cout << std::endl; -#endif - -#ifdef FFTW_HAS_FFTW3D - std::cout << "== TEST 1D - double ==" << std::endl; - test<double,1,false>(5); - std::cout << "== TEST 2D - double ==" << std::endl; - test<double,2,false>(3); - std::cout << "== TEST 3D - double ==" << std::endl; - test<double,3,false>(1); - std::cout << std::endl; -#endif - -#ifdef FFTW_HAS_FFTW3L - std::cout << "== TEST 1D - long double ==" << std::endl; - test<long double,1,false>(5); - std::cout << "== TEST 2D - long double ==" << std::endl; - test<long double,2,false>(3); - std::cout << "== TEST 3D - long double ==" << std::endl; - test<long double,3,false>(1); - std::cout << std::endl; -#endif - -#ifdef FFTW_HAS_FFTW3Q - std::cout << "== TEST 1D - __float128 ==" << std::endl; - test<__float128,1,false>(5); - std::cout << "== TEST 2D - __float128 ==" << std::endl; - test<__float128,2,false>(3); - std::cout << "== TEST 3D - __float128 ==" << std::endl; - test<__float128,3,false>(1); - std::cout << std::endl; -#endif - - return EXIT_SUCCESS; -} diff --git a/src/hysop++/main/planner.cpp b/src/hysop++/main/planner.cpp deleted file mode 100644 index 287c6713c..000000000 --- a/src/hysop++/main/planner.cpp +++ /dev/null @@ -1,197 +0,0 @@ - -#include "maths/quad_maths.h" - -#include "data/multi_array/multi_array.h" -#include "domain/domain.h" -#include "utils/constants.h" -#include "fft/planner.h" -#include "fft/extension.h" - - -using namespace hysop; -using namespace hysop::domain; - -static constexpr std::size_t nExtensions = 4 ; -static constexpr std::size_t nExtensionsPair = 6 ; -static constexpr fft::Extension ext[nExtensions] = -{ fft::Extension::NONE, fft::Extension::ODD, fft::Extension::EVEN, fft::Extension::PERIODIC }; -static constexpr std::pair<fft::Extension,fft::Extension> pext[nExtensionsPair] { - std::make_pair(ext[0],ext[0]), //none-none - std::make_pair(ext[1],ext[1]), //odd-odd - std::make_pair(ext[1],ext[2]), //odd-even - std::make_pair(ext[1],ext[2]), //even-odd - std::make_pair(ext[2],ext[2]), //even-even - std::make_pair(ext[3],ext[3]), //periodic-periodic -}; - -template <typename T, std::size_t Dim, bool verbose=false> -void test(bool inplace, bool includePeriodicBds); - - -int main(int argc, const char *argv[]) { - -#ifdef FFTW_HAS_FFTW3F - std::cout << std::endl; - std::cout << "== TEST 1D - float ==\t"; - test<float,1>(false,true); - std::cout << "== TEST 2D - float ==\t"; - test<float,2>(false,true); - std::cout << "== TEST 3D - float ==\t"; - test<float,3>(false,true); -#endif - -#ifdef FFTW_HAS_FFTW3D - std::cout << std::endl; - std::cout << "== TEST 1D - double ==\t"; - test<double,1>(true,true); - std::cout << "== TEST 2D - double ==\t"; - test<double,2>(true,true); - std::cout << "== TEST 3D - double ==\t"; - test<double,3>(true,true); -#endif - -#ifdef FFTW_HAS_FFTW3L - std::cout << std::endl; - std::cout << "== TEST 1D - long double ==\t"; - test<long double,1>(false,false); - std::cout << "== TEST 2D - long double ==\t"; - test<long double,2>(false,false); - std::cout << "== TEST 3D - long double ==\t"; - test<long double,3>(false,false); -#endif - -#ifdef FFTW_HAS_FFTW3Q - std::cout << std::endl; - std::cout << "== TEST 1D - __float128 ==\t"; - test<__float128,1>(false,false); - std::cout << "== TEST 2D - __float128 ==\t"; - test<__float128,2>(false,false); - std::cout << "== TEST 3D - __float128 ==\t"; - test<__float128,3>(false,false); -#endif - - return 0; -} - -template <typename T, std::size_t Dim, bool verbose> -void test(bool inplace, bool includePeriodicBds) { - typename Shape<Dim>::type shape; - typename Domain<T,Dim>::DomainSize domainSize; - Domain<T,Dim> ref, inBuffer, outBuffer; - - Domain<T,Dim>& in = inBuffer; - Domain<T,Dim>& out = (inplace ? inBuffer : outBuffer); - - fft::Planner<T,Dim> planner; - std::array<int,Dim> order; - - const std::size_t nPoints = 16; - shape.fill(nPoints); - domainSize.fill(1.0); - order.fill(2); - - const T eps = std::numeric_limits<T>::epsilon(); - const std::size_t N = std::accumulate(shape.begin(), shape.end(), 1, std::multiplies<std::size_t>()); - const auto criteria = std::make_tuple(50*eps*N,sqrt(50)*eps*N,700*eps); - - ref.resize(domainSize).reshape(shape); - in = ref; - out = ref; - - typename Shape<Dim>::type testCases; - testCases.fill(nExtensionsPair); - Index<Dim> testCaseId(testCases); - std::array<T,3> meanDists{0}; - while(!testCaseId.atMaxId()) { - /* generate transform configuration */ - std::array<std::pair<fft::Extension,fft::Extension>, Dim> extConfig; - for (std::size_t k=0; k<Dim; k++) { - std::size_t id = testCaseId[k]; - extConfig[k] = pext[id]; - } - fft::FftDomainConfiguration<Dim> domainConfig(extConfig, includePeriodicBds); - - const auto f = [&](T &val, const hysop::Index<Dim>& idx) { - val = static_cast<T>(rand())/static_cast<T>(RAND_MAX); - for (std::size_t d=0; d<Dim; d++) { - if(idx[d]==0) { - if(extConfig[d].first == fft::Extension::ODD) { - val=T(0); - return; - } - else if(extConfig[d].first == fft::Extension::PERIODIC) - val=T(0.42); - } - else if(std::size_t(idx[d]) == idx.dim()[d]-1) { - if(extConfig[d].second == fft::Extension::ODD) { - val=T(0); - return; - } - else if(extConfig[d].second == fft::Extension::PERIODIC && includePeriodicBds) - val=T(0.42); - } - } - }; - - if(includePeriodicBds) - ref.resetDomainConfiguration(domainConfig.boundariesConfiguration()); - - /* fill reference and copy into input buffer */ - ref.data().apply(f); - in = ref; - - /* plan transforms and check if planning succeeded */ - bool status = planner.plan(in.data(), out.data(), domainConfig, order, domainSize, FFTW_MEASURE, - includePeriodicBds, includePeriodicBds); - assert(status || testCaseId()==0); - - /* execute forward and backward inplace transforms */ - planner.executeForwardTransform(); - { - if(planner.transformType() == fft::FftTransformType::FFT_R2C) - planner.transformedComplexData().apply([&](std::complex<T>& val) { val /= planner.normalisationFactor(); }); - else if(planner.transformType() == fft::FftTransformType::FFT_R2R) - planner.transformedRealData().apply([&](T& val) { val /= planner.normalisationFactor(); }); - } - planner.executeBackwardTransform(); - - std::stringstream ss; - ss << "["; - for (std::size_t k=0; k<Dim-1; k++) - ss << extConfig[k].first << "/" << extConfig[k].second << ","; - ss << extConfig[Dim-1].first << "/" << extConfig[Dim-1].second; - ss << "]"; - - const auto dist = out.distance(ref); - const bool pass = (std::get<0>(dist) < std::get<0>(criteria)) - && (std::get<1>(dist) < std::get<1>(criteria)) - && (std::get<2>(dist) < std::get<2>(criteria)); - - if((pass && verbose) || !pass) { - std::cout << (pass ? GREEN : RED); - std::cout << "\t" << std::setw(Dim*15) << ss.str() << " => " << (pass ? "OK" : "KO") - << " " << RESET << std::scientific << std::setprecision(2) << dist << std::endl; - } - if(!pass) { - if(!inplace) - in.print("IN"); - ref.print("REF"); - out.print("OUT"); - std::cout << planner << std::endl; - exit(EXIT_FAILURE); - } - - meanDists[0] += std::get<0>(dist); - meanDists[1] += std::get<1>(dist); - meanDists[2] += std::get<2>(dist); - - ++testCaseId; - } - for (std::size_t k = 0; k < 3; k++) - meanDists[k] /= T(testCaseId.maxId()); - std::cout << "Mean distances over " << std::scientific << std::setprecision(1) << std::setw(4) - << testCaseId.maxId() << " testcases: " << meanDists; - for (std::size_t k = 0; k < 3; k++) - meanDists[k] = std::round(meanDists[k]/eps); - std::cout << " ~= " << std::fixed << std::setprecision(0) << meanDists << " eps" << std::endl; -} diff --git a/src/hysop++/main/poissonSolver.cpp b/src/hysop++/main/poissonSolver.cpp deleted file mode 100644 index e95a8cd50..000000000 --- a/src/hysop++/main/poissonSolver.cpp +++ /dev/null @@ -1,213 +0,0 @@ - -#include <cstdlib> - -#include "domain/domain.h" -#include "solver/fftPoissonSolver.h" -#include "data/multi_array/multi_array.h" -#include "utils/constants.h" -#include "domain/boundary.h" - -using namespace hysop; -using namespace hysop::domain; - -static constexpr std::size_t nBoundaries = 4; -static constexpr std::size_t nBoundaryPairs = 7; -static constexpr domain::Boundary bds[nBoundaries] = -{ domain::Boundary::NONE, domain::Boundary::HOMOGENEOUS_NEUMANN, domain::Boundary::HOMOGENEOUS_DIRICHLET, domain::Boundary::PERIODIC }; -static constexpr std::pair<domain::Boundary,domain::Boundary> pbds[nBoundaryPairs] { - std::make_pair(bds[3],bds[3]), //periodic-periodic - std::make_pair(bds[3],bds[3]), //periodic-periodic - std::make_pair(bds[2],bds[1]), //even-odd - std::make_pair(bds[1],bds[2]), //odd-even - std::make_pair(bds[2],bds[2]), //even-even - std::make_pair(bds[1],bds[1]), //odd-odd - std::make_pair(bds[0],bds[0]), //none-none -}; - -#ifdef HAS_QUADMATHS - static constexpr __float128 freqs[6] = { 1.0Q, 1.0Q, 0.75Q, 0.75Q, 0.50Q, 0.50Q }; -#else - static constexpr long double freqs[6] = { 1.0L, 1.0L, 0.75L, 0.75L, 0.50L, 0.50L }; -#endif - -template <typename T> -std::function<T(T)> func(std::size_t k) { - switch(k) { - case 0: return [=](T x) {return std::cos(T(freqs[0])*x);}; - case 1: return [=](T x) {return std::sin(T(freqs[1])*x);}; - case 2: return [=](T x) {return std::cos(T(freqs[2])*x);}; - case 3: return [=](T x) {return std::sin(T(freqs[3])*x);}; - case 4: return [=](T x) {return std::cos(T(freqs[4])*x);}; - case 5: return [=](T x) {return std::sin(T(freqs[5])*x);}; - default: return[=](T x) { return T(1); }; - } -} - -std::string bdsToStr(domain::Boundary bd) { - switch(bd) { - case(Boundary::NONE): return "None "; - case(Boundary::PERIODIC) : return "Periodic "; - case(Boundary::HOMOGENEOUS_NEUMANN): return "Hom_Neum. "; - case(Boundary::HOMOGENEOUS_DIRICHLET): return "Hom_Diric."; - case(Boundary::NEUMANN): return "Neumann "; - case(Boundary::DIRICHLET): return "Dirichlet "; - } - return ""; -} - -template <typename T, std::size_t Dim, bool verbose=false> -void test(bool includePeriodicBds=false) { - typename Shape<Dim>::type shape; - typename Domain<T,Dim>::DomainSize domainSize; - Domain<T,Dim> ref, inBuffer, outBuffer; - - Domain<T,Dim>& in = inBuffer; - Domain<T,Dim>& out = outBuffer; - - shape.fill(16); - domainSize.fill(2*hysop::constants::pi); - - const T eps = std::numeric_limits<T>::epsilon(); - const std::size_t N = std::accumulate(shape.begin(), shape.end(), 1, std::multiplies<std::size_t>()); - - ref.resize(domainSize).reshape(shape); - in = ref; - out = ref; - - typename Shape<Dim>::type testCases; - testCases.fill(nBoundaryPairs); - Index<Dim> testCaseId(testCases); - std::array<T,3> meanDists{0}; - std::size_t testCaseCount = testCaseId.maxId()-1; - - if(verbose) - std::cout << std::endl; - - while(testCaseId() != testCaseId.maxId()-1) { - - /* generate transform configuration */ - std::size_t orderSum = 0; - std::array<std::pair<domain::Boundary,domain::Boundary>, Dim> bdsConfig; - T W2sum = T(0); - for (std::size_t k=0; k<Dim; k++) { - std::size_t id = testCaseId[k]; - bdsConfig[k] = pbds[id]; - if(bdsConfig[k].first != domain::Boundary::NONE) { - W2sum += freqs[id]*freqs[id]; - orderSum+=2; - } - } - domain::DomainConfiguration<Dim> domainConfig(bdsConfig, includePeriodicBds); - - T orderPow = std::pow(T(10),T(orderSum)); - if(std::is_same<T,long double>::value) /* just in case long doubles are not hardware supported... */ - orderPow *= 1e3; - const auto criteria = std::make_tuple(orderPow*eps*N,orderPow*eps*sqrt(N),2*orderPow*eps); - - const auto phi = [&](const typename Domain<T,Dim>::SpaceVariable &x) { - T val = func<T>(testCaseId[0])(x[0]); - for (std::size_t d=1; d < Dim; d++) - val *= func<T>(testCaseId[d])(x[d]); - return val; - }; - const auto f = [&](const typename Domain<T,Dim>::SpaceVariable &x) { - return -W2sum*phi(x); - }; - - { - ref.resetDomainConfiguration(domainConfig); - in = ref; - out = ref; - - in.apply(f); - ref.apply(phi); - out.data().apply([](T& v){ v=T(0);}); - } - - solver::FftPoissonSolver<T,Dim> solver(domainSize, domainConfig, FFTW_MEASURE, includePeriodicBds, includePeriodicBds); - solver.apply(in.data(), out.data()); - - std::stringstream ss; - ss << "["; - for (std::size_t k=0; k<Dim-1; k++) - ss << bdsToStr(bdsConfig[k].first) << "/" << bdsToStr(bdsConfig[k].second) << ","; - ss << bdsToStr(bdsConfig[Dim-1].first) << "/" << bdsToStr(bdsConfig[Dim-1].second); - ss << "]"; - - const auto dist = out.distance(ref); - const bool pass = (std::get<0>(dist) < std::get<0>(criteria)) - && (std::get<1>(dist) < std::get<1>(criteria)) - && (std::get<2>(dist) < std::get<2>(criteria)); - - if((pass && verbose) || !pass) { - std::cout << (pass ? GREEN : RED); - std::cout << "\t" << std::setw(Dim*15) << ss.str() << " => " << (pass ? "OK" : "KO") - << " " << RESET << std::scientific << std::setprecision(2) << dist << std::endl; - } - if(!pass) { - //in.print("IN"); - //ref.print("REF"); - //out.print("OUT"); - std::cout << "\t\tTest Failed... Criteria was " << criteria << "." << std::endl; - exit(EXIT_FAILURE); - } - - meanDists[0] += std::get<0>(dist); - meanDists[1] += std::get<1>(dist); - meanDists[2] += std::get<2>(dist); - - ++testCaseId; - } - - for (std::size_t k = 0; k < 3; k++) - meanDists[k] /= T(testCaseCount); - std::cout << "\t=> mean distances over " << std::scientific << std::setprecision(1) << std::setw(4) - << testCaseCount << " testcases: " << meanDists; - for (std::size_t k = 0; k < 3; k++) - meanDists[k] = std::round(meanDists[k]/eps); - std::cout << " ~= " << std::fixed << std::setprecision(0) << meanDists << " eps" << std::endl; -} - -int main(int argc, const char *argv[]) { - -#ifdef FFTW_HAS_FFTW3F - std::cout << "== TEST 1D - float =="; - test<float,1,true>(); - std::cout << "== TEST 2D - float =="; - test<float,2,true>(); - std::cout << "== TEST 3D - float =="; - test<float,3,false>(); - std::cout << std::endl; -#endif - -#ifdef FFTW_HAS_FFTW3D - std::cout << "== TEST 1D - double =="; - test<double,1,false>(); - std::cout << "== TEST 2D - double =="; - test<double,2,false>(); - std::cout << "== TEST 3D - double =="; - test<double,3,false>(); - std::cout << std::endl; -#endif - -#ifdef FFTW_HAS_FFTW3L - std::cout << "== TEST 1D - long double =="; - test<long double,1,false>(); - std::cout << "== TEST 2D - long double =="; - test<long double,2,false>(); - std::cout << "== TEST 3D - long double =="; - test<long double,3,false>(); - std::cout << std::endl; -#endif - -#ifdef FFTW_HAS_FFTW3Q - std::cout << "== TEST 1D - __float128 =="; - test<__float128,1,false>(); - std::cout << "== TEST 2D - __float128 =="; - test<__float128,2,false>(); - std::cout << "== TEST 3D - __float128 =="; - test<__float128,3,false>(); - std::cout << std::endl; -#endif - return EXIT_SUCCESS; -} diff --git a/src/hysop++/src/data/accumulatorIndex.h b/src/hysop++/src/data/accumulatorIndex.h deleted file mode 100644 index b794002c2..000000000 --- a/src/hysop++/src/data/accumulatorIndex.h +++ /dev/null @@ -1,65 +0,0 @@ - -#ifndef HYSOP_ACCUMULATORINDEX_H -#define HYSOP_ACCUMULATORINDEX_H - -#include <array> -#include <cassert> -#include <vector> -#include <functional> - -#include "data/index.h" - -namespace hysop { - - template <typename T, std::size_t Dim, typename Source = std::array<std::vector<T>,Dim>, typename Functor = std::function<T(const T&, const T&)>> - struct AccumulatorIndex : public Index<Dim> { - - private: - using super = Index<Dim>; - public: - using Indices = typename super::Indices; - using Dimension = typename super::Dimension; - - public: - AccumulatorIndex(const AccumulatorIndex& idx) = default; - ~AccumulatorIndex() = default; - - template <typename DimArray=Dimension, typename AccumulatorIndexArray=Indices> - AccumulatorIndex(const DimArray& p_dim = DimArray{0}, - const Indices &p_ids = AccumulatorIndexArray{0}): - super(p_dim, p_ids), m_accumulatedData{0}, m_sourceData(nullptr), m_functor(std::plus<T>()) { - } - - AccumulatorIndex& setAccumulatorSource(const Source& p_source) { m_sourceData = &p_source; init(); return *this; } - AccumulatorIndex& setAccumulatorFunction(const Functor& p_functor) { m_functor = p_functor; init(); return *this; } - - const T& accumulatedVal() const { return m_accumulatedData[Dim-1]; } - - protected: - void init() { - if(m_sourceData != nullptr) { - m_accumulatedData[0] = (*m_sourceData)[0][this->operator[](0)]; - for (std::size_t d=0; d<Dim-1; d++) - m_accumulatedData[d+1] = m_functor(m_accumulatedData[d],(*m_sourceData)[d+1][this->operator[](d+1)]); - } - } - - virtual void onIndexChange(std::size_t pos, std::ptrdiff_t offset) final override { - if(m_sourceData != nullptr) { - assert(pos < Dim); - m_accumulatedData[pos] = (pos==0 ? (*m_sourceData)[0][this->operator[](0)] : m_functor(m_accumulatedData[pos-1],(*m_sourceData)[pos][this->operator[](pos)])); - for (std::size_t d=pos; d<Dim-1; d++) - m_accumulatedData[d+1] = m_functor(m_accumulatedData[d],(*m_sourceData)[d+1][this->operator[](d+1)]); - } - }; - - protected: - std::array<T,Dim> m_accumulatedData; - const Source* m_sourceData; - Functor m_functor; - }; - -} - -#endif /* end of include guard: HYSOP_ACCUMULATORINDEX_H */ - diff --git a/src/hysop++/src/data/index.h b/src/hysop++/src/data/index.h deleted file mode 100644 index c0dcb6993..000000000 --- a/src/hysop++/src/data/index.h +++ /dev/null @@ -1,125 +0,0 @@ - -#ifndef HYSOP_INDEX_H -#define HYSOP_INDEX_H - -#include <array> -#include <cassert> - -namespace hysop { - - template <std::size_t Dim> - struct Index { - typedef boost::array<std::ptrdiff_t,Dim> Indices; - typedef boost::array<std::size_t,Dim> Dimension; - - Index(const Index& idx) = default; - ~Index() = default; - - template <typename DimArray=Dimension, typename IndexArray=Indices> - Index(const DimArray& p_dim = DimArray{0}, - const Indices &p_ids = IndexArray{0}) : - m_dim(), m_ids(), m_id(0) { - for (std::size_t d = 0; d < Dim; d++) { - m_dim[d] = p_dim[d]; - m_ids[d] = p_ids[d]; - } - initializeId(); - } - - template <typename DimArray, typename IndexArray=Indices> - Index& reset(const DimArray& p_dim, const IndexArray &p_ids = IndexArray{0}) { - for (std::size_t d = 0; d < Dim; d++) { - m_dim[d] = p_dim[d]; - m_ids[d] = p_ids[d]; - } - initializeId(); - return *this; - } - - Index& setIndexToMinusOne() { - for (std::size_t d=0; d<Dim-1; d++) - m_ids[d] = 0; - m_ids[Dim-1] = -1; - initializeId(); - return *this; - } - - std::size_t id() const { return m_id; }; - std::size_t maxId() const { return m_maxId; } - bool atMaxId() const { return m_id == m_maxId; } - - const Indices& ids() const { return m_ids; }; - const Dimension& dim() const { return m_dim; }; - - std::ptrdiff_t operator[](std::size_t k) const { return m_ids[k]; } - std::size_t operator()() const { return m_id; } - - virtual void onIndexChange(std::size_t pos, std::ptrdiff_t offset) {}; - virtual void onIndexOverflow(std::size_t pos) {}; - virtual void onIndexUndeflow(std::size_t pos) {}; - -//__attribute__((optimize("unroll-loops"))) - Index& operator++() { //prefix - for (int d = Dim-1; d >=0; d--) { - m_ids[d]++; - if(m_ids[d]==std::ptrdiff_t(m_dim[d])) { - m_ids[d]=0; - this->onIndexOverflow(d); - } - else { - this->onIndexChange(d, +1); - break; - } - } - m_id++; - return *this; - }; -//__attribute__((optimize("unroll-loops"))) - Index& operator--() { //prefix - for (int d = 0; d < Dim; d++) { - if(m_ids[d]!=0) { - this->onIndexChange(d, -1); - m_ids[d]--; - break; - } - else { - this->onIndexUndeflow(d); - } - } - m_id--; - return *this; - }; - - Index operator++(int) { //postfix - Index result(*this); - ++(*this); - return result; - }; - Index operator--(int) { //postfix - Index result(*this); - --(*this); - return result; - }; - - protected: - void initializeId() { - m_id = 0; - m_maxId = 1; - for (std::size_t d = 0; d < Dim-1; d++) { - m_id = (m_id + m_ids[d]) * m_dim[d+1]; - m_maxId*=m_dim[d]; - } - m_id += m_ids[Dim-1]; - m_maxId*=m_dim[Dim-1]; - } - - private: - Dimension m_dim; - Indices m_ids; - std::size_t m_id, m_maxId; - }; - -} - -#endif /* end of include guard: HYSOP_INDEX_H */ - diff --git a/src/hysop++/src/data/memory/fftwAllocator.h b/src/hysop++/src/data/memory/fftwAllocator.h deleted file mode 100644 index d2b8423f3..000000000 --- a/src/hysop++/src/data/memory/fftwAllocator.h +++ /dev/null @@ -1,53 +0,0 @@ - -#ifndef HYSOP_FFTW_ALLOCATOR_H -#define HYSOP_FFTW_ALLOCATOR_H - -#include <limits> -#include <fftw3.h> - -namespace hysop { - namespace data { - namespace memory { - - /* FftwAllocator designed to correctly align data for fftw */ - template <typename T> - struct FftwAllocator { - using value_type = T; - using const_pointer = const T*; - - FftwAllocator() = default; - - template <class U> - FftwAllocator(const FftwAllocator<U>&) {} - - T* allocate(std::size_t n, const_pointer hint=nullptr) { - if (n <= std::numeric_limits<std::size_t>::max() / sizeof(T)) { - if (auto ptr = fftw_malloc(n * sizeof(T))) { - return static_cast<T*>(ptr); - } - } - throw std::bad_alloc(); - } - void deallocate(T* ptr, std::size_t n) { - fftw_free(ptr); - } - void destroy(T* ptr) { - ptr->~T(); - } - }; - - template <typename T, typename U> - inline bool operator == (const FftwAllocator<T>&, const FftwAllocator<U>&) { - return true; - } - - template <typename T, typename U> - inline bool operator != (const FftwAllocator<T>& a, const FftwAllocator<U>& b) { - return !(a == b); - } - - } /* end of namespace memory */ - } /* end of namespace data */ -} /* end of namespace hysop */ - -#endif /* end of include guard: HYSOP_FFTW_ALLOCATOR_H */ diff --git a/src/hysop++/src/data/memory/minimalAllocator.h b/src/hysop++/src/data/memory/minimalAllocator.h deleted file mode 100644 index 2460db0db..000000000 --- a/src/hysop++/src/data/memory/minimalAllocator.h +++ /dev/null @@ -1,52 +0,0 @@ - -#ifndef HYSOP_MINIMAL_ALLOCATOR_H -#define HYSOP_MINIMAL_ALLOCATOR_H - -#include <limits> - -namespace hysop { - namespace data { - namespace memory { - - /* Minimal MinimalAllocator for boost and std libs */ - template <typename T> - struct MinimalAllocator { - using value_type = T; - using const_pointer = const T*; - - MinimalAllocator() = default; - - template <class U> - MinimalAllocator(const MinimalAllocator<U>&) {} - - T* allocate(std::size_t n, const_pointer hint=nullptr) { - if (n <= std::numeric_limits<std::size_t>::max() / sizeof(T)) { - if (auto ptr = std::malloc(n * sizeof(T))) { - return static_cast<T*>(ptr); - } - } - throw std::bad_alloc(); - } - void deallocate(T* ptr, std::size_t n) { - std::free(ptr); - } - void destroy(T* ptr) { - ptr->~T(); - } - }; - - template <typename T, typename U> - inline bool operator == (const MinimalAllocator<T>&, const MinimalAllocator<U>&) { - return true; - } - - template <typename T, typename U> - inline bool operator != (const MinimalAllocator<T>& a, const MinimalAllocator<U>& b) { - return !(a == b); - } - - } /* end of namespace memory */ - } /* end of namespace data */ -} /* end of namespace hysop */ - -#endif /* end of include guard: HYSOP_MINIMAL_ALLOCATOR_H */ diff --git a/src/hysop++/src/data/multi_array/< b/src/hysop++/src/data/multi_array/< deleted file mode 100644 index 9b142c71f..000000000 --- a/src/hysop++/src/data/multi_array/< +++ /dev/null @@ -1,352 +0,0 @@ - -#ifndef HYSOP_MULTI_ARRAY_H -#define HYSOP_MULTI_ARRAY_H - -/**********************************/ -/*** Hysop boost multi array wrapper ***/ -/********************************/ - -#include "const_multi_array_view.h" -#include "multi_array_view.h" - -namespace hysop { - namespace data { - - /* forward declaration */ - FORWARD_DECLARE_TYPES() - - /* class hysop::data::multi_array */ - template <typename T, std::size_t Dim, typename Allocator> - class multi_array : public boost_multi_array<T,Dim,Allocator> { - static_assert(Dim>0, "Dim cannot be zero !"); - - private: - using super = boost_multi_array<T,Dim,Allocator>; - using super_ref = boost_multi_array_ref<T,Dim>; - public: - PUBLIC_CLASS_TYPES() - - public: - multi_array(const extents_gen<Dim>& extents = extents_gen<Dim>()); - multi_array(const Shape<Dim>& shape); - - multi_array(const multi_array& other); - multi_array(multi_array&& other); - - explicit multi_array(const array_ref& other); - explicit multi_array(const array_view& other); - explicit multi_array(const const_array_ref& other); - explicit multi_array(const const_array_view& other); - - explicit multi_array(const boost_multi_array<T,Dim,Allocator>& other); - explicit multi_array(const boost_multi_array_ref<T,Dim>& other); - explicit multi_array(const boost_multi_array_view<T,Dim>& other); - explicit multi_array(const boost_const_multi_array_ref<T,Dim>& other); - explicit multi_array(const boost_const_multi_array_view<T,Dim>& other); - explicit multi_array(boost_multi_array<T,Dim,Allocator>&& other); - - multi_array& operator=(const multi_array& other); - multi_array& operator=(const array_ref& ref); - multi_array& operator=(const array_view& view); - multi_array& operator=(const const_array_ref& ref); - multi_array& operator=(const const_array_view& view); - multi_array& operator=(multi_array&& other); - - operator array_ref(); - operator const_array_ref() const; - - public: - - multi_array& reshape(const Shape<Dim>& shape); - - /* print data */ - const multi_array& print(const std::string& name, std::ostream& os = std::cout, - unsigned int precision=2u, unsigned int width=6u) const; - - /* Apply function to all elements of the view */ - /* (1) apply func(T&) on all elements */ - /* (2) apply func(T&, const Index<Dim>&) on all elements */ - /* (3) apply func(T&, const Index<Dim>&, farg0, fargs...) on all elements */ - multi_array& apply(const std::function<void(T&)>& func); - multi_array& apply(const std::function<void(T&, const Index<Dim>&)>& func); - template <typename Functor, typename Arg0, typename... Args> - multi_array& apply(const Functor& func, Arg0&& farg0, Args&&... fargs); - - /* boolean array_view specific functions */ - ENABLE_IF_BOOL(bool) all() const; - ENABLE_IF_BOOL(bool) any() const; - ENABLE_IF_BOOL(bool) none() const; - - /* real and complex data accessors, usefull for FFT like transforms */ - ENABLE_IF_REAL ( T*) rdata() { return this->origin(); } - ENABLE_IF_REAL (const T*) rdata() const { return this->origin(); } - - ENABLE_IF_COMPLEX( T*) cdata() { return this->origin(); } - ENABLE_IF_COMPLEX(const T*) cdata() const { return this->origin(); } - - ENABLE_IF_COMPLEX( typename fft::fftw_complex_type<T>::std_type*) std_cdata() { - return reinterpret_cast< typename fft::fftw_complex_type<T>::std_type*>(this->origin()); - } - ENABLE_IF_COMPLEX(const typename fft::fftw_complex_type<T>::std_type*) std_cdata() const { - return reinterpret_cast<const typename fft::fftw_complex_type<T>::std_type*>(this->origin()); - } - ENABLE_IF_COMPLEX( typename fft::fftw_complex_type<T>::fftw_type*) fftw_cdata() { - return reinterpret_cast< typename fft::fftw_complex_type<T>::fftw_type*>(this->origin()); - } - ENABLE_IF_COMPLEX(const typename fft::fftw_complex_type<T>::fftw_type*) fftw_cdata() const { - return reinterpret_cast<const typename fft::fftw_complex_type<T>::fftw_type*>(this->origin()); - } - - ENABLE_IF_COMPLEX( typename fft::fftw_complex_type<T>::value_type*) asRealData() { - return reinterpret_cast< typename fft::fftw_complex_type<T>::value_type*>(this->origin()); - } - ENABLE_IF_COMPLEX(const typename fft::fftw_complex_type<T>::value_type*) asRealData() const { - return reinterpret_cast< const typename fft::fftw_complex_type<T>::value_type*>(this->origin()); - } - ENABLE_IF_REAL ( typename fft::fftw_complex_type<T>::std_type*) asStdComplexData() { - return reinterpret_cast< typename fft::fftw_complex_type<T>::std_type*>(this->origin()); - } - ENABLE_IF_REAL (const typename fft::fftw_complex_type<T>::std_type*) asStdComplexdata() const { - return reinterpret_cast<const typename fft::fftw_complex_type<T>::std_type*>(this->origin()); - } - ENABLE_IF_REAL ( typename fft::fftw_complex_type<T>::fftw_type*) asFftwComplexdata() { - return reinterpret_cast< typename fft::fftw_complex_type<T>::fftw_type*>(this->origin()); - } - ENABLE_IF_REAL (const typename fft::fftw_complex_type<T>::fftw_type*) asFftwComplexData() const { - return reinterpret_cast<const typename fft::fftw_complex_type<T>::fftw_type*>(this->origin()); - } - - protected: - static extents_gen<Dim> shapeToExtents(const Shape<Dim> &shape); - }; - - - /* Implementation */ - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const extents_gen<Dim>& extents): - boost_multi_array<T,Dim,Allocator>(extents) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const Shape<Dim>& shape): - boost_multi_array<T,Dim,Allocator>(shapeToExtents(shape)) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const multi_array& other): - boost_multi_array<T,Dim,Allocator>(static_cast<const boost_multi_array<T,Dim>&>(other)) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const array_view& other): - boost_multi_array<T,Dim,Allocator>(static_cast<const boost_multi_array_view<T,Dim>&>(other)) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const const_array_view& other): - boost_multi_array<T,Dim,Allocator>(static_cast<const boost_multi_array_view<T,Dim>&>(other)) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(multi_array&& other): - boost_multi_array<T,Dim,Allocator>(static_cast<boost_multi_array<T,Dim,Allocator>&&>(other)) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const boost_multi_array_view<T,Dim>& other): - boost_multi_array<T,Dim,Allocator>(other) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const boost_const_multi_array_view<T,Dim>& other): - boost_multi_array<T,Dim,Allocator>(other) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const boost_multi_array_ref<T,Dim>& other): - boost_multi_array<T,Dim,Allocator>(other) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const boost_const_multi_array_ref<T,Dim>& other): - boost_multi_array<T,Dim,Allocator>(other) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(boost_multi_array<T,Dim,Allocator>&& other): - boost_multi_array<T,Dim,Allocator>(other) {} - - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>& multi_array<T,Dim,Allocator>::operator=(const array_view& other) { - this->reshape(other.shape()); - /* cast obligatory to avoid shape() function aliasing */ - super::operator=(dynamic_cast<const boost_multi_array_view<T,Dim>&>(other)); - return *this; - } - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>& multi_array<T,Dim,Allocator>::operator=(const const_array_view& other) { - this->reshape(other.shape()); - /* cast obligatory to avoid shape() function aliasing */ - super::operator=(dynamic_cast<const boost_multi_array_view<T,Dim>&>(other)); - return *this; - } - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>& multi_array<T,Dim,Allocator>::operator=(const multi_array& other) { - this->reshape(other.shape()); - /* cast obligatory to avoid shape() function aliasing */ - super::operator=(dynamic_cast<const boost_multi_array_ref<T,Dim>&>(other)); - return *this; - } - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>& multi_array<T,Dim,Allocator>::operator=(multi_array&& other) { - super::operator=(other); - return *this; - } - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::operator array_view() { - return this->operator[](hysop::utils::buildView<Dim>()); - } - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::operator const_array_view() const { - return this->operator[](hysop::utils::buildView<Dim>()); - } - - - template <typename T, std::size_t Dim, typename Allocator> - Shape<Dim> multi_array<T,Dim,Allocator>::shape() const { - Shape<Dim> shape; - const std::size_t* extents = this->super::shape(); - for (std::size_t d = 0; d < Dim; d++) - shape[d] = static_cast<std::size_t>(extents[d]); - return shape; - } - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>& multi_array<T,Dim,Allocator>::reshape(const Shape<Dim>& shape) { - boost::array<int,Dim> extents; - for (std::size_t d = 0; d < Dim; d++) - extents[d] = static_cast<int>(shape[d]); - this->resize(extents); - return *this; - } - - template <typename T, std::size_t Dim, typename Allocator> - typename multi_array<T,Dim,Allocator>::template extents_gen<Dim> multi_array<T,Dim,Allocator>::shapeToExtents(const Shape<Dim> &shape) { - return utils::buildExtents(shape); - } - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>& multi_array<T,Dim,Allocator>::apply(const std::function<void(T&)>& func) { - T* data = this->origin(); - for (std::size_t k = 0; k < this->num_elements(); k++) { - func(data[k]); - } - return *this; - } - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>& multi_array<T,Dim,Allocator>::apply(const std::function<void(T&, const Index<Dim>&)>& func) { - hysop::Index<Dim> idx(this->shape()); - T* data = this->origin(); - for (std::size_t k = 0; k < this->num_elements(); k++) { - func(data[k], idx); - ++idx; - } - return *this; - } - - template <typename T, std::size_t Dim, typename Allocator> - template <typename Functor, typename Arg0, typename... Args> - multi_array<T,Dim,Allocator>& multi_array<T,Dim,Allocator>::apply(const Functor& func, Arg0&& farg0, Args&&... fargs) { - hysop::Index<Dim> idx(this->shape()); - T* data = this->origin(); - for (std::size_t k = 0; k < this->num_elements(); k++) { - func(data[k], idx, std::forward<Arg0>(farg0), std::forward<Args>(fargs)...); - ++idx; - } - return *this; - } - - template <typename T, std::size_t Dim, typename Allocator> - const multi_array<T,Dim,Allocator>& multi_array<T,Dim,Allocator>::print(const std::string& name, std::ostream& os, - unsigned int precision, unsigned int width) const { - auto S = this->super::shape(); - std::size_t id = 0; - - os << name << " = ["; - if(Dim==1 || Dim>3) { - for(std::size_t k=0; k<this->num_elements(); k++) { - T x = this->data()[id++]; - os << std::fixed << std::showpos << std::setprecision(precision) << std::setw(width) << x << " "; - } - } - else if(Dim==2) { - std::cout << std::endl; - for(std::size_t i=0; i<S[0]; i++) { - os << "\t["; - for(std::size_t j=0; j<S[1]; j++) { - T x = this->data()[id++]; - os << std::fixed << std::showpos << std::setprecision(precision) << std::setw(width) << x << " "; - } - os << "]" << std::endl; - } - } - else { - std::cout << std::endl; - for(std::size_t i=0; i<S[0]; i++) { - os << "\t[["; - for(std::size_t j=0; j<S[1]; j++) { - if(j>0) - os << "\t ["; - for(std::size_t k=0; k<S[2]; k++) { - T x = this->data()[id++]; - os << std::fixed << std::showpos << std::setprecision(precision) << std::setw(width) << x << " "; - } - if(j!=S[1]-1) - os << "]" << std::endl; - else - os << "]]," << std::endl; - } - } - } - os << "];" << std::endl; - return *this; - } - - /* boolean specific functions */ - template <typename T, std::size_t Dim, typename Allocator> - template <typename TT> - typename std::enable_if<std::is_same<TT,bool>::value, bool>::type multi_array<T,Dim,Allocator>::all() const { - for(std::size_t k=0; k<this->num_elements(); k++) { - if(!this->data()[k]) - return false; - } - return true; - } - - template <typename T, std::size_t Dim, typename Allocator> - template <typename TT> - typename std::enable_if<std::is_same<TT,bool>::value, bool>::type multi_array<T,Dim,Allocator>::any() const { - for(std::size_t k=0; k<this->num_elements(); k++) { - if(this->data()[k]) - return true; - } - return false; - } - - template <typename T, std::size_t Dim, typename Allocator> - template <typename TT> - typename std::enable_if<std::is_same<TT,bool>::value, bool>::type multi_array<T,Dim,Allocator>::none() const { - for(std::size_t k=0; k<this->num_elements(); k++) { - if(this->data()[k]) - return false; - } - return true; - } - - - } /* end of namespace data */ -} /* end of namespace hysop */ - -#undef ENABLE_IF_BOOL -#undef ENABLE_IF_REAL -#undef ENABLE_IF_COMPLEX - -#include "multi_array_ext.h" - -#endif /* end of include guard: HYSOP_MULTI_ARRAY_H */ diff --git a/src/hysop++/src/data/multi_array/const_multi_array_ref.h b/src/hysop++/src/data/multi_array/const_multi_array_ref.h deleted file mode 100644 index cc0a2f2c4..000000000 --- a/src/hysop++/src/data/multi_array/const_multi_array_ref.h +++ /dev/null @@ -1,53 +0,0 @@ - -#ifndef HYSOP_MULTI_ARRAY_H -#include "data/multi_array/multi_array.h" -#else - -#ifndef HYSOP_CONST_MULTI_ARRAY_REF_H -#define HYSOP_CONST_MULTI_ARRAY_REF_H - -namespace hysop { - namespace data { - - /* class hysop::data::multi_array */ - template <typename T, std::size_t Dim> - class const_multi_array_ref : public boost_const_multi_array_ref<T,Dim> { - static_assert(Dim>0, "Dim cannot be zero !"); - - private: - using super = boost_const_multi_array_ref<T,Dim>; - public: - PUBLIC_CLASS_TYPES() - - public: - const_multi_array_ref(const const_multi_array_ref<T,Dim>& ref) = default; - const_multi_array_ref& operator=(const const_multi_array_ref<T,Dim>& other) = default; - - const_multi_array_ref(const boost_const_multi_array_ref<T,Dim>& ref); - const_multi_array_ref& operator=(const boost_const_multi_array_ref<T,Dim>& other); - - public: - PUBLIC_CONST_REF_INTERFACE(SINGLE_ARG(const_multi_array_ref<T,Dim>)) - }; - - - /* Implementation */ - template <typename T, std::size_t Dim> - const_multi_array_ref<T,Dim>::const_multi_array_ref(const boost_const_multi_array_ref<T,Dim>& ref) : - super(ref) { - } - - template <typename T, std::size_t Dim> - const_multi_array_ref<T,Dim>& const_multi_array_ref<T,Dim>::operator=(const boost_const_multi_array_ref<T,Dim>& other) { - super::operator=(other); - return *this; - } - - CONST_REF_IMPLEMENTATION(SINGLE_ARG(const_multi_array_ref<T,Dim>), SINGLE_ARG(template <typename T, std::size_t Dim>)) - - } /* end of namespace data */ -} /* end of namespace hysop */ - -#endif /* end of include guard: HYSOP_CONST_MULTI_ARRAY_REF_H */ - -#endif /* end of MULTI_ARRAY include guard */ diff --git a/src/hysop++/src/data/multi_array/const_multi_array_view.h b/src/hysop++/src/data/multi_array/const_multi_array_view.h deleted file mode 100644 index 335433d8a..000000000 --- a/src/hysop++/src/data/multi_array/const_multi_array_view.h +++ /dev/null @@ -1,53 +0,0 @@ - -#ifndef HYSOP_MULTI_ARRAY_H -#include "data/multi_array/multi_array.h" -#else - -#ifndef HYSOP_CONST_MULTI_ARRAY_VIEW_H -#define HYSOP_CONST_MULTI_ARRAY_VIEW_H - -namespace hysop { - namespace data { - - /* class hysop::data::multi_array */ - template <typename T, std::size_t Dim> - class const_multi_array_view : public boost_const_multi_array_view<T,Dim> { - static_assert(Dim>0, "Dim cannot be zero !"); - - private: - using super = boost_const_multi_array_view<T,Dim>; - public: - PUBLIC_CLASS_TYPES() - - public: - const_multi_array_view(const const_multi_array_view<T,Dim>& view) = default; - const_multi_array_view& operator=(const const_multi_array_view<T,Dim>& other) = default; - - const_multi_array_view(const boost_const_multi_array_view<T,Dim>& view); - const_multi_array_view& operator=(const boost_const_multi_array_view<T,Dim>& other); - - public: - PUBLIC_CONST_VIEW_INTERFACE(SINGLE_ARG(const_multi_array_view<T,Dim>)) - }; - - - /* Implementation */ - template <typename T, std::size_t Dim> - const_multi_array_view<T,Dim>::const_multi_array_view(const boost_const_multi_array_view<T,Dim>& view) : - super(view) { - } - - template <typename T, std::size_t Dim> - const_multi_array_view<T,Dim>& const_multi_array_view<T,Dim>::operator=(const boost_const_multi_array_view<T,Dim>& other) { - super::operator=(other); - return *this; - } - - CONST_VIEW_IMPLEMENTATION(SINGLE_ARG(const_multi_array_view<T,Dim>), SINGLE_ARG(template <typename T, std::size_t Dim>)) - - } /* end of namespace data */ -} /* end of namespace hysop */ - -#endif /* end of include guard: HYSOP_CONST_MULTI_ARRAY_VIEW_H */ - -#endif /* end of MULTI_ARRAY include guard */ diff --git a/src/hysop++/src/data/multi_array/multi_array.h b/src/hysop++/src/data/multi_array/multi_array.h deleted file mode 100644 index 41746a7eb..000000000 --- a/src/hysop++/src/data/multi_array/multi_array.h +++ /dev/null @@ -1,52 +0,0 @@ - -#ifndef HYSOP_MULTI_ARRAY_H -#define HYSOP_MULTI_ARRAY_H - -#include "utils/utils.h" -#include "utils/default.h" -#include <boost/multi_array.hpp> - -/****************************************/ -/*** Hysop boost multi array wrapper ****/ -/****************************************/ - -namespace hysop { - namespace data { - - /* forward declaration of types */ - template <typename T, std::size_t Dim, typename Allocator = hysop::_default::allocator<T>> - class multi_array; - template <typename T, std::size_t Dim> - class multi_array_ref; - template <typename T, std::size_t Dim> - class const_multi_array_ref; - template <typename T, std::size_t Dim> - class multi_array_view; - template <typename T, std::size_t Dim> - class const_multi_array_view; - - template <typename T, std::size_t Dim, typename Allocator = hysop::_default::allocator<T>> - using boost_multi_array = boost::multi_array<T,Dim,Allocator>; - template <typename T, std::size_t Dim> - using boost_multi_array_ref = boost::multi_array_ref<T,Dim>; - template <typename T, std::size_t Dim> - using boost_const_multi_array_ref = boost::const_multi_array_ref<T,Dim>; - template <typename T, std::size_t Dim> - using boost_multi_array_view = boost::detail::multi_array::multi_array_view<T,Dim>; - template <typename T, std::size_t Dim> - using boost_const_multi_array_view = boost::detail::multi_array::const_multi_array_view<T,Dim>; - } -} - -#include "data/multi_array/multi_array_defines.h" - -#include "data/multi_array/const_multi_array_view.h" -#include "data/multi_array/multi_array_view.h" -#include "data/multi_array/const_multi_array_ref.h" -#include "data/multi_array/multi_array_ref.h" -#include "data/multi_array/multi_array_impl.h" -#include "data/multi_array/multi_array_ext.h" - -#include "data/multi_array/multi_array_clean.h" - -#endif /* end of include guard: HYSOP_MULTI_ARRAY_H */ diff --git a/src/hysop++/src/data/multi_array/multi_array_clean.h b/src/hysop++/src/data/multi_array/multi_array_clean.h deleted file mode 100644 index 0f8c988cc..000000000 --- a/src/hysop++/src/data/multi_array/multi_array_clean.h +++ /dev/null @@ -1,47 +0,0 @@ - -#ifndef HYSOP_MULTI_ARRAY_H -#include "data/multi_array/multi_array.h" -#else - -#ifndef HYSOP_MULTI_ARRAY_CLEAN_H -#define HYSOP_MULTI_ARRAY_CLEAN_H - -/* clean all macros used to generate hysop multiarray */ - -#undef SINGLE_ARG -#undef PUBLIC_CLASS_TYPES - -#undef ENABLE_IF_BOOL -#undef ENABLE_IF_REAL -#undef ENABLE_IF_COMPLEX - -#undef PUBLIC_COMMON_CONST_INTEFACE -#undef PUBLIC_CONST_REF_INTERFACE -#undef PUBLIC_CONST_VIEW_INTERFACE -#undef PUBLIC_COMMON_NON_CONST_INTERFACE -#undef PUBLIC_NON_CONST_REF_INTERFACE -#undef PUBLIC_NON_CONST_VIEW_INTERFACE - -#undef LOOP_VARNAME -#undef LOOP_OVER_ALL_REF_ELEMENTS -#undef REF_DATA_ACCESS -#undef LOOP_OVER_ALL_VIEW_ELEMENTS -#undef VIEW_DATA_ACCESS - -#undef COMMON_CONST_IMPLEMENTATION -#undef LOOP_DEPENDENT_CONST_IMPLEMENTATION -#undef CONST_REF_IMPL -#undef CONST_VIEW_IMPL -#undef CONST_REF_IMPLEMENTATION -#undef CONST_VIEW_IMPLEMENTATION - -#undef COMMON_NON_CONST_IMPLEMENTATION -#undef LOOP_DEPENDENT_NON_CONST_IMPLEMENTATION -#undef NON_CONST_REF_IMPL -#undef NON_CONST_VIEW_IMPL -#undef NON_CONST_REF_IMPLEMENTATION -#undef NON_CONST_VIEW_IMPLEMENTATION - -#endif /* end of include guard: MULTI_ARRAY_CLEAN_H */ - -#endif /* end of MULTI_ARRAY include guard */ diff --git a/src/hysop++/src/data/multi_array/multi_array_defines.h b/src/hysop++/src/data/multi_array/multi_array_defines.h deleted file mode 100644 index 1f8ac7fbe..000000000 --- a/src/hysop++/src/data/multi_array/multi_array_defines.h +++ /dev/null @@ -1,366 +0,0 @@ - -#ifndef HYSOP_MULTI_ARRAY_H -#include "data/multi_array/multi_array.h" -#else - -#ifndef HYSOP_MULTI_ARRAY_DEFINES_H -#define HYSOP_MULTI_ARRAY_DEFINES_H - -#include <algorithm> -#include <iostream> -#include <iomanip> -#include <cmath> - -#include "utils/utils.h" -#include "utils/types.h" -#include "data/index.h" -#include "fft/fftwComplex.h" - - -/* helper macros to generate all hysop multi_array wrappers */ -#define SINGLE_ARG(...) __VA_ARGS__ - -/* declaration of all public class types */ -#define PUBLIC_CLASS_TYPES() \ - template <typename Alloc> \ - using array = multi_array<T,Dim,Alloc>; \ - \ - using array_ref = multi_array_ref<T,Dim>; \ - using array_view = multi_array_view<T,Dim>; \ - using const_array_ref = const_multi_array_ref<T,Dim>; \ - using const_array_view = const_multi_array_view<T,Dim>; \ - \ - template <std::size_t NExtents> \ - using extents_gen = boost::detail::multi_array::extent_gen<NExtents>; \ - \ - template <std::size_t NumRanges, std::size_t NumDim> \ - using index_gen = boost::detail::multi_array::index_gen<NumRanges, NumDim>; \ - \ - using index_range = boost::multi_array_types::index_range; - - -/* various enable if macros */ -#define ENABLE_IF_BOOL(TYPE,DEFAULT) \ - template <typename TT DEFAULT> \ - typename std::enable_if< \ - std::is_same<TT,bool>::value \ - , TYPE>::type -#define ENABLE_IF_FFTW_REAL(TYPE,DEFAULT) \ - template <typename TT DEFAULT> \ - typename std::enable_if< \ - hysop::fft::is_fftw_supported_type<TT>::value \ - , TYPE>::type -#define ENABLE_IF_FFTW_COMPLEX(TYPE,DEFAULT) \ - template <typename TT DEFAULT> \ - typename std::enable_if< \ - hysop::fft::is_fftw_supported_complex_type<TT>::value \ - , TYPE>::type - -/* CLASS INTERFACES */ -/* public const common interfaces for views and referencess */ -#define PUBLIC_COMMON_CONST_INTERFACE(TYPENAME) \ - /* shape related */ \ - typename Shape<Dim>::type shape() const; \ - \ - /* print data */ \ - const TYPENAME& print(const std::string& name, std::ostream& os = std::cout, \ - unsigned int precision=2u, unsigned int width=6u) const; \ - \ - /* boolean array_view specific functions */ \ - ENABLE_IF_BOOL(bool,=T) all() const; \ - ENABLE_IF_BOOL(bool,=T) any() const; \ - ENABLE_IF_BOOL(bool,=T) none() const; - - -/* public const reference interface */ -#define PUBLIC_CONST_REF_INTERFACE(TYPENAME) \ - /* common const interface */ \ - PUBLIC_COMMON_CONST_INTERFACE(SINGLE_ARG(TYPENAME)) \ - /* real and complex data accessors, usefull for FFT like transforms */ \ - ENABLE_IF_FFTW_REAL (const T*,=T) rdata() const; \ - ENABLE_IF_FFTW_REAL (const typename fft::fftw_complex_type<T>::std_type*,=T) asStdComplexData() const; \ - ENABLE_IF_FFTW_REAL (const typename fft::fftw_complex_type<T>::fftw_type*,=T) asFftwComplexData() const; \ - ENABLE_IF_FFTW_COMPLEX(const T*,=T) cdata() const; \ - ENABLE_IF_FFTW_COMPLEX(const typename fft::fftw_complex_type<T>::std_type*,=T) std_cdata() const; \ - ENABLE_IF_FFTW_COMPLEX(const typename fft::fftw_complex_type<T>::fftw_type*,=T) fftw_cdata() const; \ - ENABLE_IF_FFTW_COMPLEX(const typename fft::fftw_complex_type<T>::value_type*,=T) asRealData() const; - - -/* public const view interface */ -#define PUBLIC_CONST_VIEW_INTERFACE(TYPENAME) \ - /* common const interface */ \ - PUBLIC_COMMON_CONST_INTERFACE(SINGLE_ARG(TYPENAME)) - - -/* non const interfaces */ -#define PUBLIC_COMMON_NON_CONST_INTERFACE(TYPENAME) \ - /* Apply function to all elements */ \ - TYPENAME& apply(const std::function<void(T&)>& func); \ - TYPENAME& apply(const std::function<void(T&, const Index<Dim>&)>& func); \ - template <typename Functor, typename Arg0, typename... Args> \ - TYPENAME& apply(const Functor& func, Arg0&& farg0, Args&&... fargs); - - -#define PUBLIC_NON_CONST_REF_INTERFACE(TYPENAME) \ - /* common non const interface */ \ - PUBLIC_COMMON_NON_CONST_INTERFACE(SINGLE_ARG(TYPENAME)) \ - /* real and complex data accessors, usefull for FFT like transforms */ \ - ENABLE_IF_FFTW_REAL(T*,=T) rdata(); \ - ENABLE_IF_FFTW_REAL(typename fft::fftw_complex_type<T>::std_type*,=T) asStdComplexData(); \ - ENABLE_IF_FFTW_REAL(typename fft::fftw_complex_type<T>::fftw_type*,=T) asFftwComplexData(); \ - ENABLE_IF_FFTW_COMPLEX(T*,=T) cdata(); \ - ENABLE_IF_FFTW_COMPLEX(typename fft::fftw_complex_type<T>::std_type*,=T) std_cdata(); \ - ENABLE_IF_FFTW_COMPLEX(typename fft::fftw_complex_type<T>::fftw_type*,=T) fftw_cdata(); \ - ENABLE_IF_FFTW_COMPLEX(typename fft::fftw_complex_type<T>::value_type*,=T) asRealData(); - - -#define PUBLIC_NON_CONST_VIEW_INTERFACE(TYPENAME) \ - /* common non const interface */ \ - PUBLIC_COMMON_NON_CONST_INTERFACE(SINGLE_ARG(TYPENAME)) - - - -/* CLASS IMPLEMENTATIONS */ - -/* Loop dependant implementation macros (references contain contiguous data but not the views) */ -#define LOOP_VARNAME multi_array_index -#define NO_DEFAULT_TEMPLATES - -/* A reference has a contiguous memory layout and can be accessed by data offsets */ -#define LOOP_OVER_ALL_REF_ELEMENTS(ARRAY) \ - for (std::size_t LOOP_VARNAME=0; LOOP_VARNAME<((ARRAY).num_elements()); LOOP_VARNAME++) - -#define REF_DATA_ACCESS(ARRAY) (ARRAY).data()[LOOP_VARNAME] - -/* A view is non a contiguous memory access and can be accessed only by index list */ -#define LOOP_OVER_ALL_VIEW_ELEMENTS(ARRAY) \ - Index<Dim> LOOP_VARNAME((ARRAY).shape()); \ - LOOP_VARNAME.setIndexToMinusOne(); \ - while((++LOOP_VARNAME)() != LOOP_VARNAME.maxId()) - -#define VIEW_DATA_ACCESS(ARRAY) (ARRAY).operator()(LOOP_VARNAME.ids()) - - -/* CONST IMPLEMENTATIONS */ -/* Common const implementation */ -#define COMMON_CONST_IMPLEMENTATION(TYPENAME,TEMPLATES) \ - /* shape related */ \ - TEMPLATES \ - typename Shape<Dim>::type TYPENAME::shape() const { \ - typename Shape<Dim>::type shape; \ - const std::size_t* extents = this->super::shape(); \ - for (std::size_t d = 0; d < Dim; d++) \ - shape[d] = static_cast<std::size_t>(extents[d]); \ - return shape; \ - } - -/* Loop dependant const implementation */ -#define LOOP_DEPENDENT_CONST_IMPLEMENTATION(TYPENAME,TEMPLATES,LOOP_OVER_ALL_ELEMENTS,DATA_ACCESS) \ - /* print data */ \ - TEMPLATES \ - const TYPENAME& TYPENAME::print(const std::string& name, std::ostream& os, \ - unsigned int precision, unsigned int width) const { \ - auto S = this->super::shape(); \ - std::size_t id = 0; \ - \ - os << name << " = ["; \ - if(Dim==1) { \ - for(std::size_t k=0; k<this->num_elements(); k++) { \ - T x = this->operator()(boost::array<std::size_t,1>{k}); \ - os << std::fixed << std::showpos << std::setprecision(precision) << std::setw(width) << x << " "; \ - } \ - } \ - else if(Dim==2) { \ - std::cout << std::endl; \ - for(std::size_t i=0; i<S[0]; i++) { \ - os << "\t["; \ - for(std::size_t j=0; j<S[1]; j++) { \ - T x = this->operator()(boost::array<std::size_t,2>{i,j}); \ - os << std::fixed << std::showpos << std::setprecision(precision) << std::setw(width) << x << " "; \ - } \ - os << "]" << std::endl; \ - } \ - } \ - else if(Dim==3) { \ - std::cout << std::endl; \ - for(std::size_t i=0; i<S[0]; i++) { \ - os << "\t[["; \ - for(std::size_t j=0; j<S[1]; j++) { \ - if(j>0) \ - os << "\t ["; \ - for(std::size_t k=0; k<S[2]; k++) { \ - T x = this->operator()(boost::array<std::size_t,3>{i,j,k}); \ - os << std::fixed << std::showpos << std::setprecision(precision) << std::setw(width) << x << " "; \ - } \ - if(j!=S[1]-1) \ - os << "]" << std::endl; \ - else \ - os << "]]," << std::endl; \ - } \ - } \ - } \ - else { \ - LOOP_OVER_ALL_ELEMENTS(*this) { \ - T x = DATA_ACCESS(*this); \ - os << std::fixed << std::showpos << std::setprecision(precision) << std::setw(width) << x << " "; \ - } \ - } \ - os << "];" << std::endl; \ - return *this; \ - } \ - \ - /* boolean array_view specific functions */ \ - TEMPLATES ENABLE_IF_BOOL(bool,NO_DEFAULT_TEMPLATES) TYPENAME::all() const { \ - LOOP_OVER_ALL_ELEMENTS(*this) { \ - const bool val = DATA_ACCESS(*this); \ - if(!val) \ - return false; \ - } \ - return true; \ - } \ - TEMPLATES ENABLE_IF_BOOL(bool,NO_DEFAULT_TEMPLATES) TYPENAME::any() const { \ - LOOP_OVER_ALL_ELEMENTS(*this) { \ - const bool val = DATA_ACCESS(*this); \ - if(val) \ - return true; \ - } \ - return false; \ - } \ - TEMPLATES ENABLE_IF_BOOL(bool,NO_DEFAULT_TEMPLATES) TYPENAME::none() const { \ - LOOP_OVER_ALL_ELEMENTS(*this) { \ - const bool val = DATA_ACCESS(*this); \ - if(val) \ - return false; \ - } \ - return true; \ - } - -/* Reference specific const implementation */ -#define CONST_REF_IMPL(TYPENAME,TEMPLATES) \ - TEMPLATES \ - ENABLE_IF_FFTW_REAL(const T*,NO_DEFAULT_TEMPLATES) TYPENAME::rdata() const { \ - return this->data(); \ - } \ - TEMPLATES \ - ENABLE_IF_FFTW_REAL(const typename fft::fftw_complex_type<T>::std_type*,NO_DEFAULT_TEMPLATES) TYPENAME::asStdComplexData() const { \ - return reinterpret_cast<const typename fft::fftw_complex_type<T>::std_type*>(this->data()); \ - } \ - TEMPLATES \ - ENABLE_IF_FFTW_REAL(const typename fft::fftw_complex_type<T>::fftw_type*,NO_DEFAULT_TEMPLATES) TYPENAME::asFftwComplexData() const { \ - return reinterpret_cast<const typename fft::fftw_complex_type<T>::fftw_type*>(this->data()); \ - } \ - TEMPLATES \ - ENABLE_IF_FFTW_COMPLEX(const T*,NO_DEFAULT_TEMPLATES) TYPENAME::cdata() const { \ - return this->data(); \ - } \ - TEMPLATES \ - ENABLE_IF_FFTW_COMPLEX(const typename fft::fftw_complex_type<T>::std_type*,NO_DEFAULT_TEMPLATES) TYPENAME::std_cdata() const { \ - return reinterpret_cast<const typename fft::fftw_complex_type<T>::std_type*>(this->data()); \ - } \ - TEMPLATES \ - ENABLE_IF_FFTW_COMPLEX(const typename fft::fftw_complex_type<T>::fftw_type*,NO_DEFAULT_TEMPLATES) TYPENAME::fftw_cdata() const { \ - return reinterpret_cast<const typename fft::fftw_complex_type<T>::fftw_type*>(this->data()); \ - } \ - TEMPLATES \ - ENABLE_IF_FFTW_COMPLEX(const typename fft::fftw_complex_type<T>::value_type*,NO_DEFAULT_TEMPLATES) TYPENAME::asRealData() const { \ - return reinterpret_cast<const typename fft::fftw_complex_type<T>::value_type*>(this->data()); \ - } - -/* View specific const implementation */ -#define CONST_VIEW_IMPL(TYPENAME,TEMPLATES) - -/* All reference const implementation */ -#define CONST_REF_IMPLEMENTATION(TYPENAME,TEMPLATES) \ - COMMON_CONST_IMPLEMENTATION(SINGLE_ARG(TYPENAME),SINGLE_ARG(TEMPLATES)) \ - LOOP_DEPENDENT_CONST_IMPLEMENTATION(SINGLE_ARG(TYPENAME),SINGLE_ARG(TEMPLATES),LOOP_OVER_ALL_REF_ELEMENTS,REF_DATA_ACCESS) \ - CONST_REF_IMPL(SINGLE_ARG(TYPENAME),SINGLE_ARG(TEMPLATES)) - -/* All view const implementation */ -#define CONST_VIEW_IMPLEMENTATION(TYPENAME,TEMPLATES) \ - COMMON_CONST_IMPLEMENTATION(SINGLE_ARG(TYPENAME),SINGLE_ARG(TEMPLATES)) \ - LOOP_DEPENDENT_CONST_IMPLEMENTATION(SINGLE_ARG(TYPENAME),SINGLE_ARG(TEMPLATES),LOOP_OVER_ALL_VIEW_ELEMENTS,VIEW_DATA_ACCESS) \ - CONST_VIEW_IMPL(SINGLE_ARG(TYPENAME),SINGLE_ARG(TEMPLATES)) - - - - -/* NON CONST IMPLEMENTATIONS */ -/* Common non const implementation */ -#define COMMON_NON_CONST_IMPLEMENTATION(TYPENAME,TEMPLATES) - -/* Loop dependant non const implementation */ -#define LOOP_DEPENDENT_NON_CONST_IMPLEMENTATION(TYPENAME,TEMPLATES,LOOP_OVER_ALL_ELEMENTS,DATA_ACCESS) \ - /* Apply function to all elements */ \ - TEMPLATES \ - TYPENAME& TYPENAME::apply(const std::function<void(T&)>& func) { \ - LOOP_OVER_ALL_ELEMENTS(*this) { \ - func( DATA_ACCESS(*this) ); \ - } \ - return *this; \ - } \ - TEMPLATES \ - TYPENAME& TYPENAME::apply(const std::function<void(T&, const Index<Dim>&)>& func) { \ - LOOP_OVER_ALL_VIEW_ELEMENTS(*this) { \ - func( VIEW_DATA_ACCESS(*this), LOOP_VARNAME ); \ - } \ - return *this; \ - } \ - TEMPLATES \ - template <typename Functor, typename Arg0, typename... Args> \ - TYPENAME& TYPENAME::apply(const Functor& func, Arg0&& farg0, Args&&... fargs) { \ - LOOP_OVER_ALL_VIEW_ELEMENTS(*this) { \ - func( VIEW_DATA_ACCESS(*this), LOOP_VARNAME, std::forward<Arg0>(farg0), std::forward<Args>(fargs)... ); \ - } \ - return *this; \ - } - -/* Reference specific non const implementation */ -#define NON_CONST_REF_IMPL(TYPENAME,TEMPLATES) \ - TEMPLATES \ - ENABLE_IF_FFTW_REAL(T*,NO_DEFAULT_TEMPLATES) TYPENAME::rdata() { \ - return this->data(); \ - } \ - TEMPLATES \ - ENABLE_IF_FFTW_REAL(typename fft::fftw_complex_type<T>::std_type*,NO_DEFAULT_TEMPLATES) TYPENAME::asStdComplexData() { \ - return reinterpret_cast<typename fft::fftw_complex_type<T>::std_type*>(this->data()); \ - } \ - TEMPLATES \ - ENABLE_IF_FFTW_REAL(typename fft::fftw_complex_type<T>::fftw_type*,NO_DEFAULT_TEMPLATES) TYPENAME::asFftwComplexData() { \ - return reinterpret_cast<typename fft::fftw_complex_type<T>::fftw_type*>(this->data()); \ - } \ - TEMPLATES \ - ENABLE_IF_FFTW_COMPLEX(T*,NO_DEFAULT_TEMPLATES) TYPENAME::cdata() { \ - return this->data(); \ - } \ - TEMPLATES \ - ENABLE_IF_FFTW_COMPLEX(typename fft::fftw_complex_type<T>::std_type*,NO_DEFAULT_TEMPLATES) TYPENAME::std_cdata() { \ - return reinterpret_cast<typename fft::fftw_complex_type<T>::std_type*>(this->data()); \ - } \ - TEMPLATES \ - ENABLE_IF_FFTW_COMPLEX(typename fft::fftw_complex_type<T>::fftw_type*,NO_DEFAULT_TEMPLATES) TYPENAME::fftw_cdata() { \ - return reinterpret_cast<typename fft::fftw_complex_type<T>::fftw_type*>(this->data()); \ - } \ - TEMPLATES \ - ENABLE_IF_FFTW_COMPLEX(typename fft::fftw_complex_type<T>::value_type*,NO_DEFAULT_TEMPLATES) TYPENAME::asRealData() { \ - return reinterpret_cast<typename fft::fftw_complex_type<T>::value_type*>(this->data()); \ - } - -/* View specific non const implementation */ -#define NON_CONST_VIEW_IMPL(TYPENAME,TEMPLATES) - -/* Reference specific non const implementation */ -#define NON_CONST_REF_IMPLEMENTATION(TYPENAME,TEMPLATES) \ - COMMON_NON_CONST_IMPLEMENTATION(SINGLE_ARG(TYPENAME),SINGLE_ARG(TEMPLATES)) \ - LOOP_DEPENDENT_NON_CONST_IMPLEMENTATION(SINGLE_ARG(TYPENAME),SINGLE_ARG(TEMPLATES),LOOP_OVER_ALL_REF_ELEMENTS,REF_DATA_ACCESS) \ - NON_CONST_REF_IMPL(SINGLE_ARG(TYPENAME),SINGLE_ARG(TEMPLATES)) - -/* View specific non const implementation */ -#define NON_CONST_VIEW_IMPLEMENTATION(TYPENAME,TEMPLATES) \ - COMMON_NON_CONST_IMPLEMENTATION(SINGLE_ARG(TYPENAME),SINGLE_ARG(TEMPLATES)) \ - LOOP_DEPENDENT_NON_CONST_IMPLEMENTATION(SINGLE_ARG(TYPENAME),SINGLE_ARG(TEMPLATES),LOOP_OVER_ALL_VIEW_ELEMENTS,VIEW_DATA_ACCESS) \ - NON_CONST_VIEW_IMPL(SINGLE_ARG(TYPENAME),SINGLE_ARG(TEMPLATES)) - - -#endif /* end of include guard: HYSOP_MULTI_ARRAY_DEFINES_H */ - -#endif /* end of MULTI_ARRAY include guard */ diff --git a/src/hysop++/src/data/multi_array/multi_array_ext.h b/src/hysop++/src/data/multi_array/multi_array_ext.h deleted file mode 100644 index da2f8f696..000000000 --- a/src/hysop++/src/data/multi_array/multi_array_ext.h +++ /dev/null @@ -1,247 +0,0 @@ - -#ifndef HYSOP_MULTI_ARRAY_H -#include "data/multi_array/multi_array.h" -#else - -#ifndef HYSOP_MULTI_ARRAY_EXT_H -#define HYSOP_MULTI_ARRAY_EXT_H - -namespace hysop { - namespace data { - - /* distances */ - template <typename T, std::size_t Dim> - T distance_L1(const const_multi_array_ref<T,Dim> &lhs, const const_multi_array_ref<T,Dim> &rhs); - template <typename T, std::size_t Dim> - T distance_L2(const const_multi_array_ref<T,Dim> &lhs, const const_multi_array_ref<T,Dim> &rhs); - template <typename T, std::size_t Dim> - T distance_Linf(const const_multi_array_ref<T,Dim> &lhs, const const_multi_array_ref<T,Dim> &rhs); - - /* unary operators */ - template <typename T, std::size_t Dim> - multi_array<T,Dim> operator+(const const_multi_array_ref<T,Dim>& arr); - template <typename T, std::size_t Dim> - multi_array<T,Dim> operator-(const const_multi_array_ref<T,Dim>& arr); - template <std::size_t Dim> - multi_array<bool,Dim> operator~(const const_multi_array_ref<bool,Dim>& arr); - - /* elementwise arithmetic operations */ - template <typename T, std::size_t Dim> - multi_array<T,Dim> operator-(const const_multi_array_ref<T,Dim>& lhs, const const_multi_array_ref<T,Dim>& rhs); - template <typename T, std::size_t Dim> - multi_array<T,Dim> operator+(const const_multi_array_ref<T,Dim>& lhs, const const_multi_array_ref<T,Dim>& rhs); - template <typename T, std::size_t Dim> - multi_array<T,Dim> operator*(const const_multi_array_ref<T,Dim>& lhs, const const_multi_array_ref<T,Dim>& rhs); - template <typename T, std::size_t Dim> - multi_array<T,Dim> operator/(const const_multi_array_ref<T,Dim>& lhs, const const_multi_array_ref<T,Dim>& rhs); - template <typename T, std::size_t Dim> - multi_array<T,Dim> operator%(const const_multi_array_ref<T,Dim>& lhs, const const_multi_array_ref<T,Dim>& rhs); - - /* elementwise boolean operations */ - template <typename T, std::size_t Dim> - multi_array<bool,Dim> operator& (const const_multi_array_ref<T,Dim>& lhs, const const_multi_array_ref<T,Dim>& rhs); - template <typename T, std::size_t Dim> - multi_array<bool,Dim> operator| (const const_multi_array_ref<T,Dim>& lhs, const const_multi_array_ref<T,Dim>& rhs); - template <typename T, std::size_t Dim> - multi_array<bool,Dim> operator^ (const const_multi_array_ref<T,Dim>& lhs, const const_multi_array_ref<T,Dim>& rhs); - - - /* element wise ordering test - near equality test for floating point types, see utils/utils.h::areEqual<T> */ - template <typename T, std::size_t Dim> - multi_array<bool,Dim> operator==(const const_multi_array_ref<T,Dim>& lhs, const const_multi_array_ref<T,Dim>& rhs); - template <typename T, std::size_t Dim> - multi_array<bool,Dim> operator!=(const const_multi_array_ref<T,Dim>& lhs, const const_multi_array_ref<T,Dim>& rhs); - template <typename T, std::size_t Dim> - multi_array<bool,Dim> operator>=(const const_multi_array_ref<T,Dim>& lhs, const const_multi_array_ref<T,Dim>& rhs); - template <typename T, std::size_t Dim> - multi_array<bool,Dim> operator<=(const const_multi_array_ref<T,Dim>& lhs, const const_multi_array_ref<T,Dim>& rhs); - template <typename T, std::size_t Dim> - multi_array<bool,Dim> operator> (const const_multi_array_ref<T,Dim>& lhs, const const_multi_array_ref<T,Dim>& rhs); - template <typename T, std::size_t Dim> - multi_array<bool,Dim> operator< (const const_multi_array_ref<T,Dim>& lhs, const const_multi_array_ref<T,Dim>& rhs); - - - - /* And all their view and rvalue references variants */ - /* Ref - Ref */ - /* Ref - View */ - /* View - Ref */ - /* View - View */ - /* */ - /* Rvalue - View */ - /* Rvalue - Ref */ - /* View - Rvalue */ - /* Ref - Rvalue */ - /* ... */ - - - /* Implementation */ - - #define CHECK_SHAPES(LHS,RHS) assert(LHS.shape() == RHS.shape()) - - #define BINARY_OP(TEMPLATES,T,R,RES,OPNAME,BINOP,LHS,RHS,LOOP_OVER_ALL_ELEMENTS,DATA_ACCESS,CREATE_BUFFER,FROM_BUFFER,RET_OP) \ - TEMPLATES \ - RES OPNAME(LHS lhs, RHS rhs) { \ - CHECK_SHAPES(lhs,rhs); \ - CREATE_BUFFER(FROM_BUFFER,R); \ - LOOP_OVER_ALL_ELEMENTS(lhs) { \ - const T& lhsVal = DATA_ACCESS(lhs); \ - const T& rhsVal = DATA_ACCESS(rhs); \ - BINOP; \ - } \ - return RET_OP(BUFFER_NAME); \ - } - - #define BINARY_OP_VIEW_VIEW(TEMPLATES,T,R,RET,OPNAME,BINOP,CREATE_BUFFER,RET_OP) \ - BINARY_OP(SINGLE_ARG(TEMPLATES),SINGLE_ARG(T),SINGLE_ARG(R),SINGLE_ARG(RET),OPNAME,SINGLE_ARG(BINOP),\ - VIEW(T),VIEW(T),LOOP_OVER_ALL_VIEW_ELEMENTS,VIEW_DATA_ACCESS,CREATE_BUFFER,lhs,RET_OP) - #define BINARY_OP_VIEW_REF(TEMPLATES,T,R,RET,OPNAME,BINOP,CREATE_BUFFER,RET_OP) \ - BINARY_OP(SINGLE_ARG(TEMPLATES),SINGLE_ARG(T),SINGLE_ARG(R),SINGLE_ARG(RET),OPNAME,SINGLE_ARG(BINOP),\ - VIEW(T),REF(T),LOOP_OVER_ALL_VIEW_ELEMENTS,VIEW_DATA_ACCESS,CREATE_BUFFER,lhs,RET_OP) - #define BINARY_OP_REF_VIEW(TEMPLATES,T,R,RET,OPNAME,BINOP,CREATE_BUFFER,RET_OP) \ - BINARY_OP(SINGLE_ARG(TEMPLATES),SINGLE_ARG(T),SINGLE_ARG(R),SINGLE_ARG(RET),OPNAME,SINGLE_ARG(BINOP),\ - REF(T),VIEW(T),LOOP_OVER_ALL_VIEW_ELEMENTS,VIEW_DATA_ACCESS,CREATE_BUFFER,lhs,RET_OP) - #define BINARY_OP_REF_REF(TEMPLATES,T,R,RET,OPNAME,BINOP,CREATE_BUFFER,RET_OP) \ - BINARY_OP(SINGLE_ARG(TEMPLATES),SINGLE_ARG(T),SINGLE_ARG(R),SINGLE_ARG(RET),OPNAME,SINGLE_ARG(BINOP),\ - REF(T),REF(T),LOOP_OVER_ALL_REF_ELEMENTS,REF_DATA_ACCESS,CREATE_BUFFER,lhs,RET_OP) - #define BINARY_OP_REF_RVALUE(TEMPLATES,T,R,RET,OPNAME,BINOP,CREATE_BUFFER,RET_OP) \ - BINARY_OP(SINGLE_ARG(TEMPLATES),SINGLE_ARG(T),SINGLE_ARG(R),SINGLE_ARG(RET),OPNAME,SINGLE_ARG(BINOP),\ - REF(T),RVALUE(T),LOOP_OVER_ALL_REF_ELEMENTS,REF_DATA_ACCESS,CREATE_BUFFER,rhs,RET_OP) - #define BINARY_OP_RVALUE_REF(TEMPLATES,T,R,RET,OPNAME,BINOP,CREATE_BUFFER,RET_OP) \ - BINARY_OP(SINGLE_ARG(TEMPLATES),SINGLE_ARG(T),SINGLE_ARG(R),SINGLE_ARG(RET),OPNAME,SINGLE_ARG(BINOP),\ - RVALUE(T),REF(T),LOOP_OVER_ALL_REF_ELEMENTS,REF_DATA_ACCESS,CREATE_BUFFER,lhs,RET_OP) - #define BINARY_OP_VIEW_RVALUE(TEMPLATES,T,R,RET,OPNAME,BINOP,CREATE_BUFFER,RET_OP) \ - BINARY_OP(SINGLE_ARG(TEMPLATES),SINGLE_ARG(T),SINGLE_ARG(R),SINGLE_ARG(RET),OPNAME,SINGLE_ARG(BINOP),\ - VIEW(T),RVALUE(T),LOOP_OVER_ALL_VIEW_ELEMENTS,VIEW_DATA_ACCESS,CREATE_BUFFER,rhs,RET_OP) - #define BINARY_OP_RVALUE_VIEW(TEMPLATES,T,R,RET,OPNAME,BINOP,CREATE_BUFFER,RET_OP) \ - BINARY_OP(SINGLE_ARG(TEMPLATES),SINGLE_ARG(T),SINGLE_ARG(R),SINGLE_ARG(RET),OPNAME,SINGLE_ARG(BINOP),\ - RVALUE(T),VIEW(T),LOOP_OVER_ALL_VIEW_ELEMENTS,VIEW_DATA_ACCESS,CREATE_BUFFER,lhs,RET_OP) - - #define LVALUE_BINARY_OPS(TEMPLATES,T,R,RET,OPNAME,BINOP,CREATE_BUFFER,RET_OP) \ - BINARY_OP_VIEW_VIEW(SINGLE_ARG(TEMPLATES),SINGLE_ARG(T),SINGLE_ARG(R),SINGLE_ARG(RET),OPNAME,SINGLE_ARG(BINOP),CREATE_BUFFER,RET_OP) \ - BINARY_OP_VIEW_REF(SINGLE_ARG(TEMPLATES),SINGLE_ARG(T),SINGLE_ARG(R),SINGLE_ARG(RET),OPNAME,SINGLE_ARG(BINOP),CREATE_BUFFER,RET_OP) \ - BINARY_OP_REF_VIEW(SINGLE_ARG(TEMPLATES),SINGLE_ARG(T),SINGLE_ARG(R),SINGLE_ARG(RET),OPNAME,SINGLE_ARG(BINOP),CREATE_BUFFER,RET_OP) \ - BINARY_OP_REF_REF(SINGLE_ARG(TEMPLATES),SINGLE_ARG(T),SINGLE_ARG(R),SINGLE_ARG(RET),OPNAME,SINGLE_ARG(BINOP),CREATE_BUFFER,RET_OP) - - #define RVALUE_BINARY_OPS(TEMPLATES,T,R,RET,OPNAME,BINOP,CREATE_BUFFER,RET_OP) \ - BINARY_OP_REF_RVALUE(SINGLE_ARG(TEMPLATES),SINGLE_ARG(T),SINGLE_ARG(R),SINGLE_ARG(RET),OPNAME,SINGLE_ARG(BINOP),CREATE_BUFFER,RET_OP) \ - BINARY_OP_RVALUE_REF(SINGLE_ARG(TEMPLATES),SINGLE_ARG(T),SINGLE_ARG(R),SINGLE_ARG(RET),OPNAME,SINGLE_ARG(BINOP),CREATE_BUFFER,RET_OP) \ - BINARY_OP_VIEW_RVALUE(SINGLE_ARG(TEMPLATES),SINGLE_ARG(T),SINGLE_ARG(R),SINGLE_ARG(RET),OPNAME,SINGLE_ARG(BINOP),CREATE_BUFFER,RET_OP) \ - BINARY_OP_RVALUE_VIEW(SINGLE_ARG(TEMPLATES),SINGLE_ARG(T),SINGLE_ARG(R),SINGLE_ARG(RET),OPNAME,SINGLE_ARG(BINOP),CREATE_BUFFER,RET_OP) - - - /* Code generator */ - #define BUFFER_NAME macro_generated_local_buffer - #define CREATE_MA_BUFFER(FROM_MA,R) multi_array<R,Dim> BUFFER_NAME(FROM_MA.shape()) - #define CREATE_R_BUFFER(FROM_MA,R) R BUFFER_NAME = R(0) - #define NO_MA_BUFFER(FROM_MA,R) multi_array<R,Dim>& BUFFER_NAME = FROM_MA - - #define SIMPLE_BINOP(OP) DATA_ACCESS(BUFFER_NAME) = ((lhsVal) OP (rhsVal)) - #define SIMPLE_FBINOP(FOP) DATA_ACCESS(BUFFER_NAME) = FOP((lhsVal),(rhsVal)) - #define SUP_OR_EQUAL() DATA_ACCESS(BUFFER_NAME) = (((lhsVal) > (rhsVal)) || hysop::utils::areEqual<T>((rhsVal),(lhsVal))) - #define INF_OR_EQUAL() DATA_ACCESS(BUFFER_NAME) = (((lhsVal) < (rhsVal)) || hysop::utils::areEqual<T>((rhsVal),(lhsVal))) - #define IDENTITY(X) (X) - - #define T1 SINGLE_ARG(template<std::size_t Dim>) - #define T1bis SINGLE_ARG(template<std::size_t Dim, typename Allocator>) - #define T2 SINGLE_ARG(template<typename T, std::size_t Dim>) - #define T3 SINGLE_ARG(template<typename T, std::size_t Dim, typename Allocator>) - #define VIEW(T) SINGLE_ARG(const const_multi_array_view<T,Dim>&) - #define REF(T) SINGLE_ARG(const const_multi_array_ref<T,Dim>&) - #define RVALUE(T) SINGLE_ARG(multi_array<T,Dim,Allocator>&&) - #define LVALUE(T) SINGLE_ARG(multi_array<T,Dim,Allocator>) - #define DLVALUE(T) SINGLE_ARG(multi_array<T,Dim>) - - - /* distances */ - LVALUE_BINARY_OPS(T2,T,T,T,distance_L1,\ - const T val = std::abs<T>(rhsVal-lhsVal); BUFFER_NAME += val,\ - CREATE_R_BUFFER,IDENTITY) - LVALUE_BINARY_OPS(T2,T,T,T,distance_L2,\ - const T val = std::abs<T>(rhsVal-lhsVal); BUFFER_NAME += val*val,\ - CREATE_R_BUFFER,std::sqrt) - LVALUE_BINARY_OPS(T2,T,T,T,distance_Linf,\ - SINGLE_ARG(const T val = std::abs<T>(rhsVal-lhsVal); BUFFER_NAME = std::max<T>(BUFFER_NAME,val)),\ - CREATE_R_BUFFER,IDENTITY) - - - /* elementwise arithmetic operations */ - LVALUE_BINARY_OPS(T2,T,T,DLVALUE(T),operator+,SIMPLE_BINOP(+),CREATE_MA_BUFFER,IDENTITY) - LVALUE_BINARY_OPS(T2,T,T,DLVALUE(T),operator-,SIMPLE_BINOP(-),CREATE_MA_BUFFER,IDENTITY) - LVALUE_BINARY_OPS(T2,T,T,DLVALUE(T),operator*,SIMPLE_BINOP(*),CREATE_MA_BUFFER,IDENTITY) - LVALUE_BINARY_OPS(T2,T,T,DLVALUE(T),operator/,SIMPLE_BINOP(/),CREATE_MA_BUFFER,IDENTITY) - LVALUE_BINARY_OPS(T2,T,T,DLVALUE(T),operator%,SIMPLE_BINOP(%),CREATE_MA_BUFFER,IDENTITY) - - RVALUE_BINARY_OPS(T3,T,T,LVALUE(T),operator+,SIMPLE_BINOP(+),NO_MA_BUFFER,IDENTITY) - RVALUE_BINARY_OPS(T3,T,T,LVALUE(T),operator-,SIMPLE_BINOP(-),NO_MA_BUFFER,IDENTITY) - RVALUE_BINARY_OPS(T3,T,T,LVALUE(T),operator*,SIMPLE_BINOP(*),NO_MA_BUFFER,IDENTITY) - RVALUE_BINARY_OPS(T3,T,T,LVALUE(T),operator/,SIMPLE_BINOP(/),NO_MA_BUFFER,IDENTITY) - RVALUE_BINARY_OPS(T3,T,T,LVALUE(T),operator%,SIMPLE_BINOP(%),NO_MA_BUFFER,IDENTITY) - - /* elementwise boolean like operations */ - LVALUE_BINARY_OPS(T2,T,bool,DLVALUE(bool),operator&,SIMPLE_BINOP(&),CREATE_MA_BUFFER,IDENTITY) - LVALUE_BINARY_OPS(T2,T,bool,DLVALUE(bool),operator|,SIMPLE_BINOP(|),CREATE_MA_BUFFER,IDENTITY) - LVALUE_BINARY_OPS(T2,T,bool,DLVALUE(bool),operator^,SIMPLE_BINOP(^),CREATE_MA_BUFFER,IDENTITY) - - RVALUE_BINARY_OPS(T1bis,bool,bool,LVALUE(bool),operator&,SIMPLE_BINOP(&),NO_MA_BUFFER,IDENTITY) - RVALUE_BINARY_OPS(T1bis,bool,bool,LVALUE(bool),operator|,SIMPLE_BINOP(|),NO_MA_BUFFER,IDENTITY) - RVALUE_BINARY_OPS(T1bis,bool,bool,LVALUE(bool),operator^,SIMPLE_BINOP(^),NO_MA_BUFFER,IDENTITY) - - /* element wise ordering test - near equality test for floating point types, see utils/utils.h::areEqual<T> */ - LVALUE_BINARY_OPS(T2,T,bool,DLVALUE(bool),operator==,SIMPLE_FBINOP(hysop::utils::areEqual<T>),CREATE_MA_BUFFER,IDENTITY) - LVALUE_BINARY_OPS(T2,T,bool,DLVALUE(bool),operator!=,SIMPLE_FBINOP(hysop::utils::areNotEqual<T>),CREATE_MA_BUFFER,IDENTITY) - LVALUE_BINARY_OPS(T2,T,bool,DLVALUE(bool),operator<,SIMPLE_BINOP(<),CREATE_MA_BUFFER,IDENTITY) - LVALUE_BINARY_OPS(T2,T,bool,DLVALUE(bool),operator>,SIMPLE_BINOP(>),CREATE_MA_BUFFER,IDENTITY) - LVALUE_BINARY_OPS(T2,T,bool,DLVALUE(bool),operator>=,SUP_OR_EQUAL(),CREATE_MA_BUFFER,IDENTITY) - LVALUE_BINARY_OPS(T2,T,bool,DLVALUE(bool),operator<=,INF_OR_EQUAL(),CREATE_MA_BUFFER,IDENTITY) - - /* Comparisson for booleans... */ - RVALUE_BINARY_OPS(T1bis,bool,bool,LVALUE(bool),operator==,SIMPLE_BINOP(==),NO_MA_BUFFER,IDENTITY) - RVALUE_BINARY_OPS(T1bis,bool,bool,LVALUE(bool),operator!=,SIMPLE_BINOP(!=),NO_MA_BUFFER,IDENTITY) - RVALUE_BINARY_OPS(T1bis,bool,bool,LVALUE(bool),operator<,SIMPLE_BINOP(<),NO_MA_BUFFER,IDENTITY) - RVALUE_BINARY_OPS(T1bis,bool,bool,LVALUE(bool),operator>,SIMPLE_BINOP(>),NO_MA_BUFFER,IDENTITY) - RVALUE_BINARY_OPS(T1bis,bool,bool,LVALUE(bool),operator>=,SIMPLE_BINOP(>=),NO_MA_BUFFER,IDENTITY) - RVALUE_BINARY_OPS(T1bis,bool,bool,LVALUE(bool),operator<=,SIMPLE_BINOP(<=),NO_MA_BUFFER,IDENTITY) - - /* clean macros */ - #undef LVALUE_BINARY_OPS - #undef RVALUE_BINARY_OPS - - #undef BINARY_OP_RVALUE_VIEW - #undef BINARY_OP_RVALUE_REF - #undef BINARY_OP_VIEW_RVALUE - #undef BINARY_OP_REF_RVALUE - - #undef BINARY_OP_REF_REF - #undef BINARY_OP_REF_VIEW - #undef BINARY_OP_VIEW_REF - #undef BINARY_OP_VIEW_VIEW - - #undef IDENTITY - #undef SIMPLE_BINOP - #undef SIMPLE_FBINOP - #undef BINARY_OP - - #undef DLVALUE - #undef LVALUE - #undef RVALUE - #undef REF - #undef VIEW - #undef T3 - #undef T2 - #undef T1bis - #undef T1 - - #undef NO_MA_BUFFER - #undef CREATE_R_BUFFER - #undef CREATE_MA_BUFFER - #undef CHECK_SHAPES - #undef BUFFER_NAME - - - } /* end of namespace data */ -} /* end of namespace hysop */ - -#endif /* end of include guard: HYSOP_MULTI_ARRAY_EXT_H */ - -#endif /* end of MULTI_ARRAY include guard */ diff --git a/src/hysop++/src/data/multi_array/multi_array_impl.h b/src/hysop++/src/data/multi_array/multi_array_impl.h deleted file mode 100644 index efb1b1c3b..000000000 --- a/src/hysop++/src/data/multi_array/multi_array_impl.h +++ /dev/null @@ -1,192 +0,0 @@ - -#ifndef HYSOP_MULTI_ARRAY_H -#include "data/multi_array/multi_array.h" -#else - -#ifndef HYSOP_MULTI_ARRAY_IMPL_H -#define HYSOP_MULTI_ARRAY_IMPL_H - -namespace hysop { - namespace data { - - /* class hysop::data::multi_array */ - template <typename T, std::size_t Dim, typename Allocator> - class multi_array : public boost_multi_array<T,Dim,Allocator> { - static_assert(Dim>0, "Dim cannot be zero !"); - - private: - using super = boost_multi_array<T,Dim,Allocator>; - public: - PUBLIC_CLASS_TYPES() - - public: - multi_array(const extents_gen<Dim>& extents = extents_gen<Dim>()); - multi_array(const typename Shape<Dim>::type& shape); - - multi_array(const multi_array& other); - multi_array(multi_array&& other); - - explicit multi_array(const array_ref& other); - explicit multi_array(const array_view& other); - explicit multi_array(const const_array_ref& other); - explicit multi_array(const const_array_view& other); - - explicit multi_array(const boost_multi_array<T,Dim,Allocator>& other); - explicit multi_array(const boost_multi_array_ref<T,Dim>& other); - explicit multi_array(const boost_multi_array_view<T,Dim>& other); - explicit multi_array(const boost_const_multi_array_ref<T,Dim>& other); - explicit multi_array(const boost_const_multi_array_view<T,Dim>& other); - explicit multi_array(boost_multi_array<T,Dim,Allocator>&& other); - - multi_array& operator=(const multi_array& other); - multi_array& operator=(const array_ref& ref); - multi_array& operator=(const array_view& view); - multi_array& operator=(const const_array_ref& ref); - multi_array& operator=(const const_array_view& view); - multi_array& operator=(multi_array&& other); - - operator array_ref(); - operator const_array_ref() const; - - public: - PUBLIC_CONST_REF_INTERFACE(SINGLE_ARG(multi_array<T,Dim,Allocator>)) - PUBLIC_NON_CONST_REF_INTERFACE(SINGLE_ARG(multi_array<T,Dim,Allocator>)) - - multi_array& reshape(const typename Shape<Dim>::type& shape); - - protected: - static extents_gen<Dim> shapeToExtents(const typename Shape<Dim>::type &shape); - }; - - - /* Implementation */ - - /* constructors */ - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const extents_gen<Dim>& extents): - boost_multi_array<T,Dim,Allocator>(extents) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const typename Shape<Dim>::type& shape): - boost_multi_array<T,Dim,Allocator>(shapeToExtents(shape)) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const multi_array& other): - boost_multi_array<T,Dim,Allocator>(static_cast<const boost_multi_array<T,Dim,Allocator>&>(other)) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const array_view& other): - boost_multi_array<T,Dim,Allocator>(static_cast<const boost_multi_array_view<T,Dim>&>(other)) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const const_array_view& other): - boost_multi_array<T,Dim,Allocator>(static_cast<const boost_const_multi_array_view<T,Dim>&>(other)) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const array_ref& other): - boost_multi_array<T,Dim,Allocator>(static_cast<const boost_multi_array_ref<T,Dim>&>(other)) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const const_array_ref& other): - boost_multi_array<T,Dim,Allocator>(static_cast<const boost_const_multi_array_ref<T,Dim>&>(other)) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(multi_array&& other): - boost_multi_array<T,Dim,Allocator>(static_cast<boost_multi_array<T,Dim,Allocator>&&>(other)) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const boost_multi_array_view<T,Dim>& other): - boost_multi_array<T,Dim,Allocator>(other) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const boost_const_multi_array_view<T,Dim>& other): - boost_multi_array<T,Dim,Allocator>(other) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const boost_multi_array_ref<T,Dim>& other): - boost_multi_array<T,Dim,Allocator>(other) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(const boost_const_multi_array_ref<T,Dim>& other): - boost_multi_array<T,Dim,Allocator>(other) {} - - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::multi_array(boost_multi_array<T,Dim,Allocator>&& other): - boost_multi_array<T,Dim,Allocator>(other) {} - - - /* operator = */ - /* cast obligatory to avoid shape() function aliasing */ - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>& multi_array<T,Dim,Allocator>::operator=(const multi_array<T,Dim,Allocator>& other) { - this->reshape(other.shape()); - super::operator=(dynamic_cast<const boost_multi_array<T,Dim,Allocator>&>(other)); - return *this; - } - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>& multi_array<T,Dim,Allocator>::operator=(const array_view& other) { - this->reshape(other.shape()); - super::operator=(dynamic_cast<const boost_multi_array_view<T,Dim>&>(other)); - return *this; - } - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>& multi_array<T,Dim,Allocator>::operator=(const const_array_view& other) { - this->reshape(other.shape()); - super::operator=(dynamic_cast<const boost_const_multi_array_view<T,Dim>&>(other)); - return *this; - } - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>& multi_array<T,Dim,Allocator>::operator=(const array_ref& other) { - this->reshape(other.shape()); - super::operator=(dynamic_cast<const boost_multi_array_ref<T,Dim>&>(other)); - return *this; - } - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>& multi_array<T,Dim,Allocator>::operator=(const const_array_ref& other) { - this->reshape(other.shape()); - super::operator=(dynamic_cast<const boost_const_multi_array_ref<T,Dim>&>(other)); - return *this; - } - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>& multi_array<T,Dim,Allocator>::operator=(multi_array&& other) { - super::operator=(other); - return *this; - } - - /* casting operators */ - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::operator multi_array_ref<T,Dim>() { - return static_cast<boost_multi_array_ref<T,Dim>>(*this); - } - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>::operator const_multi_array_ref<T,Dim>() const { - return static_cast<boost_const_multi_array_ref<T,Dim>>(*this); - } - - /* static members */ - template <typename T, std::size_t Dim, typename Allocator> - typename multi_array<T,Dim,Allocator>::template extents_gen<Dim> multi_array<T,Dim,Allocator>::shapeToExtents(const typename Shape<Dim>::type &shape) { - return utils::buildExtents(shape); - } - - /* multiarray const & non const reference implementation */ - CONST_REF_IMPLEMENTATION(SINGLE_ARG(multi_array<T,Dim,Allocator>), SINGLE_ARG(template <typename T, std::size_t Dim, typename Allocator>)) - NON_CONST_REF_IMPLEMENTATION(SINGLE_ARG(multi_array<T,Dim,Allocator>), SINGLE_ARG(template <typename T, std::size_t Dim, typename Allocator>)) - - /* multi array specific */ - template <typename T, std::size_t Dim, typename Allocator> - multi_array<T,Dim,Allocator>& multi_array<T,Dim,Allocator>::reshape(const typename Shape<Dim>::type& shape) { - boost::array<int,Dim> extents; - for (std::size_t d = 0; d < Dim; d++) - extents[d] = static_cast<int>(shape[d]); - this->resize(extents); - return *this; - } - - - } /* end of namespace data */ -} /* end of namespace hysop */ - -#endif /* end of include guard: HYSOP_MULTI_ARRAY_IMPL_H */ - -#endif /* end of MULTI_ARRAY include guard */ diff --git a/src/hysop++/src/data/multi_array/multi_array_ref.h b/src/hysop++/src/data/multi_array/multi_array_ref.h deleted file mode 100644 index 804185136..000000000 --- a/src/hysop++/src/data/multi_array/multi_array_ref.h +++ /dev/null @@ -1,70 +0,0 @@ - -#ifndef HYSOP_MULTI_ARRAY_H -#include "data/multi_array/multi_array.h" -#else - -#ifndef HYSOP_MULTI_ARRAY_REF_H -#define HYSOP_MULTI_ARRAY_REF_H - -namespace hysop { - namespace data { - - /* class hysop::data::multi_array */ - template <typename T, std::size_t Dim> - class multi_array_ref : public boost_multi_array_ref<T,Dim> { - static_assert(Dim>0, "Dim cannot be zero !"); - - private: - using super = boost_multi_array_ref<T,Dim>; - public: - PUBLIC_CLASS_TYPES() - - public: - multi_array_ref(T* base=nullptr, const extents_gen<Dim>& ranges = hysop::utils::buildExtents(std::array<std::size_t,Dim>{0})); - multi_array_ref(const multi_array_ref<T,Dim>& ref) = default; - multi_array_ref& operator=(const multi_array_ref<T,Dim>& other) = default; - - multi_array_ref(const boost_multi_array_ref<T,Dim>& ref); - multi_array_ref& operator=(const boost_multi_array_ref<T,Dim>& other); - - - operator const_array_ref() const; - - public: - PUBLIC_CONST_REF_INTERFACE(SINGLE_ARG(multi_array_ref<T,Dim>)) - PUBLIC_NON_CONST_REF_INTERFACE(SINGLE_ARG(multi_array_ref<T,Dim>)) - }; - - - /* Implementation */ - template <typename T, std::size_t Dim> - multi_array_ref<T,Dim>::multi_array_ref(T* base, const extents_gen<Dim>& ranges): - super(base,ranges) { - } - - template <typename T, std::size_t Dim> - multi_array_ref<T,Dim>::multi_array_ref(const boost_multi_array_ref<T,Dim>& ref) : - super(ref) { - } - - template <typename T, std::size_t Dim> - multi_array_ref<T,Dim>& multi_array_ref<T,Dim>::operator=(const boost_multi_array_ref<T,Dim>& other) { - super::operator=(other); - return *this; - } - - template <typename T, std::size_t Dim> - multi_array_ref<T,Dim>::operator const_array_ref() const { - return static_cast<boost_const_multi_array_ref<T,Dim>>(*this); - } - - CONST_REF_IMPLEMENTATION(SINGLE_ARG(multi_array_ref<T,Dim>), SINGLE_ARG(template <typename T, std::size_t Dim>)) - NON_CONST_REF_IMPLEMENTATION(SINGLE_ARG(multi_array_ref<T,Dim>), SINGLE_ARG(template <typename T, std::size_t Dim>)) - - } /* end of namespace data */ -} /* end of namespace hysop */ - - -#endif /* end of include guard: HYSOP_MULTI_ARRAY_REF_H */ - -#endif /* end of MULTI_ARRAY include guard */ diff --git a/src/hysop++/src/data/multi_array/multi_array_view.h b/src/hysop++/src/data/multi_array/multi_array_view.h deleted file mode 100644 index d2931c9b0..000000000 --- a/src/hysop++/src/data/multi_array/multi_array_view.h +++ /dev/null @@ -1,72 +0,0 @@ - -#ifndef HYSOP_MULTI_ARRAY_H -#include "data/multi_array/multi_array.h" -#else - -#ifndef HYSOP_MULTI_ARRAY_VIEW_H -#define HYSOP_MULTI_ARRAY_VIEW_H - -namespace hysop { - namespace data { - - /* class hysop::data::multi_array */ - template <typename T, std::size_t Dim> - class multi_array_view : public boost_multi_array_view<T,Dim> { - static_assert(Dim>0, "Dim cannot be zero !"); - - private: - using super = boost_multi_array_view<T,Dim>; - public: - PUBLIC_CLASS_TYPES() - - public: - multi_array_view(const multi_array_view<T,Dim>& view) = default; - multi_array_view& operator=(const multi_array_view<T,Dim>& other) = default; - - multi_array_view(const boost_multi_array_view<T,Dim>& view); - multi_array_view& operator=(const boost_multi_array_view<T,Dim>& other); - - operator const_array_view() const; - - public: - PUBLIC_CONST_VIEW_INTERFACE(SINGLE_ARG(multi_array_view<T,Dim>)) - PUBLIC_NON_CONST_VIEW_INTERFACE(SINGLE_ARG(multi_array_view<T,Dim>)) - }; - - - /* Implementation */ - - -// remove anoying boost warning -#if defined(__GNUG__) and !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - template <typename T, std::size_t Dim> - multi_array_view<T,Dim>::multi_array_view(const boost_multi_array_view<T,Dim>& view) : - super(view) { - } -#if defined(__GNUG__) and !defined(__clang__) -#pragma GCC diagnostic pop -#endif - - template <typename T, std::size_t Dim> - multi_array_view<T,Dim>& multi_array_view<T,Dim>::operator=(const boost_multi_array_view<T,Dim>& other) { - super::operator=(other); - return *this; - } - - template <typename T, std::size_t Dim> - multi_array_view<T,Dim>::operator const_array_view() const { - return static_cast<boost_const_multi_array_view<T,Dim>>(*this); - } - - CONST_VIEW_IMPLEMENTATION(SINGLE_ARG(multi_array_view<T,Dim>), SINGLE_ARG(template <typename T, std::size_t Dim>)) - NON_CONST_VIEW_IMPLEMENTATION(SINGLE_ARG(multi_array_view<T,Dim>), SINGLE_ARG(template <typename T, std::size_t Dim>)) - - } /* end of namespace data */ -} /* end of namespace hysop */ - -#endif /* end of include guard: HYSOP_MULTI_ARRAY_VIEW_H */ - -#endif /* end of MULTI_ARRAY include guard */ diff --git a/src/hysop++/src/detail/index_seq.h b/src/hysop++/src/detail/index_seq.h deleted file mode 100644 index e324244ab..000000000 --- a/src/hysop++/src/detail/index_seq.h +++ /dev/null @@ -1,42 +0,0 @@ - -#ifndef HYSOP_INDEX_SEQ_H -#define HYSOP_INDEX_SEQ_H - -namespace hysop { - namespace detail { - - template <int...> - struct index_seq {}; - - template <int k, std::size_t d, int... I> - struct constant_seq_impl { - typedef typename constant_seq_impl<k,d-1,k,I...>::type type; - }; - - template <int k, int... I> - struct constant_seq_impl<k,0,I...> { - typedef index_seq<I...> type; - }; - - template <std::size_t count, int step, int current, int... I> - struct index_seq_impl { - typedef typename index_seq_impl<count-1,step,current+step,I...,current>::type type; - }; - template <int step, int current, int... I> - struct index_seq_impl<0,step,current,I...> { - typedef index_seq<I...> type; - }; - - - template <std::size_t count, int i0=0, int step=1> - using index_seq_gen = typename index_seq_impl<count,step,i0>::type; - - template <int constant, std::size_t count> - using constant_seq_gen = typename constant_seq_impl<constant,count>::type; - } -} - - - -#endif /* end of include guard: HYSOP_INDEX_SEQ_H */ - diff --git a/src/hysop++/src/domain/boundary.cpp b/src/hysop++/src/domain/boundary.cpp deleted file mode 100644 index 4a3f862af..000000000 --- a/src/hysop++/src/domain/boundary.cpp +++ /dev/null @@ -1,26 +0,0 @@ - -#include "domain/boundary.h" - -namespace hysop { - namespace domain { - - static const char* boundary_strings[6] = { - "NONE", - "HOMOGENEOUS_DIRICHLET", - "HOMOGENEOUS_NEUMANN", - "DIRICHLET", - "NEUMANN", - "PERIODIC" - }; - - const char* toStringBoundary(Boundary bd) { - return boundary_strings[static_cast<int>(bd)+1]; - } - - std::ostream& operator<<(std::ostream& os, const Boundary& bd) { - os << toStringBoundary(bd); - return os; - } - - } -} diff --git a/src/hysop++/src/domain/boundary.h b/src/hysop++/src/domain/boundary.h deleted file mode 100644 index 9320085e0..000000000 --- a/src/hysop++/src/domain/boundary.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef HYSOP_BOUNDARY_H -#define HYSOP_BOUNDARY_H - -#include <iostream> - -namespace hysop { - namespace domain { - - enum class Boundary : int { - NONE = -1, - HOMOGENEOUS_DIRICHLET = 0, - HOMOGENEOUS_NEUMANN = 1, - DIRICHLET = 2, - NEUMANN = 3, - PERIODIC = 4 - }; - - const char* toStringBoundary(Boundary bd); - std::ostream& operator<<(std::ostream& os, const Boundary& bd); - } -} - -#endif /* end of include guard: HYSOP_BOUNDARY_H */ diff --git a/src/hysop++/src/domain/domain.h b/src/hysop++/src/domain/domain.h deleted file mode 100644 index 70d860ece..000000000 --- a/src/hysop++/src/domain/domain.h +++ /dev/null @@ -1,154 +0,0 @@ - -#ifndef HYSOP_DOMAIN_H -#define HYSOP_DOMAIN_H - -#include "data/multi_array/multi_array.h" -#include "utils/types.h" -#include "utils/utils.h" -#include "fft/fftDomainConfiguration.h" - -namespace hysop { - namespace domain { - - template <typename T, std::size_t Dim> - class Domain; - - template <typename T, std::size_t Dim> - std::ostream& operator<< (std::ostream& os, const Domain<T,Dim>& domain); - - template <typename T, std::size_t Dim> - class Domain { - public: - using DomainSize = std::array<T, Dim>; - using SpaceStep = std::array<T, Dim>; - using SpaceVariable = std::array<T, Dim>; - - public: - Domain() : - m_shape{0}, m_dataShape{0}, m_leftDataOffset{0}, - m_domainConfig(), m_domainSize{0}, m_spaceStep{0}, m_data() {} - - Domain(const typename Shape<Dim>::type& p_shape, const DomainConfiguration<Dim>& p_domainConfig, const DomainSize& p_domainSize) : - m_shape{0}, m_dataShape{0}, m_leftDataOffset{0}, - m_domainConfig(p_domainConfig), m_domainSize(p_domainSize), - m_spaceStep{0}, m_data() { - this->reshape(p_shape); - } - - Domain(Domain<T,Dim>&& other) = default; - Domain<T,Dim>& operator=(const Domain<T,Dim>& other) = default; - Domain<T,Dim>& operator=(Domain<T,Dim>&& other) = default; - - Domain<T,Dim>& reshape(const typename Shape<Dim>::type& p_domainShape) { - m_shape = p_domainShape; - m_domainConfig.getShapeConfiguration(m_shape, m_dataShape, m_leftDataOffset); - m_data.reshape(m_dataShape); - this->computeSpaceStep(); - return *this; - } - - Domain<T,Dim>& resize(const DomainSize& p_size) { - m_domainSize = p_size; - this->computeSpaceStep(); - return *this; - } - - Domain<T,Dim>& resetDomainConfiguration(const DomainConfiguration<Dim>& p_domainConfig) { - m_domainConfig = p_domainConfig; - this->reshape(m_shape); - return *this; - } - - Domain<T,Dim>& print(const std::string &p_name) { - m_data.print(p_name); - return *this; - } - - fft::FftDomainConfiguration<Dim> fftDomainConfiguration() const { - return fft::FftDomainConfiguration<Dim>(m_domainConfig); - } - - const typename Shape<Dim>::type& shape() const { return m_shape; } - const typename Shape<Dim>::type& dataShape() const { return m_dataShape; } - const SpaceStep& spaceStep() const { return m_spaceStep; } - const DomainSize& domainSize() const { return m_domainSize; } - const typename Offset<Dim>::type& leftDataOffset() const { return m_leftDataOffset; } - const DomainConfiguration<Dim> boundaryConfig() const { return m_domainConfig; } - - const hysop::multi_array<T,Dim>& data() const { return m_data; } - hysop::multi_array_ref<T,Dim> data() { return m_data; } - - - /* Apply f(X, fargs...) on the whole domain where X = [x_0, x_1, ..., x_{Dim-1}] is the space variable */ - /* The result of the Functor f should be convertible to domain real data type T */ - template <typename Functor, typename... Args> - Domain<T,Dim>& apply(const Functor& f, Args&&... fargs); - - T distance_L1(const Domain<T,Dim> &other) { - assert(this->dataShape() == other.dataShape()); - return hysop::data::distance_L1<T,Dim>(this->data(), other.data()); - } - T distance_L2(const Domain<T,Dim> &other) { - assert(this->dataShape() == other.dataShape()); - return hysop::data::distance_L2<T,Dim>(this->data(), other.data()); - } - T distance_Linf(const Domain<T,Dim> &other) { - assert(this->dataShape() == other.dataShape()); - return hysop::data::distance_Linf<T,Dim>(this->data(), other.data()); - } - std::tuple<T,T,T> distance(const Domain<T,Dim>& other) { - return std::tuple<T,T,T>(distance_L1(other), distance_L2(other), distance_Linf(other)); - } - - protected: - void computeSpaceStep() { - for (std::size_t d = 0; d < Dim; d++) { - //std::size_t N = ((m_domainConfig[d].first==domain::Boundary::PERIODIC && !m_domainConfig.includePeriodicBoundaries()) ? m_shape[d]-1 : m_shape[d]-1); - m_spaceStep[d] = m_domainSize[d] / (m_shape[d]-1); - } - } - - protected: - typename Shape<Dim>::type m_shape, m_dataShape; - typename Offset<Dim>::type m_leftDataOffset; - - DomainConfiguration<Dim> m_domainConfig; - DomainSize m_domainSize; - SpaceStep m_spaceStep; - - hysop::multi_array<T, Dim> m_data; - }; - - /* Apply f(X, args...) on the whole domain where X = [x_0, x_1, ..., x_{Dim-1}] is the space variable */ - template <typename T, std::size_t Dim> - template <typename Functor, typename... Args> - Domain<T,Dim>& Domain<T,Dim>::apply(const Functor& f, Args&&... fargs) { - hysop::Index<Dim> idx(m_dataShape); - std::array<T,Dim> X{0}; - T* data = m_data.origin(); - for (std::size_t k = 0; k < m_data.num_elements(); k++) { - data[k] = static_cast<T>(f(X, std::forward<Args>(fargs)...)); - ++idx; - for (std::size_t d = 0; d < Dim; d++) - X[d] = (idx[d]+m_leftDataOffset[d])*m_spaceStep[d]; - } - return *this; - } - - template <typename T, std::size_t Dim> - std::ostream& operator<< (std::ostream& os, const Domain<T,Dim>& domain) { - os << "== Domain ==" << std::endl; - os << "\tShape : " << domain.shape() << std::endl; - os << "\tSize : " << domain.domainSize() << std::endl; - os << "\tSpaceStep : " << domain.spaceStep() << std::endl; - os << domain.boundaryConfig(); - os << "\tLeftDataOffset: " << domain.leftDataOffset() << std::endl; - os << "\tDataShape : " << domain.dataShape() << std::endl; - return os; - } - - } -} - -#endif /* end of include guard: HYSOP_DOMAIN_H */ - diff --git a/src/hysop++/src/domain/domainConfiguration.h b/src/hysop++/src/domain/domainConfiguration.h deleted file mode 100644 index 3f1c7ded7..000000000 --- a/src/hysop++/src/domain/domainConfiguration.h +++ /dev/null @@ -1,100 +0,0 @@ - -#ifndef HYSOP_DOMAIN_CONFIGURATION_H -#define HYSOP_DOMAIN_CONFIGURATION_H - -#include <array> -#include <stdexcept> - -#include "utils/types.h" -#include "domain/boundary.h" -#include "detail/index_seq.h" - -namespace hysop { - namespace domain { - - template <std::size_t Dim> - class DomainConfiguration; - - template <std::size_t Dim> - std::ostream& operator<<(std::ostream& os, const DomainConfiguration<Dim>& config); - - template <std::size_t Dim> - class DomainConfiguration { - - public: - typedef std::pair<Boundary,Boundary> BoundaryPair; - typedef std::array<BoundaryPair,Dim> BoundaryArray; - public: - DomainConfiguration(const BoundaryArray& p_boundaries = defaultDomainBoundaries(), - //bool p_includeDirichletBoundaries = true, - bool p_includePeriodicBoundaries = true) : - m_boundaries(p_boundaries), - //m_includeDirichletBoundaries(p_includeDirichletBoundaries), - m_includePeriodicBoundaries(p_includePeriodicBoundaries) { - checkBoundaries(); - } - - const BoundaryArray& boundaries() const { return m_boundaries; } - //bool includeDirichletBoundaries() const { return m_includeDirichletBoundaries; } - bool includePeriodicBoundaries() const { return m_includePeriodicBoundaries; } - - const BoundaryPair& operator[](std::size_t k) const { return m_boundaries[k]; } - - void getShapeConfiguration(const typename Shape<Dim>::type &p_fullShape, typename Shape<Dim>::type &p_realShape, typename Offset<Dim>::type &p_leftOffset) const { - for (std::size_t d = 0; d < Dim; d++) { - const BoundaryPair& pair = m_boundaries[d]; - //bool hasDirichletLeftOffset = (pair.first == DIRICHLET || pair.first == HOMOGENEOUS_DIRICHLET); - //bool hasDirichletRightOffset = (pair.second == DIRICHLET || pair.second == HOMOGENEOUS_DIRICHLET); - //std::size_t dirichletLeftOffset = hasDirichletLeftOffset && !this->includeDirichletBoundaries(); - //std::size_t dirichletRightOffset = hasDirichletRightOffset && !this->includeDirichletBoundaries(); - bool hasPeriodicRightOffset = (pair.second == Boundary::PERIODIC); - std::size_t periodicRightOffset = hasPeriodicRightOffset && !this->includePeriodicBoundaries(); - std::size_t leftOffset = 0; - std::size_t rightOffset = periodicRightOffset; - if(p_fullShape[d] <= (leftOffset + rightOffset)) - throw std::runtime_error("Domain shape is to small on axe " + std::to_string(d) + " for prescribed boundaries !"); - p_leftOffset[d] = std::ptrdiff_t(leftOffset); - p_realShape[d] = p_fullShape[d] - leftOffset - rightOffset; - } - } - - protected: - void checkBoundaries() const { - for (std::size_t d = 0; d < Dim; d++) { - const BoundaryPair& pair = m_boundaries[d]; - if((pair.first == Boundary::PERIODIC) ^ (pair.second == Boundary::PERIODIC)) - throw std::runtime_error("Bad boundaries configuration on axe " + std::to_string(d) + " !"); - } - } - - #ifndef SWIG - template <int... I> - static const std::array<BoundaryPair, Dim> defaultDomainBoundariesImpl(hysop::detail::index_seq<I...>) { - const BoundaryPair defaultVal[1] = { std::make_pair(Boundary::NONE,Boundary::NONE) }; - return { defaultVal[I]..., }; - } - static const std::array<BoundaryPair, Dim> defaultDomainBoundaries() { - return defaultDomainBoundariesImpl(hysop::detail::constant_seq_gen<0,Dim>()); - } - #endif - - protected: - BoundaryArray m_boundaries; - bool m_includePeriodicBoundaries; - //bool m_includeDirichletBoundaries; - }; - - template <std::size_t Dim> - std::ostream& operator<<(std::ostream& os, const DomainConfiguration<Dim>& config) { - os << "== DomainConfiguration<Dim=" << std::to_string(Dim) << "> ==" << std::endl; - for (std::size_t d = 0; d < Dim; d++) - os << "\taxe[" << d << "]: " << config[d].first << "/" << config[d].second << std::endl; - //os << "\tDirichlet boundaries included ? " << std::boolalpha << config.includeDirichletBoundaries() << std::endl; - os << "\tPeriodic boundaries included ? " << std::boolalpha << config.includePeriodicBoundaries() << std::endl; - return os; - } - - } -} - -#endif /* end of include guard: HYSOP_DOMAIN_CONFIGURATION_H */ diff --git a/src/hysop++/src/fft/extension.cpp b/src/hysop++/src/fft/extension.cpp deleted file mode 100644 index 6f2a67e5e..000000000 --- a/src/hysop++/src/fft/extension.cpp +++ /dev/null @@ -1,24 +0,0 @@ - -#include "fft/extension.h" - -namespace hysop { - namespace fft { - - static const char* extension_strings[4] { - "NONE", - "EVEN", - "ODD", - "PERIODIC" - }; - - const char* toStringExtension(Extension ext) { - return extension_strings[static_cast<int>(ext)+1]; - } - - std::ostream& operator<<(std::ostream& os, const Extension& ext) { - os << toStringExtension(ext); - return os; - } - - } -} diff --git a/src/hysop++/src/fft/extension.h b/src/hysop++/src/fft/extension.h deleted file mode 100644 index 5aaba36f2..000000000 --- a/src/hysop++/src/fft/extension.h +++ /dev/null @@ -1,23 +0,0 @@ - -#ifndef FFT_EXTENSION_H -#define FFT_EXTENSION_H - -#include <ostream> - -namespace hysop { - namespace fft { - - enum class Extension : int { - NONE=-1, - EVEN=0, - ODD=1, - PERIODIC=2 - }; - - const char* toStringExtension(Extension ext); - std::ostream& operator<<(std::ostream& os, const Extension& ext); - } -} - - -#endif /* end of include guard: FFT_EXTENSION_H */ diff --git a/src/hysop++/src/fft/fftDomainConfiguration.h b/src/hysop++/src/fft/fftDomainConfiguration.h deleted file mode 100644 index 57f014d63..000000000 --- a/src/hysop++/src/fft/fftDomainConfiguration.h +++ /dev/null @@ -1,114 +0,0 @@ - -#ifndef HYSOP_FFTDOMAINCONFIGURATION_H -#define HYSOP_FFTDOMAINCONFIGURATION_H - -#include "utils/defines.h" -#include "domain/domainConfiguration.h" -#include "fft/extension.h" - -namespace hysop { - namespace fft { - - template <std::size_t Dim> - class FftDomainConfiguration; - - template <std::size_t Dim> - std::ostream& operator<<(std::ostream& os, const FftDomainConfiguration<Dim>& config); - - template <std::size_t Dim> - class FftDomainConfiguration { - - public: - typedef typename domain::DomainConfiguration<Dim>::BoundaryPair BoundaryPair; - typedef typename domain::DomainConfiguration<Dim>::BoundaryArray BoundaryArray; - typedef std::pair<fft::Extension,fft::Extension> ExtensionPair; - typedef std::array<ExtensionPair,Dim> ExtensionArray; - public: - FftDomainConfiguration(const ExtensionArray& p_extensions, bool p_includePeriodicBoundaries) : - m_extensions(p_extensions), m_includePeriodicBoundaries(p_includePeriodicBoundaries) { - } - - FftDomainConfiguration(const domain::DomainConfiguration<Dim>& p_domain): - m_extensions(boundariesToExtensions(p_domain.boundaries())), - m_includePeriodicBoundaries(p_domain.includePeriodicBoundaries()) { - } - - const ExtensionArray& extensions() const { return m_extensions; } - bool includePeriodicBoundaries() const { return m_includePeriodicBoundaries; } - - ExtensionPair operator[](std::size_t k) const { - return m_extensions[k]; - } - - domain::DomainConfiguration<Dim> boundariesConfiguration() const { - return domain::DomainConfiguration<Dim>(fftExtensionsToBoundaries(m_extensions), m_includePeriodicBoundaries); - } - - static BoundaryArray fftExtensionsToBoundaries(const ExtensionArray& extArray) { - BoundaryArray bdArray; - for(std::size_t d=0; d<Dim; d++) { - const ExtensionPair& extPair = extArray[d]; - bdArray[d] = std::make_pair(fftExtensionToBoundary(extPair.first), fftExtensionToBoundary(extPair.second)); - } - return bdArray; - } - - static ExtensionArray boundariesToExtensions(const BoundaryArray& bdArray) { - ExtensionArray extArray; - for(std::size_t d=0; d<Dim; d++) { - const BoundaryPair& bdPair = bdArray[d]; - extArray[d] = std::make_pair(boundaryToExtension(bdPair.first), boundaryToExtension(bdPair.second)); - } - return extArray; - } - - static domain::Boundary fftExtensionToBoundary(fft::Extension ext) { - switch(ext) { - case(fft::Extension::PERIODIC): - return domain::Boundary::PERIODIC; - case(fft::Extension::EVEN): - return domain::Boundary::HOMOGENEOUS_DIRICHLET; - case(fft::Extension::ODD): - return domain::Boundary::HOMOGENEOUS_NEUMANN; - case(fft::Extension::NONE): - return domain::Boundary::NONE; - default: - NOT_IMPLEMENTED_YET; - } - } - - static fft::Extension boundaryToExtension(domain::Boundary bd) { - switch(bd) { - case(domain::Boundary::PERIODIC): - return fft::Extension::PERIODIC; - case(domain::Boundary::HOMOGENEOUS_DIRICHLET): - return fft::Extension::EVEN; - case(domain::Boundary::HOMOGENEOUS_NEUMANN): - return fft::Extension::ODD; - case(domain::Boundary::NONE): - return fft::Extension::NONE; - //throw std::runtime_error("Cannot build a FftDomainConfiguration based on a boundary of type 'NONE' !"); - default: - NOT_IMPLEMENTED_YET; - } - } - - protected: - ExtensionArray m_extensions; - bool m_includePeriodicBoundaries; - }; - - template <std::size_t Dim> - std::ostream& operator<<(std::ostream& os, const FftDomainConfiguration<Dim>& config) { - os << "== FftDomainConfiguration<Dim=" << std::to_string(Dim) << "> ==" << std::endl; - for (std::size_t d = 0; d < Dim; d++) - os << "\taxe[" << d << "]: " << config[d].first << "/" << config[d].second; - os << "\tPeriodic boundaries included ?" << std::boolalpha << config.includePeriodicBoundaries() << std::endl; - return os; - } - - } -} - -#endif /* end of include guard: HYSOP_FFTDOMAINCONFIGURATION_H */ - diff --git a/src/hysop++/src/fft/fftw3.cpp b/src/hysop++/src/fft/fftw3.cpp deleted file mode 100644 index 25a877c87..000000000 --- a/src/hysop++/src/fft/fftw3.cpp +++ /dev/null @@ -1,40 +0,0 @@ - -#include "fft/fftw3.h" - -namespace hysop { - namespace fft { - template struct Fftw3<float>; - template struct Fftw3<double>; - template struct Fftw3<long double>; - #ifdef HAS_QUADMATHS - template struct Fftw3<__float128>; - #endif - } -} - -/* needed for swig to avoid undefined reference link error */ -#if !defined(FFTW_HAS_FFTW3F_THREADS) || !defined(FFTW_HAS_FFTW3F_OMP) - int fftwf_init_threads() { return 0; } - void fftwf_plan_with_nthreads(int) {} - void fftwf_cleanup_threads() {} -#endif - -#if !defined(FFTW_HAS_FFTW3D_THREADS) || !defined(FFTW_HAS_FFTW3D_OMP) - int fftw_init_threads() { return 0; } - void fftw_plan_with_nthreads(int) {} - void fftw_cleanup_threads() {} -#endif - -#if !defined(FFTW_HAS_FFTW3L_THREADS) || !defined(FFTW_HAS_FFTW3L_OMP) - int fftwl_init_threads() { return 0; } - void fftwl_plan_with_nthreads(int) {} - void fftwl_cleanup_threads() {} -#endif - -#ifdef HAS_QUADMATHS - #if !defined(FFTW_HAS_FFTW3Q_THREADS) || !defined(FFTW_HAS_FFTW3Q_OMP) - int fftwq_init_threads() { return 0; } - void fftwq_plan_with_nthreads(int) {} - void fftwq_cleanup_threads() {} - #endif -#endif diff --git a/src/hysop++/src/fft/fftw3.h b/src/hysop++/src/fft/fftw3.h deleted file mode 100644 index e71a137c5..000000000 --- a/src/hysop++/src/fft/fftw3.h +++ /dev/null @@ -1,534 +0,0 @@ - -#ifndef HYSOP_FFTW3_H -#define HYSOP_FFTW3_H - -#include <complex> -#include <stdexcept> -#include <fftw3.h> - -#ifdef HAS_QUADMATHS -#include "maths/quad_maths.h" -#endif - -/* */ -/* fftw3 c++ wrapper based on original macros in <fftw3.h> */ -/* */ - -/* macros normally already defined in <fftw3.h> */ -#ifndef FFTW_CONCAT -#define FFTW_CONCAT(prefix, name) prefix ## name -#endif -#ifndef FFTW_MANGLE_FLOAT -#define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name) -#endif -#ifndef FFTW_MANGLE_LONG_DOUBLE -#define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name) -#endif -#ifndef FFTW_MANGLE_QUAD -#define FFTW_MANGLE_QUAD(name) FFTW_CONCAT(fftwq_, name) -#endif -/***********************************************/ - -#undef FFTW_MANGLE_DOUBLE -#define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(::fftw_, name) - -/* prefix for function wrappers inside the class */ -#define FFTW_MANGLE_CLASS(name) FFTW_CONCAT(fftw_, name) - -/* macro used to generate a full template specialisation of class Fftw3 for each type */ -#define FFTW_DEFINE_CXX_API(X, Y, REAL, has_thread_support) \ -template <> \ - struct Fftw3<REAL> { \ - typedef REAL R; \ - typedef Y(complex) C; \ - typedef Y(plan) plan; \ - typedef Y(iodim) iodim; \ - typedef Y(iodim64) iodim64; \ - typedef Y(r2r_kind) r2r_kind; \ - typedef Y(read_char_func) read_char_func; \ - typedef Y(write_char_func) write_char_func; \ - typedef std::complex<REAL> stdC; \ - \ - void X(execute)(const plan p) const { \ - Y(execute)(p); \ - } \ - \ - plan X(plan_dft)(int rank, const int *n, \ - C *in, C *out, int sign, unsigned int flags) const { \ - return Y(plan_dft)(rank, n, in, out, sign, flags); \ - } \ - \ - plan X(plan_dft_1d)(int n, C *in, C *out, int sign, \ - unsigned int flags) const { \ - return Y(plan_dft_1d)(n, in, out, sign, flags); \ - } \ - plan X(plan_dft_2d)(int n0, int n1, \ - C *in, C *out, int sign, unsigned int flags) const { \ - return Y(plan_dft_2d)(n0, n1, in, out, sign, flags); \ - } \ - plan X(plan_dft_3d)(int n0, int n1, int n2, \ - C *in, C *out, int sign, unsigned int flags) const { \ - return Y(plan_dft_3d)(n0, n1, n2, in, out, sign, flags); \ - } \ - \ - plan X(plan_many_dft)(int rank, const int *n, \ - int howmany, \ - C *in, const int *inembed, \ - int istride, int idist, \ - C *out, const int *onembed, \ - int ostride, int odist, \ - int sign, unsigned int flags) const { \ - return Y(plan_many_dft)(rank, n, howmany, in, inembed, istride, idist, out, onembed, ostride, odist, sign, flags); \ - } \ - \ - plan X(plan_guru_dft)(int rank, const iodim *dims, \ - int howmany_rank, \ - const iodim *howmany_dims, \ - C *in, C *out, \ - int sign, unsigned int flags) const { \ - return Y(plan_guru_dft)(rank, dims, howmany_rank, howmany_dims, in, out, sign, flags); \ - } \ - plan X(plan_guru_split_dft)(int rank, const iodim *dims, \ - int howmany_rank, \ - const iodim *howmany_dims, \ - R *ri, R *ii, R *ro, R *io, \ - unsigned int flags) const { \ - return Y(plan_guru_split_dft)(rank, dims, howmany_rank, howmany_dims, ri, ii, ro, io, flags); \ - } \ - \ - plan X(plan_guru64_dft)(int rank, \ - const iodim64 *dims, \ - int howmany_rank, \ - const iodim64 *howmany_dims, \ - C *in, C *out, \ - int sign, unsigned int flags) const { \ - return Y(plan_guru64_dft)(rank, dims, howmany_rank, howmany_dims, in, out, sign, flags); \ - } \ - plan X(plan_guru64_split_dft)(int rank, \ - const iodim64 *dims, \ - int howmany_rank, \ - const iodim64 *howmany_dims, \ - R *ri, R *ii, R *ro, R *io, \ - unsigned int flags) const { \ - return Y(plan_guru64_split_dft)(rank, dims, howmany_rank, howmany_dims, ri, ii, ro, io, flags); \ - } \ - \ - void X(execute_dft)(const plan p, C *in, C *out) const { \ - Y(execute_dft)(p, in, out); \ - } \ - void X(execute_split_dft)(const plan p, R *ri, R *ii, R *ro, R *io) const { \ - Y(execute_split_dft)(p, ri, ii, ro, io); \ - } \ - \ - plan X(plan_many_dft_r2c)(int rank, const int *n, \ - int howmany, \ - R *in, const int *inembed, \ - int istride, int idist, \ - C *out, const int *onembed, \ - int ostride, int odist, \ - unsigned int flags) const { \ - return Y(plan_many_dft_r2c)(rank, n, howmany, in, inembed, istride, idist, out, onembed, ostride, odist, flags); \ - } \ - \ - plan X(plan_dft_r2c)(int rank, const int *n, \ - R *in, C *out, unsigned int flags) const { \ - return Y(plan_dft_r2c)(rank, n, in, out, flags); \ - } \ - \ - plan X(plan_dft_r2c_1d)(int n,R *in,C *out,unsigned int flags) const { \ - return Y(plan_dft_r2c_1d)(n,in,out,flags); \ - } \ - plan X(plan_dft_r2c_2d)(int n0, int n1, \ - R *in, C *out, unsigned int flags) const { \ - return Y(plan_dft_r2c_2d)(n0, n1, in, out, flags); \ - } \ - plan X(plan_dft_r2c_3d)(int n0, int n1, \ - int n2, \ - R *in, C *out, unsigned int flags) const { \ - return Y(plan_dft_r2c_3d)(n0, n1, n2, in, out, flags); \ - } \ - \ - \ - plan X(plan_many_dft_c2r)(int rank, const int *n, \ - int howmany, \ - C *in, const int *inembed, \ - int istride, int idist, \ - R *out, const int *onembed, \ - int ostride, int odist, \ - unsigned int flags) const { \ - return Y(plan_many_dft_c2r)(rank, n, howmany, in, inembed, istride, idist, out, onembed, ostride, odist, flags); \ - } \ - \ - plan X(plan_dft_c2r)(int rank, const int *n, \ - C *in, R *out, unsigned int flags) const { \ - return Y(plan_dft_c2r)(rank, n, in, out, flags); \ - } \ - \ - plan X(plan_dft_c2r_1d)(int n,C *in,R *out,unsigned int flags) const { \ - return Y(plan_dft_c2r_1d)(n,in,out,flags); \ - } \ - plan X(plan_dft_c2r_2d)(int n0, int n1, \ - C *in, R *out, unsigned int flags) const { \ - return Y(plan_dft_c2r_2d)(n0, n1, in, out, flags); \ - } \ - plan X(plan_dft_c2r_3d)(int n0, int n1, \ - int n2, \ - C *in, R *out, unsigned int flags) const { \ - return Y(plan_dft_c2r_3d)(n0, n1, n2, in, out, flags); \ - } \ - \ - plan X(plan_guru_dft_r2c)(int rank, const iodim *dims, \ - int howmany_rank, \ - const iodim *howmany_dims, \ - R *in, C *out, \ - unsigned int flags) const { \ - return Y(plan_guru_dft_r2c)(rank, dims, howmany_rank, howmany_dims, in, out, flags); \ - } \ - plan X(plan_guru_dft_c2r)(int rank, const iodim *dims, \ - int howmany_rank, \ - const iodim *howmany_dims, \ - C *in, R *out, \ - unsigned int flags) const { \ - return Y(plan_guru_dft_c2r)(rank, dims, howmany_rank, howmany_dims, in, out, flags); \ - } \ - \ - plan X(plan_guru_split_dft_r2c)( \ - int rank, const iodim *dims, \ - int howmany_rank, \ - const iodim *howmany_dims, \ - R *in, R *ro, R *io, \ - unsigned int flags) const { \ - return Y(plan_guru_split_dft_r2c)( rank, dims, howmany_rank, howmany_dims, in, ro, io, flags); \ - } \ - plan X(plan_guru_split_dft_c2r)( \ - int rank, const iodim *dims, \ - int howmany_rank, \ - const iodim *howmany_dims, \ - R *ri, R *ii, R *out, \ - unsigned int flags) const { \ - return Y(plan_guru_split_dft_c2r)( rank, dims, howmany_rank, howmany_dims, ri, ii, out, flags); \ - } \ - \ - plan X(plan_guru64_dft_r2c)(int rank, \ - const iodim64 *dims, \ - int howmany_rank, \ - const iodim64 *howmany_dims, \ - R *in, C *out, \ - unsigned int flags) const { \ - return Y(plan_guru64_dft_r2c)(rank, dims, howmany_rank, howmany_dims, in, out, flags); \ - } \ - plan X(plan_guru64_dft_c2r)(int rank, \ - const iodim64 *dims, \ - int howmany_rank, \ - const iodim64 *howmany_dims, \ - C *in, R *out, \ - unsigned int flags) const { \ - return Y(plan_guru64_dft_c2r)(rank, dims, howmany_rank, howmany_dims, in, out, flags); \ - } \ - \ - plan X(plan_guru64_split_dft_r2c)( \ - int rank, const iodim64 *dims, \ - int howmany_rank, \ - const iodim64 *howmany_dims, \ - R *in, R *ro, R *io, \ - unsigned int flags) const { \ - return Y(plan_guru64_split_dft_r2c)( rank, dims, howmany_rank, howmany_dims, in, ro, io, flags); \ - } \ - plan X(plan_guru64_split_dft_c2r)( \ - int rank, const iodim64 *dims, \ - int howmany_rank, \ - const iodim64 *howmany_dims, \ - R *ri, R *ii, R *out, \ - unsigned int flags) const { \ - return Y(plan_guru64_split_dft_c2r)( rank, dims, howmany_rank, howmany_dims, ri, ii, out, flags); \ - } \ - \ - void X(execute_dft_r2c)(const plan p, R *in, C *out) const { \ - Y(execute_dft_r2c)(p, in, out); \ - } \ - void X(execute_dft_c2r)(const plan p, C *in, R *out) const { \ - Y(execute_dft_c2r)(p, in, out); \ - } \ - \ - void X(execute_split_dft_r2c)(const plan p, \ - R *in, R *ro, R *io) const { \ - return Y(execute_split_dft_r2c)(p, in, ro, io); \ - } \ - void X(execute_split_dft_c2r)(const plan p, \ - R *ri, R *ii, R *out) const { \ - return Y(execute_split_dft_c2r)(p, ri, ii, out); \ - } \ - \ - plan X(plan_many_r2r)(int rank, const int *n, \ - int howmany, \ - R *in, const int *inembed, \ - int istride, int idist, \ - R *out, const int *onembed, \ - int ostride, int odist, \ - const r2r_kind *kind, unsigned int flags) const { \ - return Y(plan_many_r2r)(rank, n, howmany, in, inembed, istride, idist, out, onembed, ostride, odist, kind, flags); \ - } \ - \ - plan X(plan_r2r)(int rank, const int *n, R *in, R *out, \ - const r2r_kind *kind, unsigned int flags) const { \ - return Y(plan_r2r)(rank, n, in, out, kind, flags); \ - } \ - \ - plan X(plan_r2r_1d)(int n, R *in, R *out, \ - r2r_kind kind, unsigned int flags) const { \ - return Y(plan_r2r_1d)(n, in, out, kind, flags); \ - } \ - plan X(plan_r2r_2d)(int n0, int n1, R *in, R *out, \ - r2r_kind kind0, r2r_kind kind1, \ - unsigned int flags) const { \ - return Y(plan_r2r_2d)(n0, n1, in, out, kind0, kind1, flags); \ - } \ - plan X(plan_r2r_3d)(int n0, int n1, int n2, \ - R *in, R *out, r2r_kind kind0, \ - r2r_kind kind1, r2r_kind kind2, \ - unsigned int flags) const { \ - return Y(plan_r2r_3d)(n0, n1, n2, in, out, kind0, kind1, kind2, flags); \ - } \ - \ - plan X(plan_guru_r2r)(int rank, const iodim *dims, \ - int howmany_rank, \ - const iodim *howmany_dims, \ - R *in, R *out, \ - const r2r_kind *kind, unsigned int flags) const { \ - return Y(plan_guru_r2r)(rank, dims, howmany_rank, howmany_dims, in, out, kind, flags); \ - } \ - \ - plan X(plan_guru64_r2r)(int rank, const iodim64 *dims, \ - int howmany_rank, \ - const iodim64 *howmany_dims, \ - R *in, R *out, \ - const r2r_kind *kind, unsigned int flags) const { \ - return Y(plan_guru64_r2r)(rank, dims, howmany_rank, howmany_dims, in, out, kind, flags); \ - } \ - \ - void X(execute_r2r)(const plan p, R *in, R *out) const { \ - Y(execute_r2r)(p, in, out); \ - } \ - \ - void X(destroy_plan)(plan p) const { \ - Y(destroy_plan)(p); \ - } \ - void X(forget_wisdom)() const { \ - Y(forget_wisdom)(); \ - } \ - void X(cleanup)() const { \ - Y(cleanup)(); \ - } \ - \ - void X(set_timelimit)(double t) const { \ - Y(set_timelimit)(t); \ - } \ - \ - template <typename T = void> \ - typename std::enable_if<has_thread_support, T>::type \ - X(plan_with_nthreads)(int nthreads) const { \ - Y(plan_with_nthreads)(nthreads); \ - } \ - template <typename T = int> \ - typename std::enable_if<has_thread_support, T>::type \ - X(init_threads)() const { \ - return Y(init_threads)(); \ - } \ - template <typename T=void> \ - typename std::enable_if<has_thread_support, T>::type \ - X(cleanup_threads)() const { \ - Y(cleanup_threads)(); \ - } \ - \ - int X(export_wisdom_to_filename)(const char *filename) const { \ - return Y(export_wisdom_to_filename)(filename); \ - } \ - void X(export_wisdom_to_file)(FILE *output_file) const { \ - Y(export_wisdom_to_file)(output_file); \ - } \ - char *X(export_wisdom_to_string)() const { \ - return Y(export_wisdom_to_string)(); \ - } \ - void X(export_wisdom)(write_char_func write_char, \ - void *data) const { \ - return Y(export_wisdom)(write_char, data); \ - } \ - int X(import_system_wisdom)() const { \ - return Y(import_system_wisdom)(); \ - } \ - int X(import_wisdom_from_filename)(const char *filename) const { \ - return Y(import_wisdom_from_filename)(filename); \ - } \ - int X(import_wisdom_from_file)(FILE *input_file) const { \ - return Y(import_wisdom_from_file)(input_file); \ - } \ - int X(import_wisdom_from_string)(const char *input_string) const { \ - return Y(import_wisdom_from_string)(input_string); \ - } \ - int X(import_wisdom)(read_char_func read_char, void *data) const { \ - return Y(import_wisdom)(read_char, data); \ - } \ - \ - void X(fprint_plan)(const plan p, FILE *output_file) const { \ - Y(fprint_plan)(p, output_file); \ - } \ - void X(print_plan)(const plan p) const { \ - Y(print_plan)(p); \ - } \ - \ - void *X(malloc)(size_t n) const { \ - return Y(malloc)(n); \ - } \ - R *X(alloc_real)(size_t n) const { \ - return Y(alloc_real)(n); \ - } \ - C *X(alloc_complex)(size_t n) const { \ - return Y(alloc_complex)(n); \ - } \ - void X(free)(void *p) const { \ - Y(free)(p); \ - } \ - \ - void X(flops)(const plan p, \ - double *add, double *mul, double *fmas) const { \ - return Y(flops)(p, add, mul, fmas); \ - } \ - double X(estimate_cost)(const plan p) const { \ - return Y(estimate_cost)(p); \ - } \ - double X(cost)(const plan p) const { \ - return Y(cost)(p); \ - } \ - }; - - -/* Constants */ -namespace hysop { - namespace fft { - /* float */ - #ifdef FFTW_HAS_FFTW3F - static constexpr bool fftw_has_float_support = true; - #ifdef FFTW_HAS_FFTW3F_MPI - static constexpr bool fftw_has_float_mpi_support = true; - #else - static constexpr bool fftw_has_float_mpi_support = false; - #endif - #if defined(FFTW_HAS_FFTW3F_THREADS) || defined(FFTW_HAS_FFTW3F_OMP) - static constexpr bool fftw_has_float_thread_support = true; - #else - static constexpr bool fftw_has_float_thread_support = false; - #endif - #else - static constexpr bool fftw_has_float_support = false; - static constexpr bool fftw_has_float_thread_support = false; - static constexpr bool fftw_has_float_mpi_support = false; - #endif - - /* double */ - #ifdef FFTW_HAS_FFTW3D - static constexpr bool fftw_has_double_support = true; - #ifdef FFTW_HAS_FFTW3D_MPI - static constexpr bool fftw_has_double_mpi_support = true; - #else - static constexpr bool fftw_has_double_mpi_support = false; - #endif - #if defined(FFTW_HAS_FFTW3D_THREADS) || defined(FFTW_HAS_FFTW3D_OMP) - static constexpr bool fftw_has_double_thread_support = true; - #else - static constexpr bool fftw_has_double_thread_support = false; - #endif - #else - static constexpr bool fftw_has_double_support = false; - static constexpr bool fftw_has_double_thread_support = false; - static constexpr bool fftw_has_double_mpi_support = false; - #endif - - /* long double */ - #ifdef FFTW_HAS_FFTW3L - static constexpr bool fftw_has_long_double_support = true; - #ifdef FFTW_HAS_FFTW3L_MPI - static constexpr bool fftw_has_long_double_mpi_support = true; - #else - static constexpr bool fftw_has_long_double_mpi_support = false; - #endif - #if defined(FFTW_HAS_FFTW3L_THREADS) || defined(FFTW_HAS_FFTW3L_OMP) - static constexpr bool fftw_has_long_double_thread_support = true; - #else - static constexpr bool fftw_has_long_double_thread_support = false; - #endif - #else - static constexpr bool fftw_has_long_double_support = false; - static constexpr bool fftw_has_long_double_thread_support = false; - static constexpr bool fftw_has_long_double_mpi_support = false; - #endif - - /* __float128 */ - #ifdef FFTW_HAS_FFTW3Q - static constexpr bool fftw_has_quad_float_support = true; - #ifdef FFTW_HAS_FFTW3Q_MPI - static constexpr bool fftw_has_quad_float_mpi_support = true; - #else - static constexpr bool fftw_has_quad_float_mpi_support = false; - #endif - #if defined(FFTW_HAS_FFTW3Q_THREADS) || defined(FFTW_HAS_FFTW3Q_OMP) - static constexpr bool fftw_has_quad_float_thread_support = true; - #else - static constexpr bool fftw_has_quad_float_thread_support = false; - #endif - #else - static constexpr bool fftw_has_quad_float_support = false; - static constexpr bool fftw_has_quad_float_thread_support = false; - static constexpr bool fftw_has_quad_float_mpi_support = false; - #endif - } -} - -/* Wrappers */ -namespace hysop { - namespace fft { - - template <typename T> - struct Fftw3 { - Fftw3() { - throw std::runtime_error( - "Can only use Fftw3 wrapper with types {float, double, long double, __float128} ! " - "Note: __float128 type is enabled only if HAS_QUADMATHS is defined." - ); - } - }; - template <typename T> struct is_fftw_supported_type { static constexpr bool value = false; }; - template <typename T> struct is_fftw_supported_complex_type { static constexpr bool value = false; }; - - - /* Generate Ffftw<> template specialisations */ - FFTW_DEFINE_CXX_API(FFTW_MANGLE_CLASS, FFTW_MANGLE_FLOAT, float, hysop::fft::fftw_has_float_thread_support) - FFTW_DEFINE_CXX_API(FFTW_MANGLE_CLASS, FFTW_MANGLE_DOUBLE, double, hysop::fft::fftw_has_double_thread_support) - FFTW_DEFINE_CXX_API(FFTW_MANGLE_CLASS, FFTW_MANGLE_LONG_DOUBLE, long double, hysop::fft::fftw_has_long_double_thread_support) - - template <> struct is_fftw_supported_type<float> { static constexpr bool value = true; }; - template <> struct is_fftw_supported_type<double> { static constexpr bool value = true; }; - template <> struct is_fftw_supported_type<long double> { static constexpr bool value = true; }; - - template <> struct is_fftw_supported_complex_type<std::complex<float>> { static constexpr bool value = true; }; - template <> struct is_fftw_supported_complex_type<std::complex<double>> { static constexpr bool value = true; }; - template <> struct is_fftw_supported_complex_type<std::complex<long double>> { static constexpr bool value = true; }; - template <> struct is_fftw_supported_complex_type<fftwf_complex> { static constexpr bool value = true; }; - template <> struct is_fftw_supported_complex_type<fftw_complex> { static constexpr bool value = true; }; - template <> struct is_fftw_supported_complex_type<fftwl_complex> { static constexpr bool value = true; }; - -#ifdef HAS_QUADMATHS - FFTW_DEFINE_CXX_API(FFTW_MANGLE_CLASS, FFTW_MANGLE_QUAD, __float128, hysop::fft::fftw_has_quad_float_thread_support) - template <> struct is_fftw_supported_type<__float128> { static constexpr bool value = true; }; - template <> struct is_fftw_supported_complex_type<std::complex<__float128>> { static constexpr bool value = true; }; - template <> struct is_fftw_supported_complex_type<fftwq_complex> { static constexpr bool value = true; }; -#endif - - - } -} - -#undef FFTW_DEFINE_CXX_API -#undef FFTW_MANGLE_CLASS - -#endif /* end of include guard: HYSOP_FFTW3_H */ - diff --git a/src/hysop++/src/fft/fftwComplex.h b/src/hysop++/src/fft/fftwComplex.h deleted file mode 100644 index a28954a5f..000000000 --- a/src/hysop++/src/fft/fftwComplex.h +++ /dev/null @@ -1,87 +0,0 @@ - -#ifndef FFTWCOMPLEX_H -#define FFTWCOMPLEX_H - -#include <type_traits> -#include <complex> -#include <fft/fftw3.h> - -namespace hysop { - namespace fft { - - template <typename T> struct fftw_complex_type { - typedef void value_type; - typedef void fftw_type; - typedef void std_type; - }; - - template <> struct fftw_complex_type<long double> { - typedef long double value_type; - typedef fftwl_complex fftw_type; - typedef std::complex<long double> std_type; - }; - template <> struct fftw_complex_type<double> { - typedef double value_type; - typedef fftw_complex fftw_type; - typedef std::complex<double> std_type; - }; - template <> struct fftw_complex_type<float> { - typedef float value_type; - typedef fftwf_complex fftw_type; - typedef std::complex<float> std_type; - }; - - template <> struct fftw_complex_type<std::complex<long double>> { - typedef long double value_type; - typedef fftwl_complex fftw_type; - typedef std::complex<long double> std_type; - }; - template <> struct fftw_complex_type<std::complex<double>> { - typedef double value_type; - typedef fftw_complex fftw_type; - typedef std::complex<double> std_type; - }; - template <> struct fftw_complex_type<std::complex<float>> { - typedef float value_type; - typedef fftwf_complex fftw_type; - typedef std::complex<float> std_type; - }; - - template <> struct fftw_complex_type<fftwl_complex> { - typedef long double value_type; - typedef fftwl_complex fftw_type; - typedef std::complex<long double> std_type; - }; - template <> struct fftw_complex_type<fftw_complex> { - typedef double value_type; - typedef fftw_complex fftw_type; - typedef std::complex<double> std_type; - }; - template <> struct fftw_complex_type<fftwf_complex> { - typedef float value_type; - typedef fftwf_complex fftw_type; - typedef std::complex<float> std_type; - }; - -#ifdef HAS_QUADMATHS - template <> struct fftw_complex_type<__float128> { - typedef __float128 value_type; - typedef fftwq_complex fftw_type; - typedef std::complex<__float128> std_type; - }; - template <> struct fftw_complex_type<std::complex<__float128>> { - typedef __float128 value_type; - typedef fftwq_complex fftw_type; - typedef std::complex<__float128> std_type; - }; - template <> struct fftw_complex_type<fftwq_complex> { - typedef __float128 value_type; - typedef fftwq_complex fftw_type; - typedef std::complex<__float128> std_type; - }; -#endif - - } -} - -#endif /* end of include guard: FFTWCOMPLEX_H */ diff --git a/src/hysop++/src/fft/planner.h b/src/hysop++/src/fft/planner.h deleted file mode 100644 index 75b8ca852..000000000 --- a/src/hysop++/src/fft/planner.h +++ /dev/null @@ -1,747 +0,0 @@ - -#ifndef HYSOP_PLANNER_H -#define HYSOP_PLANNER_H - -#include <list> -#include <cassert> -#include <functional> - -#include "fft/fftw3.h" -#include "fft/transform.h" -#include "fft/fftDomainConfiguration.h" -#include "domain/domain.h" -#include "utils/default.h" - -namespace hysop { - namespace fft { - - enum FftTransformType : int { - FFT_NONE=-1, - FFT_R2R, - FFT_R2C - }; - - template <typename T, std::size_t Dim> - class Planner; - - template <typename T, std::size_t Dim> - std::ostream& operator<<(std::ostream& os, const Planner<T,Dim>& planner); - - template <typename T, std::size_t Dim> - class Planner : private Fftw3<T> { - static_assert(hysop::fft::is_fftw_supported_type<T>::value, - "Planner data type is not currently supported by fftw !"); - - public: - using real = typename Fftw3<T>::R; - using fftw_complex = typename Fftw3<T>::C; - using std_complex = typename Fftw3<T>::stdC; - using fftw_plan = typename Fftw3<T>::plan; - using fftw_iodim = typename Fftw3<T>::iodim; - - protected: - using RealArray = hysop::multi_array<T,Dim>; - using TransformArray = std::array<fft::Transform,Dim>; - - public: - Planner(std::complex<T> p_fixedAxeWaveNumbers = std::complex<T>(1,0), - std::complex<T> p_fixedAxeWaveNumberPows = std::complex<T>(1,0)); - Planner(const Planner& other) = delete; /* cannot copy fftw plans to prevent inter instance plan destroying */ - Planner(Planner&& other) = default; - virtual ~Planner(); - - Planner& operator=(const Planner& planner) = delete; - Planner& operator=(Planner&& planner) = default; - - /* Plans a forward and a backward DCT/DST/FFT on each axe of the domain. */ - /* An axe with a NONE/NONE fft fomain configuration or order=0 is not transformed. */ - /* Input and output can be the same but in case of inplace transform, a temporary buffer is created */ - /* during planning. */ - /* If transforms include a complex transform (FFT) or if the transform is inplace, additional data may */ - /* be allocated inside the class. */ - /* fftw_flags are used to pass flags to FFTW. */ - /* Return true if planning was successfull AND if there is any transform, else return false. */ - /* Note: To get max performance use hysop::_default::fft_allocator<T> with hysop::multi_array */ - bool plan(hysop::const_multi_array_ref<T,Dim> input_rdata, - hysop::multi_array_ref<T,Dim> output_rdata, - const fft::FftDomainConfiguration<Dim>& inputFftDomainConfig, - const std::array<int,Dim>& order, - const std::array<T ,Dim>& domainSize, - unsigned int fftw_flags, - bool includeOutputPeriodicBoundaries=false, bool mirrorOutputPeriodicBoundaries=false); - - void executeForwardTransform(); - void executeBackwardTransform(); - - FftTransformType transformType() const; - - T normalisationFactor() const; - const std::array<T,Dim> signs() const; - const std::array<std::vector<std::complex<T>>,Dim>& waveNumbers() const; - const std::array<std::vector<std::complex<T>>,Dim>& waveNumbersPows() const; - - hysop::multi_array_view<T,Dim> transformedRealData(); /* view because possibly non contiguous */ - hysop::multi_array_ref<std::complex<T>,Dim> transformedComplexData(); /* ref because contiguous (allocated inside class) */ - - /* Get planned transform description */ - const std::string& toString() const; - - /* Modify untransformed axe generated wave numbers to simplify algorithm implementations based on the planner */ - Planner<T,Dim>& setFixedAxeWaveNumbers(std::complex<T> p_fixedAxeWaveNumber); - Planner<T,Dim>& setFixedAxeWaveNumberPows(std::complex<T> p_fixedAxeWaveNumberPow); - - protected: - void checkDomainCompatibility(const fft::FftDomainConfiguration<Dim>& domainConfig) const; - void checkExtensionCompatibility(const fft::Extension &lhs, const fft::Extension &rhs) const; - - fft::Transform findTransform(const std::pair<Extension,Extension>& ed) const; - - void reset(); - - template <typename Transfo> - void toStreamTransform(std::ostream& os, const Transfo& tr, - int rank, int howmany_rank, - const fftw_iodim* dims, const fftw_iodim *howmany_dims, - int input_data_offset=0, int output_data_offset=0); - - protected: - std::complex<T> m_fixedAxeWaveNumbers, m_fixedAxeWaveNumberPows; - - hysop::multi_array_ref<T,Dim> m_realBuffer; - hysop::multi_array<std_complex,Dim,hysop::_default::fft_allocator<std_complex>> m_complexBuffer; - typename hysop::multi_array<T,Dim>::template index_gen<Dim,Dim> m_transformedRealBufferView; - - std::list<fftw_plan> m_forward_R2R_plans, m_R2C_plans; - std::list<fftw_plan> m_backward_R2R_plans, m_C2R_plans; - - FftTransformType m_transformType; - std::vector<std::size_t> m_periodicAxes; - - std::array<T,Dim> m_signs; - std::array<std::vector<std_complex>,Dim> m_waveNumbers; - std::array<std::vector<std_complex>,Dim> m_waveNumbersPows; - T m_normalisationFactor; - - bool m_mirrorOutputPeriodicBoundaries; - std::string m_plannedTransformStr; - }; - - template <typename T, std::size_t Dim> - Planner<T,Dim>::Planner(std::complex<T> p_fixedAxeWaveNumbers, std::complex<T> p_fixedAxeWaveNumberPows): - m_fixedAxeWaveNumbers(p_fixedAxeWaveNumbers), - m_fixedAxeWaveNumberPows(p_fixedAxeWaveNumberPows), - m_realBuffer(), m_complexBuffer(), - m_forward_R2R_plans(), m_R2C_plans(), - m_backward_R2R_plans(), m_C2R_plans(), - m_transformType(), - m_signs(), m_waveNumbers(), m_waveNumbersPows(), m_normalisationFactor(), - m_mirrorOutputPeriodicBoundaries(), - m_plannedTransformStr() { - reset(); - } - - template <typename T, std::size_t Dim> - Planner<T,Dim>::~Planner() { - reset(); - } - - template <typename T, std::size_t Dim> - void Planner<T,Dim>::reset() { - new (&m_realBuffer) multi_array_ref<T,Dim>(); - m_complexBuffer.reshape(typename Shape<Dim>::type{0}); - for(fftw_plan plan : m_forward_R2R_plans) - this->fftw_destroy_plan(plan); - for(fftw_plan plan : m_backward_R2R_plans) - this->fftw_destroy_plan(plan); - for(fftw_plan plan : m_C2R_plans) - this->fftw_destroy_plan(plan); - for(fftw_plan plan : m_R2C_plans) - this->fftw_destroy_plan(plan); - m_forward_R2R_plans.clear(); - m_R2C_plans.clear(); - m_backward_R2R_plans.clear(); - m_C2R_plans.clear(); - m_periodicAxes.clear(); - m_transformType = FftTransformType::FFT_NONE; - for (std::size_t d = 0; d < Dim; d++) { - m_waveNumbers[d].clear(); - m_waveNumbersPows[d].clear(); - } - m_signs.fill(0); - m_normalisationFactor = T(0); - m_mirrorOutputPeriodicBoundaries = false; - m_plannedTransformStr = "** No planned transforms **"; - } - - template <typename T, std::size_t Dim> - void Planner<T,Dim>::checkDomainCompatibility(const fft::FftDomainConfiguration<Dim>& domainConfig) const { - for (std::size_t d = 0; d < Dim; d++) - checkExtensionCompatibility(domainConfig[d].first, domainConfig[d].second); - } - - template <typename T, std::size_t Dim> - void Planner<T,Dim>::checkExtensionCompatibility(const fft::Extension &lhs, const fft::Extension &rhs) const { - if ((lhs==fft::Extension::PERIODIC) ^ (rhs==fft::Extension::PERIODIC)) - throw std::runtime_error("Planner error: Periodic domain extensions are not compatible !"); - if ((lhs==fft::Extension::NONE) ^ (rhs==fft::Extension::NONE)) - throw std::runtime_error("Planner error: None domain extensions are not compatible !"); - } - - template <typename T, std::size_t Dim> - bool Planner<T,Dim>::plan(hysop::const_multi_array_ref<T,Dim> input_rdata, - hysop::multi_array_ref<T,Dim> output_rdata, - const fft::FftDomainConfiguration<Dim>& inputFftDomainConfig, - const std::array<int,Dim>& order, - const std::array<T ,Dim>& domainSize, - unsigned int fftw_flags, - const bool includeOutputPeriodicBoundaries, - const bool mirrorOutputPeriodicBoundaries) { - - this->checkDomainCompatibility(inputFftDomainConfig); - this->reset(); - - bool inplace = (input_rdata.data() == output_rdata.data()); - hysop::multi_array<T,Dim> input_rdata_buffer; - if(inplace) - input_rdata_buffer = input_rdata; - - m_mirrorOutputPeriodicBoundaries = includeOutputPeriodicBoundaries && mirrorOutputPeriodicBoundaries; - - TransformArray forwardTransforms, backwardTransforms; - typename Shape<Dim>::type realBufferShape, complexBufferShape; - std::array<int,Dim> forward_transform_size, backward_transform_size, complex_transform_size; - std::array<int,Dim> forward_input_offset, forward_output_offset; - std::array<int,Dim> backward_input_offset, backward_output_offset; - std::array<bool,Dim> oddOrder, axeTransformed; - - bool hasRealTransforms=false, hasComplexTransforms=false; - int lastComplexTransformAxe=-1; - std::stringstream ss; - - ss << "=== Planner ===" << std::endl; - ss << "** input **" << std::endl; - ss << "\tInputDataDim: " << input_rdata.shape() << std::endl; - ss << "\tDomainConfig: " << inputFftDomainConfig; - ss << "\tOrder : " << order << std::endl; - ss << "\tDomainSize : " << domainSize << std::endl; - ss << "\tipb/mpb : " << std::boolalpha << includeOutputPeriodicBoundaries << "/" - << std::boolalpha << mirrorOutputPeriodicBoundaries << std::endl; - - for (std::size_t d = 0; d < Dim; d++) { - const FftDomainConfiguration<Dim> &inputConfig = inputFftDomainConfig; - const auto &inputExtensions = inputConfig.extensions()[d]; - const bool axeIsPeriodic = (inputExtensions.first==Extension::PERIODIC); - const bool axeIsOddOrder = (order[d]%2!=0); - const bool axeIsTransformed = !(order[d]==0 || inputExtensions.first == fft::Extension::NONE); - const std::size_t inputSize = input_rdata.shape()[d] - - std::size_t(axeIsPeriodic && inputConfig.includePeriodicBoundaries()); - - const fft::Transform tr = this->findTransform(inputExtensions); - - forwardTransforms[d] = tr; - if(axeIsOddOrder) - backwardTransforms[d] = tr.conjugateInverseTransform(); - else - backwardTransforms[d] = tr.inverseTransform(); - - realBufferShape[d] = inputSize + - std::size_t((inputExtensions.second==Extension::PERIODIC) && includeOutputPeriodicBoundaries); - complexBufferShape[d] = inputSize; - forward_transform_size[d] = inputSize; - backward_transform_size[d] = inputSize; - complex_transform_size[d] = inputSize; - - forward_input_offset[d] = 0; - forward_output_offset[d] = 0; - backward_input_offset[d] = 0; - backward_output_offset[d] = 0; - - oddOrder[d] = axeIsOddOrder; - axeTransformed[d] = axeIsTransformed; - - if(axeIsPeriodic) - m_periodicAxes.push_back(d); - - if(!axeIsTransformed) { - continue; - } - else { - if(tr.isR2R()) { - hasRealTransforms = true; - const std::size_t firstExtOdd = (inputExtensions.first == Extension::ODD); - const std::size_t secondExtOdd = (inputExtensions.second == Extension::ODD); - const std::size_t firstExtEven = (inputExtensions.first == Extension::EVEN); - const std::size_t secondExtEven = (inputExtensions.second == Extension::EVEN); - - forward_transform_size[d] -= (firstExtOdd + secondExtOdd); - forward_input_offset[d] = std::ptrdiff_t(firstExtOdd); - forward_output_offset[d] = std::ptrdiff_t(firstExtOdd); - - complexBufferShape[d] = forward_transform_size[d]; - complex_transform_size[d] = forward_transform_size[d]; - - if(axeIsOddOrder) { - backward_transform_size[d] -= (firstExtEven + secondExtEven); - backward_input_offset[d] = std::ptrdiff_t( (tr.kind == FFTW_RODFT01) - || ((tr.kind != FFTW_REDFT01) && firstExtEven) ); - backward_output_offset[d] = std::ptrdiff_t(firstExtEven); - } - else { - backward_transform_size[d] = forward_transform_size[d]; - backward_input_offset[d] = forward_output_offset[d]; - backward_output_offset[d] = forward_input_offset[d]; - } - } - else { - hasComplexTransforms = true; - lastComplexTransformAxe = d; - } - } - } - - - /* Allocate complex buffer only if necessary, return if no transforms */ - if(hasComplexTransforms) { - m_transformType = FFT_R2C; - - assert(lastComplexTransformAxe >= 0); - complexBufferShape[lastComplexTransformAxe] = complexBufferShape[lastComplexTransformAxe]/2 + 1; - m_complexBuffer.reshape(complexBufferShape); - } - else if(hasRealTransforms) { - m_transformType = FFT_R2R; - } - else { - m_transformType = FFT_NONE; - if(!inplace) - std::copy(input_rdata.begin(), input_rdata.end(), output_rdata.begin()); - this->reset(); - ss << m_plannedTransformStr << std::endl; - m_plannedTransformStr = ss.str(); - return false; - } - - /* Check if output buffer shape match */ - { - if(output_rdata.shape() != realBufferShape) - throw std::runtime_error("Output buffer shape should match the planned one !"); - new (&m_realBuffer) multi_array_ref<T,Dim>(output_rdata); - } - - /* Compute normalisation factor and wave numbers */ - m_normalisationFactor = T(1); - for(std::size_t d=0; d<Dim; d++) { - const fft::Transform tr = forwardTransforms[d]; - const std::size_t N = (tr.isR2R() ? realBufferShape[d] : complexBufferShape[d]); - const std::size_t K = (tr.isR2R() ? forward_transform_size[d] : complexBufferShape[d]); - const std::size_t S = (tr.isR2R() ? forward_transform_size[d] : complex_transform_size[d]); - const real L = domainSize[d]; - T sign = T(1); - if(!axeTransformed[d]) { - m_waveNumbers[d].resize(N); - m_waveNumbersPows[d].resize(N); - m_normalisationFactor*=T(1); - for (std::size_t k = 0; k < N; k++) { - m_waveNumbers[d][k] = m_fixedAxeWaveNumbers; - m_waveNumbersPows[d][k] = m_fixedAxeWaveNumberPows; - } - } - else { - m_waveNumbers[d].resize(K); - m_waveNumbersPows[d].resize(K); - m_normalisationFactor*= tr.normalisation<T>(S); - if(tr.isR2R()) { - const std::size_t sign_offset = (tr.basefunc()==fft::BaseFunc::COS ? 1 : 0); - sign *= std::pow(T(-1),(order[d]+sign_offset)/2); - } - for (std::size_t k = 0; k < K; k++) { - m_waveNumbers[d][k] = tr.omega<T>(k,K,L,d==std::size_t(lastComplexTransformAxe)); - m_waveNumbersPows[d][k] = sign*std::pow(m_waveNumbers[d][k], order[d]); - } - } - m_signs[d] = sign; - } - - /* Build planned transforms description string */ - ss << "** configuration **" << std::endl; - ss << "\thasRealTransforms : " << std::boolalpha << hasRealTransforms << std::endl; - ss << "\thasComplexTransforms : " << std::boolalpha << hasComplexTransforms << std::endl; - ss << "\tTransformed axes : " << std::noboolalpha << axeTransformed << std::endl; - ss << "\tOddOrder : " << std::noboolalpha << oddOrder << std::endl; - ss << "\tForward transforms : " << forwardTransforms << std::endl; - ss << "\tBackward transforms : " << backwardTransforms << std::endl; - ss << "\tLast cplx trans. axe : " << lastComplexTransformAxe << std::endl; - - ss << "** buffer shape **" << std::endl; - ss << "\tReal buffer shape : " << realBufferShape << std::endl; - ss << "\tComplex buffer shape : " << complexBufferShape << std::endl; - - ss << "** transform size and offsets **" << std::endl; - ss << "\tForward transf. size : " << forward_transform_size << std::endl; - ss << "\tForward input offset: " << forward_input_offset << std::endl; - ss << "\tForward output offset: " << forward_output_offset << std::endl; - ss << "\tComplex transf. size : " << complex_transform_size << std::endl; - ss << "\tBackward transf. size : " << backward_transform_size << std::endl; - ss << "\tBackward input offset: " << backward_input_offset << std::endl; - ss << "\tBackward output offset: " << backward_output_offset << std::endl; - - ss << "** normalisation & wave numbers **" << std::endl; - ss << "\tNormalisation: " << m_normalisationFactor << std::endl; - ss << "\tSigns: " << m_signs << std::endl; - ss << "\t--Wave numbers--"<< std::endl; - for (std::size_t k = 0; k < Dim; k++) - ss << "\t\taxe" << k << ": " << m_waveNumbers[k] << std::endl; - ss << "\t--wave numbers powers--"<< std::endl; - for (std::size_t k = 0; k < Dim; k++) - ss << "\t\taxe" << k << ": " << m_waveNumbersPows[k] << std::endl; - - - /* Compute complex plans */ - if(hasComplexTransforms) { - ss << "** complex transforms detail **" << std::endl; - fftw_plan R2C_plan=NULL, C2R_plan=NULL; - const int rank = lastComplexTransformAxe+1; - const int howmany_rank = Dim; - fftw_iodim dims[Dim]; - fftw_iodim howmany_dims[Dim]; - int forwardInputOffset=0, backwardOutputOffset=0; - { - int local_io_stride = 1; - for(int d=Dim-1; d>=0; d--) { - forwardInputOffset += forward_output_offset[d]*local_io_stride; - backwardOutputOffset += forward_output_offset[d]*local_io_stride; - local_io_stride *= realBufferShape[d]; - } - } - { - int input_stride=1, output_stride=1; - for(int d=Dim-1, dd=rank; d>=0; d--) { - const bool isR2C = forwardTransforms[d].isR2C(); - const bool isAxeTransformed = axeTransformed[d]; - if(isR2C && isAxeTransformed) { - dims[d] = fftw_iodim{complex_transform_size[d], input_stride, output_stride}; - howmany_dims[d] = fftw_iodim{ 1, input_stride, output_stride}; - } - else { - dims[d] = fftw_iodim{ 1, input_stride, output_stride}; - howmany_dims[d] = fftw_iodim{forward_transform_size[d], input_stride, output_stride}; - } - input_stride *= realBufferShape[d]; - output_stride *= complexBufferShape[d]; - } - R2C_plan = this->fftw_plan_guru_dft_r2c( - rank, dims, - howmany_rank, howmany_dims, - m_realBuffer.rdata()+forwardInputOffset, m_complexBuffer.fftw_cdata(), - fftw_flags); - this->toStreamTransform(ss, "FFTW_FORWARD", rank, howmany_rank, dims, howmany_dims, - forwardInputOffset, 0); - if(!R2C_plan) { - ss << "=> R2C plan creation FAILED !" << std::endl; - m_plannedTransformStr = ss.str(); - return false; - } - } - { - int input_stride=1, output_stride=1; - for(int d=Dim-1, dd=rank; d>=0; d--) { - const bool isR2C = forwardTransforms[d].isR2C(); - const bool isAxeTransformed = axeTransformed[d]; - if(isR2C && isAxeTransformed) { - dims[d] = fftw_iodim{complex_transform_size[d], input_stride, output_stride}; - howmany_dims[d] = fftw_iodim{ 1, input_stride, output_stride}; - } - else { - dims[d] = fftw_iodim{ 1, input_stride, output_stride}; - howmany_dims[d] = fftw_iodim{ forward_transform_size[d], input_stride, output_stride}; - } - input_stride *= complexBufferShape[d]; - output_stride *= realBufferShape[d]; - } - C2R_plan = this->fftw_plan_guru_dft_c2r( - rank, dims, - howmany_rank, howmany_dims, - m_complexBuffer.fftw_cdata(), m_realBuffer.rdata()+backwardOutputOffset, - fftw_flags); - this->toStreamTransform(ss, "FFTW_BACKWARD", rank, howmany_rank, dims, howmany_dims, - 0, backwardOutputOffset); - if(!C2R_plan) { - ss << "=> C2R plan creation FAILED !" << std::endl; - m_plannedTransformStr = ss.str(); - return false; - } - } - m_R2C_plans.push_back(R2C_plan); - m_C2R_plans.push_back(C2R_plan); - } - - /* Compute real plans */ - if(hasRealTransforms) { - ss << "** real transforms detail **" << std::endl; - const int rank = 1; - const int howmany_rank = Dim; - fftw_r2r_kind kind[rank]; - fftw_iodim dims[rank]; - fftw_iodim howmany_dims[howmany_rank]; - int io_stride = 1; - for(int k=Dim-1; k>=0; k--) { - const fft::Transform& ftr = forwardTransforms[k]; - const fft::Transform& btr = backwardTransforms[k]; - const bool isR2R = ftr.isR2R() && btr.isR2R(); - const bool isAxeTransformed = axeTransformed[k]; - //int forwardInputOffset=0, forwardOutputOffset=0, backwardInputOffset=0, backwardOutputOffset=0; - if(isR2R && isAxeTransformed) { - ss << "\tTRANSFORM (" << std::to_string(k) << "):" << std::endl; - fftw_plan forward_plan=NULL, backward_plan=NULL; - int local_io_stride = 1; - for(int d=Dim-1; d>=0; d--) { - //howmany_dims[d] = fftw_iodim{ (d==k ? 1 : forward_transform_size[d]), local_io_stride, local_io_stride }; - //forwardInputOffset += forward_input_offset[d] *local_io_stride; - //forwardOutputOffset += forward_output_offset[d] *local_io_stride; - //backwardInputOffset += backward_input_offset[d] *local_io_stride; - //backwardOutputOffset += backward_output_offset[d]*local_io_stride; - howmany_dims[d] = fftw_iodim{ (d==k ? 1 : int(realBufferShape[d])), local_io_stride, local_io_stride }; - local_io_stride *= realBufferShape[d]; - } - { - kind[0] = static_cast<fftw_r2r_kind>(ftr.kind); - dims[0] = { fftw_iodim{forward_transform_size[k], io_stride, io_stride} }; - forward_plan = this->fftw_plan_guru_r2r( - rank, dims, - howmany_rank, howmany_dims, - //m_realBuffer.rdata()+forwardInputOffset, - //m_realBuffer.rdata()+forwardOutputOffset, - m_realBuffer.rdata()+forward_input_offset[k]*io_stride, - m_realBuffer.rdata()+forward_output_offset[k]*io_stride, - kind, fftw_flags); - //this->toStreamTransform(ss, ftr, rank, howmany_rank, dims, howmany_dims, - //forwardInputOffset, forwardOutputOffset); - this->toStreamTransform(ss, ftr, rank, howmany_rank, dims, howmany_dims, - forward_input_offset[k]*io_stride, forward_output_offset[k]*io_stride); - if(!forward_plan) { - ss << "=> Forward R2R plan creation FAILED !" << std::endl; - m_plannedTransformStr = ss.str(); - return false; - } - } - { - kind[0] = static_cast<fftw_r2r_kind>(btr.kind); - dims[0] = { fftw_iodim{backward_transform_size[k], io_stride, io_stride} }; - backward_plan = this->fftw_plan_guru_r2r( - rank, dims, - howmany_rank, howmany_dims, - //m_realBuffer.rdata()+backwardInputOffset, - //m_realBuffer.rdata()+backwardOutputOffset, - m_realBuffer.rdata()+backward_input_offset[k]*io_stride, - m_realBuffer.rdata()+backward_output_offset[k]*io_stride, - kind, fftw_flags); - //this->toStreamTransform(ss, btr, rank, howmany_rank, dims, howmany_dims, - //backwardInputOffset, backwardOutputOffset); - this->toStreamTransform(ss, btr, rank, howmany_rank, dims, howmany_dims, - backward_input_offset[k]*io_stride, backward_output_offset[k]*io_stride); - if(!backward_plan) { - ss << "=> Backward R2R plan creation FAILED !" << std::endl; - m_plannedTransformStr = ss.str(); - return false; - } - } - m_forward_R2R_plans.push_back(forward_plan); - m_backward_R2R_plans.push_back(backward_plan); - } - io_stride *= realBufferShape[k]; - } - } - - /* Copy input data into the buffer */ - if(inputFftDomainConfig.includePeriodicBoundaries() ^ includeOutputPeriodicBoundaries) { - NOT_IMPLEMENTED_YET; - } - else { - if(inplace) - std::copy(input_rdata_buffer.begin(), input_rdata_buffer.end(), m_realBuffer.begin()); - else - std::copy(input_rdata.begin() , input_rdata.end() , m_realBuffer.begin()); - } - - /* Create real buffer subview */ - ss << "** real buffer view **" << std::endl; - { - ss << "\tview = index_gen"; - std::array<boost::multi_array_types::index_range,Dim> ranges; - for (std::size_t d = 0; d < Dim; d++) { - const int offset = forward_output_offset[d]; - ranges[d] = boost::multi_array_types::index_range( - offset, - offset+forward_transform_size[d]); - - ss << "[range(" << ranges[d].start() << "," << ranges[d].finish() << ")]"; - } - ss << std::endl; - m_transformedRealBufferView = hysop::utils::buildIndices<Dim>(ranges); - } - - ss << "===============" << std::endl; - m_plannedTransformStr = ss.str(); - - return true; - } - - template <typename T, std::size_t Dim> - void Planner<T,Dim>::executeForwardTransform() { - for(auto& plan : m_forward_R2R_plans) - this->fftw_execute(plan); - for(auto& plan : m_R2C_plans) - this->fftw_execute(plan); - } - - template <typename T, std::size_t Dim> - void Planner<T,Dim>::executeBackwardTransform() { - for(auto& plan : m_C2R_plans) - this->fftw_execute(plan); - for(auto plan = m_backward_R2R_plans.rbegin(); plan!=m_backward_R2R_plans.rend(); ++plan) - this->fftw_execute(*plan); - - if(m_mirrorOutputPeriodicBoundaries) { - const typename Shape<Dim>::type rshape = m_realBuffer.shape(); - T *data = m_realBuffer.rdata(); - for(const int axe : m_periodicAxes) { - const int N = rshape[axe]; - const int num_elem = m_realBuffer.num_elements()/N; - std::array<int,Dim> ids{0}; - int id = 0; - int offset=1; - { - for(int d=Dim-1; d>axe; d--) offset*= rshape[d]; - offset *= (N-1); - } - for(int i=0; i<num_elem; i++) { - data[id+offset]=data[id]; - for (int d=Dim-1; d>=0; d--) { - if(d==axe) - continue; - ids[d]++; - if(ids[d]==int(rshape[d])) - ids[d]=0; - else - break; - } - id = ids[0]; - for (std::size_t d=1; d < Dim; d++) - id = id*rshape[d] + ids[d]; - } - } - } - } - - template <typename T, std::size_t Dim> - FftTransformType Planner<T,Dim>::transformType() const { - return m_transformType; - } - - template <typename T, std::size_t Dim> - T Planner<T,Dim>::normalisationFactor() const { - return m_normalisationFactor; - } - - template <typename T, std::size_t Dim> - const std::array<T,Dim> Planner<T,Dim>::signs() const { - return m_signs; - } - - template <typename T, std::size_t Dim> - const std::array<std::vector<std::complex<T>>,Dim>& Planner<T,Dim>::waveNumbers() const { - return m_waveNumbers; - } - - template <typename T, std::size_t Dim> - const std::array<std::vector<std::complex<T>>,Dim>& Planner<T,Dim>::waveNumbersPows() const { - return m_waveNumbersPows; - } - - template <typename T, std::size_t Dim> - hysop::multi_array_view<T,Dim> Planner<T,Dim>::transformedRealData() { - if(m_transformType==FFT_R2C) - throw std::runtime_error("Requesting planner real data but planned transform is real to complex !"); - else if(m_transformType==FFT_NONE) - throw std::runtime_error("Requesting planner real data but there was no successfull planned transforms !"); - return m_realBuffer[m_transformedRealBufferView]; - } - - template <typename T, std::size_t Dim> - hysop::multi_array_ref<std::complex<T>,Dim> Planner<T,Dim>::transformedComplexData() { - if(m_transformType==FFT_R2R) - throw std::runtime_error("Requesting planner complex data but planned transform is real to real !"); - else if(m_transformType==FFT_NONE) - throw std::runtime_error("Requesting planner real data but there was no successfull planned transforms !"); - return m_complexBuffer; - } - - template <typename T, std::size_t Dim> - fft::Transform Planner<T,Dim>::findTransform(const std::pair<Extension,Extension>& ed) const { - if(ed.first == Extension::EVEN) { - if(ed.second == Extension::EVEN) - return fft::Transform(FFTW_REDFT00); - else - return fft::Transform(FFTW_REDFT01); - } - else if(ed.first == Extension::ODD) { - if(ed.second == Extension::EVEN) - return fft::Transform(FFTW_RODFT01); - else - return fft::Transform(FFTW_RODFT00); - } - else { - return fft::Transform(FFTW_FORWARD); - } - } - - template <typename T, std::size_t Dim> - template <typename Transfo> - void Planner<T,Dim>::toStreamTransform(std::ostream& os, const Transfo& tr, - int rank, int howmany_rank, - const fftw_iodim* dims, const fftw_iodim* howmany_dims, - const int input_data_offset, const int output_data_offset) { - os << "\t --" << tr << "--" << std::endl; - os << "\t\tdims[" << rank << "] = {" << std::endl; - for (int i = 0; i < rank-1; i++) - os << "\t\t " << dims[i] << "," << std::endl; - os << "\t\t " << dims[rank-1] << std::endl; - os << "\t\t};" << std::endl; - os << "\t\thowmany[" << howmany_rank << "] = {" << std::endl; - for (int i = 0; i < howmany_rank-1; i++) - os << "\t\t " << howmany_dims[i] << "," << std::endl; - os << "\t\t " << howmany_dims[howmany_rank-1] << std::endl; - os << "\t\t};" << std::endl; - os << "\t\tinput data offset: " << input_data_offset << std::endl; - os << "\t\toutput data offset: " << output_data_offset << std::endl; - } - - /* Get planned transform description */ - template <typename T, std::size_t Dim> - const std::string& Planner<T,Dim>::toString() const { - return m_plannedTransformStr; - } - - template <typename T, std::size_t Dim> - std::ostream& operator<<(std::ostream& os, const Planner<T,Dim>& planner) { - os << planner.toString(); - return os; - } - - template <typename T, std::size_t Dim> - Planner<T,Dim>& Planner<T,Dim>::setFixedAxeWaveNumbers(std::complex<T> p_fixedAxeWaveNumber) { - m_fixedAxeWaveNumbers = p_fixedAxeWaveNumber; - return *this; - } - - template <typename T, std::size_t Dim> - Planner<T,Dim>& Planner<T,Dim>::setFixedAxeWaveNumberPows(std::complex<T> p_fixedAxeWaveNumberPow) { - m_fixedAxeWaveNumberPows = p_fixedAxeWaveNumberPow; - return *this; - } - - } /* end of namespace fft */ -} /* end of namespace hysop */ - - -#endif /* end of include guard: HYSOP_PLANNER_H */ diff --git a/src/hysop++/src/fft/transform.cpp b/src/hysop++/src/fft/transform.cpp deleted file mode 100644 index 53531952f..000000000 --- a/src/hysop++/src/fft/transform.cpp +++ /dev/null @@ -1,14 +0,0 @@ - -#include "fft/transform.h" - -namespace hysop { - namespace fft { - - std::ostream& operator<<(std::ostream& os, const Transform &tr) { - os << tr.toString(); - return os; - } - - } -} - diff --git a/src/hysop++/src/fft/transform.h b/src/hysop++/src/fft/transform.h deleted file mode 100644 index 7a6e36a3b..000000000 --- a/src/hysop++/src/fft/transform.h +++ /dev/null @@ -1,188 +0,0 @@ - -#ifndef FFTTRANSFORM_H -#define FFTTRANSFORM_H - -#include <complex> -#include <iostream> -#include <fftw3.h> - -#include "utils/constants.h" - -namespace hysop { - namespace fft { - - struct Transform; - std::ostream& operator<<(std::ostream& os, const Transform &tr); - - enum BaseFunc { - CEXP, - SIN, - COS - }; - - struct Transform { - public: - int kind; - - Transform(int p_kind = 0): - kind(p_kind) {} - - bool isR2C() const { - return kind == FFTW_FORWARD; - } - bool isR2R() const { - return !this->isR2C(); - } - - BaseFunc basefunc() const { - switch(kind) { - case(FFTW_REDFT00): - case(FFTW_REDFT01): - case(FFTW_REDFT10): - case(FFTW_REDFT11): - return COS; - case(FFTW_RODFT00): - case(FFTW_RODFT01): - case(FFTW_RODFT10): - case(FFTW_RODFT11): - return SIN; - case(FFTW_R2HC): - case(FFTW_HC2R): - case(FFTW_FORWARD): - return CEXP; - default: - throw std::runtime_error("Unknown transform !"); - } - } - - template <typename T> - std::complex<T> omega(std::size_t k, std::size_t N, T L = T(1), bool lastDim=false) const { - using namespace hysop::constants; - switch(kind) { - case(FFTW_FORWARD): - if(lastDim) { - return std::complex<T>(T(0),T(2)*pi*T(k)/L); - } - else { - T kk; - if(k <= N/2 -1) - kk = T(k); - else if(k==N/2) - kk = T(0); - else - kk = T(k)-T(N); - return std::complex<T>(T(0),T(2)*pi*kk/L); - } - case(FFTW_REDFT00): - return std::complex<T>(pi*T(k)/L, T(0)); - case(FFTW_RODFT00): /* offset +1 */ - return std::complex<T>(pi*T(k+1)/L, T(0)); - case(FFTW_REDFT01): - return std::complex<T>(pi*(T(k)+T(0.5))/L, T(0)); - case(FFTW_RODFT01): /* -0.5 + 1 offset = +0.5 */ - return std::complex<T>(pi*(T(k)+T(0.5))/L, T(0)); - default: - throw std::runtime_error("Not implemented yet !"); - } - } - - template <typename T> - T normalisation(std::size_t n) const { - switch(kind) { - case(FFTW_FORWARD): - return T(n); - case(FFTW_RODFT00): - return T(2*(n+1)); - case(FFTW_REDFT00): - return T(2*(n-1)); - case(FFTW_REDFT01): - case(FFTW_REDFT10): - case(FFTW_REDFT11): - case(FFTW_RODFT01): - case(FFTW_RODFT10): - case(FFTW_RODFT11): - return T(2*n); - default: - return T(n); - } - } - - int inverseTransform() const { - switch(kind) { - case(FFTW_REDFT00): - case(FFTW_RODFT00): - return kind; - case(FFTW_REDFT01): - return FFTW_REDFT10; - case(FFTW_REDFT10): - return FFTW_REDFT01; - case(FFTW_RODFT01): - return FFTW_RODFT10; - case(FFTW_RODFT10): - return FFTW_RODFT01; - case(FFTW_R2HC): - return FFTW_HC2R; - case(FFTW_HC2R): - return FFTW_R2HC; - case(FFTW_FORWARD): - return FFTW_BACKWARD; - default: - throw std::runtime_error("Unknown transform !"); - } - } - - int conjugateInverseTransform() const { - switch(kind) { - case(FFTW_REDFT00): - return FFTW_RODFT00; - case(FFTW_REDFT01): - return FFTW_RODFT10; - case(FFTW_REDFT10): - return FFTW_RODFT01; - case(FFTW_RODFT00): - return FFTW_REDFT00; - case(FFTW_RODFT01): - return FFTW_REDFT10; - case(FFTW_RODFT10): - return FFTW_REDFT01; - default: - return this->inverseTransform(); - } - } - - std::string toString() const { - switch(kind) { - case(FFTW_REDFT00): - return "FFTW_REDFT00"; - case(FFTW_RODFT00): - return "FFTW_RODFT00"; - case(FFTW_REDFT01): - return "FFTW_REDFT01"; - case(FFTW_REDFT11): - return "FFTW_REDFT11"; - case(FFTW_REDFT10): - return "FFTW_REDFT10"; - case(FFTW_RODFT01): - return "FFTW_RODFT01"; - case(FFTW_RODFT10): - return "FFTW_RODFT10"; - case(FFTW_RODFT11): - return "FFTW_RODFT11"; - case(FFTW_R2HC): - return "FFTW_R2HC"; - //case(FFTW_HC2R): - //return "FFTW_HC2R"; - case(FFTW_BACKWARD): - return "FFTW_BACKWARD"; - case(FFTW_FORWARD): - return "FFTW_FORWARD"; - default: - return "FFTW_TRANSFORM_KIND_STRING_NOT_FOUND"; - } - } - }; - - } -} - -#endif /* end of include guard: FFTTRANSFORM_H */ diff --git a/src/hysop++/src/maths/polynomial.h b/src/hysop++/src/maths/polynomial.h deleted file mode 100644 index 5373e9ece..000000000 --- a/src/hysop++/src/maths/polynomial.h +++ /dev/null @@ -1,428 +0,0 @@ - -#ifndef HYSOP_POLYNOMIAL_H -#define HYSOP_POLYNOMIAL_H - -#include <array> -#include "data/multi_array/multi_array.h" - -namespace hysop { - namespace maths { - - /* Polynomials in dimension Dim with coefficients of type T */ - /* Basic polynomial operations are provided */ - /* TODO: Implement fast Nlog(N) multiplication by FFT */ - /* TODO: Implement polynomial division */ - template <typename T, std::size_t Dim> - class Polynomial; - - template <typename T, std::size_t Dim> - std::ostream& operator<<(std::ostream& os, const Polynomial<T,Dim>& poly); - - template <typename T, std::size_t Dim> - class Polynomial { - public: - /* constructors, destructors & operator= */ - Polynomial() = default; - Polynomial(const Polynomial& p_other) = default; - Polynomial( Polynomial&& p_other) = default; - Polynomial& operator=(const Polynomial& p_other) = default; - Polynomial& operator=( Polynomial&& p_other) = default; - ~Polynomial() = default; - - Polynomial(const std::array<std::size_t,Dim>& p_order); - explicit Polynomial(const hysop::multi_array<T,Dim>& p_coeffs); - explicit Polynomial( hysop::multi_array<T,Dim>&& p_coeffs); - - template <typename U> - explicit Polynomial(const Polynomial<U,Dim>& p_other); - - /* accessors */ - const hysop::multi_array<T,Dim>& coefficients() const; - hysop::multi_array<T,Dim>& coefficients(); - const std::array<std::size_t,Dim>& order() const; - std::array<std::size_t,Dim> shape() const; /* == order + 1 */ - - /* mutators */ - Polynomial& reshape(const std::array<std::size_t,Dim>& p_shape); - Polynomial& setOrder(const std::array<std::size_t,Dim>& p_order); - - Polynomial& applyToCoefficients(const std::function<void(T&)>& func); - Polynomial& applyToCoefficients(const std::function<void(T&, const Index<Dim>&)>& func); - - /* apply func(T&, const Index<Dim>&, farg0, fargs...) to all coefficients */ - template <typename Functor, typename Arg0, typename... Args> - Polynomial& applyToCoefficients(const Functor& func, Arg0&& farg0, Args&&... fargs); - - /* elementwise access to coefficients */ - const T& operator[](const Index<Dim> &p_id) const; - T& operator[](const Index<Dim> &p_id); - const T& operator[](std::size_t k) const; - T& operator[](std::size_t k); - - /* polynomial function evaluation with arbitrary type */ - template <typename U1, typename... U, typename R = typename std::common_type<T,U1,U...>::type> - R operator()(const U1& x1, const U&... xs) const; - template <typename U, typename R=typename std::common_type<T,U>::type> - R operator()(const std::array<U,Dim> &x) const; - template <typename U, typename R=typename std::common_type<T,U>::type> - R operator()(const U* x) const; - - /* basic elementwise operations */ - Polynomial& operator+=(const Polynomial& p_other); - Polynomial& operator-=(const Polynomial& p_other); - - Polynomial& operator*=(const T& p_val); - Polynomial& operator/=(const T& p_val); - Polynomial& operator%=(const T& p_val); - - /* polynomial multiplication and division */ - Polynomial& operator*=(const Polynomial& p_other); - Polynomial& operator/=(const Polynomial& p_other); - - /* integral and derivatives */ - Polynomial& integrate (std::size_t dim, int order); - Polynomial& differentiate(std::size_t dim, int order); - - template <typename I> typename std::enable_if<std::is_integral<I>::value, Polynomial&>::type - differentiate(const std::array<I,Dim>& order); - template <typename I> typename std::enable_if<std::is_integral<I>::value, Polynomial&>::type - integrate(const std::array<I,Dim>& order); - - template <typename I> typename std::enable_if<std::is_integral<I>::value, Polynomial&>::type - operator >>=(const std::array<I,Dim>& order); - template <typename I> typename std::enable_if<std::is_integral<I>::value, Polynomial&>::type - operator <<=(const std::array<I,Dim>& order); - - /* comparisson operators - uses near equality if T is a floating point type */ - bool operator==(const Polynomial& other); - bool operator!=(const Polynomial& other); - - /* misc */ - std::string toString(unsigned int p_precision=2, unsigned int p_width=6) const; - - protected: - /* misc */ - template <std::size_t D> - std::string toStringImpl(const T& p_coeff, unsigned int p_precision, unsigned int p_width, bool p_begin, bool p_end) const { - std::stringstream ss; - ss << (p_begin ? "" : " ") << std::fixed << std::showpos << std::setprecision(p_precision) << p_coeff; - return ss.str(); - } - template <std::size_t D, typename ArrayView, std::size_t K=Dim-D> - std::string toStringImpl(const ArrayView& p_view, unsigned int p_precision, unsigned int p_width, - bool=false, bool=false) const { - static const char varNames[3] = { 'z','y','x' }; - static const int offset = (Dim==1 ? 2 : (Dim==2 ? 1 : (Dim==3 ? 0 : -1))); - static const char delimiters[3][2] = { {'[',']'}, - {'{','}'}, - {'(',')'} }; - - - std::string str; - for (std::ptrdiff_t k=m_coeffs.shape()[K]-1; k>=0; k--) { - std::string localStr = toStringImpl<D-1>( - p_view[k], p_precision, p_width, k==std::ptrdiff_t(m_coeffs.shape()[K]-1), k==0); - if(localStr!="") { - if(D>1) - str += delimiters[D%3][0]; - str += localStr; - if(D>1) - str += delimiters[D%3][1]; - - std::string varName; - if(Dim<=3) - varName = varNames[K+offset]; - else - varName = "x_"+std::to_string(D); - if(k==0) - ; - else if(k==1) - str += varName; - else - str += varName + "^" + std::to_string(k); - if(k>0 && D>1) - str += " + "; - } - } - return str; - } - - /* static members */ - static std::array<std::size_t,Dim> orderFromShape(const std::array<std::size_t,Dim>& p_shape); - static std::array<std::size_t,Dim> shapeFromOrder(const std::array<std::size_t,Dim>& p_order); - - public: - template <typename X> - struct PolynomIndex : public Index<Dim> { - - public: - using typename Index<Dim>::Dimension; - using typename Index<Dim>::Indices; - public: - template <typename DimArray=typename Index<Dim>::Dimension, typename IndexArray=typename Index<Dim>::Indices> - PolynomIndex(std::array<X,Dim> p_spaceVar, - const DimArray& p_dim = Dimension{0}, - const IndexArray& p_ids = Indices{0}); - const std::array<X,Dim>& spaceVariable() const; /* returns {X[0],...,X[Dim-1]} */ - X value() const; /* returns X[0]^id[0] * X1^id[1] * ... * X[Dim-1]^id[Dim-1]*/ - protected: - void initialize(); - virtual void onIndexChange (std::size_t p_pos, std::ptrdiff_t p_offset) final override; - virtual void onIndexOverflow (std::size_t p_pos) final override; - - protected: - const std::array<X,Dim> m_spaceVar; - std::array<X,Dim> m_powers; - X m_value; - }; - - protected: - hysop::multi_array<T,Dim> m_coeffs; - std::array<std::size_t,Dim> m_order; - }; - - /* unary operations */ - template <typename T, std::size_t Dim> - Polynomial<T,Dim> operator+(const Polynomial<T,Dim>& poly); - template <typename T, std::size_t Dim> - Polynomial<T,Dim> operator-(const Polynomial<T,Dim>& poly); - - /* basic operations */ - template <typename T1, typename T2, std::size_t Dim, typename T = typename std::common_type<T1,T2>::type> - Polynomial<T,Dim> operator+(const Polynomial<T1,Dim>& lhs, const Polynomial<T2,Dim>& rhs); - template <typename T1, typename T2, std::size_t Dim, typename T = typename std::common_type<T1,T2>::type> - Polynomial<T,Dim> operator-(const Polynomial<T1,Dim>& lhs, const Polynomial<T2,Dim>& rhs); - template <typename T1, typename T2, std::size_t Dim, typename T = typename std::common_type<T1,T2>::type> - Polynomial<T,Dim> operator*(const Polynomial<T1,Dim>& lhs, const Polynomial<T2,Dim>& rhs); - template <typename T1, typename T2, std::size_t Dim, typename T = typename std::common_type<T1,T2>::type> - Polynomial<T,Dim> operator/(const Polynomial<T1,Dim>& lhs, const Polynomial<T2,Dim>& rhs); - - - /* tensor product of polynomials */ - template <typename T1, typename T2, std::size_t Dim1, std::size_t Dim2, - typename T=typename std::common_type<T1,T2>::type, std::size_t Dim=Dim1+Dim2> - Polynomial<T,Dim> operator|(const Polynomial<T1,Dim1>& lhs, const Polynomial<T2,Dim2>& rhs); - - - /* integral and derivatives */ - template <typename T, std::size_t Dim, typename I> - typename std::enable_if<std::is_integral<I>::value, Polynomial<T,Dim>>::type - operator<<(const Polynomial<T,Dim>& lhs, const std::array<I,Dim>& k); - template <typename T, std::size_t Dim, typename I> - typename std::enable_if<std::is_integral<I>::value, Polynomial<T,Dim>>::type - operator>>(const Polynomial<T,Dim>& lhs, const std::array<I,Dim>& k); - - template <typename T, std::size_t Dim, typename I> - typename std::enable_if<std::is_integral<I>::value, Polynomial<T,Dim>>::type - operator<<(Polynomial<T,Dim>&& lhs, const std::array<I,Dim>& k); - template <typename T, std::size_t Dim, typename I> - typename std::enable_if<std::is_integral<I>::value, Polynomial<T,Dim>>::type - operator>>(Polynomial<T,Dim>&& lhs, const std::array<I,Dim>& k); - - - - /********************/ - /** IMPLEMENTATION **/ - /********************/ - - /* static members */ - template <typename T, std::size_t Dim> - std::array<std::size_t,Dim> Polynomial<T,Dim>::orderFromShape(const std::array<std::size_t,Dim>& p_shape) { - std::array<std::size_t,Dim> order; - for (std::size_t d = 0; d < Dim; d++) - order[d] = p_shape[d]-1; - return order; - } - - template <typename T, std::size_t Dim> - std::array<std::size_t,Dim> Polynomial<T,Dim>::shapeFromOrder(const std::array<std::size_t,Dim>& p_order) { - std::array<std::size_t,Dim> shape; - for (std::size_t d = 0; d < Dim; d++) - shape[d] = p_order[d]+1; - return shape; - } - - /* constructors, destructors & operator= */ - template <typename T, std::size_t Dim> - Polynomial<T,Dim>::Polynomial(const std::array<std::size_t,Dim>& p_shape) : - m_coeffs(), m_order() { - this->reshape(p_shape); - } - - template <typename T, std::size_t Dim> - Polynomial<T,Dim>::Polynomial(const hysop::multi_array<T,Dim>& p_coeffs) : - m_coeffs(p_coeffs), m_order(orderFromShape(m_coeffs.shape())) { - } - - template <typename T, std::size_t Dim> - Polynomial<T,Dim>::Polynomial(hysop::multi_array<T,Dim>&& p_coeffs) : - m_coeffs(std::move(p_coeffs)), m_order(orderFromShape(m_coeffs.shape())) { - } - - template <typename T, std::size_t Dim> - template <typename U> - Polynomial<T,Dim>::Polynomial(const Polynomial<U,Dim>& p_other) { - this->reshape(p_other.shape()); - for (std::size_t k=0; k < m_coeffs.num_elements(); k++) - m_coeffs.data()[k] = static_cast<T>(p_other.data()[k]); - } - - /* accessors */ - template <typename T, std::size_t Dim> - const hysop::multi_array<T,Dim>& Polynomial<T,Dim>::coefficients() const { - return m_coeffs; - } - template <typename T, std::size_t Dim> - hysop::multi_array<T,Dim>& Polynomial<T,Dim>::coefficients() { - return m_coeffs; - } - template <typename T, std::size_t Dim> - const std::array<std::size_t,Dim>& Polynomial<T,Dim>::order() const { - return m_order; - } - template <typename T, std::size_t Dim> - std::array<std::size_t,Dim> Polynomial<T,Dim>::shape() const { - return m_coeffs.shape(); - } - - /* mutators */ - template <typename T, std::size_t Dim> - Polynomial<T,Dim>& Polynomial<T,Dim>::reshape(const std::array<std::size_t,Dim>& p_shape) { - m_order = orderFromShape(p_shape); - m_coeffs.reshape(p_shape); - return *this; - } - - template <typename T, std::size_t Dim> - Polynomial<T,Dim>& Polynomial<T,Dim>::setOrder(const std::array<std::size_t,Dim>& p_order) { - m_order = p_order; - m_coeffs.reshape(shapeFromOrder(p_order)); - return *this; - } - - - template <typename T, std::size_t Dim> - Polynomial<T,Dim>& Polynomial<T,Dim>::applyToCoefficients(const std::function<void(T&)>& func) { - m_coeffs.apply(func); - return *this; - } - template <typename T, std::size_t Dim> - Polynomial<T,Dim>& Polynomial<T,Dim>::applyToCoefficients(const std::function<void(T&, const Index<Dim>&)>& func) { - m_coeffs.apply(func); - return *this; - } - - /* apply func(T&, const Index<Dim>&, farg0, fargs...) on all coefficients */ - template <typename T, std::size_t Dim> - template <typename Functor, typename Arg0, typename... Args> - Polynomial<T,Dim>& Polynomial<T,Dim>::applyToCoefficients(const Functor& func, Arg0&& farg0, Args&&... fargs) { - m_coeffs.apply(func, farg0, fargs...); - return *this; - } - - /* access to coefficients */ - template <typename T, std::size_t Dim> - const T& Polynomial<T,Dim>::operator[](std::size_t k) const { - return m_coeffs.data()[k]; - } - template <typename T, std::size_t Dim> - T& Polynomial<T,Dim>::operator[](std::size_t k) { - return m_coeffs.data()[k]; - } - template <typename T, std::size_t Dim> - const T& Polynomial<T,Dim>::operator[](const Index<Dim> &p_id) const { - return m_coeffs.data()[p_id.id()]; - } - - template <typename T, std::size_t Dim> - T& Polynomial<T,Dim>::operator[](const Index<Dim> &p_id) { - return m_coeffs.data()[p_id.id()]; - } - - /* polynomial evaluation */ - template <typename T, std::size_t Dim> - template <typename U1, typename... U, typename R> - R Polynomial<T,Dim>::operator()(const U1& x1, const U&... xs) const { - return this->operator()(std::array<R,Dim>{x1,xs...}); - } - template <typename T, std::size_t Dim> - template <typename U, typename R> - R Polynomial<T,Dim>::operator()(const U* p_x) const { - return this->operator()(std::array<U,Dim>(p_x)); - } - template <typename T, std::size_t Dim> - template <typename U, typename R> - R Polynomial<T,Dim>::operator()(const std::array<U,Dim> &p_x) const { - /* compute result */ - R res = R(0); - const T* coeffs = m_coeffs.data(); - PolynomIndex<U> idx(p_x, this->shape()); - while(!idx.atMaxId()) { - res += coeffs[idx()]*idx.value(); - ++idx; - } - return res; - } - - template <typename T, std::size_t Dim> - std::string Polynomial<T,Dim>::toString(unsigned int p_precision, unsigned int p_width) const { - return toStringImpl<Dim>(m_coeffs, p_precision, p_width); - } - - /* struct PolynomIndex */ - template <typename T, std::size_t Dim> - template <typename X> - template <typename DimArray, typename IndexArray> - Polynomial<T,Dim>::PolynomIndex<X>:: - PolynomIndex(std::array<X,Dim> p_spaceVar, const DimArray& p_dim, const IndexArray& p_ids): - Index<Dim>(p_dim, p_ids), m_spaceVar(p_spaceVar), m_powers{0}, m_value(0) { - this->initialize(); - } - template <typename T, std::size_t Dim> - template <typename X> - void Polynomial<T,Dim>::PolynomIndex<X>::initialize() { - m_value = X(1); - for (std::size_t d=0; d<Dim; d++) { - X power = std::pow(m_spaceVar[d],this->operator[](d)); - m_powers[d] = power; - m_value *= power; - } - } - template <typename T, std::size_t Dim> - template <typename X> - const std::array<X,Dim>& Polynomial<T,Dim>::PolynomIndex<X>::spaceVariable() const { - return m_spaceVar; - } - template <typename T, std::size_t Dim> - template <typename X> - X Polynomial<T,Dim>::PolynomIndex<X>::value() const { - return m_value; - } - template <typename T, std::size_t Dim> - template <typename X> - void Polynomial<T,Dim>::PolynomIndex<X>::onIndexChange(std::size_t p_pos, std::ptrdiff_t p_offset) { - assert(p_offset == 1); - m_powers[p_pos] = m_powers[p_pos]*m_spaceVar[p_pos]; - m_value *= m_spaceVar[p_pos]; - } - template <typename T, std::size_t Dim> - template <typename X> - void Polynomial<T,Dim>::PolynomIndex<X>::onIndexOverflow (std::size_t p_pos) { - m_powers[p_pos] = X(1); - m_value = X(1); - for (std::size_t d=0; d < Dim; d++) - m_value *= m_powers[d]; - } - - template <typename T, std::size_t Dim> - std::ostream& operator<<(std::ostream& os, const Polynomial<T,Dim>& poly) { - os << poly.toString(); - return os; - } - - } /* end of namespace maths */ -} /* end of namesapce hysop */ - - -#endif /* end of include guard: HYSOP_POLYNOMIAL_H */ - diff --git a/src/hysop++/src/maths/quad_maths.h b/src/hysop++/src/maths/quad_maths.h deleted file mode 100644 index 97ae1fe0b..000000000 --- a/src/hysop++/src/maths/quad_maths.h +++ /dev/null @@ -1,299 +0,0 @@ - -#ifdef HAS_QUADMATHS - -#ifndef HYSOP_QUAD_MATHS_H -#define HYSOP_QUAD_MATHS_H - -#include <cfloat> -#include <cmath> -#include <limits> -#include <quadmath.h> - -#include <iostream> -#include <iomanip> - -/* missing gcc defines */ -#define FLT128_RADIX FLT_RADIX -#define FLT128_HAS_DENORM true -#define FLT128_HAS_INFINITY true -#define FLT128_HAS_QUIET_NAN true - -namespace std { - - template<> struct numeric_limits<__float128> { - static constexpr bool is_specialized = true; - - static constexpr __float128 min() { return FLT128_MIN; } - static constexpr __float128 max() { return FLT128_MAX; } - static constexpr __float128 lowest() noexcept { return -FLT128_MAX; } - - static constexpr int digits = FLT128_MANT_DIG; - static constexpr int digits10 = FLT128_DIG; - static constexpr int max_digits10 = (2 + (FLT128_MANT_DIG) * 643L / 2136); - - static constexpr bool is_signed = true; - static constexpr bool is_integer = false; - static constexpr bool is_exact = false; - static constexpr int radix = FLT128_RADIX; - - static constexpr __float128 epsilon() { return FLT128_EPSILON; } - static constexpr __float128 round_error() { return 0.5; } - - static constexpr int min_exponent = FLT128_MIN_EXP; - static constexpr int min_exponent10 = FLT128_MIN_10_EXP; - static constexpr int max_exponent = FLT128_MAX_EXP; - static constexpr int max_exponent10 = FLT128_MAX_10_EXP; - - static constexpr bool has_infinity = FLT128_HAS_INFINITY; - static constexpr bool has_quiet_NaN = FLT128_HAS_QUIET_NAN; - static constexpr bool has_signaling_NaN = has_quiet_NaN; - static constexpr float_denorm_style has_denorm = bool(FLT128_HAS_DENORM) ? denorm_present : denorm_absent; - static constexpr bool has_denorm_loss = std::numeric_limits<float>::has_denorm_loss; - - static constexpr __float128 infinity() { return std::numeric_limits<float>::infinity(); } - static constexpr __float128 quiet_NaN() { return std::numeric_limits<float>::quiet_NaN(); } - static constexpr __float128 signaling_NaN() { return std::numeric_limits<float>::signaling_NaN(); } - static constexpr __float128 denorm_min() { return FLT128_DENORM_MIN; } - - static constexpr bool is_iec559 = has_infinity && has_quiet_NaN && has_denorm == denorm_present; - static constexpr bool is_bounded = true; - static constexpr bool is_modulo = false; - - static constexpr bool traps = false; - static constexpr bool tinyness_before = false; - static constexpr float_round_style round_style = round_to_nearest; - }; - - inline int fpclassify(__float128 arg) { return std::fpclassify(static_cast<long double>(arg)); } - - inline __float128 abs(__float128 x) { return cabsq(__complex128{x,0.0Q}); } - inline __float128 acos(__float128 x) { return acosq(x); } - inline __float128 acosh(__float128 x) { return acoshq(x); } - inline __float128 asin(__float128 x) { return asinq(x); } - inline __float128 asinh(__float128 x) { return asinhq(x); } - inline __float128 atan(__float128 x) { return atanq(x); } - inline __float128 atanh(__float128 x) { return atanhq(x); } - inline __float128 cbrt(__float128 x) { return cbrtq(x); } - inline __float128 ceil(__float128 x) { return ceilq(x); } - inline __float128 cosh(__float128 x) { return coshq(x); } - inline __float128 cos(__float128 x) { return cosq(x); } - inline __float128 erf(__float128 x) { return erfq(x); } - inline __float128 erfc(__float128 x) { return erfcq(x); } - inline __float128 exp(__float128 x) { return expq(x); } - inline __float128 expm1(__float128 x) { return expm1q(x); } - inline __float128 fabs(__float128 x) { return fabsq(x); } - inline int finite(__float128 x) { return finiteq(x); } - inline __float128 floor(__float128 x) { return floorq(x); } - inline __float128 frexp(__float128 x, int* p) { return frexpq(x,p); } - inline int isinf(__float128 x) { return isinfq(x); } - inline int ilogb(__float128 x) { return ilogbq(x); } - inline int isnan(__float128 x) { return isnanq(x); } - inline __float128 j0(__float128 x) { return j0q(x); } - inline __float128 j1(__float128 x) { return j1q(x); } - inline __float128 jn(int i, __float128 x) { return jnq(i,x); } - inline __float128 ldexp(__float128 x, int i) { return ldexpq(x,i); } - inline __float128 lgamma(__float128 x) { return lgammaq(x); } - inline long long int llrint(__float128 x) { return llrintq(x); } - inline long long int llround(__float128 x) { return llroundq(x); } - inline __float128 log(__float128 x) { return logq(x); } - inline __float128 log10(__float128 x) { return log10q(x); } - inline __float128 log2(__float128 x) { return log2q(x); } - inline __float128 log1p(__float128 x) { return log1pq(x); } - inline long int lrint(__float128 x) { return lrintq(x); } - inline long int lround(__float128 x) { return lroundq(x); } - inline __float128 nearbyint(__float128 x) { return nearbyintq(x); } - inline __float128 pow(__float128 x, __float128 y) { return powq(x,y); } - inline __float128 rint(__float128 x) { return rintq(x); } - inline __float128 round(__float128 x) { return roundq(x); } - inline __float128 scalbln(__float128 x, long int li) { return scalblnq(x,li); } - inline __float128 scalbn(__float128 x, int i) { return scalbnq(x,i); } - inline int signbit(__float128 x) { return signbitq(x); } - inline __float128 sinh(__float128 x) { return sinhq(x); } - inline __float128 sin(__float128 x) { return sinq(x); } - inline __float128 sqrt(__float128 x) { return sqrtq(x); } - inline __float128 tan(__float128 x) { return tanq(x); } - inline __float128 tanh(__float128 x) { return tanhq(x); } - inline __float128 tgamma(__float128 x) { return tgammaq(x); } - inline __float128 trunc(__float128 x) { return truncq(x); } - inline __float128 y0(__float128 x) { return y0q(x); } - inline __float128 y1(__float128 x) { return y1q(x); } - inline __float128 yn(int i, __float128 x) { return ynq(i,x); } - - - /* Prototypes for complex functions */ - inline __float128 abs(__complex128 x) { return cabsq(x); } - inline __float128 arg(__complex128 x) { return cargq(x); } - inline __float128 imag(__complex128 x) { return cimagq(x); } - inline __float128 real(__complex128 x) { return crealq(x); } - inline __complex128 acos(__complex128 x) { return cacosq(x); } - inline __complex128 acosh(__complex128 x) { return cacoshq(x); } - inline __complex128 asin(__complex128 x) { return casinq(x); } - inline __complex128 asinh(__complex128 x) { return casinhq(x); } - inline __complex128 atan(__complex128 x) { return catanq(x); } - inline __complex128 atanh(__complex128 x) { return catanhq(x); } - inline __complex128 cos(__complex128 x) { return ccosq(x); } - inline __complex128 cosh(__complex128 x) { return ccoshq(x); } - inline __complex128 exp(__complex128 x) { return cexpq(x); } - inline __complex128 expi(__float128 x) { return cexpiq(x); } - inline __complex128 log10(__complex128 x) { return clog10q(x); } - inline __complex128 conj(__complex128 x) { return conjq(x); } - inline __complex128 pow(__complex128 x, __complex128 y) { return cpowq(x,y); } - inline __complex128 proj(__complex128 x) { return cprojq(x); } - inline __complex128 sin(__complex128 x) { return csinq(x); } - inline __complex128 sinh(__complex128 x) { return csinhq(x); } - inline __complex128 sqrt(__complex128 x) { return csqrtq(x); } - inline __complex128 tan(__complex128 x) { return ctanq(x); } - inline __complex128 tanh(__complex128 x) { return ctanhq(x); } - - inline std::ostream& operator<<(std::ostream& os, __float128 x) { - const int prec = os.precision(); - - if(prec==0) { - os << static_cast<long long int>(x); - } - else { - char buf[128]; - const std::string format = "%+-#"+std::to_string(prec)+".*Qe"; - const int n = quadmath_snprintf(buf,128,format.c_str(),prec,x); - if(n>127) { - char *str = new char[n+1]; - if (str) - quadmath_snprintf (str,n+1,format.c_str(),prec,x); - os << str; - delete(str); - } - else { - os << buf; - } - } - - return os; - } -} - -#include <complex> - -namespace std { - - inline __float128 abs(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - return cabsq(X); - } - inline __float128 arg(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - return cargq(X); - } - inline __float128 imag(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - return cimagq(X); - } - inline __float128 real(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - return crealq(X); - } - inline std::complex<__float128> acos(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - X = cacosq(X); - return std::complex<__float128>(__real__ X, __imag__ X); - } - inline std::complex<__float128> acosh(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - X = cacoshq(X); - return std::complex<__float128>(__real__ X, __imag__ X); - } - inline std::complex<__float128> asin(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - X = casinq(X); - return std::complex<__float128>(__real__ X, __imag__ X); - } - inline std::complex<__float128> asinh(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - X = casinhq(X); - return std::complex<__float128>(__real__ X, __imag__ X); - } - inline std::complex<__float128> atan(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - X = catanq(X); - return std::complex<__float128>(__real__ X, __imag__ X); - } - inline std::complex<__float128> atanh(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - X = catanhq(X); - return std::complex<__float128>(__real__ X, __imag__ X); - } - inline std::complex<__float128> cos(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - X = ccosq(X); - return std::complex<__float128>(__real__ X, __imag__ X); - } - inline std::complex<__float128> cosh(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - X = ccoshq(X); - return std::complex<__float128>(__real__ X, __imag__ X); - } - inline std::complex<__float128> exp(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - X = cexpq(X); - return std::complex<__float128>(__real__ X, __imag__ X); - } - //inline std::complex<__float128> expi(__float128 x) { - //__complex128 X = cexpiq(x); - //return std::complex<__float128>(__real__ X, __imag__ X); - //} - inline std::complex<__float128> log10(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - X = clog10q(X); - return std::complex<__float128>(__real__ X, __imag__ X); - } - inline std::complex<__float128> conj(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - X = conjq(X); - return std::complex<__float128>(__real__ X, __imag__ X); - } - inline std::complex<__float128> pow(std::complex<__float128> x, std::complex<__float128> y) { - __complex128 X{x.real(),x.imag()}; - __complex128 Y{y.real(),y.imag()}; - X = cpowq(X,Y); - return std::complex<__float128>(__real__ X, __imag__ X); - } - inline std::complex<__float128> proj(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - X = cprojq(X); - return std::complex<__float128>(__real__ X, __imag__ X); - } - inline std::complex<__float128> sin(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - X = csinq(X); - return std::complex<__float128>(__real__ X, __imag__ X); - } - inline std::complex<__float128> sinh(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - X = csinhq(X); - return std::complex<__float128>(__real__ X, __imag__ X); - } - inline std::complex<__float128> sqrt(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - X = csqrtq(X); - return std::complex<__float128>(__real__ X, __imag__ X); - } - inline std::complex<__float128> tan(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - X = ctanq(X); - return std::complex<__float128>(__real__ X, __imag__ X); - } - inline std::complex<__float128> tanh(std::complex<__float128> x) { - __complex128 X{x.real(),x.imag()}; - X = ctanhq(X); - return std::complex<__float128>(__real__ X, __imag__ X); - } - - inline std::complex< __float128 > pow(std::complex< __float128> x , __float128 y) { - __float128 R = powq(std::abs(x), y); - __float128 phi = atanq(x.imag()/x.real()); - return std::complex<__float128 >(R*cosq(y*phi), R*sinq(y*phi)); - } -} - -#endif /* end of include guard: HYSOP_QUAD_MATHS_H */ - -#endif diff --git a/src/hysop++/src/solver/diffSolver.h b/src/hysop++/src/solver/diffSolver.h deleted file mode 100644 index 7b6908803..000000000 --- a/src/hysop++/src/solver/diffSolver.h +++ /dev/null @@ -1,29 +0,0 @@ - -#ifndef HYSOP_DIFFSOLVER_H -#define HYSOP_DIFFSOLVER_H - -#include "data/multi_array/multi_array.h" - -namespace hysop { - namespace solver { - template <typename T, std::size_t Dim> - class DiffSolver { - - public: - virtual void apply(hysop::const_multi_array_ref<T,Dim> input, - hysop::multi_array_ref<T,Dim> output, - const std::array<int,Dim> &order) const = 0; - - void operator()(hysop::const_multi_array_ref<T,Dim> input, - hysop::multi_array_ref<T,Dim> output, - const std::array<int,Dim> &order) { - this->apply(input,output,order); - } - - }; - - } /* end of namespace solver */ -} /* end of namespace hysop */ - -#endif /* end of include guard: HYSOP_DIFFSOLVER_H */ - diff --git a/src/hysop++/src/solver/fftDiffSolver.h b/src/hysop++/src/solver/fftDiffSolver.h deleted file mode 100644 index d9951e7a7..000000000 --- a/src/hysop++/src/solver/fftDiffSolver.h +++ /dev/null @@ -1,191 +0,0 @@ - -#ifndef HYSOP_FFTDIFFSOLVER_H -#define HYSOP_FFTDIFFSOLVER_H - -#include "solver/diffSolver.h" -#include "fft/planner.h" -#include "data/accumulatorIndex.h" - -namespace hysop { - namespace solver { - - template <typename T, std::size_t Dim> - class FftDiffSolver : public DiffSolver<T,Dim> { - - private: - using super = DiffSolver<T,Dim>; - public: - FftDiffSolver() = default; - FftDiffSolver(const FftDiffSolver& p_other) = default; - FftDiffSolver( FftDiffSolver&& p_other) = default; - ~FftDiffSolver() = default; - - FftDiffSolver& operator=(const FftDiffSolver& p_other) = default; - FftDiffSolver& operator=( FftDiffSolver&& p_other) = default; - - FftDiffSolver(const std::array<T,Dim> &p_domainSize, const fft::FftDomainConfiguration<Dim> &p_inputFftConfig, - unsigned int p_fftFlags = FFTW_MEASURE, - bool p_includeOutputPeriodicBds=false, bool p_mirrorOutputPeriodicBds=false); - - /* Mutators */ - FftDiffSolver& setDomainSize(const std::array<T,Dim>& p_domainSize); - FftDiffSolver& setFftDomainConfiguration(const fft::FftDomainConfiguration<Dim>& p_fftConfig); - - FftDiffSolver& setFftFlags(unsigned int p_flags); - FftDiffSolver& appendFftFlags(unsigned int p_flags); - - FftDiffSolver& includeOutputPeriodicBoundaries(bool p_val = true); - FftDiffSolver& excludeOutputPeriodicBoundaries(); - - FftDiffSolver& enableOutputPeriodicBoundariesMirroring(bool p_val = true); - FftDiffSolver& disableOutputPeriodicBoundariesMirroring(); - - /* Accessors */ - std::array<T,Dim> domainSize() const; - fft::FftDomainConfiguration<Dim> inputFftConfig() const; - - unsigned int fftFlags() const; - bool includeOutputPeriodicBds() const; - bool mirrorOutputPeriodicBds() const; - - /* Apply operator */ - virtual void apply(hysop::const_multi_array_ref<T,Dim> p_input, - hysop::multi_array_ref<T,Dim> p_output, - const std::array<int,Dim> &p_order) const final override; - - protected: - std::array<T,Dim> m_domainSize; - fft::FftDomainConfiguration<Dim> m_inputFftConfig; - unsigned int m_fftFlags; - bool m_includeOutputPeriodicBds, m_mirrorOutputPeriodicBds; - }; - - - - /* Implementation */ - - template <typename T, std::size_t Dim> - FftDiffSolver<T,Dim>::FftDiffSolver(const std::array<T,Dim> &p_domainSize, const fft::FftDomainConfiguration<Dim> &p_inputFftConfig, - unsigned int p_fftFlags, - bool p_includeOutputPeriodicBds, bool p_mirrorOutputPeriodicBds): - m_domainSize(p_domainSize), m_inputFftConfig(p_inputFftConfig), - m_fftFlags(p_fftFlags), - m_includeOutputPeriodicBds(p_includeOutputPeriodicBds), m_mirrorOutputPeriodicBds(p_mirrorOutputPeriodicBds) { - } - - - /* Mutators */ - template <typename T, std::size_t Dim> - FftDiffSolver<T,Dim>& FftDiffSolver<T,Dim>::setDomainSize(const std::array<T,Dim>& p_domainSize) { - m_domainSize = p_domainSize; - return *this; - } - template <typename T, std::size_t Dim> - FftDiffSolver<T,Dim>& FftDiffSolver<T,Dim>::setFftDomainConfiguration(const fft::FftDomainConfiguration<Dim>& p_fftConfig) { - m_inputFftConfig = p_fftConfig; - return *this; - } - template <typename T, std::size_t Dim> - FftDiffSolver<T,Dim>& FftDiffSolver<T,Dim>::includeOutputPeriodicBoundaries(bool p_val) { - m_includeOutputPeriodicBds = p_val; - return *this; - } - template <typename T, std::size_t Dim> - FftDiffSolver<T,Dim>& FftDiffSolver<T,Dim>::excludeOutputPeriodicBoundaries() { - return this->includeOutputPeriodicBoundaries(false); - } - template <typename T, std::size_t Dim> - FftDiffSolver<T,Dim>& FftDiffSolver<T,Dim>::setFftFlags(unsigned int p_flags) { - m_fftFlags = p_flags; - return *this; - } - template <typename T, std::size_t Dim> - FftDiffSolver<T,Dim>& FftDiffSolver<T,Dim>::appendFftFlags(unsigned int p_flags) { - m_fftFlags |= p_flags; - return *this; - } - template <typename T, std::size_t Dim> - FftDiffSolver<T,Dim>& FftDiffSolver<T,Dim>::enableOutputPeriodicBoundariesMirroring(bool p_val) { - m_mirrorOutputPeriodicBds = p_val; - return *this; - } - template <typename T, std::size_t Dim> - FftDiffSolver<T,Dim>& FftDiffSolver<T,Dim>::disableOutputPeriodicBoundariesMirroring() { - return this->enableOutputPeriodicBoundariesMirroring(false); - } - - /* Accessors */ - template <typename T, std::size_t Dim> - std::array<T,Dim> FftDiffSolver<T,Dim>::domainSize() const { - return m_domainSize; - } - template <typename T, std::size_t Dim> - fft::FftDomainConfiguration<Dim> FftDiffSolver<T,Dim>::inputFftConfig() const { - return m_inputFftConfig; - } - template <typename T, std::size_t Dim> - unsigned int FftDiffSolver<T,Dim>::fftFlags() const { - return m_fftFlags; - } - template <typename T, std::size_t Dim> - bool FftDiffSolver<T,Dim>::includeOutputPeriodicBds() const { - return m_includeOutputPeriodicBds; - } - template <typename T, std::size_t Dim> - bool FftDiffSolver<T,Dim>::mirrorOutputPeriodicBds() const { - return m_mirrorOutputPeriodicBds; - } - - /* Apply operator */ - template <typename T, std::size_t Dim> - void FftDiffSolver<T,Dim>::apply( - hysop::const_multi_array_ref<T,Dim> p_input, - hysop::multi_array_ref<T,Dim> p_output, - const std::array<int,Dim> &p_order) const { - - fft::Planner<T,Dim> planner; - bool success = planner.plan(p_input, p_output, m_inputFftConfig, p_order, m_domainSize, m_fftFlags, - m_includeOutputPeriodicBds, m_mirrorOutputPeriodicBds); - if(!success) - throw std::runtime_error("Failed to plan transforms !"); - - planner.executeForwardTransform(); - { - AccumulatorIndex<std::complex<T>,Dim> idx; - idx.setAccumulatorSource(planner.waveNumbersPows()).setAccumulatorFunction(std::multiplies<std::complex<T>>()); - - if(planner.transformType() == fft::FftTransformType::FFT_R2R) { - multi_array_view<T,Dim> view = planner.transformedRealData(); - //view.print("PRE-RDATA"); - - idx.reset(view.shape()); - while(!idx.atMaxId()) { - view(idx.ids()) *= idx.accumulatedVal().real()/planner.normalisationFactor(); - ++idx; - } - - //view.print("POST-RDATA"); - } - else if(planner.transformType() == fft::FftTransformType::FFT_R2C) { - multi_array_ref<std::complex<T>,Dim> ref = planner.transformedComplexData(); - std::complex<T> *data = ref.data(); - //ref.print("PRE-CDATA"); - - idx.reset(ref.shape()); - while(!idx.atMaxId()) { - data[idx()] *= idx.accumulatedVal()/planner.normalisationFactor(); - ++idx; - } - - //ref.print("POST-CDATA"); - } - } - planner.executeBackwardTransform(); - } - - } /* end of namespace solver */ -} /* end of namespace hysop */ - - - -#endif /* end of include guard: HYSOP_FFTDIFFSOLVER_H */ diff --git a/src/hysop++/src/solver/fftPoissonSolver.h b/src/hysop++/src/solver/fftPoissonSolver.h deleted file mode 100644 index 5e9ac41c0..000000000 --- a/src/hysop++/src/solver/fftPoissonSolver.h +++ /dev/null @@ -1,206 +0,0 @@ - -#ifndef HYSOP_FFTPOISSONSOLVER_H -#define HYSOP_FFTPOISSONSOLVER_H - -#include <cmath> - -#include "maths/quad_maths.h" -#include "solver/poissonSolver.h" -#include "fft/planner.h" -#include "data/accumulatorIndex.h" - -namespace hysop { - namespace solver { - - template <typename T, std::size_t Dim> - class FftPoissonSolver : public PoissonSolver<T,Dim> { - - private: - using super = PoissonSolver<T,Dim>; - public: - FftPoissonSolver() = default; - FftPoissonSolver(const FftPoissonSolver& p_other) = default; - FftPoissonSolver( FftPoissonSolver&& p_other) = default; - ~FftPoissonSolver() = default; - - FftPoissonSolver& operator=(const FftPoissonSolver& p_other) = default; - FftPoissonSolver& operator=( FftPoissonSolver&& p_other) = default; - - FftPoissonSolver(const std::array<T,Dim> &p_domainSize, const domain::DomainConfiguration<Dim> &p_domainConfig, - unsigned int p_fftFlags = FFTW_MEASURE, - bool p_includeOutputPeriodicBds=false, bool p_mirrorOutputPeriodicBds=false); - - /* Mutators */ - FftPoissonSolver& setDomainSize(const std::array<T,Dim>& p_domainSize); - FftPoissonSolver& setInputDomainConfiguration(const domain::DomainConfiguration<Dim>& p_domainConfig); - - FftPoissonSolver& setFftFlags(unsigned int p_flags); - FftPoissonSolver& appendFftFlags(unsigned int p_flags); - - FftPoissonSolver& includeOutputPeriodicBoundaries(bool p_val = true); - FftPoissonSolver& excludeOutputPeriodicBoundaries(); - - FftPoissonSolver& enableOutputPeriodicBoundariesMirroring(bool p_val = true); - FftPoissonSolver& disableOutputPeriodicBoundariesMirroring(); - - /* Accessors */ - std::array<T,Dim> domainSize() const; - domain::DomainConfiguration<Dim> inputDomainConfig() const; - - unsigned int fftFlags() const; - bool includeOutputPeriodicBds() const; - bool mirrorOutputPeriodicBds() const; - - /* Apply operator */ - virtual void apply(hysop::const_multi_array_ref<T,Dim> p_input, - hysop::multi_array_ref<T,Dim> p_output) const final override; - - protected: - std::array<T,Dim> m_domainSize; - domain::DomainConfiguration<Dim> m_inputDomainConfig; - unsigned int m_fftFlags; - bool m_includeOutputPeriodicBds, m_mirrorOutputPeriodicBds; - }; - - - - /* Implementation */ - - template <typename T, std::size_t Dim> - FftPoissonSolver<T,Dim>::FftPoissonSolver(const std::array<T,Dim> &p_domainSize, const domain::DomainConfiguration<Dim> &p_inputDomainConfig, - unsigned int p_fftFlags, - bool p_includeOutputPeriodicBds, bool p_mirrorOutputPeriodicBds): - m_domainSize(p_domainSize), m_inputDomainConfig(p_inputDomainConfig), - m_fftFlags(p_fftFlags), - m_includeOutputPeriodicBds(p_includeOutputPeriodicBds), m_mirrorOutputPeriodicBds(p_mirrorOutputPeriodicBds) { - } - - - /* Mutators */ - template <typename T, std::size_t Dim> - FftPoissonSolver<T,Dim>& FftPoissonSolver<T,Dim>::setDomainSize(const std::array<T,Dim>& p_domainSize) { - m_domainSize = p_domainSize; - return *this; - } - template <typename T, std::size_t Dim> - FftPoissonSolver<T,Dim>& FftPoissonSolver<T,Dim>::setInputDomainConfiguration(const domain::DomainConfiguration<Dim>& p_inputDomainConfig) { - m_inputDomainConfig = p_inputDomainConfig; - return *this; - } - template <typename T, std::size_t Dim> - FftPoissonSolver<T,Dim>& FftPoissonSolver<T,Dim>::includeOutputPeriodicBoundaries(bool p_val) { - m_includeOutputPeriodicBds = p_val; - return *this; - } - template <typename T, std::size_t Dim> - FftPoissonSolver<T,Dim>& FftPoissonSolver<T,Dim>::excludeOutputPeriodicBoundaries() { - return this->includeOutputPeriodicBoundaries(false); - } - template <typename T, std::size_t Dim> - FftPoissonSolver<T,Dim>& FftPoissonSolver<T,Dim>::setFftFlags(unsigned int p_flags) { - m_fftFlags = p_flags; - return *this; - } - template <typename T, std::size_t Dim> - FftPoissonSolver<T,Dim>& FftPoissonSolver<T,Dim>::appendFftFlags(unsigned int p_flags) { - m_fftFlags |= p_flags; - return *this; - } - template <typename T, std::size_t Dim> - FftPoissonSolver<T,Dim>& FftPoissonSolver<T,Dim>::enableOutputPeriodicBoundariesMirroring(bool p_val) { - m_mirrorOutputPeriodicBds = p_val; - return *this; - } - template <typename T, std::size_t Dim> - FftPoissonSolver<T,Dim>& FftPoissonSolver<T,Dim>::disableOutputPeriodicBoundariesMirroring() { - return this->enableOutputPeriodicBoundariesMirroring(false); - } - - /* Accessors */ - template <typename T, std::size_t Dim> - std::array<T,Dim> FftPoissonSolver<T,Dim>::domainSize() const { - return m_domainSize; - } - template <typename T, std::size_t Dim> - domain::DomainConfiguration<Dim> FftPoissonSolver<T,Dim>::inputDomainConfig() const { - return m_inputDomainConfig; - } - template <typename T, std::size_t Dim> - unsigned int FftPoissonSolver<T,Dim>::fftFlags() const { - return m_fftFlags; - } - template <typename T, std::size_t Dim> - bool FftPoissonSolver<T,Dim>::includeOutputPeriodicBds() const { - return m_includeOutputPeriodicBds; - } - template <typename T, std::size_t Dim> - bool FftPoissonSolver<T,Dim>::mirrorOutputPeriodicBds() const { - return m_mirrorOutputPeriodicBds; - } - - /* Apply operator */ - template <typename T, std::size_t Dim> - void FftPoissonSolver<T,Dim>::apply( - hysop::const_multi_array_ref<T,Dim> p_input, - hysop::multi_array_ref<T,Dim> p_output) const { - - - fft::Planner<T,Dim> planner; - planner.setFixedAxeWaveNumberPows(std::complex<T>(0,0)); - { - std::array<int, Dim> order; - for (std::size_t d=0; d<Dim; d++) - order[d] = (m_inputDomainConfig[d].first == domain::Boundary::NONE ? 0 : 2); - bool success = planner.plan(p_input, p_output, m_inputDomainConfig, order, m_domainSize, m_fftFlags, - m_includeOutputPeriodicBds, m_mirrorOutputPeriodicBds); - if(!success) - throw std::runtime_error("Failed to plan transforms !"); - } - const T normalisationFactor = planner.normalisationFactor(); - //std::cout << planner << std::endl; - - planner.executeForwardTransform(); - { - AccumulatorIndex<std::complex<T>,Dim> idx; - idx.setAccumulatorSource(planner.waveNumbersPows()).setAccumulatorFunction(std::plus<std::complex<T>>()); - - if(planner.transformType() == fft::FftTransformType::FFT_R2R) { - multi_array_view<T,Dim> view = planner.transformedRealData(); - //view.print("PRE-RDATA"); - - idx.reset(view.shape()); - while(!idx.atMaxId()) { - T filter = idx.accumulatedVal().real(); - filter = (std::fpclassify(filter)==FP_ZERO ? T(0) : (T(1)/filter)*(T(1)/normalisationFactor)); - view(idx.ids()) *= filter; - ++idx; - } - - //view.print("POST-RDATA"); - } - else if(planner.transformType() == fft::FftTransformType::FFT_R2C) { - multi_array_ref<std::complex<T>,Dim> ref = planner.transformedComplexData(); - std::complex<T> *data = ref.data(); - //ref.print("PRE-CDATA"); - - idx.reset(ref.shape()); - while(!idx.atMaxId()) { - std::complex<T> filter = idx.accumulatedVal(); - filter = ((std::fpclassify(filter.real())==FP_ZERO) && (std::fpclassify(filter.imag())==FP_ZERO) ? - std::complex<T>(0,0) : (T(1)/filter)*(T(1)/normalisationFactor)); - data[idx()] *= filter; - ++idx; - } - - //ref.print("POST-CDATA"); - } - } - planner.executeBackwardTransform(); - } - - } /* end of namespace solver */ -} /* end of namespace hysop */ - - - -#endif /* end of include guard: HYSOP_FFTPOISSONSOLVER_H */ diff --git a/src/hysop++/src/solver/poissonSolver.h b/src/hysop++/src/solver/poissonSolver.h deleted file mode 100644 index 61b16440a..000000000 --- a/src/hysop++/src/solver/poissonSolver.h +++ /dev/null @@ -1,27 +0,0 @@ - -#ifndef HYSOP_POISSONSOLVER_H -#define HYSOP_POISSONSOLVER_H - -#include "data/multi_array/multi_array.h" - -namespace hysop { - namespace solver { - template <typename T, std::size_t Dim> - class PoissonSolver { - - public: - virtual void apply(hysop::const_multi_array_ref<T,Dim> input, - hysop::multi_array_ref<T,Dim> output) const = 0; - - void operator()(hysop::const_multi_array_ref<T,Dim> input, - hysop::multi_array_ref<T,Dim> output) { - this->apply(input,output); - } - - }; - - } /* end of namespace solver */ -} /* end of namespace hysop */ - -#endif /* end of include guard: HYSOP_POISSONSOLVER_H */ - diff --git a/src/hysop++/src/utils/constants.h b/src/hysop++/src/utils/constants.h deleted file mode 100644 index 585ed629e..000000000 --- a/src/hysop++/src/utils/constants.h +++ /dev/null @@ -1,22 +0,0 @@ - -#ifndef CONSTANTS_H -#define CONSTANTS_H - -#include <cmath> -#include "maths/quad_maths.h" -#include "utils/types.h" - -namespace hysop { - namespace constants { - static constexpr hysop::types::complex I = hysop::types::complex(0,1); - static constexpr hysop::types::complex Z = hysop::types::complex(0,0); - -#ifdef HAS_QUADMATHS - static const __float128 pi = acosq(-1.0Q); -#else - static const long double pi = acosl(-1.0L); -#endif - } -} - -#endif /* end of include guard: CONSTANTS_H */ diff --git a/src/hysop++/src/utils/default.h b/src/hysop++/src/utils/default.h deleted file mode 100644 index efeacfb8d..000000000 --- a/src/hysop++/src/utils/default.h +++ /dev/null @@ -1,20 +0,0 @@ - -#ifndef HYSOP_DEFAULT_H -#define HYSOP_DEFAULT_H - -#include "data/memory/minimalAllocator.h" -#include "data/memory/fftwAllocator.h" - -namespace hysop { - namespace _default { - - template <typename T> - using allocator = hysop::data::memory::MinimalAllocator<T>; - - template <typename T> - using fft_allocator = hysop::data::memory::FftwAllocator<T>; - - } /* end of namespace _default */ -} /* end of namespace hysop */ - -#endif /* end of include guard: HYSOP_DEFAULT_H */ diff --git a/src/hysop++/src/utils/defines.h b/src/hysop++/src/utils/defines.h deleted file mode 100644 index b456d75fa..000000000 --- a/src/hysop++/src/utils/defines.h +++ /dev/null @@ -1,46 +0,0 @@ - -#ifndef HYSOP_DEFINES_H -#define HYSOP_DEFINES_H - -#include <stdexcept> -#include <string> - -#if __cplusplus >= 201103L -#define HAS_CXX11 -#endif - -#if __cplusplus >= 201402L -#define HAS_CXX14 -#endif - -#define CAT(X,Y) CAT2(X,Y) -#define CAT2(X,Y) X##Y -#define CAT_2 CAT -#define CAT_3(X,Y,Z) CAT(X,CAT(Y,Z)) -#define CAT_4(A,X,Y,Z) CAT(A,CAT_3(X,Y,Z)) -#define CAT_5(A,B,X,Y,Z) CAT_3(A,B,CAT_3(X,Y,Z)) - -#define NOT_IMPLEMENTED_YET { \ - throw std::runtime_error("Function not implemented yet in " + std::string(__FILE__) + ":" + std::to_string(__LINE__) + "."); \ -} - -//Linux console colors -#define RESET "\033[0m" -#define BLACK "\033[30m" /* Black */ -#define RED "\033[31m" /* Red */ -#define GREEN "\033[32m" /* Green */ -#define YELLOW "\033[33m" /* Yellow */ -#define BLUE "\033[34m" /* Blue */ -#define MAGENTA "\033[35m" /* Magenta */ -#define CYAN "\033[36m" /* Cyan */ -#define WHITE "\033[37m" /* White */ -#define BOLDBLACK "\033[1m\033[30m" /* Bold Black */ -#define BOLDRED "\033[1m\033[31m" /* Bold Red */ -#define BOLDGREEN "\033[1m\033[32m" /* Bold Green */ -#define BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */ -#define BOLDBLUE "\033[1m\033[34m" /* Bold Blue */ -#define BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */ -#define BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */ -#define BOLDWHITE "\033[1m\033[37m" /* Bold White */ - -#endif /* end of include guard: HYSOP_DEFINES_H */ diff --git a/src/hysop++/src/utils/types.h b/src/hysop++/src/utils/types.h deleted file mode 100644 index ccbd3c345..000000000 --- a/src/hysop++/src/utils/types.h +++ /dev/null @@ -1,63 +0,0 @@ - -#ifndef HYSOP_TYPES_H -#define HYSOP_TYPES_H - -#include <complex> -#include <array> - -#include "utils/utils.h" -#include "utils/default.h" - -namespace hysop { - - /* forward declare external types */ - namespace data { - template <typename T, std::size_t Dim, typename Allocator> - class multi_array; - template <typename T, std::size_t Dim> - class multi_array_ref; - template <typename T, std::size_t Dim> - class multi_array_view; - template <typename T, std::size_t Dim> - class const_multi_array_view; - template <typename T, std::size_t Dim> - class const_multi_array_ref; - } /* end of namespace data */ - - - namespace types { - typedef double real; - typedef std::complex<real> complex; - } /* end of namespace types */ - - -/* expose the folowwing types to namespace hysop */ - -/* swig does not support alias templates... */ - template <std::size_t Dim> - struct Shape { - typedef std::array<std::size_t, Dim> type; - }; - template <std::size_t Dim> - struct Offset { - typedef std::array<std::ptrdiff_t, Dim> type; - }; - - template <typename T, std::size_t Dim, typename Allocator = hysop::_default::allocator<T>> - using multi_array = hysop::data::multi_array<T,Dim,Allocator>; - - template <typename T, std::size_t Dim> - using multi_array_view = hysop::data::multi_array_view<T,Dim>; - - template <typename T, std::size_t Dim> - using const_multi_array_view = hysop::data::const_multi_array_view<T,Dim>; - - template <typename T, std::size_t Dim> - using multi_array_ref = hysop::data::multi_array_ref<T,Dim>; - - template <typename T, std::size_t Dim> - using const_multi_array_ref = hysop::data::const_multi_array_ref<T,Dim>; - -} /* end of namespace hysop */ - -#endif /* end of include guard: HYSOP_TYPES_H */ diff --git a/src/hysop++/src/utils/utils.cpp b/src/hysop++/src/utils/utils.cpp deleted file mode 100644 index 501243272..000000000 --- a/src/hysop++/src/utils/utils.cpp +++ /dev/null @@ -1,17 +0,0 @@ - -#include "utils/utils.h" - -namespace std { - std::ostream& operator<<(std::ostream& os, const fftw_iodim& iodim) { - os << "[n=" << iodim.n << ", is=" << iodim.is << ", os=" << iodim.os << "]"; - return os; - } -} - -namespace hysop { - namespace utils { - - } -} - - diff --git a/src/hysop++/src/utils/utils.h b/src/hysop++/src/utils/utils.h deleted file mode 100644 index 4eaf5fcac..000000000 --- a/src/hysop++/src/utils/utils.h +++ /dev/null @@ -1,197 +0,0 @@ - -#ifndef HYSOP_UTILS_H -#define HYSOP_UTILS_H - -#include <fftw3.h> -#include <array> -#include <vector> -#include <tuple> -#include <iostream> -#include <limits> - -#include "maths/quad_maths.h" -#include "detail/index_seq.h" -#include <boost/multi_array.hpp> - -namespace hysop { - namespace utils { - - template <typename... T> - void printTuple(std::ostream& os, const std::tuple<T...>& tuple); - - template <typename T> - bool areEqual(const T &lhs, const T &rhs); - template <typename T> - bool areNotEqual(const T &lhs, const T &rhs); - - - /* boost related utilities */ - template <std::size_t NumDims> - boost::detail::multi_array::index_gen<NumDims, NumDims> buildView(); - - template <std::size_t NumDims> - boost::detail::multi_array::index_gen<NumDims, NumDims> buildIndices( - const std::array<boost::multi_array_types::index_range, NumDims> &p_ranges); - - template <std::size_t NumRanges> - boost::detail::multi_array::extent_gen<NumRanges> buildExtents( - const std::array<std::size_t, NumRanges> &p_shape); - - - /* Implementation */ - - template <typename Tuple, int... I> - void printTupleImpl(std::ostream& os, const Tuple& tuple, hysop::detail::index_seq<I...>) { - const int dummy[sizeof...(I)] = { (os << std::get<I>(tuple) << ",", 0)... }; - os << std::get<sizeof...(I)>(tuple); - } - template <typename... T> - void printTuple(std::ostream& os, const std::tuple<T...>& tuple) { - os << "("; - printTupleImpl(os,tuple, hysop::detail::index_seq_gen<sizeof...(T)-1>()); - os << ")"; - } - - template <typename T, typename> - bool areEqualImpl(const T& lhs, const T& rhs) { - return lhs == rhs; - } - template <typename T, typename std::enable_if<std::is_floating_point<T>::value, int>::type* = nullptr> - bool areEqualImpl(const T& lhs, const T& rhs) { - return (std::abs(rhs - lhs) <= std::numeric_limits<T>::epsilon() * std::max(std::abs(lhs), std::abs(rhs))); - } - - template <typename T> - bool areEqual(const T &lhs, const T &rhs) { - return areEqualImpl<T>(lhs,rhs); - } - template <typename T> - bool areNotEqual(const T &lhs, const T &rhs) { - return !areEqualImpl<T>(lhs,rhs); - } - - - /* boost related utilities */ - template <std::size_t NumDims> - struct BuildViewImpl { - static_assert(NumDims >= 1, "NumDims cannot be < 1"); - boost::detail::multi_array::index_gen<NumDims, NumDims> build() const { - return BuildViewImpl<NumDims-1>().build()[boost::multi_array_types::index_range()]; - } - }; - template <> - struct BuildViewImpl<1> { - boost::detail::multi_array::index_gen<1,1> build() const { - return boost::multi_array_types::index_gen()[boost::multi_array_types::index_range()]; - } - }; - template <std::size_t NumDims> - boost::detail::multi_array::index_gen<NumDims, NumDims> buildView() { - return BuildViewImpl<NumDims>().build(); - } - - template <std::size_t NumDims, std::size_t K=NumDims> - struct BuildIndicesImpl { - static_assert(NumDims >= 1, "NumDims cannot be < 1"); - const std::array<boost::multi_array_types::index_range, NumDims> &m_ranges; - BuildIndicesImpl(const std::array<boost::multi_array_types::index_range, NumDims> &p_ranges): m_ranges(p_ranges) {} - boost::detail::multi_array::index_gen<K,K> build() const { - return BuildIndicesImpl<NumDims,K-1>(m_ranges).build()[m_ranges[K-1]]; - } - }; - template <std::size_t NumDims> - struct BuildIndicesImpl<NumDims,1> { - const std::array<boost::multi_array_types::index_range, NumDims> &m_ranges; - BuildIndicesImpl(const std::array<boost::multi_array_types::index_range, NumDims> &p_ranges): m_ranges(p_ranges) {} - boost::detail::multi_array::index_gen<1,1> build() const { - return boost::multi_array_types::index_gen()[m_ranges[0]]; - } - }; - template <std::size_t NumDims> - boost::detail::multi_array::index_gen<NumDims, NumDims> buildIndices( - const std::array<boost::multi_array_types::index_range, NumDims> &p_ranges) { - return BuildIndicesImpl<NumDims>(p_ranges).build(); - } - - template <std::size_t NumRanges, std::size_t K=NumRanges> - struct BuildExtentImpl { - static_assert(NumRanges >= 1, "NumDims cannot be < 1"); - const std::array<std::size_t,NumRanges>& m_shape; - BuildExtentImpl(const std::array<std::size_t, NumRanges>& p_shape): m_shape(p_shape) {} - boost::detail::multi_array::extent_gen<K> build() const { - return BuildExtentImpl<NumRanges,K-1>(m_shape).build()[m_shape[K-1]]; - } - }; - template <std::size_t NumRanges> - struct BuildExtentImpl<NumRanges,1> { - const std::array<std::size_t,NumRanges>& m_shape; - BuildExtentImpl(const std::array<std::size_t, NumRanges>& p_shape): m_shape(p_shape) {} - boost::detail::multi_array::extent_gen<1> build() const { - return boost::multi_array_types::extent_gen()[m_shape[0]]; - } - }; - template <std::size_t NumRanges> - boost::detail::multi_array::extent_gen<NumRanges> buildExtents( - const std::array<std::size_t, NumRanges> &p_shape) { - return BuildExtentImpl<NumRanges>(p_shape).build(); - } - } -} - - -/* quick and dirty fix to allow non namespace dependant operators << for std containers */ -namespace std { - - template <typename T, std::size_t Dim> - std::ostream& operator<<(std::ostream& os, const std::array<T,Dim>& array); - template <typename T, std::size_t Dim> - std::ostream& operator<<(std::ostream& os, const boost::array<T,Dim>& array); - - template <typename T> - std::ostream& operator<<(std::ostream& os, const std::vector<T>& vector); - - template <typename... T> - std::ostream& operator<<(std::ostream& os, const std::tuple<T...>& tuple); - - std::ostream& operator<<(std::ostream& os, const fftw_iodim& iodim); - - - - /* Implementation */ - template <typename T, std::size_t Dim> - std::ostream& operator<<(std::ostream& os, const std::array<T,Dim>& array) { - os << "["; - for (std::size_t i = 0; i < Dim-1; i++) - os << array[i] << ","; - os << array[Dim-1]; - os << "]"; - return os; - } - template <typename T, std::size_t Dim> - std::ostream& operator<<(std::ostream& os, const boost::array<T,Dim>& array) { - os << "["; - for (std::size_t i = 0; i < Dim-1; i++) - os << array[i] << ","; - os << array[Dim-1]; - os << "]"; - return os; - } - template <typename T> - std::ostream& operator<<(std::ostream& os, const std::vector<T>& vector) { - os << "["; - if(!vector.empty()) { - for (std::size_t i = 0; i < vector.size()-1; i++) - os << vector[i] << ","; - os << vector[vector.size()-1]; - } - os << "]"; - return os; - } - template <typename... T> - std::ostream& operator<<(std::ostream& os, const std::tuple<T...>& tuple) { - hysop::utils::printTuple(os,tuple); - return os; - } -} - -#endif /* end of include guard: HYSOP_UTILS_H */ diff --git a/src/hysop++/tests/CMakeLists.txt b/src/hysop++/tests/CMakeLists.txt deleted file mode 100644 index 30668e041..000000000 --- a/src/hysop++/tests/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ - -include("${CMAKE_SOURCE_DIR}/cmake/GoogleTestHelper.cmake") - -add_subdirectory("testPolynoms") -add_subdirectory("testPlanner") -add_subdirectory("testDiffSolver") -add_subdirectory("testPoissonSolver") diff --git a/src/hysop++/tests/testDiffSolver/CMakeLists.txt b/src/hysop++/tests/testDiffSolver/CMakeLists.txt deleted file mode 100644 index 6f3ddcdc8..000000000 --- a/src/hysop++/tests/testDiffSolver/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ - -file(GLOB CPP_SRCS *.cpp) -set(SRCS ${CPP_SRCS}) - -get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) -add_definitions(${CXX_EXTRA_DEFINES}) -add_executable(${test_name} ${SRCS}) -add_dependencies(${test_name} ${HYSOP_CXX_LIBRARY_DEP}) - -target_link_libraries(${test_name} ${HYSOP_CXX_LIBRARY}) -target_link_libraries(${test_name} ${GTEST_LIBRARIES} ${CXX_EXT_LIBS}) - -add_test("${test_name}" "${test_name}") - diff --git a/src/hysop++/tests/testDiffSolver/main.cpp b/src/hysop++/tests/testDiffSolver/main.cpp deleted file mode 100644 index b6141085e..000000000 --- a/src/hysop++/tests/testDiffSolver/main.cpp +++ /dev/null @@ -1,10 +0,0 @@ - -#include "gtest/gtest.h" - -int main(int argc, char **argv) -{ - ::testing::InitGoogleTest(&argc, argv); - int ret = RUN_ALL_TESTS(); - - return ret; -} diff --git a/src/hysop++/tests/testDiffSolver/testDiffSolver.cpp b/src/hysop++/tests/testDiffSolver/testDiffSolver.cpp deleted file mode 100644 index 55fec62f5..000000000 --- a/src/hysop++/tests/testDiffSolver/testDiffSolver.cpp +++ /dev/null @@ -1,243 +0,0 @@ - -#include "testDiffSolver.h" - -#include <cstdlib> - -#include "domain/domain.h" -#include "solver/fftDiffSolver.h" -#include "data/multi_array/multi_array.h" -#include "utils/constants.h" -#include "fft/extension.h" - -using namespace hysop; -using namespace hysop::domain; - -static constexpr std::size_t nExtensions = 4 ; -static constexpr std::size_t nExtensionsPair = 7 ; -static constexpr fft::Extension ext[nExtensions] = -{ fft::Extension::NONE, fft::Extension::ODD, fft::Extension::EVEN, fft::Extension::PERIODIC }; -static constexpr std::pair<fft::Extension,fft::Extension> pext[nExtensionsPair] { - std::make_pair(ext[3],ext[3]), //periodic-periodic - std::make_pair(ext[3],ext[3]), //periodic-periodic - std::make_pair(ext[2],ext[1]), //even-odd - std::make_pair(ext[1],ext[2]), //odd-even - std::make_pair(ext[2],ext[2]), //even-even - std::make_pair(ext[1],ext[1]), //odd-odd - std::make_pair(ext[0],ext[0]), //none-none -}; - -#ifdef HAS_QUADMATHS - static constexpr __float128 freqs[6] = { 1.0Q, 1.0Q, 0.75Q, 0.75Q, 0.50Q, 0.50Q }; -#else - static constexpr long double freqs[6] = { 1.0L, 1.0L, 0.75L, 0.75L, 0.50L, 0.50L }; -#endif - -template <typename T> -std::function<T(T)> func(std::size_t k) { - switch(k) { - case 0: return [=](T x) {return std::cos(T(freqs[0])*x);}; - case 1: return [=](T x) {return std::sin(T(freqs[1])*x);}; - case 2: return [=](T x) {return std::cos(T(freqs[2])*x);}; - case 3: return [=](T x) {return std::sin(T(freqs[3])*x);}; - case 4: return [=](T x) {return std::cos(T(freqs[4])*x);}; - case 5: return [=](T x) {return std::sin(T(freqs[5])*x);}; - default: return[=](T x) { return T(1); }; - } -} - -template <typename T> -std::function<T(T)> derivative(std::size_t k, int order) { - bool even = (k%2==0); - std::size_t p, offset; - T sign, coeff; - if(k>5) { - if(order != 0) - throw std::runtime_error("Non zero order !"); - return func<T>(k); - } - else if(even) { /* cos func */ - p = (order%2==0 ? k : k+1); - sign = std::pow(T(-1),(order+1)/2); - coeff = std::pow(freqs[k], order); - } - else { /* sin func */ - p = (order%2==0 ? k : k-1); - sign = std::pow(T(-1),order/2); - coeff = std::pow(freqs[k], order); - } - return [=](T x) { return sign*coeff*(func<T>(p)(x)); }; -} - -template <typename T, std::size_t Dim, bool verbose=false> -void test(std::size_t p_maxOrder, bool includePeriodicBds=false) { - typename Shape<Dim>::type shape; - typename Domain<T,Dim>::DomainSize domainSize; - Domain<T,Dim> ref, inBuffer, outBuffer; - - Domain<T,Dim>& in = inBuffer; - Domain<T,Dim>& out = outBuffer; - - std::array<int,Dim> order; - - shape.fill(8); - domainSize.fill(2*hysop::constants::pi); - - T eps = std::numeric_limits<T>::epsilon(); - const std::size_t N = std::accumulate(shape.begin(), shape.end(), 1, std::multiplies<std::size_t>()); - - ref.resize(domainSize).reshape(shape); - in = ref; - out = ref; - - typename Shape<Dim>::type maxOrder, testCases; - maxOrder.fill(p_maxOrder+1); - testCases.fill(nExtensionsPair); - Index<Dim> orderId(maxOrder); - Index<Dim> testCaseId; - std::size_t testCaseCount; - while(!(++orderId).atMaxId()) { - std::cout << " ::Order::" << orderId.ids() << (verbose ? "\n" : ""); - - std::array<T,3> meanDists; - meanDists.fill(0); - testCaseId.reset(testCases); - testCaseCount = testCaseId.maxId(); - while(!testCaseId.atMaxId()) { - std::copy(orderId.ids().begin(),orderId.ids().end(), order.begin()); - - /* generate transform configuration */ - std::array<std::pair<fft::Extension,fft::Extension>, Dim> extConfig; - for (std::size_t k=0; k<Dim; k++) { - std::size_t id = testCaseId[k]; - extConfig[k] = pext[id]; - if(pext[id].first==fft::Extension::NONE) - order[k] = 0; - } - fft::FftDomainConfiguration<Dim> domainConfig(extConfig, includePeriodicBds); - - const std::size_t orderSum = std::accumulate(order.begin(), order.end(), 0); - if(orderSum == 0) { - testCaseCount--; - ++testCaseId; - continue; - } - T orderPow = std::pow(T(10),T(orderSum)); - if(std::is_same<T,long double>::value) /* just in case long doubles are not hardware supported... */ - orderPow *= 1e3; - const auto criteria = std::make_tuple(orderPow*eps*N,orderPow*eps*sqrt(N),2*orderPow*eps); - - const auto f = [&](const typename Domain<T,Dim>::SpaceVariable &x) { - T val = func<T>(testCaseId[0])(x[0]); - for (std::size_t d=1; d < Dim; d++) - val *= func<T>(testCaseId[d])(x[d]); - return val; - }; - const auto d = [&](const typename Domain<T,Dim>::SpaceVariable &x) { - T val = derivative<T>(testCaseId[0],order[0])(x[0]); - for (std::size_t d=1; d < Dim; d++) - val *= derivative<T>(testCaseId[d],order[d])(x[d]); - return val; - }; - { - ref.resetDomainConfiguration(domainConfig.boundariesConfiguration()); - in = ref; - out = ref; - - in.apply(f); - ref.apply(d); - out.data().apply([](T& v){ v=T(0);}); - } - - solver::FftDiffSolver<T,Dim> solver(domainSize, domainConfig, FFTW_MEASURE, includePeriodicBds, includePeriodicBds); - solver.apply(in.data(), out.data(), order); - - std::stringstream ss; - ss << "["; - for (std::size_t k=0; k<Dim-1; k++) - ss << extConfig[k].first << "/" << extConfig[k].second << ","; - ss << extConfig[Dim-1].first << "/" << extConfig[Dim-1].second; - ss << "]"; - - const auto dist = out.distance(ref); - const bool pass = (std::get<0>(dist) < std::get<0>(criteria)) - && (std::get<1>(dist) < std::get<1>(criteria)) - && (std::get<2>(dist) < std::get<2>(criteria)); - - if((pass && verbose) || !pass) { - std::cout << (pass ? GREEN : RED); - std::cout << "\t" << std::setw(Dim*15) << ss.str() << " => " << (pass ? "OK" : "KO") - << " " << RESET << std::scientific << std::setprecision(2) << dist << std::endl; - } - if(!pass) { - //in.print("IN"); - //ref.print("REF"); - //out.print("OUT"); - std::cout << "Test failed => Criteria was: " << criteria << std::endl; - } - - meanDists[0] += std::get<0>(dist); - meanDists[1] += std::get<1>(dist); - meanDists[2] += std::get<2>(dist); - - EXPECT_TRUE(pass); - - ++testCaseId; - } - for (std::size_t k = 0; k < 3; k++) - meanDists[k] /= T(testCaseCount); - std::cout << "=> mean distances over " << std::scientific << std::setprecision(1) << std::setw(4) - << testCaseCount << " testcases: " << meanDists; - for (std::size_t k = 0; k < 3; k++) - meanDists[k] = std::round(meanDists[k]/eps); - std::cout << " ~= " << std::fixed << std::setprecision(0) << meanDists << " eps" << std::endl; - } -} - -#ifdef FFTW_HAS_FFTW3F -TEST_F(DiffSolverTest, FloatDerivatives) { - std::cout << std::endl; - std::cout << "== TEST 1D - float ==" << std::endl; - test<float,1,false>(5); - std::cout << "== TEST 2D - float ==" << std::endl; - test<float,2,false>(3); - std::cout << "== TEST 3D - float ==" << std::endl; - test<float,3,false>(1); -} -#endif - -#ifdef FFTW_HAS_FFTW3D -TEST_F(DiffSolverTest, DoubleDerivatives) { - std::cout << std::endl; - std::cout << "== TEST 1D - double ==" << std::endl; - test<double,1,false>(5); - std::cout << "== TEST 2D - double ==" << std::endl; - test<double,2,false>(3); - std::cout << "== TEST 3D - double ==" << std::endl; - test<double,3,false>(1); -} -#endif - -#ifdef FFTW_HAS_FFTW3L -TEST_F(DiffSolverTest, LongDoubleDerivatives) { - std::cout << std::endl; - std::cout << "== TEST 1D - long double ==" << std::endl; - test<long double,1,false>(5); - std::cout << "== TEST 2D - long double ==" << std::endl; - test<long double,2,false>(3); - std::cout << "== TEST 3D - long double ==" << std::endl; - test<long double,3,false>(1); -} -#endif - -#ifdef FFTW_HAS_FFTW3Q -TEST_F(DiffSolverTest, QuadFloatDerivatives) { - std::cout << std::endl; - std::cout << "== TEST 1D - __float128 ==" << std::endl; - test<__float128,1,false>(5); - std::cout << "== TEST 2D - __float128 ==" << std::endl; - test<__float128,2,false>(3); - std::cout << "== TEST 3D - __float128 ==" << std::endl; - test<__float128,3,false>(1); -} -#endif - diff --git a/src/hysop++/tests/testDiffSolver/testDiffSolver.h b/src/hysop++/tests/testDiffSolver/testDiffSolver.h deleted file mode 100644 index b51090915..000000000 --- a/src/hysop++/tests/testDiffSolver/testDiffSolver.h +++ /dev/null @@ -1,14 +0,0 @@ - -#include "gtest/gtest.h" -#include "solver/fftDiffSolver.h" -#include "fft/extension.h" - -using namespace hysop; - -class DiffSolverTest : public ::testing::Test { - protected: - DiffSolverTest() {} - void SetUp() {} - void TearDown() {} - virtual ~DiffSolverTest() {} -}; diff --git a/src/hysop++/tests/testPlanner/CMakeLists.txt b/src/hysop++/tests/testPlanner/CMakeLists.txt deleted file mode 100644 index 6f3ddcdc8..000000000 --- a/src/hysop++/tests/testPlanner/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ - -file(GLOB CPP_SRCS *.cpp) -set(SRCS ${CPP_SRCS}) - -get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) -add_definitions(${CXX_EXTRA_DEFINES}) -add_executable(${test_name} ${SRCS}) -add_dependencies(${test_name} ${HYSOP_CXX_LIBRARY_DEP}) - -target_link_libraries(${test_name} ${HYSOP_CXX_LIBRARY}) -target_link_libraries(${test_name} ${GTEST_LIBRARIES} ${CXX_EXT_LIBS}) - -add_test("${test_name}" "${test_name}") - diff --git a/src/hysop++/tests/testPlanner/main.cpp b/src/hysop++/tests/testPlanner/main.cpp deleted file mode 100644 index b6141085e..000000000 --- a/src/hysop++/tests/testPlanner/main.cpp +++ /dev/null @@ -1,10 +0,0 @@ - -#include "gtest/gtest.h" - -int main(int argc, char **argv) -{ - ::testing::InitGoogleTest(&argc, argv); - int ret = RUN_ALL_TESTS(); - - return ret; -} diff --git a/src/hysop++/tests/testPlanner/testPlanner.cpp b/src/hysop++/tests/testPlanner/testPlanner.cpp deleted file mode 100644 index aab308e98..000000000 --- a/src/hysop++/tests/testPlanner/testPlanner.cpp +++ /dev/null @@ -1,200 +0,0 @@ - -#include "maths/quad_maths.h" -#include "testPlanner.h" - -#include "data/multi_array/multi_array.h" -#include "domain/domain.h" -#include "utils/constants.h" -#include "fft/planner.h" -#include "fft/extension.h" - - -using namespace hysop; -using namespace hysop::domain; - -static constexpr std::size_t nExtensions = 4 ; -static constexpr std::size_t nExtensionsPair = 6 ; -static constexpr fft::Extension ext[nExtensions] = -{ fft::Extension::NONE, fft::Extension::ODD, fft::Extension::EVEN, fft::Extension::PERIODIC }; -static constexpr std::pair<fft::Extension,fft::Extension> pext[nExtensionsPair] { - std::make_pair(ext[0],ext[0]), //none-none - std::make_pair(ext[1],ext[1]), //odd-odd - std::make_pair(ext[1],ext[2]), //odd-even - std::make_pair(ext[1],ext[2]), //even-odd - std::make_pair(ext[2],ext[2]), //even-even - std::make_pair(ext[3],ext[3]), //periodic-periodic -}; - -template <typename T, std::size_t Dim, bool verbose=false> -void test(bool inplace, bool includePeriodicBds); - -#ifdef FFTW_HAS_FFTW3F -TEST_F(PlannerTest, InplaceFloatTransforms) { - std::cout << std::endl; - std::cout << "== TEST 1D - float ==\t"; - test<float,1>(false,true); - std::cout << "== TEST 2D - float ==\t"; - test<float,2>(false,true); - std::cout << "== TEST 3D - float ==\t"; - test<float,3>(false,true); -} -#endif - -#ifdef FFTW_HAS_FFTW3D -TEST_F(PlannerTest, InplaceDoubleTransforms) { - std::cout << std::endl; - std::cout << "== TEST 1D - double ==\t"; - test<double,1>(true,true); - std::cout << "== TEST 2D - double ==\t"; - test<double,2>(true,true); - std::cout << "== TEST 3D - double ==\t"; - test<double,3>(true,true); -} -#endif - -#ifdef FFTW_HAS_FFTW3L -TEST_F(PlannerTest, InplaceLongDoubleTransforms) { - std::cout << std::endl; - std::cout << "== TEST 1D - long double ==\t"; - test<long double,1>(false,false); - std::cout << "== TEST 2D - long double ==\t"; - test<long double,2>(false,false); - std::cout << "== TEST 3D - long double ==\t"; - test<long double,3>(false,false); -} -#endif - -#ifdef FFTW_HAS_FFTW3Q -TEST_F(PlannerTest, InplaceQuadDoubleTransforms) { - std::cout << std::endl; - std::cout << "== TEST 1D - __float128 ==\t"; - test<__float128,1>(false,false); - std::cout << "== TEST 2D - __float128 ==\t"; - test<__float128,2>(false,false); - std::cout << "== TEST 3D - __float128 ==\t"; - test<__float128,3>(false,false); -} -#endif - -template <typename T, std::size_t Dim, bool verbose> -void test(bool inplace, bool includePeriodicBds) { - typename Shape<Dim>::type shape; - typename Domain<T,Dim>::DomainSize domainSize; - Domain<T,Dim> ref, inBuffer, outBuffer; - - Domain<T,Dim>& in = inBuffer; - Domain<T,Dim>& out = (inplace ? inBuffer : outBuffer); - - fft::Planner<T,Dim> planner; - std::array<int,Dim> order; - - const std::size_t nPoints = 16; - shape.fill(nPoints); - domainSize.fill(1.0); - order.fill(2); - - const T eps = std::numeric_limits<T>::epsilon(); - const std::size_t N = std::accumulate(shape.begin(), shape.end(), 1, std::multiplies<std::size_t>()); - const auto criteria = std::make_tuple(50*eps*N,sqrt(50)*eps*N,700*eps); - - ref.resize(domainSize).reshape(shape); - in = ref; - out = ref; - - typename Shape<Dim>::type testCases; - testCases.fill(nExtensionsPair); - Index<Dim> testCaseId(testCases); - std::array<T,3> meanDists{0}; - while(!testCaseId.atMaxId()) { - /* generate transform configuration */ - std::array<std::pair<fft::Extension,fft::Extension>, Dim> extConfig; - for (std::size_t k=0; k<Dim; k++) { - std::size_t id = testCaseId[k]; - extConfig[k] = pext[id]; - } - fft::FftDomainConfiguration<Dim> domainConfig(extConfig, includePeriodicBds); - - const auto f = [&](T &val, const hysop::Index<Dim>& idx) { - val = static_cast<T>(rand())/static_cast<T>(RAND_MAX); - for (std::size_t d=0; d<Dim; d++) { - if(idx[d]==0) { - if(extConfig[d].first == fft::Extension::ODD) { - val=T(0); - return; - } - else if(extConfig[d].first == fft::Extension::PERIODIC) - val=T(0.42); - } - else if(std::size_t(idx[d]) == idx.dim()[d]-1) { - if(extConfig[d].second == fft::Extension::ODD) { - val=T(0); - return; - } - else if(extConfig[d].second == fft::Extension::PERIODIC && includePeriodicBds) - val=T(0.42); - } - } - }; - - if(includePeriodicBds) - ref.resetDomainConfiguration(domainConfig.boundariesConfiguration()); - - /* fill reference and copy into input buffer */ - ref.data().apply(f); - in = ref; - - /* plan transforms and check if planning succeeded */ - bool status = planner.plan(in.data(), out.data(), domainConfig, order, domainSize, FFTW_MEASURE, - includePeriodicBds, includePeriodicBds); - assert(status || testCaseId()==0); - - /* execute forward and backward inplace transforms */ - planner.executeForwardTransform(); - { - if(planner.transformType() == fft::FftTransformType::FFT_R2C) - planner.transformedComplexData().apply([&](std::complex<T>& val) { val /= planner.normalisationFactor(); }); - else if(planner.transformType() == fft::FftTransformType::FFT_R2R) - planner.transformedRealData().apply([&](T& val) { val /= planner.normalisationFactor(); }); - } - planner.executeBackwardTransform(); - - std::stringstream ss; - ss << "["; - for (std::size_t k=0; k<Dim-1; k++) - ss << extConfig[k].first << "/" << extConfig[k].second << ","; - ss << extConfig[Dim-1].first << "/" << extConfig[Dim-1].second; - ss << "]"; - - const auto dist = out.distance(ref); - const bool pass = (std::get<0>(dist) < std::get<0>(criteria)) - && (std::get<1>(dist) < std::get<1>(criteria)) - && (std::get<2>(dist) < std::get<2>(criteria)); - - if((pass && verbose) || !pass) { - std::cout << (pass ? GREEN : RED); - std::cout << "\t" << std::setw(Dim*15) << ss.str() << " => " << (pass ? "OK" : "KO") - << " " << RESET << std::scientific << std::setprecision(2) << dist << std::endl; - } - if(!pass) { - if(!inplace) - in.print("IN"); - ref.print("REF"); - out.print("OUT"); - std::cout << planner << std::endl; - exit(EXIT_FAILURE); - } - - meanDists[0] += std::get<0>(dist); - meanDists[1] += std::get<1>(dist); - meanDists[2] += std::get<2>(dist); - - ++testCaseId; - } - for (std::size_t k = 0; k < 3; k++) - meanDists[k] /= T(testCaseId.maxId()); - std::cout << "Mean distances over " << std::scientific << std::setprecision(1) << std::setw(4) - << testCaseId.maxId() << " testcases: " << meanDists; - for (std::size_t k = 0; k < 3; k++) - meanDists[k] = std::round(meanDists[k]/eps); - std::cout << " ~= " << std::fixed << std::setprecision(0) << meanDists << " eps" << std::endl; -} diff --git a/src/hysop++/tests/testPlanner/testPlanner.h b/src/hysop++/tests/testPlanner/testPlanner.h deleted file mode 100644 index 5be17aa72..000000000 --- a/src/hysop++/tests/testPlanner/testPlanner.h +++ /dev/null @@ -1,20 +0,0 @@ - -#include "gtest/gtest.h" -#include "fft/planner.h" -#include "fft/extension.h" - -using T = double; -constexpr std::size_t Dim = 1; - -using namespace hysop; - -class PlannerTest : public ::testing::Test { - protected: - PlannerTest() {} - void SetUp() {} - void TearDown() {} - virtual ~PlannerTest() {} - - public: - fft::Planner<T,Dim> planner; -}; diff --git a/src/hysop++/tests/testPoissonSolver/CMakeLists.txt b/src/hysop++/tests/testPoissonSolver/CMakeLists.txt deleted file mode 100644 index 6f3ddcdc8..000000000 --- a/src/hysop++/tests/testPoissonSolver/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ - -file(GLOB CPP_SRCS *.cpp) -set(SRCS ${CPP_SRCS}) - -get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) -add_definitions(${CXX_EXTRA_DEFINES}) -add_executable(${test_name} ${SRCS}) -add_dependencies(${test_name} ${HYSOP_CXX_LIBRARY_DEP}) - -target_link_libraries(${test_name} ${HYSOP_CXX_LIBRARY}) -target_link_libraries(${test_name} ${GTEST_LIBRARIES} ${CXX_EXT_LIBS}) - -add_test("${test_name}" "${test_name}") - diff --git a/src/hysop++/tests/testPoissonSolver/main.cpp b/src/hysop++/tests/testPoissonSolver/main.cpp deleted file mode 100644 index b6141085e..000000000 --- a/src/hysop++/tests/testPoissonSolver/main.cpp +++ /dev/null @@ -1,10 +0,0 @@ - -#include "gtest/gtest.h" - -int main(int argc, char **argv) -{ - ::testing::InitGoogleTest(&argc, argv); - int ret = RUN_ALL_TESTS(); - - return ret; -} diff --git a/src/hysop++/tests/testPoissonSolver/testPoissonSolver.cpp b/src/hysop++/tests/testPoissonSolver/testPoissonSolver.cpp deleted file mode 100644 index 58d87d544..000000000 --- a/src/hysop++/tests/testPoissonSolver/testPoissonSolver.cpp +++ /dev/null @@ -1,208 +0,0 @@ - -#include "testPoissonSolver.h" - -#include <cstdlib> - -#include "domain/domain.h" -#include "solver/fftPoissonSolver.h" -#include "data/multi_array/multi_array.h" -#include "utils/constants.h" -#include "domain/boundary.h" - -using namespace hysop; -using namespace hysop::domain; - -static constexpr std::size_t nBoundaries = 4; -static constexpr std::size_t nBoundaryPairs = 7; -static constexpr domain::Boundary bds[nBoundaries] = -{ domain::Boundary::NONE, domain::Boundary::HOMOGENEOUS_NEUMANN, domain::Boundary::HOMOGENEOUS_DIRICHLET, domain::Boundary::PERIODIC }; -static constexpr std::pair<domain::Boundary,domain::Boundary> pbds[nBoundaryPairs] { - std::make_pair(bds[3],bds[3]), //periodic-periodic - std::make_pair(bds[3],bds[3]), //periodic-periodic - std::make_pair(bds[2],bds[1]), //even-odd - std::make_pair(bds[1],bds[2]), //odd-even - std::make_pair(bds[2],bds[2]), //even-even - std::make_pair(bds[1],bds[1]), //odd-odd - std::make_pair(bds[0],bds[0]), //none-none -}; - -#ifdef HAS_QUADMATHS - static constexpr __float128 freqs[6] = { 1.0Q, 1.0Q, 0.75Q, 0.75Q, 0.50Q, 0.50Q }; -#else - static constexpr long double freqs[6] = { 1.0L, 1.0L, 0.75L, 0.75L, 0.50L, 0.50L }; -#endif - -template <typename T> -std::function<T(T)> func(std::size_t k) { - switch(k) { - case 0: return [=](T x) {return std::cos(T(freqs[0])*x);}; - case 1: return [=](T x) {return std::sin(T(freqs[1])*x);}; - case 2: return [=](T x) {return std::cos(T(freqs[2])*x);}; - case 3: return [=](T x) {return std::sin(T(freqs[3])*x);}; - case 4: return [=](T x) {return std::cos(T(freqs[4])*x);}; - case 5: return [=](T x) {return std::sin(T(freqs[5])*x);}; - default: return[=](T x) { return T(1); }; - } -} - -template <typename T, std::size_t Dim, bool verbose=false> -void test(bool includePeriodicBds=false) { - typename Shape<Dim>::type shape; - typename Domain<T,Dim>::DomainSize domainSize; - Domain<T,Dim> ref, inBuffer, outBuffer; - - Domain<T,Dim>& in = inBuffer; - Domain<T,Dim>& out = outBuffer; - - shape.fill(16); - domainSize.fill(2*hysop::constants::pi); - - T eps = std::numeric_limits<T>::epsilon(); - const std::size_t N = std::accumulate(shape.begin(), shape.end(), 1, std::multiplies<std::size_t>()); - - ref.resize(domainSize).reshape(shape); - in = ref; - out = ref; - - typename Shape<Dim>::type testCases; - testCases.fill(nBoundaryPairs); - Index<Dim> testCaseId(testCases); - std::array<T,3> meanDists{0}; - std::size_t testCaseCount = testCaseId.maxId()-1; - - if(verbose) - std::cout << std::endl; - - while(testCaseId() != testCaseId.maxId()-1) { - - /* generate transform configuration */ - std::size_t orderSum = 0; - std::array<std::pair<domain::Boundary,domain::Boundary>, Dim> bdsConfig; - T W2sum = T(0); - for (std::size_t k=0; k<Dim; k++) { - std::size_t id = testCaseId[k]; - bdsConfig[k] = pbds[id]; - if(bdsConfig[k].first != domain::Boundary::NONE) { - W2sum += freqs[id]*freqs[id]; - orderSum+=2; - } - } - domain::DomainConfiguration<Dim> domainConfig(bdsConfig, includePeriodicBds); - - T orderPow = std::pow(T(10),T(orderSum)); - if(std::is_same<T,long double>::value) /* just in case long doubles are not hardware supported... */ - orderPow *= 1e3; - const auto criteria = std::make_tuple(orderPow*eps*N,orderPow*eps*sqrt(N),2*orderPow*eps); - - const auto phi = [&](const typename Domain<T,Dim>::SpaceVariable &x) { - T val = func<T>(testCaseId[0])(x[0]); - for (std::size_t d=1; d < Dim; d++) - val *= func<T>(testCaseId[d])(x[d]); - return val; - }; - const auto f = [&](const typename Domain<T,Dim>::SpaceVariable &x) { - return -W2sum*phi(x); - }; - - { - ref.resetDomainConfiguration(domainConfig); - in = ref; - out = ref; - - in.apply(f); - ref.apply(phi); - out.data().apply([](T& v){ v=T(0);}); - } - - solver::FftPoissonSolver<T,Dim> solver(domainSize, domainConfig, FFTW_MEASURE, includePeriodicBds, includePeriodicBds); - solver.apply(in.data(), out.data()); - - std::stringstream ss; - ss << "["; - for (std::size_t k=0; k<Dim-1; k++) - ss << bdsConfig[k].first << "/" << bdsConfig[k].second << ","; - ss << bdsConfig[Dim-1].first << "/" << bdsConfig[Dim-1].second; - ss << "]"; - - const auto dist = out.distance(ref); - const bool pass = (std::get<0>(dist) < std::get<0>(criteria)) - && (std::get<1>(dist) < std::get<1>(criteria)) - && (std::get<2>(dist) < std::get<2>(criteria)); - - if((pass && verbose) || !pass) { - std::cout << (pass ? GREEN : RED); - std::cout << "\t" << std::setw(Dim*15) << ss.str() << " => " << (pass ? "OK" : "KO") - << " " << RESET << std::scientific << std::setprecision(2) << dist << std::endl; - } - if(!pass) { - //in.print("IN"); - //ref.print("REF"); - //out.print("OUT"); - std::cout << "\t\tTest Failed... Criteria was " << criteria << "." << std::endl; - } - EXPECT_TRUE(pass); - - meanDists[0] += std::get<0>(dist); - meanDists[1] += std::get<1>(dist); - meanDists[2] += std::get<2>(dist); - - ++testCaseId; - } - - for (std::size_t k = 0; k < 3; k++) - meanDists[k] /= T(testCaseCount); - std::cout << "\t=> mean distances over " << std::scientific << std::setprecision(1) << std::setw(4) - << testCaseCount << " testcases: " << meanDists; - for (std::size_t k = 0; k < 3; k++) - meanDists[k] = std::round(meanDists[k]/eps); - std::cout << " ~= " << std::fixed << std::setprecision(0) << meanDists << " eps" << std::endl; -} - - -#ifdef FFTW_HAS_FFTW3F -TEST_F(PoissonSolverTest, FloatPoissonSolver) { - std::cout << std::endl; - std::cout << "== TEST 1D - float =="; - test<float,1,false>(true); - std::cout << "== TEST 2D - float =="; - test<float,2,false>(); - std::cout << "== TEST 3D - float =="; - test<float,3,false>(); -} -#endif - -#ifdef FFTW_HAS_FFTW3D -TEST_F(PoissonSolverTest, DoublePoissonSolver) { - std::cout << std::endl; - std::cout << "== TEST 1D - double =="; - test<double,1,false>(); - std::cout << "== TEST 2D - double =="; - test<double,2,false>(); - std::cout << "== TEST 3D - double =="; - test<double,3,false>(); -} -#endif - -#ifdef FFTW_HAS_FFTW3L -TEST_F(PoissonSolverTest, LongDoublePoissonSolver) { - std::cout << std::endl; - std::cout << "== TEST 1D - long double =="; - test<long double,1,false>(); - std::cout << "== TEST 2D - long double =="; - test<long double,2,false>(); - std::cout << "== TEST 3D - long double =="; - test<long double,3,false>(); -} -#endif - -#ifdef FFTW_HAS_FFTW3Q -TEST_F(PoissonSolverTest, QuadFloatPoissonSolver) { - std::cout << std::endl; - std::cout << "== TEST 1D - __float128 =="; - test<__float128,1,false>(); - std::cout << "== TEST 2D - __float128 =="; - test<__float128,2,false>(); - std::cout << "== TEST 3D - __float128 =="; - test<__float128,3,false>(); -} -#endif diff --git a/src/hysop++/tests/testPoissonSolver/testPoissonSolver.h b/src/hysop++/tests/testPoissonSolver/testPoissonSolver.h deleted file mode 100644 index a5115abef..000000000 --- a/src/hysop++/tests/testPoissonSolver/testPoissonSolver.h +++ /dev/null @@ -1,14 +0,0 @@ - -#include "gtest/gtest.h" -#include "solver/fftPoissonSolver.h" -#include "fft/extension.h" - -using namespace hysop; - -class PoissonSolverTest : public ::testing::Test { - protected: - PoissonSolverTest() {} - void SetUp() {} - void TearDown() {} - virtual ~PoissonSolverTest() {} -}; diff --git a/src/hysop++/tests/testPolynoms/CMakeLists.txt b/src/hysop++/tests/testPolynoms/CMakeLists.txt deleted file mode 100644 index ae4b35dd2..000000000 --- a/src/hysop++/tests/testPolynoms/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ - -file(GLOB CPP_SRCS *.cpp) -set(SRCS ${CPP_SRCS}) - -get_filename_component(test_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) -add_definitions(${CXX_EXTRA_DEFINES}) -add_executable(${test_name} ${SRCS}) -add_dependencies(${test_name} ${HYSOP_CXX_LIBRARY_DEP}) - -target_link_libraries(${test_name} ${HYSOP_LIBRARY}) -target_link_libraries(${test_name} ${GTEST_LIBRARIES} ${CXX_EXT_LIBS}) - -add_test("${test_name}" "${test_name}") - diff --git a/src/hysop++/tests/testPolynoms/main.cpp b/src/hysop++/tests/testPolynoms/main.cpp deleted file mode 100644 index b6141085e..000000000 --- a/src/hysop++/tests/testPolynoms/main.cpp +++ /dev/null @@ -1,10 +0,0 @@ - -#include "gtest/gtest.h" - -int main(int argc, char **argv) -{ - ::testing::InitGoogleTest(&argc, argv); - int ret = RUN_ALL_TESTS(); - - return ret; -} diff --git a/src/hysop++/tests/testPolynoms/testPolynoms.cpp b/src/hysop++/tests/testPolynoms/testPolynoms.cpp deleted file mode 100644 index 0849af6a4..000000000 --- a/src/hysop++/tests/testPolynoms/testPolynoms.cpp +++ /dev/null @@ -1,115 +0,0 @@ - -#include "testPolynoms.h" - -using namespace hysop::maths; - -template <typename T, std::size_t Dim> -void evalTest(std::size_t p_size, std::size_t p_samples); - -TEST_F(PolynomialTest, EvalTest1D) { - const std::size_t order=10; - const std::size_t samples=4096; - - evalTest<bool,1>(order,samples); - - evalTest<char,1>(order,samples); - evalTest<short,1>(order,samples); - evalTest<int,1>(order,samples); - evalTest<long int,1>(order,samples); - evalTest<long long int,1>(order,samples); - - evalTest<unsigned char,1>(order,samples); - evalTest<unsigned short,1>(order,samples); - evalTest<unsigned int,1>(order,samples); - evalTest<unsigned long int,1>(order,samples); - evalTest<unsigned long long int,1>(order,samples); - - evalTest<float,1>(order,samples); - evalTest<double,1>(order,samples); - evalTest<long double,1>(order,samples); -#ifdef HAS_QUADMATHS - evalTest<__float128,1>(order,samples); -#endif - - evalTest<std::size_t,1>(order,samples); - evalTest<std::ptrdiff_t,1>(order,samples); -} - -TEST_F(PolynomialTest, EvalTest2D) { - const std::size_t order=10; - const std::size_t samples=32; - - evalTest<float,2>(order,samples); - evalTest<double,2>(order,samples); - evalTest<long double,2>(order,samples); -#ifdef HAS_QUADMATHS - evalTest<__float128,2>(order,samples); -#endif -} - -TEST_F(PolynomialTest, EvalTest3D) { - const std::size_t order=10; - const std::size_t samples=4; - - evalTest<float,3>(order,samples); - evalTest<double,3>(order,samples); - evalTest<long double,3>(order,samples); -#ifdef HAS_QUADMATHS - evalTest<__float128,3>(order,samples); -#endif -} - -TEST_F(PolynomialTest, EvalTest4D) { - const std::size_t order=10; - const std::size_t samples=2; - - evalTest<float,4>(order,samples); - evalTest<double,4>(order,samples); - evalTest<long double,4>(order,samples); -#ifdef HAS_QUADMATHS - evalTest<__float128,4>(order,samples); -#endif -} - -template <typename T, std::size_t Dim> -void evalTest(const std::size_t p_size, const std::size_t p_samples) { - Polynomial<T,Dim> P; - Index<Dim> polyIdx; - { - typename Shape<Dim>::type polyShape; - polyShape.fill(p_size); - P.reshape(polyShape).applyToCoefficients([](T& ak, const Index<Dim>& idx){ - ak = T(idx())/T(idx.maxId()); - }); - } - - std::array<T,Dim> X; - T dX; - { - const T a = T(0); - const T b = T(1); - dX = (b-a)/(p_samples-1); - } - - typename Shape<Dim>::type sampleShape; - sampleShape.fill(p_samples); - Index<Dim> sampleIdx(sampleShape); - while(!sampleIdx.atMaxId()) { - for (std::size_t d=0; d < Dim; d++) - X[d] = sampleIdx[d]*dX; - T lhs, rhs; - lhs = P(X); - rhs = T(0); - polyIdx.reset(P.shape()); - while(!polyIdx.atMaxId()) { - T val = T(1); - for (std::size_t d=0; d<Dim; d++) - val *= std::pow(X[d],polyIdx[d]); - rhs += T(polyIdx())/T(polyIdx.maxId())*val; - ++polyIdx; - } - ASSERT_LE(std::abs(rhs-lhs),std::pow(10,Dim)*std::numeric_limits<T>::epsilon()); - ++sampleIdx; - } -} - diff --git a/src/hysop++/tests/testPolynoms/testPolynoms.h b/src/hysop++/tests/testPolynoms/testPolynoms.h deleted file mode 100644 index d7dd0bd6a..000000000 --- a/src/hysop++/tests/testPolynoms/testPolynoms.h +++ /dev/null @@ -1,13 +0,0 @@ - -#include "gtest/gtest.h" -#include "maths/polynomial.h" - -using namespace hysop; - -class PolynomialTest : public ::testing::Test { - protected: - PolynomialTest() {} - void SetUp() {} - void TearDown() {} - virtual ~PolynomialTest() {} -}; -- GitLab