Skip to content

Commit bb9d602

Browse files
committed
split rust code into crates
so that we get more parallelism out of cargo
1 parent 28e255c commit bb9d602

File tree

4 files changed

+63
-31
lines changed

4 files changed

+63
-31
lines changed

crates/intrinsic-test/src/arm/config.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ pub const AARCH_CONFIGURATIONS: &str = r#"
114114
#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_fcma))]
115115
#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_dotprod))]
116116
#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_i8mm))]
117-
#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_sha3))]
118117
#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_sm4))]
119118
#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_ftts))]
120119
#![feature(fmt_helpers_for_derive)]

crates/intrinsic-test/src/arm/mod.rs

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ use crate::common::SupportedArchitectureTest;
1313
use crate::common::cli::ProcessedCli;
1414
use crate::common::compare::compare_outputs;
1515
use crate::common::gen_c::{write_main_cpp, write_mod_cpp};
16-
use crate::common::gen_rust::{compile_rust_programs, write_cargo_toml, write_main_rs};
16+
use crate::common::gen_rust::{
17+
compile_rust_programs, write_bin_cargo_toml, write_lib_cargo_toml, write_main_rs,
18+
};
1719
use crate::common::intrinsic::Intrinsic;
1820
use crate::common::intrinsic_helpers::TypeKind;
1921
use config::{AARCH_CONFIGURATIONS, F16_FORMATTING_DEF, build_notices};
@@ -137,19 +139,20 @@ impl SupportedArchitectureTest for ArmArchitectureTest {
137139
"aarch64"
138140
};
139141

142+
// Experimentally, keeping 2 cores free is fastest for cargo.
140143
let available_parallelism = std::thread::available_parallelism().unwrap().get();
141-
let chunk_size = self.intrinsics.len().div_ceil(available_parallelism);
144+
let chunk_count = Ord::min(available_parallelism, self.intrinsics.len());
145+
let chunk_size = self.intrinsics.len().div_ceil(chunk_count);
142146

143147
let mut cargo = File::create("rust_programs/Cargo.toml").unwrap();
144-
write_cargo_toml(&mut cargo, &[]).unwrap();
148+
write_bin_cargo_toml(&mut cargo, chunk_count).unwrap();
145149

146150
let mut main_rs = File::create("rust_programs/src/main.rs").unwrap();
147151
write_main_rs(
148152
&mut main_rs,
149-
available_parallelism,
150-
architecture,
153+
chunk_count,
151154
AARCH_CONFIGURATIONS,
152-
F16_FORMATTING_DEF,
155+
"",
153156
self.intrinsics.iter().map(|i| i.name.as_str()),
154157
)
155158
.unwrap();
@@ -165,19 +168,41 @@ impl SupportedArchitectureTest for ArmArchitectureTest {
165168
.map(|(i, chunk)| {
166169
use std::io::Write;
167170

168-
let rust_filename = format!("rust_programs/src/mod_{i}.rs");
171+
std::fs::create_dir_all(format!("rust_programs/mod_{i}/src"))?;
172+
173+
let rust_filename = format!("rust_programs/mod_{i}/src/lib.rs");
169174
trace!("generating `{rust_filename}`");
170175
let mut file = File::create(rust_filename).unwrap();
171176

172177
write!(file, "{notice}")?;
173178

179+
writeln!(file, "#![feature(simd_ffi)]")?;
180+
writeln!(file, "#![feature(f16)]")?;
181+
writeln!(file, "#![allow(unused)]")?;
182+
183+
// Cargo will spam the logs if these warnings are not silenced.
184+
writeln!(file, "#![allow(non_upper_case_globals)]")?;
185+
writeln!(file, "#![allow(non_camel_case_types)]")?;
186+
writeln!(file, "#![allow(non_snake_case)]")?;
187+
188+
let cfg = AARCH_CONFIGURATIONS;
189+
writeln!(file, "{cfg}")?;
190+
174191
writeln!(file, "use core_arch::arch::{architecture}::*;")?;
175-
writeln!(file, "use crate::{{debug_simd_finish, debug_f16}};")?;
192+
193+
let definitions = F16_FORMATTING_DEF;
194+
writeln!(file, "{definitions}")?;
176195

177196
for intrinsic in chunk {
178197
crate::common::gen_rust::create_rust_test_module(&mut file, intrinsic)?;
179198
}
180199

200+
let toml_filename = format!("rust_programs/mod_{i}/Cargo.toml");
201+
trace!("generating `{toml_filename}`");
202+
let mut file = File::create(toml_filename).unwrap();
203+
204+
write_lib_cargo_toml(&mut file, &format!("mod_{i}"))?;
205+
181206
Ok(())
182207
})
183208
.collect::<Result<(), std::io::Error>>()

crates/intrinsic-test/src/common/compare.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub fn compare_outputs(intrinsic_name_list: &Vec<String>, runner: &str, target:
2424
let rust = runner_command(runner)
2525
.arg(format!("target/{target}/release/intrinsic-test-programs"))
2626
.arg(intrinsic_name)
27+
.current_dir("rust_programs")
2728
.output();
2829

2930
let (c, rust) = match (c, rust) {

crates/intrinsic-test/src/common/gen_rust.rs

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,46 +9,53 @@ use super::intrinsic_helpers::IntrinsicTypeDefinition;
99
// The number of times each intrinsic will be called.
1010
const PASSES: u32 = 20;
1111

12-
pub fn write_cargo_toml(w: &mut impl std::io::Write, binaries: &[String]) -> std::io::Result<()> {
12+
fn write_cargo_toml_header(w: &mut impl std::io::Write, name: &str) -> std::io::Result<()> {
1313
writeln!(
1414
w,
1515
concat!(
1616
"[package]\n",
17-
"name = \"intrinsic-test-programs\"\n",
17+
"name = \"{name}\"\n",
1818
"version = \"{version}\"\n",
1919
"authors = [{authors}]\n",
2020
"license = \"{license}\"\n",
2121
"edition = \"2018\"\n",
22-
"[workspace]\n",
23-
"[dependencies]\n",
24-
"core_arch = {{ path = \"../crates/core_arch\" }}",
2522
),
23+
name = name,
2624
version = env!("CARGO_PKG_VERSION"),
2725
authors = env!("CARGO_PKG_AUTHORS")
2826
.split(":")
2927
.format_with(", ", |author, fmt| fmt(&format_args!("\"{author}\""))),
3028
license = env!("CARGO_PKG_LICENSE"),
31-
)?;
29+
)
30+
}
3231

33-
for binary in binaries {
34-
writeln!(
35-
w,
36-
concat!(
37-
"[[bin]]\n",
38-
"name = \"{binary}\"\n",
39-
"path = \"{binary}/main.rs\"\n",
40-
),
41-
binary = binary,
42-
)?;
32+
pub fn write_bin_cargo_toml(
33+
w: &mut impl std::io::Write,
34+
module_count: usize,
35+
) -> std::io::Result<()> {
36+
write_cargo_toml_header(w, "intrinsic-test-programs")?;
37+
38+
writeln!(w, "[dependencies]")?;
39+
40+
for i in 0..module_count {
41+
writeln!(w, "mod_{i} = {{ path = \"mod_{i}/\" }}")?;
4342
}
4443

4544
Ok(())
4645
}
4746

47+
pub fn write_lib_cargo_toml(w: &mut impl std::io::Write, name: &str) -> std::io::Result<()> {
48+
write_cargo_toml_header(w, name)?;
49+
50+
writeln!(w, "[dependencies]")?;
51+
writeln!(w, "core_arch = {{ path = \"../../crates/core_arch\" }}")?;
52+
53+
Ok(())
54+
}
55+
4856
pub fn write_main_rs<'a>(
4957
w: &mut impl std::io::Write,
50-
available_parallelism: usize,
51-
architecture: &str,
58+
chunk_count: usize,
5259
cfg: &str,
5360
definitions: &str,
5461
intrinsics: impl Iterator<Item = &'a str> + Clone,
@@ -65,10 +72,7 @@ pub fn write_main_rs<'a>(
6572
writeln!(w, "{cfg}")?;
6673
writeln!(w, "{definitions}")?;
6774

68-
writeln!(w, "use core_arch::arch::{architecture}::*;")?;
69-
70-
for module in 0..Ord::min(available_parallelism, intrinsics.clone().count()) {
71-
writeln!(w, "mod mod_{module};")?;
75+
for module in 0..chunk_count {
7276
writeln!(w, "use mod_{module}::*;")?;
7377
}
7478

@@ -100,6 +104,9 @@ pub fn compile_rust_programs(toolchain: Option<&str>, target: &str, linker: Opti
100104
let mut cargo_command = Command::new("cargo");
101105
cargo_command.current_dir("rust_programs");
102106

107+
// Do not use the target directory of the workspace please.
108+
cargo_command.env("CARGO_TARGET_DIR", "target");
109+
103110
if let Some(toolchain) = toolchain
104111
&& !toolchain.is_empty()
105112
{

0 commit comments

Comments
 (0)