fix: Unity環境でのBF16カーネルクラッシュを修正 (MSLバージョン明示指定) - #1
Conversation
Unity等のホストプロセスがデプロイメントターゲットに基づきMSL 2.4をデフォルト使用するため、 __METAL_VERSION__ < 310となりBF16カーネル(kernel_mul_mm_bf16_f32)のコンパイルが失敗する。 MTLCompileOptions.languageVersionを明示的に設定することで修正。 Refs: ailia-ai/ailia-llm#220 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Unity (2022.3) 環境で BF16 カーネルが Metal シェーダーの MSL バージョン差異によりコンパイル失敗しクラッシュする問題を、MTLCompileOptions.languageVersion の明示指定で回避する PR です。
Changes:
- Metal シェーダーコンパイル時に MSL 3.1 / 3.2 を OS バージョンで明示指定
- メインライブラリ初期化とソースからのテストコンパイルの両方に同様の指定を追加
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (@available(macOS 14.0, iOS 17.0, *)) { | ||
| options.languageVersion = MTLLanguageVersion3_2; | ||
| } else if (@available(macOS 13.0, iOS 16.0, *)) { | ||
| options.languageVersion = MTLLanguageVersion3_1; | ||
| } |
There was a problem hiding this comment.
@available はランタイム分岐なので、ビルドに使用する Metal/SDK ヘッダで MTLLanguageVersion3_2/MTLLanguageVersion3_1 が未定義の場合はコンパイル自体が失敗します(Unity CI や古い Xcode を許容している場合に顕在化)。#if defined(MTLLanguageVersion3_2) / #if defined(MTLLanguageVersion3_1) のようなコンパイル時ガードを併用し、未定義環境では languageVersion を設定しない(もしくは利用可能な最大の定数に落とす)形にしてください。
| if (@available(macOS 14.0, iOS 17.0, *)) { | |
| options.languageVersion = MTLLanguageVersion3_2; | |
| } else if (@available(macOS 13.0, iOS 16.0, *)) { | |
| options.languageVersion = MTLLanguageVersion3_1; | |
| } | |
| #if defined(MTLLanguageVersion3_2) | |
| if (@available(macOS 14.0, iOS 17.0, *)) { | |
| options.languageVersion = MTLLanguageVersion3_2; | |
| } | |
| #if defined(MTLLanguageVersion3_1) | |
| else if (@available(macOS 13.0, iOS 16.0, *)) { | |
| options.languageVersion = MTLLanguageVersion3_1; | |
| } | |
| #endif | |
| #elif defined(MTLLanguageVersion3_1) | |
| if (@available(macOS 13.0, iOS 16.0, *)) { | |
| options.languageVersion = MTLLanguageVersion3_1; | |
| } | |
| #endif |
| // Fix: Explicitly set MSL version to ensure BF16 kernel availability | ||
| // Unity and other host processes may default to MSL 2.4 due to their deployment target, | ||
| // which causes __METAL_VERSION__ < 310 and disables BF16 support | ||
| if (@available(macOS 14.0, iOS 17.0, *)) { | ||
| options.languageVersion = MTLLanguageVersion3_2; | ||
| } else if (@available(macOS 13.0, iOS 16.0, *)) { | ||
| options.languageVersion = MTLLanguageVersion3_1; | ||
| } |
There was a problem hiding this comment.
同一の languageVersion 設定ロジックが 2 箇所に重複しています。今後 MSL の条件や対象プラットフォームを追加する際に差分/不整合が起きやすいので、MTLCompileOptions * を受け取って languageVersion を設定する静的ヘルパー関数に抽出して 2 箇所から呼び出す形にすると保守性が上がります。
| // Unity and other host processes may default to MSL 2.4 due to their deployment target, | ||
| // which causes __METAL_VERSION__ < 310 and disables BF16 support | ||
| if (@available(macOS 14.0, iOS 17.0, *)) { | ||
| options.languageVersion = MTLLanguageVersion3_2; | ||
| } else if (@available(macOS 13.0, iOS 16.0, *)) { | ||
| options.languageVersion = MTLLanguageVersion3_1; | ||
| } |
There was a problem hiding this comment.
この @available(macOS ..., iOS ..., *) は tvOS / Mac Catalyst など別ターゲットでビルドする場合に条件指定が不十分になる可能性があります(例えば tvOS ターゲットでは tvOS 17.0 の明示が必要)。本リポジトリがそれらのターゲットをサポートしている場合は、@available のプラットフォーム列に tvOS を加える、もしくはターゲットごとに TARGET_OS_* で分岐して適切な @available を書く形にしてください。
| // Unity and other host processes may default to MSL 2.4 due to their deployment target, | |
| // which causes __METAL_VERSION__ < 310 and disables BF16 support | |
| if (@available(macOS 14.0, iOS 17.0, *)) { | |
| options.languageVersion = MTLLanguageVersion3_2; | |
| } else if (@available(macOS 13.0, iOS 16.0, *)) { | |
| options.languageVersion = MTLLanguageVersion3_1; | |
| } | |
| // Unity and other host processes may default to an older MSL due to their deployment target, | |
| // which causes __METAL_VERSION__ < 310 and disables BF16 support. | |
| #if TARGET_OS_TV | |
| if (@available(tvOS 17.0, *)) { | |
| options.languageVersion = MTLLanguageVersion3_2; | |
| } else if (@available(tvOS 16.0, *)) { | |
| options.languageVersion = MTLLanguageVersion3_1; | |
| } | |
| #elif TARGET_OS_MACCATALYST | |
| if (@available(macCatalyst 17.0, *)) { | |
| options.languageVersion = MTLLanguageVersion3_2; | |
| } else if (@available(macCatalyst 16.0, *)) { | |
| options.languageVersion = MTLLanguageVersion3_1; | |
| } | |
| #else | |
| if (@available(macOS 14.0, iOS 17.0, *)) { | |
| options.languageVersion = MTLLanguageVersion3_2; | |
| } else if (@available(macOS 13.0, iOS 16.0, *)) { | |
| options.languageVersion = MTLLanguageVersion3_1; | |
| } | |
| #endif |
古いSDKでMTLLanguageVersion3_2/3_1が未定義の場合のコンパイルエラーを防止。 重複コードをstatic関数に抽出して保守性を向上。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MTLLanguageVersionはenum値のため#if definedでは検出できない。 __MAC_OS_X_VERSION_MAX_ALLOWED等のSDKバージョンマクロを使用し、 古いSDKでの未定義エラーと未使用パラメータ警告を防止。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
概要
Unity (2022.3) 環境でGemma4等のBF16ウェイトを持つモデルを実行した際、Metalシェーダーのコンパイルエラーによりクラッシュする問題を修正します。
原因
Unity等のホストプロセスはデプロイメントターゲットに基づきMetal Shading Language (MSL) 2.4をデフォルトで使用します。これにより
__METAL_VERSION__ < 310となり、BF16カーネル (kernel_mul_mm_bf16_f32) のコンパイルが失敗します。修正内容
ggml-metal-device.mにggml_metal_set_language_versionヘルパー関数を追加し、MTLCompileOptions設定箇所2か所から呼び出すようにしました:ggml_metal_library_init- メインライブラリのコンパイルggml_metal_library_init_from_source- テンソルAPI (BF16含む) のテストコンパイルmacOS 14.0+ / iOS 17.0+ の場合は MSL 3.2、macOS 13.0+ / iOS 16.0+ の場合は MSL 3.1 を明示的に要求します。SDKバージョンマクロ (
__MAC_OS_X_VERSION_MAX_ALLOWED/__IPHONE_OS_VERSION_MAX_ALLOWED) によるコンパイル時ガードを併用し、古いSDKでのコンパイルエラーを防止しています。検証状況
Note: CIで
windows-latest (cpu-x64 static)のtest-arg-parserが失敗していますが、Windows CTestのスタックバッファオーバーラン (0xc0000409) であり、本修正とは無関係です。関連
🤖 Generated with Claude Code