Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ jobs:
# track `rust-toolchain.toml`'s `channel` rather than be bumped on its own.
# Dependabot reads the tag as an ordinary version and will try to raise it;
# `.github/dependabot.yml` ignores this action for that reason.
- uses: dtolnay/rust-toolchain@1.93.1
- uses: dtolnay/rust-toolchain@1.97.1
with:
components: rustfmt
- run: cargo fmt --all -- --check
Expand Down Expand Up @@ -187,7 +187,7 @@ jobs:
# parser resolves to the identical commit for that same input: the two
# unit-test files below each cover one parser in isolation and cannot
# catch a same-input value mismatch on their own.
- uses: dtolnay/rust-toolchain@1.93.1
- uses: dtolnay/rust-toolchain@1.97.1
- name: Run the Rust pin parser's unit and cross-parser tests
run: cargo test -p mlxcel-mlx-pin

Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [Unreleased]

### Changed

- The pinned Rust toolchain moves from 1.93.1 (2026-02-11) to 1.97.1 (2026-07-14), and the `dtolnay/rust-toolchain` tag in `ci.yml` tracks it as the comment there requires. The workflows that install `@stable` are unaffected and were never building at a different version: that action runs `rustup default` and never exports `RUSTUP_TOOLCHAIN`, so `rust-toolchain.toml` overrode it per directory and every cargo invocation in the tree already resolved to the pin. `cargo fmt` produces no diff at the new version, so the bump reformats nothing, but six new clippy lints fire under `-D warnings` and are fixed here: `question_mark` in `memory_estimate.rs` and `sanitize.rs`, `collapsible_match` in `chat_request.rs`, `for_kv_map` and `unnecessary_cast` in two test modules, and `unneeded_wildcard_pattern` in `pipeline_remote_real_models.rs`. All six are mechanical and behavior-preserving.

## [v0.5.0-beta.1] - 2026-08-06

### Added
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ Detailed setup instructions are in [`docs/installation.md`](docs/installation.md

Minimum:

- Rust **1.93+** (project uses edition 2024)
- Rust **1.97+** (project uses edition 2024)
- macOS: Apple Silicon Mac on macOS Sonoma+; Xcode Command Line Tools
- Linux: CUDA 13+ toolchain, OpenBLAS, LAPACK (see [`docs/installation.md`](docs/installation.md) for the package list)

Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
# letting `stable` float. Keep this version identical in mlxcel and the
# internal development repo.
[toolchain]
channel = "1.93.1"
channel = "1.97.1"
components = ["rustfmt", "clippy"]
2 changes: 1 addition & 1 deletion src/distributed/disaggregated/request_router_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@ fn handle_node_failure_distributes_rerouted_requests() {
// Force all requests onto prefill-0 for the test.
{
let mut requests = router.requests.write().unwrap();
for (_, tracked) in requests.iter_mut() {
for tracked in requests.values_mut() {
tracked.phase = RequestPhase::Prefilling {
node_id: "prefill-0".to_string(),
};
Expand Down
6 changes: 2 additions & 4 deletions src/execution/memory_estimate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -732,11 +732,9 @@ pub fn kv_cache_params_from_path(
let explicit_head_dim = config_fields::get_u64(text_cfg, config_fields::HEAD_DIM_KEYS);
let head_dim = if let Some(head_dim) = explicit_head_dim {
head_dim
} else if let Some(hidden_size) = hidden_size {
// 64 is the historical fallback for malformed configs with zero heads.
hidden_size.checked_div(num_heads).unwrap_or(64)
} else {
return None;
// 64 is the historical fallback for malformed configs with zero heads.
hidden_size?.checked_div(num_heads).unwrap_or(64)
};

Some(KvCacheParams {
Expand Down
4 changes: 1 addition & 3 deletions src/models/dbrx_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,9 +314,7 @@ fn clip_qkv_actually_clamps_the_projection() {
assert_eq!(unclipped.clip_qkv, None);

// Large inputs push the fused projection well past +/-8.
let big: Vec<f32> = (0..(args.d_model as usize))
.map(|i| 40.0 + i as f32)
.collect();
let big: Vec<f32> = (0..args.d_model).map(|i| 40.0 + i as f32).collect();
let x = mlxcel_core::from_slice_f32(&big, &[1, 1, args.d_model as i32]);

let mut cache_a = KVCache::new();
Expand Down
7 changes: 4 additions & 3 deletions src/models/sanitize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,10 +329,11 @@ fn normalize_nvfp4_keys(weights: &mut mlxcel_core::weights::WeightMap) {
format!("vision_tower.{rest}")
} else if let Some(rest) = k.strip_prefix("model.embed_vision.") {
format!("embed_vision.{rest}")
} else if let Some(rest) = k.strip_prefix("model.lm_head.") {
format!("lm_head.{rest}")
} else {
return None; // No remapping needed
// Anything that is not one of these prefixes needs no remapping,
// and `?` drops it from the collected set.
let rest = k.strip_prefix("model.lm_head.")?;
format!("lm_head.{rest}")
};
Some((k.clone(), new_key))
})
Expand Down
8 changes: 4 additions & 4 deletions src/server/chat_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,16 +286,16 @@ fn validate_no_reserved_media_sentinels(request: &ChatCompletionRequest) -> Resu
{
anyhow::bail!("message text contains a reserved ordered-media sentinel");
}
MessageContent::Parts(parts) => {
MessageContent::Parts(parts)
if parts.iter().any(|part| {
matches!(
part,
ContentPart::Text { text }
if text.contains(super::types::request::ORDERED_MEDIA_PREFIX)
)
}) {
anyhow::bail!("message text contains a reserved ordered-media sentinel");
}
}) =>
{
anyhow::bail!("message text contains a reserved ordered-media sentinel");
}
_ => {}
}
Expand Down
6 changes: 1 addition & 5 deletions tests/pipeline_remote_real_models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,7 @@ fn pipeline_remote_runtime_llama_real_model_parity_and_cleanup() {
let active_states = runtime.probe_stages().unwrap();
assert!(active_states.iter().all(|state| matches!(
state,
RemoteStageResponse::State {
state,
pending_entry_replies: _,
..
} if state.in_flight_requests == 1
RemoteStageResponse::State { state, .. } if state.in_flight_requests == 1
)));

let atol = 1e-4f64;
Expand Down