Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
929901d
cmake: Exclude subdirectories from all builds
tdarote Feb 2, 2026
b31faa1
Document shuffle + zip interaction in tf.data.Dataset
VibhorGautam Mar 9, 2026
4ee6562
Remove fragile seed-matching example, recommend shuffle-after-zip only
VibhorGautam Jul 4, 2026
7e7ad97
Merge branch 'master' into fix/shuffle-zip-docs
VibhorGautam Jul 13, 2026
ed8d4c1
Fix signed-to-unsigned conversion bug in DatasetRandomAccessCache::Get
Deeven-Seru Jul 24, 2026
3324146
Fix 32-bit index truncation issues per reviewer feedback
Deeven-Seru Jul 25, 2026
c46fe7a
[tf.data] Validate `buffer_size` in shuffle to prevent process crash
tirthfx Jul 29, 2026
66bf279
Address review: validate buffer_size via constant_value, not isinstance
tirthfx Jul 31, 2026
7d43384
Allow a Tensor buffer_size in Dataset.prefetch
abhijeet117 Aug 23, 2026
2bbfb12
Reject non-empty tensors missing tensor_content in ParseFast
vee1e Aug 27, 2026
8aebb14
Update tensor_coding test assertions for ParseSlow fallback and ampli…
vee1e Aug 28, 2026
1c93abb
Merge pull request #111928 from VibhorGautam:fix/shuffle-zip-docs
tensorflower-gardener Aug 31, 2026
5121c32
Use the new XLA GPU autotune cache format by default.
shyamliagrawal Aug 31, 2026
ad3cdcf
Remove StreamExecutorGpuClient and update all references to use Commo…
pschuh Aug 31, 2026
fa0bc06
Prevent fusing AllGather instructions into GEMM fusions.
vwbaker Aug 31, 2026
75cafaf
Automated Code Change
tensorflower-gardener Aug 31, 2026
e059531
Allow visibility of profile_interface and profile_factory prior torch…
ecalubaquib Aug 31, 2026
dbff666
Fix heap buffer overflow in DynamicUpdateSliceInt4 by clamping memcpy…
tensorflower-gardener Aug 31, 2026
3da48b3
Merge pull request #126283 from vee1e:fix/tensor-coding-uninitialized…
tensorflower-gardener Aug 31, 2026
2c5ad30
Merge pull request #125956 from abhijeet117:fix/prefetch-tensor-buffe…
tensorflower-gardener Aug 31, 2026
983dd6e
Merge pull request #123491 from Deeven-Seru:fix-cache-dataset-negativ…
tensorflower-gardener Aug 31, 2026
94f18a7
Automated Code Change
tensorflower-gardener Aug 31, 2026
3f3bfd6
Add FourSigFigs for rounding step time outputs.
bmass02 Aug 31, 2026
7223a98
Merge pull request #124248 from tirthfx:fix/shuffle-dataset-buffer-si…
tensorflower-gardener Aug 31, 2026
8a1b178
PR #47666: [XLA:GPU][oneAPI] Add XPU target check in Triton ThreadDim…
akhilgoe Aug 31, 2026
afc9e6a
Propagate actual failure status to definition event promises in Async…
junwhanahn Aug 31, 2026
a24bc35
Don't DCE tokens in opt barriers. This allows expressing an after rel…
pschuh Aug 31, 2026
66420a1
Add BlockScalingConfig to xla_data.proto and hlo.proto to describe block
tensorflower-gardener Aug 31, 2026
eafe265
[Mosaic TPU] Support packed types strided load with static indices by…
yueshengys Aug 31, 2026
cb2bb36
Merge pull request #109378 from tdarote:optimization-exclude-subdirs
tensorflower-gardener Aug 31, 2026
505c29c
Switch PJRT C API GPU client to use StreamExecutor client directly.
zacmustin Aug 31, 2026
3e1e9b9
[IFRT IR] Add Fingerprint method to IfrtIRProgram
ICGog Sep 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions tensorflow/compiler/mlir/tensorflow/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,7 @@ cc_library(
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/container:node_hash_map",
"@com_google_absl//absl/log",
"@com_google_absl//absl/log:vlog_is_on",
"@llvm-project//llvm:Support",
"@llvm-project//mlir:Analysis",
"@llvm-project//mlir:FuncDialect",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ limitations under the License.
#include "absl/container/flat_hash_set.h"
#include "absl/container/node_hash_map.h"
#include "absl/log/log.h"
#include "absl/log/vlog_is_on.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
Expand Down
1 change: 0 additions & 1 deletion tensorflow/compiler/mlir/tensorflow/ir/tf_ops_a_m.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ limitations under the License.
#include <algorithm>
#include <array>
#include <cassert>
#include <complex>
#include <cstddef>
#include <cstdint>
#include <iterator>
Expand Down
3 changes: 3 additions & 0 deletions tensorflow/core/distributed_runtime/tensor_coding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ bool TensorResponse::ParseTensorSubmessage(
.ok()) {
return false;
}
if (shape.num_elements() != 0) {
return false;
}
Tensor t(allocator_, tensor_meta->dtype(), shape);
tensor_ = std::move(t);
}
Expand Down
58 changes: 58 additions & 0 deletions tensorflow/core/distributed_runtime/tensor_coding_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,64 @@ TEST_F(TensorResponseTest, InitPartialOverflow) {
EXPECT_TRUE(absl::IsInvalidArgument(s));
}

TEST_F(TensorResponseTest, ZeroLengthTensorMissingContentAccepted) {
RecvTensorResponse proto;
proto.set_is_dead(false);
proto.set_send_start_micros(123456);
TensorProto* tensor_proto = proto.mutable_tensor();
tensor_proto->set_dtype(DT_FLOAT);
tensor_proto->mutable_tensor_shape()->add_dim()->set_size(0);

std::string encoded;
proto.AppendToString(&encoded);
StringSource source(&encoded, 1024);
TensorResponse response;
DummyDevice cpu_device(Env::Default());
response.InitAlloc(&cpu_device, AllocatorAttributes());
EXPECT_TRUE(response.ParseFrom(&source).ok());
EXPECT_EQ(response.tensor().NumElements(), 0);
}

TEST_F(TensorResponseTest,
NonEmptyTensorMissingContentZeroInitializedViaSlowPath) {
RecvTensorResponse proto;
proto.set_is_dead(false);
proto.set_send_start_micros(123456);
TensorProto* tensor_proto = proto.mutable_tensor();
tensor_proto->set_dtype(DT_FLOAT);
tensor_proto->mutable_tensor_shape()->add_dim()->set_size(10);

std::string encoded;
proto.AppendToString(&encoded);
StringSource source(&encoded, 1024);
TensorResponse response;
DummyDevice cpu_device(Env::Default());
response.InitAlloc(&cpu_device, AllocatorAttributes());
EXPECT_TRUE(response.ParseFrom(&source).ok());
EXPECT_EQ(response.tensor().NumElements(), 10);
for (int i = 0; i < 10; ++i) {
EXPECT_EQ(response.tensor().flat<float>()(i), 0.0f);
}
}

TEST_F(TensorResponseTest, AmplificationProtoWithoutContentRejected) {
RecvTensorResponse proto;
proto.set_is_dead(false);
proto.set_send_start_micros(123456);
TensorProto* tensor_proto = proto.mutable_tensor();
tensor_proto->set_dtype(DT_FLOAT);
// 1 billion floats = 4GB (> 2GB safe limit) with no tensor_content
tensor_proto->mutable_tensor_shape()->add_dim()->set_size(1000000000);

std::string encoded;
proto.AppendToString(&encoded);
StringSource source(&encoded, 1024);
TensorResponse response;
DummyDevice cpu_device(Env::Default());
response.InitAlloc(&cpu_device, AllocatorAttributes());
EXPECT_FALSE(response.ParseFrom(&source).ok());
}

std::string MakeFloatTensorTestCase(int num_elems) {
std::vector<int8_t> v(num_elems);
for (int i = 0; i < num_elems; i++) {
Expand Down
21 changes: 14 additions & 7 deletions tensorflow/core/kernels/data/cache_dataset_ops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,13 @@ class DatasetRandomAccessCache {
GetIteratorResourceFromDataset(ctx, input_));
TF_RETURN_IF_ERROR(iter_resource_->SetIteratorFromDataset(ctx, input_));
}
if (index >= cache_.size()) {
TF_RETURN_IF_ERROR(ExtendTempCacheToIndex(index, ctx));
}
if (index < 0) {
return absl::InvalidArgumentError(
absl::StrCat("Expected index >= 0; Received index: ", index));
}
if (index >= static_cast<int64_t>(cache_.size())) {
TF_RETURN_IF_ERROR(ExtendTempCacheToIndex(index, ctx));
}
*out_tensors = cache_.at(index);
return absl::OkStatus();
}
Expand All @@ -111,7 +111,7 @@ class DatasetRandomAccessCache {
private:
absl::Status ExtendTempCacheToIndex(int64_t index, OpKernelContext* ctx) {
bool end_of_sequence;
while (cache_.size() <= index) {
while (static_cast<int64_t>(cache_.size()) <= index) {
std::vector<Tensor> out_tensors;
TF_RETURN_IF_ERROR(
iter_resource_->GetNext(ctx, &out_tensors, &end_of_sequence));
Expand Down Expand Up @@ -151,15 +151,22 @@ class IteratorRandomAccessCache {
explicit IteratorRandomAccessCache(const DatasetBase* input)
: input_(input) {}

absl::Status Get(AnyContext ctx, size_t element_position,
absl::Status Get(AnyContext ctx, int64_t element_position,
std::vector<Tensor>* out_tensors) {
if (element_position < cache_.size() && !cache_[element_position].empty()) {
if (element_position < 0) {
return absl::InvalidArgumentError(
absl::StrCat("Element position must be non-negative; Received: ",
element_position));
}

if (element_position < static_cast<int64_t>(cache_.size()) &&
!cache_[element_position].empty()) {
*out_tensors = cache_[element_position];
return absl::OkStatus();
}

TF_RETURN_IF_ERROR(input_->Get(ctx, element_position, out_tensors));
if (element_position >= cache_.size()) {
if (element_position >= static_cast<int64_t>(cache_.size())) {
cache_.resize(element_position + 1);
}
cache_[element_position] = *out_tensors;
Expand Down
12 changes: 10 additions & 2 deletions tensorflow/lite/kernels/dynamic_update_slice.cc
Original file line number Diff line number Diff line change
Expand Up @@ -278,15 +278,23 @@ void DynamicUpdateSliceInt4(const TfLiteTensor* input,
// If the update is the entirety of the output, then simply copy it and
// return.
if (input_shape.FlatSize() == update_shape.FlatSize()) {
memcpy(output_data, update_data, input->bytes);
// Clamp the copy length to the destination size. `input->bytes` is derived
// from the raw FlatBuffer buffer size for constant tensors and may be
// inflated relative to the logical shape, so it must be bounded by
// `output->bytes` to avoid an out-of-bounds write.
memcpy(output_data, update_data, std::min(input->bytes, output->bytes));
return;
}
RuntimeShape clamped_start_indices =
ClampStartIndices(input_dims, indices_data, input_shape, update_shape);

// If the operation is not done in-place, copy the input data to the output.
// Clamp the copy length to the destination size, since `input->bytes` may be
// larger than the output allocation for constant tensors loaded from a
// FlatBuffer model.
size_t bytes = std::min(input->bytes, output->bytes);
if (input->data.data != output->data.data) {
memcpy(output->data.data, input->data.data, input->bytes);
memcpy(output->data.data, input->data.data, bytes);
}

// Update tensor has no elements. Skip.
Expand Down
1 change: 1 addition & 0 deletions tensorflow/lite/tools/cmake/modules/cpuinfo.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,5 @@ set(CPUINFO_BUILD_BENCHMARKS OFF CACHE BOOL "Disable cpuinfo micro-benchmarks")
add_subdirectory(
"${cpuinfo_SOURCE_DIR}"
"${cpuinfo_BINARY_DIR}"
EXCLUDE_FROM_ALL
)
2 changes: 1 addition & 1 deletion tensorflow/lite/tools/cmake/modules/eigen.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,4 @@ set(EIGEN_TEST_SYCL OFF CACHE BOOL "Disable Sycl test")
set(EIGEN_SYCL_TRISYCL OFF CACHE BOOL "Disable triSYCL test")
# Make sure only MPL2.0 or more permissively licensed code is included.
add_compile_definitions(EIGEN_MPL2_ONLY)
add_subdirectory("${eigen_SOURCE_DIR}" "${eigen_BINARY_DIR}")
add_subdirectory("${eigen_SOURCE_DIR}" "${eigen_BINARY_DIR}" EXCLUDE_FROM_ALL)
1 change: 1 addition & 0 deletions tensorflow/lite/tools/cmake/modules/farmhash.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,5 @@ set(FARMHASH_SOURCE_DIR "${farmhash_SOURCE_DIR}" CACHE PATH
add_subdirectory(
"${CMAKE_CURRENT_LIST_DIR}/farmhash"
"${farmhash_BINARY_DIR}"
EXCLUDE_FROM_ALL
)
1 change: 1 addition & 0 deletions tensorflow/lite/tools/cmake/modules/fft2d.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ set(FFT2D_SOURCE_DIR "${fft2d_SOURCE_DIR}" CACHE PATH "fft2d source")
add_subdirectory(
"${CMAKE_CURRENT_LIST_DIR}/fft2d"
"${fft2d_BINARY_DIR}"
EXCLUDE_FROM_ALL
)
1 change: 1 addition & 0 deletions tensorflow/lite/tools/cmake/modules/flatbuffers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ add_definitions(-DNOMINMAX=1)
add_subdirectory(
"${flatbuffers_SOURCE_DIR}"
"${flatbuffers_BINARY_DIR}"
EXCLUDE_FROM_ALL
)
remove_definitions(-DNOMINMAX)

Expand Down
1 change: 1 addition & 0 deletions tensorflow/lite/tools/cmake/modules/gemmlowp.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ set(GEMMLOWP_SOURCE_DIR "${gemmlowp_SOURCE_DIR}" CACHE PATH "Source directory")
add_subdirectory(
"${gemmlowp_SOURCE_DIR}/contrib"
"${gemmlowp_BINARY_DIR}"
EXCLUDE_FROM_ALL
)

set(BUILD_TESTING ${BUILD_TESTING_TMP})
1 change: 1 addition & 0 deletions tensorflow/lite/tools/cmake/modules/neon2sse.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@ endif()
add_subdirectory(
"${neon2sse_SOURCE_DIR}"
"${neon2sse_BINARY_DIR}"
EXCLUDE_FROM_ALL
)
1 change: 1 addition & 0 deletions tensorflow/lite/tools/cmake/modules/ruy.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ set(RUY_SOURCE_DIR "${ruy_SOURCE_DIR}" CACHE PATH "RUY source directory")
add_subdirectory(
"${ruy_SOURCE_DIR}"
"${ruy_BINARY_DIR}"
EXCLUDE_FROM_ALL
)
15 changes: 15 additions & 0 deletions tensorflow/python/data/kernel_tests/prefetch_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from tensorflow.python.data.ops import options as options_lib
from tensorflow.python.data.ops import prefetch_op
from tensorflow.python.framework import combinations
from tensorflow.python.framework import constant_op
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import errors
from tensorflow.python.ops import script_ops
Expand All @@ -40,6 +41,20 @@ def testBufferSize(self, buffer_size):
dataset = dataset_ops.Dataset.range(10).prefetch(buffer_size=buffer_size)
self.assertDatasetProduces(dataset, expected_output=range(10))

@combinations.generate(test_base.default_test_combinations())
def testTensorBufferSize(self):
# `buffer_size` is documented as an int64 scalar `tf.Tensor`.
dataset = dataset_ops.Dataset.range(10).prefetch(
buffer_size=constant_op.constant(2, dtypes.int64)
)
self.assertDatasetProduces(dataset, expected_output=range(10))

# A tensor holding the AUTOTUNE value keeps autotuning enabled.
dataset = dataset_ops.Dataset.range(10).prefetch(
buffer_size=constant_op.constant(-1, dtypes.int64)
)
self.assertDatasetProduces(dataset, expected_output=range(10))

@combinations.generate(
combinations.times(test_base.eager_only_combinations(),
combinations.combine(buffer_size=[0, 1, 2, 42])))
Expand Down
14 changes: 14 additions & 0 deletions tensorflow/python/data/kernel_tests/shuffle_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,20 @@ def testDefaultArguments(self):
for i in range(5):
self.assertEqual(10, counts[i])

@combinations.generate(test_base.default_test_combinations())
def testExcessiveBufferSize(self):
dataset = dataset_ops.Dataset.from_tensor_slices([1, 2, 3, 4, 5])
with self.assertRaisesRegex(ValueError, "buffer_size"):
dataset.shuffle(buffer_size=sys.maxsize)
with self.assertRaisesRegex(ValueError, "buffer_size"):
dataset.shuffle(buffer_size=2**31 - 1)
with self.assertRaisesRegex(ValueError, "buffer_size"):
dataset.shuffle(buffer_size=np.int64(2**31 - 1))
with self.assertRaisesRegex(ValueError, "buffer_size"):
dataset.shuffle(
buffer_size=constant_op.constant(2**31 - 1, dtype=dtypes.int64)
)

@combinations.generate(
combinations.times(
test_base.default_test_combinations(),
Expand Down
21 changes: 21 additions & 0 deletions tensorflow/python/data/ops/dataset_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,12 @@ def zip(*args, datasets=None, name=None) -> "DatasetV2":
>>> [(i.item(), j.item()) for i, j in ds.as_numpy_iterator()]
[(1, 13), (2, 14)]

Note: `zip` iterates its input datasets in parallel. If one dataset has
been shuffled and another has not, the element correspondence from the
original order will be lost. To keep elements aligned after shuffling,
apply `shuffle` after `zip` rather than before it. See
`tf.data.Dataset.shuffle` for more details.

Args:
*args: Datasets or nested structures of datasets to zip together. This
can't be set if `datasets` is set.
Expand Down Expand Up @@ -1492,6 +1498,21 @@ def shuffle(
# [18, 4, 9, 2, 17, 8, 5, 10, 0, 6, 16, 3, 19, 7, 14, 11, 15, 13, 12, 1]
```

#### Using shuffle with zip

When you `shuffle` a dataset and then `zip` it with an unshuffled dataset,
the element pairing will not match the original order because each input
dataset is iterated independently. If you need to shuffle multiple datasets
while preserving the correspondence between their elements, you should
shuffle after zipping:

```python
# Correct: shuffle after zipping to keep pairs aligned.
a = tf.data.Dataset.range(3)
b = tf.data.Dataset.range(3)
dataset = tf.data.Dataset.zip(a, b).shuffle(3)
```

Args:
buffer_size: An int or `tf.int64` scalar `tf.Tensor`, representing the
number of elements from this dataset from which the new dataset will
Expand Down
14 changes: 12 additions & 2 deletions tensorflow/python/data/ops/prefetch_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from tensorflow.python.data.ops import debug_mode
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import ops
from tensorflow.python.framework import tensor_util
from tensorflow.python.ops import gen_dataset_ops


Expand All @@ -39,6 +40,14 @@ def __init__(self, input_dataset, buffer_size, slack_period=None, name=None):
self._buffer_size = ops.convert_to_tensor(
buffer_size, dtype=dtypes.int64, name="buffer_size")
self._name = name
# `legacy_autotune` must be a Python bool, so decide from the statically
# known value of the converted `buffer_size`; it is None for symbolic
# tensors, which then use the non-legacy path.
buffer_size_constant = tensor_util.constant_value(self._buffer_size)
legacy_autotune = (
buffer_size_constant is not None
and int(buffer_size_constant) == dataset_ops.AUTOTUNE
)
# pylint: disable=protected-access
# We colocate the prefetch dataset with its input as this collocation only
# happens automatically in graph mode.
Expand All @@ -47,6 +56,7 @@ def __init__(self, input_dataset, buffer_size, slack_period=None, name=None):
input_dataset._variant_tensor,
buffer_size=self._buffer_size,
slack_period=slack_period,
legacy_autotune=(buffer_size == dataset_ops.AUTOTUNE),
**self._common_args)
legacy_autotune=legacy_autotune,
**self._common_args
)
super().__init__(input_dataset, variant_tensor)
20 changes: 20 additions & 0 deletions tensorflow/python/data/ops/shuffle_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,16 @@
from tensorflow.python.eager import context
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import ops
from tensorflow.python.framework import tensor_util
from tensorflow.python.ops import gen_dataset_ops

# Sanity limit on the number of elements in the shuffle buffer. The C++
# kernel eagerly allocates a slot for every element up to `buffer_size` when
# the iterator is created, so a pathologically large value (e.g.
# `sys.maxsize`) reaches that allocation and crashes the process instead of
# raising a catchable error.
_MAX_SHUFFLE_BUFFER_SIZE_ELEMENTS = 1 << 30 # ~1 billion elements


def _shuffle( # pylint: disable=unused-private-name
input_dataset,
Expand Down Expand Up @@ -48,6 +56,18 @@ def __init__(
self._input_dataset = input_dataset
self._buffer_size = ops.convert_to_tensor(
buffer_size, dtype=dtypes.int64, name="buffer_size")
constant_buffer_size = tensor_util.constant_value(self._buffer_size)
if (
constant_buffer_size is not None
and constant_buffer_size > _MAX_SHUFFLE_BUFFER_SIZE_ELEMENTS
):
raise ValueError(
"`buffer_size` must not exceed "
f"{_MAX_SHUFFLE_BUFFER_SIZE_ELEMENTS} elements, but got "
f"{constant_buffer_size}. Requesting a shuffle buffer this large "
"would cause the dataset to abort the process instead of raising "
"a catchable error."
)
self._seed, self._seed2 = random_seed.get_seed(seed)
self._reshuffle_each_iteration = reshuffle_each_iteration
self._name = name
Expand Down
Loading
Loading