# EnergyMon Python Bindings
[](https://energymon-py.readthedocs.io/en/latest/?badge=latest)
This project provides Python bindings to [energymon](https://github.com/energymon/energymon) libraries.
If using this project for other scientific works or publications, please reference:
* Connor Imes, Lars Bergstrom, and Henry Hoffmann. "A Portable Interface for Runtime Energy Monitoring". In: FSE. 2016. DOI: https://doi.org/10.1145/2950290.2983956
<details>
<summary>[BibTex]</summary>
```BibTex
@inproceedings{imes2016energymon,
author = {Imes, Connor and Bergstrom, Lars and Hoffmann, Henry},
title = {A Portable Interface for Runtime Energy Monitoring},
year = {2016},
isbn = {9781450342186},
publisher = {Association for Computing Machinery},
address = {New York, NY, USA},
url = {https://doi.org/10.1145/2950290.2983956},
doi = {10.1145/2950290.2983956},
booktitle = {Proceedings of the 2016 24th ACM SIGSOFT International Symposium on Foundations of Software Engineering},
pages = {968–974},
numpages = {7},
keywords = {portable energy measurement},
location = {Seattle, WA, USA},
series = {FSE 2016}
}
```
## Dependencies
The `energymon` libraries should be installed to the system and on the library search path (e.g., `LD_LIBRARY_PATH` on Linux/POSIX systems or `DYLD_LIBRARY_PATH` on macOS systems).
The latest `energymon` C libraries can be found at https://github.com/energymon/energymon.
## Installing
Versioned releases of the `energymon` package are published in the Python Package Index and installable with pip:
```sh
pip install energymon
```
To install from source:
```sh
pip install .
```
## Usage
The following subsections document usage with increasing levels of abstraction.
### Direct Bindings
At the lowest level, the `energymon` package exposes an `energymon` class, which is a binding to the `energymon` C struct.
To directly use the energymon API, first load the library, create and "get" the struct to populate its function pointers, then initialize, do work, and cleanup when finished.
For example:
```Python
from ctypes import CDLL, byref, create_string_buffer, sizeof, set_errno, get_errno
from ctypes.util import find_library
from energymon import energymon
# try to find the library by name:
lib_path = find_library('energymon-default')
if lib_path is None:
# maybe fall back on a relative or absolute path
lib_path = 'libenergymon-default.so'
lib = CDLL(lib_path, use_errno=True)
em = energymon()
if lib.energymon_get_default(byref(em)) != 0:
# handle error...
exit(1)
name = create_string_buffer(256)
if not em.fsource(name, sizeof(name)):
# handle error
exit(1)
print(name.value.decode())
if em.finit(byref(em)) != 0:
# handle error
exit(1)
set_errno(0)
uj = em.fread(byref(em))
if uj == 0 and get_errno() != 0:
# handle error (but don't skip cleanup!)
pass
if em.ffinish(byref(em)) != 0:
# handle error
exit(1)
```
### Utility Functions
Utility functions work with the direct bindings, but simplify their usage by (1) abstracting the user from the Python `ctypes` (including pointers) and (2) raising exceptions when errors are reported by the native library.
For example, to load the `energymon-default` library, "get" the energymon, and report the energy source and current value:
```Python
from energymon import util
lib = util.load_energymon_library()
em = util.get_energymon(lib)
print(util.get_source(em))
util.init(em)
try:
print(util.get_uj(em))
finally:
util.finish(em)
```
### Context Management
The `context` submodule provides the `EnergyMon` class, which is both a wrapper around `energymon` bindings and a Python context manager.
As a context manager, the class handles the `energymon` lifecycle, and is both reentrant and reusable.
For example, to use as a context manager:
```Python
from energymon.context import EnergyMon
with EnergyMon() as em:
print('source:', em.get_source())
print('reading (uJ):', em.get_uj())
```
Alternatively, you can manage the lifecycle yourself with `em.init()` and `em.finish()` (instead of using `with ...`).
Take care to handle exceptions, including correct lifecycle management if not using the automatic context management.
## Project Source
Find this and related project sources at the [energymon organization on GitHub](https://github.com/energymon).
This project originates at: https://github.com/energymon/energymon-py
Bug reports and pull requests for bug fixes and enhancements are welcome.