Skip to content

Commit 0899c17

Browse files
committed
use model data (untested)
1 parent 5f578fb commit 0899c17

4 files changed

Lines changed: 106 additions & 30 deletions

File tree

Cargo.lock

Lines changed: 5 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ plotters = "0.3.7"
8383
proc-macro2 = "1.0"
8484
quote = "1.0"
8585
rand = { version = "0.9.0", default-features = false }
86+
regex = { version = "1.11.3", default-features = false }
8687
serde = { version = "1.0", default-features = false }
8788
serde_csv = { version = "1.3.1", package = "csv" } # rename due to conflict
8889
serde_json = "1.0"

baselines/analysis/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ linfa.workspace = true
1818
linfa-linear.workspace = true
1919
ndarray.workspace = true
2020
rand.workspace = true
21+
regex.workspace = true
2122
serde = { workspace = true, features = ["derive"] }
2223
serde_json.workspace = true
2324

baselines/analysis/src/main.rs

Lines changed: 99 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,18 @@ use linfa_linear::FittedLinearRegression;
1616
use ndarray::{Array, Array2, ArrayBase, FixedInitializer, Ix1, Ix2, OwnedRepr};
1717
use rand::rngs::StdRng;
1818
use rand::{RngCore, SeedableRng};
19+
use regex::Regex;
1920
use serde::{Deserialize, Serialize};
2021
use std::collections::BTreeMap;
2122
use std::convert::Infallible;
2223
use std::error::Error;
2324
use std::fs::File;
2425
use std::hint::black_box;
2526
use std::io::{BufRead, BufReader};
26-
use std::iter;
2727
use std::ops::Div;
28+
use std::str::FromStr;
2829
use std::time::{Duration, Instant};
30+
use std::{fs, iter};
2931

3032
#[derive(Serialize, Deserialize, Copy, Clone)]
3133
#[serde(tag = "kind")]
@@ -74,6 +76,16 @@ struct OperationModel {
7476
mutate: FittedLinearRegression<f64>,
7577
}
7678

79+
type DataRepr = DatasetBase<ArrayBase<OwnedRepr<f64>, Ix2>, ArrayBase<OwnedRepr<f64>, Ix1>>;
80+
81+
struct OperationData {
82+
crossover: DataRepr,
83+
evaluate: DataRepr,
84+
fix: DataRepr,
85+
generate: DataRepr,
86+
mutate: DataRepr,
87+
}
88+
7789
const SUBJECTS: &'static [&'static str] = &["csv", "rest", "scriptsizec", "xml"];
7890

7991
#[derive(Default)]
@@ -104,13 +116,12 @@ where
104116
}
105117
}
106118

119+
type ModelWithDataset = (FittedLinearRegression<f64>, DataRepr);
120+
107121
fn regress<const DIM: usize>(
108122
measurements: Vec<(f64, [f64; DIM])>,
109123
features: [&'static str; DIM],
110-
) -> (
111-
FittedLinearRegression<f64>,
112-
DatasetBase<ArrayBase<OwnedRepr<f64>, Ix2>, ArrayBase<OwnedRepr<f64>, Ix1>>,
113-
)
124+
) -> ModelWithDataset
114125
where
115126
[f64; DIM]: FixedInitializer<Elem = f64>, // give the compiler a little help
116127
{
@@ -217,7 +228,7 @@ where
217228
println!("RS models for {subject}:");
218229

219230
// generation
220-
let mut samples = Vec::with_capacity(DISTR_SEGMENTS);
231+
let mut samples = Vec::new();
221232
for &(size, seed) in &distributed {
222233
let (time, generated) = measure(StdRng::seed_from_u64(seed), |sampler| {
223234
B::generate(sampler, &mut generator)
@@ -246,7 +257,7 @@ where
246257
);
247258

248259
// fixing
249-
let mut samples = Vec::with_capacity(DISTR_SEGMENTS);
260+
let mut samples = Vec::new();
250261
for &(size, seed) in &distributed {
251262
let generated = B::generate(&mut StdRng::seed_from_u64(seed), &mut generator);
252263
let mut local_sampler = StdSampler::seed_from_u64(0xdeadbeef);
@@ -269,7 +280,7 @@ where
269280
);
270281

271282
// evaluate
272-
let mut samples = Vec::with_capacity(DISTR_SEGMENTS);
283+
let mut samples = Vec::new();
273284
for &(size, seed) in &distributed {
274285
let generated = B::generate(&mut StdRng::seed_from_u64(seed), &mut generator);
275286
let (time, _) = measure(generated, |fixed| {
@@ -290,7 +301,7 @@ where
290301
);
291302

292303
// mutation
293-
let mut samples = Vec::with_capacity(DISTR_SEGMENTS);
304+
let mut samples = Vec::new();
294305
for &(size, seed) in &distributed {
295306
let generated = B::generate(&mut StdRng::seed_from_u64(seed), &mut generator);
296307
let count = generated.count_nodes();
@@ -341,7 +352,7 @@ where
341352
);
342353

343354
// crossover
344-
let mut samples = Vec::with_capacity(DISTR_SEGMENTS);
355+
let mut samples = Vec::new();
345356
for &(size1, seed1) in distributed
346357
.chunks(distributed.len() / CROSSOVERS)
347358
.map(|a| a.first().unwrap())
@@ -465,8 +476,20 @@ where
465476
}
466477

467478
fn main() -> Result<(), Box<dyn Error>> {
479+
// regexes for extracting execution data later
480+
let time_re = Regex::new(r"^user\t([0-9]+)m([0-9]+\.[0-9]+)s$").unwrap();
481+
// reported isla multipliers
482+
let mut isla = HashMap::new();
483+
isla.extend([
484+
("csv", 1335.0),
485+
("rest", 146.0),
486+
("scriptsizec", 29.0),
487+
("xml", 183.0),
488+
]);
489+
468490
let mut fandango_models = HashMap::new();
469-
for subject in SUBJECTS {
491+
let mut fandango_data = HashMap::new();
492+
for &subject in SUBJECTS {
470493
let mut crossovers = Vec::new();
471494
let mut evaluates = Vec::new();
472495
let mut fixes = Vec::new();
@@ -525,64 +548,65 @@ fn main() -> Result<(), Box<dyn Error>> {
525548
}
526549

527550
println!("Fandango models for {subject}:");
528-
let (generate, data) = regress(generates, ["size"]);
551+
let (generate, generate_data) = regress(generates, ["size"]);
529552
println!(
530553
" generate: {:.2} microseconds/node (MAE = {:.2}, {} samples)",
531554
generate.params()[0] * 1_000_000f64,
532-
(generate.predict(&data.records) - data.targets)
555+
(generate.predict(&generate_data.records) - generate_data.targets.view())
533556
.mapv(|f| f.abs())
534557
.mean()
535558
.unwrap_or(0.0)
536559
* 1_000_000f64,
537-
data.records.len(),
560+
generate_data.records.len(),
538561
);
539-
let (fix, data) = regress(fixes, ["size"]);
562+
let (fix, fix_data) = regress(fixes, ["size"]);
540563
println!(
541564
" fix: {:.2} microseconds/node (MAE = {:.2}, {} samples)",
542565
fix.params()[0] * 1_000_000f64,
543-
(fix.predict(&data.records) - data.targets)
566+
(fix.predict(&fix_data.records) - fix_data.targets.view())
544567
.mapv(|f| f.abs())
545568
.mean()
546569
.unwrap_or(0.0)
547570
* 1_000_000f64,
548-
data.records.len(),
571+
fix_data.records.len(),
549572
);
550-
let (evaluate, data) = regress(evaluates, ["size"]);
573+
let (evaluate, evaluate_data) = regress(evaluates, ["size"]);
551574
println!(
552575
" evaluate: {:.2} microseconds/node (MAE = {:.2}, {} samples)",
553576
evaluate.params()[0] * 1_000_000f64,
554-
(evaluate.predict(&data.records) - data.targets)
577+
(evaluate.predict(&evaluate_data.records) - evaluate_data.targets.view())
555578
.mapv(|f| f.abs())
556579
.mean()
557580
.unwrap_or(0.0)
558581
* 1_000_000f64,
559-
data.records.len(),
582+
evaluate_data.records.len(),
560583
);
561-
let (mutate, data) = regress(mutates, ["size", "mutated"]);
584+
let (mutate, mutate_data) = regress(mutates, ["size", "mutated"]);
562585
println!(
563586
" mutate: {:.2} microseconds/node + {:.2} microseconds/node generated (MAE = {:.2}, {} samples)",
564587
mutate.params()[0] * 1_000_000f64,
565588
mutate.params()[1] * 1_000_000f64,
566-
(mutate.predict(&data.records) - data.targets)
589+
(mutate.predict(&mutate_data.records) - mutate_data.targets.view())
567590
.mapv(|f| f.abs())
568591
.mean()
569592
.unwrap_or(0.0)
570593
* 1_000_000f64,
571-
data.records.len(),
594+
mutate_data.records.len(),
572595
);
573-
let (crossover, data) = regress(crossovers, ["parent1", "parent2", "child1", "child2"]);
596+
let (crossover, crossover_data) =
597+
regress(crossovers, ["parent1", "parent2", "child1", "child2"]);
574598
println!(
575599
" crossover: {:.2} microseconds/node of parent 1 + {:.2} microseconds/node of parent 2 + {:.2} microseconds/node of child 1 + {:.2} microseconds/node of child 2 (MAE = {:.2}, {} samples)",
576600
crossover.params()[0] * 1_000_000f64,
577601
crossover.params()[1] * 1_000_000f64,
578602
crossover.params()[2] * 1_000_000f64,
579603
crossover.params()[3] * 1_000_000f64,
580-
(crossover.predict(&data.records) - data.targets)
604+
(crossover.predict(&crossover_data.records) - crossover_data.targets.view())
581605
.mapv(|f| f.abs())
582606
.mean()
583607
.unwrap_or(0.0)
584608
* 1_000_000f64,
585-
data.records.len(),
609+
crossover_data.records.len(),
586610
);
587611
fandango_models.insert(
588612
subject,
@@ -594,6 +618,16 @@ fn main() -> Result<(), Box<dyn Error>> {
594618
mutate,
595619
},
596620
);
621+
fandango_data.insert(
622+
subject,
623+
OperationData {
624+
crossover: crossover_data,
625+
evaluate: evaluate_data,
626+
fix: fix_data,
627+
generate: generate_data,
628+
mutate: mutate_data,
629+
},
630+
);
597631
}
598632

599633
let mut rs_models = HashMap::new();
@@ -605,5 +639,44 @@ fn main() -> Result<(), Box<dyn Error>> {
605639
);
606640
rs_models.insert("xml", perform_benchmark::<xml::Benchmark>("xml"));
607641

642+
for subject in ["csv", "rest", "scriptsizec", "xml"] {
643+
let mut time_elapsed = 0f64;
644+
for trial in 1..=5 {
645+
let experiment_output = fs::read_to_string(format!(
646+
"baselines/profiling-results/{subject}/{trial}/experiment_output.txt"
647+
))?;
648+
649+
let time_captures = time_re.captures(&experiment_output).unwrap();
650+
time_elapsed += (usize::from_str(time_captures.get(1).unwrap().as_str()).unwrap() * 60)
651+
as f64
652+
+ f64::from_str(time_captures.get(2).unwrap().as_str()).unwrap();
653+
}
654+
655+
let original_time = time_elapsed;
656+
let data = fandango_data.get(subject).unwrap();
657+
let modeled = rs_models.get(subject).unwrap();
658+
659+
let mut apply_model = |data: &DataRepr, model: &FittedLinearRegression<f64>| {
660+
let original_expended = data.targets.sum();
661+
let predicted_expended = model.predict(&data.records).sum();
662+
time_elapsed = time_elapsed + predicted_expended - original_expended;
663+
};
664+
665+
apply_model(&data.generate, &modeled.generate);
666+
apply_model(&data.fix, &modeled.fix);
667+
apply_model(&data.evaluate, &modeled.evaluate);
668+
apply_model(&data.mutate, &modeled.mutate);
669+
apply_model(&data.crossover, &modeled.crossover);
670+
671+
let duration_multiplier = (60 * 60) as f64 / original_time; // scale to one hour
672+
let scaled_time = time_elapsed * duration_multiplier;
673+
let computed_isla = (60 * 60) as f64 * *isla.get(subject).unwrap();
674+
675+
println!(
676+
"{scaled_time} seconds => 1 hour => {} days",
677+
computed_isla / (60 * 60 * 24) as f64
678+
);
679+
}
680+
608681
Ok(())
609682
}

0 commit comments

Comments
 (0)