diff --git a/nifty/__init__.py b/nifty/__init__.py index 296043d5b84431d7a4f0de8939dea863c7af0a6a..fb1f17de01754eb9dcbb266399aca8b2e2b9fb74 100644 --- a/nifty/__init__.py +++ b/nifty/__init__.py @@ -24,16 +24,11 @@ from .version import __version__ from keepers import MPILogger logger = MPILogger() -# it is important to import config before d2o such that NIFTy is able to -# pre-create d2o's configuration object with the corrected path from .config import dependency_injector,\ - nifty_configuration,\ - d2o_configuration + nifty_configuration logger.logger.setLevel(nifty_configuration['loglevel']) -from d2o import distributed_data_object, d2o_librarian - from .field import Field from .random import Random diff --git a/nifty/basic_arithmetics.py b/nifty/basic_arithmetics.py index e2830da6ba7fb82260eb6a6c59568bff5f387ec6..97c244a20d15ca7a3c047c1337a31c016fa662bb 100644 --- a/nifty/basic_arithmetics.py +++ b/nifty/basic_arithmetics.py @@ -18,7 +18,6 @@ from __future__ import division import numpy as np -from d2o import distributed_data_object from .field import Field @@ -32,8 +31,6 @@ def _math_helper(x, function): result_val = x.val.apply_scalar_function(function) result = x.copy_empty(dtype=result_val.dtype) result.val = result_val - elif isinstance(x, distributed_data_object): - result = x.apply_scalar_function(function, inplace=False) else: result = function(np.asarray(x)) diff --git a/nifty/domain_object.py b/nifty/domain_object.py index f6994ec63ec0611af42c27ee4b2c133dcaebd03b..3142fa641f5e14e4fb87b0c90ff49769dde4c822 100644 --- a/nifty/domain_object.py +++ b/nifty/domain_object.py @@ -142,7 +142,7 @@ class DomainObject(with_metaclass( Parameters ---------- - x : distributed_data_object + x : numpy.ndarray The fields data array. power : int, *optional* The power to which the volume-weight is raised (default: 1). @@ -158,7 +158,7 @@ class DomainObject(with_metaclass( Returns ------- - distributed_data_object + numpy.ndarray A weighted version of x, with volume-weights raised to the given power. @@ -217,7 +217,7 @@ class DomainObject(with_metaclass( Returns ------- - distributed_data_object + numpy.ndarray Processed input where casting that needs Space-specific knowledge (for example location of pixels on the manifold) was performed. diff --git a/nifty/field.py b/nifty/field.py index e6990f3a363270f18918662dc1c8cc504a4d46c5..bb5c6bf44f3eeb08afe12fd964c9d3e61a56814a 100644 --- a/nifty/field.py +++ b/nifty/field.py @@ -18,7 +18,6 @@ from __future__ import division from builtins import zip -#from builtins import str from builtins import range import ast @@ -27,9 +26,6 @@ import numpy as np from keepers import Versionable,\ Loggable -from d2o import distributed_data_object,\ - STRATEGIES as DISTRIBUTION_STRATEGIES - from .config import nifty_configuration as gc from .domain_object import DomainObject @@ -55,7 +51,7 @@ class Field(Loggable, Versionable, object): LMSpace or PowerSpace. It might also be a FieldArray, which is an unstructured domain. - val : scalar, numpy.ndarray, distributed_data_object, Field + val : scalar, numpy.ndarray, Field The values the array should contain after init. A scalar input will fill the whole array with this scalar. If an array is provided the array's dimensions must match the domain's. @@ -63,18 +59,11 @@ class Field(Loggable, Versionable, object): dtype : type A numpy.type. Most common are int, float and complex. - distribution_strategy: optional[{'fftw', 'equal', 'not', 'freeform'}] - Specifies which distributor will be created and used. - 'fftw' uses the distribution strategy of pyfftw, - 'equal' tries to distribute the data as uniform as possible - 'not' does not distribute the data at all - 'freeform' distribute the data according to the given local data/shape - copy: boolean Attributes ---------- - val : distributed_data_object + val : numpy.ndarray domain : DomainObject See Parameters. @@ -82,8 +71,6 @@ class Field(Loggable, Versionable, object): Enumerates the axes of the Field dtype : type Contains the datatype stored in the Field. - distribution_strategy : string - Name of the used distribution_strategy. Raise ----- @@ -93,38 +80,17 @@ class Field(Loggable, Versionable, object): instance *val is an array that has a different dimension than the domain - Examples - -------- - >>> a = Field(RGSpace([4,5]),val=2) - >>> a.val - <distributed_data_object> - array([[2, 2, 2, 2, 2], - [2, 2, 2, 2, 2], - [2, 2, 2, 2, 2], - [2, 2, 2, 2, 2]]) - >>> a.dtype - dtype('int64') - - See Also - -------- - distributed_data_object - """ # ---Initialization methods--- - def __init__(self, domain=None, val=None, dtype=None, - distribution_strategy=None, copy=False): + def __init__(self, domain=None, val=None, dtype=None, copy=False): self.domain = self._parse_domain(domain=domain, val=val) self.domain_axes = self._get_axes_tuple(self.domain) self.dtype = self._infer_dtype(dtype=dtype, val=val) - self.distribution_strategy = self._parse_distribution_strategy( - distribution_strategy=distribution_strategy, - val=val) - if val is None: self._val = None else: @@ -177,26 +143,10 @@ class Field(Loggable, Versionable, object): return dtype - def _parse_distribution_strategy(self, distribution_strategy, val): - if distribution_strategy is None: - if isinstance(val, distributed_data_object): - distribution_strategy = val.distribution_strategy - elif isinstance(val, Field): - distribution_strategy = val.distribution_strategy - else: - self.logger.debug("distribution_strategy set to default!") - distribution_strategy = gc['default_distribution_strategy'] - elif distribution_strategy not in DISTRIBUTION_STRATEGIES['global']: - raise ValueError( - "distribution_strategy must be a global-type " - "strategy.") - return distribution_strategy - # ---Factory methods--- @classmethod - def from_random(cls, random_type, domain=None, dtype=None, - distribution_strategy=None, **kwargs): + def from_random(cls, random_type, domain=None, dtype=None, **kwargs): """ Draws a random field with the given parameters. Parameters @@ -213,9 +163,6 @@ class Field(Loggable, Versionable, object): dtype : type The datatype of the output random field - distribution_strategy : all supported distribution strategies - The distribution strategy of the output random field - Returns ------- out : Field @@ -229,8 +176,7 @@ class Field(Loggable, Versionable, object): """ # create a initially empty field - f = cls(domain=domain, dtype=dtype, - distribution_strategy=distribution_strategy) + f = cls(domain=domain, dtype=dtype) # now use the processed input in terms of f in order to parse the # random arguments @@ -238,23 +184,14 @@ class Field(Loggable, Versionable, object): f=f, **kwargs) - # extract the distributed_data_object from f and apply the appropriate + # extract the data from f and apply the appropriate # random number generator to it sample = f.get_val(copy=False) generator_function = getattr(Random, random_type) - comm = sample.comm - size = comm.size - if (sample.distribution_strategy in DISTRIBUTION_STRATEGIES['not'] and - size > 1): - seed = np.random.randint(10000000) - seed = comm.bcast(seed, root=0) - np.random.seed(seed) - - sample.apply_generator( - lambda shape: generator_function(dtype=f.dtype, - shape=shape, - **random_arguments)) + sample[:]=generator_function(dtype=f.dtype, + shape=sample.shape, + **random_arguments) return f @staticmethod @@ -400,13 +337,8 @@ class Field(Loggable, Versionable, object): # into the real and imaginary parts of the power spectrum. # If it was complex, all the power is put into a real power spectrum. - distribution_strategy = \ - work_field.val.get_axes_local_distribution_strategy( - work_field.domain_axes[space_index]) - harmonic_domain = work_field.domain[space_index] power_domain = PowerSpace(harmonic_partner=harmonic_domain, - distribution_strategy=distribution_strategy, logarithmic=logarithmic, nbin=nbin, binbounds=binbounds) power_spectrum = cls._calculate_power_spectrum( @@ -421,8 +353,7 @@ class Field(Loggable, Versionable, object): result_field = work_field.copy_empty( domain=result_domain, - dtype=result_dtype, - distribution_strategy=power_spectrum.distribution_strategy) + dtype=result_dtype) result_field.set_val(new_val=power_spectrum, copy=False) return result_field @@ -437,7 +368,6 @@ class Field(Loggable, Versionable, object): pindex = cls._shape_up_pindex( pindex=pindex, target_shape=field_val.shape, - target_strategy=field_val.distribution_strategy, axes=axes) power_spectrum = pindex.bincount(weights=field_val, @@ -453,31 +383,18 @@ class Field(Loggable, Versionable, object): @staticmethod def _shape_up_pindex(pindex, target_shape, target_strategy, axes): - if pindex.distribution_strategy not in \ - DISTRIBUTION_STRATEGIES['global']: - raise ValueError("pindex's distribution strategy must be " - "global-type") - - if pindex.distribution_strategy in DISTRIBUTION_STRATEGIES['slicing']: - if ((0 not in axes) or - (target_strategy is not pindex.distribution_strategy)): - raise ValueError( - "A slicing distributor shall not be reshaped to " - "something non-sliced.") - semiscaled_local_shape = [1, ] * len(target_shape) for i in range(len(axes)): semiscaled_local_shape[axes[i]] = pindex.local_shape[i] local_data = pindex.get_local_data(copy=False) semiscaled_local_data = local_data.reshape(semiscaled_local_shape) - result_obj = pindex.copy_empty(global_shape=target_shape, - distribution_strategy=target_strategy) + result_obj = pindex.copy_empty(global_shape=target_shape) result_obj.data[:] = semiscaled_local_data return result_obj def power_synthesize(self, spaces=None, real_power=True, real_signal=True, - mean=None, std=None, distribution_strategy=None): + mean=None, std=None): """ Yields a sampled field with `self`**2 as its power spectrum. This method draws a Gaussian random field in the harmonic partner @@ -552,16 +469,12 @@ class Field(Loggable, Versionable, object): else: result_list = [None, None] - if distribution_strategy is None: - distribution_strategy = gc['default_distribution_strategy'] - result_list = [self.__class__.from_random( 'normal', mean=mean, std=std, domain=result_domain, - dtype=np.complex, - distribution_strategy=distribution_strategy) + dtype=np.complex) for x in result_list] # from now on extract the values from the random fields for further @@ -569,7 +482,7 @@ class Field(Loggable, Versionable, object): # if the signal-space field should be real, hermitianize the field # components - spec = self.val.get_full_data() + spec = self.val.copy() spec = np.sqrt(spec) for power_space_index in spaces: @@ -683,16 +596,6 @@ class Field(Loggable, Versionable, object): # weight the random fields with the power spectrum # therefore get the pindex from the power space pindex = power_space.pindex - # take the local data from pindex. This data must be compatible to the - # local data of the field given the slice of the PowerSpace - local_distribution_strategy = \ - result_list[0].val.get_axes_local_distribution_strategy( - result_list[0].domain_axes[power_space_index]) - - if pindex.distribution_strategy is not local_distribution_strategy: - raise AttributeError( - "The distribution_strategy of pindex does not fit the " - "slice_local distribution strategy of the synthesized field.") # Now use numpy advanced indexing in order to put the entries of the # power spectrum into the appropriate places of the pindex array. @@ -711,7 +614,7 @@ class Field(Loggable, Versionable, object): # ---Properties--- def set_val(self, new_val=None, copy=False): - """ Sets the field's distributed_data_object. + """ Sets the field's data object. Parameters ---------- @@ -736,17 +639,17 @@ class Field(Loggable, Versionable, object): return self def get_val(self, copy=False): - """ Returns the distributed_data_object associated with this Field. + """ Returns the data object associated with this Field. Parameters ---------- copy : boolean - If true, a copy of the Field's underlying distributed_data_object + If true, a copy of the Field's underlying data object is returned. Returns ------- - out : distributed_data_object + out : numpy.ndarray See Also -------- @@ -764,11 +667,11 @@ class Field(Loggable, Versionable, object): @property def val(self): - """ Returns the distributed_data_object associated with this Field. + """ Returns the data object associated with this Field. Returns ------- - out : distributed_data_object + out : numpy.ndarray See Also -------- @@ -874,13 +777,13 @@ class Field(Loggable, Versionable, object): # ---Special unary/binary operations--- def cast(self, x=None, dtype=None): - """ Transforms x to a d2o with the correct dtype and shape. + """ Transforms x to an object with the correct dtype and shape. Parameters ---------- - x : scalar, d2o, Field, array_like - The input that shall be casted on a d2o of the same shape like the - domain. + x : scalar, numpy.ndarray, Field, array_like + The input that shall be casted on a numpy.ndarray of the same shape + like the domain. dtype : type The datatype the output shall have. This can be used to override @@ -888,7 +791,7 @@ class Field(Loggable, Versionable, object): Returns ------- - out : distributed_data_object + out : numpy.ndarray The output object. See Also @@ -921,21 +824,17 @@ class Field(Loggable, Versionable, object): if dtype is None: dtype = self.dtype + if x is not None: + return np.asarray(x, dtype=dtype).reshape(self.shape) + else: + return np.empty(self.shape, dtype=dtype) - return_x = distributed_data_object( - global_shape=self.shape, - dtype=dtype, - distribution_strategy=self.distribution_strategy) - return_x.set_full_data(x, copy=False) - return return_x - - def copy(self, domain=None, dtype=None, distribution_strategy=None): + def copy(self, domain=None, dtype=None): """ Returns a full copy of the Field. If no keyword arguments are given, the returned object will be an identical copy of the original Field. By explicit specification one is - able to define the domain, the dtype and the distribution_strategy of - the returned Field. + able to define the domain and the dtype of the returned Field. Parameters ---------- @@ -945,9 +844,6 @@ class Field(Loggable, Versionable, object): dtype : type The new dtype the Field shall have. - distribution_strategy : all supported distribution strategies - The new distribution strategy the Field shall have. - Returns ------- out : Field @@ -962,20 +858,18 @@ class Field(Loggable, Versionable, object): copied_val = self.get_val(copy=True) new_field = self.copy_empty( domain=domain, - dtype=dtype, - distribution_strategy=distribution_strategy) + dtype=dtype) new_field.set_val(new_val=copied_val, copy=False) return new_field - def copy_empty(self, domain=None, dtype=None, distribution_strategy=None): + def copy_empty(self, domain=None, dtype=None): """ Returns an empty copy of the Field. If no keyword arguments are given, the returned object will be an identical copy of the original Field. The memory for the data array is only allocated but not actively set to any value (c.f. numpy.ndarray.copy_empty). By explicit specification one is able - to change the domain, the dtype and the distribution_strategy of the - returned Field. + to change the domain and the dtype of the returned Field. Parameters ---------- @@ -985,9 +879,6 @@ class Field(Loggable, Versionable, object): dtype : type The new dtype the Field shall have. - distribution_strategy : string, all supported distribution strategies - The distribution strategy the new Field should have. - Returns ------- out : Field @@ -1009,9 +900,6 @@ class Field(Loggable, Versionable, object): else: dtype = np.dtype(dtype) - if distribution_strategy is None: - distribution_strategy = self.distribution_strategy - fast_copyable = True try: for i in range(len(self.domain)): @@ -1021,13 +909,10 @@ class Field(Loggable, Versionable, object): except IndexError: fast_copyable = False - if (fast_copyable and dtype == self.dtype and - distribution_strategy == self.distribution_strategy): + if (fast_copyable and dtype == self.dtype): new_field = self._fast_copy_empty() else: - new_field = Field(domain=domain, - dtype=dtype, - distribution_strategy=distribution_strategy) + new_field = Field(domain=domain, dtype=dtype) return new_field def _fast_copy_empty(self): @@ -1040,7 +925,7 @@ class Field(Loggable, Versionable, object): if key != '_val': new_field.__dict__[key] = value else: - new_field.__dict__[key] = self.val.copy_empty() + new_field.__dict__[key] = np.empty_like(self.val) return new_field def weight(self, power=1, inplace=False, spaces=None): @@ -1217,7 +1102,7 @@ class Field(Loggable, Versionable, object): except TypeError: axes_list = () - # perform the contraction on the d2o + # perform the contraction on the data data = self.get_val(copy=False) data = getattr(data, op)(axis=axes_list) @@ -1567,7 +1452,6 @@ class Field(Loggable, Versionable, object): def _to_hdf5(self, hdf5_group): hdf5_group.attrs['dtype'] = self.dtype.name - hdf5_group.attrs['distribution_strategy'] = self.distribution_strategy hdf5_group.attrs['domain_axes'] = str(self.domain_axes) hdf5_group['num_domain'] = len(self.domain) @@ -1602,8 +1486,6 @@ class Field(Loggable, Versionable, object): new_field._val = None new_field.dtype = np.dtype(hdf5_group.attrs['dtype']) - new_field.distribution_strategy =\ - hdf5_group.attrs['distribution_strategy'] return new_field diff --git a/nifty/operators/diagonal_operator/diagonal_operator.py b/nifty/operators/diagonal_operator/diagonal_operator.py index 7a59a783655da7c3a9b1d8ad6ea3cfc73cc9c8da..38a1489f5e316f361492678211136b6216f3d89d 100644 --- a/nifty/operators/diagonal_operator/diagonal_operator.py +++ b/nifty/operators/diagonal_operator/diagonal_operator.py @@ -20,9 +20,6 @@ from __future__ import division from builtins import range import numpy as np -from d2o import distributed_data_object,\ - STRATEGIES as DISTRIBUTION_STRATEGIES - from ...config import nifty_configuration as gc from ...field import Field from ..endomorphic_operator import EndomorphicOperator @@ -47,10 +44,6 @@ class DiagonalOperator(EndomorphicOperator): (default: False). copy : boolean Internal copy of the diagonal (default: True) - distribution_strategy : string - setting the prober distribution_strategy of the - diagonal (default : None). In case diagonal is d2o-object or Field, - their distribution_strategy is used as a fallback. default_spaces : tuple of ints *optional* Defines on which space(s) of a given field the Operator acts by default (default: None) @@ -66,9 +59,6 @@ class DiagonalOperator(EndomorphicOperator): Indicates whether the Operator is unitary or not. self_adjoint : boolean Indicates whether the operator is self_adjoint or not. - distribution_strategy : string - Defines the distribution_strategy of the distributed_data_object - in which the diagonal entries are stored in. Raises ------ @@ -83,16 +73,6 @@ class DiagonalOperator(EndomorphicOperator): deals with the bare entries that allow for correct interpretation of the matrix entries; e.g., as variance in case of an covariance operator. - Examples - -------- - >>> x_space = RGSpace(5) - >>> D = DiagonalOperator(x_space, diagonal=[1., 3., 2., 4., 6.]) - >>> f = Field(x_space, val=2.) - >>> res = D.times(f) - >>> res.val - <distributed_data_object> - array([ 2., 6., 4., 8., 12.]) - See Also -------- EndomorphicOperator @@ -102,28 +82,17 @@ class DiagonalOperator(EndomorphicOperator): # ---Overwritten properties and methods--- def __init__(self, domain=(), diagonal=None, bare=False, copy=True, - distribution_strategy=None, default_spaces=None): + default_spaces=None): super(DiagonalOperator, self).__init__(default_spaces) self._domain = self._parse_domain(domain) - if distribution_strategy is None: - if isinstance(diagonal, distributed_data_object): - distribution_strategy = diagonal.distribution_strategy - elif isinstance(diagonal, Field): - distribution_strategy = diagonal.distribution_strategy - - self._distribution_strategy = self._parse_distribution_strategy( - distribution_strategy=distribution_strategy, - val=diagonal) - self._self_adjoint = None self._unitary = None self.set_diagonal(diagonal=diagonal, bare=bare, copy=copy) def _add_attributes_to_copy(self, copy, **kwargs): copy._domain = self._domain - copy._distribution_strategy = self._distribution_strategy copy.set_diagonal(diagonal=self.diagonal(bare=True), bare=True) copy._self_adjoint = self._self_adjoint copy._unitary = self._unitary @@ -207,35 +176,6 @@ class DiagonalOperator(EndomorphicOperator): # ---Added properties and methods--- - @property - def distribution_strategy(self): - """ - distribution_strategy : string - Defines the way how the diagonal operator is distributed - among the nodes. Available distribution_strategies are: - 'fftw', 'equal' and 'not'. - - Notes : - https://arxiv.org/abs/1606.05385 - - """ - - return self._distribution_strategy - - def _parse_distribution_strategy(self, distribution_strategy, val): - if distribution_strategy is None: - if isinstance(val, distributed_data_object): - distribution_strategy = val.distribution_strategy - elif isinstance(val, Field): - distribution_strategy = val.distribution_strategy - else: - self.logger.info("Datamodel set to default!") - distribution_strategy = gc['default_distribution_strategy'] - elif distribution_strategy not in DISTRIBUTION_STRATEGIES['all']: - raise ValueError( - "Invalid distribution_strategy!") - return distribution_strategy - def set_diagonal(self, diagonal, bare=False, copy=True): """ Sets the diagonal of the Operator. @@ -254,7 +194,6 @@ class DiagonalOperator(EndomorphicOperator): # use the casting functionality from Field to process `diagonal` f = Field(domain=self.domain, val=diagonal, - distribution_strategy=self.distribution_strategy, copy=copy) # weight if the given values were `bare` is True @@ -280,8 +219,6 @@ class DiagonalOperator(EndomorphicOperator): # here the actual multiplication takes place return operation(self.diagonal(copy=False))(x) - # if the distribution_strategy of self is sub-slice compatible to - # the one of x, reshape the local data of self and apply it directly active_axes = [] if spaces is None: active_axes = list(range(len(x.shape))) @@ -289,17 +226,7 @@ class DiagonalOperator(EndomorphicOperator): for space_index in spaces: active_axes += x.domain_axes[space_index] - axes_local_distribution_strategy = \ - x.val.get_axes_local_distribution_strategy(active_axes) - if axes_local_distribution_strategy == self.distribution_strategy: - local_diagonal = self._diagonal.val.get_local_data(copy=False) - else: - # create an array that is sub-slice compatible - self.logger.warn("The input field is not sub-slice compatible to " - "the distribution strategy of the operator.") - redistr_diagonal_val = self._diagonal.val.copy( - distribution_strategy=axes_local_distribution_strategy) - local_diagonal = redistr_diagonal_val.get_local_data(copy=False) + local_diagonal = self._diagonal.val.get_local_data(copy=False) reshaper = [x.val.data.shape[i] if i in active_axes else 1 for i in range(len(x.shape))] diff --git a/nifty/operators/fft_operator/transformations/rg_transforms.py b/nifty/operators/fft_operator/transformations/rg_transforms.py index 29e06a1ce19f4e34e87f51450cefa73a326cd927..b27fcb99b0c3951b5a7a2ded93130108867a23d3 100644 --- a/nifty/operators/fft_operator/transformations/rg_transforms.py +++ b/nifty/operators/fft_operator/transformations/rg_transforms.py @@ -21,7 +21,6 @@ from builtins import object import warnings import numpy as np -from d2o import distributed_data_object, STRATEGIES from ....config import dependency_injector as gdi from ....config import nifty_configuration as gc from .... import nifty_utilities as utilities @@ -331,15 +330,13 @@ class MPIFFT(Transform): return return_val def _repack_to_fftw_and_transform(self, val, axes, **kwargs): - temp_val = val.copy_empty(distribution_strategy='fftw') - self.logger.info("Repacking d2o to fftw distribution strategy") + temp_val = val.copy_empty() temp_val.set_full_data(val, copy=False) # Recursive call to transform result = self.transform(temp_val, axes, **kwargs) - return_val = result.copy_empty( - distribution_strategy=val.distribution_strategy) + return_val = result.copy_empty() return_val.set_full_data(data=result, copy=False) return return_val @@ -433,32 +430,10 @@ class MPIFFT(Transform): raise ValueError("Provided axes does not match array shape") # If the input is a numpy array we transform it locally - if not isinstance(val, distributed_data_object): - # Cast to a np.ndarray - temp_val = np.asarray(val) + temp_val = np.asarray(val) - # local transform doesn't apply transforms inplace - return_val = self._local_transform(temp_val, axes) - else: - if val.distribution_strategy in STRATEGIES['slicing']: - if axes is None or 0 in axes: - if val.distribution_strategy != 'fftw': - return_val = \ - self._repack_to_fftw_and_transform( - val, axes, **kwargs - ) - else: - return_val = self._mpi_transform( - val, axes, **kwargs - ) - else: - return_val = self._local_transform( - val, axes, **kwargs - ) - else: - return_val = self._repack_to_fftw_and_transform( - val, axes, **kwargs - ) + # local transform doesn't apply transforms inplace + return_val = self._local_transform(temp_val, axes) return return_val @@ -590,35 +565,14 @@ class SerialFFT(Transform): not all(axis in range(len(val.shape)) for axis in axes): raise ValueError("Provided axes does not match array shape") - return_val = val.copy_empty(global_shape=val.shape, - dtype=np.complex) - - if (axes is None) or (0 in axes) or \ - (val.distribution_strategy not in STRATEGIES['slicing']): + return_val = np.empty(val.shape, dtype=np.complex) - if val.distribution_strategy == 'not': - local_val = val.get_local_data(copy=False) - else: - local_val = val.get_full_data() + local_val = val - result_data = self._atomic_transform(local_val=local_val, - axes=axes, - local_offset_Q=False) - return_val.set_full_data(result_data, copy=False) - - else: - local_offset_list = np.cumsum( - np.concatenate([[0, ], - val.distributor.all_local_slices[:, 2]])) - local_offset_Q = \ - bool(local_offset_list[val.distributor.comm.rank] % 2) - - local_val = val.get_local_data() - result_data = self._atomic_transform(local_val=local_val, - axes=axes, - local_offset_Q=local_offset_Q) - - return_val.set_local_data(result_data, copy=False) + result_data = self._atomic_transform(local_val=local_val, + axes=axes, + local_offset_Q=False) + return_val=result_data return return_val diff --git a/nifty/operators/fft_operator/transformations/rgrgtransformation.py b/nifty/operators/fft_operator/transformations/rgrgtransformation.py index 6ccf080f394a525ed376136b33c3111bfd87c3c7..9de880c09fa81f98b2785e924ff06474e667a283 100644 --- a/nifty/operators/fft_operator/transformations/rgrgtransformation.py +++ b/nifty/operators/fft_operator/transformations/rgrgtransformation.py @@ -156,21 +156,21 @@ class RGRGTransformation(Transformation): Tval_imag = self._transform.transform(val.imag, axes, **kwargs) if self.codomain.harmonic: - Tval_real.data.real += Tval_real.data.imag - Tval_real.data.imag = \ - Tval_imag.data.real + Tval_imag.data.imag + Tval_real.real += Tval_real.imag + Tval_real.imag = \ + Tval_imag.real + Tval_imag.imag else: - Tval_real.data.real -= Tval_real.data.imag - Tval_real.data.imag = \ - Tval_imag.data.real - Tval_imag.data.imag + Tval_real.real -= Tval_real.imag + Tval_real.imag = \ + Tval_imag.real - Tval_imag.imag Tval = Tval_real else: Tval = self._transform.transform(val, axes, **kwargs) if self.codomain.harmonic: - Tval.data.real += Tval.data.imag + Tval.real += Tval.imag else: - Tval.data.real -= Tval.data.imag + Tval.real -= Tval.imag Tval = Tval.real if not self._transform.codomain.harmonic: diff --git a/nifty/operators/fft_operator/transformations/slicing_transformation.py b/nifty/operators/fft_operator/transformations/slicing_transformation.py index 36a953b19507a85d4465ef3c1e041776ef64a6d8..7ee5fefb4eea123647bb3d0ffdcf6c2d613fbb86 100644 --- a/nifty/operators/fft_operator/transformations/slicing_transformation.py +++ b/nifty/operators/fft_operator/transformations/slicing_transformation.py @@ -35,14 +35,12 @@ class SlicingTransformation(Transformation): for slice_list in utilities.get_slice_list(val.shape, axes): if return_val is None: - return_val = val.copy_empty(global_shape=return_shape) - - data = val.get_data(slice_list, copy=False) - data = data.get_full_data() + return_val = np.empty(return_shape,dtype=val.dtype) + data = val[slice_list] data = self._transformation_of_slice(data, **kwargs) - return_val.set_data(data=data, to_key=slice_list, copy=False) + return_val[slice_list] = data return return_val diff --git a/nifty/operators/response_operator/response_operator.py b/nifty/operators/response_operator/response_operator.py index f8757515dd2b0f7cd409f6bfe2deb42416e3e3f1..da58f0d4f12f31147a09aa60b37518fa8247b6b0 100644 --- a/nifty/operators/response_operator/response_operator.py +++ b/nifty/operators/response_operator/response_operator.py @@ -44,27 +44,6 @@ class ResponseOperator(LinearOperator): raised if: * len of sigma-list and exposure-list are not equal - Notes - ----- - - Examples - -------- - >>> x1 = RGSpace(5) - >>> x2 = RGSpace(10) - >>> R = ResponseOperator(domain=(x1,x2), sigma=[.5, .25], - exposure=[2.,3.]) - >>> f = Field((x1,x2), val=4.) - >>> R.times(f) - <distributed_data_object> - array([[ 24., 24., 24., 24., 24., 24., 24., 24., 24., 24.], - [ 24., 24., 24., 24., 24., 24., 24., 24., 24., 24.], - [ 24., 24., 24., 24., 24., 24., 24., 24., 24., 24.], - [ 24., 24., 24., 24., 24., 24., 24., 24., 24., 24.], - [ 24., 24., 24., 24., 24., 24., 24., 24., 24., 24.]]) - - See Also - -------- - """ def __init__(self, domain, sigma=[1.], exposure=[1.], diff --git a/nifty/spaces/lm_space/lm_space.py b/nifty/spaces/lm_space/lm_space.py index 5b0b6c229dbce28118d4c6c9b7f6147ed3365089..6c8010fdebb629f6b7aac25bc72200d8d19cf207 100644 --- a/nifty/spaces/lm_space/lm_space.py +++ b/nifty/spaces/lm_space/lm_space.py @@ -22,8 +22,6 @@ import numpy as np from ..space import Space -from d2o import arange, distributed_data_object - class LMSpace(Space): """ @@ -126,33 +124,18 @@ class LMSpace(Space): else: return x.copy() - def get_distance_array(self, distribution_strategy): - if distribution_strategy == 'not': # short cut - lmax = self.lmax - ldist = np.empty((self.dim,), dtype=np.float64) - ldist[0:lmax+1] = np.arange(lmax+1, dtype=np.float64) - tmp = np.empty((2*lmax+2), dtype=np.float64) - tmp[0::2] = np.arange(lmax+1) - tmp[1::2] = np.arange(lmax+1) - idx = lmax+1 - for l in range(1, lmax+1): - ldist[idx:idx+2*(lmax+1-l)] = tmp[2*l:] - idx += 2*(lmax+1-l) - dists = distributed_data_object( - global_shape=self.shape, - dtype=np.float, - distribution_strategy=distribution_strategy) - dists.set_local_data(ldist) - return dists - - dists = arange(start=0, stop=self.shape[0], - distribution_strategy=distribution_strategy) - - dists = dists.apply_scalar_function( - lambda x: self._distance_array_helper(x, self.lmax), - dtype=np.float64) - - return dists + def get_distance_array(self): + lmax = self.lmax + ldist = np.empty((self.dim,), dtype=np.float64) + ldist[0:lmax+1] = np.arange(lmax+1, dtype=np.float64) + tmp = np.empty((2*lmax+2), dtype=np.float64) + tmp[0::2] = np.arange(lmax+1) + tmp[1::2] = np.arange(lmax+1) + idx = lmax+1 + for l in range(1, lmax+1): + ldist[idx:idx+2*(lmax+1-l)] = tmp[2*l:] + idx += 2*(lmax+1-l) + return ldist def get_unique_distances(self): return np.arange(self.lmax+1, dtype=np.float64) diff --git a/nifty/spaces/power_space/power_space.py b/nifty/spaces/power_space/power_space.py index 17e7c54b531655ff7d37a9cfc7ff3b8b898694af..9a8a697e8ed49485826d4a5959e88c971519d1a6 100644 --- a/nifty/spaces/power_space/power_space.py +++ b/nifty/spaces/power_space/power_space.py @@ -20,9 +20,6 @@ import ast import numpy as np -from d2o import distributed_data_object,\ - STRATEGIES as DISTRIBUTION_STRATEGIES - from ...spaces.space import Space from functools import reduce from ...config import nifty_configuration as gc @@ -35,10 +32,6 @@ class PowerSpace(Space): ---------- harmonic_partner : Space The harmonic Space of which this is the power space. - distribution_strategy : str *optional* - The distribution strategy used for the distributed_data_objects - derived from this PowerSpace, e.g. the pindex. - (default : 'not') logarithmic : bool *optional* True if logarithmic binning should be used (default : None). nbin : {int, None} *optional* @@ -61,7 +54,7 @@ class PowerSpace(Space): Attributes ---------- - pindex : distributed_data_object + pindex : numpy.ndarray This holds the information which pixel of the harmonic partner gets mapped to which power bin kindex : numpy.ndarray @@ -91,18 +84,11 @@ class PowerSpace(Space): # ---Overwritten properties and methods--- - def __init__(self, harmonic_partner, distribution_strategy=None, + def __init__(self, harmonic_partner, logarithmic=None, nbin=None, binbounds=None): super(PowerSpace, self).__init__() self._ignore_for_hash += ['_pindex', '_kindex', '_rho'] - if distribution_strategy is None: - distribution_strategy = gc['default_distribution_strategy'] - elif distribution_strategy not in DISTRIBUTION_STRATEGIES['global']: - raise ValueError( - "distribution_strategy must be a global-type " - "strategy.") - if not (isinstance(harmonic_partner, Space) and harmonic_partner.harmonic): raise ValueError("harmonic_partner must be a harmonic space.") @@ -116,26 +102,25 @@ class PowerSpace(Space): if binbounds is not None: binbounds = tuple(binbounds) - key = (harmonic_partner, distribution_strategy, logarithmic, nbin, - binbounds) + key = (harmonic_partner, logarithmic, nbin, binbounds) if self._powerIndexCache.get(key) is None: distance_array = \ - self.harmonic_partner.get_distance_array(distribution_strategy) + self.harmonic_partner.get_distance_array() temp_binbounds = self._compute_binbounds( harmonic_partner=self.harmonic_partner, - distribution_strategy=distribution_strategy, logarithmic=logarithmic, nbin=nbin, binbounds=binbounds) temp_pindex = self._compute_pindex( harmonic_partner=self.harmonic_partner, distance_array=distance_array, - binbounds=temp_binbounds, - distribution_strategy=distribution_strategy) - temp_rho = temp_pindex.bincount().get_full_data() - temp_kindex = \ - (temp_pindex.bincount(weights=distance_array).get_full_data() / - temp_rho) + binbounds=temp_binbounds) + #temp_rho = temp_pindex.bincount().get_full_data() + temp_rho = np.bincount(temp_pindex.flatten()) + #temp_kindex = \ + # (temp_pindex.bincount(weights=distance_array).get_full_data() / + # temp_rho) + temp_kindex = np.bincount(temp_pindex.flatten(),weights=distance_array.flatten())/temp_rho self._powerIndexCache[key] = (temp_binbounds, temp_pindex, temp_kindex, @@ -145,7 +130,7 @@ class PowerSpace(Space): self._powerIndexCache[key] @staticmethod - def _compute_binbounds(harmonic_partner, distribution_strategy, + def _compute_binbounds(harmonic_partner, logarithmic, nbin, binbounds): if logarithmic is None and nbin is None and binbounds is None: @@ -182,19 +167,10 @@ class PowerSpace(Space): return result @staticmethod - def _compute_pindex(harmonic_partner, distance_array, binbounds, - distribution_strategy): - - # Compute pindex, kindex and rho according to bb - pindex = distributed_data_object( - global_shape=distance_array.shape, - dtype=np.int, - distribution_strategy=distribution_strategy) + def _compute_pindex(harmonic_partner, distance_array, binbounds): if binbounds is None: binbounds = harmonic_partner.get_natural_binbounds() - pindex.set_local_data( - np.searchsorted(binbounds, distance_array.get_local_data())) - return pindex + return np.searchsorted(binbounds, distance_array) def pre_cast(self, x, axes): """ Casts power spectrum functions to discretized power spectra. @@ -224,10 +200,8 @@ class PowerSpace(Space): # ---Mandatory properties and methods--- def __repr__(self): - return ("PowerSpace(harmonic_partner=%r, distribution_strategy=%r, " - "binbounds=%r)" - % (self.harmonic_partner, self.pindex.distribution_strategy, - self._binbounds)) + return ("PowerSpace(harmonic_partner=%r, binbounds=%r)" + % (self.harmonic_partner, self._binbounds)) @property def harmonic(self): @@ -247,9 +221,7 @@ class PowerSpace(Space): return float(reduce(lambda x, y: x*y, self.pindex.shape)) def copy(self): - distribution_strategy = self.pindex.distribution_strategy return self.__class__(harmonic_partner=self.harmonic_partner, - distribution_strategy=distribution_strategy, binbounds=self._binbounds) def weight(self, x, power, axes, inplace=False): @@ -269,10 +241,8 @@ class PowerSpace(Space): return result_x - def get_distance_array(self, distribution_strategy): - return distributed_data_object( - self.kindex, dtype=np.float64, - distribution_strategy=distribution_strategy) + def get_distance_array(self): + return self.kindex.copy() def get_fft_smoothing_kernel_function(self, sigma): raise NotImplementedError( @@ -292,7 +262,7 @@ class PowerSpace(Space): @property def pindex(self): - """ A distributed_data_object having the shape of the harmonic partner + """ A numpy.ndarray having the shape of the harmonic partner space containing the indices of the power bin a pixel belongs to. """ return self._pindex @@ -313,8 +283,6 @@ class PowerSpace(Space): def _to_hdf5(self, hdf5_group): hdf5_group.attrs['binbounds'] = str(self._binbounds) - hdf5_group.attrs['distribution_strategy'] = \ - self._pindex.distribution_strategy return { 'harmonic_partner': self.harmonic_partner, @@ -324,5 +292,4 @@ class PowerSpace(Space): def _from_hdf5(cls, hdf5_group, repository): hp = repository.get('harmonic_partner', hdf5_group) bb = ast.literal_eval(hdf5_group.attrs['binbounds']) - ds = hdf5_group.attrs['distribution_strategy'] - return PowerSpace(hp, ds, binbounds=bb) + return PowerSpace(hp, binbounds=bb) diff --git a/nifty/spaces/rg_space/rg_space.py b/nifty/spaces/rg_space/rg_space.py index 04b0b08e264ce3a53cf681c54bf368d1d78c9e0b..2f561f8e302bb96335e46a263bcedd5834d6dc47 100644 --- a/nifty/spaces/rg_space/rg_space.py +++ b/nifty/spaces/rg_space/rg_space.py @@ -34,9 +34,6 @@ from functools import reduce import numpy as np -from d2o import distributed_data_object,\ - STRATEGIES as DISTRIBUTION_STRATEGIES - from ..space import Space from ...config import nifty_configuration @@ -193,42 +190,23 @@ class RGSpace(Space): result_x = x*weight return result_x - def get_distance_array(self, distribution_strategy): + def get_distance_array(self): """ Calculates an n-dimensional array with its entries being the lengths of the vectors from the zero point of the grid. - Parameters - ---------- - distribution_strategy : str - The distribution_strategy which shall be used the returned - distributed_data_object. - Returns ------- - distributed_data_object - A d2o containing the distances. + numpy.ndarray + An array containing the distances. """ shape = self.shape - # prepare the distributed_data_object - nkdict = distributed_data_object( - global_shape=shape, dtype=np.float64, - distribution_strategy=distribution_strategy) - - if distribution_strategy in DISTRIBUTION_STRATEGIES['slicing']: - # get the node's individual slice of the first dimension - slice_of_first_dimension = slice( - *nkdict.distributor.local_slice[0:2]) - elif distribution_strategy in DISTRIBUTION_STRATEGIES['not']: - slice_of_first_dimension = slice(0, shape[0]) - else: - raise ValueError( - "Unsupported distribution strategy") + + slice_of_first_dimension = slice(0, shape[0]) dists = self._distance_array_helper(slice_of_first_dimension) - nkdict.set_local_data(dists) - return nkdict + return dists def _distance_array_helper(self, slice_of_first_dimension): dk = self.distances diff --git a/nifty/spaces/space/space.py b/nifty/spaces/space/space.py index 57b3e469a36e2064cfa00b9978fa9ef6a8053bed..a4e1c599dd24bd9eb60064676b24b831aa7a6f0d 100644 --- a/nifty/spaces/space/space.py +++ b/nifty/spaces/space/space.py @@ -95,22 +95,16 @@ class Space(DomainObject): return self.__class__() - def get_distance_array(self, distribution_strategy): + def get_distance_array(self): """ The distances of the pixel to zero. This returns an array that gives for each pixel its distance to the center of the manifolds grid. - Parameters - ---------- - distribution_strategy : str - The distribution_strategy which shall be used the returned - distributed_data_object. - Returns ------- - distributed_data_object - A d2o containing the distances + numpy.ndarray + An array containing the distances """ @@ -125,7 +119,7 @@ class Space(DomainObject): Returns ------- - distributed_data_object + np.ndarray A numpy array containing the binbounds """ @@ -174,7 +168,7 @@ class Space(DomainObject): Returns ------- - distributed_data_object + numpy.ndarray The Hermitian-flipped of x. """ diff --git a/nifty/sugar.py b/nifty/sugar.py index 346269196e4625122cad9da2f3ab141548976240..6f25f425eb5db5543b97752b1573802d074a4583 100644 --- a/nifty/sugar.py +++ b/nifty/sugar.py @@ -32,8 +32,7 @@ __all__ = ['create_power_operator', 'create_composed_fft_operator'] -def create_power_operator(domain, power_spectrum, dtype=None, - distribution_strategy=None): +def create_power_operator(domain, power_spectrum, dtype=None): """ Creates a diagonal operator with the given power spectrum. Constructs a diagonal operator that lives over the specified domain. @@ -49,9 +48,6 @@ def create_power_operator(domain, power_spectrum, dtype=None, dtype that the field holding the power spectrum shall use (default : None). if dtype == None: the dtype of `power_spectrum` will be used. - distribution_strategy : string *optional* - Distributed strategy to be used by the underlying d2o objects. - (default : 'not') Returns ------- @@ -59,20 +55,13 @@ def create_power_operator(domain, power_spectrum, dtype=None, """ - if distribution_strategy is None: - distribution_strategy = \ - nifty_configuration['default_distribution_strategy'] - if isinstance(power_spectrum, Field): power_domain = power_spectrum.domain else: - power_domain = PowerSpace(domain, - distribution_strategy=distribution_strategy) + power_domain = PowerSpace(domain) - fp = Field(power_domain, val=power_spectrum, dtype=dtype, - distribution_strategy='not') - f = fp.power_synthesize(mean=1, std=0, real_signal=False, - distribution_strategy=distribution_strategy) + fp = Field(power_domain, val=power_spectrum, dtype=dtype) + f = fp.power_synthesize(mean=1, std=0, real_signal=False) if not issubclass(fp.dtype.type, np.complexfloating): f = f.real diff --git a/test/test_field.py b/test/test_field.py index 600595a545bbaa04eb1007c614bf47edb4387fd4..bfff979c4d2f3d67c5a21015752fdfdc85b5f206 100644 --- a/test/test_field.py +++ b/test/test_field.py @@ -32,9 +32,6 @@ from nifty import Field,\ PowerSpace,\ nifty_configuration -import d2o -from d2o import distributed_data_object - from test.common import expand @@ -44,10 +41,9 @@ SPACE_COMBINATIONS = [(), SPACES[0], SPACES[1], SPACES] class Test_Interface(unittest.TestCase): @expand(product(SPACE_COMBINATIONS, - [['distribution_strategy', str], - ['domain', tuple], + [['domain', tuple], ['domain_axes', tuple], - ['val', distributed_data_object], + ['val', np.ndarray], ['shape', tuple], ['dim', np.int], ['dof', np.int], @@ -86,10 +82,10 @@ class Test_Functionality(unittest.TestCase): h3, a3 = Field._hermitian_decomposition((r1, r2), f2.val, (1, 0), ((0,), (1,)), preserve) - assert_almost_equal(h1.get_full_data(), h2.get_full_data()) - assert_almost_equal(a1.get_full_data(), a2.get_full_data()) - assert_almost_equal(h1.get_full_data(), h3.get_full_data()) - assert_almost_equal(a1.get_full_data(), a3.get_full_data()) + assert_almost_equal(h1, h2) + assert_almost_equal(a1, a2) + assert_almost_equal(h1, h3) + assert_almost_equal(a1, a3) @expand(product([RGSpace((8,), harmonic=True, zerocenter=False), @@ -102,7 +98,7 @@ class Test_Functionality(unittest.TestCase): def test_power_synthesize_analyze(self, space1, space2, base): nifty_configuration['harmonic_rg_base'] = base - d2o.random.seed(11) + np.random.seed(11) p1 = PowerSpace(space1) spec1 = lambda k: 42/(1+k)**2 @@ -112,7 +108,7 @@ class Test_Functionality(unittest.TestCase): spec2 = lambda k: 42/(1+k)**3 fp2 = Field(p2, val=spec2) - outer = np.outer(fp1.val.get_full_data(), fp2.val.get_full_data()) + outer = np.outer(fp1.val, fp2.val) fp = Field((p1, p2), val=outer) samples = 2000 @@ -125,11 +121,11 @@ class Test_Functionality(unittest.TestCase): ps1 += sp.sum(spaces=1)/fp2.sum() ps2 += sp.sum(spaces=0)/fp1.sum() - assert_allclose(ps1.val.get_full_data()/samples, - fp1.val.get_full_data(), + assert_allclose(ps1.val/samples, + fp1.val, rtol=0.2) - assert_allclose(ps2.val.get_full_data()/samples, - fp2.val.get_full_data(), + assert_allclose(ps2.val/samples, + fp2.val, rtol=0.2) def test_vdot(self): diff --git a/test/test_operators/test_fft_operator.py b/test/test_operators/test_fft_operator.py index 881a34ec92cb4b702ea75ae02e002324711903a6..ebc290c394a2ee498439383f3337ac505836e86a 100644 --- a/test/test_operators/test_fft_operator.py +++ b/test/test_operators/test_fft_operator.py @@ -32,8 +32,6 @@ from itertools import product from test.common import expand from nose.plugins.skip import SkipTest -from d2o import STRATEGIES - def _get_rtol(tp): if (tp == np.float64) or (tp == np.complex128): @@ -43,14 +41,11 @@ def _get_rtol(tp): class FFTOperatorTests(unittest.TestCase): - @expand(product(["numpy", "fftw", "fftw_mpi"], - [16, ], [0.1, 1, 3.7], STRATEGIES['global'], + @expand(product(["numpy", "fftw"], + [16, ], [0.1, 1, 3.7], [np.float64, np.float32, np.complex64, np.complex128], ['real', 'complex'])) - def test_fft1D(self, module, dim1, d, distribution_strategy, itp, base): - if module == "fftw_mpi": - if not hasattr(gdi.get('fftw'), 'FFTW_MPI'): - raise SkipTest + def test_fft1D(self, module, dim1, d, itp, base): if module == "fftw" and "fftw" not in gdi: raise SkipTest tol = _get_rtol(itp) @@ -62,23 +57,17 @@ class FFTOperatorTests(unittest.TestCase): np.random.seed(16) inp = Field.from_random(domain=a, random_type='normal', std=7, mean=3, - dtype=itp, - distribution_strategy=distribution_strategy) + dtype=itp) out = fft.adjoint_times(fft.times(inp)) - assert_allclose(inp.val.get_full_data(), - out.val.get_full_data(), - rtol=tol, atol=tol) + assert_allclose(inp.val, out.val, rtol=tol, atol=tol) - @expand(product(["numpy", "fftw", "fftw_mpi"], + @expand(product(["numpy", "fftw"], [12, 15], [9, 12], [0.1, 1, 3.7], - [0.4, 1, 2.7], STRATEGIES['global'], + [0.4, 1, 2.7], [np.float64, np.float32, np.complex64, np.complex128], ['real', 'complex'])) - def test_fft2D(self, module, dim1, dim2, d1, d2, distribution_strategy, + def test_fft2D(self, module, dim1, dim2, d1, d2, itp, base): - if module == "fftw_mpi": - if not hasattr(gdi.get('fftw'), 'FFTW_MPI'): - raise SkipTest if module == "fftw" and "fftw" not in gdi: raise SkipTest tol = _get_rtol(itp) @@ -90,21 +79,16 @@ class FFTOperatorTests(unittest.TestCase): fft._backward_transformation.harmonic_base = base inp = Field.from_random(domain=a, random_type='normal', std=7, mean=3, - dtype=itp, - distribution_strategy=distribution_strategy) + dtype=itp) out = fft.adjoint_times(fft.times(inp)) assert_allclose(inp.val, out.val, rtol=tol, atol=tol) - @expand(product(["numpy", "fftw", "fftw_mpi"], + @expand(product(["numpy", "fftw"], [0, 1, 2], - STRATEGIES['global'], [np.float64, np.float32, np.complex64, np.complex128], ['real', 'complex'])) - def test_composed_fft(self, module, index, distribution_strategy, dtype, + def test_composed_fft(self, module, index, dtype, base): - if module == "fftw_mpi": - if not hasattr(gdi.get('fftw'), 'FFTW_MPI'): - raise SkipTest if module == "fftw" and "fftw" not in gdi: raise SkipTest tol = _get_rtol(dtype) @@ -115,8 +99,7 @@ class FFTOperatorTests(unittest.TestCase): fft._backward_transformation.harmonic_base = base inp = Field.from_random(domain=(a1, a2, a3), random_type='normal', - std=7, mean=3, dtype=dtype, - distribution_strategy=distribution_strategy) + std=7, mean=3, dtype=dtype) out = fft.adjoint_times(fft.times(inp)) assert_allclose(inp.val, out.val, rtol=tol, atol=tol) diff --git a/test/test_spaces/test_power_space.py b/test/test_spaces/test_power_space.py index 667c3200a9ba0fdcafaed63a77ebd92a443a222c..aed6def32336b271cdf6aa3d03188a8a9cf07860 100644 --- a/test/test_spaces/test_power_space.py +++ b/test/test_spaces/test_power_space.py @@ -21,7 +21,6 @@ from __future__ import division import unittest import numpy as np -from d2o import distributed_data_object from numpy.testing import assert_, assert_equal, assert_almost_equal,\ assert_raises from nifty import PowerSpace, RGSpace, Space, LMSpace @@ -41,41 +40,37 @@ HARMONIC_SPACES = [RGSpace((8,), harmonic=True), LMSpace(9)] -#Try all sensible kinds of combinations of spaces, distributuion strategy and -#binning parameters +# Try all sensible kinds of combinations of spaces and binning parameters CONSISTENCY_CONFIGS_IMPLICIT = product(HARMONIC_SPACES, - ["not", "equal", "fftw"], [None], [None, 3, 4], [True, False]) CONSISTENCY_CONFIGS_EXPLICIT = product(HARMONIC_SPACES, - ["not", "equal", "fftw"], [[0., 1.3]], [None], [None]) CONSISTENCY_CONFIGS = chain(CONSISTENCY_CONFIGS_IMPLICIT, CONSISTENCY_CONFIGS_EXPLICIT) -# [harmonic_partner, distribution_strategy, -# logarithmic, nbin, binbounds, expected] +# [harmonic_partner, logarithmic, nbin, binbounds, expected] CONSTRUCTOR_CONFIGS = [ - [1, 'not', False, None, None, {'error': ValueError}], - [RGSpace((8,)), 'not', False, None, None, {'error': ValueError}], - [RGSpace((8,), harmonic=True), 'not', None, None, None, { + [1, False, None, None, {'error': ValueError}], + [RGSpace((8,)), False, None, None, {'error': ValueError}], + [RGSpace((8,), harmonic=True), None, None, None, { 'harmonic': True, 'shape': (5,), 'dim': 5, 'total_volume': 8.0, 'harmonic_partner': RGSpace((8,), harmonic=True), 'binbounds': None, - 'pindex': distributed_data_object([0, 1, 2, 3, 4, 3, 2, 1]), + 'pindex': np.array([0, 1, 2, 3, 4, 3, 2, 1]), 'kindex': np.array([0., 1., 2., 3., 4.]), 'rho': np.array([1, 2, 2, 2, 1]), }], - [RGSpace((8,), harmonic=True), 'not', True, None, None, { + [RGSpace((8,), harmonic=True), True, None, None, { 'harmonic': True, 'shape': (2,), 'dim': 2, 'total_volume': 8.0, 'harmonic_partner': RGSpace((8,), harmonic=True), 'binbounds': (0.70710678118654757,), - 'pindex': distributed_data_object([0, 1, 1, 1, 1, 1, 1, 1]), + 'pindex': np.array([0, 1, 1, 1, 1, 1, 1, 1]), 'kindex': np.array([0., 2.28571429]), 'rho': np.array([1, 7]), }], @@ -111,7 +106,7 @@ class PowerSpaceInterfaceTest(unittest.TestCase): @expand([ ['harmonic_partner', Space], ['binbounds', type(None)], - ['pindex', distributed_data_object], + ['pindex', np.ndarray], ['kindex', np.ndarray], ['rho', np.ndarray], ]) @@ -123,35 +118,26 @@ class PowerSpaceInterfaceTest(unittest.TestCase): class PowerSpaceConsistencyCheck(unittest.TestCase): @expand(CONSISTENCY_CONFIGS) - def test_rhopindexConsistency(self, harmonic_partner, distribution_strategy, + def test_rhopindexConsistency(self, harmonic_partner, binbounds, nbin, logarithmic): - if distribution_strategy == "fftw": - if not hasattr(gdi.get('fftw'), 'FFTW_MPI'): - raise SkipTest p = PowerSpace(harmonic_partner=harmonic_partner, - distribution_strategy=distribution_strategy, logarithmic=logarithmic, nbin=nbin, binbounds=binbounds) - assert_equal(p.pindex.flatten().bincount(), p.rho, + assert_equal(np.bincount(p.pindex.flatten()), p.rho, err_msg='rho is not equal to pindex degeneracy') class PowerSpaceFunctionalityTest(unittest.TestCase): @expand(CONSTRUCTOR_CONFIGS) - def test_constructor(self, harmonic_partner, distribution_strategy, + def test_constructor(self, harmonic_partner, logarithmic, nbin, binbounds, expected): - if distribution_strategy == "fftw": - if not hasattr(gdi.get('fftw'), 'FFTW_MPI'): - raise SkipTest if 'error' in expected: with assert_raises(expected['error']): PowerSpace(harmonic_partner=harmonic_partner, - distribution_strategy=distribution_strategy, logarithmic=logarithmic, nbin=nbin, binbounds=binbounds) else: p = PowerSpace(harmonic_partner=harmonic_partner, - distribution_strategy=distribution_strategy, logarithmic=logarithmic, nbin=nbin, binbounds=binbounds) for key, value in expected.items(): @@ -163,7 +149,7 @@ class PowerSpaceFunctionalityTest(unittest.TestCase): @expand(get_distance_array_configs()) def test_distance_array(self, harmonic_partner, expected): p = PowerSpace(harmonic_partner=harmonic_partner) - assert_almost_equal(p.get_distance_array('not'), expected) + assert_almost_equal(p.get_distance_array(), expected) @expand(get_weight_configs()) def test_weight(self, harmonic_partner, x, power, axes, diff --git a/test/test_spaces/test_rg_space.py b/test/test_spaces/test_rg_space.py index 6720f7fcbd192cc2657e765c5264be8b88d22cbf..0be6c7e33c60844c9099c67513642be326a5f649 100644 --- a/test/test_spaces/test_rg_space.py +++ b/test/test_spaces/test_rg_space.py @@ -21,8 +21,6 @@ from __future__ import division import unittest import numpy as np -from d2o import distributed_data_object - from numpy.testing import assert_, assert_equal, assert_almost_equal, \ assert_array_equal from nifty import RGSpace, nifty_configuration @@ -165,7 +163,7 @@ class RGSpaceFunctionalityTests(unittest.TestCase): r = RGSpace(shape, harmonic=True, zerocenter=zerocenter) except ValueError: raise SkipTest - v = distributed_data_object(global_shape=shape, dtype=np.complex128) + v = np.empty(shape, dtype=np.complex128) v[:] = np.random.random(shape) + 1j*np.random.random(shape) nifty_configuration['harmonic_rg_base'] = base @@ -191,7 +189,7 @@ class RGSpaceFunctionalityTests(unittest.TestCase): @expand(get_distance_array_configs()) def test_distance_array(self, shape, distances, zerocenter, expected): r = RGSpace(shape=shape, distances=distances, zerocenter=zerocenter) - assert_almost_equal(r.get_distance_array('not'), expected) + assert_almost_equal(r.get_distance_array(), expected) @expand(get_weight_configs()) def test_weight(self, shape, distances, harmonic, x, power, axes,