forked from jan/opencl_fdfd
use logging package for output, and remove 'verbose' options
This commit is contained in:
parent
4e3d4a8b2c
commit
4ffa5e4a66
@ -16,6 +16,7 @@ satisfy the constraints for the 'conjugate gradient' algorithm
|
|||||||
|
|
||||||
from typing import Dict, Any
|
from typing import Dict, Any
|
||||||
import time
|
import time
|
||||||
|
import logging
|
||||||
|
|
||||||
import numpy
|
import numpy
|
||||||
from numpy.linalg import norm
|
from numpy.linalg import norm
|
||||||
@ -27,6 +28,11 @@ import fdfd_tools.solvers
|
|||||||
from . import ops
|
from . import ops
|
||||||
|
|
||||||
|
|
||||||
|
__author__ = 'Jan Petykiewicz'
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class CSRMatrix(object):
|
class CSRMatrix(object):
|
||||||
"""
|
"""
|
||||||
Matrix stored in Compressed Sparse Row format, in GPU RAM.
|
Matrix stored in Compressed Sparse Row format, in GPU RAM.
|
||||||
@ -49,7 +55,6 @@ def cg(A: 'scipy.sparse.csr_matrix',
|
|||||||
err_threshold: float = 1e-6,
|
err_threshold: float = 1e-6,
|
||||||
context: pyopencl.Context = None,
|
context: pyopencl.Context = None,
|
||||||
queue: pyopencl.CommandQueue = None,
|
queue: pyopencl.CommandQueue = None,
|
||||||
verbose: bool = False,
|
|
||||||
) -> numpy.ndarray:
|
) -> numpy.ndarray:
|
||||||
"""
|
"""
|
||||||
General conjugate-gradient solver for sparse matrices, where A @ x = b.
|
General conjugate-gradient solver for sparse matrices, where A @ x = b.
|
||||||
@ -60,7 +65,6 @@ def cg(A: 'scipy.sparse.csr_matrix',
|
|||||||
:param err_threshold: Error threshold for successful solve, relative to norm(b)
|
:param err_threshold: Error threshold for successful solve, relative to norm(b)
|
||||||
:param context: PyOpenCL context. Will be created if not given.
|
:param context: PyOpenCL context. Will be created if not given.
|
||||||
:param queue: PyOpenCL command queue. Will be created if not given.
|
:param queue: PyOpenCL command queue. Will be created if not given.
|
||||||
:param verbose: Whether to print statistics to screen.
|
|
||||||
:return: Solution vector x; returned even if solve doesn't converge.
|
:return: Solution vector x; returned even if solve doesn't converge.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -102,13 +106,11 @@ def cg(A: 'scipy.sparse.csr_matrix',
|
|||||||
|
|
||||||
_, err2 = rhoerr_step(r, [])
|
_, err2 = rhoerr_step(r, [])
|
||||||
b_norm = numpy.sqrt(err2)
|
b_norm = numpy.sqrt(err2)
|
||||||
if verbose:
|
logging.debug('b_norm check: ', b_norm)
|
||||||
print('b_norm check: ', b_norm)
|
|
||||||
|
|
||||||
success = False
|
success = False
|
||||||
for k in range(max_iters):
|
for k in range(max_iters):
|
||||||
if verbose:
|
logging.debug('[{:06d}] rho {:.4} alpha {:4.4}'.format(k, rho, alpha))
|
||||||
print('[{:06d}] rho {:.4} alpha {:4.4}'.format(k, rho, alpha), end=' ')
|
|
||||||
|
|
||||||
rho_prev = rho
|
rho_prev = rho
|
||||||
e = xr_step(x, p, r, v, alpha, [])
|
e = xr_step(x, p, r, v, alpha, [])
|
||||||
@ -116,8 +118,7 @@ def cg(A: 'scipy.sparse.csr_matrix',
|
|||||||
|
|
||||||
errs += [numpy.sqrt(err2) / b_norm]
|
errs += [numpy.sqrt(err2) / b_norm]
|
||||||
|
|
||||||
if verbose:
|
logging.debug('err {}'.format(errs[-1]))
|
||||||
print('err', errs[-1])
|
|
||||||
|
|
||||||
if errs[-1] < err_threshold:
|
if errs[-1] < err_threshold:
|
||||||
success = True
|
success = True
|
||||||
@ -128,7 +129,7 @@ def cg(A: 'scipy.sparse.csr_matrix',
|
|||||||
alpha = rho / dot(p, v, e)
|
alpha = rho / dot(p, v, e)
|
||||||
|
|
||||||
if verbose and k % 1000 == 0:
|
if verbose and k % 1000 == 0:
|
||||||
print(k)
|
logging.info('iteration {}'.format(k))
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Done solving
|
Done solving
|
||||||
@ -137,17 +138,16 @@ def cg(A: 'scipy.sparse.csr_matrix',
|
|||||||
|
|
||||||
x = x.get()
|
x = x.get()
|
||||||
|
|
||||||
if verbose:
|
if success:
|
||||||
if success:
|
logging.info('Solve success')
|
||||||
print('Success', end='')
|
else:
|
||||||
else:
|
logging.warning('Solve failure')
|
||||||
print('Failure', end=', ')
|
logging.info('{} iterations in {} sec: {} iterations/sec \
|
||||||
print(', {} iterations in {} sec: {} iterations/sec \
|
'.format(k, time_elapsed, k / time_elapsed))
|
||||||
'.format(k, time_elapsed, k / time_elapsed))
|
logging.debug('final error {}'.format(errs[-1]))
|
||||||
print('final error', errs[-1])
|
logging.debug('overhead {} sec'.format(start_time2 - start_time))
|
||||||
print('overhead {} sec'.format(start_time2 - start_time))
|
|
||||||
|
|
||||||
print('Final residual:', norm(A @ x - b) / norm(b))
|
logging.info('Final residual: {}'.format(norm(A @ x - b) / norm(b)))
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ a matrix).
|
|||||||
|
|
||||||
from typing import List
|
from typing import List
|
||||||
import time
|
import time
|
||||||
|
import logging
|
||||||
|
|
||||||
import numpy
|
import numpy
|
||||||
from numpy.linalg import norm
|
from numpy.linalg import norm
|
||||||
@ -18,8 +19,11 @@ import fdfd_tools.operators
|
|||||||
|
|
||||||
from . import ops
|
from . import ops
|
||||||
|
|
||||||
|
|
||||||
__author__ = 'Jan Petykiewicz'
|
__author__ = 'Jan Petykiewicz'
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def cg_solver(omega: complex,
|
def cg_solver(omega: complex,
|
||||||
dxes: List[List[numpy.ndarray]],
|
dxes: List[List[numpy.ndarray]],
|
||||||
@ -32,7 +36,6 @@ def cg_solver(omega: complex,
|
|||||||
max_iters: int = 40000,
|
max_iters: int = 40000,
|
||||||
err_threshold: float = 1e-6,
|
err_threshold: float = 1e-6,
|
||||||
context: pyopencl.Context = None,
|
context: pyopencl.Context = None,
|
||||||
verbose: bool = False,
|
|
||||||
) -> numpy.ndarray:
|
) -> numpy.ndarray:
|
||||||
"""
|
"""
|
||||||
OpenCL FDFD solver using the iterative conjugate gradient (cg) method
|
OpenCL FDFD solver using the iterative conjugate gradient (cg) method
|
||||||
@ -57,7 +60,6 @@ def cg_solver(omega: complex,
|
|||||||
:param err_threshold: If (r @ r.conj()) / norm(1j * omega * J) < err_threshold, success.
|
:param err_threshold: If (r @ r.conj()) / norm(1j * omega * J) < err_threshold, success.
|
||||||
Default 1e-6.
|
Default 1e-6.
|
||||||
:param context: PyOpenCL context to run in. If not given, construct a new context.
|
:param context: PyOpenCL context to run in. If not given, construct a new context.
|
||||||
:param verbose: If True, print progress to stdout. Default False.
|
|
||||||
:return: E-field which solves the system. Returned even if we did not converge.
|
:return: E-field which solves the system. Returned even if we did not converge.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -171,12 +173,13 @@ def cg_solver(omega: complex,
|
|||||||
|
|
||||||
_, err2 = rhoerr_step(r, [])
|
_, err2 = rhoerr_step(r, [])
|
||||||
b_norm = numpy.sqrt(err2)
|
b_norm = numpy.sqrt(err2)
|
||||||
print('b_norm check: ', b_norm)
|
logging.debug('b_norm check: {}'.format(b_norm))
|
||||||
|
|
||||||
success = False
|
success = False
|
||||||
for k in range(max_iters):
|
for k in range(max_iters):
|
||||||
if verbose:
|
do_print = (k % 100 == 0)
|
||||||
print('[{:06d}] rho {:.4} alpha {:4.4}'.format(k, rho, alpha), end=' ')
|
if do_print:
|
||||||
|
logger.debug('[{:06d}] rho {:.4} alpha {:4.4}'.format(k, rho, alpha))
|
||||||
|
|
||||||
rho_prev = rho
|
rho_prev = rho
|
||||||
e = xr_step(x, p, r, v, alpha, [])
|
e = xr_step(x, p, r, v, alpha, [])
|
||||||
@ -184,8 +187,8 @@ def cg_solver(omega: complex,
|
|||||||
|
|
||||||
errs += [numpy.sqrt(err2) / b_norm]
|
errs += [numpy.sqrt(err2) / b_norm]
|
||||||
|
|
||||||
if verbose:
|
if do_print:
|
||||||
print('err', errs[-1])
|
logger.debug('err {}'.format(errs[-1]))
|
||||||
|
|
||||||
if errs[-1] < err_threshold:
|
if errs[-1] < err_threshold:
|
||||||
success = True
|
success = True
|
||||||
@ -196,7 +199,7 @@ def cg_solver(omega: complex,
|
|||||||
alpha = rho / dot(p, v, e)
|
alpha = rho / dot(p, v, e)
|
||||||
|
|
||||||
if k % 1000 == 0:
|
if k % 1000 == 0:
|
||||||
print(k)
|
logger.info('iteration {}'.format(k))
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Done solving
|
Done solving
|
||||||
@ -210,18 +213,18 @@ def cg_solver(omega: complex,
|
|||||||
x = (Pr * x).get()
|
x = (Pr * x).get()
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
print('Success', end='')
|
logger.info('Solve success')
|
||||||
else:
|
else:
|
||||||
print('Failure', end=', ')
|
logger.warning('Solve failure')
|
||||||
print(', {} iterations in {} sec: {} iterations/sec \
|
logger.info('{} iterations in {} sec: {} iterations/sec \
|
||||||
'.format(k, time_elapsed, k / time_elapsed))
|
'.format(k, time_elapsed, k / time_elapsed))
|
||||||
print('final error', errs[-1])
|
logger.debug('final error {}'.format(errs[-1]))
|
||||||
print('overhead {} sec'.format(start_time2 - start_time))
|
logger.debug('overhead {} sec'.format(start_time2 - start_time))
|
||||||
|
|
||||||
A0 = fdfd_tools.operators.e_full(omega, dxes, epsilon, mu).tocsr()
|
A0 = fdfd_tools.operators.e_full(omega, dxes, epsilon, mu).tocsr()
|
||||||
if adjoint:
|
if adjoint:
|
||||||
# Remember we conjugated all the contents of A earlier
|
# Remember we conjugated all the contents of A earlier
|
||||||
A0 = A0.T
|
A0 = A0.T
|
||||||
print('Post-everything residual:', norm(A0 @ x - b) / norm(b))
|
logger.info('Post-everything residual: {}'.format(norm(A0 @ x - b) / norm(b)))
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ See kernels/ for any of the .cl files loaded in this file.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import List, Callable
|
from typing import List, Callable
|
||||||
|
import logging
|
||||||
|
|
||||||
import numpy
|
import numpy
|
||||||
import jinja2
|
import jinja2
|
||||||
@ -18,6 +19,8 @@ from pyopencl.elementwise import ElementwiseKernel
|
|||||||
from pyopencl.reduction import ReductionKernel
|
from pyopencl.reduction import ReductionKernel
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# Create jinja2 env on module load
|
# Create jinja2 env on module load
|
||||||
jinja_env = jinja2.Environment(loader=jinja2.PackageLoader(__name__, 'kernels'))
|
jinja_env = jinja2.Environment(loader=jinja2.PackageLoader(__name__, 'kernels'))
|
||||||
|
|
||||||
@ -145,6 +148,11 @@ def create_a(context: pyopencl.Context,
|
|||||||
e2 = H2E_kernel(E, H, oeps, Pl, pec, *idxes[1], wait_for=[e2])
|
e2 = H2E_kernel(E, H, oeps, Pl, pec, *idxes[1], wait_for=[e2])
|
||||||
return [e2]
|
return [e2]
|
||||||
|
|
||||||
|
logger.debug('Preamble: \n{}'.format(preamble))
|
||||||
|
logger.debug('p2e: \n{}'.format(p2e_source))
|
||||||
|
logger.debug('e2h: \n{}'.format(e2h_source))
|
||||||
|
logger.debug('h2e: \n{}'.format(h2e_source))
|
||||||
|
|
||||||
return spmv
|
return spmv
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user