Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/target
fibonacci.uplc
test.uplc
turbo
turbo.tar.xz
11 changes: 11 additions & 0 deletions crates/pluton/src/cmd/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ fn parse_plutus_version(s: &str) -> Result<PlutusVersion, String> {

impl Args {
pub fn exec(self) -> miette::Result<()> {
let handle = std::thread::Builder::new()
.stack_size(8 * 1024 * 1024)
.spawn(move || self.exec_inner())
.into_diagnostic()?;

handle
.join()
.map_err(|_| miette::miette!("Thread panicked"))?
}

fn exec_inner(self) -> miette::Result<()> {
let arena = uplc_turbo::bumpalo::Bump::with_capacity(1_024_000);

let program = if let Some(file_path) = self.file {
Expand Down
2 changes: 1 addition & 1 deletion crates/uplc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ publish = true
[dependencies]
blst = "0.3.13"
bumpalo = { version = "3.16.0", features = ["collections"] }
chumsky = { version = "=1.0.0-alpha.7", features = ["pratt"] }
chumsky = { version = "=1.0.0-alpha.8", features = ["pratt"] }
cryptoxide = { version = "0.4.4", features = ["ripemd160"] }
hamming = "0.1.3"
hex = "0.4.3"
Expand Down
3 changes: 2 additions & 1 deletion crates/uplc/benches/bench_main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use criterion::criterion_main;
mod benchmarks;

criterion_main! {
benchmarks::haskell,
benchmarks::turbo,
benchmarks::plutus_use_cases,
benchmarks::add_integer,
benchmarks::fibonacci,
}
50 changes: 0 additions & 50 deletions crates/uplc/benches/benchmarks/haskell.rs

This file was deleted.

4 changes: 2 additions & 2 deletions crates/uplc/benches/benchmarks/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
mod add_integer;
mod fibonacci;
mod haskell;
mod real_world;
mod utils;

pub use add_integer::add_integer;
pub use fibonacci::fibonacci;
pub use haskell::haskell;
pub use real_world::*;
133 changes: 133 additions & 0 deletions crates/uplc/benches/benchmarks/real_world.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
use bumpalo::Bump;
use criterion::{criterion_group, Criterion};
use itertools::Itertools;
use std::{fs, time::Duration};
use uplc_turbo::{binder::DeBruijn, flat, machine::PlutusVersion};

#[derive(Debug)]
struct CborWrappped(Vec<u8>);

impl<'d, C> minicbor::Decode<'d, C> for CborWrappped {
fn decode(
d: &mut minicbor::Decoder<'d>,
_ctx: &mut C,
) -> Result<Self, minicbor::decode::Error> {
let bytes = d.bytes()?;
Ok(CborWrappped(bytes.to_vec()))
}
}

pub fn bench_turbo(c: &mut Criterion) {
let data_dir = std::path::Path::new("benches/benchmarks/turbo");

let dir = fs::read_dir(data_dir).unwrap();

if dir.count() == 0 {
panic!(
"missing turbo benchmarks; download archive at {} and unpack it under {}",
"https://pub-2239d82d9a074482b2eb2c886191cb4e.r2.dev/turbo.tar.xz",
data_dir.to_str().unwrap_or_default(),
);
}

let dir = fs::read_dir(data_dir).unwrap();

for subdir in dir
.map(|entry| entry.unwrap())
.map(|entry| entry.path())
.sorted()
{
if subdir.is_dir() {
for entry in fs::read_dir(subdir).unwrap() {
let entry = entry.unwrap();
let path = entry.path();
let file_name = format!(
"turbo~{}",
path.file_name()
.unwrap()
.to_str()
.unwrap()
.replace(".flat", "")
);

let plutus_version = if file_name.ends_with("v1") {
PlutusVersion::V1
} else if file_name.ends_with("v2") {
PlutusVersion::V2
} else if file_name.ends_with("v3") {
PlutusVersion::V3
} else {
panic!("cannot decode plutus version from filename: {file_name:?}");
};

let cbor = std::fs::read(&path).unwrap();
let mut arena = Bump::with_capacity(1_048_576);
let CborWrappped(flat) = minicbor::decode(&cbor).expect("cannot decode from CBOR");

c.bench_function(&file_name, |b| {
b.iter(|| {
let program =
flat::decode::<DeBruijn>(&arena, &flat).expect("Failed to decode");

let result = program.eval_version(&arena, plutus_version);

let _term = result.term.expect("Failed to evaluate");

arena.reset();
})
});
}
}
}
}

criterion_group! {
name = turbo;
config = Criterion::default()
.measurement_time(Duration::from_secs(10));
targets = bench_turbo
}

pub fn bench_plutus_use_cases(c: &mut Criterion) {
let data_dir = std::path::Path::new("benches/benchmarks/plutus_use_cases");

for path in fs::read_dir(data_dir)
.unwrap()
.map(|entry| entry.unwrap())
.map(|entry| entry.path())
.sorted()
{
if path.is_file() {
let file_name = path
.file_name()
.unwrap()
.to_str()
.unwrap()
.replace(".flat", "");

let script = std::fs::read(&path).unwrap();

let mut arena = Bump::with_capacity(1_048_576);

c.bench_function(&file_name, |b| {
b.iter(|| {
let program =
flat::decode::<DeBruijn>(&arena, &script).expect("Failed to decode");

let result = program.eval(&arena);

let _term = result.term.expect("Failed to evaluate");

arena.reset();
})
});
}
}
}

criterion_group! {
name = plutus_use_cases;
config = Criterion::default()
.measurement_time(Duration::from_secs(10));
targets = bench_plutus_use_cases
}
Empty file.
43 changes: 43 additions & 0 deletions crates/uplc/src/flat/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,49 @@ pub fn try_from_tag(arena: &Bump, v: u8) -> Result<&DefaultFunction, FlatDecodeE
Ok(arena.alloc(DefaultFunction::ByteStringToInteger))
}

v if v == DefaultFunction::AndByteString as u8 => {
Ok(arena.alloc(DefaultFunction::AndByteString))
}
v if v == DefaultFunction::OrByteString as u8 => {
Ok(arena.alloc(DefaultFunction::OrByteString))
}
v if v == DefaultFunction::XorByteString as u8 => {
Ok(arena.alloc(DefaultFunction::XorByteString))
}
v if v == DefaultFunction::ComplementByteString as u8 => {
Ok(arena.alloc(DefaultFunction::ComplementByteString))
}
v if v == DefaultFunction::ReadBit as u8 => Ok(arena.alloc(DefaultFunction::ReadBit)),
v if v == DefaultFunction::WriteBits as u8 => Ok(arena.alloc(DefaultFunction::WriteBits)),
v if v == DefaultFunction::ReplicateByte as u8 => {
Ok(arena.alloc(DefaultFunction::ReplicateByte))
}
v if v == DefaultFunction::ShiftByteString as u8 => {
Ok(arena.alloc(DefaultFunction::ShiftByteString))
}
v if v == DefaultFunction::RotateByteString as u8 => {
Ok(arena.alloc(DefaultFunction::RotateByteString))
}
v if v == DefaultFunction::CountSetBits as u8 => {
Ok(arena.alloc(DefaultFunction::CountSetBits))
}
v if v == DefaultFunction::FindFirstSetBit as u8 => {
Ok(arena.alloc(DefaultFunction::FindFirstSetBit))
}
v if v == DefaultFunction::Ripemd_160 as u8 => Ok(arena.alloc(DefaultFunction::Ripemd_160)),

v if v == DefaultFunction::ExpModInteger as u8 => {
Ok(arena.alloc(DefaultFunction::ExpModInteger))
}
v if v == DefaultFunction::DropList as u8 => Ok(arena.alloc(DefaultFunction::DropList)),
v if v == DefaultFunction::LengthOfArray as u8 => {
Ok(arena.alloc(DefaultFunction::LengthOfArray))
}
v if v == DefaultFunction::ListToArray as u8 => {
Ok(arena.alloc(DefaultFunction::ListToArray))
}
v if v == DefaultFunction::IndexArray as u8 => Ok(arena.alloc(DefaultFunction::IndexArray)),

_ => Err(FlatDecodeError::DefaultFunctionNotFound(v)),
}
}
Loading
Loading