[pull] master from tensorflow:master - #8786
Merged
Merged
Conversation
convert() called _load() (tf.saved_model.load) solely to obtain graph_debug_info, which is the GraphDebugInfo proto stored on disk alongside saved_model.pb. For large models like DenseNet121, _load() allocates ~25 MB of variable tensors and registers the model's function defs in TF's C++ EagerContext. Reference cycles in the resulting trackable object graph caused these allocations to survive the explicit `del trackable_obj; gc.collect()` call, producing ~22 MB of leaked RSS per convert() invocation (issue #122598). Fix: replace _load() with _parse_saved_model_with_debug_info(), which reads the debug info proto directly from disk without loading any model weights or registering EagerContext function defs. This function is already imported in lite.py. Since _convert_debug_info_func() ignores original_nodes and returns the proto unchanged, the function-name adjustment performed by _load()'s adjust_debug_info_func_names() has no effect on the TFLite C++ conversion pipeline, making the raw proto equally correct. Also remove the now-unused `import gc`. Add regression test testConvertDoesNotCallLoad that mocks lite._load and asserts it is never called during convert(), then verifies the converted model produces correct inference results.
…info Three issues raised in review: 1. The remote branch had a bad merge commit (c74f815) that accidentally discarded the lite.py fix. This force-push restores the correct state: the _load() block is removed and replaced with _parse_saved_model_with_debug_info() as originally intended. 2. In testConvertDoesNotCallLoad, save.save() was called without the concrete function, which can produce an empty signature set and cause TFLiteConverterV2.from_saved_model() to fail with: ValueError: Only support at least one signature key. Fix: capture the concrete function and pass it explicitly as the signatures argument to save.save(). 3. Regarding adjust_debug_info_func_names: add a comment explaining why it is not needed. _convert_debug_info_func() (util.py:382) does `del original_nodes` and returns saved_debug_info unchanged, so the function-name adjustment that _load() applies via adjust_debug_info_func_names() has no effect on the TFLite pipeline regardless of which path is taken. The on-disk proto contains the names as written at save() time, which is what the TFLite C++ pipeline uses for source-location tracking.
TensorFlow Lite currently has no OSS-Fuzz coverage. The 29 fuzz targets built
by projects/tensorflow cover TF core ops, framework types, path/string helpers
and the graph/SavedModel loaders, but nothing under tensorflow/lite: the builtin
kernels, the arena planner and the shape-propagation paths are unfuzzed.
This adds a single end-to-end harness. An arbitrary buffer is verified as a
flatbuffer model, an interpreter is built for it, tensors are allocated, inputs
are filled deterministically and the graph is invoked. That reaches the builtin
kernel implementations through the same path a real caller uses.
Notes on the harness:
* VerifyAndBuildFromBuffer runs tflite::VerifyModelBuffer first, so
structurally invalid buffers are rejected cheaply rather than being fed to
the interpreter.
* BuiltinOpResolverWithoutDefaultDelegates is used so the fuzzer exercises the
reference and optimized CPU kernels rather than a delegate's own
implementation.
* Model size and total input-arena size are bounded (1 MiB / 64 MiB) to keep
runs inside the OSS-Fuzz memory budget; larger models exercise the allocator
rather than the kernels.
* String, resource and variant inputs are skipped: those tensors own a
dynamic buffer with its own layout, and writing raw bytes into it would
corrupt interpreter state instead of testing a kernel.
Avoids any possibility of total_bytes wrapping before the limit is compared.
ResizeOutputTensor checks that every entry of `perm` is in [-dims, dims), but
never that the entries form a permutation of [0, dims). A repeated entry passes
the range check.
Both the output shape and the element offsets are derived from `perm`:
output_size->data[idx] = input_size->data[new_perm_data[idx]];
so with `perm = {0, 0}` on an input of shape [3, N] the output is sized [3, 3]
while the offsets the kernel computes for it are those of a [3, N] traversal.
The two disagree, and the transpose reads outside the input tensor. The values
read are copied into the output, so they are observable by the caller.
TensorFlow's own Transpose op already enforces this
(tensorflow/core/kernels/transpose_op.cc): it records each index in a `bits`
array and then requires every position to have been seen, rejecting
`{0, 0}` with "0 is missing from {0,0}". The TFLite kernel was missing the
equivalent check.
Track which normalised indices have been used and reject duplicates. The check
runs after negative entries are normalised, so `{0, -2}` on a rank-2 input is
rejected as well. Valid permutations are unaffected.
Adds two regression tests alongside the existing TestPermOutOfBounds.
Prepare() returns early when the output shape is fully specified, leaving the output static. Eval() only re-runs ResizeOutputShape() for a dynamic output, so CalculateOutputShapeVector() -- the one place begin and size are checked against the input -- never runs. When the input has an unspecified dimension the declared output shape says nothing about whether the slice fits the actual extent, and the kernel reads past the input. Fall through when the input has an unspecified dimension so the output is marked dynamic and the bounds are validated on every invocation.
Avoids a heap allocation in the kernel. dims is bounded by kTransposeMaxDimensions (8), enforced in Prepare() before this function is reachable, so 64 bits are sufficient; asserted at compile time.
Adds the two tests requested in review, covering a dynamic input dimension with a statically declared output shape: an in-bounds slice that must succeed and mark the output dynamic, and an out-of-bounds window that must be rejected. The suite is named SliceOpDynamicInputTest rather than SliceOpTest because the latter is a TEST_P fixture, and gtest rejects a suite that mixes TEST and TEST_P. Also checks ShapeHasRank before HasUnspecifiedDimension for both tensors. An unranked or scalar shape would otherwise take the early return and skip validation, since HasUnspecifiedDimension only inspects dims_signature.
A delegate that claims the SLICE node sets the output allocation type itself, so the kTfLiteDynamic assertion and the out-of-bounds error check would no longer describe the built-in CPU kernel. XNNPACK does handle BuiltinOperator_SLICE, so this is reachable whenever a delegate is supplied via the test delegate providers. AllocateTensors() still runs, since allocate_and_delegate defaults to true.
PiperOrigin-RevId: 972062503
…er-memory-leak PiperOrigin-RevId: 972084818
PjRtCpuClient::LoadSerializedExecutable. PiperOrigin-RevId: 972088010
… donate twice PiperOrigin-RevId: 972090625
PiperOrigin-RevId: 972106935
PiperOrigin-RevId: 972118327
This pass removes unnecessary size-1 from the module. Degenerate dimensions are generally no-op, but it add unnecessary reshapes/bitcasts to the graph that can sometime prevent better fusion and tiling decision or cause problem with emitter pipelines, like Triton. PiperOrigin-RevId: 972126534
PiperOrigin-RevId: 972146467
backends which are known to only support a single hlo module. PiperOrigin-RevId: 972151130
Reverting due to compilation failure when handling complex types during TPU lowering: passing Zero(builder, type) where Abs(a) produces a real scalar causes type mismatch and HLO verification/compilation failure. Reverts 6ae3d02 PiperOrigin-RevId: 972162896
memref.subview expects standard strided or identity layouts and does not support #xtile.layout, which breaks the verification. PiperOrigin-RevId: 972166650
Adds `StatType::kDimensions` ("dims") and `StatType::kType` ("type") to the TSL profiler XPlane schema to support events with individual dimension and data type attributes.
PiperOrigin-RevId: 972166901
…uctions. In preparation for supporting thread filtering in buffer assignment, this change removes the restriction in the HLO verifier that prevents call instructions from having output-to-operand aliasing. This allows call instructions to specify input/output aliasing. PiperOrigin-RevId: 972174275
…ation PiperOrigin-RevId: 972176367
… fusions. PiperOrigin-RevId: 972181976
… loops in Memory Space Assignment. PiperOrigin-RevId: 972189121
Imported from GitHub PR openxla/xla#47522 📝 Summary of Changes Move ROCm CI to use upcoming ROCm 10 🎯 Justification In order to match JAX CI 🚀 Kind of Contribution ✨ New Feature 📊 Benchmark (for Performance Improvements) N\A 🧪 Unit Tests: None 🧪 Execution Tests: None Copybara import of the project: -- 0555bf88e02ff894acb63b22251ec5decf762aec by Dragan Mladjenovic <Dragan.Mladjenovic@amd.com>: [ROCm] Move CI to rocm 7.14 take two -- 95b0f3e4d9e79c3b17c425608af672bedf65da3b by Dragan Mladjenovic <Dragan.Mladjenovic@amd.com>: Fix LLVM symbol clash w/o --dynamic-mode=off -- 1319f537b000c46e3a4f474535e7454edb5c1362 by Dragan Mladjenovic <Dragan.Mladjenovic@amd.com>: Remove dup --local_test_jobs=1 -- be17fac4960b2349db3e7b71bc1e4d5ed81da0af by Dragan Mladjenovic <Dragan.Mladjenovic@amd.com>: Use rocm-dev-infra -- 5a27cc86870c7ad05a2d47bfbabf1fee347db311 by Dragan Mladjenovic <Dragan.Mladjenovic@amd.com>: Move to ROCm 10 -- 24b4136130b5ee7bb648a182423ea1a0dab60c5a by Dragan Mladjenovic <Dragan.Mladjenovic@amd.com>: Avoid bzlmod for hermetic rocm path -- 1b5690ac3d9afe5cc3f2c6b96398fe8cd982b9b3 by Dragan Mladjenovic <Dragan.Mladjenovic@amd.com>: Update rocm-distro-url to stable Merging this change closes #47522 PiperOrigin-RevId: 972195867
This change fixes two problems in RamFileBlockCache. First, RamFileBlockCache::Flush() would remove blocks from the cache and its associated lists without setting the blocks' timestamps to 0. If a block was in the process of being fetched at that time, the "reconcile_state" cleanup callback in MaybeFetch() would treat the lra_iterator as valid, when it in fact it may have been made invalid. Second, if RamFileBlockCache::RemoveFile() were called and removed a block that was in the process of being fetched, RemoveBlock() would access the block's data field (by using data.capacity()), racing with MaybeFetch(), which sets that field. Even if the race were otherwise considered harmless, this might cause the cache_size_ field no longer to reflect the true size of the cache. This change addresses the first problem by making Flush() use code similar to RemoveFile(), thus using RemoveBlock() on every block. RemoveBlock() resets the block's timestamp field to zero. It addresses the second problem by checking the block's state field before accessing the data field, performing the access only if the state is FINISHED. The block's size is not counted in cache_size_ unless the state is FINISHED, and once the state is FINISHED, the data field is immutable, and can be read at will. I added/modified comments that would have helped me understand the code's synchronization invariants, in the hope that they will help future maintainers. PiperOrigin-RevId: 972217969
…ves them with other dimension types. If they are transposed within themselves, then this is okay as it won't affect the stores within a kernel. PiperOrigin-RevId: 972226337
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )