Skip to content

perf(hafnian): Replace implementation#291

Merged
Kolarovszki merged 1 commit into
mainfrom
kz-hafnian
Apr 3, 2024
Merged

perf(hafnian): Replace implementation#291
Kolarovszki merged 1 commit into
mainfrom
kz-hafnian

Conversation

@Kolarovszki

@Kolarovszki Kolarovszki commented Apr 3, 2024

Copy link
Copy Markdown
Collaborator

Problem

The PiquassoBoost version of the (loop)hafnian is very efficient, but the implementation in Piquasso itself is not, the performance gap is large between the two implementations.

Solution

An efficient version of the (loop)hafnian function got implemented using Numba and the PiquassoBoost code translated from C++ to Python. The power trace algorithm has been copied using Glynn-type iterations, which is enabled by default in PiquassoBoost. Of course, this does not replace the PiquassoBoost implementation, only narrows the performance gap between the two, to provide relatively fast (loop)hafnian calculations without the need of installing PiquassoBoost.

numba is added as a dependency.

The piquasso/_math/hafnian folder is ignored in Codecov, since it cou
ld not track code compiled with Numba.

@codecov

codecov Bot commented Apr 3, 2024

Copy link
Copy Markdown

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 95.28%. Comparing base (7a37d25) to head (74221de).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #291      +/-   ##
==========================================
- Coverage   95.41%   95.28%   -0.13%     
==========================================
  Files          61       60       -1     
  Lines        3356     3266      -90     
==========================================
- Hits         3202     3112      -90     
  Misses        154      154              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

**Problem**

The PiquassoBoost version of the (loop)hafnian is very efficient, but the
implementation in Piquasso itself is not, the performance gap is large between
the two implementations.

**Solution**

An efficient version of the (loop)hafnian function got implemented using Numba
and the PiquassoBoost code translated from C++ to Python. The power trace
algorithm has been copied using Glynn-type iterations, which is enabled by
default in PiquassoBoost. Of course, this does not replace the PiquassoBoost
implementation, only narrows the performance gap between the two, to provide
relatively fast (loop)hafnian calculations without the need of installing
PiquassoBoost.

`numba` is added as a dependency.

The `piquasso/_math/hafnian` folder is ignored in Codecov, since it could not track code compiled with Numba.
@Kolarovszki Kolarovszki merged commit a2cb114 into main Apr 3, 2024
Kolarovszki pushed a commit that referenced this pull request Nov 3, 2025
…to >=4.0,<5.3 (#532)

Updates the requirements on
[pytest-benchmark](https://github.com/ionelmc/pytest-benchmark) to
permit the latest version.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/ionelmc/pytest-benchmark/blob/master/CHANGELOG.rst">pytest-benchmark's
changelog</a>.</em></p>
<blockquote>
<h2>5.2.0 (2025-10-30)</h2>
<ul>
<li>Added support for a per-round <code>teardown</code> function to
pedantic mode.
Contributed Patrick Winter by
<code>[#264](ionelmc/pytest-benchmark#264)
&lt;https://github.com/ionelmc/pytest-benchmark/pull/264&gt;</code>_.</li>
<li>Added <code>--benchmark-time-unit</code> option.
Contributed by Tony Kuo in
<code>[#281](ionelmc/pytest-benchmark#281)
&lt;https://github.com/ionelmc/pytest-benchmark/pull/281&gt;</code>_.</li>
<li>Fixed deprecated hook examples in docstrings.
Contributed by Ali-Akber Saifee in
<code>[#284](ionelmc/pytest-benchmark#284)
&lt;https://github.com/ionelmc/pytest-benchmark/pull/284&gt;</code>_.</li>
<li>Changed <code>--benchmark-compare-fail</code> to accept percentages
higher than 100%.
Contributed by Ben Avrahami in
<code>[#290](ionelmc/pytest-benchmark#290)
&lt;https://github.com/ionelmc/pytest-benchmark/pull/280&gt;</code>_.</li>
<li>Added minimal typing support.
Contributed by Sorin Sbarnea in
<code>[#290](ionelmc/pytest-benchmark#290)
&lt;https://github.com/ionelmc/pytest-benchmark/pull/290&gt;</code>_.</li>
<li>Fixed support for Python 3.9.
Contributed by Enno Gotthold in
<code>[#291](ionelmc/pytest-benchmark#291)
&lt;https://github.com/ionelmc/pytest-benchmark/pull/291&gt;</code>_.</li>
<li>Replaced the complicated and broken code of
<code>pytest_benchmark.utils.clonefunc</code> with a simple return of
the input.
That function was supposed to allow benchmarking with the cost of PyPy
JIT included but it's a hassle to maintain.</li>
<li>Moved the instrumentation pause outside the round loops (in addition
to tracing, profiling is paused too).
Pedantic mode will keep doing this per round (as the user manually
controls the round count).
This is necessary because in some scenarios setting and unsetting the
tracer too much will overflow an internal counter
(found to cause &quot;OverflowError: events set too many times&quot; at
least on Python 3.13).</li>
</ul>
<h2>5.1.0 (2024-10-30)</h2>
<ul>
<li>Fixed broken hooks handling on pytest 8.1 or later (the
<code>TypeError: import_path() missing 1 required keyword-only argument:
'consider_namespace_packages'</code> issue).
Unfortunately this sets the minimum supported pytest version to
8.1.</li>
</ul>
<h2>5.0.1 (2024-10-30)</h2>
<ul>
<li>Fixed bad fixture check that broke down then <code>nbmake
&lt;https://pypi.org/project/nbmake/&gt;</code>_ was enabled.</li>
</ul>
<h2>5.0.0 (2024-10-29)</h2>
<ul>
<li>
<p>Dropped support for now EOL Python 3.8. Also moved tests suite to
only test the latest pytest versions (8.3.x).</p>
</li>
<li>
<p>Fix generate parametrize tests benchmark csv report errors (issue
<code>[#268](ionelmc/pytest-benchmark#268)
&lt;https://github.com/ionelmc/pytest-benchmark/issues/268&gt;</code><em>).
Contributed by Johnny Huang in
<code>[#269](ionelmc/pytest-benchmark#269)
&lt;https://github.com/ionelmc/pytest-benchmark/pull/269&gt;</code></em>.</p>
</li>
<li>
<p>Added the <code>--benchmark-time-unit</code> cli option for
overriding the measurement unit used for display.
Contributed by Tony Kuo in
<code>[#257](ionelmc/pytest-benchmark#257)
&lt;https://github.com/ionelmc/pytest-benchmark/pull/257&gt;</code>_.</p>
</li>
<li>
<p>Fixes spelling in some help texts.
Contributed by Eugeniy in
<code>[#267](ionelmc/pytest-benchmark#267)
&lt;https://github.com/ionelmc/pytest-benchmark/pull/267&gt;</code>_.</p>
</li>
<li>
<p>Added new cprofile options:</p>
<ul>
<li><code>--benchmark-cprofile-loops=LOOPS</code> - previously profiling
only ran the function once, this allow customization.</li>
<li><code>--benchmark-cprofile-top=COUNT</code> - allows showing more
rows.</li>
<li><code>--benchmark-cprofile-dump=[FILENAME-PREFIX]</code> - allows
saving to a file (that you can load in <code>snakeviz
&lt;https://pypi.org/project/snakeviz/&gt;</code><em>, <code>RunSnakeRun
&lt;https://pypi.org/project/RunSnakeRun/&gt;</code></em> or other
tools).</li>
</ul>
</li>
<li>
<p>Removed hidden dependency on <code>py.path
&lt;https://pypi.org/project/py/&gt;</code>_ (replaced with
pathlib).</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/ionelmc/pytest-benchmark/commit/5a164cec3b7290e30c38cb4ea32ac4e1be65ec87"><code>5a164ce</code></a>
Bump version: 5.1.0 → 5.2.0</li>
<li><a
href="https://github.com/ionelmc/pytest-benchmark/commit/abfb09bab2c1655e269254c10ed54fc5f8146c0d"><code>abfb09b</code></a>
Reword the last 2 changes.</li>
<li><a
href="https://github.com/ionelmc/pytest-benchmark/commit/f8c081b2aec1ee295b4bfa20e03bdd46d6a9804f"><code>f8c081b</code></a>
Bump hooks and fix mypy complaint.</li>
<li><a
href="https://github.com/ionelmc/pytest-benchmark/commit/604c2e7ee470fffe1e4a70664309d0c52029a591"><code>604c2e7</code></a>
Replace all the manual tracer unset/restore with a context manager, and
move ...</li>
<li><a
href="https://github.com/ionelmc/pytest-benchmark/commit/0e247fd6f651c8d8e8d04f4606d0c27b6e417c7e"><code>0e247fd</code></a>
Do not unset/set the tracer/profiler if there's no previous one.</li>
<li><a
href="https://github.com/ionelmc/pytest-benchmark/commit/64ae56d32b1a17fcbfccc6d2dc088cd237c9eea5"><code>64ae56d</code></a>
Rename to match convention from cprofile mode.</li>
<li><a
href="https://github.com/ionelmc/pytest-benchmark/commit/347d84d152f6cc334f0cb0a7671e1600ab2bb6c0"><code>347d84d</code></a>
Also disable other profiler.</li>
<li><a
href="https://github.com/ionelmc/pytest-benchmark/commit/68687926c06c972a5d3f04fe5ce24ddd6329a1bc"><code>6868792</code></a>
Make cprofile mode disable tracers, just like regular bench mode. Should
make...</li>
<li><a
href="https://github.com/ionelmc/pytest-benchmark/commit/8e735b23798cc8cf59239f2a0e1f063b5b81e66b"><code>8e735b2</code></a>
Nuke the now-broken clonefunc with a identity function. It's currently
broken...</li>
<li><a
href="https://github.com/ionelmc/pytest-benchmark/commit/cecc6ef394adde005ce23b8734bbc1d0ef4dc267"><code>cecc6ef</code></a>
Fix some badges.</li>
<li>Additional commits viewable in <a
href="https://github.com/ionelmc/pytest-benchmark/compare/v4.0.0...v5.2.0">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant