diff --git a/.github/workflows/ci-macos.yml b/.github/workflows/ci-macos.yml new file mode 100644 index 0000000..f6883a3 --- /dev/null +++ b/.github/workflows/ci-macos.yml @@ -0,0 +1,49 @@ +name: ci +on: + pull_request: + push: + branches: + - macos +jobs: + format: + name: cargo fmt + runs-on: macos-latest + steps: + - uses: actions/checkout@v5 + + - name: Setup toolchain + uses: actions-rust-lang/setup-rust-toolchain@v1 + + - name: Run fmt + run: make fmt + + cargo-clippy: + name: cargo clippy + runs-on: macos-latest + steps: + - uses: actions/checkout@v5 + + # This action will configure Rust cache automatically: + # https://github.com/actions-rust-lang/setup-rust-toolchain?tab=readme-ov-file#inputs + - name: Setup toolchain + uses: actions-rust-lang/setup-rust-toolchain@v1 + + - run: make lint + + build-and-test: + name: build and test + runs-on: macos-latest + steps: + - uses: actions/checkout@v5 + + - name: Setup toolchain + uses: actions-rust-lang/setup-rust-toolchain@v1 + + - name: Build + run: make build + + - name: Build with metal + run: cargo build --features metal + +# - name: Run Unit Test +# run: make test \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 42320ea..9e14dc2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -379,6 +379,12 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2" +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + [[package]] name = "built" version = "0.7.7" @@ -440,10 +446,12 @@ checksum = "a9f51e2ecf6efe9737af8f993433c839f956d2b6ed4fd2dd4a7c6d8b0fa667ff" dependencies = [ "byteorder", "candle-kernels", + "candle-metal-kernels", "cudarc", "gemm 0.17.1", "half", "memmap2", + "metal 0.27.0", "num-traits", "num_cpus", "rand 0.9.2", @@ -453,6 +461,7 @@ dependencies = [ "thiserror 1.0.69", "ug", "ug-cuda", + "ug-metal", "yoke 0.7.5", "zip", ] @@ -478,6 +487,19 @@ dependencies = [ "bindgen_cuda", ] +[[package]] +name = "candle-metal-kernels" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a323ee9c813707f73b6e59300661b354a70410f31fe4135170c4eda8a061534" +dependencies = [ + "half", + "metal 0.27.0", + "once_cell", + "thiserror 1.0.69", + "tracing", +] + [[package]] name = "candle-nn" version = "0.9.1" @@ -485,7 +507,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1980d53280c8f9e2c6cbe1785855d7ff8010208b46e21252b978badf13ad69d" dependencies = [ "candle-core", + "candle-metal-kernels", "half", + "metal 0.27.0", "num-traits", "rayon", "safetensors", @@ -702,6 +726,17 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + [[package]] name = "crc32fast" version = "1.5.0" @@ -1161,7 +1196,28 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "foreign-types-shared", + "foreign-types-shared 0.1.1", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared 0.3.1", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1170,6 +1226,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + [[package]] name = "form_urlencoded" version = "1.2.2" @@ -2257,6 +2319,15 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "670fdfda89751bc4a84ac13eaa63e205cf0fd22b4c9a5fbfa085b63c1f1d3a30" +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + [[package]] name = "matchers" version = "0.2.0" @@ -2292,6 +2363,36 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "metal" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43f73953f8cbe511f021b58f18c3ce1c3d1ae13fe953293e13345bf83217f25" +dependencies = [ + "bitflags 2.10.0", + "block", + "core-graphics-types", + "foreign-types 0.5.0", + "log", + "objc", + "paste", +] + +[[package]] +name = "metal" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" +dependencies = [ + "bitflags 2.10.0", + "block", + "core-graphics-types", + "foreign-types 0.5.0", + "log", + "objc", + "paste", +] + [[package]] name = "mime" version = "0.3.17" @@ -2598,6 +2699,25 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + [[package]] name = "object" version = "0.37.3" @@ -2649,7 +2769,7 @@ checksum = "24ad14dd45412269e1a30f52ad8f0664f0f4f4a89ee8fe28c3b3527021ebb654" dependencies = [ "bitflags 2.10.0", "cfg-if", - "foreign-types", + "foreign-types 0.3.2", "libc", "once_cell", "openssl-macros", @@ -4438,6 +4558,20 @@ dependencies = [ "ug", ] +[[package]] +name = "ug-metal" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76daec3c7a32a1b4a0e3307b6b057fa067aa64e750713987410a2c402e5cd731" +dependencies = [ + "half", + "metal 0.29.0", + "objc", + "serde", + "thiserror 1.0.69", + "ug", +] + [[package]] name = "uncased" version = "0.9.10" diff --git a/Cargo.toml b/Cargo.toml index 65f9fcb..f72347f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,6 +40,7 @@ symphonia = { version = "0.5.5", features = ["mp3", "wav"] } [features] flash-attn=["candle-flash-attn"] cuda=["candle-nn/cuda", "candle-core/cuda", "candle-transformers/cuda"] +metal=["candle-nn/metal", "candle-core/metal", "candle-transformers/metal"] ffmpeg=["ffmpeg-next"] [lints.clippy] diff --git a/src/utils/mod.rs b/src/utils/mod.rs index d14996e..32995f0 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -27,7 +27,11 @@ pub fn get_device(device: Option<&Device>) -> Device { { Device::new_cuda(0).unwrap_or(Device::Cpu) } - #[cfg(not(feature = "cuda"))] + #[cfg(all(not(feature = "cuda"), feature = "metal"))] + { + Device::new_metal(0).unwrap_or(Device::Cpu) + } + #[cfg(all(not(feature = "cuda"), not(feature = "metal")))] { Device::Cpu }