Skip to content

Commit

Permalink
Remove eagle related code and reference since eagle is retired.
Browse files Browse the repository at this point in the history
  • Loading branch information
rajeee committed Nov 5, 2024
1 parent 24d6523 commit 9c74e1a
Show file tree
Hide file tree
Showing 16 changed files with 49 additions and 261 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ log file here
```

**Platform (please complete the following information):**
- Simulation platform: [e.g. Kestrel, Eagle, AWS, local docker; please label with this as well]
- Simulation platform: [e.g. Kestrel, AWS, local docker; please label with this as well]
- BuildStockBatch version, branch, or sha:
- resstock or comstock repo version, branch, or sha:
- Local Desktop OS: [e.g. Windows, Mac, Linux, especially important if running locally]
Expand Down
2 changes: 1 addition & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ Not all may apply
- [ ] All other unit and integration tests passing
- [ ] Update validation for project config yaml file changes
- [ ] Update existing documentation
- [ ] Run a small batch run on Kestrel/Eagle to make sure it all works if you made changes that will affect Kestrel/Eagle
- [ ] Run a small batch run on Kestrel to make sure it all works if you made changes that will affect Kestrel
- [ ] Add to the changelog_dev.rst file and propose migration text in the pull request
16 changes: 0 additions & 16 deletions buildstockbatch/eagle.sh

This file was deleted.

33 changes: 0 additions & 33 deletions buildstockbatch/eagle_postprocessing.sh

This file was deleted.

2 changes: 1 addition & 1 deletion buildstockbatch/gcp/gcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -807,7 +807,7 @@ def process_results(self, skip_combine=False, use_dask_cluster=True):
Storage. The BSB implementation tries to write both indirectly (via
`postprocessing.combine_results()`, using `get_fs()`), and directly (through
`upload_results`). Which way the results end up on S3 depends on whether the script was run
via aws.py (indirect write), or locally or Eagle (direct upload).
via aws.py (indirect write), or locally or Kestrel (direct upload).
Here, where writing to GCS is (currently) coupled to running on GCS, the writing
to GCS will happen indirectly (via `postprocessing.combine_results()`), and we don't need to
Expand Down
55 changes: 6 additions & 49 deletions buildstockbatch/hpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""
buildstockbatch.hpc
~~~~~~~~~~~~~~~
This class contains the object & methods that allow for usage of the library with Eagle and Kestrel
This class contains the object & methods that allow for usage of the library with Kestrel
:author: Noel Merket
:copyright: (c) 2018 by The Alliance for Sustainable Energy
Expand Down Expand Up @@ -732,38 +732,6 @@ def rerun_failed_jobs(self, hipri=False):
self.queue_post_processing(job_ids, hipri=hipri)


class EagleBatch(SlurmBatch):
DEFAULT_SYS_IMAGE_DIR = "/shared-projects/buildstock/singularity_images"
HPC_NAME = "eagle"
CORES_PER_NODE = 36
MIN_SIMS_PER_JOB = 36 * 2
DEFAULT_POSTPROCESSING_NODE_MEMORY_MB = 85248
DEFAULT_NODE_MEMORY_MB = 85248 # standard node on Eagle
DEFAULT_POSTPROCESSING_N_PROCS = 18
DEFAULT_POSTPROCESSING_N_WORKERS = 2

@classmethod
def validate_output_directory_eagle(cls, project_file):
cfg = get_project_configuration(project_file)
output_dir = path_rel_to_file(project_file, cfg["output_directory"])
if not re.match(r"/(lustre/eaglefs/)?(scratch|projects)", output_dir):
raise ValidationError(
f"`output_directory` must be in /scratch or /projects," f" `output_directory` = {output_dir}"
)

@classmethod
def validate_project(cls, project_file):
super(cls, cls).validate_project(project_file)
cls.validate_output_directory_eagle(project_file)
logger.info("Eagle Validation Successful")
return True

@staticmethod
def _queue_jobs_env_vars() -> dict:
env = {"MY_CONDA_ENV": os.environ["CONDA_PREFIX"]}
return env


class KestrelBatch(SlurmBatch):
DEFAULT_SYS_IMAGE_DIR = "/kfs2/shared-projects/buildstock/apptainer_images"
HPC_NAME = "kestrel"
Expand Down Expand Up @@ -824,17 +792,13 @@ def _queue_jobs_env_vars() -> dict:
}


def eagle_cli(argv=sys.argv[1:]):
user_cli(EagleBatch, argv)


def kestrel_cli(argv=sys.argv[1:]):
user_cli(KestrelBatch, argv)


def user_cli(Batch: SlurmBatch, argv: list):
"""
This is the user entry point for running buildstockbatch on Eagle/Kestrel
This is the user entry point for running buildstockbatch on Kestrel
"""
# set up logging, currently based on within-this-file hard-coded config
logging.config.dictConfig(logging_config)
Expand Down Expand Up @@ -916,24 +880,19 @@ def main():
- upload results to Athena (job_array_number == 0 and POSTPROCESS and UPLOADONLY)
The context for the work is deinfed by the project_filename (project .yml file),
which is used to initialize an EagleBatch object.
which is used to initialize an KestrelBatch object.
"""

# set up logging, currently based on within-this-file hard-coded config
logging.config.dictConfig(logging_config)

# only direct script argument is the project .yml file
parser = argparse.ArgumentParser()
parser.add_argument("hpc_name", choices=["eagle", "kestrel"])
parser.add_argument("project_filename")
args = parser.parse_args()

# initialize the EagleBatch/KestrelBatch object
if args.hpc_name == "eagle":
batch = EagleBatch(args.project_filename)
else:
assert args.hpc_name == "kestrel"
batch = KestrelBatch(args.project_filename)
# initialize the KestrelBatch object
batch = KestrelBatch(args.project_filename)
# other arguments/cues about which part of the process we are in are
# encoded in slurm job environment variables
job_array_number = int(os.environ.get("SLURM_ARRAY_TASK_ID", 0))
Expand Down Expand Up @@ -966,9 +925,7 @@ def main():

if __name__ == "__main__":
bsb_cli = os.environ.get("BUILDSTOCKBATCH_CLI")
if bsb_cli == "eagle":
eagle_cli()
elif bsb_cli == "kestrel":
if bsb_cli == "kestrel":
kestrel_cli()
else:
main()
2 changes: 1 addition & 1 deletion buildstockbatch/postprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ def combine_results(fs, results_dir, cfg, do_timeseries=True):

# Determine how many files should be in each partition and group the files
parquet_memory = int(
cfg.get("eagle", {}).get("postprocessing", {}).get("parquet_memory_mb", MAX_PARQUET_MEMORY)
cfg.get("kestrel", {}).get("postprocessing", {}).get("parquet_memory_mb", MAX_PARQUET_MEMORY)
)
logger.info(f"Max parquet memory: {parquet_memory} MB")
max_files_per_partition = max(1, math.floor(parquet_memory / (mean_mem / 1e6)))
Expand Down
3 changes: 1 addition & 2 deletions buildstockbatch/schemas/v0.4.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
schema_version: enum('0.4')
schema_version: enum('0.5')
buildstock_directory: str()
project_directory: str(required=True)
weather_files_path: str(required=False)
weather_files_url: str(required=False)
sampler: include('sampler-spec', required=True)
workflow_generator: include('workflow-generator-spec', required=True)
eagle: include('hpc-spec', required=False)
kestrel: include('hpc-spec', required=False)
gcp: include('gcp-spec', required=False)
aws: include('aws-spec', required=False)
Expand Down
2 changes: 1 addition & 1 deletion buildstockbatch/test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
def basic_residential_project_file():
with tempfile.TemporaryDirectory() as test_directory:

def _basic_residential_project_file(update_args={}, raw=False, hpc_name="eagle"):
def _basic_residential_project_file(update_args={}, raw=False, hpc_name="kestrel"):
output_dir = "simulations_job0" if raw else "simulation_output"
buildstock_directory = os.path.join(test_directory, "openstudio_buildstock")
shutil.copytree(
Expand Down
42 changes: 15 additions & 27 deletions buildstockbatch/test/test_hpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from unittest.mock import patch
import gzip

from buildstockbatch.hpc import eagle_cli, kestrel_cli, EagleBatch, KestrelBatch, SlurmBatch # noqa: F401
from buildstockbatch.hpc import kestrel_cli, KestrelBatch, SlurmBatch # noqa: F401
from buildstockbatch.base import BuildStockBatchBase
from buildstockbatch.utils import get_project_configuration, read_csv

Expand Down Expand Up @@ -95,11 +95,8 @@ def test_hpc_run_building(mock_subprocess, monkeypatch, basic_residential_projec

def _test_env_vars_passed(mock_subprocess, hpc_name):
env_vars_to_check = ["PROJECTFILE", "MEASURESONLY", "SAMPLINGONLY"]
if hpc_name == "eagle":
env_vars_to_check.append("MY_CONDA_ENV")
else:
assert hpc_name == "kestrel"
env_vars_to_check.append("MY_PYTHON_ENV")
assert hpc_name == "kestrel"
env_vars_to_check.append("MY_PYTHON_ENV")
export_found = False
for arg in mock_subprocess.run.call_args[0][0]:
if arg.startswith("--export"):
Expand All @@ -110,7 +107,7 @@ def _test_env_vars_passed(mock_subprocess, hpc_name):
assert exported_env_vars.issuperset(env_vars_to_check)


@pytest.mark.parametrize("hpc_name", ["eagle", "kestrel"])
@pytest.mark.parametrize("hpc_name", ["kestrel"])
def test_user_cli(basic_residential_project_file, monkeypatch, mocker, hpc_name):
mock_subprocess = mocker.patch("buildstockbatch.hpc.subprocess")
mock_validate_apptainer_image = mocker.patch("buildstockbatch.hpc.SlurmBatch.validate_apptainer_image_hpc")
Expand All @@ -125,13 +122,9 @@ def test_user_cli(basic_residential_project_file, monkeypatch, mocker, hpc_name)

project_filename, results_dir = basic_residential_project_file(hpc_name=hpc_name)
shutil.rmtree(results_dir)
if hpc_name == "eagle":
monkeypatch.setenv("CONDA_PREFIX", "something")
cli = eagle_cli
else:
assert hpc_name == "kestrel"
monkeypatch.setenv("VIRTUAL_ENV", "something")
cli = kestrel_cli
assert hpc_name == "kestrel"
monkeypatch.setenv("VIRTUAL_ENV", "something")
cli = kestrel_cli
argv = [project_filename]
cli(argv)
mock_subprocess.run.assert_called_once()
Expand Down Expand Up @@ -188,7 +181,7 @@ def test_user_cli(basic_residential_project_file, monkeypatch, mocker, hpc_name)
assert "0" == mock_subprocess.run.call_args[1]["env"]["MEASURESONLY"]


@pytest.mark.parametrize("hpc_name", ["eagle", "kestrel"])
@pytest.mark.parametrize("hpc_name", ["kestrel"])
def test_qos_high_job_submit(basic_residential_project_file, monkeypatch, mocker, hpc_name):
mock_subprocess = mocker.patch("buildstockbatch.hpc.subprocess")
mock_subprocess.run.return_value.stdout = "Submitted batch job 1\n"
Expand All @@ -198,11 +191,8 @@ def test_qos_high_job_submit(basic_residential_project_file, monkeypatch, mocker
mocker.patch.object(SlurmBatch, "weather_dir", None)
project_filename, results_dir = basic_residential_project_file(hpc_name=hpc_name)
shutil.rmtree(results_dir)
if hpc_name == "eagle":
monkeypatch.setenv("CONDA_PREFIX", "something")
else:
assert hpc_name == "kestrel"
monkeypatch.setenv("VIRTUAL_ENV", "something")
assert hpc_name == "kestrel"
monkeypatch.setenv("VIRTUAL_ENV", "something")
monkeypatch.setenv("SLURM_JOB_QOS", "high")

batch = Batch(project_filename)
Expand All @@ -224,7 +214,7 @@ def test_qos_high_job_submit(basic_residential_project_file, monkeypatch, mocker
assert "--qos=high" in mock_subprocess.run.call_args[0][0]


@pytest.mark.parametrize("hpc_name", ["eagle", "kestrel"])
@pytest.mark.parametrize("hpc_name", ["kestrel"])
def test_queue_jobs_minutes_per_sim(mocker, basic_residential_project_file, monkeypatch, hpc_name):
mock_subprocess = mocker.patch("buildstockbatch.hpc.subprocess")
Batch = eval(f"{hpc_name.capitalize()}Batch")
Expand All @@ -242,11 +232,9 @@ def test_queue_jobs_minutes_per_sim(mocker, basic_residential_project_file, monk
}
)
shutil.rmtree(results_dir)
if hpc_name == "eagle":
monkeypatch.setenv("CONDA_PREFIX", "something")
else:
assert hpc_name == "kestrel"
monkeypatch.setenv("VIRTUAL_ENV", "something")

assert hpc_name == "kestrel"
monkeypatch.setenv("VIRTUAL_ENV", "something")

batch = Batch(project_filename)
for i in range(1, 11):
Expand All @@ -255,7 +243,7 @@ def test_queue_jobs_minutes_per_sim(mocker, basic_residential_project_file, monk
json.dump({"batch": list(range(1000))}, f)
batch.queue_jobs()
mock_subprocess.run.assert_called_once()
n_minutes = 14 if hpc_name == "eagle" else 5
n_minutes = 5
assert f"--time={n_minutes}" in mock_subprocess.run.call_args[0][0]


Expand Down
34 changes: 6 additions & 28 deletions buildstockbatch/test/test_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import tempfile
import json
import pathlib
from buildstockbatch.hpc import EagleBatch, SlurmBatch, KestrelBatch
from buildstockbatch.hpc import SlurmBatch, KestrelBatch
from buildstockbatch.aws.aws import AwsBatch
from buildstockbatch.local import LocalBatch
from buildstockbatch.base import BuildStockBatchBase, ValidationError
Expand Down Expand Up @@ -53,8 +53,8 @@ def test_base_schema_validation_is_static():
assert isinstance(BuildStockBatchBase.validate_project_schema, types.FunctionType)


def test_eagle_validation_is_classmethod():
assert inspect.ismethod(EagleBatch.validate_project)
def test_kestrel_validation_is_classmethod():
assert inspect.ismethod(KestrelBatch.validate_project)


def test_local_docker_validation_is_classmethod():
Expand Down Expand Up @@ -106,7 +106,7 @@ def test_xor_violations_fail(project_file, expected):


@pytest.mark.parametrize(
"project_file, base_expected, eagle_expected",
"project_file, base_expected, kestrel_expected",
[
(
os.path.join(example_yml_dir, "missing-required-schema.yml"),
Expand All @@ -127,7 +127,7 @@ def test_xor_violations_fail(project_file, expected):
(os.path.join(example_yml_dir, "minimal-schema.yml"), True, ValidationError),
],
)
def test_validation_integration(project_file, base_expected, eagle_expected):
def test_validation_integration(project_file, base_expected, kestrel_expected):
# patch the validate_options_lookup function to always return true for this case
with patch.object(BuildStockBatchBase, "validate_options_lookup", lambda _: True), patch.object(
BuildStockBatchBase, "validate_measure_references", lambda _: True
Expand All @@ -138,7 +138,7 @@ def test_validation_integration(project_file, base_expected, eagle_expected):
):
for cls, expected in [
(BuildStockBatchBase, base_expected),
(EagleBatch, eagle_expected),
(KestrelBatch, kestrel_expected),
]:
if expected is not True:
with pytest.raises(expected):
Expand Down Expand Up @@ -495,28 +495,6 @@ def test_dask_config():
with pytest.raises(ValidationError, match=r"needs to be a multiple of 1024"):
AwsBatch.validate_dask_settings(test3_filename)


def test_validate_eagle_output_directory():
minimal_yml = pathlib.Path(example_yml_dir, "minimal-schema.yml")
with pytest.raises(ValidationError, match=r"must be in /scratch or /projects"):
EagleBatch.validate_output_directory_eagle(str(minimal_yml))
with tempfile.TemporaryDirectory() as tmpdir:
dirs_to_try = [
"/scratch/username/out_dir",
"/projects/projname/out_dir",
"/lustre/eaglefs/scratch/username/out_dir",
"/lustre/eaglefs/projects/projname/out_dir",
]
for output_directory in dirs_to_try:
with open(minimal_yml, "r") as f:
cfg = yaml.load(f, Loader=yaml.SafeLoader)
cfg["output_directory"] = output_directory
temp_yml = pathlib.Path(tmpdir, "temp.yml")
with open(temp_yml, "w") as f:
yaml.dump(cfg, f, Dumper=yaml.SafeDumper)
EagleBatch.validate_output_directory_eagle(str(temp_yml))


def test_validate_kestrel_output_directory():
minimal_yml = pathlib.Path(example_yml_dir, "minimal-schema.yml")
with pytest.raises(ValidationError, match=r"must be in /scratch or /projects"):
Expand Down
Loading

0 comments on commit 9c74e1a

Please sign in to comment.