Commit dc144ef8 authored by ultimanet's avatar ultimanet
Browse files

Added a mpi_dummy.py. Integrated the paradicts to the spaces. Implemented...

Added a mpi_dummy.py. Integrated the paradicts to the spaces. Implemented unary_operation, binary_operation and norm in the spaces. Extended the functions of the distributed_data_object for the unary and binary operations.
parent df1e7ede
......@@ -26,18 +26,24 @@ from nifty_power import *
from nifty_tools import *
from nifty_explicit import *
from nifty_mpi_data import distributed_data_object
from nifty_paradict import space_paradict,\
point_space_paradict,\
nested_space_paradict
## optional submodule `rg`
try:
from rg import *
from nifty_paradict import rg_space_paradict
except(ImportError):
pass
## optional submodule `lm`
try:
from lm import *
from nifty_paradict import lm_space_paradict,\
gl_space_paradict,\
hp_space_paradict
except(ImportError):
print 'asdf'
pass
from demos import *
......
......@@ -44,6 +44,10 @@ from nifty.nifty_core import pi, \
space, \
point_space, \
field
from nifty_paradict import lm_space_paradict,\
gl_space_paradict,\
hp_space_paradict
#import libsharp_wrapper_gl as gl
try:
import libsharp_wrapper_gl as gl
......@@ -152,22 +156,12 @@ class lm_space(point_space):
If input `nside` is invaild.
"""
## check imports
if(not _gl_available)and(not _hp_available):
raise ImportError(about._errors.cstring("ERROR: neither libsharp_wrapper_gl nor healpy available."))
## check parameters
if(lmax<1):
raise ValueError(about._errors.cstring("ERROR: nonpositive number."))
if(lmax%2==0)and(lmax>2): ## exception lmax == 2 (nside == 1)
about.warnings.cprint("WARNING: unrecommended parameter ( lmax <> 2*n+1 ).")
if(mmax is None):
mmax = lmax
elif(mmax<1)or(mmax>lmax):
about.warnings.cprint("WARNING: parameter set to default.")
mmax = lmax
if(mmax!=lmax):
about.warnings.cprint("WARNING: unrecommended parameter ( mmax <> lmax ).")
self.para = np.array([lmax,mmax],dtype=np.int)
self.paradict = lm_space_paradict(lmax=lmax, mmax=mmax)
## check data type
if(datatype is None):
......@@ -180,6 +174,20 @@ class lm_space(point_space):
self.discrete = True
self.vol = np.real(np.array([1],dtype=self.datatype))
@property
def para(self):
temp = np.array([self.paradict['lmax'],
self.paradict['mmax']], dtype=int)
return temp
@para.setter
def para(self, x):
self.paradict['lmax'] = x[0]
self.paradict['mmax'] = x[1]
##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def lmax(self):
......@@ -191,7 +199,7 @@ class lm_space(point_space):
lmax : int
Maximum quantum number :math:`\ell`.
"""
return self.para[0]
return self.paradict['lmax']
def mmax(self):
"""
......@@ -203,7 +211,7 @@ class lm_space(point_space):
Maximum quantum number :math:`m`.
"""
return self.para[1]
return self.paradict['mmax']
def dim(self,split=False):
"""
......@@ -1014,19 +1022,9 @@ class gl_space(point_space):
## check imports
if(not _gl_available):
raise ImportError(about._errors.cstring("ERROR: libsharp_wrapper_gl not available."))
## check parameters
if(nlat<1):
raise ValueError(about._errors.cstring("ERROR: nonpositive number."))
if(nlat%2!=0):
raise ValueError(about._errors.cstring("ERROR: invalid parameter ( nlat <> 2*n )."))
if(nlon is None):
nlon = 2*nlat-1
elif(nlon<1):
about.warnings.cprint("WARNING: parameter set to default.")
nlon = 2*nlat-1
if(nlon!=2*nlat-1):
about.warnings.cprint("WARNING: unrecommended parameter ( nlon <> 2*nlat-1 ).")
self.para = np.array([nlat,nlon],dtype=np.int)
self.paradict = gl_space_paradict(nlat=nlat, nlon=nlon)
## check data type
if(datatype is None):
......@@ -1039,6 +1037,19 @@ class gl_space(point_space):
self.discrete = False
self.vol = gl.vol(self.para[0],nlon=self.para[1]).astype(self.datatype)
@property
def para(self):
temp = np.array([self.paradict['nlat'],
self.paradict['nlon']], dtype=int)
return temp
@para.setter
def para(self, x):
self.paradict['nlat'] = x[0]
self.paradict['nlon'] = x[1]
##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def nlat(self):
......@@ -1050,7 +1061,7 @@ class gl_space(point_space):
nlat : int
Number of latitudinal bins, or rings.
"""
return self.para[0]
return self.paradict['nlat']
def nlon(self):
"""
......@@ -1061,7 +1072,7 @@ class gl_space(point_space):
nlon : int
Number of longitudinal bins.
"""
return self.para[1]
return self.paradict['nlon']
def dim(self,split=False):
"""
......@@ -1683,17 +1694,24 @@ class hp_space(point_space):
## check imports
if(not _hp_available):
raise ImportError(about._errors.cstring("ERROR: healpy not available."))
## check parameters
if(nside<1):
raise ValueError(about._errors.cstring("ERROR: nonpositive number."))
if(not hp.isnsideok(nside)):
raise ValueError(about._errors.cstring("ERROR: invalid parameter ( nside <> 2**n )."))
self.para = np.array([nside],dtype=np.int)
## check parameters
self.paradict = hp_space_paradict(nside=nside)
self.datatype = np.float64
self.discrete = False
self.vol = np.array([4*pi/(12*self.para[0]**2)],dtype=self.datatype)
@property
def para(self):
temp = np.array([self.paradict['nside']], dtype=int)
return temp
@para.setter
def para(self, x):
self.paradict['nside'] = x[0]
##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def nside(self):
......@@ -1705,7 +1723,7 @@ class hp_space(point_space):
nside : int
HEALPix resolution parameter.
"""
return self.para[0]
return self.paradict['nside']
def dim(self,split=False):
......
......@@ -25,6 +25,8 @@ class _COMM_WORLD():
return self.size
def _scattergather_helper(self, sendbuf, recvbuf=None):
sendbuf = self._unwrapper(sendbuf)
recvbuf = self._unwrapper(recvbuf)
if recvbuf != None:
recvbuf[:] = sendbuf
return recvbuf
......@@ -38,17 +40,17 @@ class _COMM_WORLD():
def Bcast(self, sendbuf, *args, **kwargs):
return sendbuf
def scatter(self, *args, **kwargs):
return self._scattergather_helper(*args, **kwargs)
def scatter(self, sendbuf, *args, **kwargs):
return sendbuf[0]
def Scatter(self, *args, **kwargs):
return self._scattergather_helper(*args, **kwargs)
def Scatterv(self, *args, **kwargs):
return self._scattergather_helper(*args, **kwargs)
def gather(self, *args, **kwargs):
return self._scattergather_helper(*args, **kwargs)
def gather(self, sendbuf, *args, **kwargs):
return [sendbuf,]
def Gather(self, *args, **kwargs):
return self._scattergather_helper(*args, **kwargs)
......@@ -56,9 +58,9 @@ class _COMM_WORLD():
def Gatherv(self, *args, **kwargs):
return self._scattergather_helper(*args, **kwargs)
def allgather(self, *args, **kwargs):
return self._scattergather_helper(*args, **kwargs)
def allgather(self, sendbuf, *args, **kwargs):
return [sendbuf,]
def Allgather(self, *args, **kwargs):
return self._scattergather_helper(*args, **kwargs)
......@@ -78,15 +80,15 @@ class _COMM_WORLD():
return x[0]
else:
return x
def Barrier(self):
pass
class _datatype():
def __init__(self, name):
self.name = str(name)
SHORT = _datatype('MPI_SHORT')
UNSIGNED_SHORT = _datatype("MPI_UNSIGNED_SHORT")
UNSIGNED_INT = _datatype("MPI_UNSIGNED_INT")
INT = _datatype("MPI_INT")
......
......@@ -149,7 +149,9 @@ from multiprocessing import Pool as mp
from multiprocessing import Value as mv
from multiprocessing import Array as ma
from nifty_mpi_data import distributed_data_object
from nifty_paradict import space_paradict,\
point_space_paradict,\
nested_space_paradict
__version__ = "1.0.7"
......@@ -996,11 +998,7 @@ class space(object):
-------
None
"""
if(np.isscalar(para)):
para = np.array([para],dtype=np.int)
else:
para = np.array(para,dtype=np.int)
self.para = para
self.paradict = space_paradict(default=para)
## check data type
if(datatype is None):
......@@ -1015,6 +1013,15 @@ class space(object):
self.shape = None
@property
def para(self):
return self.paradict['default']
#return self.distributed_val
@para.setter
def para(self, x):
self.paradict['default'] = x
##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def _freeze_config(self, dictionary):
"""
......@@ -1042,6 +1049,10 @@ class space(object):
def binary_operation(self, x, y, op=None):
raise NotImplementedError(about._errors.cstring("ERROR: no generic instance method 'binary_operation'."))
##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def norm(self, x, q):
raise NotImplementedError(about._errors.cstring("ERROR: no generic instance method 'norm'."))
##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def dim(self,split=False):
......@@ -1207,7 +1218,7 @@ class space(object):
##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def cast(self, x):
raise NotImplementedError(about._errors.cstring("ERROR: no generic instance method 'cast'."))
return self.enforce_values(x)
##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
......@@ -1425,7 +1436,10 @@ class space(object):
dot : scalar
Inner product of the two arrays.
"""
raise NotImplementedError(about._errors.cstring("ERROR: no generic instance method 'calc_dot'."))
raise NotImplementedError(about._errors.cstring(\
"ERROR: no generic instance method 'dot'."))
##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
......@@ -1795,11 +1809,8 @@ class point_space(space):
-------
None.
"""
## check parameter
if(num<1):
raise ValueError(about._errors.cstring("ERROR: nonpositive number."))
self.para = np.array([num],dtype=np.int)
self.paradict = point_space_paradict(num=num)
## check datatype
if(datatype is None):
datatype = np.float64
......@@ -1811,8 +1822,120 @@ class point_space(space):
self.discrete = True
self.vol = np.real(np.array([1],dtype=self.datatype))
##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@property
def para(self):
temp = np.array([self.paradict['num']], dtype=int)
return temp
#return self.distributed_val
@para.setter
def para(self, x):
self.paradict['num'] = x
##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def unary_operation(self, x, op='None', **kwargs):
"""
x must be a numpy array which is compatible with the space!
Valid operations are
"""
def _argmin(z, **kwargs):
ind = np.argmin(z, **kwargs)
if np.isscalar(ind):
ind = np.unravel_index(ind, z.shape, order='C')
if(len(ind)==1):
return ind[0]
return ind
def _argmax(z, **kwargs):
ind = np.argmax(z, **kwargs)
if np.isscalar(ind):
ind = np.unravel_index(ind, z.shape, order='C')
if(len(ind)==1):
return ind[0]
return ind
translation = {"pos" : lambda y: getattr(y, '__pos__')(),
"neg" : lambda y: getattr(y, '__neg__')(),
"abs" : lambda y: getattr(y, '__abs__')(),
"nanmin" : np.nanmin,
"min" : np.amin,
"nanmax" : np.nanmax,
"max" : np.amax,
"med" : np.median,
"mean" : np.mean,
"std" : np.std,
"var" : np.var,
"argmin" : _argmin,
"argmin_flat" : np.argmin,
"argmax" : _argmax,
"argmax_flat" : np.argmax,
"conjugate" : np.conjugate,
"None" : lambda y: y}
return translation[op](x, **kwargs)
##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def binary_operation(self, x, y, op='None', cast=0):
translation = {"add" : lambda z: getattr(z, '__add__'),
"iadd" : lambda z: getattr(z, '__iadd__'),
"sub" : lambda z: getattr(z, '__sub__'),
"rsub" : lambda z: getattr(z, '__rsub__'),
"isub" : lambda z: getattr(z, '__isub__'),
"mul" : lambda z: getattr(z, '__mul__'),
"imul" : lambda z: getattr(z, '__imul__'),
"div" : lambda z: getattr(z, '__div__'),
"rdiv" : lambda z: getattr(z, '__rdiv__'),
"idiv" : lambda z: getattr(z, '__idiv__'),
"pow" : lambda z: getattr(z, '__pow__'),
"rpow" : lambda z: getattr(z, '__rpow__'),
"ipow" : lambda z: getattr(z, '__ipow__'),
"None" : lambda z: lambda u: u}
if (cast & 1) != 0:
x = self.cast(x)
if (cast & 2) != 0:
y = self.cast(y)
return translation[op](x)(y)
##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def norm(self, x, q=2):
"""
Computes the Lq-norm of field values.
Parameters
----------
x : np.ndarray
The data array
q : scalar
Parameter q of the Lq-norm (default: 2).
Returns
-------
norm : scalar
The Lq-norm of the field values.
"""
if(q == 2):
result = self.calc_dot(x,x)
else:
y = x**(q-1)
result = self.calc_dot(x,y)
result = result**(1./q)
return result
##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def num(self):
"""
Returns the number of points.
......@@ -2189,7 +2312,31 @@ class point_space(space):
return x*self.vol**power
##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def calc_dot(self, x, y):
"""
Computes the discrete inner product of two given arrays of field
values.
Parameters
----------
x : numpy.ndarray
First array
y : numpy.ndarray
Second array
Returns
-------
dot : scalar
Inner product of the two arrays.
"""
x = self.cast(x)
y = self.cast(y)
result = np.vdot(x, y)
if np.isreal(result):
result = np.asscalar(np.real(result))
return result
'''
def calc_dot(self,x,y):
"""
Computes the discrete inner product of two given arrays of field
......@@ -2206,6 +2353,7 @@ class point_space(space):
-------
dot : scalar
Inner product of the two arrays.
"""
x = self.enforce_shape(np.array(x,dtype=self.datatype))
y = self.enforce_shape(np.array(y,dtype=self.datatype))
......@@ -2215,6 +2363,8 @@ class point_space(space):
return np.asscalar(np.real(dot))
else:
return dot
'''
##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
......@@ -4511,21 +4661,25 @@ class nested_space(space):
raise TypeError(about._errors.cstring("ERROR: invalid input."))
## check nest
purenest = []
para = np.array([],dtype=np.int)
pre_para = []
for nn in nest:
if(not isinstance(nn,space)):
raise TypeError(about._errors.cstring("ERROR: invalid input."))
elif(isinstance(nn,nested_space)): ## no 2nd level nesting
for nn_ in nn.nest:
purenest.append(nn_)
para = np.append(para,nn_.dim(split=True),axis=None)
pre_para = pre_para + [nn_.dim(split=True)]
else:
purenest.append(nn)
para = np.append(para,nn.dim(split=True),axis=None)
pre_para = pre_para + [nn.dim(split=True)]
if(len(purenest)<2):
raise ValueError(about._errors.cstring("ERROR: invalid input."))
self.nest = purenest
self.para = para
self.paradict = nested_space_paradict(ndim=len(pre_para))
for i in range(len(pre_para)):
self.paradict[i]=pre_para[i]
## check data type
for nn in self.nest[:-1]:
......@@ -4537,6 +4691,24 @@ class nested_space(space):
self.discrete = np.prod([nn.discrete for nn in self.nest],axis=0,dtype=np.bool,out=None)
self.vol = np.prod([nn.get_meta_volume(total=True) for nn in self.nest],axis=0,dtype=None,out=None) ## total volume
@property
def para(self):
temp = []
for i in range(self.paradict.ndim):
temp = np.append(temp, self.paradict[i])
return temp
@para.setter
def para(self, x):
dict_iter = 0
x_iter = 0
while dict_iter < self.paradict.ndim:
temp = x[x_iter:x_iter+len(self.paradict[dict_iter])]
self.paradict[dict_iter] = temp
x_iter = x_iter+len(self.paradict[dict_iter])
dict_iter += 1
##+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def dim(self,split=False):
......
This diff is collapsed.
......@@ -6,9 +6,10 @@ Created on Thu Apr 2 21:29:30 2015
"""
import numpy as np
## Importing * is ugly, but necessary because of the cyclic import structure
from nifty import *
#from nifty import about
"""
def paradict_getter(space_instance):
paradict_dictionary = {
str(space().__class__) : _space_paradict,
......@@ -21,21 +22,31 @@ def paradict_getter(space_instance):
}
return paradict_dictionary[str(space_instance.__class__)]()
"""
class _space_paradict(object):
class space_paradict(object):
def __init__(self, **kwargs):
self.parameters = {}
for key in kwargs:
self[key] = kwargs[key]
def __repr__(self):
return self.parameters.__repr__()
def __setitem__(self, key, arg):
if(np.isscalar(arg)):
arg = np.array([arg],dtype=np.int)
else:
arg = np.array(arg,dtype=np.int)
self.parameters.__setitem__(key, arg)
def __getitem__(self, key):
return self.parameters.__getitem__(key)
class _point_space_paradict(_space_paradict):
class point_space_paradict(space_paradict):
def __setitem__(self, key, arg):
if key is not 'num':
raise ValueError(about._errors.cstring("ERROR: Unsupported point_space parameter"))
......@@ -43,20 +54,20 @@ class _point_space_paradict(_space_paradict):
self.parameters.__setitem__(key, temp)
class _rg_space_paradict(_space_paradict):
def __init__(self, num, hermitian=False, zerocenter=False):
<