EMLX iOS Integration Summary

Copy Markdown View Source

This document summarizes the EMLX integration for iOS in the Dala framework.

What Was Added

1. Core Modules (lib/dala/ml/)

ModulePurpose
Dala.Ml.EmlxiOS-specific EMLX configuration and helpers
Dala.Ml.NxNx integration helpers and backend selection
Dala.Ml.ExamplePractical examples of using EMLX on iOS
Dala.Ml.ConfigHelperConfiguration snippets for mix.exs

2. Documentation

  • guides/ios_ml_support.md - Simplified guide covering:

    • Quick start instructions
    • EMLX configuration for iOS devices vs simulator
    • Build instructions
    • Limitations and troubleshooting
  • AGENTS.md - Updated with simplified iOS ML Support section

Key Features

Platform Detection

Dala.Ml.Emlx.ios_device?()    # true for real iOS device
Dala.Ml.Emlx.ios_simulator?() # true for simulator
Dala.Ml.Emlx.platform_config() # returns appropriate config

Automatic Backend Selection

Dala.Ml.Nx.init_for_ios()
# Automatically selects EMLX (if available) or falls back to Nx.BinaryBackend

Verification

Dala.Ml.Emlx.available?()           # check if EMLX is working
Dala.Ml.Emlx.verify_installation()  # test with a simple tensor operation
Dala.Ml.Emlx.benchmark()           # run a simple performance test

Usage in a Dala iOS App

Step 1: Add Dependencies

In your app's mix.exs:

def deps do
  [
    {:nx, github: "elixir-nx/nx", sparse: "nx"},
    {:axon, "~> 0.6"},
    {:emlx, github: "elixir-nx/emlx", branch: "main"}
  ]
end

Step 2: Configure

In config/config.exs:

# Disable JIT for iOS devices
config :emlx, jit_enabled: false

# Use Metal GPU (recommended for Apple Silicon)
config :nx, :default_backend, {EMLX.Backend, device: :gpu}

Step 3: Initialize

In your app's startup:

defmodule MyApp.App do
  use Dala.App

  def start(_type, _args) do
    Dala.Ml.Nx.init_for_ios()
    # ... rest of app
  end
end

Step 4: Use ML

# Create tensors
tensor = Nx.tensor([1.0, 2.0, 3.0])

# Matrix operations
a = Nx.tensor([[1.0, 2.0], [3.0, 4.0]])
b = Nx.tensor([[5.0], [6.0]])
result = Nx.dot(a, b)  # Runs on GPU via EMLX

Important Constraints

  1. No JIT on iOS devices - W^X policy blocks JIT. Use LIBMLX_ENABLE_JIT=false.
  2. Metal GPU available - EMLX uses MLX with Metal on iOS devices and simulator.
  3. Unified memory - Apple Silicon's shared CPU/GPU memory makes EMLX efficient.
  4. No 64-bit floats - Metal doesn't support them. Use 32-bit floats. result = Nx.dot(a, b) # Runs on GPU via EMLX
    
    ## Repository Analysis Summary
    
    | Repository | iOS Support | Notes |
    |------------|--------------|-------|
    | **Nx** |  Ready | Pure Elixir, works on any platform |
    | **Axon** |  Ready | Neural networks, pure Elixir |
    | **EMLX** |  Setup needed | **Recommended for iOS** |
    
    **Not supported on iOS:**
    - Emily (macOS-only)
    - NxIREE (IREE runtime doesn't target iOS)
    - EXLA/XLA (XLA doesn't target iOS)
    - Torchx (requires LibTorch cross-compile)
    
    ## Files Modified/Created
    
    ### New Files
    - `lib/dala/ml/emlx.ex` - EMLX integration module
    - `lib/dala/ml/nx.ex` - Nx helpers
    - `lib/dala/ml/example.ex` - Usage examples
    - `lib/dala/ml/config_helper.ex` - Configuration helper
    - `guides/ios_ml_support.md` - Complete iOS ML guide
    - `guides/emlx_ios_summary.md` - This summary
    
    ### Modified Files
    - `AGENTS.md` - Added iOS ML Support section
    
    ## Next Steps
    
    1. **Test in iOS Simulator** - Verify EMLX works in iOS simulator
    2. **Test on iOS Device** - Cross-compile MLX for iOS arm64 and test
    3. **Add Precompiled Binaries** - Consider providing precompiled MLX iOS binaries
    4. **Integration Tests** - Add tests for the Dala.ML modules
    5. **Update dala_new Templates** - Add EMLX configuration to project templates