From ec5baa7ef6bfbc14267d9254396713cbb4063cd9 Mon Sep 17 00:00:00 2001 From: Max Lindqvist Date: Thu, 2 Apr 2026 15:47:14 +0200 Subject: [PATCH 1/2] Added a @profile decorator --- src/pylikwid/__init__.py | 33 +++++++++++++++++++++++++++++++++ tests/testmarker.py | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/src/pylikwid/__init__.py b/src/pylikwid/__init__.py index 183e0ad..f2c4bed 100644 --- a/src/pylikwid/__init__.py +++ b/src/pylikwid/__init__.py @@ -1 +1,34 @@ +import functools + from .pylikwid import * + + +def profile(_func=None, *, region_name=None): + """Decorator that wraps a function in a LIKWID marker region. + + Usage:: + + @profile + def my_func(): ... # region name = "my_func" + + @profile(region_name="work") + def my_func(): ... # region name = "work" + """ + def decorator(func): + name = region_name if region_name is not None else func.__name__ + + @functools.wraps(func) + def wrapper(*args, **kwargs): + markerstartregion(name) + try: + return func(*args, **kwargs) + finally: + markerstopregion(name) + + return wrapper + + if _func is not None: + # Used as @profile without parentheses + return decorator(_func) + # Used as @profile(...) with parentheses + return decorator diff --git a/tests/testmarker.py b/tests/testmarker.py index ee6651e..abb3dcb 100755 --- a/tests/testmarker.py +++ b/tests/testmarker.py @@ -26,3 +26,40 @@ def test_marker_region(): assert count >= 0 pylikwid.markerclose() + +def test_profile_decorator(): + pylikwid.markerinit() + pylikwid.markerthreadinit() + + @pylikwid.profile + def my_work(): + return list(range(100_000)) + + result = my_work() + assert len(result) == 100_000 + + nr_events, elist, time, count = pylikwid.markergetregion("my_work") + assert nr_events >= 0 + assert time >= 0 + assert count >= 0 + + pylikwid.markerclose() + + +def test_profile_decorator_with_custom_region_name(): + pylikwid.markerinit() + pylikwid.markerthreadinit() + + @pylikwid.profile(region_name="custom") + def my_work(): + return list(range(100_000)) + + result = my_work() + assert len(result) == 100_000 + + nr_events, elist, time, count = pylikwid.markergetregion("custom") + assert nr_events >= 0 + assert time >= 0 + assert count >= 0 + + pylikwid.markerclose() From 4449e25ca4d2ebbee72afdcef1ab11c2a62767e8 Mon Sep 17 00:00:00 2001 From: Max Lindqvist Date: Mon, 1 Jun 2026 14:12:03 +0200 Subject: [PATCH 2/2] Updated the README --- README.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.rst b/README.rst index cd9f709..2809a62 100644 --- a/README.rst +++ b/README.rst @@ -60,6 +60,9 @@ Marker API command line, this function performs no operation. - ``pylikwid.markerreset(regiontag)``: Reset the values stored using the region name ``regiontag``. On success, 0 is returned. +- ``@pylikwid.profile``: Decorator that wraps a function in a LIKWID marker + region. By default, the function name is used as the region name. It can + also be called with a custom name: ``@pylikwid.profile(region_name="work")``. - ``pylikwid.markerclose()``: Close the connection to the LIKWID Marker API and write out measurement data to file. This file will be evaluated by ``likwid-perfctr``.