Skip to content

Commit c9f4a57

Browse files
Merge pull request #240 from macrocosm-os/staging
Staging
2 parents 9ba7fac + 04a8df1 commit c9f4a57

File tree

9 files changed

+78
-204
lines changed

9 files changed

+78
-204
lines changed

README.md

+17-9
Original file line numberDiff line numberDiff line change
@@ -76,28 +76,36 @@ When the simulations finally converge (ΔE/t < threshold), they produce the form
7676
## Requirements
7777
Protein folding utilizes an open-source package called [OpenMM](https://openmm.org). To run, you will need:
7878
1. A Linux-based machine
79-
2. At least 1 CUDA-compatible GPU
79+
2. At least 1 CUDA-compatible GPU. We recommend an RXT 4090.
8080
3. Conda Distribution (we recommend [Miniconda](https://docs.anaconda.com/miniconda/)). Using conda is an [OpenMM requirement](http://docs.openmm.org/latest/userguide/application/01_getting_started.html#installing-openmm).
8181

8282
For more information regarding recommended hardware specifications, look at [min_compute.yml](./min_compute.yml)
8383

84-
## Weights and Biases
84+
## Installation
8585
As a validator, you are **required** to have Weights and Biases (Wandb) active on your machine. We open-source our logging to the community, so this is a necessary component. The repo will not work without Wandb.
8686

87-
Simply:
87+
As a miner, this is an optional include. As such, we do not have logic for logging natively in the base miner, but can be easily added.
88+
89+
This repository requires python3.8 or higher. To install it, simply clone this repository and run the [install.sh](./install.sh) script. Below are all the steps needed to ensure that your machine is running properly:
90+
91+
Firstly, you must install conda:
92+
```bash
93+
mkdir -p ~/miniconda3
94+
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh
95+
bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3
96+
rm ~/miniconda3/miniconda.sh
97+
```
98+
8899
```bash
89100
pip install wandb
90101
wandb login
91-
```
92-
93-
As a miner, this is an optional include. As such, we do not have logic for logging natively in the base miner, but can be easily added.
94102

95-
## Installation
96-
This repository requires python3.8 or higher. To install it, simply clone this repository and run the [install.sh](./install.sh) script.
97-
```bash
98103
git clone https://github.com/macrocosm-os/folding.git
99104
cd folding
100105
bash install.sh
106+
107+
conda activate folding
108+
pip install -e .
101109
```
102110

103111
This will also create a virtual environment in which the repo can be run inside of.

folding/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from .protocol import JobSubmissionSynapse
22
from .validators.protein import Protein
33

4-
__version__ = "1.0.5"
4+
__version__ = "1.0.6"
55
version_split = __version__.split(".")
66
__spec_version__ = (
77
(10000 * int(version_split[0]))

folding/utils/data.py

-163
This file was deleted.

folding/utils/ops.py

+33-26
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
import os
33
import sys
44
import tqdm
5+
import signal
56
import random
67
import shutil
78
import requests
9+
import functools
810
import traceback
911
import subprocess
1012
import pickle as pkl
1113
from typing import Dict, List
12-
1314
import numpy as np
1415
import pandas as pd
1516
import parmed as pmd
@@ -19,6 +20,10 @@
1920
from folding.protocol import JobSubmissionSynapse
2021

2122

23+
class TimeoutException(Exception):
24+
pass
25+
26+
2227
class OpenMMException(Exception):
2328
"""Exception raised for errors in the versioning."""
2429

@@ -35,6 +40,33 @@ def __init__(self, message="Version error occurred"):
3540
super().__init__(self.message)
3641

3742

43+
def timeout_handler(seconds, func_name):
44+
raise TimeoutException(f"Function '{func_name}' timed out after {seconds} seconds")
45+
46+
47+
# Decorator to apply the timeout
48+
def timeout(seconds):
49+
def decorator(func):
50+
@functools.wraps(func) # Retain original function metadata
51+
def wrapper(*args, **kwargs):
52+
# Set the signal alarm with the function name
53+
signal.signal(
54+
signal.SIGALRM,
55+
lambda signum, frame: timeout_handler(seconds, func.__name__),
56+
)
57+
signal.alarm(seconds)
58+
try:
59+
result = func(*args, **kwargs)
60+
finally:
61+
# Disable the alarm
62+
signal.alarm(0)
63+
return result
64+
65+
return wrapper
66+
67+
return decorator
68+
69+
3870
def delete_directory(directory: str):
3971
"""We create a lot of files in the process of tracking pdb files.
4072
Therefore, we want to delete the directory after we are done with the tests.
@@ -134,31 +166,6 @@ def get_tracebacks():
134166
bt.logging.warning(" ---------------- End of Traceback ----------------\n")
135167

136168

137-
def run_cmd_commands(
138-
commands: List[str], suppress_cmd_output: bool = True, verbose: bool = False
139-
):
140-
for cmd in tqdm.tqdm(commands):
141-
bt.logging.debug(f"Running command: {cmd}")
142-
143-
try:
144-
result = subprocess.run(
145-
cmd,
146-
check=True,
147-
shell=True,
148-
stdout=subprocess.PIPE,
149-
stderr=subprocess.PIPE,
150-
)
151-
if not suppress_cmd_output:
152-
bt.logging.info(result.stdout.decode())
153-
154-
except subprocess.CalledProcessError as e:
155-
bt.logging.error(f"❌ Failed to run command ❌: {cmd}")
156-
if verbose:
157-
bt.logging.error(f"Output: {e.stdout.decode()}")
158-
bt.logging.error(f"Error: {e.stderr.decode()}")
159-
get_tracebacks()
160-
raise
161-
162169

163170
def check_and_download_pdbs(
164171
pdb_directory: str,

folding/validators/forward.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
from folding.utils.ops import (
1818
load_and_sample_random_pdb_ids,
1919
get_response_info,
20+
TimeoutException,
21+
OpenMMException,
2022
)
2123

2224
ROOT_DIR = Path(__file__).resolve().parents[2]
@@ -261,9 +263,18 @@ def try_prepare_challenge(config, pdb_id: str) -> Dict:
261263
f"Initial energy is positive: {protein.init_energy}. Simulation failed."
262264
)
263265

264-
except Exception:
266+
except TimeoutException as e:
267+
bt.logging.info(e)
268+
event["validator_search_status"] = False
269+
tries = 10
270+
271+
except OpenMMException as e:
272+
bt.logging.info(f"OpenMMException occurred: init_energy is NaN {e}")
273+
event["validator_search_status"] = False
274+
275+
except Exception as e:
265276
# full traceback
266-
bt.logging.error(traceback.format_exc())
277+
bt.logging.info(e)
267278
event["validator_search_status"] = False
268279

269280
finally:

folding/validators/protein.py

+7
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
write_pkl,
2828
load_and_sample_random_pdb_ids,
2929
plot_miner_validator_curves,
30+
timeout,
3031
)
3132

3233
ROOT_DIR = Path(__file__).resolve().parents[2]
@@ -198,6 +199,7 @@ def read_and_return_files(self, filenames: List) -> Dict:
198199
continue
199200
return files_to_return
200201

202+
@timeout(180)
201203
def setup_simulation(self):
202204
"""forward method defines the following:
203205
1. gather the pdb_id and setup the namings.
@@ -578,6 +580,11 @@ def is_run_valid(self):
578580

579581
return True, check_energies.tolist(), miner_energies.tolist()
580582

583+
def get_ns_computed(self):
584+
"""Calculate the number of nanoseconds computed by the miner."""
585+
586+
return (self.cpt_step * self.system_config.time_step_size) / 1e6
587+
581588
def save_pdb(self, output_path: str):
582589
"""Save the pdb file to the output path."""
583590
positions = self.simulation.context.getState(getPositions=True).getPositions()

folding/validators/reward.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def get_energies(
2929
event["rmsds"] = [0] * len(uids)
3030
event["process_md_output_time"] = [0] * len(uids)
3131
event["is_run_valid"] = [0] * len(uids)
32+
event["ns_computed"] = [0] * len(uids)
3233

3334
energies = np.zeros(len(uids))
3435

@@ -52,7 +53,7 @@ def get_energies(
5253
f"uid {uid} responded with status code {resp.dendrite.status_code}"
5354
)
5455
continue
55-
56+
ns_computed = protein.get_ns_computed()
5657
energy = protein.get_energy()
5758
rmsd = protein.get_rmsd()
5859

@@ -70,6 +71,7 @@ def get_energies(
7071
event["is_valid"][i] = is_valid
7172
event["reported_energy"][i] = float(energy)
7273
event["rmsds"][i] = float(rmsd)
74+
event["ns_computed"][i] = float(ns_computed)
7375

7476
except Exception as E:
7577
# If any of the above methods have an error, we will catch here.

0 commit comments

Comments
 (0)