Skip to content

Commit e10c804

Browse files
authored
Merge pull request #47 from bernalde/pr-23
Pr 23
2 parents 7920695 + 180ce47 commit e10c804

32 files changed

+819
-16049
lines changed

README.md

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Details of the implementation and an illustrative example for Wishart instances
1818
- [Background](#background)
1919
- [Installation](#installation)
2020
- [Examples](#examples)
21+
- [Testing](#testing)
2122
- [Contributors](#contributors)
2223
- [Acknowledgements](#acknowledgements)
2324
- [License](#license)
@@ -46,8 +47,8 @@ The current package implements the following functionality:
4647

4748
1. **Clone the Repository**:
4849
```bash
49-
git clone https://github.com/usra-riacs/stochastic-benchmarking.git
50-
cd stochastic-benchmarking
50+
git clone https://github.com/usra-riacs/stochastic-benchmark.git
51+
cd stochastic-benchmark
5152
```
5253

5354
2. **Set up a Virtual Environment (Recommended)**:
@@ -64,7 +65,7 @@ The current package implements the following functionality:
6465
### Method 2: Downloading as a Zip Archive
6566

6667
1. **Download the Repository**:
67-
- Navigate to the [stochastic-benchmarking GitHub page](https://github.com/usra-riacs/stochastic-benchmarking).
68+
- Navigate to the [stochastic-benchmark GitHub page](https://github.com/usra-riacs/stochastic-benchmark).
6869
- Click on the `Code` button.
6970
- Choose `Download ZIP`.
7071
- Once downloaded, extract the ZIP archive and navigate to the extracted folder in your terminal or command prompt.
@@ -82,11 +83,36 @@ The current package implements the following functionality:
8283

8384
<!-- the following `pip` command can install this package -->
8485

85-
<!-- ``pip install -i https://test.pypi.org/simple/ stochastic-benchmark==0.0.1`` -->
86+
<!-- ``pip install -i https://test.pypi.org/simple/ stochastic-benchmark==0.1.0`` -->
8687

8788
## Examples
8889

89-
For a full demonstration of the stochastic-benchmarking analysis in action, refer to the example notebooks located in the `examples` folder of this repository.
90+
For a full demonstration of the stochastic-benchmark analysis in action, refer to the example notebooks located in the `examples` folder of this repository.
91+
92+
## Testing
93+
94+
Tests can be executed using the helper script `run_tests.py`. Specify the type of
95+
tests to run along with any optional flags:
96+
97+
```bash
98+
python run_tests.py [unit|integration|smoke|all|coverage] [--verbose] [--fast]
99+
```
100+
101+
Example commands:
102+
103+
- Run the unit test suite:
104+
105+
```bash
106+
python run_tests.py unit
107+
```
108+
109+
- Generate a coverage report:
110+
111+
```bash
112+
python run_tests.py coverage
113+
```
114+
115+
For additional details see [TESTING.md](TESTING.md).
90116

91117
## Contributors
92118
- [@robinabrown](https://github.com/robinabrown) Robin Brown

examples/QAOA_iterative/qaoa_demo.ipynb

Lines changed: 91 additions & 15915 deletions
Large diffs are not rendered by default.

requirements-dev.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-r requirements.txt
2+
pytest
3+
pytest-cov
4+
pytest-xdist

requirements.txt

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
cloudpickle==2.2.0
2-
dill==0.3.5.1
3-
fonttools==4.25.0
4-
future==0.18.3
5-
hyperopt==0.2.7
6-
mkl-service==2.4.0
7-
multiprocess==0.70.13
8-
munkres==1.1.4
9-
networkx==2.8.6
10-
numpy==1.22.0
11-
pandas==1.4.3
12-
seaborn==0.12.0rc0
13-
tqdm==4.66.3
1+
cloudpickle>=2.2
2+
dill>=0.3.5
3+
fonttools>=4.25
4+
future>=0.18
5+
hyperopt>=0.2.7
6+
mkl-service>=2.5.2
7+
multiprocess>=0.70.18
8+
munkres>=1.1.4
9+
networkx>=3.5
10+
numpy>=2.0
11+
pandas>=2.3
12+
scipy>=1.11
13+
matplotlib>=3.7
14+
seaborn>=0.13.2
15+
tqdm>=4.66

run_tests.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import subprocess
1010
import sys
1111
import os
12+
import glob
1213

1314
def run_command(cmd, description):
1415
"""Run a command and handle errors."""
@@ -60,12 +61,18 @@ def main():
6061
success = True
6162

6263
if args.test_type == "unit" or args.test_type == "all":
63-
cmd = ["python", "-m", "pytest", "tests/test_*.py"]
64-
if args.verbose:
65-
cmd.append("-v")
66-
if args.fast:
67-
cmd.extend(["-m", "not slow"])
68-
success &= run_command(cmd, "Unit tests")
64+
# Expand glob pattern manually so pytest receives explicit file paths
65+
unit_files = sorted(glob.glob(os.path.join("tests", "test_*.py")))
66+
if not unit_files:
67+
print("No unit test files found")
68+
success &= False
69+
else:
70+
cmd = ["python", "-m", "pytest", *unit_files]
71+
if args.verbose:
72+
cmd.append("-v")
73+
if args.fast:
74+
cmd.extend(["-m", "not slow"])
75+
success &= run_command(cmd, "Unit tests")
6976

7077
if args.test_type == "integration" or args.test_type == "all":
7178
cmd = ["python", "-m", "pytest", "tests/integration/"]

setup.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setuptools.setup(
77
name="stochastic-benchmark",
8-
version="0.0.1",
8+
version="0.1.0",
99
author="David Bernal",
1010
author_email="dbernalneira@usra.edu",
1111
description="A package to analyze benchmarking results of stochastic optimization solvers",
@@ -17,10 +17,10 @@
1717
},
1818
classifiers=[
1919
"Programming Language :: Python :: 3",
20-
"License :: OSI Approved :: MIT License",
20+
"License :: OSI Approved :: Apache Software License",
2121
"Operating System :: OS Independent",
2222
],
2323
package_dir={"": "src"},
2424
packages=setuptools.find_packages(where="src"),
25-
python_requires=">=3.6",
25+
python_requires=">=3.9",
2626
)

src/bootstrap.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from collections import defaultdict
22
import copy
33
from dataclasses import dataclass, field
4+
import logging
45
import df_utils
56
from itertools import product
67
from multiprocess import Process, Pool, Manager
@@ -17,6 +18,8 @@
1718
confidence_level = 68
1819
gap = 1.0
1920

21+
logger = logging.getLogger(__name__)
22+
2023
tqdm.pandas()
2124

2225

@@ -272,7 +275,7 @@ def Bootstrap(df, group_on, bs_params_list, progress_dir=None):
272275
df = pd.read_pickle(df)
273276

274277
if type(df) != pd.DataFrame:
275-
print("Unsupport type as bootstrap input")
278+
logger.error("Unsupported type as bootstrap input")
276279

277280
def f(bs_params):
278281
if progress_dir is not None:
@@ -365,12 +368,12 @@ def bs_params_eval(bs_params):
365368

366369
elif type(df) == list:
367370
if type(df[0]) == str:
368-
print("calling list of names method")
371+
logger.debug("calling list of names method")
369372

370373
def upper_f(upper_group_filename, bs_params_list):
371374
df_group = pd.read_pickle(upper_group_filename)
372375
group_name = name_fcn(upper_group_filename)
373-
print("evaluation bs for {}".format(group_name))
376+
logger.info("evaluation bs for %s", group_name)
374377
filename = os.path.join(
375378
bootstrap_dir, "bootstrapped_results_{}.pkl".format(group_name)
376379
) # TODO fix filename

src/cross_validation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ def interpolate_raw_performance(
268268

269269
# For each split_ind, do interpolation separately over the resource grid
270270
temp_df_interp = df_many_splits_performance_raw.groupby(group_on).progress_apply(
271-
lambda df: interpolate.InterpolateSingle(df, iParams, group_on)
271+
lambda df: interpolate.InterpolateSingle(df, iParams, group_on), include_groups=False
272272
)
273273
temp_df_interp.reset_index(inplace=True)
274274
return temp_df_interp

src/df_utils.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import glob
22
from multiprocess import Pool
33
import os
4+
import logging
45
import pandas as pd
56
import names
67
import numpy as np
@@ -10,6 +11,8 @@
1011
s = 0.99
1112
gap = 1.0
1213

14+
logger = logging.getLogger(__name__)
15+
1316

1417
def applyParallel(dfGrouped, func):
1518
"""
@@ -91,8 +94,7 @@ def monotone_df(
9194
)
9295
]
9396
if len(matched_row) == 0:
94-
print("No matched row found for")
95-
print(row)
97+
logger.debug("No matched row found for row: %s", row)
9698
continue
9799
else:
98100
matched_row = matched_row.iloc[0]
@@ -101,7 +103,7 @@ def monotone_df(
101103
df.loc[idx, rolling_cols] = matched_row[rolling_cols].copy()
102104
else:
103105
prev_row = row.copy()
104-
df.drop(columns=[c for c in df.columns if "level" in c])
106+
df.drop(columns=[c for c in df.columns if "level" in c], inplace=True)
105107
return df
106108

107109

@@ -123,17 +125,18 @@ def eval_cumm(df, group_on, resource_col, response_col, opt_sense):
123125
Returns
124126
-------
125127
df : pd.DataFrame
126-
Datafram with the cummulative evaluation
128+
Dataframe with the cumulative evaluation
127129
"""
128130

129131
def cummSingle(single_df):
130132
single_df = monotone_df(single_df.copy(), resource_col, response_col, 1)
131-
single_df.loc[:, "cummulative" + resource_col] = (
133+
single_df.loc[:, "cumulative" + resource_col] = (
132134
single_df[resource_col].expanding(min_periods=1).sum()
133135
)
134136
return single_df
135137

136-
cumm_df = df.groupby(group_on).apply(cummSingle)
138+
cumm_df = df.groupby(group_on).apply(cummSingle, include_groups=False)
139+
cumm_df.reset_index(inplace=True)
137140
return cumm_df
138141

139142

src/interpolate.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ def __post_init__(self):
4040
self.resource_value_type = "log"
4141

4242
elif self.resource_value_type in ["data", "log"] and (
43-
len(self.resource_values) >= 0
43+
len(self.resource_values) > 0
4444
):
4545
warn_str = "Resource value type {} does not support passing in values. Removing.".format(
4646
self.resource_value_type
4747
)
4848
warnings.warn(warn_str)
49-
self.resource_value = []
49+
self.resource_values = []
5050

5151

5252
def generateResourceColumn(df: pd.DataFrame, interp_params: InterpolationParameters):
@@ -124,15 +124,12 @@ def InterpolateSingle(
124124
df_out = pd.DataFrame(index=interpolate_resource)
125125
df_out.index.name = "resource"
126126

127-
for colname, col in df_single.iteritems():
128-
col = pd.to_numeric(col, errors="ignore")
127+
for colname, col in df_single.items():
129128
if colname in group_on:
130129
continue
131130
elif colname in interp_params.ignore_cols:
132131
df_out[colname] = df_single[colname].iloc[0]
133-
elif np.issubdtype(
134-
col, np.number
135-
): # An alternative: pd.api.types.is_numeric_dtype(col)
132+
elif np.issubdtype(col.dtype, np.number):
136133
df_out[colname] = np.interp(
137134
interpolate_resource, df_single.index, col, left=np.nan
138135
)
@@ -165,8 +162,7 @@ def Interpolate(df: pd.DataFrame, interp_params: InterpolationParameters, group_
165162
def dfInterp(df):
166163
return InterpolateSingle(df, interp_params, group_on)
167164

168-
df_interp = df.groupby(group_on).progress_apply(dfInterp)
169-
df_interp.reset_index(inplace=True)
165+
df_interp = df.groupby(group_on).progress_apply(dfInterp, include_groups=False)
170166
return df_interp
171167

172168

@@ -195,7 +191,8 @@ def Interpolate_reduce_mem(
195191
df = pd.read_pickle(df_name)
196192
generateResourceColumn(df, interp_params)
197193
temp_df_interp = df.groupby(group_on).progress_apply(
198-
lambda df: InterpolateSingle(df, interp_params, group_on)
194+
lambda df: InterpolateSingle(df, interp_params, group_on),
195+
include_groups=False
199196
)
200197
temp_df_interp.reset_index(inplace=True)
201198
df_interp_list.append(temp_df_interp)

0 commit comments

Comments
 (0)