source: codes/icosagcm/devel/Python/dev/wrap.py @ 985

Last change on this file since 985 was 825, checked in by dubos, 5 years ago

devel/Python : moved Fortran bindings and *.pyx to dynamico/dev module + necessary changes to test/py/*.py

File size: 2.9 KB
Line 
1#------------------- wrap C/Fortran routines -------------------#                                                                                           
2from dynamico import getargs
3log_master, log_world = getargs.getLogger(__name__)
4INFO, DEBUG, ERROR = log_master.info, log_master.debug, log_world.error
5INFO_ALL, DEBUG_ALL = log_world.info, log_world.debug
6
7
8import numpy as np 
9from ctypes import *
10
11class Struct: pass
12
13# converts numpy array to void * for calling C/Fortran routines                                                                                             
14def loc(array): return array.ctypes.data_as(c_void_p)
15
16# defines converter functions depending on type of Python argument
17def noop(x): return x
18py2c = { np.ndarray:loc, np.float64:c_double, np.float32:c_float, int:c_int, 
19         c_void_p:noop, str:noop, c_int:noop }
20
21class Wrap:
22    def __init__(self, fun, check_args, argtypes):
23        fun.restype=None
24        if check_args:
25            fun.argtypes=argtypes
26        self.fun=fun
27        self.convert=None
28    def __call__(self, *args):
29        if self.convert is None:
30            self.convert=[ py2c[type(arg)] for arg in args]
31        args = [ conv(arg) for conv,arg in zip(self.convert,args) ]
32        return self.fun(*args)
33
34def typelist(argtypes):
35    lst=[]
36    for x in argtypes:
37        if type(x) is int:
38            lst+=(x-1)*[prev] # x-1 because prev has already been appended once                                                             
39        else:
40            lst.append(x)
41        prev=x
42    return lst
43
44class SharedLib:
45    def __init__(self,vardict,lib,check_args=True, prefix_so='',prefix_py=''):
46        self.vardict, self.check_args = vardict, check_args
47        self.prefix_so, self.prefix_py = prefix_so, prefix_py
48        self.lib=lib
49        self.vars={}
50    def import_funs(self,prototypes,prefix=''):
51        for proto in prototypes:
52            names=[]
53            while type(proto[0]) is str:
54                names.append(proto.pop(0))
55            if proto[0] is None:
56                proto=None
57            else:
58                proto = typelist(proto)
59            for name in names:
60                name = prefix+name
61                soname = self.prefix_so+name
62                DEBUG('wrap.Sharedlib : importing %s' % soname)
63                self.vardict[self.prefix_py+name] = Wrap(self.lib[soname], self.check_args, proto)
64    def addvars(self,*types_and_names):
65        for x in types_and_names:
66            if type(x) is str:
67                self.vars[x]=ctype.in_dll(self.lib, x.lower())
68            else:
69                ctype = x
70    def getvar(self,name):
71        return self.vars[name].value
72    def getvars(self,*names):
73        return [self.vars[name].value for name in names]
74    def setvar(self,name,val):
75        self.vars[name].value=val
76    def setvars(self,names,vals):
77        for name,val in zip(names,vals):
78            self.vars[name].value=val
Note: See TracBrowser for help on using the repository browser.