~fluidity-core/fluidity/adjoint

« back to all changes in this revision

Viewing changes to libspud/python/libspud.py.ctypes

Merge the fluidity_revolve branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
 
 
3
# A draft python binding for libspud
 
4
# You will need to compile _libspud.so
 
5
# by hand for now -- haven't hooked it up
 
6
# to the Makefile
 
7
 
 
8
from ctypes import *
 
9
import os
 
10
 
 
11
SPUD_REAL      = 0
 
12
SPUD_INTEGER   = 1
 
13
SPUD_NONE      = 2
 
14
SPUD_CHARACTER = 3
 
15
pytype_map = {SPUD_REAL: float, SPUD_INTEGER: int, SPUD_NONE: None, SPUD_CHARACTER: str}
 
16
typepy_map = {float: SPUD_REAL, int: SPUD_INTEGER, None: SPUD_NONE, str: SPUD_CHARACTER}
 
17
ctype_map  = {float: c_double, int: c_int, None: None, str: c_char_p}
 
18
 
 
19
SPUD_NO_ERROR                = 0
 
20
SPUD_KEY_ERROR               = 1
 
21
SPUD_TYPE_ERROR              = 2
 
22
SPUD_RANK_ERROR              = 3
 
23
SPUD_SHAPE_ERROR             = 4
 
24
SPUD_NEW_KEY_WARNING         = -1
 
25
SPUD_ATTR_SET_FAILED_WARNING = -2
 
26
 
 
27
OPTION_PATH_LEN = 8192
 
28
 
 
29
class SpudKeyError(Exception):
 
30
  def __init__(self, msg = "The specified option is not present in the dictionary."):
 
31
    self.message = msg
 
32
 
 
33
class SpudTypeError(Exception):
 
34
  def __init__(self, msg = "The specified option has a different type from that of the option argument provided."):
 
35
    self.message = msg
 
36
 
 
37
class SpudRankError(Exception):
 
38
  def __init__(self, msg = "The specified option has a different rank from that of the option argument provided."):
 
39
    self.message = msg
 
40
 
 
41
class SpudShapeError(Exception):
 
42
  def __init__(self, msg = "The specified option has a different shape from that of the option argument provided."):
 
43
    self.message = msg
 
44
 
 
45
class SpudNewKeyWarning(Exception):
 
46
  def __init__(self, msg = "The option being inserted is not already in the dictionary."):
 
47
    self.message = msg
 
48
  
 
49
class SpudAttrSetFailedWarning(Exception):
 
50
  def __init__(self, msg = "The option being set as an attribute can not be set as an attribute."):
 
51
    self.message = msg
 
52
  
 
53
spud_exceptions = {SPUD_KEY_ERROR: SpudKeyError,
 
54
                   SPUD_TYPE_ERROR: SpudTypeError,
 
55
                   SPUD_RANK_ERROR: SpudRankError,
 
56
                   SPUD_SHAPE_ERROR: SpudShapeError,
 
57
                   SPUD_NEW_KEY_WARNING: SpudNewKeyWarning,
 
58
                   SPUD_ATTR_SET_FAILED_WARNING: SpudAttrSetFailedWarning}
 
59
 
 
60
libspud = cdll.LoadLibrary('@prefix@'  + '/lib/libspud.so')
 
61
 
 
62
cclear_options = libspud.spud_clear_options
 
63
cclear_options.argtypes = []
 
64
cclear_options.restype = None
 
65
 
 
66
def clear_options():
 
67
  cclear_options()
 
68
 
 
69
cload_options = libspud.spud_load_options
 
70
cload_options.argtypes = [c_char_p, c_int]
 
71
cload_options.restype = c_int
 
72
 
 
73
def load_options(s):
 
74
  out = cload_options(s, c_int(len(s)))
 
75
  if out != SPUD_NO_ERROR:
 
76
    raise spud_exceptions[out]
 
77
 
 
78
cwrite_options = libspud.spud_write_options
 
79
cwrite_options.argtypes = [c_char_p, c_int]
 
80
cwrite_options.restype = c_int
 
81
 
 
82
def write_options(filename):
 
83
  out = cwrite_options(filename, c_int(len(filename)))
 
84
  if out != SPUD_NO_ERROR:
 
85
    raise spud_exceptions[out]
 
86
 
 
87
cget_child_name = libspud.spud_get_child_name
 
88
cget_child_name.argtypes = [c_char_p, c_int, c_int, c_char_p, c_int]
 
89
cget_child_name.restype = c_int
 
90
 
 
91
def get_child_name(s, idx):
 
92
  val = create_string_buffer(OPTION_PATH_LEN)
 
93
  out = cget_child_name(s, c_int(len(s)), c_int(idx), val, c_int(len(val)))
 
94
  
 
95
  if out != SPUD_NO_ERROR:
 
96
    raise spud_exceptions[out]
 
97
    
 
98
  return val.value.strip()
 
99
  
 
100
cget_number_of_children = libspud.spud_get_number_of_children
 
101
cget_number_of_children.argtypes = [c_char_p, c_int, POINTER(c_int)]
 
102
cget_number_of_children.restype = c_int
 
103
 
 
104
def get_number_of_children(s):
 
105
  val = c_int()
 
106
  out = cget_number_of_children(s, c_int(len(s)), byref(val))
 
107
  
 
108
  if out != SPUD_NO_ERROR:
 
109
    raise spud_exceptions[out]
 
110
  
 
111
  return val.value
 
112
    
 
113
coption_count = libspud.spud_option_count
 
114
coption_count.argtypes = [c_char_p, c_int]
 
115
coption_count.restype = c_int
 
116
 
 
117
def option_count(s):
 
118
  return coption_count(s, c_int(len(s)))
 
119
   
 
120
chave_option = libspud.spud_have_option
 
121
chave_option.argtypes = [c_char_p, c_int]
 
122
chave_option.restype = c_int
 
123
 
 
124
def have_option(s):
 
125
  out = chave_option(s, c_int(len(s)))
 
126
  
 
127
  if out == 1:
 
128
    return True
 
129
  else:
 
130
    return False
 
131
 
 
132
cget_option_type = libspud.spud_get_option_type
 
133
cget_option_type.argtypes = [c_char_p, c_int, POINTER(c_int)]
 
134
cget_option_type.restype = c_int
 
135
 
 
136
def get_option_type(s):
 
137
  val = c_int()
 
138
  out = cget_option_type(s, c_int(len(s)), byref(val))
 
139
 
 
140
  if out != SPUD_NO_ERROR:
 
141
    raise spud_exceptions[out]
 
142
 
 
143
  return pytype_map[val.value]
 
144
  
 
145
cget_option_rank = libspud.spud_get_option_rank
 
146
cget_option_rank.argtypes = [c_char_p, c_int, POINTER(c_int)]
 
147
cget_option_rank.restype = c_int
 
148
 
 
149
def get_option_rank(s):
 
150
  rank = c_int()
 
151
  out = cget_option_rank(s, c_int(len(s)), byref(rank))
 
152
  if out != SPUD_NO_ERROR:
 
153
    raise spud_exceptions[out]
 
154
  return rank.value
 
155
  
 
156
cget_option_shape = libspud.spud_get_option_shape
 
157
cget_option_shape.argtypes = [c_char_p, c_int, POINTER(c_int)]
 
158
cget_option_shape.restype = int
 
159
 
 
160
def get_option_shape(s):
 
161
  shape_type = c_int * 2
 
162
  shape = shape_type()
 
163
  out = cget_option_shape(s, c_int(len(s)), shape)
 
164
 
 
165
  if out != SPUD_NO_ERROR:
 
166
    raise spud_exceptions[out]
 
167
 
 
168
  return tuple(shape)
 
169
 
 
170
cget_option = libspud.spud_get_option
 
171
cget_option.argtypes = [c_char_p, c_int, c_void_p]
 
172
cget_option.restype = c_int
 
173
 
 
174
def get_option(s):
 
175
  type = get_option_type(s)
 
176
  rank=0
 
177
  if type is str:
 
178
    strlen = get_option_shape(s)[0]
 
179
    val = create_string_buffer(strlen+1)
 
180
  elif type is None:
 
181
    raise spud_exceptions[SPUD_TYPE_ERROR]("No value exists at the given path")
 
182
  else:
 
183
    val_type = ctype_map[type]
 
184
    rank = get_option_rank(s)
 
185
    shape = get_option_shape(s)
 
186
    # reverse the numbering so we get a rowxcolumn list of lists
 
187
    for i in range(rank-1, -1, -1): val_type = val_type*shape[i]
 
188
    val = val_type()
 
189
 
 
190
  out = cget_option(s, c_int(len(s)), byref(val))
 
191
  if out != SPUD_NO_ERROR:
 
192
    raise spud_exceptions[out]
 
193
 
 
194
  if rank==2:
 
195
    val_out = [[val[i][j] for j in range(shape[1])] for i in range(shape[0])]
 
196
  elif rank==1:
 
197
    val_out = [val[i] for i in range(shape[0])]
 
198
  else:
 
199
    val_out = val.value
 
200
  return val_out
 
201
 
 
202
cadd_option = libspud.spud_add_option
 
203
cadd_option.argtypes = [c_char_p, c_int]
 
204
cadd_option.restype = c_int
 
205
 
 
206
def add_option(s):
 
207
  out = cadd_option(s, c_int(len(s)))
 
208
 
 
209
  if out != SPUD_NO_ERROR:
 
210
    raise spud_exceptions[out]
 
211
 
 
212
  return
 
213
 
 
214
cset_option = libspud.spud_set_option
 
215
cset_option.argtypes = [c_char_p, c_int, c_void_p, c_int, c_int, POINTER(c_int)]
 
216
cset_option.restype = c_int
 
217
 
 
218
def set_option(s, val):
 
219
  rank = 0
 
220
  shape_type = c_int * 2
 
221
  shape = shape_type(1, -1)
 
222
  py_type = type(val)
 
223
  if py_type not in typepy_map:
 
224
    if py_type == list:
 
225
      subval = val
 
226
      for i in range(2):
 
227
        if type(subval) == list:
 
228
          shape[i] = len(subval)
 
229
          rank += 1
 
230
          subval = subval[0]
 
231
        else:
 
232
          break 
 
233
      py_type = type(subval)
 
234
    # elif ...
 
235
      # could put numpy array handling in here 
 
236
      # (they'd be easier but didn't want to
 
237
      #  add a numpy dependency)
 
238
    else:
 
239
      raise spud_exceptions[SPUD_TYPE_ERROR]("Unknown value type.  Only know about floats, ints, strings and lists thereof.")
 
240
  spud_code = typepy_map[py_type]
 
241
  c_type = ctype_map[py_type]
 
242
  # reverse the order of the shape entries as that way we end up with a rows x columns c_type
 
243
  for i in range(rank-1, -1, -1): c_type = c_type*shape[i]
 
244
  if rank == 2:
 
245
    c_val = c_type()
 
246
    for i in range(shape[0]):
 
247
      for j in range(shape[1]):
 
248
        c_val[i][j] = val[i][j]
 
249
  elif rank == 1:
 
250
    c_val = c_type()
 
251
    for i in range(shape[0]):
 
252
      c_val[i] = val[i]
 
253
  else:
 
254
    c_val = c_type(val)
 
255
 
 
256
  if py_type is str:
 
257
    shape = shape_type(len(val), -1)
 
258
    rank = 1
 
259
    out = cset_option(s, c_int(len(s)), (c_val), c_int(spud_code), c_int(rank), shape)
 
260
  else:
 
261
    out = cset_option(s, c_int(len(s)), byref(c_val), c_int(spud_code), c_int(rank), shape)
 
262
 
 
263
  if out != SPUD_NO_ERROR:
 
264
    raise spud_exceptions[out]
 
265
    
 
266
cset_option_attribute = libspud.spud_set_option_attribute
 
267
cset_option_attribute.argtypes = [c_char_p, c_int, c_char_p, c_int]
 
268
cset_option_attribute.restype = c_int
 
269
 
 
270
def set_option_attribute(s, val):
 
271
  out = cset_option_attribute(s, c_int(len(s)), val, c_int(len(val)))
 
272
  
 
273
  if out != SPUD_NO_ERROR:
 
274
    raise spud_exceptions[out]
 
275
 
 
276
  return
 
277
  
 
278
cdelete_option = libspud.spud_delete_option
 
279
cdelete_option.argtypes = [c_char_p, c_int]
 
280
cdelete_option.restype = c_int
 
281
 
 
282
def delete_option(s):
 
283
  out = cdelete_option(s, c_int(len(s)))
 
284
  
 
285
  if out != SPUD_NO_ERROR:
 
286
    raise spud_exceptions[out]
 
287
 
 
288
  return
 
289
 
 
290
cmove_option = libspud.spud_move_option
 
291
cmove_option.argtypes = [c_char_p, c_int, c_char_p, c_int]
 
292
cmove_option.restype = c_int
 
293
 
 
294
def move_option(s1, s2):
 
295
  out = cmove_option(s1, c_int(len(s1)), s2, c_int(len(s2)))
 
296
  
 
297
  if out != SPUD_NO_ERROR:
 
298
    raise spud_exceptions[out]
 
299
 
 
300
  return
 
301
 
 
302
cprint_options = libspud.spud_print_options
 
303
cprint_options.restype = None
 
304
cprint_options.argtypes = []
 
305
 
 
306
def print_options():
 
307
  cprint_options()