diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1b302bbb07dcc6199bfc7738fd4f4472238bfa6d..87c060400560e04630c9c1dec66bc4edb18e8c36 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -103,6 +103,19 @@ Documentation: only: - master +Pylint: + script: + # Needed to avoid name shadowing issues when running from source directory. + - PROJECT_INSTALL_FLAGS="--editable" + - export PY_EXE=python3 + - EXTRA_INSTALL="pybind11 numpy mako matplotlib" + - curl -L -O -k https://gitlab.tiker.net/inducer/ci-support/raw/master/prepare-and-run-pylint.sh + - ". ./prepare-and-run-pylint.sh pytential test/test_*.py" + tags: + - python3 + except: + - tags + Flake8: script: - curl -L -O -k https://gitlab.tiker.net/inducer/ci-support/raw/master/prepare-and-run-flake8.sh diff --git a/.pylintrc-local.yml b/.pylintrc-local.yml new file mode 100644 index 0000000000000000000000000000000000000000..fbd7df48f7bc893b651a778aed4f4fdd7a5fff71 --- /dev/null +++ b/.pylintrc-local.yml @@ -0,0 +1,5 @@ +- arg: ignore + val: + - old_diffop_primitives.py + - generalized_debye.py + - waveguide.py # See issue #116 on gitlab diff --git a/pytential/qbx/__init__.py b/pytential/qbx/__init__.py index 832ddcbcf2d2f5caff9f57c4d2fdf525047240f0..8961659e67dc44fb46379185a21509697739813a 100644 --- a/pytential/qbx/__init__.py +++ b/pytential/qbx/__init__.py @@ -147,7 +147,7 @@ class QBXLayerPotentialSource(LayerPotentialSourceBase): if fmm_order is False: fmm_level_to_order = False else: - def fmm_level_to_order(kernel, kernel_args, tree, level): + def fmm_level_to_order(kernel, kernel_args, tree, level): # noqa pylint:disable=function-redefined return fmm_order if _max_leaf_refine_weight is None: @@ -172,9 +172,10 @@ class QBXLayerPotentialSource(LayerPotentialSourceBase): # }}} + LayerPotentialSourceBase.__init__(self, density_discr) + self.fine_order = fine_order self.qbx_order = qbx_order - self.density_discr = density_discr self.fmm_level_to_order = fmm_level_to_order assert target_association_tolerance is not None diff --git a/pytential/qbx/fmm.py b/pytential/qbx/fmm.py index badf630046b239303344e1b1a3664e706a12a0f4..3918914713e9f9b3605ce51ff74a9246cb1b7ca8 100644 --- a/pytential/qbx/fmm.py +++ b/pytential/qbx/fmm.py @@ -598,7 +598,7 @@ def assemble_performance_data(geo_data, uses_pde_expansions, # FIXME: This should suport target filtering. if summarize_parallel is None: - def summarize_parallel(parallel_array, sym_multipliers): + def summarize_parallel(parallel_array, sym_multipliers): # noqa pylint:disable=function-redefined return np.sum(parallel_array) * sym_multipliers from collections import OrderedDict diff --git a/pytential/qbx/refinement.py b/pytential/qbx/refinement.py index 1911a48d1df66c1ea12c7fbb1e8e930ff3a18028..a80a8098aa234834c216aff5cdf0e5b3e7ccd39e 100644 --- a/pytential/qbx/refinement.py +++ b/pytential/qbx/refinement.py @@ -276,11 +276,6 @@ class RefinerCodeContainer(TreeCodeContainerMixin): # {{{ wrangler class RefinerWrangler(TreeWranglerBase): - - def __init__(self, code_container, queue): - self.code_container = code_container - self.queue = queue - # {{{ check subroutines for conditions 1-3 @log_process(logger) diff --git a/pytential/qbx/target_assoc.py b/pytential/qbx/target_assoc.py index 11b70c4b2f1cee8db85fd2c00a159a28682d7fa1..25170c5f593f136576005937dfb4f838264606a4 100644 --- a/pytential/qbx/target_assoc.py +++ b/pytential/qbx/target_assoc.py @@ -433,10 +433,6 @@ class TargetAssociationCodeContainer(TreeCodeContainerMixin): class TargetAssociationWrangler(TreeWranglerBase): - def __init__(self, code_container, queue): - self.code_container = code_container - self.queue = queue - @log_process(logger) def mark_targets(self, tree, peer_lists, lpot_source, target_status, debug, wait_for=None): diff --git a/pytential/qbx/utils.py b/pytential/qbx/utils.py index b0ffc066035c0c8f1aea690ecc5dcb2618367275..c7d06247e329eb9f0c516b5da6dc49fbe791034d 100644 --- a/pytential/qbx/utils.py +++ b/pytential/qbx/utils.py @@ -189,6 +189,10 @@ class TreeCodeContainerMixin(object): class TreeWranglerBase(object): + def __init__(self, code_container, queue): + self.code_container = code_container + self.queue = queue + def build_tree(self, lpot_source, targets_list=(), use_stage2_discr=False): tb = self.code_container.build_tree() @@ -327,38 +331,6 @@ def el_view(discr, group_nr, global_array): # }}} -# {{{ discr plotter - -def plot_discr(lpot_source, outfilename="discr.pdf"): - with cl.CommandQueue(lpot_source.cl_context) as queue: - from boxtree.tree_builder import TreeBuilder - tree_builder = TreeBuilder(lpot_source.cl_context) - tree = tree_builder(queue, lpot_source).get(queue=queue) - from boxtree.visualization import TreePlotter - - import matplotlib - matplotlib.use('Agg') - import matplotlib.pyplot as plt - tp = TreePlotter(tree) - tp.draw_tree() - sources = (tree.sources[0], tree.sources[1]) - sti = tree.sorted_target_ids - plt.plot(sources[0][sti[tree.qbx_user_source_slice]], - sources[1][sti[tree.qbx_user_source_slice]], - lw=0, marker=".", markersize=1, label="sources") - plt.plot(sources[0][sti[tree.qbx_user_center_slice]], - sources[1][sti[tree.qbx_user_center_slice]], - lw=0, marker=".", markersize=1, label="centers") - plt.plot(sources[0][sti[tree.qbx_user_target_slice]], - sources[1][sti[tree.qbx_user_target_slice]], - lw=0, marker=".", markersize=1, label="targets") - plt.axis("equal") - plt.legend() - plt.savefig(outfilename) - -# }}} - - # {{{ tree-with-metadata: data structure class TreeWithQBXMetadata(Tree): diff --git a/pytential/solve.py b/pytential/solve.py index dce9d8a31082bf815936d47f98c8e8d06d6c7f35..82d6f68ff18e25fcbbb1e975b1ce8dc4af12eeba 100644 --- a/pytential/solve.py +++ b/pytential/solve.py @@ -211,7 +211,7 @@ def _gmres(A, b, restart=None, tol=None, x0=None, dot=None, # noqa if (stall_iterations and len(residual_norms) > stall_iterations and norm_r > ( - residual_norms[-stall_iterations] + residual_norms[-stall_iterations] # noqa pylint:disable=invalid-unary-operand-type / no_progress_factor)): state = "stalled" diff --git a/pytential/source.py b/pytential/source.py index 9334dff7e1785cf7d1b36c991effcd6382d2a52e..e628fe21291341b15e8d24b9a64c858d2b94e754 100644 --- a/pytential/source.py +++ b/pytential/source.py @@ -191,6 +191,21 @@ class LayerPotentialSourceBase(PotentialSource): .. method:: exec_compute_potential_insn """ + def __init__(self, density_discr): + self.density_discr = density_discr + + @property + def stage2_density_discr(self): + raise NotImplementedError + + @property + def quad_stage2_density_discr(self): + raise NotImplementedError + + @property + def resampler(self): + raise NotImplementedError + @property def ambient_dim(self): return self.density_discr.ambient_dim diff --git a/pytential/symbolic/compiler.py b/pytential/symbolic/compiler.py index 456044e75a3903b08ffdfa6537f1fac0cd1f6e09..cb9a9c1de493da6df5b005c8e8d665d608e40da4 100644 --- a/pytential/symbolic/compiler.py +++ b/pytential/symbolic/compiler.py @@ -304,7 +304,7 @@ class Code(object): def dump_dataflow_graph(self): from pytools.debug import open_unique_debug_file - open_unique_debug_file("dataflow", ".dot")\ + open_unique_debug_file("dataflow", ".dot")[0]\ .write(dot_dataflow_graph(self, max_node_label_length=None)) def __str__(self): diff --git a/pytential/symbolic/execution.py b/pytential/symbolic/execution.py index 976e352f48c6a03c61429830758eb24517a47407..165ab796633e9deaf352e29521513a54e7fa7366 100644 --- a/pytential/symbolic/execution.py +++ b/pytential/symbolic/execution.py @@ -168,7 +168,7 @@ class EvaluationMapper(EvaluationMapperBase): from pytential.solve import gmres rhs = self.rec(expr.rhs) - result = gmres(scipy_op, rhs, debug=False) + result = gmres(scipy_op, rhs) return result def map_quad_kernel_op(self, expr): @@ -452,7 +452,9 @@ class GeometryCollection(object): return where in self.places def copy(self): - return GeometryCollection(self.places, auto_where=self.where) + return GeometryCollection( + self.places, + auto_where=self._default_place_ids) def get_cache(self, name): return self.caches.setdefault(name, {}) diff --git a/pytential/symbolic/pde/maxwell/__init__.py b/pytential/symbolic/pde/maxwell/__init__.py index 8bdab9df9fc837962cade74bf0af9d14a1d88b11..1431f75b1d01ea0e5b6055c9352d1f2d48aec25e 100644 --- a/pytential/symbolic/pde/maxwell/__init__.py +++ b/pytential/symbolic/pde/maxwell/__init__.py @@ -225,8 +225,8 @@ class MuellerAugmentedMFIEOperator(object): S = partial(sym.S, self.kernel, qbx_forced_limit="avg") - def curl_S(dens): - return sym.curl(sym.S(self.kernel, dens, qbx_forced_limit="avg")) + def curl_S(dens, k): + return sym.curl(sym.S(self.kernel, dens, qbx_forced_limit="avg", k=k)) grad = partial(sym.grad, 3) @@ -244,7 +244,7 @@ class MuellerAugmentedMFIEOperator(object): F3 = (xyz_to_tangential(sym.n_cross(E1-E0) + 0.5*(mu0+mu1)*Mxyz)) # sign flip included - F4 = -sym.n_dot(mu1*H1-mu0*H0) + 0.5*(mu1+mu0)*u.rho_m + F4 = -sym.n_dot(mu1*H1-mu0*H0) + 0.5*(mu1+mu0)*u.rho_m # noqa pylint:disable=invalid-unary-operand-type return sym.join_fields(F1, F2, F3, F4) diff --git a/pytential/symbolic/pde/scalar.py b/pytential/symbolic/pde/scalar.py index 4d211916304d925198586a79ff99d73bc50cfc85..840d804429344f16c62e8f388c654c65dffc6f5b 100644 --- a/pytential/symbolic/pde/scalar.py +++ b/pytential/symbolic/pde/scalar.py @@ -124,7 +124,7 @@ class DirichletOperator(L2WeightedPDEOperator): inv_sqrt_w_u = cse(u/sqrt_w) if map_potentials is None: - def map_potentials(x): + def map_potentials(x): # pylint:disable=function-redefined return x def S(density): # noqa @@ -236,7 +236,7 @@ class NeumannOperator(L2WeightedPDEOperator): inv_sqrt_w_u = cse(u/sqrt_w) if map_potentials is None: - def map_potentials(x): + def map_potentials(x): # pylint:disable=function-redefined return x kwargs["qbx_forced_limit"] = qbx_forced_limit diff --git a/pytential/unregularized.py b/pytential/unregularized.py index e7fe1b3e73bfe17e14ab9aa6d57a86f6c9c92375..4bd67ae97fe1206442bfdad357ec8cbc9ef0779f 100644 --- a/pytential/unregularized.py +++ b/pytential/unregularized.py @@ -66,7 +66,7 @@ class UnregularizedLayerPotentialSource(LayerPotentialSourceBase): """ :arg fmm_order: `False` for direct calculation. """ - self.density_discr = density_discr + LayerPotentialSourceBase.__init__(self, density_discr) self.debug = debug if fmm_order is not False and fmm_level_to_order is not None: @@ -74,7 +74,7 @@ class UnregularizedLayerPotentialSource(LayerPotentialSourceBase): if fmm_level_to_order is None: if fmm_order is not False: - def fmm_level_to_order(kernel, kernel_args, tree, level): + def fmm_level_to_order(kernel, kernel_args, tree, level): # noqa pylint:disable=function-redefined return fmm_order else: fmm_level_to_order = False diff --git a/test/test_scalar_int_eq.py b/test/test_scalar_int_eq.py index 72d08fcf3dcee46ebbdbd03f960c40eb1839992f..1e048b7f6495e664767850c18b6e9bf7f6c2d404 100644 --- a/test/test_scalar_int_eq.py +++ b/test/test_scalar_int_eq.py @@ -64,6 +64,23 @@ def make_circular_point_group(ambient_dim, npoints, radius, # {{{ test cases class IntEqTestCase: + + @property + def default_helmholtz_k(self): + raise NotImplementedError + + @property + def name(self): + raise NotImplementedError + + @property + def qbx_order(self): + raise NotImplementedError + + @property + def target_order(self): + raise NotImplementedError + def __init__(self, helmholtz_k, bc_type, prob_side): """ :arg prob_side: may be -1, +1, or ``'scat'`` for a scattering problem @@ -93,6 +110,9 @@ class IntEqTestCase: class CurveIntEqTestCase(IntEqTestCase): resolutions = [40, 50, 60] + def curve_func(self, *args, **kwargs): + raise NotImplementedError + def get_mesh(self, resolution, target_order): return make_curve_mesh( self.curve_func, @@ -639,7 +659,9 @@ def run_int_eq_test(cl_ctx, queue, case, resolution, visualize): if 0: from sumpy.tools import build_matrix - mat = build_matrix(bound_op.scipy_op("u", dtype=dtype, k=case.k)) + mat = build_matrix( + bound_op.scipy_op( + queue, arg_name="u", dtype=dtype, k=case.k)) w, v = la.eig(mat) if 0: pt.imshow(np.log10(1e-20+np.abs(mat)))