Skip to content

Commit f2773b9

Browse files
authored
Merge pull request #2640 from subspace/farmer-support-cpu-core-ranges
Support CPU core ranges in farmer
2 parents 360fb7e + 4095e46 commit f2773b9

File tree

2 files changed

+55
-8
lines changed

2 files changed

+55
-8
lines changed

crates/subspace-farmer/src/utils.rs

+22-7
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@ use futures::channel::oneshot::Canceled;
1111
use futures::future::Either;
1212
use rayon::{ThreadBuilder, ThreadPool, ThreadPoolBuildError, ThreadPoolBuilder};
1313
use std::future::Future;
14-
use std::num::{NonZeroUsize, ParseIntError};
14+
use std::num::NonZeroUsize;
1515
use std::ops::Deref;
1616
use std::pin::{pin, Pin};
17-
use std::str::FromStr;
1817
use std::task::{Context, Poll};
1918
use std::{io, thread};
2019
use thread_priority::{set_current_thread_priority, ThreadPriority};
@@ -273,16 +272,32 @@ pub fn all_cpu_cores() -> Vec<CpuCoreSet> {
273272

274273
/// Parse space-separated set of groups of CPU cores (individual cores are coma-separated) into
275274
/// vector of CPU core sets that can be used for creation of plotting/replotting thread pools.
276-
pub fn parse_cpu_cores_sets(s: &str) -> Result<Vec<CpuCoreSet>, ParseIntError> {
275+
pub fn parse_cpu_cores_sets(
276+
s: &str,
277+
) -> Result<Vec<CpuCoreSet>, Box<dyn std::error::Error + Send + Sync>> {
277278
#[cfg(feature = "numa")]
278279
let topology = hwlocality::Topology::new().map(std::sync::Arc::new).ok();
279280

280281
s.split(' ')
281282
.map(|s| {
282-
let cores = s
283-
.split(',')
284-
.map(usize::from_str)
285-
.collect::<Result<Vec<usize>, _>>()?;
283+
let mut cores = Vec::new();
284+
for s in s.split(',') {
285+
let mut parts = s.split('-');
286+
let range_start = parts
287+
.next()
288+
.ok_or(
289+
"Bad string format, must be comma separated list of CPU cores or ranges",
290+
)?
291+
.parse()?;
292+
293+
if let Some(range_end) = parts.next() {
294+
let range_end = range_end.parse()?;
295+
296+
cores.extend(range_start..=range_end);
297+
} else {
298+
cores.push(range_start);
299+
}
300+
}
286301

287302
Ok(CpuCoreSet {
288303
cores,

crates/subspace-farmer/src/utils/tests.rs

+33-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::utils::run_future_in_dedicated_thread;
1+
use crate::utils::{parse_cpu_cores_sets, run_future_in_dedicated_thread};
22
use std::future;
33
use tokio::sync::oneshot;
44

@@ -46,3 +46,35 @@ fn run_future_in_dedicated_thread_tokio_on_drop() {
4646
));
4747
});
4848
}
49+
50+
#[test]
51+
fn test_parse_cpu_cores_sets() {
52+
{
53+
let cores = parse_cpu_cores_sets("0").unwrap();
54+
assert_eq!(cores.len(), 1);
55+
assert_eq!(cores[0].cores, vec![0]);
56+
}
57+
{
58+
let cores = parse_cpu_cores_sets("0,1,2").unwrap();
59+
assert_eq!(cores.len(), 1);
60+
assert_eq!(cores[0].cores, vec![0, 1, 2]);
61+
}
62+
{
63+
let cores = parse_cpu_cores_sets("0,1,2 4,5,6").unwrap();
64+
assert_eq!(cores.len(), 2);
65+
assert_eq!(cores[0].cores, vec![0, 1, 2]);
66+
assert_eq!(cores[1].cores, vec![4, 5, 6]);
67+
}
68+
{
69+
let cores = parse_cpu_cores_sets("0-2 4-6,7").unwrap();
70+
assert_eq!(cores.len(), 2);
71+
assert_eq!(cores[0].cores, vec![0, 1, 2]);
72+
assert_eq!(cores[1].cores, vec![4, 5, 6, 7]);
73+
}
74+
75+
assert!(parse_cpu_cores_sets("").is_err());
76+
assert!(parse_cpu_cores_sets("a").is_err());
77+
assert!(parse_cpu_cores_sets("0,").is_err());
78+
assert!(parse_cpu_cores_sets("0,a").is_err());
79+
assert!(parse_cpu_cores_sets("0 a").is_err());
80+
}

0 commit comments

Comments
 (0)