Package: energymon
EnergyMon Python BindingsThis project provides Python bindings toenergymonlibraries.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[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}}DependenciesTheenergymonlibraries should be installed to the system and on the library search path (e.g.,LD_LIBRARY_PATHon Linux/POSIX systems orDYLD_LIBRARY_PATHon macOS systems).The latestenergymonC libraries can be found athttps://github.com/energymon/energymon.InstallingVersioned releases of theenergymonpackage are published in the Python Package Index and installable with pip:pipinstallenergymonand through Conda Forge:condainstallenergymonTo install from source:pipinstall.UsageThe following subsections document usage with increasing levels of abstraction.Direct BindingsAt the lowest level, theenergymonpackage exposes anenergymonclass, which is a binding to theenergymonC 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:fromctypesimportCDLL,byref,create_string_buffer,sizeof,set_errno,get_errnofromctypes.utilimportfind_libraryfromenergymonimportenergymon# try to find the library by name:lib_path=find_library('energymon-default')iflib_pathisNone:# maybe fall back on a relative or absolute pathlib_path='libenergymon-default.so'lib=CDLL(lib_path,use_errno=True)em=energymon()iflib.energymon_get_default(byref(em))!=0:# handle error...exit(1)name=create_string_buffer(256)ifnotem.fsource(name,sizeof(name)):# handle errorexit(1)print(name.value.decode())ifem.finit(byref(em))!=0:# handle errorexit(1)set_errno(0)uj=em.fread(byref(em))ifuj==0andget_errno()!=0:# handle error (but don't skip cleanup!)passifem.ffinish(byref(em))!=0:# handle errorexit(1)Utility FunctionsUtility functions work with the direct bindings, but simplify their usage by (1) abstracting the user from the Pythonctypes(including pointers) and (2) raising exceptions when errors are reported by the native library.
For example, to load theenergymon-defaultlibrary, "get" the energymon, and report the energy source and current value:fromenergymonimportutillib=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 ManagementThecontextsubmodule provides theEnergyMonclass, which is both a wrapper aroundenergymonbindings and a Python context manager.
As a context manager, the class handles theenergymonlifecycle, and is both reentrant and reusable.
For example, to use as a context manager:fromenergymon.contextimportEnergyMonwithEnergyMon()asem:print('source:',em.get_source())print('reading (uJ):',em.get_uj())Alternatively, you can manage the lifecycle yourself withem.init()andem.finish()(instead of usingwith ...).
Take care to handle exceptions, including correct lifecycle management if not using the automatic context management.Project SourceFind this and related project sources at theenergymon organization on GitHub.This project originates at:https://github.com/energymon/energymon-pyBug reports and pull requests for bug fixes and enhancements are welcome.