/ concept-collection / benchcompress
Sign in
concept-collection / benchcompress
upload datasets
Jeremy Magland <jmagland@flatironinstitute.org> committed commit b0521c01727e parent 8e08b2c Browse files
5 changed files+145−31
web-ui/src/pages/Datasets.tsxmodified+31−0View file
@@ -77,6 +77,17 @@ function Datasets({ datasets }: DatasetsProps) {
7777 >
7878 Source
7979 </th>
80+ <th
81+ style={{
82+ padding: "8px 12px",
83+ textAlign: "left",
84+ borderBottom: "1px solid #ddd",
85+ fontSize: "0.9rem",
86+ whiteSpace: "nowrap",
87+ }}
88+ >
89+ Data
90+ </th>
8091 </tr>
8192 </thead>
8293 <tbody>
@@ -167,6 +178,26 @@ function Datasets({ datasets }: DatasetsProps) {
167178 </a>
168179 )}
169180 </td>
181+ <td
182+ style={{
183+ padding: "6px 12px",
184+ borderBottom: "1px solid #ddd",
185+ fontSize: "0.9rem",
186+ }}
187+ >
188+ {dataset.data_url && (
189+ <a
190+ href={dataset.data_url}
191+ download={`${dataset.name}-${dataset.version}.bin`}
192+ style={{
193+ color: "#0066cc",
194+ textDecoration: "none",
195+ }}
196+ >
197+ Download
198+ </a>
199+ )}
200+ </td>
170201 </tr>
171202 ))}
172203 </tbody>
web-ui/src/types.tsmodified+1−0View file
@@ -30,6 +30,7 @@ export interface Dataset {
3030 version: string;
3131 tags: string[];
3232 source_file?: string;
33+ data_url?: string; // URL to download the raw dataset
3334 }
3435
3536 export interface BenchmarkData {
zia_benchmark/src/zia_benchmark/_memobin.pymodified+56−13View file
@@ -61,8 +61,9 @@ def construct_memobin_url(
6161 alg_version: str,
6262 dataset_version: str,
6363 system_version: str,
64+ file_type: str = "metadata.json",
6465 ) -> str:
65- """Construct the memobin URL for a specific benchmark result.
66+ """Construct the memobin URL for a specific benchmark result or dataset.
6667
6768 Args:
6869 alg_name: Name of the algorithm
@@ -70,49 +71,91 @@ def construct_memobin_url(
7071 alg_version: Version of the algorithm
7172 dataset_version: Version of the dataset
7273 system_version: Version of the system
74+ file_type: Type of file (metadata.json or data.bin)
7375
7476 Returns:
7577 The constructed memobin URL
7678 """
77- path = f"{alg_name}/{dataset_name}/{alg_version}/{dataset_version}/{system_version}/metadata.json"
79+ path = f"{alg_name}/{dataset_name}/{alg_version}/{dataset_version}/{system_version}/{file_type}"
80+ return f"https://tempory.net/f/memobin/{path}"
81+
82+
83+def construct_dataset_url(dataset_name: str, dataset_version: str) -> str:
84+ """Construct the memobin URL for a dataset.
85+
86+ Args:
87+ dataset_name: Name of the dataset
88+ dataset_version: Version of the dataset
89+
90+ Returns:
91+ The constructed memobin URL for the dataset
92+ """
93+ path = f"datasets/{dataset_name}/{dataset_version}/data.bin"
7894 return f"https://tempory.net/f/memobin/{path}"
7995
8096
8197 def upload_to_memobin(
82- metadata: dict, url: str, user_id: str, memobin_api_key: str
98+ data: dict | bytes,
99+ url: str,
100+ user_id: str,
101+ memobin_api_key: str,
102+ content_type: str = "application/json",
83103 ) -> None:
84- """Upload metadata to memobin.
104+ """Upload data to memobin.
85105
86106 Args:
87- metadata: The metadata to upload
107+ data: The data to upload (dict for JSON or bytes for binary)
88108 url: The target URL for the file
89109 user_id: User ID for memobin
90110 memobin_api_key: API key for memobin authentication
111+ content_type: Content type of the data
91112
92113 Raises:
93114 requests.RequestException: If the upload fails
94115 """
95- metadata_bytes = json.dumps(metadata).encode("utf-8")
96- size = len(metadata_bytes)
116+ if isinstance(data, dict):
117+ data_bytes = json.dumps(data).encode("utf-8")
118+ else:
119+ data_bytes = data
120+ size = len(data_bytes)
97121
98122 upload_url = create_signed_upload_url(url, size, user_id, memobin_api_key)
99123
100124 response = requests.put(
101- upload_url, data=metadata_bytes, headers={"Content-Type": "application/json"}
125+ upload_url, data=data_bytes, headers={"Content-Type": content_type}
102126 )
103127
104128 if not response.ok:
105- raise requests.RequestException("Failed to upload metadata to memobin")
129+ raise requests.RequestException("Failed to upload data to memobin")
130+
131+
132+def exists_in_memobin(url: str) -> bool:
133+ """Check if a file exists in memobin using a HEAD request.
134+
135+ Args:
136+ url: The URL to check
137+
138+ Returns:
139+ True if the file exists, False otherwise
140+ """
141+ try:
142+ response = requests.head(url)
143+ return (
144+ 200 <= response.status_code < 300
145+ ) # Any 2xx status code indicates success
146+ except requests.RequestException:
147+ return False
106148
107149
108-def download_from_memobin(url: str) -> Optional[dict]:
109- """Download metadata from memobin.
150+def download_from_memobin(url: str, as_json: bool = True) -> Optional[dict | bytes]:
151+ """Download data from memobin.
110152
111153 Args:
112154 url: The URL to download from
155+ as_json: Whether to parse the response as JSON
113156
114157 Returns:
115- The downloaded metadata as a dictionary, or None if not found
158+ The downloaded data as a dictionary or bytes, or None if not found
116159
117160 Raises:
118161 requests.RequestException: If the download fails for a reason other than 404
@@ -123,7 +166,7 @@ def download_from_memobin(url: str) -> Optional[dict]:
123166 if response.status_code == 404:
124167 return None
125168 response.raise_for_status()
126- return response.json()
169+ return response.json() if as_json else response.content
127170 except requests.RequestException as e:
128171 if response and response.status_code == 404:
129172 return None
zia_benchmark/src/zia_benchmark/datasets/bernoulli/__init__.pymodified+1−1View file
@@ -13,7 +13,7 @@ def create_bernoulli(*, n_samples: int, p: float, seed: int) -> np.ndarray:
1313 datasets = [
1414 {
1515 "name": "bernoulli-0.1",
16- "version": "1",
16+ "version": "2",
1717 "create": lambda: create_bernoulli(n_samples=1_000_000, p=0.1, seed=0),
1818 "description": "Binary sequence with 10% probability of ones.",
1919 "tags": ["binary"],
zia_benchmark/src/zia_benchmark/run_benchmarks.pymodified+56−17View file
@@ -6,7 +6,13 @@ import numpy as np
66 from statistics import median
77 from .algorithms import algorithms
88 from .datasets import datasets
9-from ._memobin import construct_memobin_url, upload_to_memobin, download_from_memobin
9+from ._memobin import (
10+ construct_memobin_url,
11+ construct_dataset_url,
12+ upload_to_memobin,
13+ download_from_memobin,
14+ exists_in_memobin,
15+)
1016
1117
1218 system_version = "v4"
@@ -95,15 +101,14 @@ def run_benchmarks(
95101 with open(metadata_file, "r") as f:
96102 cached_data = json.load(f)
97103 # if versions do not match, then set to None
98- if (
99- cached_data["result"]["algorithm_version"]
100- != algorithm["version"]
101- or cached_data["result"]["dataset_version"]
102- != dataset["version"]
103- or cached_data["result"].get("system_version", "")
104- != system_version
105- ):
106- cached_data = None
104+ if isinstance(cached_data, dict) and "result" in cached_data:
105+ result = cached_data["result"]
106+ if (
107+ result["algorithm_version"] != algorithm["version"]
108+ or result["dataset_version"] != dataset["version"]
109+ or result.get("system_version", "") != system_version
110+ ):
111+ cached_data = None
107112
108113 # If not in local cache, try memobin
109114 if cached_data is None:
@@ -113,6 +118,7 @@ def run_benchmarks(
113118 algorithm["version"],
114119 dataset["version"],
115120 system_version,
121+ "metadata.json",
116122 )
117123 if verbose:
118124 print(" Looking for cached result in memobin...")
@@ -125,14 +131,21 @@ def run_benchmarks(
125131 with open(metadata_file, "w") as f:
126132 json.dump(cached_data, f, indent=2)
127133
128- if cached_data is not None and (
129- cached_data["result"]["algorithm_version"] == algorithm["version"]
130- and cached_data["result"]["dataset_version"] == dataset["version"]
131- and cached_data["result"].get("system_version", "") == system_version
134+ if (
135+ cached_data is not None
136+ and isinstance(cached_data, dict)
137+ and "result" in cached_data
132138 ):
133- print(" Using cached result:")
134- results.append(cached_data["result"])
135- continue
139+ result = cached_data["result"]
140+ if (
141+ isinstance(result, dict)
142+ and result.get("algorithm_version") == algorithm["version"]
143+ and result.get("dataset_version") == dataset["version"]
144+ and result.get("system_version", "") == system_version
145+ ):
146+ print(" Using cached result:")
147+ results.append(result)
148+ continue
136149
137150 print(" Running new benchmark...")
138151 if data is None:
@@ -143,6 +156,31 @@ def run_benchmarks(
143156 print(f"Created dataset: shape={data.shape}, dtype={dtype}")
144157 print(f"Original size: {original_size:,} bytes")
145158
159+ # Upload dataset to memobin if enabled
160+ memobin_api_key = os.environ.get("MEMOBIN_API_KEY")
161+ upload_enabled = os.environ.get("UPLOAD_TO_MEMOBIN") == "1"
162+ if memobin_api_key and upload_enabled:
163+ try:
164+ dataset_url = construct_dataset_url(
165+ dataset["name"], dataset["version"]
166+ )
167+ if not exists_in_memobin(dataset_url):
168+ if verbose:
169+ print(" Uploading dataset to memobin...")
170+ upload_to_memobin(
171+ data.tobytes(),
172+ dataset_url,
173+ os.environ.get("MEMOBIN_USER_ID", "default"),
174+ memobin_api_key,
175+ content_type="application/octet-stream",
176+ )
177+ if verbose:
178+ print(" Successfully uploaded dataset")
179+ except Exception as e:
180+ print(
181+ f" Warning: Failed to upload dataset to memobin: {str(e)}"
182+ )
183+
146184 assert data is not None
147185 assert isinstance(data, np.ndarray)
148186 assert isinstance(original_size, int)
@@ -281,6 +319,7 @@ def run_benchmarks(
281319 "description": dataset.get("description", ""),
282320 "version": dataset["version"],
283321 "tags": dataset.get("tags", []),
322+ "data_url": construct_dataset_url(dataset["name"], dataset["version"]),
284323 }
285324 if "source_file" in dataset:
286325 info["source_file"] = GITHUB_DATASETS_PREFIX + dataset["source_file"]
moveopenescclose