Skip to content

Commit af6bf90

Browse files
committed
Initial commit
0 parents  commit af6bf90

File tree

6 files changed

+252
-0
lines changed

6 files changed

+252
-0
lines changed

.gitignore

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
env/
12+
build/
13+
develop-eggs/
14+
dist/
15+
downloads/
16+
eggs/
17+
.eggs/
18+
lib/
19+
lib64/
20+
parts/
21+
sdist/
22+
var/
23+
*.egg-info/
24+
.installed.cfg
25+
*.egg
26+
27+
# PyInstaller
28+
# Usually these files are written by a python script from a template
29+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
30+
*.manifest
31+
*.spec
32+
33+
# Installer logs
34+
pip-log.txt
35+
pip-delete-this-directory.txt
36+
37+
# Unit test / coverage reports
38+
htmlcov/
39+
.tox/
40+
.coverage
41+
.coverage.*
42+
.cache
43+
nosetests.xml
44+
coverage.xml
45+
*,cover
46+
.hypothesis/
47+
48+
# Translations
49+
*.mo
50+
*.pot
51+
52+
# Django stuff:
53+
*.log
54+
55+
# Sphinx documentation
56+
docs/_build/
57+
58+
# PyBuilder
59+
target/
60+
61+
#Ipython Notebook
62+
.ipynb_checkpoints
63+
*.sublime-project
64+
*.sublime-workspace

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2016 David Marchant
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# pyMKLwrap
2+
Python wrapper of Intel MKL routines

pyMKL/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import numpy as np
2+
import scipy.sparse as sp
3+
from ctypes import CDLL, cdll, RTLD_GLOBAL
4+
from ctypes import POINTER, byref, c_int, c_longlong
5+
6+
path = 'libmkl_intel_lp64.dylib'
7+
MKLlib = CDLL(path, RTLD_GLOBAL)
8+
9+
from pardisoInterface import pardisoinit, pardiso
10+
from pardisoSolver import pardisoSolver

pyMKL/pardisoInterface.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from pyMKL import MKLlib
2+
from ctypes import POINTER, c_int, c_longlong
3+
4+
pardisoinit = MKLlib.pardisoinit
5+
6+
pardisoinit.argtypes = [POINTER(c_longlong),
7+
POINTER(c_int),
8+
POINTER(c_int)]
9+
pardisoinit.restype = None
10+
11+
pardiso = MKLlib.pardiso
12+
pardiso.argtypes = [POINTER(c_longlong), # pt
13+
POINTER(c_int), # maxfct
14+
POINTER(c_int), # mnum
15+
POINTER(c_int), # mtype
16+
POINTER(c_int), # phase
17+
POINTER(c_int), # n
18+
POINTER(None), # a
19+
POINTER(c_int), # ia
20+
POINTER(c_int), # ja
21+
POINTER(c_int), # perm
22+
POINTER(c_int), # nrhs
23+
POINTER(c_int), # iparm
24+
POINTER(c_int), # msglvl
25+
POINTER(None), # b
26+
POINTER(None), # x
27+
POINTER(c_int)] # error)
28+
pardiso.restype = None

pyMKL/pardisoSolver.py

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
from pyMKL import pardisoinit, pardiso
2+
from ctypes import POINTER, byref, c_longlong, c_int, c_float
3+
import numpy as np
4+
5+
"""
6+
mtype options
7+
1 -> real and structurally symmetric
8+
2 -> real and symmetric positive definite
9+
-2 -> real and symmetric indefinite
10+
3 -> complex and structurally symmetric
11+
4 -> complex and Hermitian positive definite
12+
-4 -> complex and Hermitian indefinite
13+
6 -> complex and symmetric
14+
11 -> real and nonsymmetric
15+
13 -> complex and nonsymmetric
16+
17+
18+
phase options
19+
11 -> Analysis
20+
12 -> Analysis, numerical factorization
21+
13 -> Analysis, numerical factorization, solve, iterative refinement
22+
22 -> Numerical factorization
23+
23 -> Numerical factorization, solve, iterative refinement
24+
33 -> Solve, iterative refinement
25+
331 -> like phase=33, but only forward substitution
26+
332 -> like phase=33, but only diagonal substitution (if available)
27+
333 -> like phase=33, but only backward substitution
28+
0 -> Release internal memory for L and U matrix number mnum
29+
-1 -> Release all internal memory for all matrices
30+
"""
31+
32+
class pardisoSolver(object):
33+
"""docstring for pardisoSolver"""
34+
def __init__(self, A, mtype=11):
35+
36+
# Prep the matrix
37+
self.A = A.tocsr()
38+
self.a = A.data
39+
self.ia = A.indptr
40+
self.ja = A.indices
41+
42+
self._MKL_a = self.a.ctypes.data_as(POINTER(c_float))
43+
self._MKL_ia = self.ia.ctypes.data_as(POINTER(c_int))
44+
self._MKL_ja = self.ja.ctypes.data_as(POINTER(c_int))
45+
46+
self.mtype = mtype
47+
self.n = A.shape[0]
48+
49+
# Hardcode some parameters for now...
50+
self.maxfct = 1
51+
self.mnum = 1
52+
self.perm = 0
53+
self.msglvl = 1
54+
55+
# Initialize handle to data structure
56+
self.pt = np.zeros(64, np.int64)
57+
self._MKL_pt = self.pt.ctypes.data_as(POINTER(c_longlong))
58+
59+
# Initialize parameters
60+
self.iparm = np.zeros(64, dtype=np.int32)
61+
self._MKL_iparm = self.iparm.ctypes.data_as(POINTER(c_int))
62+
63+
# Initialize pardiso
64+
pardisoinit(self._MKL_pt, byref(c_int(self.mtype)), self._MKL_iparm)
65+
66+
# Set iparm
67+
self.iparm[1] = 3 # Use parallel nested dissection for reordering
68+
self.iparm[23] = 1 # Use parallel factorization
69+
self.iparm[34] = 1 # Zero base indexing
70+
71+
72+
def run_pardiso(self, phase, rhs=None):
73+
74+
if rhs is None:
75+
nrhs = 0
76+
x = np.zeros(1)
77+
rhs = np.zeros(1)
78+
else:
79+
nrhs = 1
80+
x = np.zeros(self.n)
81+
82+
MKL_rhs = rhs.ctypes.data_as(POINTER(c_float))
83+
MKL_x = x.ctypes.data_as(POINTER(c_float))
84+
ERR = 0
85+
86+
pardiso(self._MKL_pt, # pt
87+
byref(c_int(self.maxfct)), # maxfct
88+
byref(c_int(self.mnum)), # mnum
89+
byref(c_int(self.mtype)), # mtype
90+
byref(c_int(phase)), # phase
91+
byref(c_int(self.n)), # n
92+
self._MKL_a, # a
93+
self._MKL_ia, # ia
94+
self._MKL_ja, # ja
95+
byref(c_int(self.perm)), # perm
96+
byref(c_int(nrhs)), # nrhs
97+
self._MKL_iparm, # iparm
98+
byref(c_int(self.msglvl)), # msglvl
99+
MKL_rhs, # b
100+
MKL_x, # x
101+
byref(c_int(ERR))) # error
102+
103+
return x
104+
105+
106+
107+
if __name__ == '__main__':
108+
109+
import scipy.sparse as sp
110+
111+
nSize = 20
112+
A = sp.rand(nSize, nSize, 0.05, format='csr', random_state=10)
113+
A = A.T.dot(A) + sp.spdiags(np.ones(nSize), 0, nSize, nSize)
114+
A = A.tocsr()
115+
116+
np.random.seed(1)
117+
xTrue = np.random.rand(nSize)
118+
rhs = A.dot(xTrue)
119+
120+
pSolve = pardisoSolver(A)
121+
122+
pSolve.run_pardiso(12)
123+
x = pSolve.run_pardiso(33, rhs)
124+
125+
print np.linalg.norm(x-xTrue)/np.linalg.norm(xTrue)
126+
127+

0 commit comments

Comments
 (0)