From c2ea6553e71ea357baed498ee0288d8e0a80dada Mon Sep 17 00:00:00 2001 From: Alex G Rice <766758+guidorice@users.noreply.github.com> Date: Sat, 25 Nov 2023 14:27:55 -0700 Subject: [PATCH] Prepare for modcon-contest submission. (#1) * Prepare for submission. * Update readme * Cleanup code * Add unit tests * Add makefile, and github actions workflow * Add github actions badge --- .github/workflows/test.yaml | 50 +++++++++ .gitignore | 4 + Makefile | 29 ++++++ README.md | 88 +++++++++++++++- docs/benchmark-results.ods | Bin 0 -> 19453 bytes docs/img/benchmarks-1.png | Bin 0 -> 41804 bytes docs/img/benchmarks-2.png | Bin 0 -> 35911 bytes docs/img/bounding_box.png | Bin 0 -> 68235 bytes environment.yml | 10 ++ mojo_impl/__init__.mojo | 0 mojo_impl/naive.mojo | 66 ++++++++++++ mojo_impl/optimized_a.mojo | 79 +++++++++++++++ mojo_impl/optimized_b.mojo | 82 +++++++++++++++ mojo_impl/tests/__init__.mojo | 0 mojo_impl/tests/test_impls.mojo | 34 +++++++ mojo_impl/tests/util.mojo | 20 ++++ py_impl/__init__.py | 0 py_impl/naive.py | 27 +++++ py_impl/naive_benchmark.ipynb | 163 ++++++++++++++++++++++++++++++ py_impl/optimized_benchmark.ipynb | 163 ++++++++++++++++++++++++++++++ py_impl/optimized_numpy.py | 12 +++ py_impl/tests/__init__.py | 0 py_impl/tests/test_impls.py | 17 ++++ 23 files changed, 842 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/test.yaml create mode 100644 Makefile create mode 100644 docs/benchmark-results.ods create mode 100644 docs/img/benchmarks-1.png create mode 100644 docs/img/benchmarks-2.png create mode 100644 docs/img/bounding_box.png create mode 100644 environment.yml create mode 100644 mojo_impl/__init__.mojo create mode 100644 mojo_impl/naive.mojo create mode 100644 mojo_impl/optimized_a.mojo create mode 100644 mojo_impl/optimized_b.mojo create mode 100644 mojo_impl/tests/__init__.mojo create mode 100644 mojo_impl/tests/test_impls.mojo create mode 100644 mojo_impl/tests/util.mojo create mode 100644 py_impl/__init__.py create mode 100644 py_impl/naive.py create mode 100644 py_impl/naive_benchmark.ipynb create mode 100644 py_impl/optimized_benchmark.ipynb create mode 100644 py_impl/optimized_numpy.py create mode 100644 py_impl/tests/__init__.py create mode 100644 py_impl/tests/test_impls.py diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..3cf225f --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,50 @@ +name: Run Tests + +on: + pull_request: + types: [opened, reopened, edited] + + push: + branches: + - 'main' + +jobs: + + tests: + runs-on: ubuntu-latest + + defaults: + run: + shell: bash -el {0} + + steps: + - name: Check out repository code + uses: actions/checkout@v4 + with: + submodules: "recursive" + + - name: "Setup conda env (base)" + uses: conda-incubator/setup-miniconda@v2 + with: + python-version: 3.11 + auto-activate-base: true + + - name: "Install mojo" + run: | + curl https://get.modular.com | MODULAR_AUTH=${{ secrets.MODULAR_AUTH }} sh - + modular auth ${{ secrets.MODULAR_AUTH }} + modular install mojo + + - name: "Setup conda env (modcon23-contest)" + uses: conda-incubator/setup-miniconda@v2 + with: + python-version: 3.11 + activate-environment: modcon23-contest + environment-file: environment.yml + + - name: "Run mojo-pytest" + run: | + export MODULAR_HOME="/home/runner/.modular" + export PATH="/home/runner/.modular/pkg/packages.modular.com_mojo/bin:$PATH" + export MOJO_PYTHON_LIBRARY="$(find $CONDA_PREFIX/lib -iname 'libpython*.[s,d]*' | sort -r | head -n 1)" + make test diff --git a/.gitignore b/.gitignore index 68bc17f..662d5de 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +.vscode/ +.DS_Store +scratch/ + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..335126b --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +.PHONY: test benchmark-mojo install-py-packages + +install-py-packages: + conda env create -p venv --file environment.yml + +test: + pytest -W error + +benchmark-mojo: + mojo mojo_impl/naive.mojo 100 + mojo mojo_impl/naive.mojo 1000 + mojo mojo_impl/naive.mojo 10000 + mojo mojo_impl/naive.mojo 100000 + mojo mojo_impl/naive.mojo 1000000 + mojo mojo_impl/naive.mojo 10000000 + + mojo mojo_impl/optimized_a.mojo 100 + mojo mojo_impl/optimized_a.mojo 1000 + mojo mojo_impl/optimized_a.mojo 10000 + mojo mojo_impl/optimized_a.mojo 100000 + mojo mojo_impl/optimized_a.mojo 1000000 + mojo mojo_impl/optimized_a.mojo 10000000 + + mojo mojo_impl/optimized_b.mojo 100 + mojo mojo_impl/optimized_b.mojo 1000 + mojo mojo_impl/optimized_b.mojo 10000 + mojo mojo_impl/optimized_b.mojo 100000 + mojo mojo_impl/optimized_b.mojo 1000000 + mojo mojo_impl/optimized_b.mojo 10000000 diff --git a/README.md b/README.md index 7e0d516..4a9cc30 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,86 @@ -# modcon23-contest -modcon23-contest +# Spatial envelope optimization and benchmarks + +A [Mojo](https://github.com/modularml/mojo)🔥 project calculating the spatial envelope, and exploring the +performance of Python, NumPy, and Mojo. + +[![Run Tests](https://github.com/guidorice/modcon23-contest/actions/workflows/tests.yaml/badge.svg)](https://github.com/guidorice/modcon23-contest/actions/workflows/tests.yaml) + +## Envelope + +Calculating an envelope is a fundamental part of spatial analysis. The envelope +(aka: bounds, bbox, mbr) is usually defined by an xmin, ymin, xmax, and ymax +representing the minimum and maximum x (longitude) and y (latitude) coordinates +that encompass the bounded feature(s). + +![bounding box](./docs/img/bounding_box.png) + +Figure attribution: [QGIS documentation](https://docs.qgis.org/3.28/en/docs/user_manual/processing_algs/qgis/vectorgeometry.html#bounding-boxes): Fig. 27.53 Black lines represent the bounding boxes of each polygon feature. + +## Variants benchmarked + +- [naïve Python](./py_impl/naive.py) +- [naïve Mojo](./mojo_impl/naive.mojo) +- [Python using NumPy (well-optimized C code)](./py_impl/optimized_numpy.py) +- [Mojo optimized with vectorization and loop unrolling, single-threaded (mojo optimized "a")](./mojo_impl/optimized_a.mojo) +- [Mojo optimized with parallelization, vectorization and loop unrolling. (mojo optimized "b")](./mojo_impl/optimized_b.mojo) + +## Variants also considered + +I wanted to benchmark the [Shapely](https://shapely.readthedocs.io/en/stable/) +package which wraps the [GEOS library](https://libgeos.org/), another +well-optimized C/C++ codebase. However Shapely seems to cache the envelope upon +geometry creation, so it was not feasible to benchmark the envelope +calculations separately from geometry constructors. Using NumPy seemed like a +good alternative. + +## All benchmarks + +Test system: mojo `0.5.0` on Apple M2, 24GB RAM. Data type: `float32`. + +![overall benchmarks](./docs/img/benchmarks-1.png) + +## Chart of optimized variants only + +![optimized benchmarks](./docs/img/benchmarks-2.png) + +## Key Findings + +1. [Mojo optimized "a"](./mojo_impl/optimized_a.mojo) is the best overall +performer. However for large feature spaces (millions of points) we can get +at least an additional 25% speedup by using one thread per dimension, as shown in +[Mojo optimized "b"](./mojo_impl/optimized_b.mojo). + +2. Even more performance optimizations are possibly left on the table, such as +auto-tuning, stack allocation, and tiled/striped memory access. A fusion of +Mojo optimized "a" and "b" could offer the best performance across all feature +sizes. + +3. In addition to being performance winners, the Mojo variants are +parameterized by the number of dimensions (`dims`) and by data type (`dtype`). +In other words, the same generic code can run, for example, `float16`, +`float64` or with 3, 4 or more dimensions. In GIS systems the number of +dimensions is sometimes referred to as XY, XYZ, or XYZM, where Z is "height", +and M is "measure". + +## Example output from Mojo's `benchmark` module + +```text +$ mojo mojo_impl/optimized_a.mojo 100 +float32 100 +--------------------- +Benchmark Report (s) +--------------------- +Mean: 6.5356175103213615e-07 +Total: 0.75083200000000005 +Iters: 1148831 +Warmup Mean: 9.9999999999999995e-07 +Warmup Total: 1.9999999999999999e-06 +Warmup Iters: 2 +Fastest Mean: 6.4460000000000004e-07 +Slowest Mean: 7.9999999999999996e-07 + +ns: 653.56175103213616 +microsecs: 0.6535617510321361 +ms: 0.0006535617510321361 +s: 6.5356175103213615e-07 +``` diff --git a/docs/benchmark-results.ods b/docs/benchmark-results.ods new file mode 100644 index 0000000000000000000000000000000000000000..24b912bee3ae3ba9d532c3c184a18df466c16edc GIT binary patch literal 19453 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 literal 0 HcmV?d00001 diff --git a/docs/img/benchmarks-1.png b/docs/img/benchmarks-1.png new file mode 100644 index 0000000000000000000000000000000000000000..89e867b5a2c795a8eadfcb841456448fa8fad2f1 GIT binary patch literal 41804 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%0ACOcGoL( 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 literal 0 HcmV?d00001 diff --git a/docs/img/benchmarks-2.png b/docs/img/benchmarks-2.png new file mode 100644 index 0000000000000000000000000000000000000000..1a290c9a289e0c1c90e015f17633ceaadbf9f8bf GIT binary patch literal 35911 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 Oqp7ZYJzw?y)BgkTlcae7 literal 0 HcmV?d00001 diff --git a/docs/img/bounding_box.png b/docs/img/bounding_box.png new file mode 100644 index 0000000000000000000000000000000000000000..c682bd611492de812ddd350c7bcb54aa5a539469 GIT binary patch literal 68235 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 z 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 NNQ%mdR0-(^{2xX-bb9~* literal 0 HcmV?d00001 diff --git a/environment.yml b/environment.yml new file mode 100644 index 0000000..a8bac29 --- /dev/null +++ b/environment.yml @@ -0,0 +1,10 @@ +name: modcon23-contest +channels: + - defaults +dependencies: + - python=3.11 + - ipykernel + - numpy + - pip + - pip: + - git+https://github.com/guidorice/mojo-pytest.git@v0.2.0 diff --git a/mojo_impl/__init__.mojo b/mojo_impl/__init__.mojo new file mode 100644 index 0000000..e69de29 diff --git a/mojo_impl/naive.mojo b/mojo_impl/naive.mojo new file mode 100644 index 0000000..5bec603 --- /dev/null +++ b/mojo_impl/naive.mojo @@ -0,0 +1,66 @@ +import benchmark +from math.limit import inf, neginf +from random import rand +from sys import argv +from tensor import Tensor, TensorSpec +from utils.index import Index + +fn envelope[dtype: DType, dims: Int](tensor: Tensor[dtype]) -> SIMD[dtype, 2 * dims]: + """ + Calculate envelope: iterative, plain mojo code. Uses static types and a stdlib numeric container type (Tensor). + """ + + @parameter + constrained[dims > 0 and dims % 2 == 0, "power-of-two dims only"]() + + let NegInf = neginf[dtype]() + let Inf = inf[dtype]() + let num_features = tensor.shape()[1] + var result = SIMD[dtype, 2 * dims]() + + for d in range(dims): + result[d] = Inf + + for d in range(dims, 2 * dims): + result[d] = NegInf + + for y in range(dims): + for x in range(num_features): + let val = tensor[Index(y, x)] + if val < result[y]: + result[y] = val + if val > result[dims + y]: + result[dims + y] = val + + return result + +alias dtype = DType.float32 +alias dims = 2 + +fn main() raises: + """ + Usage: `mojo naive.mojo {n}` , where n is an integer number of features. + """ + + # read number of features + let width = atol(argv()[1]) + + # create a tensor, filled with random values + print(dtype, width) + let spec = TensorSpec(dtype, dims, width) + let tensor = rand[dtype](spec) + + # run bechmark module + @parameter + fn envelope_worker(): + _ = envelope[dtype, dims](tensor) + + let mojo_report = benchmark.run[envelope_worker]() + mojo_report.print() + let secs = mojo_report.mean["s"]() + let ns = mojo_report.mean["ns"]() + let ms = mojo_report.mean["ms"]() + print("ns:", ns) + print("microsecs:", secs * 10 ** 6) + print("ms:", ms) + print("s:", secs) diff --git a/mojo_impl/optimized_a.mojo b/mojo_impl/optimized_a.mojo new file mode 100644 index 0000000..978a913 --- /dev/null +++ b/mojo_impl/optimized_a.mojo @@ -0,0 +1,79 @@ +import benchmark +from algorithm import vectorize +from math.limit import inf, neginf +from random import rand +from sys import argv +from sys.info import simdbitwidth +from tensor import Tensor, TensorSpec +from utils.index import Index + +alias nelts = simdbitwidth() + +fn envelope[dtype: DType, dims: Int](tensor: Tensor[dtype]) -> SIMD[dtype, dims * 2]: + """ + Calculate envelope: vectorized, unrolled, single-threaded. + """ + + @parameter + constrained[dims > 0 and dims % 2 == 0, "power-of-two dims only"]() + + let NegInf = neginf[dtype]() + let Inf = inf[dtype]() + let num_features = tensor.shape()[1] + var result = SIMD[dtype, dims * 2]() + + @unroll + for d in range(dims): + result[d] = Inf + + @unroll + for d in range(dims, 2 * dims): + result[d] = NegInf + + @unroll + for dim in range(dims): + @parameter + fn min_max_simd[simd_width: Int](feature_idx: Int): + let index = Index(dim, feature_idx) + let vals = tensor.simd_load[simd_width](index) + let min = vals.reduce_min() + if min < result[dim]: + result[dim] = min + let max = vals.reduce_max() + if max > result[dims + dim]: + result[dims + dim] = max + vectorize[nelts, min_max_simd](num_features) + + return result + + +alias dtype = DType.float32 +alias dims = 2 + + +fn main() raises: + """ + Usage: `mojo optimized_a.mojo {n}` , where n is an integer number of features. + """ + # read number of features + let width = atol(argv()[1]) + + # create a tensor, filled with random values + print(dtype, width) + let spec = TensorSpec(dtype, dims, width) + let tensor = rand[dtype](spec) + + # run bechmark module + @parameter + fn envelope_worker(): + _ = envelope[dtype, dims](tensor) + + let mojo_report = benchmark.run[envelope_worker]() + mojo_report.print() + let secs = mojo_report.mean["s"]() + let ns = mojo_report.mean["ns"]() + let ms = mojo_report.mean["ms"]() + print("ns:", ns) + print("microsecs:", secs * 10 ** 6) + print("ms:", ms) + print("s:", secs) diff --git a/mojo_impl/optimized_b.mojo b/mojo_impl/optimized_b.mojo new file mode 100644 index 0000000..8834dd9 --- /dev/null +++ b/mojo_impl/optimized_b.mojo @@ -0,0 +1,82 @@ +import benchmark +from algorithm import vectorize +from algorithm.functional import parallelize +from math.limit import inf, neginf +from random import rand +from sys import argv +from sys.info import simdbitwidth +from tensor import Tensor, TensorSpec +from utils.index import Index + +alias nelts = simdbitwidth() + +fn envelope[dtype: DType, dims: Int](tensor: Tensor[dtype]) -> SIMD[dtype, 2 * dims]: + """ + Calculate envelope: parallelized, vectorized, unrolled. + """ + @parameter + constrained[dims > 0 and dims % 2 == 0, "power-of-two dims only"]() + + let NegInf = neginf[dtype]() + let Inf = inf[dtype]() + let num_features = tensor.shape()[1] + + var result = SIMD[dtype, 2 * dims]() + + @unroll + for d in range(dims): + result[d] = Inf + + @unroll + for d in range(dims, 2 * dims): + result[d] = NegInf + + @parameter + fn min_max_task(dim: Int): + @parameter + fn min_max_simd[simd_width: Int](feature_idx: Int): + let index = Index(dim, feature_idx) + let vals = tensor.simd_load[simd_width](index) + let min = vals.reduce_min() + if min < result[dim]: + result[dim] = min + let max = vals.reduce_max() + if max > result[dims + dim]: + result[dims + dim] = max + + vectorize[nelts, min_max_simd](num_features) + + parallelize[min_max_task](dims) + + return result + +alias dtype = DType.float32 +alias dims = 2 + +fn main() raises: + """ + Usage: `mojo optimized_b.mojo {n}` , where n is an integer number of features. + """ + + # read number of features + var width = atol(argv()[1]) + print(dtype, width) + + # create a tensor, filled with random values + let spec = TensorSpec(dtype, dims, width) + let tensor = rand[dtype](spec) + + # run bechmark module + @parameter + fn envelope_worker(): + _ = envelope[dtype, dims](tensor) + + let mojo_report = benchmark.run[envelope_worker]() + mojo_report.print() + let secs = mojo_report.mean["s"]() + let ns = mojo_report.mean["ns"]() + let ms = mojo_report.mean["ms"]() + print("ns:", ns) + print("microsecs:", secs * 10 ** 6) + print("ms:", ms) + print("s:", secs) diff --git a/mojo_impl/tests/__init__.mojo b/mojo_impl/tests/__init__.mojo new file mode 100644 index 0000000..e69de29 diff --git a/mojo_impl/tests/test_impls.mojo b/mojo_impl/tests/test_impls.mojo new file mode 100644 index 0000000..0131631 --- /dev/null +++ b/mojo_impl/tests/test_impls.mojo @@ -0,0 +1,34 @@ +from random import rand +from sys import argv +from tensor import Tensor, TensorSpec +from math.limit import inf, neginf + +from mojo_impl.tests.util import MojoTest +from mojo_impl.naive import envelope as envelope_naive +from mojo_impl.optimized_a import envelope as envelope_opt_a +from mojo_impl.optimized_b import envelope as envelope_opt_b + +alias dtype = DType.float32 +alias dims = 2 +alias width = 1000 + + +fn main() raises: + test_naive_mojo_impls() + + +fn test_naive_mojo_impls(): + let test = MojoTest("mojo implementations are all consistent") + + # create a tensor, filled with random values + let spec = TensorSpec(dtype, dims, width) + let tensor = rand[dtype](spec) + + # check the 3 mojo implementations all return the same value + let result_naive = envelope_naive[dtype, dims](tensor) + + let result_opt_a = envelope_opt_a[dtype, dims](tensor) + test.assert_true(result_naive == result_opt_a, "naive == envelope_opt_a") + + let result_opt_b = envelope_opt_b[dtype, dims](tensor) + test.assert_true(result_naive == result_opt_b, "naive == envelope_opt_b") diff --git a/mojo_impl/tests/util.mojo b/mojo_impl/tests/util.mojo new file mode 100644 index 0000000..4398fda --- /dev/null +++ b/mojo_impl/tests/util.mojo @@ -0,0 +1,20 @@ +import testing + + +@value +struct MojoTest: + """ + A utility struct for testing. + """ + + var test_name: String + + fn __init__(inout self, test_name: String): + self.test_name = test_name + print("# " + test_name) + + fn assert_true(self, cond: Bool, message: String): + """ + Wraps testing.assert_true. + """ + _ = testing.assert_true(cond, message) diff --git a/py_impl/__init__.py b/py_impl/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/py_impl/naive.py b/py_impl/naive.py new file mode 100644 index 0000000..88be973 --- /dev/null +++ b/py_impl/naive.py @@ -0,0 +1,27 @@ +from math import inf +import numpy as np + + +def envelope(x_coords: list[float], y_coords: list[float]) -> list[float]: + """ + Calculate envelope with iterative, plain python code. + """ + assert len(x_coords) == len(y_coords) + + result: list[float] = [inf, inf, -inf, -inf] + + for i in range(len(x_coords)): + x = x_coords[i] + y = y_coords[i] + + if x < result[0]: + result[0] = x + if y < result[1]: + result[1] = y + + if x > result[2]: + result[2] = x + if y > result[3]: + result[3] = y + + return result diff --git a/py_impl/naive_benchmark.ipynb b/py_impl/naive_benchmark.ipynb new file mode 100644 index 0000000..5b9173e --- /dev/null +++ b/py_impl/naive_benchmark.ipynb @@ -0,0 +1,163 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from naive import envelope" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "multipoint_10_2 = np.array(np.random.rand(2, 10 ** 2), dtype=np.float32)\n", + "multipoint_10_3 = np.array(np.random.rand(2, 10 ** 3), dtype=np.float32)\n", + "multipoint_10_4 = np.array(np.random.rand(2, 10 ** 4), dtype=np.float32)\n", + "multipoint_10_5= np.array(np.random.rand(2, 10 ** 5), dtype=np.float32)\n", + "multipoint_10_6 = np.array(np.random.rand(2, 10 ** 6), dtype=np.float32)\n", + "multipoint_10_7 = np.array(np.random.rand(2, 10 ** 7), dtype=np.float32)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "13.5 µs ± 183 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "envelope(x_coords=list(multipoint_10_2[0]), y_coords=list(multipoint_10_2[1]))" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "103 µs ± 95 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "envelope(x_coords=list(multipoint_10_3[0]), y_coords=list(multipoint_10_3[1]))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 ms ± 6.2 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "envelope(x_coords=list(multipoint_10_4[0]), y_coords=list(multipoint_10_4[1]))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10.5 ms ± 132 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "envelope(x_coords=list(multipoint_10_5[0]), y_coords=list(multipoint_10_5[1]))" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "109 ms ± 399 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "envelope(x_coords=list(multipoint_10_6[0]), y_coords=list(multipoint_10_6[1]))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.09 s ± 2.14 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "envelope(x_coords=list(multipoint_10_7[0]), y_coords=list(multipoint_10_7[1]))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/py_impl/optimized_benchmark.ipynb b/py_impl/optimized_benchmark.ipynb new file mode 100644 index 0000000..7454b88 --- /dev/null +++ b/py_impl/optimized_benchmark.ipynb @@ -0,0 +1,163 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from optimized_numpy import envelope" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "multipoint_10_2 = np.array(np.random.rand(2, 10 ** 2), dtype=np.float32)\n", + "multipoint_10_3 = np.array(np.random.rand(2, 10 ** 3), dtype=np.float32)\n", + "multipoint_10_4 = np.array(np.random.rand(2, 10 ** 4), dtype=np.float32)\n", + "multipoint_10_5= np.array(np.random.rand(2, 10 ** 5), dtype=np.float32)\n", + "multipoint_10_6 = np.array(np.random.rand(2, 10 ** 6), dtype=np.float32)\n", + "multipoint_10_7 = np.array(np.random.rand(2, 10 ** 7), dtype=np.float32)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2.84 µs ± 21.6 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "envelope(multipoint_10_2)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3.09 µs ± 57.9 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "envelope(multipoint_10_3)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4.14 µs ± 10.2 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "envelope(multipoint_10_4)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "22.5 µs ± 62.3 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "envelope(multipoint_10_5)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "195 µs ± 229 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "envelope(multipoint_10_6)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2.64 ms ± 16.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "envelope(multipoint_10_7)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/py_impl/optimized_numpy.py b/py_impl/optimized_numpy.py new file mode 100644 index 0000000..18e9115 --- /dev/null +++ b/py_impl/optimized_numpy.py @@ -0,0 +1,12 @@ +import numpy as np + + +def envelope(arr: np.array) -> list[float]: + """ + Calculate envelope with numpy, 'the fundamental package for scientific computing with Python'. + """ + xmin = arr[0].min() + xmax = arr[0].max() + ymin = arr[1].min() + ymax = arr[1].max() + return [xmin, ymin, xmax, ymax] diff --git a/py_impl/tests/__init__.py b/py_impl/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/py_impl/tests/test_impls.py b/py_impl/tests/test_impls.py new file mode 100644 index 0000000..ced0b7b --- /dev/null +++ b/py_impl/tests/test_impls.py @@ -0,0 +1,17 @@ +import numpy as np + +from ..naive import envelope as envelope_naive +from ..optimized_numpy import envelope as envelope_numpy + + +def test_python_impls(): + """ + Test the python implementations are consistent. + """ + multipoint_10_3 = np.array(np.random.rand(2, 10**3), dtype=np.float32) + + result_naive = envelope_naive( + x_coords=list(multipoint_10_3[0]), y_coords=list(multipoint_10_3[1]) + ) + result_numpy = envelope_numpy(multipoint_10_3) + assert result_naive == result_numpy