diff --git a/5396e439e2cc40d95a20bd829134096c12fc2286.patch b/5396e439e2cc40d95a20bd829134096c12fc2286.patch new file mode 100644 index 0000000..110acda --- /dev/null +++ b/5396e439e2cc40d95a20bd829134096c12fc2286.patch @@ -0,0 +1,137 @@ +From 5396e439e2cc40d95a20bd829134096c12fc2286 Mon Sep 17 00:00:00 2001 +From: Brad Geltz +Date: Tue, 27 Jan 2026 12:27:12 -0800 +Subject: [PATCH] Update usage of DataFrame.to_hdf + +- Starting with Pandas v3.0.0 the most paremeters are + keyword-only. + +Signed-off-by: Brad Geltz +--- + geopmpy/geopmpy/io.py | 26 +++++++++++-------- + .../experiment/ffnet/gen_hdf_from_fsweep.py | 4 +-- + .../sst_evaluation/gen_plot_time.py | 8 +++--- + 3 files changed, 21 insertions(+), 17 deletions(-) + +diff --git a/geopmpy/geopmpy/io.py b/geopmpy/geopmpy/io.py +index b7ecc567a5..4fb7f7dfd9 100644 +--- a/geopmpy/geopmpy/io.py ++++ b/geopmpy/geopmpy/io.py +@@ -25,7 +25,7 @@ + if os.getenv('GEOPM_USE_UNSAFE_HDF5') is not None: + from pandas import read_hdf + else: +- def read_hdf(path, name): ++ def read_hdf(path, key=None, **kwargs): + if not os.path.exists(path): + raise IOError(f'Trace HDF5 file {path} not detected') + raise ImportWarning('Refusing to read HDF5 format files: file format could result in arbitrary code execution. To enable "export GEOPM_USE_UNSAFE_HDF5=1"') +@@ -111,7 +111,7 @@ def __init__(self, traces=None, dir_name='.', verbose=False, do_cache=True): + + do_load_raw = True + try: +- self._traces_df = read_hdf(trace_h5_name, 'trace') ++ self._traces_df = read_hdf(trace_h5_name, key='trace') + do_load_raw = False + if verbose: + sys.stdout.write(f'Loaded traces from {trace_h5_name}.\n') +@@ -125,7 +125,7 @@ def __init__(self, traces=None, dir_name='.', verbose=False, do_cache=True): + try: + if verbose: + sys.stdout.write('Generating HDF5 files... ') +- self._traces_df.to_hdf(trace_h5_name, 'trace') ++ self._traces_df.to_hdf(trace_h5_name, key='trace') + except ImportError as error: + sys.stderr.write(f'Warning: geopmpy.io: Unable to write HDF5 file: {error}\n') + +@@ -878,16 +878,16 @@ def load_reports(self, reports, dir_name, dir_cache, verbose, do_cache): + sys.stdout.write('Attempting to read {}...\n'.format(self._report_h5_name)) + # load dataframes from cache + try: +- self._reports_df = read_hdf(self._report_h5_name, 'report') ++ self._reports_df = read_hdf(self._report_h5_name, key='report') + except KeyError: + pass # No regions in cached report +- self._app_reports_df = read_hdf(self._report_h5_name, 'app_report') ++ self._app_reports_df = read_hdf(self._report_h5_name, key='app_report') + try: +- self._unmarked_reports_df = read_hdf(self._report_h5_name, 'unmarked_report') ++ self._unmarked_reports_df = read_hdf(self._report_h5_name, key='unmarked_report') + except KeyError: + pass + try: +- self._epoch_reports_df = read_hdf(self._report_h5_name, 'epoch_report') ++ self._epoch_reports_df = read_hdf(self._report_h5_name, key='epoch_report') + except KeyError: + pass + if verbose: +@@ -902,19 +902,23 @@ def load_reports(self, reports, dir_name, dir_cache, verbose, do_cache): + + # Cache report dataframe + cache_created = False ++ did_fixup_metadata = False + while not cache_created: + try: + if verbose: + sys.stdout.write('Generating HDF5 files... ') +- self._app_reports_df.to_hdf(self._report_h5_name, 'app_report', format='table') ++ self._app_reports_df.to_hdf(self._report_h5_name, key='app_report', format='table') + if len(self._reports_df) > 0: +- self._reports_df.to_hdf(self._report_h5_name, 'report', format='table', append=True) ++ self._reports_df.to_hdf(self._report_h5_name, key='report', format='table', append=True) + if len(self._unmarked_reports_df) > 0: +- self._unmarked_reports_df.to_hdf(self._report_h5_name, 'unmarked_report', format='table', append=True) ++ self._unmarked_reports_df.to_hdf(self._report_h5_name, key='unmarked_report', format='table', append=True) + if len(self._epoch_reports_df) > 0: +- self._epoch_reports_df.to_hdf(self._report_h5_name, 'epoch_report', format='table', append=True) ++ self._epoch_reports_df.to_hdf(self._report_h5_name, key='epoch_report', format='table', append=True) + cache_created = True + except TypeError as error: ++ if did_fixup_metadata: ++ raise ++ did_fixup_metadata = True + fm = RawReportCollection.fixup_metadata + if verbose: + sys.stdout.write('Applying workaround for strings in HDF5 files... ') +diff --git a/integration/experiment/ffnet/gen_hdf_from_fsweep.py b/integration/experiment/ffnet/gen_hdf_from_fsweep.py +index 770d30bd6b..4817af6321 100755 +--- a/integration/experiment/ffnet/gen_hdf_from_fsweep.py ++++ b/integration/experiment/ffnet/gen_hdf_from_fsweep.py +@@ -148,7 +148,7 @@ + + pd \ + .concat(reports_dfs, ignore_index=True) \ +- .to_hdf(f"{output_prefix}_stats.h5", "stats", mode='w') ++ .to_hdf(f"{output_prefix}_stats.h5", key="stats", mode='w') + + #Creating trace hdf for training neural net, annotated with region hashes or + #generated region names when hashes are not available +@@ -158,7 +158,7 @@ + + pd \ + .concat(trace_dfs, ignore_index=True) \ +- .to_hdf(f"{output_prefix}_traces.h5", "traces", mode='w') ++ .to_hdf(f"{output_prefix}_traces.h5", key="traces", mode='w') + + + if __name__ == "__main__": +diff --git a/integration/experiment/sst_evaluation/gen_plot_time.py b/integration/experiment/sst_evaluation/gen_plot_time.py +index a75ca48f0c..ea0ee479aa 100755 +--- a/integration/experiment/sst_evaluation/gen_plot_time.py ++++ b/integration/experiment/sst_evaluation/gen_plot_time.py +@@ -267,11 +267,11 @@ def reports_and_traces_to_dataframes(report_paths): + except OSError: + # Write the preprocessed data to a cached file + df, frequency_df, epoch_df, core_frequencies_by_time_df = reports_and_traces_to_dataframes(args.report_paths) +- df.to_hdf(os.path.join(args.analysis_dir, 'cache.hdf'), 'df', 'w') +- frequency_df.to_hdf(os.path.join(args.analysis_dir, 'cache.hdf'), 'frequency_df', 'a') +- epoch_df.to_hdf(os.path.join(args.analysis_dir, 'cache.hdf'), 'epoch_df', 'a') ++ df.to_hdf(os.path.join(args.analysis_dir, 'cache.hdf'), key='df', mode='w') ++ frequency_df.to_hdf(os.path.join(args.analysis_dir, 'cache.hdf'), key='frequency_df', mode='a') ++ epoch_df.to_hdf(os.path.join(args.analysis_dir, 'cache.hdf'), key='epoch_df', mode='a') + core_frequencies_by_time_df.to_hdf(os.path.join(args.analysis_dir, 'cache.hdf'), +- 'core_frequencies_by_time_df', 'a') ++ key='core_frequencies_by_time_df', mode='a') + + df['Application'] = df['Application'].str.rsplit('_', 1).str[-1] + epoch_df['Application'] = epoch_df['Application'].str.rsplit('_', 1).str[-1] diff --git a/python-geopmpy.spec b/python-geopmpy.spec index 4029d99..722a9bf 100644 --- a/python-geopmpy.spec +++ b/python-geopmpy.spec @@ -1,4 +1,3 @@ -%global debug_package %{nil} %global prj_name geopmpy %global desc %{expand: \ The Global Extensible Open Power Manager (GEOPM) provides a framework to @@ -10,7 +9,7 @@ optimize system hardware settings to achieve energy efficiency and/or performance objectives.} Name: python-%{prj_name} -Version: 3.1.0 +Version: 3.2.2 Release: %autorelease Summary: Python bindings for libgeopm @@ -18,17 +17,16 @@ License: BSD-3-Clause URL: https://geopm.github.io Source0: https://github.com/geopm/geopm/archive/v%{version}/geopm-%{version}.tar.gz +# Update usage of DataFrame.to_hdf +# https://github.com/geopm/geopm/commit/5396e439e2cc40d95a20bd829134096c12fc2286 +Patch0: 5396e439e2cc40d95a20bd829134096c12fc2286.patch + ExclusiveArch: x86_64 +BuildRequires: gcc BuildRequires: python3-devel -BuildRequires: python3-setuptools -BuildRequires: python3-geopmdpy -BuildRequires: python3-pandas -BuildRequires: python3-natsort -BuildRequires: python3-pyyaml -BuildRequires: python3-tables -BuildRequires: libgeopm-devel -BuildRequires: libgeopmd-devel +BuildRequires: libgeopm-devel >= 3.2.2 +BuildRequires: libgeopmd-devel >= 3.2.2 Requires: geopmd %description @@ -41,32 +39,30 @@ Summary: %{summary} %{desc} %prep -%autosetup -n geopm-%{version} +%autosetup -p1 -n geopm-%{version} +echo %{version} > %{prj_name}/%{prj_name}/VERSION -pushd %{prj_name} -echo %{version} > %{prj_name}/VERSION -popd +%generate_buildrequires +cd %{prj_name} +%pyproject_buildrequires %build -pushd %{prj_name} -%py3_build -popd +cd %{prj_name} +%pyproject_wheel %install -pushd %{prj_name} -%py3_install -popd +cd %{prj_name} +%pyproject_install +%pyproject_save_files %{prj_name} %check -pushd %{prj_name} -%{python3} -m unittest discover -p 'Test*.py' -v -popd +cd %{prj_name} +%{python3} -m unittest discover -s test -p 'Test*.py' -v -%files -n python3-%{prj_name} +%files -n python3-%{prj_name} -f %{pyproject_files} %license LICENSE-BSD-3-Clause %doc README.md -%{python3_sitelib}/%{prj_name} -%{python3_sitelib}/%{prj_name}-*.egg-info +%{python3_sitearch}/_libgeopm_py_cffi.abi3*.so %{_bindir}/geopmlaunch %changelog diff --git a/sources b/sources index 94a95f9..01816e4 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (geopm-3.1.0.tar.gz) = e0446d7e330a8a7ecbdfb89dc98e707364b07168e708805d68dcfa14117fc701658cce7d01c58df0380876acdfb7b3518699900e60d7c7a6cb022001b592717b +SHA512 (geopm-3.2.2.tar.gz) = f4e9d1abc5920cee0a790be89c0dab76fc3bff57276b65106dad963c117c8709945ae72bd93091b247a199d6867f743906ec558174f8743fc7b8906d614f9300