From 9198779974787ad4f78a5609e9d09340d9bdca30 Mon Sep 17 00:00:00 2001 From: jan Date: Thu, 4 Aug 2016 20:14:17 -0700 Subject: [PATCH] Cleanup and comment --- .gitignore | 2 +- README.md | 24 ++++++++++++++++++++++-- opencl_fdfd/__init__.py | 2 +- opencl_fdfd/csr.py | 36 ++++++++++++++++++++++++++---------- opencl_fdfd/main.py | 8 ++++++++ opencl_fdfd/ops.py | 10 ++++++++++ setup.py | 2 +- 7 files changed, 69 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index 7b9aef9..2ec014d 100644 --- a/.gitignore +++ b/.gitignore @@ -59,4 +59,4 @@ docs/_build/ target/ # PyCharm -.idea +.idea/ diff --git a/README.md b/README.md index 4901949..e365c4b 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Bloch boundary conditions are not included but wouldn't be very hard to add. The default solver (opencl_fdfd.cg_solver(...)) located in main.py implements the E-field wave operator directly (ie, as a list of OpenCL instructions rather than a matrix). Additionally, there is a slower (and slightly more -versatile) sovler in csr.py which attempts to solve an arbitrary sparse +versatile) solver in csr.py which attempts to solve an arbitrary sparse matrix in compressed sparse row (CSR) format using the same conjugate gradient method as the default solver. The CSR solver is significantly slower, but can be very useful for testing alternative formulations of the FDFD wave equation. @@ -29,9 +29,29 @@ generalization to multiple GPUs should be pretty straightforward (ie, just copy over edge values during the matrix multiplication step). +## Installation + **Dependencies:** * python 3 (written and tested with 3.5) * numpy * pyopencl * jinja2 -* [fdfd_tools](https://mpxd.net/gogs/jan/fdfd_tools) \ No newline at end of file +* [fdfd_tools](https://mpxd.net/gogs/jan/fdfd_tools) + + +Install with pip, via git: +```bash +pip install git+https://mpxd.net/gogs/jan/opencl_fdfd.git@release +``` + + +## Use + +See the documentation for opencl_fdfd.cg_solver(...) +(located in main.py) for details about how to call the solver. + +An alternate (slower) FDFD solver and a general gpu-based sparse matrix +solver is available in csr.py . These aren't particularly well-optimized, +and something like [MAGMA](http://icl.cs.utk.edu/magma/index.html) would +probably be a better choice if you absolutely need to solve arbitrary +sparse matrices and can tolerate writing and compiling C/C++ code. diff --git a/opencl_fdfd/__init__.py b/opencl_fdfd/__init__.py index 570efba..5a16e67 100644 --- a/opencl_fdfd/__init__.py +++ b/opencl_fdfd/__init__.py @@ -19,7 +19,7 @@ The default solver (opencl_fdfd.cg_solver(...)) located in main.py implements the E-field wave operator directly (ie, as a list of OpenCL instructions rather than a matrix). Additionally, there is a slower (and slightly more - versatile) sovler in csr.py which attempts to solve an arbitrary sparse + versatile) solver in csr.py which attempts to solve an arbitrary sparse matrix in compressed sparse row (CSR) format using the same conjugate gradient method as the default solver. The CSR solver is significantly slower, but can be very useful for testing alternative formulations of the FDFD wave equation. diff --git a/opencl_fdfd/csr.py b/opencl_fdfd/csr.py index 7deec66..7961ebf 100644 --- a/opencl_fdfd/csr.py +++ b/opencl_fdfd/csr.py @@ -1,3 +1,19 @@ +""" +Sparse matrix solvers + +This file holds the sparse matrix solvers, as well as the +CSRMatrix sparse matrix representation. + +The FDFD solver (fdfd_cg_solver()) solves an FDFD problem by +creating a sparse matrix representing the problem (using +fdfd_tools) and then passing it to cg(), which performs a +conjugate gradient solve. + +cg() is capable of solving arbitrary sparse matrices which +satisfy the constraints for the 'conjugate gradient' algorithm +(positive definite, symmetric) and some that don't. +""" + from typing import List, Dict, Any import time @@ -133,16 +149,16 @@ def cg(a: 'scipy.sparse.csr_matrix', return x -def cg_solver(omega: complex, - dxes: List[List[numpy.ndarray]], - J: numpy.ndarray, - epsilon: numpy.ndarray, - mu: numpy.ndarray = None, - pec: numpy.ndarray = None, - pmc: numpy.ndarray = None, - adjoint: bool = False, - solver_opts: Dict[str, Any] = None, - ) -> numpy.ndarray: +def fdfd_cg_solver(omega: complex, + dxes: List[List[numpy.ndarray]], + J: numpy.ndarray, + epsilon: numpy.ndarray, + mu: numpy.ndarray = None, + pec: numpy.ndarray = None, + pmc: numpy.ndarray = None, + adjoint: bool = False, + solver_opts: Dict[str, Any] = None, + ) -> numpy.ndarray: """ Conjugate gradient FDFD solver using CSR sparse matrices, mainly for testing and development since it's much slower than the solver in main.py. diff --git a/opencl_fdfd/main.py b/opencl_fdfd/main.py index f9c9c33..6903556 100644 --- a/opencl_fdfd/main.py +++ b/opencl_fdfd/main.py @@ -1,3 +1,11 @@ +""" +Default FDFD solver + +This file holds the default FDFD solver, which uses an E-field wave +operator implemented directly as OpenCL arithmetic (rather than as +a matrix). +""" + from typing import List import time diff --git a/opencl_fdfd/ops.py b/opencl_fdfd/ops.py index 395af3c..8a0cf8b 100644 --- a/opencl_fdfd/ops.py +++ b/opencl_fdfd/ops.py @@ -1,3 +1,12 @@ +""" +Basic PyOpenCL operations + +The functions are mostly concerned with creating and compiling OpenCL +kernels for use by the other solvers. + +See kernels/ for any of the .cl files loaded in this file. +""" + from typing import List, Callable import numpy @@ -8,6 +17,7 @@ import pyopencl.array from pyopencl.elementwise import ElementwiseKernel from pyopencl.reduction import ReductionKernel + # Create jinja2 env on module load jinja_env = jinja2.Environment(loader=jinja2.PackageLoader(__name__, 'kernels')) diff --git a/setup.py b/setup.py index bf4216c..3edbb91 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from setuptools import setup, find_packages setup(name='opencl_fdfd', - version='0.1', + version='0.2', description='Opencl FDFD solver', author='Jan Petykiewicz', author_email='anewusername@gmail.com',