Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GPU plotting preparation #3004

Merged
merged 5 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
24 changes: 17 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 0 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,3 @@ sp-weights = { git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d
staging-xcm = { git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" }
substrate-prometheus-endpoint = { git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" }
xcm-procedural = { git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" }

# TODO: Importing https://github.com/supranational/blst/pull/203 to take advantage of optimizations introduced there,
# switch to upstream once merged or once similar performance improvements land upstream
[patch."https://github.com/supranational/blst.git"]
blst = { git = "https://github.com/subspace/blst", rev = "ab042e18cb3b62e131423380513964e4b2c7b445" }
4 changes: 2 additions & 2 deletions crates/subspace-core-primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ blake3 = { version = "1.5.3", default-features = false }
bytes = { version = "1.7.1", default-features = false }
derive_more = { version = "1.0.0", default-features = false, features = ["full"] }
hex = { version = "0.4.3", default-features = false, features = ["alloc"] }
kzg = { git = "https://github.com/sifraitech/rust-kzg", rev = "c34b73916af9b8a699a74bd0186f82f25e72861c", default-features = false }
kzg = { git = "https://github.com/grandinetech/rust-kzg", rev = "6c8fcc623df3d7e8c0f30951a49bfea764f90bf4", default-features = false }
num-traits = { version = "0.2.18", default-features = false }
parity-scale-codec = { version = "3.6.12", default-features = false, features = ["bytes", "derive", "max-encoded-len"] }
parking_lot = { version = "0.12.2", optional = true }
rayon = { version = "1.10.0", optional = true }
rust-kzg-blst = { git = "https://github.com/sifraitech/rust-kzg", rev = "c34b73916af9b8a699a74bd0186f82f25e72861c", default-features = false }
rust-kzg-blst = { git = "https://github.com/grandinetech/rust-kzg", rev = "6c8fcc623df3d7e8c0f30951a49bfea764f90bf4", default-features = false }
scale-info = { version = "2.11.2", default-features = false, features = ["derive"] }
serde = { version = "1.0.206", optional = true, features = ["alloc", "derive"] }
serde_arrays = { version = "0.1.0", optional = true }
Expand Down
5 changes: 4 additions & 1 deletion crates/subspace-core-primitives/src/crypto/kzg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use spin::Mutex;
use tracing::debug;

/// Embedded KZG settings as bytes, too big for `no_std` in most cases
/// Generated with with following command (using current Ethereum KZG Summoning Ceremony):
/// Generated using following command (using current Ethereum KZG Summoning Ceremony):
/// ```bash
/// curl -s https://seq.ceremony.ethereum.org/info/current_state | jq '.transcripts[3].powersOfTau' | jq -r '.G1Powers + .G2Powers | map(.[2:]) | join("")' | xxd -r -p - eth-public-parameters.bin
/// ```
Expand Down Expand Up @@ -72,10 +72,13 @@ pub fn bytes_to_kzg_settings(

// Below is the same as `FsKZGSettings::new(&s1, &s2, num_g1_powers, &fft_settings)`, but without
// extra checks (parameters are static anyway) and without unnecessary allocations
// TODO: Switch to `::new()` constructor once
// https://github.com/grandinetech/rust-kzg/issues/264 is resolved
Ok(FsKZGSettings {
fs: fft_settings,
secret_g1,
secret_g2,
precomputation: None,
})
}

Expand Down
4 changes: 3 additions & 1 deletion crates/subspace-core-primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,10 @@ impl Default for PosProof {
}

impl PosProof {
/// Constant K used for proof of space
pub const K: u8 = 20;
/// Size of proof of space proof in bytes.
pub const SIZE: usize = 20 * 8;
pub const SIZE: usize = Self::K as usize * 8;

/// Proof hash.
pub fn hash(&self) -> Blake3Hash {
Expand Down
6 changes: 3 additions & 3 deletions crates/subspace-erasure-coding/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ include = [
bench = false

[dependencies]
kzg = { git = "https://github.com/sifraitech/rust-kzg", rev = "c34b73916af9b8a699a74bd0186f82f25e72861c", default-features = false }
rust-kzg-blst = { git = "https://github.com/sifraitech/rust-kzg", rev = "c34b73916af9b8a699a74bd0186f82f25e72861c", default-features = false }
kzg = { git = "https://github.com/grandinetech/rust-kzg", rev = "6c8fcc623df3d7e8c0f30951a49bfea764f90bf4", default-features = false }
rust-kzg-blst = { git = "https://github.com/grandinetech/rust-kzg", rev = "6c8fcc623df3d7e8c0f30951a49bfea764f90bf4", default-features = false }
subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives", default-features = false }

[dev-dependencies]
rust-kzg-blst = { git = "https://github.com/sifraitech/rust-kzg", rev = "c34b73916af9b8a699a74bd0186f82f25e72861c" }
rust-kzg-blst = { git = "https://github.com/grandinetech/rust-kzg", rev = "6c8fcc623df3d7e8c0f30951a49bfea764f90bf4" }
criterion = "0.5.1"
rand = "0.8.5"

Expand Down
1 change: 1 addition & 0 deletions crates/subspace-farmer/src/plotter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//! implementations without the rest of the library being aware of implementation details.

pub mod cpu;
pub mod pool;

use async_trait::async_trait;
use futures::channel::mpsc;
Expand Down
49 changes: 25 additions & 24 deletions crates/subspace-farmer/src/plotter/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,28 +354,6 @@ where
metrics.plotting_capacity_used.inc();
}

let plotting_fn = || {
let mut sector = Vec::new();

let plotted_sector = encode_sector(
downloaded_sector,
EncodeSectorOptions {
sector_index,
sector_output: &mut sector,
records_encoder: &mut CpuRecordsEncoder::<PosTable>::new(
&mut (0..record_encoding_concurrency.get())
.map(|_| PosTable::generator())
.collect::<Vec<_>>(),
&erasure_coding,
&global_mutex,
),
abort_early: &abort_early,
},
)?;

Ok((sector, plotted_sector))
};

let thread_pool = if replotting {
&thread_pools.replotting
} else {
Expand All @@ -400,8 +378,31 @@ where

let encoding_start = Instant::now();

let plotting_result =
tokio::task::block_in_place(|| thread_pool.install(plotting_fn));
let plotting_result = tokio::task::block_in_place(|| {
thread_pool.install(|| {
let mut sector = Vec::new();
let mut generators = (0..record_encoding_concurrency.get())
.map(|_| PosTable::generator())
.collect::<Vec<_>>();
let mut records_encoder = CpuRecordsEncoder::<PosTable>::new(
&mut generators,
&erasure_coding,
&global_mutex,
);

let plotted_sector = encode_sector(
downloaded_sector,
EncodeSectorOptions {
sector_index,
sector_output: &mut sector,
records_encoder: &mut records_encoder,
abort_early: &abort_early,
},
)?;

Ok((sector, plotted_sector))
})
});
drop(thread_pools);
if let Some(metrics) = &metrics {
metrics.plotting_capacity_used.dec();
Expand Down
117 changes: 117 additions & 0 deletions crates/subspace-farmer/src/plotter/pool.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
//! Pool plotter

use crate::plotter::{Plotter, SectorPlottingProgress};
use async_trait::async_trait;
use futures::channel::mpsc;
use std::any::type_name_of_val;
use std::time::Duration;
use subspace_core_primitives::{PublicKey, SectorIndex};
use subspace_farmer_components::FarmerProtocolInfo;
use tracing::{error, trace};

/// Pool plotter.
///
/// This plotter implementation relies on retries and should only be used with local plotter
/// implementations (like CPU and GPU).
#[derive(Debug)]
pub struct AggregatePlotter {
plotters: Vec<Box<dyn Plotter + Send + Sync>>,
retry_interval: Duration,
}

#[async_trait]
impl Plotter for AggregatePlotter {
async fn has_free_capacity(&self) -> Result<bool, String> {
for (index, plotter) in self.plotters.iter().enumerate() {
match plotter.has_free_capacity().await {
Ok(result) => {
if result {
return Ok(true);
}
}
Err(error) => {
error!(
%error,
%index,
r#type = type_name_of_val(plotter),
"Failed to check free capacity for plotter"
);
}
}
}

Ok(false)
}

async fn plot_sector(
&self,
public_key: PublicKey,
sector_index: SectorIndex,
farmer_protocol_info: FarmerProtocolInfo,
pieces_in_sector: u16,
replotting: bool,
progress_sender: mpsc::Sender<SectorPlottingProgress>,
) {
loop {
for plotter in &self.plotters {
if plotter
.try_plot_sector(
public_key,
sector_index,
farmer_protocol_info,
pieces_in_sector,
replotting,
progress_sender.clone(),
)
.await
{
return;
}
}

trace!(
retry_interval = ?self.retry_interval,
"All plotters are busy, will wait and try again later"
);
tokio::time::sleep(self.retry_interval).await;
}
}

async fn try_plot_sector(
&self,
public_key: PublicKey,
sector_index: SectorIndex,
farmer_protocol_info: FarmerProtocolInfo,
pieces_in_sector: u16,
replotting: bool,
progress_sender: mpsc::Sender<SectorPlottingProgress>,
) -> bool {
for plotter in &self.plotters {
if plotter
.try_plot_sector(
public_key,
sector_index,
farmer_protocol_info,
pieces_in_sector,
replotting,
progress_sender.clone(),
)
.await
{
return true;
}
}

false
}
}

impl AggregatePlotter {
/// Create new instance
pub fn new(plotters: Vec<Box<dyn Plotter + Send + Sync>>, retry_interval: Duration) -> Self {
Self {
plotters,
retry_interval,
}
}
}
2 changes: 1 addition & 1 deletion crates/subspace-proof-of-space/src/chia.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{PosTableType, Table, TableGenerator};
use core::mem;
use subspace_core_primitives::{PosProof, PosSeed};

const K: u8 = 20;
const K: u8 = PosProof::K;

/// Subspace proof of space table generator.
///
Expand Down
2 changes: 1 addition & 1 deletion crates/subspace-proof-of-space/src/chia_legacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{PosTableType, Table, TableGenerator};
use core::mem;
use subspace_core_primitives::{PosProof, PosSeed};

const K: u8 = 20;
const K: u8 = PosProof::K;

/// Subspace proof of space table generator.
///
Expand Down
Loading