Skip to content

Cleanup: remove deprecated imports, add LocalizedError, use async URLSession - #1

Merged
mzbac merged 1 commit into
mzbac:mainfrom
PicoMLX:pr1-cleanup
Feb 11, 2026
Merged

Cleanup: remove deprecated imports, add LocalizedError, use async URLSession#1
mzbac merged 1 commit into
mzbac:mainfrom
PicoMLX:pr1-cleanup

Conversation

@ronaldmannak

Copy link
Copy Markdown
Contributor

Summary

  • Remove deprecated @preconcurrency import statements that are no longer needed
  • Add LocalizedError conformance to error types for better error descriptions
  • Replace synchronous Data(contentsOf:) with async URLSession.shared.data(from:) for image loading

These are independent cleanup improvements that don't change any behavior.

Files changed

  • Sources/Flux2/PixtralVisionTower.swift
  • Sources/Flux2/VAEBlocks.swift
  • Sources/Flux2/Flux2DevPipeline.swift
  • Sources/Flux2/Flux2KleinPipeline.swift
  • Sources/Flux2/LatentPreparation.swift
  • Sources/Flux2/Scheduler.swift
  • Sources/Flux2CLI/CLI+Generate.swift
  • Sources/Flux2CLI/CLI+Image.swift

Test plan

  • Verify project builds with swift build
  • Verify image generation still works end-to-end

🤖 Generated with Claude Code

…Session

- Remove standalone `import MLXRandom` and `import MLXFast` where
  namespaced calls work via `import MLX`
- Add LocalizedError conformance with errorDescription to all public
  error enums for better consumer diagnostics
- Replace DispatchSemaphore + callback-based URLSession.dataTask with
  modern async URLSession.data(for:) in fetchRemoteData()
- Hoist async image loading out of Device.withDefaultDevice closure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@mzbac

mzbac commented Feb 10, 2026

Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 010ca03c26

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +291 to 295
let loadStart = clock.now
var loaded: [ConditioningImage] = []
for spec in imageSpecs {
try await loaded.append(loadConditioningImage(spec: spec))
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep conditioning MLXArrays on GPU to avoid copies

Here loadConditioningImage is awaited before entering Device.withDefaultDevice(.gpu). That helper builds an MLXArray from the decoded image (see CLI+Image.loadConditioningImage), so this change creates the conditioning tensors on the default device (typically CPU) instead of GPU. When the pipeline later consumes conditioningImages inside the GPU context, MLX has to transfer those arrays, which is an unintended host↔device copy and a measurable performance regression for image conditioning. Consider moving the loading (or at least the MLXArray creation) back inside the GPU block or explicitly placing the array on the GPU.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This suggestion is incorrect for MLX on Apple Silicon.

Apple Silicon uses unified memory (UMA) — the GPU and CPU share the same physical memory space. There is no separate "host" and "device" memory, so there is no "host↔device copy" like you'd see with CUDA on discrete NVIDIA GPUs. An MLXArray created outside Device.withDefaultDevice(.gpu) is already accessible to the GPU without any data transfer.

Device.withDefaultDevice(.gpu) sets the compute context (where operations execute), not where data lives. The conditioning image arrays are read directly by GPU kernels inside the pipeline with zero copy overhead.

Additionally, loadConditioningImage is async (it uses URLSession.data), so it cannot be called inside Device.withDefaultDevice(.gpu), which takes a synchronous closure. The current code correctly hoists the async work before the device block — this is the intended pattern.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

human Ronald here. Can I trigger your @codex as well?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I see. I need to bring my own Codex? That's going to be fun. We'll have three bots talking to each other

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I will pull down the PR on my local machine and testing it late tonight, currently the Mac is occupied by porting glm ocr:)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@codex look at the previous comments and give me your take

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I just connected Claude to Github too. Let's see if I can summon @claude to turn this discussion into a Furby Frenzy

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 010ca03c26

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


let semaphore = DispatchSemaphore(value: 0)
var result: Result<Data, Error>?
let (data, response) = try await session.data(for: request)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve CLIError wrapping for URLSession transport failures

When session.data(for:) throws (for example on DNS/TLS failures, offline mode, or request timeout), this now propagates a raw URLError instead of the CLI-specific CLIError.invalidOption that previously included the image URL and a clear "Failed to download image" message. In generate --image ... flows that fetch remote conditioning images, users will now get less actionable errors and lose consistent CLI error formatting; wrapping this call in do/catch and rethrowing CLIError.invalidOption(...) restores the prior behavior.

Useful? React with 👍 / 👎.

@mzbac
mzbac merged commit 98643db into mzbac:main Feb 11, 2026
2 checks passed
@mzbac

mzbac commented Feb 11, 2026

Copy link
Copy Markdown
Owner

@ronaldmannak thanks for cleanup :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants