Skip to content

Commit 5b71f06

Browse files
committed
migrate to rustc's FxHasher
1 parent 4c20974 commit 5b71f06

104 files changed

Lines changed: 610 additions & 545 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

Lines changed: 21 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ keywords = ["computer-vision", "deep-learning", "image-processing", "onnx", "vid
4343

4444
[workspace.dependencies]
4545
thiserror = "2"
46+
rustc-hash = "2.1.3"
4647

4748
[workspace.lints.rust]
4849
unsafe_code = "deny"

apps/llm-bench/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ yscv-kernels = { version = "0.1", path = "../../crates/yscv-kernels", default-fe
4646
serde = { version = "1.0", features = ["derive"] }
4747
serde_json = "1.0"
4848
thiserror.workspace = true
49+
rustc-hash.workspace = true
4950

5051
[lints]
5152
workspace = true

apps/llm-bench/src/bin/nchwc_coverage.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_hash::FxHashMap;
12
/// NCHWc layout coverage probe — Step 0 of NCHWc-everywhere plan.
23
///
34
/// Loads a tracker ONNX model and classifies every Conv op as NCHWc-eligible
@@ -7,8 +8,7 @@
78
/// Usage:
89
/// cargo run --release --no-default-features -p yscv-llm-bench --bin nchwc_coverage \
910
/// -- private/private/model.onnx
10-
use std::collections::{HashMap, HashSet};
11-
11+
use std::collections::HashSet;
1212
use yscv_onnx::{OnnxAttribute, OnnxModel, OnnxNode, load_onnx_model_from_file};
1313

1414
fn main() {
@@ -76,8 +76,8 @@ fn is_passthrough(op_type: &str) -> bool {
7676
/// Build a map: tensor_name → shape, tracing through Identity nodes to
7777
/// resolve weight-sharing aliases. In Siamese networks, branch1 weights
7878
/// are Identity(branch0_initializer) — treat them as static weights.
79-
fn build_effective_initializers(model: &OnnxModel) -> HashMap<String, Vec<usize>> {
80-
let mut effective: HashMap<String, Vec<usize>> = model
79+
fn build_effective_initializers(model: &OnnxModel) -> FxHashMap<String, Vec<usize>> {
80+
let mut effective: FxHashMap<String, Vec<usize>> = model
8181
.initializers
8282
.iter()
8383
.map(|(k, v)| (k.clone(), v.shape().to_vec()))
@@ -139,8 +139,8 @@ fn run_coverage_probe(model: &OnnxModel) {
139139
// Classify each conv op
140140
let mut eligible = 0usize;
141141
let mut rejected = 0usize;
142-
let mut kind_counts: HashMap<String, usize> = HashMap::new();
143-
let mut reject_reasons: HashMap<String, usize> = HashMap::new();
142+
let mut kind_counts: FxHashMap<String, usize> = FxHashMap::default();
143+
let mut reject_reasons: FxHashMap<String, usize> = FxHashMap::default();
144144

145145
for (_, node) in &conv_ops {
146146
let weight_name = node.inputs.get(1).map(|s| s.as_str()).unwrap_or("");
@@ -331,7 +331,7 @@ fn run_coverage_probe(model: &OnnxModel) {
331331
println!();
332332
println!("QLinearConv ops in model: {}", qlinear_conv.len());
333333
// Show all non-Conv node op types and counts
334-
let mut op_counts: HashMap<&str, usize> = HashMap::new();
334+
let mut op_counts: FxHashMap<&str, usize> = FxHashMap::default();
335335
for node in &model.nodes {
336336
*op_counts.entry(node.op_type.as_str()).or_default() += 1;
337337
}
@@ -349,7 +349,7 @@ fn run_coverage_probe(model: &OnnxModel) {
349349
// Non-passthrough, non-Conv ops require NHWC → insert converter at boundary
350350

351351
// Build tensor → producing node index
352-
let mut tensor_producer: HashMap<&str, usize> = HashMap::new();
352+
let mut tensor_producer: FxHashMap<&str, usize> = FxHashMap::default();
353353
for (i, node) in model.nodes.iter().enumerate() {
354354
for out in &node.outputs {
355355
if !out.is_empty() {

apps/llm-bench/src/bin/quantize_tracker.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use std::collections::HashMap;
3535
use std::path::{Path, PathBuf};
3636
use std::process::ExitCode;
3737

38+
use rustc_hash::FxHashMap;
3839
use serde::Deserialize;
3940
use yscv_onnx::quantize::{
4041
CalibrationCollector, fold_constant_qdq_weights_for_yscv_fast, prune_unused_initializers,
@@ -385,8 +386,8 @@ struct TrackingDelta {
385386
/// the output maps by shape, then compare argmax cell + the box at the fp32
386387
/// peak cell. Returns `None` if no 1-channel score map is present.
387388
fn decoded_tracking_delta(
388-
out_fp32: &HashMap<String, Tensor>,
389-
out_qdq: &HashMap<String, Tensor>,
389+
out_fp32: &FxHashMap<String, Tensor>,
390+
out_qdq: &FxHashMap<String, Tensor>,
390391
) -> Option<TrackingDelta> {
391392
let mut score: Option<(&Tensor, &Tensor)> = None;
392393
let mut bbox: Option<(&Tensor, &Tensor)> = None;

crates/yscv-detect/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ yscv-onnx = { version = "0.1", path = "../yscv-onnx", optional = true }
1818
yscv-tensor = { version = "0.1", path = "../yscv-tensor" }
1919
yscv-video = { version = "0.1", path = "../yscv-video" }
2020
thiserror.workspace = true
21+
rustc-hash.workspace = true
2122

2223
[dev-dependencies]
2324
criterion = { version = "0.5", default-features = false, features = ["cargo_bench_support"] }

crates/yscv-detect/src/nms.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,9 @@ pub fn soft_nms(detections: &mut Vec<Detection>, sigma: f32, score_threshold: f3
118118
/// each group independently, then merges and returns results sorted by score
119119
/// descending.
120120
pub fn batched_nms(detections: &[Detection], iou_threshold: f32) -> Vec<Detection> {
121-
use std::collections::HashMap;
121+
use rustc_hash::FxHashMap;
122122

123-
let mut by_class: HashMap<usize, Vec<Detection>> = HashMap::new();
123+
let mut by_class: FxHashMap<usize, Vec<Detection>> = FxHashMap::default();
124124
for det in detections {
125125
by_class.entry(det.class_id).or_default().push(*det);
126126
}

crates/yscv-detect/src/yolo.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ pub fn detect_yolov8_onnx(
360360
img_width: usize,
361361
config: &YoloConfig,
362362
) -> Result<Vec<Detection>, crate::DetectError> {
363-
use std::collections::HashMap;
363+
use rustc_hash::FxHashMap;
364364

365365
let input_name = model
366366
.inputs
@@ -373,7 +373,7 @@ pub fn detect_yolov8_onnx(
373373
image_data.to_vec(),
374374
)?;
375375

376-
let mut inputs = HashMap::new();
376+
let mut inputs = FxHashMap::default();
377377
inputs.insert(input_name, tensor);
378378

379379
let outputs = yscv_onnx::run_onnx_model(model, inputs)?;

crates/yscv-eval/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ serde_json = "1.0"
1818
roxmltree = "0.20"
1919
csv = "1.3"
2020
thiserror.workspace = true
21+
rustc-hash.workspace = true
2122

2223
[dev-dependencies]
2324
criterion = { version = "0.5", default-features = false, features = ["cargo_bench_support"] }

crates/yscv-eval/src/dataset/coco.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::collections::HashMap;
1+
use rustc_hash::{FxBuildHasher, FxHashMap};
22

33
use yscv_detect::{BoundingBox, Detection};
44

@@ -11,7 +11,8 @@ pub(crate) fn build_detection_dataset_from_coco(
1111
predictions: Vec<CocoPredictionWire>,
1212
) -> Result<Vec<DetectionDatasetFrame>, EvalError> {
1313
let mut frames = Vec::with_capacity(ground_truth.images.len());
14-
let mut image_index_by_id = HashMap::with_capacity(ground_truth.images.len());
14+
let mut image_index_by_id =
15+
FxHashMap::with_capacity_and_hasher(ground_truth.images.len(), FxBuildHasher);
1516

1617
for (frame_idx, image) in ground_truth.images.into_iter().enumerate() {
1718
if image_index_by_id.insert(image.id, frame_idx).is_some() {

0 commit comments

Comments
 (0)