fix(docs): the documented 'metal' delegate throws unconditionally - #199
Open
giaBaoJS wants to merge 1 commit into
Open
fix(docs): the documented 'metal' delegate throws unconditionally#199giaBaoJS wants to merge 1 commit into
'metal' delegate throws unconditionally#199giaBaoJS wants to merge 1 commit into
Conversation
The migration guide told users to migrate to `useTensorflowModel(source, ['metal'])`, but `getMetalDelegate()` in `cpp/TfliteHelpers.cpp` unconditionally throws, so that exact snippet fails 100% of the time on every platform. - README: the feature list advertised Metal as a supported GPU delegate; name the delegates that actually have an implementation instead. - MIGRATION_V2_TO_V3.md: use `'core-ml'` in the array-migration example and document that `'metal'` is not implemented. - Tflite.nitro.ts: document each delegate on `TensorflowModelDelegate` and mark `'metal'` as deprecated/not implemented. The union is unchanged, so this is not a breaking type change and `nitrogen` output is unaffected. - TfliteHelpers.cpp: the error message now names the delegates that work. - example/ios/Podfile: drop `$EnableMetalDelegate`, which the podspec never reads (it only reads `$EnableCoreMLDelegate`). Also fixes three stale doc comments: `loadTensorflowModel`/ `useTensorflowModel` still claimed `delegates` "uses the standard CPU delegate per default" after it became a required positional parameter, and a comment example referenced the removed `'default'` delegate.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The contradiction
The v2 → v3 migration guide instructs users to migrate to the
'metal'delegate:https://github.com/mrousavy/react-native-fast-tflite/blob/691f4b8/MIGRATION_V2_TO_V3.md#L38-L41
That exact "after" snippet fails 100% of the time, on every platform.
cpp/TfliteHelpers.cpp#L149-L151:There is no
#ifdefand no build flag around it — unlikegetCoreMLDelegate()(#ifdef __APPLE__/#if FAST_TFLITE_ENABLE_CORE_ML,TfliteHelpers.cpp#L133-L147),getNNAPIDelegate()(#ifdef ANDROID) andgetAndroidGPUDelegate()(#ifdef ANDROID).getMetalDelegate()is the only one whose body is a bare, unconditionalthrow.The reachable path is unconditional too:
createModelloops over every requested delegate and callsgetDelegate(), which routesMETALstraight there —HybridTfliteModule.cpp#L18-L31and#L46-L49. So the throw happens during model creation, before the interpreter is built.Three more places repeat the claim:
README.md#L15— "Supports GPU-accelerated delegates (CoreML/Metal/OpenGL)". The### Using GPU Delegatessection below it only documents CoreML and Android GPU/NNAPI, so the feature bullet is the only place Metal is promised.example/ios/Podfile#L18—$EnableMetalDelegate=true. The podspec never reads that global; it reads only$EnableCoreMLDelegateand only definesFAST_TFLITE_ENABLE_CORE_ML(react-native-fast-tflite.podspec#L5-L9,#L29-L31). Setting it does nothing — it reads as "this is the switch that turns Metal on", which is the most misleading part of the whole story.src/specs/Tflite.nitro.ts#L4—'metal'is an undocumented member of the publicTensorflowModelDelegateunion, so autocomplete offers it as an equal peer of'core-ml'.What this PR changes
Documentation and one error message. No behaviour change, no type-level breaking change.
README.mdMIGRATION_V2_TO_V3.md'core-ml'; new short section documents that'metal'is not implementedsrc/specs/Tflite.nitro.tsTensorflowModelDelegatedocumenting each member, and that'metal'is deprecated / not implementedcpp/TfliteHelpers.cppexample/ios/Podfile$EnableMetalDelegate=trueThree stale doc comments fixed in passing
delegatesbecame a required positional parameter, but both doc comments still described it as optional with a default:src/loadTensorflowModel.ts#L25andsrc/useTensorflowModel.ts#L27: "Uses the standard CPU delegate per default" — there is no default; you must pass[]. (docs: add required delegates array to README examples #182 fixed the README examples but not these.) They also pointed users atmetalas a GPU-accelerated option.src/useTensorflowModel.ts#L53: the comment example['core-ml', 'default']references'default', which the same migration guide documents as removed and which no longer typechecks.Deprecate vs. remove
'metal'I deprecated it in place rather than removing it from the union. Happy to switch if you'd rather — the reasoning:
['metal']in their source compiles today (it only throws at runtime). Removing the member turns that into a build error. Deciding whether that break is worth taking, and in which release, is your call — it doesn't belong in a docs-correctness PR.'metal'is member0of the generatedTensorflowModelDelegateenum (nitrogen/generated/shared/c++/TensorflowModelDelegate.hpp#L32-L35). Dropping it shiftsCORE_ML1→0,NNAPI2→1,ANDROID_GPU3→2 across the generated JSI converters, and requires deletinggetMetalDelegate()fromcpp/TfliteHelpers.cpp+cpp/TfliteHelpers.hppand theMETALcase fromcpp/HybridTfliteModule.cpp.cpp/TfliteHelpers.cpp; fix: skip unavailable delegates and free delegates on model destruction #197 and feat: implement dispose() for deterministic native resource release #198 editcpp/HybridTfliteModule.cpp. As it stands this PR merges cleanly with all three (verified locally with a trial merge of fix(ios): zero-initialize TfLiteCoreMlDelegateOptions #196, the only one sharing a file with this PR — clean).Honest caveat about the deprecation: I first tried a per-member
/** @deprecated */JSDoc directly on| 'metal'. I checked whether TypeScript actually surfaces it, and it does not — querying the TS 5.3.3 language service for completions at aTensorflowModelDelegateposition returnskindModifiers: ""for every member, so there is no strikethrough on string-literal union members. (Prettier also collapses the union onto one line when a comment is inserted mid-union, which made the diff noisier for no gain.) So I moved the documentation to the type alias, wheregetQuickInfoAtPositiondoes return it — hoveringTensorflowModelDelegatenow shows the per-delegate list including the Metal warning. I'd rather say that plainly than imply a strikethrough that doesn't exist.I have not claimed anywhere that Metal could or should be implemented — I only checked what the code does today, not what it would take to add.
Verification
yarn typecheck— passesyarn lint— passesnpx clang-format --dry-run -Werror cpp/TfliteHelpers.cpp— clean (CI uses clang-format 16; checked with 17)npx nitrogen— regeneratesnitrogen/generated/**byte-identically, confirming the JSDoc-only spec change does not affect generated native codeconst d: TensorflowModelDelegate = 'metal',loadTensorflowModel(src, ['metal'])anduseTensorflowModel(src, [d])against this branch — 0 errors, so no existing user code breaksyarn testcurrently fails onmainfor unrelated reasons (Babel/jest config), untouched here.