feat(aiken-project): use rayon to run tests in parallel

This commit is contained in:
rvcas 2023-01-09 18:04:39 -05:00 committed by Lucas
parent 6ea9ad9c41
commit 158b3dfe51
5 changed files with 93 additions and 40 deletions

View File

@ -4,7 +4,7 @@
### Added ### Added
N/A - **aiken-project**: new dep rayon for parallel test execution
### Changed ### Changed

56
Cargo.lock generated
View File

@ -123,6 +123,7 @@ dependencies = [
"pallas-traverse", "pallas-traverse",
"petgraph", "petgraph",
"pulldown-cmark", "pulldown-cmark",
"rayon",
"regex", "regex",
"reqwest", "reqwest",
"serde", "serde",
@ -442,6 +443,30 @@ dependencies = [
"crossbeam-utils", "crossbeam-utils",
] ]
[[package]]
name = "crossbeam-deque"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset",
"scopeguard",
]
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.14" version = "0.8.14"
@ -1018,6 +1043,15 @@ version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "memoffset"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "miette" name = "miette"
version = "5.5.0" version = "5.5.0"
@ -1610,6 +1644,28 @@ dependencies = [
"rand_core", "rand_core",
] ]
[[package]]
name = "rayon"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"num_cpus",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.2.16" version = "0.2.16"

View File

@ -22,6 +22,7 @@ pallas = "0.16.0"
pallas-traverse = "0.16.0" pallas-traverse = "0.16.0"
petgraph = "0.6.2" petgraph = "0.6.2"
pulldown-cmark = { version = "0.8.0", default-features = false } pulldown-cmark = { version = "0.8.0", default-features = false }
rayon = "1.6.1"
regex = "1.6.0" regex = "1.6.0"
reqwest = "0.11.13" reqwest = "0.11.13"
serde = { version = "1.0.144", features = ["derive"] } serde = { version = "1.0.144", features = ["derive"] }

View File

@ -10,7 +10,6 @@ pub mod pretty;
pub mod script; pub mod script;
pub mod telemetry; pub mod telemetry;
use crate::module::{CERT, MINT, SPEND, VALIDATOR_NAMES, WITHDRAW};
use aiken_lang::{ use aiken_lang::{
ast::{Definition, Function, ModuleKind, TypedDataType, TypedDefinition, TypedFunction}, ast::{Definition, Function, ModuleKind, TypedDataType, TypedDefinition, TypedFunction},
builder::{DataTypeKey, FunctionAccessKey}, builder::{DataTypeKey, FunctionAccessKey},
@ -44,7 +43,10 @@ use uplc::{
use crate::{ use crate::{
config::Config, config::Config,
error::{Error, Warning}, error::{Error, Warning},
module::{CheckedModule, CheckedModules, ParsedModule, ParsedModules}, module::{
CheckedModule, CheckedModules, ParsedModule, ParsedModules, CERT, MINT, SPEND,
VALIDATOR_NAMES, WITHDRAW,
},
telemetry::Event, telemetry::Event,
}; };
@ -691,6 +693,8 @@ where
} }
fn eval_scripts(&self, scripts: Vec<Script>, match_name: Option<String>) -> Vec<EvalInfo> { fn eval_scripts(&self, scripts: Vec<Script>, match_name: Option<String>) -> Vec<EvalInfo> {
use rayon::prelude::*;
// TODO: in the future we probably just want to be able to // TODO: in the future we probably just want to be able to
// tell the machine to not explode on budget consumption. // tell the machine to not explode on budget consumption.
let initial_budget = ExBudget { let initial_budget = ExBudget {
@ -698,43 +702,31 @@ where
cpu: i64::MAX, cpu: i64::MAX,
}; };
let mut results = Vec::new(); scripts
.into_par_iter()
for script in scripts { .filter(|script| -> bool {
let path = format!("{}{}", script.module, script.name); let path = format!("{}{}", script.module, script.name);
if matches!(&match_name, Some(search_str) if !path.to_string().contains(search_str)) { !matches!(&match_name, Some(search_str) if !path.contains(search_str))
continue; })
} .map(|script| match script.program.eval(initial_budget) {
(Ok(result), remaining_budget, logs) => EvalInfo {
match script.program.eval(initial_budget) {
(Ok(result), remaining_budget, logs) => {
let eval_info = EvalInfo {
success: result != Term::Error success: result != Term::Error
&& result != Term::Constant(Constant::Bool(false)), && result != Term::Constant(Constant::Bool(false)),
script, script,
spent_budget: initial_budget - remaining_budget, spent_budget: initial_budget - remaining_budget,
output: Some(result), output: Some(result),
logs, logs,
}; },
(Err(..), remaining_budget, logs) => EvalInfo {
results.push(eval_info);
}
(Err(..), remaining_budget, logs) => {
let eval_info = EvalInfo {
success: false, success: false,
script, script,
spent_budget: initial_budget - remaining_budget, spent_budget: initial_budget - remaining_budget,
output: None, output: None,
logs, logs,
}; },
})
results.push(eval_info); .collect()
}
}
}
results
} }
fn output_path(&self) -> PathBuf { fn output_path(&self) -> PathBuf {

View File

@ -3,7 +3,7 @@ use aiken_lang::ast::BinOp;
use std::path::PathBuf; use std::path::PathBuf;
use uplc::ast::{NamedDeBruijn, Program}; use uplc::ast::{NamedDeBruijn, Program};
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct Script { pub struct Script {
pub input_path: PathBuf, pub input_path: PathBuf,
pub module: String, pub module: String,
@ -12,6 +12,8 @@ pub struct Script {
pub evaluation_hint: Option<EvalHint>, pub evaluation_hint: Option<EvalHint>,
} }
unsafe impl Send for Script {}
impl Script { impl Script {
pub fn new( pub fn new(
input_path: PathBuf, input_path: PathBuf,
@ -45,3 +47,5 @@ pub struct EvalInfo {
pub output: Option<Term<NamedDeBruijn>>, pub output: Option<Term<NamedDeBruijn>>,
pub logs: Vec<String>, pub logs: Vec<String>,
} }
unsafe impl Send for EvalInfo {}