11from ctypes import *
22import platform
33import array
4+ import os
45
56def debug_print (arg ):
67 pass
@@ -96,18 +97,18 @@ def get_transpose(x):
9697 else :
9798 return UMFPACK_A
9899
99- def get_dll_naming ():
100+ def _get_dll_naming ():
100101 systems = {
101102 'Linux' : {"prefix" : "lib" , "suffix" : ".so" },
102103 'Darwin' : {"prefix" : "lib" , "suffix" : ".dylib" },
103104 'Windows' : {"prefix" : "" , "suffix" : ".dll" },
104105 }
105106 return systems [platform .system ()]
106107
107- def get_umfpack_name ():
108- return "./%(prefix)sumfpack_lgpl%(suffix)s" % get_dll_naming ()
108+ def _get_umfpack_name ():
109+ return "./%(prefix)sumfpack_lgpl%(suffix)s" % _get_dll_naming ()
109110
110- def load_umfpack_dll (dllname ):
111+ def _load_umfpack_dll (dllname ):
111112 dll = cdll .LoadLibrary (dllname )
112113 if not dll :
113114 raise RuntimeError ("Cannot find UMFPACK dll" )
@@ -119,7 +120,7 @@ def get_blas_name():
119120 else :
120121 return "%(prefix)sopenblas%(suffix)s" % get_dll_naming ()
121122
122- def load_blas_dll (gdata , blaslib = None , noexcept = False ):
123+ def _load_blas_dll (gdata , blaslib = None , noexcept = False ):
123124 #print(dll.blasw_load_dll)
124125 if blaslib :
125126 dllname = blaslib
@@ -145,7 +146,7 @@ def load_blas_dll(gdata, blaslib = None, noexcept = False):
145146 #print(h)
146147 return h
147148
148- def load_blas_functions (gdata , h ):
149+ def _load_blas_functions (gdata , h ):
149150 gdata .dll .blasw_load_functions .restype = c_int
150151 gdata .dll .blasw_load_functions .argtypes = [c_void_p ]
151152 i = gdata .dll .blasw_load_functions (h ._handle )
@@ -176,27 +177,27 @@ def __del__(self):
176177 if self .umf_control .is_complex :
177178 if self .Symbolic :
178179 debug_print ('umfpack_zi_free_symbolic 176' )
179- self . umf_control . gdata . dll .umfpack_zi_free_symbolic (byref (self .Symbolic ))
180+ umf_dll .umfpack_zi_free_symbolic (byref (self .Symbolic ))
180181 else :
181182 if self .Symbolic :
182183 debug_print ('umfpack_di_free_symbolic 180' )
183- self . umf_control . gdata . dll .umfpack_di_free_symbolic (byref (self .Symbolic ))
184+ umf_dll .umfpack_di_free_symbolic (byref (self .Symbolic ))
184185 self .umf_control = None
185186
186187 def factor_symbolic (self , matrix ):
187188 if self .umf_control .is_complex :
188189 if self .Symbolic :
189190 debug_print ('umfpack_zi_free_symbolic 187' )
190- self . umf_control . gdata . dll .umfpack_zi_free_symbolic (byref (self .Symbolic ))
191+ umf_dll .umfpack_zi_free_symbolic (byref (self .Symbolic ))
191192 NULL = c_void_p ()
192193 debug_print ('umfpack_zi_symbolic 190/u' )
193- self .status = self . umf_control . gdata . dll .umfpack_zi_symbolic (matrix .n , matrix .n , matrix .AP , matrix .AI , matrix .AX , NULL , byref (self .Symbolic ), self .umf_control .Control , self .umf_control .Info )
194+ self .status = umf_dll .umfpack_zi_symbolic (matrix .n , matrix .n , matrix .AP , matrix .AI , matrix .AX , NULL , byref (self .Symbolic ), self .umf_control .Control , self .umf_control .Info )
194195 else :
195196 if self .Symbolic :
196197 debug_print ('umfpack_di_free_symbolic 194' )
197- self . umf_control . gdata . dll .umfpack_di_free_symbolic (byref (self .Symbolic ))
198+ umf_dll .umfpack_di_free_symbolic (byref (self .Symbolic ))
198199 debug_print ('umfpack_di_symbolic 196' )
199- self .status = self . umf_control . gdata . dll .umfpack_di_symbolic (matrix .n , matrix .n , matrix .AP , matrix .AI , matrix .AX , byref (self .Symbolic ), self .umf_control .Control , self .umf_control .Info )
200+ self .status = umf_dll .umfpack_di_symbolic (matrix .n , matrix .n , matrix .AP , matrix .AI , matrix .AX , byref (self .Symbolic ), self .umf_control .Control , self .umf_control .Info )
200201 return self .status
201202
202203class di_numeric :
@@ -208,46 +209,46 @@ def __del__(self):
208209 if self .umf_control .is_complex :
209210 if self .Numeric :
210211 debug_print ('umfpack_zi_free_numeric 209' )
211- self . umf_control . gdata . dll .umfpack_zi_free_numeric (byref (self .Numeric ))
212+ umf_dll .umfpack_zi_free_numeric (byref (self .Numeric ))
212213 else :
213214 if self .Numeric :
214215 debug_print ('umfpack_di_free_numeric 213' )
215- self . umf_control . gdata . dll .umfpack_di_free_numeric (byref (self .Numeric ))
216+ umf_dll .umfpack_di_free_numeric (byref (self .Numeric ))
216217
217218 def factor_numeric (self , matrix , Symbolic ):
218219 if self .umf_control .is_complex :
219220 if self .Numeric :
220221 debug_print ('umfpack_zi_free_numeric 219' )
221- self . umf_control . gdata . dll .umfpack_zi_free_numeric (byref (self .Numeric ))
222+ umf_dll .umfpack_zi_free_numeric (byref (self .Numeric ))
222223 NULL = c_void_p ()
223224 debug_print ('umfpack_zi_numeric 222' )
224- self .status = self . umf_control . gdata . dll .umfpack_zi_numeric (matrix .AP , matrix .AI , matrix .AX , NULL , Symbolic .Symbolic , byref (self .Numeric ), self .umf_control .Control , self .umf_control .Info )
225+ self .status = umf_dll .umfpack_zi_numeric (matrix .AP , matrix .AI , matrix .AX , NULL , Symbolic .Symbolic , byref (self .Numeric ), self .umf_control .Control , self .umf_control .Info )
225226 else :
226227 if self .Numeric :
227228 debug_print ('umfpack_di_free_numeric 226' )
228- self . umf_control . gdata . dll .umfpack_di_free_numeric (byref (self .Numeric ))
229+ umf_dll .umfpack_di_free_numeric (byref (self .Numeric ))
229230 debug_print ('umfpack_di_numeric 228' )
230- self .status = self . umf_control . gdata . dll .umfpack_di_numeric (matrix .AP , matrix .AI , matrix .AX , Symbolic .Symbolic , byref (self .Numeric ), self .umf_control .Control , self .umf_control .Info )
231+ self .status = umf_dll .umfpack_di_numeric (matrix .AP , matrix .AI , matrix .AX , Symbolic .Symbolic , byref (self .Numeric ), self .umf_control .Control , self .umf_control .Info )
231232 return self .status
232233
233234 def solve (self , matrix , x , b , transpose ):
234235 X = c_void_p (x .buffer_info ()[0 ])
235236 B = c_void_p (b .buffer_info ()[0 ])
236237 if self .umf_control .is_complex :
237238 NULL = c_void_p ()
238- self .status = self . umf_control . gdata . dll .umfpack_zi_solve (get_transpose (transpose ), matrix .AP , matrix .AI , matrix .AX , NULL , X , NULL , B , NULL , self .Numeric , self .umf_control .Control , self .umf_control .Info )
239+ self .status = umf_dll .umfpack_zi_solve (get_transpose (transpose ), matrix .AP , matrix .AI , matrix .AX , NULL , X , NULL , B , NULL , self .Numeric , self .umf_control .Control , self .umf_control .Info )
239240 else :
240- self .status = self . umf_control . gdata . dll .umfpack_di_solve (get_transpose (transpose ), matrix .AP , matrix .AI , matrix .AX , X , B , self .Numeric , self .umf_control .Control , self .umf_control .Info )
241+ self .status = umf_dll .umfpack_di_solve (get_transpose (transpose ), matrix .AP , matrix .AI , matrix .AX , X , B , self .Numeric , self .umf_control .Control , self .umf_control .Info )
241242 return self .status
242243
243244 def determinant (self , x , r ):
244245 X = c_void_p (x .buffer_info ()[0 ])
245246 R = c_void_p (r .buffer_info ()[0 ])
246247 if self .umf_control .is_complex :
247248 NULL = c_void_p ()
248- self .status = self . umf_control . gdata . dll .umfpack_zi_get_determinant (X , NULL , R , NULL , self .Numeric , self .umf_control .Info )
249+ self .status = umf_dll .umfpack_zi_get_determinant (X , NULL , R , NULL , self .Numeric , self .umf_control .Info )
249250 else :
250- self .status = self . umf_control . gdata . dll .umfpack_di_get_determinant (X , R , self .Numeric , self .umf_control .Info )
251+ self .status = umf_dll .umfpack_di_get_determinant (X , R , self .Numeric , self .umf_control .Info )
251252 return self .status
252253
253254class di_triplet :
@@ -279,7 +280,7 @@ def __init__(self, uc, Ap, Ai, Ax):
279280 def __del__ (self ):
280281 pass
281282
282- class global_data :
283+ class _global_data :
283284 def __init__ (self ):
284285 self .printcb = None
285286 self .blaslibs = []
@@ -290,6 +291,22 @@ def __del__(self):
290291 self .blaslibs = None
291292 self .dll = None
292293
294+ def initialize_umfpack (self , math_libraries ):
295+ self .dll = _load_umfpack_dll (os .path .join (os .path .dirname (__file__ ), _get_umfpack_name ()))
296+ global umf_dll
297+ umf_dll = self .dll
298+ for b in math_libraries :
299+ h = _load_blas_dll (self , blaslib = b , noexcept = True )
300+ if h :
301+ mcount = _load_blas_functions (self , h )
302+ if mcount == 0 :
303+ break
304+ if mcount != 0 :
305+ raise RuntimeError ('Missing %d math functions' % mcount )
306+
307+ global_data_instance = _global_data ()
308+ umf_dll = None
309+
293310class umf_control :
294311 def __init__ (self , gdata , matrix_type ):
295312 self .timer = None
@@ -315,18 +332,18 @@ def __del__(self):
315332
316333 def tic (self ):
317334 self .timer = (c_double * 2 )()
318- self . gdata . dll .umfpack_tic (byref (self .timer ))
335+ umf_dll .umfpack_tic (byref (self .timer ))
319336
320337 def toc (self ):
321- self . gdata . dll .umfpack_toc (self .timer )
338+ umf_dll .umfpack_toc (self .timer )
322339 print ("\n umfpack complete.\n Total time: %5.2f seconds (CPU time), %5.2f seconds (wallclock time)\n " % ( self .timer [1 ], self .timer [0 ]))
323340
324341 def set_defaults (self ):
325342 self .Control = (c_double * UMFPACK_CONTROL )()
326343 if self .is_complex :
327- self . gdata . dll .umfpack_zi_defaults (self .Control )
344+ umf_dll .umfpack_zi_defaults (self .Control )
328345 else :
329- self . gdata . dll .umfpack_di_defaults (self .Control )
346+ umf_dll .umfpack_di_defaults (self .Control )
330347 self .Info = (c_double * UMFPACK_INFO )()
331348
332349 def init_verbose (self ):
@@ -335,37 +352,37 @@ def init_verbose(self):
335352 self .Control [UMFPACK_PRL ] = 6
336353 # /* print the license agreement */
337354 if self .is_complex :
338- self . gdata . dll .umfpack_zi_report_status (self .Control , UMFPACK_OK )
355+ umf_dll .umfpack_zi_report_status (self .Control , UMFPACK_OK )
339356 else :
340- self . gdata . dll .umfpack_di_report_status (self .Control , UMFPACK_OK )
357+ umf_dll .umfpack_di_report_status (self .Control , UMFPACK_OK )
341358 self .Control [UMFPACK_PRL ] = 5
342359 #
343360 # /* print the control parameters */
344361 if self .is_complex :
345- self . gdata . dll .umfpack_zi_report_control (self .Control )
362+ umf_dll .umfpack_zi_report_control (self .Control )
346363 else :
347- self . gdata . dll .umfpack_di_report_control (self .Control )
364+ umf_dll .umfpack_di_report_control (self .Control )
348365
349366 def print_vector (self , b , label ):
350367 # /* print the right-hand-side */
351368 print ("\n %s: " % (label ,), flush = True , end = "" )
352369 if self .is_complex :
353370 NULL = (c_void_p )()
354- self . gdata . dll .umfpack_zi_report_vector .argtypes = [c_int , c_void_p , c_void_p , c_void_p ]
355- self . gdata . dll .umfpack_zi_report_vector .restype = None
356- self . gdata . dll .umfpack_zi_report_vector (len (b )// 2 , b .buffer_info ()[0 ], NULL , self .Control )
371+ umf_dll .umfpack_zi_report_vector .argtypes = [c_int , c_void_p , c_void_p , c_void_p ]
372+ umf_dll .umfpack_zi_report_vector .restype = None
373+ umf_dll .umfpack_zi_report_vector (len (b )// 2 , b .buffer_info ()[0 ], NULL , self .Control )
357374 else :
358- self . gdata . dll .umfpack_di_report_vector .argtypes = [c_int , c_void_p , c_void_p ]
359- self . gdata . dll .umfpack_di_report_vector .restype = None
360- self . gdata . dll .umfpack_di_report_vector (len (b ), b .buffer_info ()[0 ], self .Control )
375+ umf_dll .umfpack_di_report_vector .argtypes = [c_int , c_void_p , c_void_p ]
376+ umf_dll .umfpack_di_report_vector .restype = None
377+ umf_dll .umfpack_di_report_vector (len (b ), b .buffer_info ()[0 ], self .Control )
361378
362379 def print_triplet (self , tm ):
363380 print ("\n A: " )
364381 if self .is_complex :
365382 NULL = (c_void_p )()
366- self . gdata . dll .umfpack_zi_report_triplet (tm .n , tm .n , tm .nz , tm .Ar , tm .Ac , tm .Av , NULL , self .Control )
383+ umf_dll .umfpack_zi_report_triplet (tm .n , tm .n , tm .nz , tm .Ar , tm .Ac , tm .Av , NULL , self .Control )
367384 else :
368- self . gdata . dll .umfpack_di_report_triplet (tm .n , tm .n , tm .nz , tm .Ar , tm .Ac , tm .Av , self .Control )
385+ umf_dll .umfpack_di_report_triplet (tm .n , tm .n , tm .nz , tm .Ar , tm .Ac , tm .Av , self .Control )
369386
370387 def triplet_to_col (self , tm ):
371388 n = tm .n
@@ -377,14 +394,14 @@ def triplet_to_col(self, tm):
377394 if self .is_complex :
378395 Ax = array .array ('d' , [0 ] * (2 * nz1 ))
379396 matrix = di_matrix (self , Ap , Ai , Ax )
380- self .status = self . gdata . dll .umfpack_zi_triplet_to_col (n , n , nz , tm .Ar , tm .Ac , tm .Av , NULL , matrix .AP , matrix .AI , matrix .AX , NULL , NULL )
397+ self .status = umf_dll .umfpack_zi_triplet_to_col (n , n , nz , tm .Ar , tm .Ac , tm .Av , NULL , matrix .AP , matrix .AI , matrix .AX , NULL , NULL )
381398 else :
382399 Ax = array .array ('d' , [0 ] * (nz1 ))
383400 matrix = di_matrix (self , Ap , Ai , Ax )
384- self .status = self . gdata . dll .umfpack_di_triplet_to_col (n , n , nz , tm .Ar , tm .Ac , tm .Av , matrix .AP , matrix .AI , matrix .AX , NULL )
401+ self .status = umf_dll .umfpack_di_triplet_to_col (n , n , nz , tm .Ar , tm .Ac , tm .Av , matrix .AP , matrix .AI , matrix .AX , NULL )
385402
386403 if self .status < 0 :
387- self . gdata . dll .umfpack_di_report_status (self .Control , self .status )
404+ umf_dll .umfpack_di_report_status (self .Control , self .status )
388405 raise RuntimeError ("umfpack triplet_to_col failed" )
389406
390407 return matrix
@@ -393,21 +410,21 @@ def print_matrix(self, matrix):
393410 print ("\n A: " )
394411 if self .is_complex :
395412 NULL = (c_void_p )()
396- self . gdata . dll .umfpack_zi_report_matrix (matrix .n , matrix .n , matrix .AP , matrix .AI , matrix .AX , NULL , 1 , self .Control )
413+ umf_dll .umfpack_zi_report_matrix (matrix .n , matrix .n , matrix .AP , matrix .AI , matrix .AX , NULL , 1 , self .Control )
397414 else :
398- self . gdata . dll .umfpack_di_report_matrix (matrix .n , matrix .n , matrix .AP , matrix .AI , matrix .AX , 1 , self .Control )
415+ umf_dll .umfpack_di_report_matrix (matrix .n , matrix .n , matrix .AP , matrix .AI , matrix .AX , 1 , self .Control )
399416
400417 def print_info (self ):
401418 if self .is_complex :
402- self . gdata . dll .umfpack_zi_report_info (self .Control , self .Info )
419+ umf_dll .umfpack_zi_report_info (self .Control , self .Info )
403420 else :
404- self . gdata . dll .umfpack_di_report_info (self .Control , self .Info )
421+ umf_dll .umfpack_di_report_info (self .Control , self .Info )
405422
406423 def print_status (self ):
407424 if self .is_complex :
408- self . gdata . dll .umfpack_zi_report_status (self .Control , self .status )
425+ umf_dll .umfpack_zi_report_status (self .Control , self .status )
409426 else :
410- self . gdata . dll .umfpack_di_report_status (self .Control , self .status )
427+ umf_dll .umfpack_di_report_status (self .Control , self .status )
411428
412429 def error_on_result (self , msg ):
413430 if self .status != 0 :
@@ -424,9 +441,9 @@ def symbolic(self, matrix):
424441 def print_symbolic (self , Symbolic ):
425442 print ("\n Symbolic factorization of A: " )
426443 if self .is_complex :
427- self . gdata . dll .umfpack_zi_report_symbolic (Symbolic .Symbolic , self .Control )
444+ umf_dll .umfpack_zi_report_symbolic (Symbolic .Symbolic , self .Control )
428445 else :
429- self . gdata . dll .umfpack_di_report_symbolic (Symbolic .Symbolic , self .Control )
446+ umf_dll .umfpack_di_report_symbolic (Symbolic .Symbolic , self .Control )
430447
431448 def numeric (self , matrix , Symbolic ):
432449 Numeric = di_numeric (self )
@@ -437,9 +454,9 @@ def numeric(self, matrix, Symbolic):
437454 def print_numeric (self , Numeric ):
438455 print ("\n Numeric factorization of A: " )
439456 if self .is_complex :
440- self . gdata . dll .umfpack_zi_report_numeric (Numeric .Numeric , self .Control )
457+ umf_dll .umfpack_zi_report_numeric (Numeric .Numeric , self .Control )
441458 else :
442- self . gdata . dll .umfpack_di_report_numeric (Numeric .Numeric , self .Control )
459+ umf_dll .umfpack_di_report_numeric (Numeric .Numeric , self .Control )
443460
444461 def solve (self , matrix , x , b , Numeric , transpose ):
445462 if self .is_complex :
0 commit comments