Skip to content

Commit

Permalink
Resolve pylint benchmarks (#178)
Browse files Browse the repository at this point in the history
* resolved pylint complaints in distribution benchmarks

* cleaned up pylint messages in linearsolver, too

* pulled out random spd matrix

* finalised distribution and linearsolver

* blacked results

* black messed up my pylint ignore

* removed benchmark directory from tox pylint ignore

* blacked

* re-fix ivpsolver and linearsolver

* added pylint ignores, renamed property into method

* renamed random spd matrix

* globally ignored missing-function-docstring

* documented benchmark change in tox file

* blacked

* mini docstring updates
  • Loading branch information
pnkraemer authored Sep 1, 2020
1 parent ab66e15 commit 9fc3341
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 53 deletions.
14 changes: 14 additions & 0 deletions benchmarks/benchmark_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""Reocurring constants and methods for benchmarking functions."""

import numpy as np


SPD_MATRIX_5x5 = np.array(
[
[2.3, -2.3, 3.5, 4.2, 1.8],
[-2.3, 3.0, -3.5, -4.8, -1.9],
[3.5, -3.5, 6.9, 5.8, 0.8],
[4.2, -4.8, 5.8, 10.1, 6.3],
[1.8, -1.9, 0.8, 6.3, 12.1],
]
)
3 changes: 3 additions & 0 deletions benchmarks/ivpsolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ class IVPSolve:
params = [["eks0", "ekf0"], ["with", "without"], ["ibm4", "ioup4", "matern92"]]

def setup(self, method, precond, prior):
# pylint: disable=attribute-defined-outside-init,invalid-name,unused-argument
self.ivp = load_lotkavolterra()
self.stepsize = 1e-2

def time_solve(self, method, precond, prior):
# pylint: disable=missing-function-docstring
precond_step = self.stepsize if precond == "with" else 1.0
probsolve_ivp(
self.ivp,
Expand All @@ -35,6 +37,7 @@ def time_solve(self, method, precond, prior):
)

def peakmem_solve(self, method, precond, prior):
# pylint: disable=missing-function-docstring
precond_step = self.stepsize if precond == "with" else 1.0
probsolve_ivp(
self.ivp,
Expand Down
44 changes: 25 additions & 19 deletions benchmarks/linearsolvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import scipy.sparse

from probnum.linalg import problinsolve
from benchmarks.benchmark_utils import SPD_MATRIX_5x5


def load_poisson_linear_system():
Expand All @@ -21,59 +22,63 @@ def load_poisson_linear_system():
Linear system resulting from discretization on an elliptic grid.
"""
# pylint: disable=invalid-name
fpath = os.path.join(os.path.dirname(__file__), "../tests/resources")
A = scipy.sparse.load_npz(file=fpath + "/matrix_poisson.npz")
f = np.load(file=fpath + "/rhs_poisson.npy")
return A, f


class LinSolve:
"""
Benchmark solving a linear system.
"""
"""Benchmark solving a linear system."""

param_names = ["system"]
params = [["sparse", "dense"]] # , "large-scale"]

def setup(self, system):
# pylint: disable=attribute-defined-outside-init,invalid-name

# Seed
np.random.seed(42)

if system == "sparse":
self.A, self.b = load_poisson_linear_system()
(
self.A,
self.b,
) = load_poisson_linear_system()
elif system == "dense":
self.A = np.array(
[
[2.3, -2.3, 3.5, 4.2, 1.8],
[-2.3, 3.0, -3.5, -4.8, -1.9],
[3.5, -3.5, 6.9, 5.8, 0.8],
[4.2, -4.8, 5.8, 10.1, 6.3],
[1.8, -1.9, 0.8, 6.3, 12.1],
]
)
self.A = SPD_MATRIX_5x5
self.b = np.random.normal(size=self.A.shape[0])
elif system == "large-scale":
self.A = None
self.b = None

def time_solve(self, system):
# Solve linear system
self.xhat, self.Ahat, self.Ainvhat, _ = problinsolve(A=self.A, b=self.b)
"""Time solving a linear system"""
# pylint: disable=unused-argument
problinsolve(A=self.A, b=self.b)

def mem_solve(self, system):
# Solve linear system
self.xhat, self.Ahat, self.Ainvhat, _ = problinsolve(A=self.A, b=self.b)
"""Time solving a linear system"""
# pylint: disable=unused-argument
problinsolve(A=self.A, b=self.b)

def peakmem_solve(self, system):
# Solve linear system
self.xhat, self.Ahat, self.Ainvhat, _ = problinsolve(A=self.A, b=self.b)
"""Time solving a linear system"""
# pylint: disable=unused-argument
problinsolve(A=self.A, b=self.b)


class PosteriorDist:
"""Benchmark sampling from the posterior distribution."""

param_names = ["output"]
params = [["solution", "matrix", "matrix_inverse"]]

def setup(self, output):
# pylint: disable=attribute-defined-outside-init
# pylint: disable=unused-argument, invalid-name

# Sparse system
self.A, self.b = load_poisson_linear_system()

Expand All @@ -84,6 +89,7 @@ def setup(self, output):
self.n_samples = 10

def time_sample(self, output):
"""Time sampling from the posterior distribution"""
if output == "solution":
self.xhat.sample(self.n_samples)
elif output == "matrix":
Expand Down
63 changes: 30 additions & 33 deletions benchmarks/random_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
from probnum import random_variables as rvs
import probnum.linalg.linops as linops

from benchmarks.benchmark_utils import SPD_MATRIX_5x5

# Module level variables
rv_names = [
RV_NAMES = [
"univar_normal",
"multivar_normal",
"matrixvar_normal",
Expand All @@ -18,27 +20,17 @@


def get_randvar(rv_name):
"""
Return a random variable for a given distribution name
"""
"""Return a random variable for a given distribution name."""
# Distribution Means and Covariances
spd_mat = np.array(
[
[2.3, -2.3, 3.5, 4.2, 1.8],
[-2.3, 3.0, -3.5, -4.8, -1.9],
[3.5, -3.5, 6.9, 5.8, 0.8],
[4.2, -4.8, 5.8, 10.1, 6.3],
[1.8, -1.9, 0.8, 6.3, 12.1],
]
)

mean_0d = np.random.rand()
mean_1d = np.random.rand(5)
mean_2d_mat = spd_mat
mean_2d_linop = linops.MatrixMult(spd_mat)
mean_2d_mat = SPD_MATRIX_5x5
mean_2d_linop = linops.MatrixMult(SPD_MATRIX_5x5)
cov_0d = np.random.rand() + 10 ** -12
cov_1d = spd_mat
cov_2d_kron = linops.Kronecker(A=spd_mat, B=spd_mat)
cov_2d_symkron = linops.SymmetricKronecker(A=spd_mat)
cov_1d = SPD_MATRIX_5x5
cov_2d_kron = linops.Kronecker(A=SPD_MATRIX_5x5, B=SPD_MATRIX_5x5)
cov_2d_symkron = linops.SymmetricKronecker(A=SPD_MATRIX_5x5)

if rv_name == "univar_normal":
randvar = rvs.Normal(mean=mean_0d, cov=cov_0d)
Expand All @@ -55,50 +47,55 @@ def get_randvar(rv_name):


class Functions:
"""
Benchmark various functions of distributions.
"""
"""Benchmark various functions of random variables."""

param_names = ["randvar", "method"]
params = [RV_NAMES, ["pdf", "logpdf", "cdf", "logcdf"]]

param_names = ["randvar", "property"]
params = [rv_names, ["pdf", "logpdf", "cdf", "logcdf"]]
def setup(self, randvar, method):
# pylint: disable=unused-argument,attribute-defined-outside-init,missing-function-docstring

def setup(self, randvar, property):
self.randvar = get_randvar(rv_name=randvar)
self.eval_point = np.random.uniform(size=self.randvar.shape)
self.quantile = np.random.uniform(size=self.randvar.shape)

def time_distr_functions(self, randvar, property):
def time_distr_functions(self, randvar, method):
"""Times evaluation of the pdf, logpdf, cdf and logcdf."""
# pylint: disable=unused-argument

try:
if property == "pdf":
if method == "pdf":
self.randvar.pdf(x=self.eval_point)
elif property == "logpdf":
elif method == "logpdf":
self.randvar.logpdf(x=self.eval_point)
elif property == "cdf":
elif method == "cdf":
self.randvar.cdf(x=self.quantile)
elif property == "logcdf":
elif method == "logcdf":
self.randvar.logcdf(x=self.quantile)
except NotImplementedError:
pass


class Sampling:
"""
Benchmark sampling routines for various distributions.
"""
"""Benchmark sampling routines for various distributions."""

param_names = ["randvar"]
params = [rv_names]
params = [RV_NAMES]

def setup(self, randvar):
# pylint: disable=unused-argument,attribute-defined-outside-init,missing-function-docstring
np.random.seed(42)
self.n_samples = 1000
self.randvar = get_randvar(rv_name=randvar)

def time_sample(self, randvar):
"""Times sampling from this distribution."""
# pylint: disable=unused-argument

self.randvar.sample(self.n_samples)

def peakmem_sample(self, randvar):
"""Peak memory of sampling process."""
# pylint: disable=unused-argument

self.randvar.sample(self.n_samples)
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,5 @@ commands =
pylint src/probnum/quad --disable="attribute-defined-outside-init,too-few-public-methods,redefined-builtin,arguments-differ,unused-argument,missing-module-docstring"
pylint src/probnum/random_variables --disable="missing-function-docstring"
pylint src/probnum/utils --disable="duplicate-code,missing-module-docstring,missing-function-docstring"
pylint benchmarks --disable="missing-function-docstring" # not a work in progress, but final
pylint tests --disable="line-too-long,duplicate-code,missing-class-docstring,unnecessary-pass,unused-variable,protected-access,attribute-defined-outside-init,no-self-use,abstract-class-instantiated,too-many-arguments,too-many-instance-attributes,too-many-locals,unused-argument,fixme,missing-module-docstring,missing-function-docstring"
pylint benchmarks --disable="attribute-defined-outside-init,unused-argument,redefined-builtin,missing-class-docstring,duplicate-code,missing-function-docstring"

0 comments on commit 9fc3341

Please sign in to comment.