committed by
Grimes
parent
3133ee2401
commit
b825d04597
@ -31,6 +31,7 @@ solana-logger = { path = "../logger", version = "0.21.0" }
|
||||
solana-measure = { path = "../measure", version = "0.21.0" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "0.21.0" }
|
||||
solana-metrics = { path = "../metrics", version = "0.21.0" }
|
||||
solana-perf = { path = "../perf", version = "0.21.0" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "0.21.0" }
|
||||
solana-runtime = { path = "../runtime", version = "0.21.0" }
|
||||
solana-sdk = { path = "../sdk", version = "0.21.0" }
|
||||
|
@ -2,7 +2,6 @@
|
||||
//! unique ID that is the hash of the Entry before it, plus the hash of the
|
||||
//! transactions within it. Entries cannot be reordered, and its field `num_hashes`
|
||||
//! represents an approximate amount of time since the last Entry was created.
|
||||
use crate::perf_libs;
|
||||
use crate::poh::Poh;
|
||||
use log::*;
|
||||
use rayon::prelude::*;
|
||||
@ -11,6 +10,7 @@ use serde::{Deserialize, Serialize};
|
||||
use solana_measure::measure::Measure;
|
||||
use solana_merkle_tree::MerkleTree;
|
||||
use solana_metrics::*;
|
||||
use solana_perf::perf_libs;
|
||||
use solana_rayon_threadlimit::get_thread_count;
|
||||
use solana_sdk::hash::Hash;
|
||||
use solana_sdk::timing;
|
||||
|
@ -12,7 +12,7 @@ pub mod genesis_utils;
|
||||
pub mod leader_schedule;
|
||||
pub mod leader_schedule_cache;
|
||||
pub mod leader_schedule_utils;
|
||||
pub mod perf_libs;
|
||||
pub mod packet;
|
||||
pub mod poh;
|
||||
pub mod rooted_slot_iterator;
|
||||
pub mod shred;
|
||||
|
87
ledger/src/packet.rs
Normal file
87
ledger/src/packet.rs
Normal file
@ -0,0 +1,87 @@
|
||||
//! The `packet` module defines data structures and methods to pull data from the network.
|
||||
use solana_perf::{
|
||||
cuda_runtime::PinnedVec,
|
||||
recycler::{Recycler, Reset},
|
||||
};
|
||||
pub use solana_sdk::packet::{Meta, Packet, PACKET_DATA_SIZE};
|
||||
use std::{mem, net::SocketAddr};
|
||||
|
||||
pub const NUM_PACKETS: usize = 1024 * 8;
|
||||
|
||||
pub const PACKETS_PER_BATCH: usize = 256;
|
||||
pub const NUM_RCVMMSGS: usize = 128;
|
||||
pub const PACKETS_BATCH_SIZE: usize = (PACKETS_PER_BATCH * PACKET_DATA_SIZE);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Packets {
|
||||
pub packets: PinnedVec<Packet>,
|
||||
|
||||
recycler: Option<PacketsRecycler>,
|
||||
}
|
||||
|
||||
impl Drop for Packets {
|
||||
fn drop(&mut self) {
|
||||
if let Some(ref recycler) = self.recycler {
|
||||
let old = mem::replace(&mut self.packets, PinnedVec::default());
|
||||
recycler.recycle(old)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Reset for Packets {
|
||||
fn reset(&mut self) {
|
||||
self.packets.resize(0, Packet::default());
|
||||
}
|
||||
}
|
||||
|
||||
//auto derive doesn't support large arrays
|
||||
impl Default for Packets {
|
||||
fn default() -> Packets {
|
||||
let packets = PinnedVec::with_capacity(NUM_RCVMMSGS);
|
||||
Packets {
|
||||
packets,
|
||||
recycler: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type PacketsRecycler = Recycler<PinnedVec<Packet>>;
|
||||
|
||||
impl Packets {
|
||||
pub fn new(packets: Vec<Packet>) -> Self {
|
||||
let packets = PinnedVec::from_vec(packets);
|
||||
Self {
|
||||
packets,
|
||||
recycler: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_with_recycler(recycler: PacketsRecycler, size: usize, name: &'static str) -> Self {
|
||||
let mut packets = recycler.allocate(name);
|
||||
packets.reserve_and_pin(size);
|
||||
Packets {
|
||||
packets,
|
||||
recycler: Some(recycler),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_addr(&mut self, addr: &SocketAddr) {
|
||||
for m in self.packets.iter_mut() {
|
||||
m.meta.set_addr(&addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_packets_reset() {
|
||||
let mut packets = Packets::default();
|
||||
packets.packets.resize(10, Packet::default());
|
||||
assert_eq!(packets.packets.len(), 10);
|
||||
packets.reset();
|
||||
assert_eq!(packets.packets.len(), 0);
|
||||
}
|
||||
}
|
@ -1,190 +0,0 @@
|
||||
use core::ffi::c_void;
|
||||
use dlopen::symbor::{Container, SymBorApi, Symbol};
|
||||
use dlopen_derive::SymBorApi;
|
||||
use log::*;
|
||||
use solana_sdk::packet::Packet;
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs;
|
||||
use std::os::raw::{c_int, c_uint};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Once;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Elems {
|
||||
pub elems: *const Packet,
|
||||
pub num: u32,
|
||||
}
|
||||
|
||||
#[derive(SymBorApi)]
|
||||
pub struct Api<'a> {
|
||||
pub ed25519_init: Symbol<'a, unsafe extern "C" fn() -> bool>,
|
||||
pub ed25519_set_verbose: Symbol<'a, unsafe extern "C" fn(val: bool)>,
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub ed25519_verify_many: Symbol<
|
||||
'a,
|
||||
unsafe extern "C" fn(
|
||||
vecs: *const Elems,
|
||||
num: u32, //number of vecs
|
||||
message_size: u32, //size of each element inside the elems field of the vec
|
||||
total_packets: u32,
|
||||
total_signatures: u32,
|
||||
message_lens: *const u32,
|
||||
pubkey_offsets: *const u32,
|
||||
signature_offsets: *const u32,
|
||||
signed_message_offsets: *const u32,
|
||||
out: *mut u8, //combined length of all the items in vecs
|
||||
use_non_default_stream: u8,
|
||||
) -> u32,
|
||||
>,
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub ed25519_sign_many: Symbol<
|
||||
'a,
|
||||
unsafe extern "C" fn(
|
||||
vecs: *mut Elems,
|
||||
num: u32, //number of vecs
|
||||
message_size: u32, //size of each element inside the elems field of the vec
|
||||
total_packets: u32,
|
||||
total_signatures: u32,
|
||||
message_lens: *const u32,
|
||||
pubkey_offsets: *const u32,
|
||||
privkey_offsets: *const u32,
|
||||
signed_message_offsets: *const u32,
|
||||
sgnatures_out: *mut u8, //combined length of all the items in vecs
|
||||
use_non_default_stream: u8,
|
||||
) -> u32,
|
||||
>,
|
||||
|
||||
pub chacha_cbc_encrypt_many_sample: Symbol<
|
||||
'a,
|
||||
unsafe extern "C" fn(
|
||||
input: *const u8,
|
||||
sha_state: *mut u8,
|
||||
in_len: usize,
|
||||
keys: *const u8,
|
||||
ivec: *mut u8,
|
||||
num_keys: u32,
|
||||
samples: *const u64,
|
||||
num_samples: u32,
|
||||
starting_block: u64,
|
||||
time_us: *mut f32,
|
||||
),
|
||||
>,
|
||||
|
||||
pub chacha_init_sha_state: Symbol<'a, unsafe extern "C" fn(sha_state: *mut u8, num_keys: u32)>,
|
||||
pub chacha_end_sha_state:
|
||||
Symbol<'a, unsafe extern "C" fn(sha_state_in: *const u8, out: *mut u8, num_keys: u32)>,
|
||||
|
||||
pub poh_verify_many: Symbol<
|
||||
'a,
|
||||
unsafe extern "C" fn(
|
||||
hashes: *mut u8,
|
||||
num_hashes_arr: *const u64,
|
||||
num_elems: usize,
|
||||
use_non_default_stream: u8,
|
||||
) -> c_int,
|
||||
>,
|
||||
|
||||
pub cuda_host_register:
|
||||
Symbol<'a, unsafe extern "C" fn(ptr: *mut c_void, size: usize, flags: c_uint) -> c_int>,
|
||||
|
||||
pub cuda_host_unregister: Symbol<'a, unsafe extern "C" fn(ptr: *mut c_void) -> c_int>,
|
||||
}
|
||||
|
||||
static mut API: Option<Container<Api>> = None;
|
||||
|
||||
fn init(name: &OsStr) {
|
||||
static INIT_HOOK: Once = Once::new();
|
||||
|
||||
info!("Loading {:?}", name);
|
||||
unsafe {
|
||||
INIT_HOOK.call_once(|| {
|
||||
API = Some(Container::load(name).unwrap_or_else(|err| {
|
||||
error!("Unable to load {:?}: {}", name, err);
|
||||
std::process::exit(1);
|
||||
}));
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn locate_perf_libs() -> Option<PathBuf> {
|
||||
let exe = env::current_exe().expect("Unable to get executable path");
|
||||
let perf_libs = exe.parent().unwrap().join("perf-libs");
|
||||
if perf_libs.is_dir() {
|
||||
info!("perf-libs found at {:?}", perf_libs);
|
||||
return Some(perf_libs);
|
||||
}
|
||||
warn!("{:?} does not exist", perf_libs);
|
||||
None
|
||||
}
|
||||
|
||||
fn find_cuda_home(perf_libs_path: &Path) -> Option<PathBuf> {
|
||||
// Search /usr/local for a `cuda-` directory that matches a perf-libs subdirectory
|
||||
for entry in fs::read_dir(&perf_libs_path).unwrap() {
|
||||
if let Ok(entry) = entry {
|
||||
let path = entry.path();
|
||||
if !path.is_dir() {
|
||||
continue;
|
||||
}
|
||||
let dir_name = path.file_name().unwrap().to_str().unwrap_or("");
|
||||
if !dir_name.starts_with("cuda-") {
|
||||
continue;
|
||||
}
|
||||
|
||||
let cuda_home: PathBuf = ["/", "usr", "local", dir_name].iter().collect();
|
||||
if !cuda_home.is_dir() {
|
||||
continue;
|
||||
}
|
||||
|
||||
return Some(cuda_home);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn init_cuda() {
|
||||
if let Some(perf_libs_path) = locate_perf_libs() {
|
||||
if let Some(cuda_home) = find_cuda_home(&perf_libs_path) {
|
||||
info!("CUDA installation found at {:?}", cuda_home);
|
||||
|
||||
let cuda_lib64_dir = cuda_home.join("lib64");
|
||||
if cuda_lib64_dir.is_dir() {
|
||||
let ld_library_path = cuda_lib64_dir.to_str().unwrap_or("").to_string()
|
||||
+ ":"
|
||||
+ &env::var("LD_LIBRARY_PATH").unwrap_or_else(|_| "".to_string());
|
||||
info!("LD_LIBRARY_PATH set to {:?}", ld_library_path);
|
||||
|
||||
// Prefix LD_LIBRARY_PATH with $CUDA_HOME/lib64 directory
|
||||
// to ensure the correct CUDA version is used
|
||||
env::set_var("LD_LIBRARY_PATH", ld_library_path)
|
||||
} else {
|
||||
warn!("{:?} does not exist", cuda_lib64_dir);
|
||||
}
|
||||
|
||||
let libcuda_crypt = perf_libs_path
|
||||
.join(cuda_home.file_name().unwrap())
|
||||
.join("libcuda-crypt.so");
|
||||
return init(libcuda_crypt.as_os_str());
|
||||
} else {
|
||||
warn!("CUDA installation not found");
|
||||
}
|
||||
}
|
||||
|
||||
// Last resort! Blindly load the shared object and hope it all works out
|
||||
init(OsStr::new("libcuda-crypt.so"))
|
||||
}
|
||||
|
||||
pub fn api() -> Option<&'static Container<Api<'static>>> {
|
||||
{
|
||||
static INIT_HOOK: Once = Once::new();
|
||||
INIT_HOOK.call_once(|| {
|
||||
if std::env::var("TEST_PERF_LIBS_CUDA").is_ok() {
|
||||
init_cuda();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
unsafe { API.as_ref() }
|
||||
}
|
Reference in New Issue
Block a user