Skip to content

Commit b1c5005

Browse files
author
counterclocker
committed
added report methods to umfpack solver
1 parent a38d8ef commit b1c5005

13 files changed

Lines changed: 5999 additions & 1604 deletions

File tree

examples/umfpack.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,7 @@
1919
solver.report_control()
2020

2121
solver.report_info()
22+
23+
solver.report_symbolic()
24+
25+
solver.report_numeric()

setup.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ def get_path_option(config, section, option):
3939
suitesparse_include_dirs = get_path_option(cysparse_config, 'SUITESPARSE', 'include_dirs')
4040
suitesparse_library_dirs = get_path_option(cysparse_config, 'SUITESPARSE', 'library_dirs')
4141

42+
print "TOTO:"
43+
print suitesparse_include_dirs
44+
4245
########################################################################################################################
4346
# EXTENSIONS
4447
########################################################################################################################
@@ -57,6 +60,7 @@ def get_path_option(config, section, option):
5760
Extension("sparse_lib.sparse.ll_mat", ["sparse_lib/sparse/ll_mat.pxd", "sparse_lib/sparse/ll_mat.pyx"], **sparse_ext_params),
5861
Extension("sparse_lib.sparse.sparse_mat", ["sparse_lib/sparse/sparse_mat.pxd", "sparse_lib/sparse/sparse_mat.pyx"], **sparse_ext_params),
5962
Extension("sparse_lib.sparse.csr_mat", ["sparse_lib/sparse/csr_mat.pxd", "sparse_lib/sparse/csr_mat.pyx"], **sparse_ext_params),
63+
Extension("sparse_lib.sparse.csc_mat", ["sparse_lib/sparse/csc_mat.pxd", "sparse_lib/sparse/csc_mat.pyx"], **sparse_ext_params),
6064
Extension("sparse_lib.sparse.ll_mat_view", ["sparse_lib/sparse/ll_mat_view.pxd", "sparse_lib/sparse/ll_mat_view.pyx"], **sparse_ext_params),
6165
Extension("sparse_lib.utils.equality", ["sparse_lib/utils/equality.pxd", "sparse_lib/utils/equality.pyx"], **sparse_ext_params),
6266
#Extension("sparse.ll_vec", ["sparse_lib/sparse/ll_vec.pyx"], **sparse_ext_params)
@@ -66,6 +70,7 @@ def get_path_option(config, section, option):
6670
# *** umfpack ***
6771
umfpack_ext_params = ext_params.copy()
6872
umfpack_ext_params['include_dirs'].extend(suitesparse_include_dirs)
73+
#umfpack_ext_params['include_dirs'] = suitesparse_include_dirs
6974
umfpack_ext_params['library_dirs'] = suitesparse_library_dirs
7075
umfpack_ext_params['libraries'] = ['umfpack', 'amd']
7176

@@ -80,7 +85,7 @@ def get_path_option(config, section, option):
8085
########################################################################################################################
8186
# SETUP
8287
########################################################################################################################
83-
ext_modules = sparse_ext + umfpack_ext
88+
ext_modules = sparse_ext + umfpack_ext
8489

8590

8691
setup(name= 'SparseLib',

sparse_lib/solvers/suitesparse/umfpack.c

Lines changed: 1552 additions & 422 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,10 @@
11
from sparse_lib.sparse.ll_mat cimport LLSparseMatrix
2+
from sparse_lib.sparse.csc_mat cimport CSCSparseMatrix
23

3-
cdef extern from "suitesparse/umfpack.h":
4+
cdef extern from "umfpack.h":
45
cdef enum:
56
UMFPACK_CONTROL, UMFPACK_INFO
67

7-
# OPAQUE UMFPACK OBJECTS
8-
cdef struct Symbolic:
9-
pass
10-
ctypedef Symbolic * symbolic_t
11-
12-
cdef struct Numeric:
13-
pass
14-
ctypedef Numeric * numeric_t
158

169

1710
cdef class UmfpackSolver:
@@ -22,19 +15,22 @@ cdef class UmfpackSolver:
2215
int ncol
2316

2417
# Matrix A in CSC format
25-
cdef double * val
26-
cdef int * col
27-
cdef int * ind
18+
#double * val
19+
#int * col
20+
#int * ind
21+
CSCSparseMatrix csc_mat
2822

2923
# UMFPACK opaque objects
30-
symbolic_t symbolic
24+
void * symbolic
3125
bint symbolic_computed
3226

33-
numeric_t numeric
27+
void * numeric
3428
bint numeric_computed
3529

3630
# Control and Info arrays
3731
public double info[UMFPACK_INFO]
3832
public double control[UMFPACK_CONTROL]
3933

40-
cdef create_symbolic(self, recompute=?)
34+
cdef int _create_symbolic(self)
35+
cdef int _create_numeric(self)
36+

sparse_lib/solvers/suitesparse/umfpack.pyx

Lines changed: 130 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,10 @@
11
from sparse_lib.sparse.ll_mat cimport LLSparseMatrix
22

3-
cdef extern from "suitesparse/umfpack.h":
3+
import sys
44

5-
char * UMFPACK_DATE
6-
7-
# OPAQUE UMFPACK OBJECTS
8-
cdef struct Symbolic:
9-
pass
10-
ctypedef Symbolic * symbolic_t
5+
cdef extern from "umfpack.h":
116

12-
cdef struct Numeric:
13-
pass
14-
ctypedef Numeric * numeric_t
7+
char * UMFPACK_DATE
158

169
cdef enum:
1710
UMFPACK_CONTROL, UMFPACK_INFO
@@ -88,26 +81,31 @@ cdef extern from "suitesparse/umfpack.h":
8881

8982
int umfpack_di_symbolic(int n_row, int n_col,
9083
int * Ap, int * Ai, double * Ax,
91-
symbolic_t * symbolic,
84+
void ** symbolic,
9285
double * control, double * info)
9386

9487
int umfpack_di_numeric(int * Ap, int * Ai, double * Ax,
95-
symbolic_t symbolic,
96-
numeric_t * numeric,
88+
void * symbolic,
89+
void ** numeric,
9790
double * control, double * info)
9891

99-
void umfpack_di_free_symbolic(symbolic_t * symbolic)
100-
void umfpack_di_free_numeric(numeric_t * numeric)
92+
void umfpack_di_free_symbolic(void ** symbolic)
93+
void umfpack_di_free_numeric(void ** numeric)
10194
void umfpack_di_defaults(double * control)
10295

10396
int umfpack_di_get_lunz(int * lnz, int * unz, int * n_row, int * n_col,
104-
int * nz_udiag, numeric_t numeric)
97+
int * nz_udiag, void * numeric)
10598

10699
int umfpack_di_get_numeric(int * Lp, int * Lj, double * Lx, double * Lz,
107100
int * Up, int * Ui, double * Ux, double * Uz,
108101
int * P, int * Q, double * Dx, double * Dz,
109102
int * do_recip, double * Rs,
110-
numeric_t numeric)
103+
void * numeric)
104+
105+
void umfpack_di_report_control(double *)
106+
void umfpack_di_report_info(double *, double *)
107+
void umfpack_di_report_symbolic(void *, double *)
108+
void umfpack_di_report_numeric(void *, double *)
111109

112110

113111
def umfpack_version():
@@ -181,16 +179,26 @@ def test_umfpack_result(status, msg, raise_error=True, print_on_screen=True):
181179

182180

183181
cdef class UmfpackSolver:
182+
"""
183+
Umfpack Solver from SuiteSparse.
184+
185+
This version **only** deals with ``LLSparseMatrix`` objects.
186+
187+
We follow the common use of Umfpack. In particular, we use the same names for the methods of this
188+
class as their corresponding counter-parts in Umfpack.
189+
"""
184190
UMFPACK_VERSION = "%s.%s.%s (%s)" % (UMFPACK_MAIN_VERSION,
185191
UMFPACK_SUB_VERSION,
186192
UMFPACK_SUBSUB_VERSION,
187193
UMFPACK_DATE)
194+
188195
def __cinit__(self, LLSparseMatrix A):
189196
self.A = A
190197
self.nrow = A.nrow
191198
self.ncol = A.ncol
192199

193-
self.csc = self.A.to_csc()
200+
# TODO: type csc in pxd file
201+
self.csc_mat = self.A.to_csc()
194202

195203
#cdef double * val = self.val
196204
#cdef int * col = <int *> self.col
@@ -224,42 +232,111 @@ cdef class UmfpackSolver:
224232
####################################################################################################################
225233
# PRIMARY ROUTINES
226234
####################################################################################################################
227-
cdef create_symbolic(self, recompute=False):
235+
cdef int _create_symbolic(self):
228236

229237
if self.symbolic_computed:
230-
if not recompute:
231-
pass
232-
else:
233-
self.free_symbolic()
234-
235-
#cdef double* info = <double>self.info.data
236-
#cdef double * control = self.control.data
237-
#cdef symbolic_t symbolic = self.symbolic
238-
239-
240-
241-
#status= umfpack_di_symbolic(self.nrow, self.ncol, ind, col, val, &self.symbolic, &self.control, &self.info)
242-
243-
#if status != UMFPACK_OK:
244-
# self.free_symbolic()
245-
# test_umfpack_result(status, "create_symbolic()")
246-
#else:
247-
# self.symbolic_computed = True
248-
249-
# def create_numeric(self, recompute=False):
250-
#
251-
# if self.numeric is not None:
252-
# if not recompute:
253-
# pass
254-
# else:
255-
# self.free_numeric()
256-
#
257-
# self.create_symbolic()
258-
#
259-
# status, self.numeric = self.UMFPACK_ROUTINES['numeric'](self.ind, self.col, self.val, self.symbolic, self.control, self.info)
260-
#
261-
# if status != UMFPACK_OK:
262-
# self.numeric = None
263-
# test_umfpack_result(status, "create_numeric()")
238+
self.free_symbolic()
239+
240+
cdef int * ind = <int *> self.csc_mat.ind
241+
cdef int * row = <int *> self.csc_mat.row
242+
cdef double * val = <double *> self.csc_mat.val
243+
244+
245+
cdef int status= umfpack_di_symbolic(self.nrow, self.ncol, ind, row, val, &self.symbolic, self.control, self.info)
246+
247+
self.symbolic_computed = True
248+
249+
return status
250+
251+
252+
def create_symbolic(self, recompute=False):
253+
if not recompute and self.symbolic_computed:
254+
return
264255

256+
cdef int status = self._create_symbolic()
257+
258+
if status != UMFPACK_OK:
259+
self.free_symbolic()
260+
test_umfpack_result(status, "create_symbolic")
261+
262+
cdef int _create_numeric(self):
263+
264+
if self.numeric_computed:
265+
self.free_numeric()
266+
267+
cdef int * ind = <int *> self.csc_mat.ind
268+
cdef int * row = <int *> self.csc_mat.row
269+
cdef double * val = <double *> self.csc_mat.val
270+
271+
cdef int status = umfpack_di_numeric(ind, row, val,
272+
self.symbolic,
273+
&self.numeric,
274+
self.control, self.info)
275+
276+
self.numeric_computed = True
277+
278+
return status
279+
280+
def create_numeric(self, recompute=False):
281+
282+
if not recompute and self.numeric_computed:
283+
return
284+
285+
cdef int status = self._create_numeric()
286+
287+
if status != UMFPACK_OK:
288+
self.free_numeric()
289+
test_umfpack_result(status, "create_numeric")
290+
291+
292+
####################################################################################################################
293+
# REPORTING ROUTINES
294+
####################################################################################################################
295+
def set_verbosity(self, level):
296+
"""
297+
Set UMFPACK verbosity level.
298+
299+
Args:
300+
level (int): Verbosity level (default: 1).
301+
"""
302+
self.control[UMFPACK_PRL] = level
303+
304+
def get_verbosity(self):
305+
"""
306+
Return UMFPACK verbosity level.
307+
308+
Returns:
309+
verbosity_level (int): The verbosity level set.
310+
"""
311+
return self.control[UMFPACK_PRL]
312+
313+
def report_control(self):
314+
"""
315+
Print control values.
316+
"""
317+
umfpack_di_report_control(self.control)
318+
319+
def report_info(self):
320+
"""
321+
Print all status information.
322+
323+
Use **after** calling :meth:`create_symbolic()`, :meth:`create_numeric()`, :meth:`factorize()` or :meth:`solve()`.
324+
"""
325+
umfpack_di_report_info(self.control, self.info)
326+
327+
def report_symbolic(self):
328+
"""
329+
Print information about the opaque ``symbolic`` object.
330+
"""
331+
if not self.symbolic_computed:
332+
print "No opaque symbolic object has been computed"
333+
return
334+
335+
umfpack_di_report_symbolic(self.symbolic, self.control)
336+
337+
def report_numeric(self):
338+
"""
339+
Print information about the opaque ``numeric`` object.
340+
"""
341+
umfpack_di_report_numeric(self.numeric, self.control)
265342

0 commit comments

Comments
 (0)