From ea578478d41b046d0bd14a6e73378bd65ef72211 Mon Sep 17 00:00:00 2001 From: Ivar Flakstad <69173633+ivarflakstad@users.noreply.github.com> Date: Thu, 11 Jul 2024 18:00:03 +0800 Subject: [PATCH] Initial generic metallib build.rs script --- candle-metal-kernels/.gitignore | 1 + candle-metal-kernels/build.rs | 137 ++++++++++++++++++ .../src/{ => kernels}/affine.metal | 0 .../src/{ => kernels}/binary.metal | 0 .../src/{ => kernels}/cast.metal | 0 .../src/{ => kernels}/conv.metal | 0 .../src/{ => kernels}/indexing.metal | 0 .../src/{ => kernels}/quantized.metal | 0 .../src/{ => kernels}/random.metal | 0 .../src/{ => kernels}/reduce.metal | 4 +- .../src/{ => kernels}/sort.metal | 0 .../src/{ => kernels}/ternary.metal | 0 .../src/{ => kernels}/unary.metal | 0 candle-metal-kernels/src/kernels/utils.metal | 47 ++++++ candle-metal-kernels/src/lib.rs | 38 +++-- .../src/libraries/candle.metallib | Bin 0 -> 333664 bytes .../libMetalFlashAttention.metallib | Bin 17 files changed, 210 insertions(+), 17 deletions(-) create mode 100644 candle-metal-kernels/.gitignore create mode 100644 candle-metal-kernels/build.rs rename candle-metal-kernels/src/{ => kernels}/affine.metal (100%) rename candle-metal-kernels/src/{ => kernels}/binary.metal (100%) rename candle-metal-kernels/src/{ => kernels}/cast.metal (100%) rename candle-metal-kernels/src/{ => kernels}/conv.metal (100%) rename candle-metal-kernels/src/{ => kernels}/indexing.metal (100%) rename candle-metal-kernels/src/{ => kernels}/quantized.metal (100%) rename candle-metal-kernels/src/{ => kernels}/random.metal (100%) rename candle-metal-kernels/src/{ => kernels}/reduce.metal (99%) rename candle-metal-kernels/src/{ => kernels}/sort.metal (100%) rename candle-metal-kernels/src/{ => kernels}/ternary.metal (100%) rename candle-metal-kernels/src/{ => kernels}/unary.metal (100%) create mode 100644 candle-metal-kernels/src/kernels/utils.metal create mode 100644 candle-metal-kernels/src/libraries/candle.metallib rename candle-metal-kernels/src/{ => libraries}/libMetalFlashAttention.metallib (100%) diff --git a/candle-metal-kernels/.gitignore b/candle-metal-kernels/.gitignore new file mode 100644 index 00000000..ec97a588 --- /dev/null +++ b/candle-metal-kernels/.gitignore @@ -0,0 +1 @@ +src/air diff --git a/candle-metal-kernels/build.rs b/candle-metal-kernels/build.rs new file mode 100644 index 00000000..22f279bd --- /dev/null +++ b/candle-metal-kernels/build.rs @@ -0,0 +1,137 @@ +use std::process::Command; +use std::{env, str}; + +const COMPILED_KERNELS: [&str; 1] = ["reduce"]; + +enum Platform { + MacOS, + IOS, +} + +impl Platform { + fn as_str(&self) -> &'static str { + match self { + Platform::MacOS => "macosx", + Platform::IOS => "iphoneos", + } + } +} + +fn get_xcode_sdk_path(platform: Platform) -> Result { + let xcrun_output = Command::new("xcrun") + .args(["--sdk", platform.as_str(), "--show-sdk-path"]) + .output() + .expect("xcrun command failed to start"); + + Ok(str::from_utf8(&xcrun_output.stdout) + .expect("Invalid UTF-8 from xcrun") + .replace('\n', "")) +} + +fn compile_candle_metallib(sdk_path: String, bfloat_support: bool) -> Result<(), String> { + let current_dir = env::current_dir().expect("Failed to get current directory"); + let out_dir = current_dir.join("src/libraries"); + let air_dir = current_dir.join("src/air"); + let working_directory = air_dir.display(); + let sources = current_dir.join("src/kernels"); + + // Compile metal to air + let mut compile_air_cmd = Command::new("xcrun"); + compile_air_cmd + .arg("metal") + .arg(format!("-working-directory={working_directory}")) + .arg("-Wall") + .arg("-Wextra") + .arg("-O3") + .arg("-c") + .arg("-w"); + for metal_file in COMPILED_KERNELS { + compile_air_cmd.arg(sources.join(format!("{metal_file}.metal"))); + } + compile_air_cmd.arg(sources.join("utils.metal")); + compile_air_cmd.spawn().expect("Failed to compile air"); + + let mut child = compile_air_cmd.spawn().expect("Failed to compile air"); + + match child.try_wait() { + Ok(Some(status)) => { + if !status.success() { + panic!( + "Compiling metal -> air failed. Exit with status: {}", + status + ) + } + } + Ok(None) => { + let status = child + .wait() + .expect("Compiling metal -> air failed while waiting for result"); + if !status.success() { + panic!( + "Compiling metal -> air failed. Exit with status: {}", + status + ) + } + } + Err(e) => panic!("Compiling metal -> air failed: {:?}", e), + } + + // Compile air to metallib + let metallib = out_dir.join("candle.metallib"); + + let mut compile_metallib_cmd = Command::new("xcrun"); + compile_metallib_cmd.arg("metal").arg("-o").arg(&metallib); + + for metal_file in COMPILED_KERNELS { + compile_metallib_cmd.arg(air_dir.join(format!("{metal_file}.air"))); + } + compile_metallib_cmd.arg(air_dir.join("utils.air")); + + let mut child = compile_metallib_cmd + .spawn() + .expect("Failed to compile air -> metallib"); + + match child.try_wait() { + Ok(Some(status)) => { + if !status.success() { + panic!( + "Compiling air -> metallib failed. Exit with status: {}", + status + ) + } + } + Ok(None) => { + let status = child + .wait() + .expect("Compiling air -> metallib failed while waiting for result"); + if !status.success() { + panic!( + "Compiling air -> metallib failed. Exit with status: {}", + status + ) + } + } + Err(e) => panic!("Compiling air -> metallib failed: {:?}", e), + } + + Ok(()) +} + +fn main() -> Result<(), String> { + println!("cargo::rerun-if-changed=build.rs"); + + let current_dir = env::current_dir().expect("Failed to get current directory"); + let sources = current_dir.join("src/kernels"); + + for metal_file in COMPILED_KERNELS { + println!("cargo::rerun-if-changed={}", sources.join(format!("{metal_file}.metal")).display()); + println!("cargo:warning=output {}", sources.join(format!("{metal_file}.metal")).display()); + } + + let macos_sdk = get_xcode_sdk_path(Platform::MacOS).expect("Failed to get MacOS SDK path"); + let iphoneos_sdk = get_xcode_sdk_path(Platform::IOS).expect("Failed to get IOS SDK path"); + + compile_candle_metallib(macos_sdk, false)?; + + Ok(()) +} diff --git a/candle-metal-kernels/src/affine.metal b/candle-metal-kernels/src/kernels/affine.metal similarity index 100% rename from candle-metal-kernels/src/affine.metal rename to candle-metal-kernels/src/kernels/affine.metal diff --git a/candle-metal-kernels/src/binary.metal b/candle-metal-kernels/src/kernels/binary.metal similarity index 100% rename from candle-metal-kernels/src/binary.metal rename to candle-metal-kernels/src/kernels/binary.metal diff --git a/candle-metal-kernels/src/cast.metal b/candle-metal-kernels/src/kernels/cast.metal similarity index 100% rename from candle-metal-kernels/src/cast.metal rename to candle-metal-kernels/src/kernels/cast.metal diff --git a/candle-metal-kernels/src/conv.metal b/candle-metal-kernels/src/kernels/conv.metal similarity index 100% rename from candle-metal-kernels/src/conv.metal rename to candle-metal-kernels/src/kernels/conv.metal diff --git a/candle-metal-kernels/src/indexing.metal b/candle-metal-kernels/src/kernels/indexing.metal similarity index 100% rename from candle-metal-kernels/src/indexing.metal rename to candle-metal-kernels/src/kernels/indexing.metal diff --git a/candle-metal-kernels/src/quantized.metal b/candle-metal-kernels/src/kernels/quantized.metal similarity index 100% rename from candle-metal-kernels/src/quantized.metal rename to candle-metal-kernels/src/kernels/quantized.metal diff --git a/candle-metal-kernels/src/random.metal b/candle-metal-kernels/src/kernels/random.metal similarity index 100% rename from candle-metal-kernels/src/random.metal rename to candle-metal-kernels/src/kernels/random.metal diff --git a/candle-metal-kernels/src/reduce.metal b/candle-metal-kernels/src/kernels/reduce.metal similarity index 99% rename from candle-metal-kernels/src/reduce.metal rename to candle-metal-kernels/src/kernels/reduce.metal index e009ca1d..d58e66d5 100644 --- a/candle-metal-kernels/src/reduce.metal +++ b/candle-metal-kernels/src/kernels/reduce.metal @@ -104,7 +104,7 @@ METAL_FUNC void argmax( threadgroup T * shared_memory, threadgroup uint * shared_indices ) { - // Elements summed in this block range from dst_id * el_to_sum_per_block + // Elements summed in this block range from dst_id * el_to_sum_per_block // to (dst_id + 1) * el_to_sum_per_block. size_t start_idx = dst_id * el_to_sum_per_block; size_t stop_idx = start_idx + el_to_sum_per_block; @@ -173,7 +173,7 @@ METAL_FUNC void reduce( threadgroup T * shared_memory, T (*fn)(T, T) ) { - // Elements summed in this block range from dst_id * el_to_sum_per_block + // Elements summed in this block range from dst_id * el_to_sum_per_block // to (dst_id + 1) * el_to_sum_per_block. size_t start_idx = dst_id * el_to_sum_per_block; size_t stop_idx = start_idx + el_to_sum_per_block; diff --git a/candle-metal-kernels/src/sort.metal b/candle-metal-kernels/src/kernels/sort.metal similarity index 100% rename from candle-metal-kernels/src/sort.metal rename to candle-metal-kernels/src/kernels/sort.metal diff --git a/candle-metal-kernels/src/ternary.metal b/candle-metal-kernels/src/kernels/ternary.metal similarity index 100% rename from candle-metal-kernels/src/ternary.metal rename to candle-metal-kernels/src/kernels/ternary.metal diff --git a/candle-metal-kernels/src/unary.metal b/candle-metal-kernels/src/kernels/unary.metal similarity index 100% rename from candle-metal-kernels/src/unary.metal rename to candle-metal-kernels/src/kernels/unary.metal diff --git a/candle-metal-kernels/src/kernels/utils.metal b/candle-metal-kernels/src/kernels/utils.metal new file mode 100644 index 00000000..8ee6b4ad --- /dev/null +++ b/candle-metal-kernels/src/kernels/utils.metal @@ -0,0 +1,47 @@ +#pragma once +#include +using namespace metal; + +METAL_FUNC uint nonzero(uint n) { + return n == 0 ? 1 : n; +} + +template +constexpr uint nonzero() { + return N == 0 ? 1 : N; +} + +template +constexpr ushort granularity() { + return nonzero::value>(); +} + +METAL_FUNC uint next_p2(uint x) { + return 1 << (32 - clz(x - 1)); +} + +METAL_FUNC uint prev_p2(uint x) { + return 1 << (31 - clz(x)); +} + +constant uint MAX_SHARED_MEM = 32767; + +template +METAL_FUNC uint max_shared_mem(uint n) { + return min(n, prev_p2(MAX_SHARED_MEM / sizeof(T))); +} + +METAL_FUNC uint get_strided_index( + uint idx, + constant const uint &num_dims, + constant const size_t *dims, + constant const size_t *strides +) { + uint strided_i = 0; + for (uint d = 0; d < num_dims; d++) { + uint dim_idx = num_dims - 1 - d; + strided_i += (idx % dims[dim_idx]) * strides[dim_idx]; + idx /= dims[dim_idx]; + } + return strided_i; +} diff --git a/candle-metal-kernels/src/lib.rs b/candle-metal-kernels/src/lib.rs index 1815dd32..65d7f62b 100644 --- a/candle-metal-kernels/src/lib.rs +++ b/candle-metal-kernels/src/lib.rs @@ -10,21 +10,23 @@ mod utils; pub use utils::BufferOffset; use utils::{get_block_dims, linear_split}; -const AFFINE: &str = include_str!("affine.metal"); -const INDEXING: &str = include_str!("indexing.metal"); -const UNARY: &str = include_str!("unary.metal"); -const BINARY: &str = include_str!("binary.metal"); -const TERNARY: &str = include_str!("ternary.metal"); -const CAST: &str = include_str!("cast.metal"); -const CONV: &str = include_str!("conv.metal"); -const REDUCE: &str = include_str!("reduce.metal"); -const RANDOM: &str = include_str!("random.metal"); -const MFA: &[u8] = include_bytes!("libMetalFlashAttention.metallib"); -const QUANTIZED: &str = include_str!("quantized.metal"); -const SORT: &str = include_str!("sort.metal"); +const AFFINE: &str = include_str!("kernels/affine.metal"); +const INDEXING: &str = include_str!("kernels/indexing.metal"); +const UNARY: &str = include_str!("kernels/unary.metal"); +const BINARY: &str = include_str!("kernels/binary.metal"); +const TERNARY: &str = include_str!("kernels/ternary.metal"); +const CAST: &str = include_str!("kernels/cast.metal"); +const CONV: &str = include_str!("kernels/conv.metal"); +const REDUCE: &str = include_str!("kernels/reduce.metal"); +const RANDOM: &str = include_str!("kernels/random.metal"); +const QUANTIZED: &str = include_str!("kernels/quantized.metal"); +const SORT: &str = include_str!("kernels/sort.metal"); +const MFA: &[u8] = include_bytes!("libraries/libMetalFlashAttention.metallib"); +const CANDLE: &[u8] = include_bytes!("libraries/libMetalFlashAttention.metallib"); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum Source { + Candle, Affine, Indexing, Unary, @@ -200,7 +202,7 @@ impl Kernels { Source::Random => RANDOM, Source::Quantized => QUANTIZED, Source::Sort => SORT, - Source::Mfa => panic!("Invalid lib"), + _ => panic!("Invalid lib"), } } @@ -216,9 +218,15 @@ impl Kernels { Ok(lib.clone()) } else { let lib = match source { + Source::Candle => { + device.new_library_with_data(CANDLE).map_err(|e| { + MetalKernelError::LoadLibraryError(format!( + "Candle metal requires macosx > 13.0 or higher, cannot load candle: {e}" + )) + })? + } Source::Mfa => { - let source_data = MFA; - device.new_library_with_data(source_data).map_err(|e| { + device.new_library_with_data(MFA).map_err(|e| { MetalKernelError::LoadLibraryError(format!( "Candle metal requires macosx > 13.0 or higher, cannot load mfa: {e}" )) diff --git a/candle-metal-kernels/src/libraries/candle.metallib b/candle-metal-kernels/src/libraries/candle.metallib new file mode 100644 index 0000000000000000000000000000000000000000..80bc73699c807119545c218b61ae7564480cad4b GIT binary patch literal 333664 zcmeEP3tSUd_MSY*L_TzE_GcO6fJFSORIHl*KPmj<{=4!qP4AVXMRl1 z%$>{R=CVh87{(Df2?Ab?C*`g&wOu+GW@PhRUopVvL-%FPXJS;0 zfzdDuHYa2LA|{57a8=BjF*}=yxxB)#`{rh358zkjV18LMMrpo&*D#&^+sv4Tl{;vS zm!50?N5T2Xx`(5ih;8{(Tze~$9hlD7Tyhn{%8VACfLy=Z#HL$ezjCSN~w~>rYcCpKpkYUw!Dh-M+iMlk=U2aOq7?iZ zteg1rSO0NX7&-LSyF0$!Hm`%xnccdn`6%nY`+gf-mbCB0UtDfU-EMiT=uR!SHbm9uZLn>H3#u)(9YGhBY2} zrfAXV6Mxz6qW1{fF-{uR0QEG(h}I@;%e4tA=2zjykZ{-S+<8UM#IP0vo>@UKySPbt0p z!O4G)jOC^LC;n8E%QKVPGmmXwJh*2g&s(r1$C+_XH$DRB= z=WJHYA3ChMlE9RA-�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 N&g~BRcjW2F{|5n6zZw7l literal 0 HcmV?d00001 diff --git a/candle-metal-kernels/src/libMetalFlashAttention.metallib b/candle-metal-kernels/src/libraries/libMetalFlashAttention.metallib similarity index 100% rename from candle-metal-kernels/src/libMetalFlashAttention.metallib rename to candle-metal-kernels/src/libraries/libMetalFlashAttention.metallib