Skip to content
This repository has been archived by the owner on Jan 13, 2025. It is now read-only.

Apple M1 compatibility #16346

Merged
merged 20 commits into from
Apr 10, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
oops
  • Loading branch information
cdrappi committed Apr 9, 2021
commit 22c34795cf3f18faf5751076e9d7c6fcc33ee2a2
2,062 changes: 1,044 additions & 1,018 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion core/src/banking_stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use solana_ledger::{
blockstore::Blockstore, blockstore_processor::TransactionStatusSender,
entry::hash_transactions, leader_schedule_cache::LeaderScheduleCache,
};
use solana_measure::{measure::Measure, thread_mem_usage};
use solana_measure::{measure::Measure};
use solana_metrics::{inc_new_counter_debug, inc_new_counter_info};
use solana_perf::{
cuda_runtime::PinnedVec,
Expand Down
2 changes: 0 additions & 2 deletions core/src/fetch_stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
use crate::banking_stage::HOLD_TRANSACTIONS_SLOT_OFFSET;
use crate::poh_recorder::PohRecorder;
use crate::result::{Error, Result};
use solana_measure::thread_mem_usage;
use solana_metrics::{inc_new_counter_debug, inc_new_counter_info};
use solana_perf::packet::PacketsRecycler;
use solana_perf::recycler::Recycler;
Expand Down Expand Up @@ -140,7 +139,6 @@ impl FetchStage {
let fwd_thread_hdl = Builder::new()
.name("solana-fetch-stage-fwd-rcvr".to_string())
.spawn(move || loop {
thread_mem_usage::datapoint("solana-fetch-stage-fwd-rcvr");
if let Err(e) =
Self::handle_forwarded_packets(&forward_receiver, &sender, &poh_recorder)
{
Expand Down
32 changes: 1 addition & 31 deletions core/src/replay_stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use solana_ledger::{
entry::VerifyRecyclers,
leader_schedule_cache::LeaderScheduleCache,
};
use solana_measure::{measure::Measure, thread_mem_usage};
use solana_measure::{measure::Measure};
use solana_metrics::inc_new_counter_info;
use solana_runtime::{
accounts_background_service::AbsRequestSender, bank::Bank, bank_forks::BankForks,
Expand Down Expand Up @@ -319,15 +319,11 @@ impl ReplayStage {
let mut voted_signatures = Vec::new();
let mut has_new_vote_been_rooted = !wait_for_vote_to_start_leader;
loop {
let allocated = thread_mem_usage::Allocatedp::default();

thread_mem_usage::datapoint("solana-replay-stage");
// Stop getting entries if we get exit signal
if exit.load(Ordering::Relaxed) {
break;
}

let start = allocated.get();
let mut generate_new_bank_forks_time =
Measure::start("generate_new_bank_forks_time");
Self::generate_new_bank_forks(
Expand All @@ -338,11 +334,9 @@ impl ReplayStage {
&mut progress,
);
generate_new_bank_forks_time.stop();
Self::report_memory(&allocated, "generate_new_bank_forks", start);

let mut tpu_has_bank = poh_recorder.lock().unwrap().has_bank();

let start = allocated.get();
let mut replay_active_banks_time = Measure::start("replay_active_banks_time");
let ancestors = bank_forks.read().unwrap().ancestors();
let descendants = bank_forks.read().unwrap().descendants().clone();
Expand All @@ -364,11 +358,8 @@ impl ReplayStage {
&descendants,
);
replay_active_banks_time.stop();
Self::report_memory(&allocated, "replay_active_banks", start);

let forks_root = bank_forks.read().unwrap().root();
let start = allocated.get();

// Reset any duplicate slots that have been confirmed
// by the network in anticipation of the confirmed version of
// the slot
Expand Down Expand Up @@ -455,7 +446,6 @@ impl ReplayStage {
.select_forks(&frozen_banks, &tower, &progress, &ancestors, &bank_forks);
select_forks_time.stop();

Self::report_memory(&allocated, "select_fork", start);

let mut select_vote_and_reset_forks_time =
Measure::start("select_vote_and_reset_forks");
Expand Down Expand Up @@ -493,8 +483,6 @@ impl ReplayStage {
}
heaviest_fork_failures_time.stop();

let start = allocated.get();

let mut voting_time = Measure::start("voting_time");
// Vote on a fork
if let Some((ref vote_bank, ref switch_fork_decision)) = vote_bank {
Expand Down Expand Up @@ -535,9 +523,6 @@ impl ReplayStage {
};
voting_time.stop();

Self::report_memory(&allocated, "votable_bank", start);
let start = allocated.get();

let mut reset_bank_time = Measure::start("reset_bank");
// Reset onto a fork
if let Some(reset_bank) = reset_bank {
Expand Down Expand Up @@ -605,12 +590,9 @@ impl ReplayStage {
}
}
}
Self::report_memory(&allocated, "reset_bank", start);
}
reset_bank_time.stop();
Self::report_memory(&allocated, "reset_bank", start);

let start = allocated.get();
let mut start_leader_time = Measure::start("start_leader_time");
if !tpu_has_bank {
Self::maybe_start_leader(
Expand All @@ -636,7 +618,6 @@ impl ReplayStage {
}
}
start_leader_time.stop();
Self::report_memory(&allocated, "start_leader", start);

let mut wait_receive_time = Measure::start("wait_receive_time");
if !did_complete_bank {
Expand Down Expand Up @@ -749,17 +730,6 @@ impl ReplayStage {
(progress, heaviest_subtree_fork_choice)
}

fn report_memory(
allocated: &solana_measure::thread_mem_usage::Allocatedp,
name: &'static str,
start: u64,
) {
datapoint_debug!(
"replay_stage-memory",
(name, (allocated.get() - start) as i64, i64),
);
}

#[allow(dead_code)]
fn reset_duplicate_slots(
duplicate_slots_reset_receiver: &DuplicateSlotsResetReceiver,
Expand Down
8 changes: 0 additions & 8 deletions core/src/serve_repair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use bincode::serialize;
use rand::distributions::{Distribution, WeightedIndex};
use solana_ledger::{blockstore::Blockstore, shred::Nonce};
use solana_measure::measure::Measure;
use solana_measure::thread_mem_usage;
use solana_metrics::{datapoint_debug, inc_new_counter_debug};
use solana_perf::packet::{limited_deserialize, Packets, PacketsRecycler};
use solana_sdk::{
Expand Down Expand Up @@ -307,7 +306,6 @@ impl ServeRepair {
Self::report_reset_stats(&me, &mut stats);
last_print = Instant::now();
}
thread_mem_usage::datapoint("solana-repair-listen");
}
})
.unwrap()
Expand All @@ -322,9 +320,7 @@ impl ServeRepair {
stats: &mut ServeRepairStats,
) {
// iter over the packets
let allocated = thread_mem_usage::Allocatedp::default();
packets.packets.iter().for_each(|packet| {
let start = allocated.get();
let from_addr = packet.meta.addr();
limited_deserialize(&packet.data[..packet.meta.size])
.into_iter()
Expand All @@ -336,10 +332,6 @@ impl ServeRepair {
let _ignore_disconnect = response_sender.send(rsp);
}
});
datapoint_debug!(
"solana-serve-repair-memory",
("serve_repair", (allocated.get() - start) as i64, i64),
);
});
}

Expand Down
9 changes: 9 additions & 0 deletions core/src/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1392,6 +1392,15 @@ fn report_target_features() {

#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), not(target_os = "macos")))]
Copy link
Contributor

@mvines mvines Apr 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

macos m1 claims to be target_arch = "x86" or target_arch = "x86_64"? that seems terrible

Copy link
Contributor

@sakridge sakridge Apr 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But is that just for the interpreter? There is the mode on m1 to execute x86 code, so it has to report that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't this feature check affect the x86 macs which have AVX?

Copy link
Contributor Author

@cdrappi cdrappi Apr 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To get this going on an M1, you have to install all of your stuff with Rosetta 2, a tool that allows you to run x86_64 software. This amounts to using a version of rust/cargo etc. that targets x86_64 instead of aarch64. And so to get this running, I had to insert this extremely confusing feature flag

Without Rosetta, rust would target aarch64 – I tried to do this initially, and gave up after a day as there were several more blockers upstream

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, got it. Would you mind sneaking in a comment in the code then here about why we're excluding macos. Otherwise somebody with an intel mbp (everybody on the core team) is likely to remove this line later inadvertently

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sakridge yes it would and is a clear downside of including this feature check. If you could think of a better way to get around this, I'm happy to implement it and be your Mac M1 guinea pig guy

@mvines yes of course! Was planning on this and appreciate the reminder

{
// We exclude Mac OS here to be compatible with computers that have Mac M1 chips.
// For these computers, one must install rust/cargo/brew etc. using Rosetta 2,
// which allows them to run software targeted for x86_64 on an aarch64.
// Hence the code below will run on these machines (target_arch="x86_64")
// if we don't exclude with target_os="macos"
// It's going to require more more work to get Solana building
// on Mac M1's without Rosetta
// and when that happens we should remove this
// (the feature flag for that would be target_arch="aarch64")
unsafe { check_avx() };
}
}
Expand Down
18 changes: 4 additions & 14 deletions ledger/src/blockstore_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use itertools::Itertools;
use log::*;
use rand::{seq::SliceRandom, thread_rng};
use rayon::{prelude::*, ThreadPool};
use solana_measure::{measure::Measure, thread_mem_usage};
use solana_measure::measure::Measure;
use solana_metrics::{datapoint_error, inc_new_counter_debug};
use solana_rayon_threadlimit::get_thread_count;
use solana_runtime::{
Expand Down Expand Up @@ -423,8 +423,6 @@ fn do_process_blockstore_from_root(
transaction_status_sender: Option<TransactionStatusSender>,
) -> BlockstoreProcessorResult {
info!("processing ledger from slot {}...", bank.slot());
let allocated = thread_mem_usage::Allocatedp::default();
let initial_allocation = allocated.get();

// Starting slot must be a root, and thus has no parents
assert!(bank.parent().is_none());
Expand Down Expand Up @@ -503,9 +501,8 @@ fn do_process_blockstore_from_root(

info!("ledger processing timing: {:?}", timing);
info!(
"ledger processed in {}. {} MB allocated. root slot is {}, {} fork{} at {}, with {} frozen bank{}",
"ledger processed in {}. {} root slot is {}, {} fork{} at {}, with {} frozen bank{}",
HumanTime::from(chrono::Duration::from_std(now.elapsed()).unwrap()).to_text_en(Accuracy::Precise, Tense::Present),
allocated.since(initial_allocation) / 1_000_000,
bank_forks.root(),
initial_forks.len(),
if initial_forks.len() > 1 { "s" } else { "" },
Expand Down Expand Up @@ -824,9 +821,6 @@ fn process_next_slots(
// Only process full slots in blockstore_processor, replay_stage
// handles any partials
if next_meta.is_full() {
let allocated = thread_mem_usage::Allocatedp::default();
let initial_allocation = allocated.get();

let next_bank = Arc::new(Bank::new_from_parent(
&bank,
&leader_schedule_cache
Expand All @@ -835,10 +829,9 @@ fn process_next_slots(
*next_slot,
));
trace!(
"New bank for slot {}, parent slot is {}. {} bytes allocated",
"New bank for slot {}, parent slot is {}",
next_slot,
bank.slot(),
allocated.since(initial_allocation)
);
pending_slots.push((next_meta, next_bank, bank.last_blockhash()));
}
Expand Down Expand Up @@ -905,8 +898,6 @@ fn load_frozen_forks(
txs = 0;
}

let allocated = thread_mem_usage::Allocatedp::default();
let initial_allocation = allocated.get();

let mut progress = ConfirmationProgress::new(last_entry_hash);

Expand Down Expand Up @@ -987,10 +978,9 @@ fn load_frozen_forks(
slots_elapsed += 1;

trace!(
"Bank for {}slot {} is complete. {} bytes allocated",
"Bank for {}slot {} is complete",
if last_root == slot { "root " } else { "" },
slot,
allocated.since(initial_allocation)
);

process_next_slots(
Expand Down
1 change: 0 additions & 1 deletion measure/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
#![allow(clippy::integer_arithmetic)]
pub mod measure;
pub mod thread_mem_usage;
50 changes: 0 additions & 50 deletions measure/src/thread_mem_usage.rs

This file was deleted.

3 changes: 0 additions & 3 deletions streamer/src/streamer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

use crate::packet::{self, send_to, Packets, PacketsRecycler, PACKETS_PER_BATCH};
use crate::recvmmsg::NUM_RCVMMSGS;
use solana_measure::thread_mem_usage;
use solana_sdk::timing::{duration_as_ms, timestamp};
use std::net::UdpSocket;
use std::sync::atomic::{AtomicBool, Ordering};
Expand Down Expand Up @@ -97,7 +96,6 @@ pub fn receiver(
Builder::new()
.name("solana-receiver".to_string())
.spawn(move || {
thread_mem_usage::datapoint(name);
let _ = recv_loop(
&sock,
exit,
Expand Down Expand Up @@ -144,7 +142,6 @@ pub fn responder(name: &'static str, sock: Arc<UdpSocket>, r: PacketReceiver) ->
let mut last_error = None;
let mut last_print = 0;
loop {
thread_mem_usage::datapoint(name);
if let Err(e) = recv_send(&sock, &r) {
match e {
StreamerError::RecvTimeoutError(RecvTimeoutError::Disconnected) => break,
Expand Down