From d609fa59043cfa0c5bfc9c63552848a9b40791a0 Mon Sep 17 00:00:00 2001
From: ultimanet <ultimanet@users.noreply.github.com>
Date: Thu, 9 Apr 2015 15:05:32 +0200
Subject: [PATCH] Implemented paradict

---
 Makefile          | 181 +++++++++++++++++++++++++
 mpi_dummy.py      | 116 ++++++++++++++++
 nifty_paradict.py | 327 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 624 insertions(+)
 create mode 100644 Makefile
 create mode 100644 mpi_dummy.py
 create mode 100644 nifty_paradict.py

diff --git a/Makefile b/Makefile
new file mode 100644
index 000000000..15481075c
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,181 @@
+# This Makefile implements common tasks needed by developers
+# A list of implemented rules can be obtained by the command "make help"
+
+.DEFAULT_GOAL=build
+.PHONY .SILENT : help
+help :
+	echo
+	echo "    Implemented targets:"
+	echo
+	echo "    build        build pypmc for python2 and python3"
+	echo "    buildX       build pypmc for pythonX only where X is one of {2,3}"
+	echo "    build-sdist  build pypmc from the dist directory (python 2 and 3)"
+	echo "    build-sdistX build pypmc from the dist directory (pythonX, X in {2,3})"
+	echo "    check        use nosetests to test pypmc with python 2.7 and 3"
+	echo "    checkX       use nosetests to test pypmc with python 2.7 or 3,"
+	echo "                 where X is one of {2,3}"
+	echo "    check-fast   use nosetests to run only quick tests of pypmc"
+	echo "                 using nosetests-2.7 and nosetests3"
+	echo "    check-sdist  use nosetests-2.7 and nosetests3 to test the distribution"
+	echo "                 generated by 'make sdist'"
+	echo "    check-sdistX use nosetests-2.7 or nosetests3 to test the distribution"
+	echo "                 generated by 'make sdist', where X is one of {2,3}"
+	echo "    clean        delete compiled and temporary files"
+	echo "    coverage     produce and show a code coverage report"
+	echo "                 Note: Cython modules cannot be analyzed"
+	echo "    distcheck    runs 'check', check-sdist', 'run-examples' and"
+	echo "                 opens a browser with the built documentation"
+	echo "    doc          build the html documentation using sphinx"
+	echo "    doc-pdf      build the pdf documentation using sphinx"
+	echo "    help         show this message"
+	echo "    run-examples run all examples using python 2 and 3"
+	echo "    sdist        make a source distribution"
+	echo "    show-todos   show todo marks in the source code"
+	echo
+
+.PHONY : clean
+clean:
+	#remove build doc
+	rm -rf ./doc/_build
+
+	#remove .pyc files created by python 2.7
+	rm -f ./*.pyc
+	find -P . -name '*.pyc' -delete
+
+	#remove .pyc files crated by python 3
+	rm -rf ./__pycache__
+	find -P . -name __pycache__ -delete
+
+	#remove build folder in root directory
+	rm -rf ./build
+
+	#remove cythonized C source and object files
+	find -P . -name '*.c' -delete
+
+	#remove variational binaries only if command line argument specified
+	find -P . -name '*.so' -delete
+
+	#remove backup files
+	find -P . -name '*~' -delete
+
+	#remove files created by coverage
+	rm -f .coverage
+	rm -rf coverage
+
+	# remove egg info
+	rm -rf pypmc.egg-info
+
+	# remove downloaded seutptools
+	rm -f setuptools-3.3.zip
+
+	# remove dist/
+	rm -rf dist
+
+.PHONY : build
+build : build2
+
+.PHONY : build2
+build2 :
+	python2 setup.py build_ext --inplace
+
+.PHONY :
+check : check2
+
+.PHONY : check2
+check2 : build2
+	@ # run tests
+	nosetests-2.7 --processes=-1 --process-timeout=60
+
+	# run tests in parallel
+	mpirun -n 2 nosetests-2.7
+
+.PHONY : check-fast
+check-fast : build
+	nosetests-2.7 -a '!slow' --processes=-1 --process-timeout=60
+	nosetests3    -a '!slow' --processes=-1 --process-timeout=60
+
+.PHONY : .build-system-default
+.build-system-default :
+	python setup.py build_ext --inplace
+
+.PHONY : doc
+doc : .build-system-default
+	cd doc && make html
+
+.PHONY : doc-pdf
+doc-pdf : .build-system-default
+	cd doc; make latexpdf
+
+.PHONY : run-examples
+run-examples : build
+	cd examples ; \
+	for file in $$(ls) ; do \
+	    echo running $${file} with python2 && \
+	    python2 $${file} && \
+	    echo running $${file} with python3 && \
+	    python3 $${file} && \
+	    \
+	    # execute with mpirun if mpi4py appears in the file \
+	    if grep -Fq 'mpi4py' $${file} ; then \
+		echo "$${file}" is mpi parallelized && \
+		echo running $${file} in parallel with python2 && \
+		mpirun -n 2 python2 $${file} && \
+		echo running $${file} in parallel with python3 && \
+		mpirun -n 2 python3 $${file} ; \
+	    fi \
+	; \
+	done
+
+.PHONY : sdist
+sdist :
+	python setup.py sdist
+
+.PHONY : build-sdist
+build-sdist : build-sdist2 build-sdist3
+
+./dist/pypmc*/NUL : sdist
+	cd dist && tar xaf *.tar.gz && cd *
+
+.PHONY : build-sdist2
+build-sdist2 : ./dist/pypmc*/NUL
+	cd dist/pypmc* && python2 setup.py build
+
+.PHONY : build-sdist3
+build-sdist3 : ./dist/pypmc*/NUL
+	cd dist/pypmc* && python3 setup.py build
+
+.PHONY : check-sdist
+check-sdist : check-sdist2 check-sdist3
+
+.PHONY : check-sdist2
+check-sdist2 : build-sdist2
+	cd dist/*/build/lib*2.7 && \
+	nosetests-2.7 --processes=-1 --process-timeout=60 && \
+	mpirun -n 2 nosetests-2.7
+
+.PHONY : check-sdist3
+check-sdist3 : build-sdist3
+	cd dist/*/build/lib*3.* && \
+	nosetests3 --processes=-1 --process-timeout=60 && \
+	mpirun -n 2 nosetests3
+
+.PHONY : distcheck
+distcheck : check check-sdist doc
+	@ # execute "run-examples" after all other recipes makes are done
+	make run-examples
+	xdg-open link_to_documentation
+
+.PHONY : show-todos
+grep_cmd = ack-grep -i --no-html --no-cc [^"au""sphinx.ext."]todo
+show-todos :
+	@ # suppress errors here
+	@ # note that no todo found is considered as error
+	$(grep_cmd) doc ; \
+	$(grep_cmd) pypmc ; \
+	$(grep_cmd) examples ; echo \
+
+.PHONY : coverage
+coverage : .build-system-default
+	rm -rf coverage
+	nosetests --with-coverage --cover-package=nifty --cover-html --cover-html-dir=coverage
+	xdg-open coverage/index.html
diff --git a/mpi_dummy.py b/mpi_dummy.py
new file mode 100644
index 000000000..063a39631
--- /dev/null
+++ b/mpi_dummy.py
@@ -0,0 +1,116 @@
+# -*- coding: utf-8 -*-
+
+import numpy as np
+
+def MIN():
+    return np.min
+    
+def MAX():
+    return np.max
+    
+def SUM():
+    return np.sum    
+
+
+
+class _COMM_WORLD():
+    def __init__(self):
+        self.rank = 0
+        self.size = 1
+    
+    def Get_rank(self):
+        return self.rank
+    
+    def Get_size(self):
+        return self.size
+    
+    def _scattergather_helper(self, sendbuf, recvbuf=None):
+        if recvbuf != None:        
+            recvbuf[:] = sendbuf
+            return recvbuf
+        else:
+            recvbuf = np.copy(sendbuf)
+            return recvbuf
+    
+    def bcast(self, sendbuf, *args, **kwargs):
+        return sendbuf
+    
+    def Bcast(self, sendbuf, *args, **kwargs):
+        return sendbuf
+    
+    def scatter(self, *args, **kwargs):
+        return self._scattergather_helper(*args, **kwargs)
+    
+    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, *args, **kwargs):
+        return self._scattergather_helper(*args, **kwargs)
+
+    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, *args, **kwargs):
+        return self._scattergather_helper(*args, **kwargs)
+    
+    def Allgatherv(self, *args, **kwargs):
+        return self._scattergather_helper(*args, **kwargs)
+    
+    def Allreduce(self, sendbuf, recvbuf, op, **kwargs):
+        recvbuf[None] = op(sendbuf)
+        return recvbuf
+        
+    def allreduce(self, sendbuf, recvbuf, op, **kwargs):
+        recvbuf[None] = op(sendbuf)
+        return recvbuf
+    
+    def _unwrapper(self, x):
+        if isinstance(x, list):
+            return x[0]
+        else:
+            return x
+        
+
+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")
+LONG = _datatype("MPI_LONG")
+UNSIGNED_LONG = _datatype("MPI_UNSIGNED_LONG")
+LONG_LONG = _datatype("MPI_LONG_LONG")
+UNSIGNED_LONG_LONG = _datatype("MPI_UNSIGNED_LONG_LONG")
+FLOAT = _datatype("MPI_FLOAT")
+DOUBLE = _datatype("MPI_DOUBLE")
+LONG_DOUBLE = _datatype("MPI_LONG_DOUBLE")
+COMPLEX = _datatype("MPI_COMPLEX")
+DOUBLE_COMPLEX = _datatype("MPI_DOUBLE_COMPLEX")
+
+        
+COMM_WORLD = _COMM_WORLD()
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
\ No newline at end of file
diff --git a/nifty_paradict.py b/nifty_paradict.py
new file mode 100644
index 000000000..70481339a
--- /dev/null
+++ b/nifty_paradict.py
@@ -0,0 +1,327 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Thu Apr  2 21:29:30 2015
+
+@author: steininger
+"""
+
+import numpy as np
+from nifty import *
+#from nifty import about
+
+def paradict_getter(space_instance):
+    paradict_dictionary = {
+        str(space().__class__) : _space_paradict,
+        str(point_space((2)).__class__) : _point_space_paradict,           
+        str(rg_space((2)).__class__) : _rg_space_paradict,
+        str(nested_space([point_space(2), point_space(2)]).__class__) : _nested_space_paradict,
+        str(lm_space(1).__class__) : _lm_space_paradict,
+        str(gl_space(2).__class__) : _gl_space_paradict,
+        str(hp_space(1).__class__) : _hp_space_paradict,
+    }
+    return paradict_dictionary[str(space_instance.__class__)]()
+
+
+class _space_paradict(object):
+    def __init__(self, **kwargs):
+        self.parameters = {}
+        for key in kwargs:
+            self[key] = kwargs[key]
+            
+    def __setitem__(self, key, arg):
+        self.parameters.__setitem__(key, arg)
+    
+    def __getitem__(self, key):
+        return self.parameters.__getitem__(key)        
+      
+
+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"))
+        temp = np.array(arg, dtype=int).flatten()[0]
+        self.parameters.__setitem__(key, temp)
+    
+      
+class _rg_space_paradict(_space_paradict):
+    def __init__(self, num, hermitian=False, zerocenter=False):
+        self.ndim = len(np.array(num).flatten())        
+        _space_paradict.__init__(self, num=num, hermitian=hermitian, zerocenter=zerocenter)
+        
+    def __setitem__(self, key, arg):
+        if key not in ['num', 'hermitian', 'zerocenter']:
+            raise ValueError(about._errors.cstring("ERROR: Unsupported rg_space parameter"))
+        
+        if key == 'num':
+            temp = list(np.array(arg, dtype=int).flatten())
+            if len(temp) != self.ndim:
+                raise ValueError(about._errors.cstring("ERROR: Number of dimensions does not match the init value."))
+        elif key == 'hermitian':
+            temp = int(arg)
+        elif key == 'zerocenter':
+            temp = np.empty(self.ndim, dtype=bool)
+            temp[:] = arg
+            temp = list(temp)
+            #if len(temp) != self.ndim:
+            #    raise ValueError(about._errors.cstring("ERROR: Number of dimensions does not match the init value."))            
+        self.parameters.__setitem__(key, temp)
+        
+class _nested_space_paradict(_space_paradict):
+    def __init__(self, ndim):
+        self.ndim = np.int(ndim)
+        _space_paradict.__init__(self)
+    def __setitem__(self, key, arg):
+        if not isinstance(key, int):
+            raise ValueError(about._errors.cstring("ERROR: Unsupported point_space parameter"))
+        if key >= self.ndim or key < 0:
+            raise ValueError(about._errors.cstring("ERROR: Nestindex out of bounds"))
+        temp = list(np.array(arg, dtype=int).flatten())   
+        self.parameters.__setitem__(key, temp)
+    
+    
+class _lm_space_paradict(_space_paradict):
+    def __init__(self, lmax, mmax=None):
+        _space_paradict.__init__(self, lmax=lmax)
+        if mmax == None:        
+           mmax = -1 
+        self['mmax'] = mmax      
+        
+    def __setitem__(self, key, arg):
+        if key not in ['lmax', 'mmax']:
+            raise ValueError(about._errors.cstring("ERROR: Unsupported rg_space parameter"))
+
+        if key == 'lmax':
+            temp = int(arg)
+            if(temp<1):
+                raise ValueError(about._errors.cstring("ERROR: lmax: nonpositive number."))
+            if (temp%2 == 0) and (temp > 2): ## exception lmax == 2 (nside == 1)
+                about.warnings.cprint("WARNING: unrecommended parameter (lmax <> 2*n+1).")
+            try:
+                if temp < self['mmax']:
+                    about.warnings.cprint("WARNING: mmax parameter set to lmax.")
+                    self['mmax'] = temp
+                if (temp != self['mmax']):
+                    about.warnings.cprint("WARNING: unrecommended parameter set (mmax <> lmax).")
+            except:
+                pass
+        elif key == 'mmax':
+            temp = int(arg)            
+            if (temp < 1) or(temp > self['lmax']):
+                about.warnings.cprint("WARNING: mmax parameter set to default.")
+                temp = self['lmax']            
+            if(temp != self['lmax']):
+                about.warnings.cprint("WARNING: unrecommended parameter set (mmax <> lmax).")
+          
+        self.parameters.__setitem__(key, temp)
+
+class _gl_space_paradict(_space_paradict):
+    def __init__(self, nlat, nlon=None):
+        _space_paradict.__init__(self, nlat=nlat)
+        if nlon == None:        
+           nlon = -1
+        self['nlon'] = nlon
+        
+    def __setitem__(self, key, arg):
+        if key not in ['nlat', 'nlon']:
+            raise ValueError(about._errors.cstring("ERROR: Unsupported rg_space parameter"))
+
+        if key == 'nlat':
+            temp = int(arg)
+            if(temp<1):
+                raise ValueError(about._errors.cstring("ERROR: nlat: nonpositive number."))
+            if (temp%2 != 0):
+                raise ValueError(about._errors.cstring("ERROR: invalid parameter (nlat <> 2n)."))
+            try:
+                if temp < self['mmax']:
+                    about.warnings.cprint("WARNING: mmax parameter set to lmax.")
+                    self['mmax'] = temp
+                if (temp != self['mmax']):
+                    about.warnings.cprint("WARNING: unrecommended parameter set (mmax <> lmax).")
+            except:
+                pass
+        elif key == 'nlon':
+            temp = int(arg)            
+            if (temp < 1):
+                about.warnings.cprint("WARNING: nlon parameter set to default.")
+                temp = 2*self['nlat']-1
+            if(temp != 2*self['nlat']-1):
+                about.warnings.cprint("WARNING: unrecommended parameter set (nlon <> 2*nlat-1).")
+        self.parameters.__setitem__(key, temp)
+
+
+        
+class _hp_space_paradict(_space_paradict):
+    def __init__(self, nside):
+        _space_paradict.__init__(self, nside=nside)
+    def __setitem__(self, key, arg):
+        if key not in ['nside']:
+            raise ValueError(about._errors.cstring("ERROR: Unsupported hp_space parameter"))        
+        
+        temp = int(arg)
+        #if(not hp.isnsideok(nside)):
+        if ((temp & (temp-1)) != 0) or (temp < 2):
+            raise ValueError(about._errors.cstring("ERROR: invalid parameter ( nside <> 2**n )."))
+        self.parameters.__setitem__(key, temp)        
+
+##################
+
+
+class _space(object):
+    def __init__(self):
+        self.paradict = _space_paradict(default=123)        
+        #self.para = [1,2,3]
+        
+    @property
+    def para(self):
+        return self.paradict['default']
+        #return self.distributed_val
+    
+    @para.setter
+    def para(self, x):
+        self.paradict['default'] = x
+
+##################
+##################
+        
+
+    
+class _point_space(object):
+    def __init__(self):
+        self.paradict = _point_space_paradict()        
+        self.para = [10]
+        
+    @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
+
+##################
+##################
+        
+
+class _rg_space(object):
+    def __init__(self):
+        self.paradict = _rg_space_paradict(num=[10,100,200])        
+        
+    @property
+    def para(self):
+        temp = np.array(self.paradict['num'] + \
+                         [self.paradict['hermitian']] + \
+                         self.paradict['zerocenter'], dtype=int)
+        return temp
+        
+    
+    @para.setter
+    def para(self, x):
+        self.paradict['num'] = x[:(np.size(x)-1)//2]
+        self.paradict['zerocenter'] = x[(np.size(x)+1)//2:]
+        self.paradict['hermitian'] = x[(np.size(x)-1)//2]
+        
+##################
+##################
+        
+class _nested_space(object):
+    def __init__(self):
+        self.paradict = _nested_space_paradict(ndim=10)
+        for i in range(10):
+            self.paradict[i] = [1+i, 2+i, 3+i]
+        
+    @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
+                
+##################
+##################
+
+class _lm_space(object):
+    def __init__(self):
+        self.paradict = _lm_space_paradict(lmax = 10)        
+        
+    @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]
+    
+        
+##################
+##################
+
+class _gl_space(object):
+    def __init__(self):
+        self.paradict = _gl_space_paradict(nlat = 10)        
+        
+    @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]
+    
+        
+##################
+##################
+
+
+class _hp_space(object):
+    def __init__(self):
+        self.paradict = _hp_space_paradict(nside=16)        
+        
+    @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]
+        
+    
+        
+##################
+##################
+
+
+        
+if __name__ == '__main__':
+    myspace = _space()
+    print myspace.para
+    print myspace.paradict.parameters.items()
+    myspace.para = [4,5,6]
+    print myspace.para
+    print myspace.paradict.parameters.items()
+    
+    myspace.paradict.parameters['default'] = [1,4,7] 
+    print myspace.para
+    print myspace.paradict.parameters.items()
+    
\ No newline at end of file
-- 
GitLab