Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
87372d7
Add AArch64 oneDNN async module repo
cfRod Sep 7, 2026
b599ff6
Validate axis bounds in experimental.numpy reduction functions
kaivalya-cyber Sep 18, 2026
bb4d7e2
Handle scalar and 0-d array axes in reduction axis validation
kaivalya-cyber Sep 18, 2026
f137c3e
Expect ValueError for out-of-bounds reduction axis in testReductionOf…
kaivalya-cyber Sep 22, 2026
a712eb4
Reject negative integer powers on GPU
GodlyDonuts Sep 22, 2026
094f260
Simplify GPU Pow validation callback
GodlyDonuts Sep 22, 2026
6a1d236
Retain GPU validation tensor safely
GodlyDonuts Sep 22, 2026
05f42d2
Use valid integer exponents in generated GPU Pow tests
GodlyDonuts Sep 23, 2026
8084b92
Declare Abseil status dependency for GPU integer Pow
GodlyDonuts Sep 24, 2026
1e52bce
Account for input aliasing in forward-mode function caches
bhushanasati25 Sep 25, 2026
5d0d0f9
Merge remote-tracking branch 'origin/master' into fix/np-reduce-axis-…
kaivalya-cyber Sep 25, 2026
409ead9
Guard GPU-only integer Pow header in CPU builds
GodlyDonuts Sep 25, 2026
fb411ed
Iterate forward-mode cache inputs without concatenation
bhushanasati25 Sep 25, 2026
6ad8816
[XLA] Upgrade nanobind to da42c8a5890eff09e672e7cfd953627655aa3e28
hawkinsp Sep 27, 2026
1a01b64
[XLA:GPU][AMD] Disable topk_special_floats_test to unblock presubmits.
pifon2a Sep 27, 2026
659a0a5
[XLA:CPU] Remove redundant passes from the new XTile compilation pipe…
pifon2a Sep 27, 2026
5ad2263
[XLA] Extend HLO kDot with block scaling and sparsity.
sashabu Sep 27, 2026
7d5b984
[XLA:CPU] Cap vector tile size and unroll large or batched vector.tra…
pifon2a Sep 27, 2026
98b4ae0
Reverts f87634eaff1171e67c8d98cb04198cf168fc4c98
tensorflower-gardener Sep 27, 2026
66585ca
[XLA] Cache xla.range for apply_indexing op.
pifon2a Sep 27, 2026
3df6868
Optimize tflite::reference_ops::StridedSlice via contiguous dimension…
tensorflower-gardener Sep 28, 2026
1bed4d3
Merge pull request #127873 from GodlyDonuts:codex/reject-negative-gpu…
tensorflower-gardener Sep 28, 2026
89ba87d
PR #49586: [ROCm]Add rocm_platform_test.
linchen1-robot Sep 28, 2026
9725c54
[XLA:GPU] Fix out-of-bounds index handling in ScatterDeterminismExpander
akuegel Sep 28, 2026
01f1f55
Merge pull request #127606 from kaivalya-cyber:fix/np-reduce-axis-bounds
tensorflower-gardener Sep 28, 2026
e1a22a9
Mutex guard cuDNN compilation handle.
derdrdirk Sep 28, 2026
96aebc2
Add constant folding pass before fusing convolutions.
derdrdirk Sep 28, 2026
57e6215
[XLA:GPU] Allow a symbolic TilingSpace to be cloned into another MLIR…
Moerafaat Sep 28, 2026
749b510
Merge pull request #128029 from bhushanasati25:fix-nested-forward-acc…
tensorflower-gardener Sep 28, 2026
bf313a7
Merge pull request #127109 from cfRod:onednn-aarch64-async-propagation
tensorflower-gardener Sep 28, 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 MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ use_repo(
"nvshmem",
"onednn",
"onednn_async",
"onednn_async_aarch64",
"pthreadpool",
"raft",
"riegeli",
Expand Down
10 changes: 10 additions & 0 deletions tensorflow/core/kernels/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -3821,6 +3821,15 @@ tf_kernel_library(
deps = MATH_DEPS + ["//tensorflow/core:framework_internal"],
)

tf_kernel_library(
name = "integer_pow_gpu",
prefix = "integer_pow_gpu",
deps = MATH_DEPS + [
"//tensorflow/core:framework_internal",
"@com_google_absl//absl/status",
],
)

tf_kernel_library(
name = "cross_op",
prefix = "cross_op",
Expand All @@ -3842,6 +3851,7 @@ tf_kernel_library(
),
prefix = "cwise_op",
deps = MATH_DEPS + [
":integer_pow_gpu",
"//tensorflow/core/kernels/mlir_generated:cwise_op",
"@com_google_absl//absl/base:prefetch",
"@com_google_absl//absl/status",
Expand Down
9 changes: 8 additions & 1 deletion tensorflow/core/kernels/cwise_op_pow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ limitations under the License.

#include "tensorflow/core/kernels/cwise_ops_common.h"

#if GOOGLE_CUDA || TENSORFLOW_USE_ROCM
#include "tensorflow/core/kernels/integer_pow_gpu.h"
#endif

namespace tensorflow {
REGISTER6(BinaryOp, CPU, "Pow", functor::pow, float, Eigen::half, bfloat16,
double, complex64, complex128);
Expand All @@ -24,7 +28,10 @@ REGISTER4(BinaryOp, CPU, "Pow", functor::safe_pow, int8_t, int16_t, int32_t,
#if GOOGLE_CUDA || TENSORFLOW_USE_ROCM
#if !defined(MLIR_GENERATED_GPU_KERNELS_ENABLED)
REGISTER3(BinaryOp, GPU, "Pow", functor::pow, float, Eigen::half, double);
REGISTER(BinaryOp, GPU, "Pow", functor::safe_pow_ignore_error, int64);
using Int64GpuPowOp = IntegerPowGpuOp<
int64_t, BinaryOp<GPUDevice, functor::safe_pow_ignore_error<int64_t>>>;
REGISTER_KERNEL_BUILDER(
Name("Pow").Device(DEVICE_GPU).TypeConstraint<int64_t>("T"), Int64GpuPowOp);
#endif
REGISTER(BinaryOp, GPU, "Pow", functor::pow, bfloat16);
#endif
Expand Down
5 changes: 3 additions & 2 deletions tensorflow/core/kernels/cwise_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -1221,8 +1221,9 @@ struct safe_pow : base<T, Eigen::internal::safe_scalar_binary_pow_op<T, T>> {
static constexpr bool has_errors = true;
};

// Version of safe_pow for integers which returns 0 if RHS is negative and LHS
// is not 1 or -1. For use on GPUs, where we cannot raise an error.
// Version of safe_pow for GPU computation. The integer Pow GPU kernel checks
// negative exponents separately and reports an error after the device work
// completes; this functor must still produce a defined result on the device.
template <typename T>
struct safe_pow_ignore_error_op {
static_assert(std::is_integral<T>::value, "Integer type expected");
Expand Down
58 changes: 58 additions & 0 deletions tensorflow/core/kernels/integer_pow_gpu.cu.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* Copyright 2026 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#if GOOGLE_CUDA || TENSORFLOW_USE_ROCM

#define EIGEN_USE_GPU
#include "tensorflow/core/kernels/integer_pow_gpu.h"

#include <algorithm>
#include <cstdint>

#include "tensorflow/core/util/gpu_kernel_helper.h"

namespace tensorflow {
namespace {

template <typename T>
__global__ void CheckNegativeExponentKernel(const T* exponents, int64_t size,
int32_t* found_negative) {
for (int64_t i : GpuGridRangeX<int64_t>(size)) {
if (exponents[i] < 0) {
atomicExch(found_negative, 1);
}
}
}

} // namespace

template <typename T>
absl::Status CheckNegativeExponentGpu<T>::operator()(
const Eigen::GpuDevice& device, const T* exponents, int64_t size,
int32_t* found_negative) {
constexpr int kThreads = 256;
const int blocks = static_cast<int>(
std::min<int64_t>((size + kThreads - 1) / kThreads, 1024));
return GpuLaunchKernel(CheckNegativeExponentKernel<T>, blocks, kThreads, 0,
device.stream(), exponents, size, found_negative);
}

template struct CheckNegativeExponentGpu<int8_t>;
template struct CheckNegativeExponentGpu<int16_t>;
template struct CheckNegativeExponentGpu<int64_t>;

} // namespace tensorflow

#endif // GOOGLE_CUDA || TENSORFLOW_USE_ROCM
119 changes: 119 additions & 0 deletions tensorflow/core/kernels/integer_pow_gpu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/* Copyright 2026 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#ifndef TENSORFLOW_CORE_KERNELS_INTEGER_POW_GPU_H_
#define TENSORFLOW_CORE_KERNELS_INTEGER_POW_GPU_H_

#if GOOGLE_CUDA || TENSORFLOW_USE_ROCM

#include <cstdint>
#include <utility>

#include "absl/status/status.h"
#include "tensorflow/core/common_runtime/gpu/gpu_event_mgr.h"
#include "tensorflow/core/framework/op_kernel.h"
#include "tensorflow/core/framework/tensor_types.h"
#include "tensorflow/core/platform/errors.h"
#include "tensorflow/core/util/bcast.h"

namespace tensorflow {

// Instantiated in integer_pow_gpu.cu.cc for the signed GPU Pow types.
template <typename T>
struct CheckNegativeExponentGpu {
absl::Status operator()(const Eigen::GpuDevice& device, const T* exponents,
int64_t size, int32_t* found_negative);
};

// Applies the same exponent validation to the Eigen and MLIR GPU kernels.
// The check runs before Pow can reuse an exponent buffer for its output. Only
// a single flag is copied back to the host, without blocking the caller.
template <typename T, typename Kernel>
class IntegerPowGpuOp : public AsyncOpKernel {
public:
explicit IntegerPowGpuOp(OpKernelConstruction* context)
: AsyncOpKernel(context), kernel_(context) {}

void ComputeAsync(OpKernelContext* context, DoneCallback done) override {
const BCast bcast(BCast::FromShape(context->input(0).shape()),
BCast::FromShape(context->input(1).shape()));
if (!bcast.IsValid() ||
BCast::ToShape(bcast.output_shape()).num_elements() == 0) {
kernel_.Compute(context);
done();
return;
}

auto* stream = context->op_device_context()->stream();
OP_REQUIRES_ASYNC(context, stream != nullptr,
absl::InternalError("No GPU stream available."), done);

Tensor found_negative;
OP_REQUIRES_OK_ASYNC(
context,
context->allocate_temp(DT_INT32, TensorShape({}), &found_negative),
done);
stream_executor::DeviceAddressBase device_flag(
found_negative.flat<int32_t>().data(), sizeof(int32_t));
OP_REQUIRES_OK_ASYNC(
context, stream->Memset32(&device_flag, 0, sizeof(int32_t)), done);
const auto& exponents = context->input(1).flat<T>();
OP_REQUIRES_OK_ASYNC(
context,
CheckNegativeExponentGpu<T>()(context->eigen_device<Eigen::GpuDevice>(),
exponents.data(), exponents.size(),
found_negative.flat<int32_t>().data()),
done);

AllocatorAttributes attributes;
attributes.set_on_host(true);
attributes.set_gpu_compatible(true);
Tensor host_flag;
OP_REQUIRES_OK_ASYNC(context,
context->allocate_temp(DT_INT32, TensorShape({}),
&host_flag, attributes),
done);
OP_REQUIRES_ASYNC(
context,
stream
->Memcpy(host_flag.flat<int32_t>().data(), device_flag,
sizeof(int32_t))
.ok(),
absl::InternalError("GPU memcpy from device to host failed"), done);

kernel_.Compute(context);

auto check = [found_negative, host_flag, context, done]() {
// Keep the device flag alive until the queued GPU work has completed.
(void)found_negative;
if (context->status().ok() && host_flag.scalar<int32_t>()() != 0) {
context->SetStatus(absl::InvalidArgumentError(
"Integers to negative integer powers are not allowed"));
}
done();
};
context->device()
->tensorflow_accelerator_device_info()
->event_mgr->ThenExecute(stream, std::move(check));
}

private:
Kernel kernel_;
};

} // namespace tensorflow

#endif // GOOGLE_CUDA || TENSORFLOW_USE_ROCM
#endif // TENSORFLOW_CORE_KERNELS_INTEGER_POW_GPU_H_
1 change: 1 addition & 0 deletions tensorflow/core/kernels/mlir_generated/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ tf_kernel_library(
tags = ["manual"],
deps = if_mlir_generated_gpu_kernels_enabled([
":base_gpu_op",
"//tensorflow/core/kernels:integer_pow_gpu",
":gpu_atan2_kernels",
":gpu_bitwise_and_kernels",
":gpu_bitwise_or_kernels",
Expand Down
13 changes: 10 additions & 3 deletions tensorflow/core/kernels/mlir_generated/gpu_binary_ops_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1304,6 +1304,13 @@ absl::InlinedVector<T, 10> PowInput() {
return test::InputAsVector<T, double>({-2, -1, -1, 1, 1, 3});
}

template <typename T>
absl::InlinedVector<T, 10> IntegerPowExponents() {
// These generated tests expect successful results. Negative exponents are
// covered separately by the GPU Pow error tests.
return test::InputAsVector<T>({0, 1, 2, 1, 2, 3});
}

template <>
Eigen::half baseline_pow(Eigen::half lhs, Eigen::half rhs) {
return static_cast<Eigen::half>(
Expand All @@ -1327,18 +1334,18 @@ GENERATE_DEFAULT_TESTS_WITH_SPECIFIC_INPUT_VALUES(
GENERATE_DEFAULT_TESTS_WITH_SPECIFIC_INPUT_VALUES(
Pow,
/*test_name=*/Int64, int64_t, int64_t, PowInput<int64_t>(),
PowInput<int64_t>(), baseline_pow,
IntegerPowExponents<int64_t>(), baseline_pow,
test::OpsTestConfig().ExpectStrictlyEqual())

/// Test the JIT-compiled kernels.
#if defined(MLIR_GENERATED_GPU_KERNELS_ENABLED)
GENERATE_DEFAULT_TESTS_WITH_SPECIFIC_INPUT_VALUES(
Pow, /*test_name=*/Int8, int8_t, int8_t, PowInput<int8_t>(),
PowInput<int8_t>(), baseline_pow,
IntegerPowExponents<int8_t>(), baseline_pow,
test::OpsTestConfig().ExpectStrictlyEqual())
GENERATE_DEFAULT_TESTS_WITH_SPECIFIC_INPUT_VALUES(
Pow, /*test_name=*/Int16, int16_t, int16_t, PowInput<int16_t>(),
PowInput<int16_t>(), baseline_pow,
IntegerPowExponents<int16_t>(), baseline_pow,
test::OpsTestConfig().ExpectStrictlyEqual())
#endif

Expand Down
26 changes: 23 additions & 3 deletions tensorflow/core/kernels/mlir_generated/gpu_op_pow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,37 @@ limitations under the License.
==============================================================================*/
#include "unsupported/Eigen/CXX11/Tensor" // from @eigen_archive
#include "tensorflow/core/framework/types.pb.h"
#include "tensorflow/core/kernels/integer_pow_gpu.h"
#include "tensorflow/core/kernels/mlir_generated/base_gpu_op.h"

namespace tensorflow {

GENERATE_AND_REGISTER_BINARY_GPU_KERNEL(Pow, DT_HALF);
GENERATE_AND_REGISTER_BINARY_GPU_KERNEL(Pow, DT_FLOAT);
GENERATE_AND_REGISTER_BINARY_GPU_KERNEL(Pow, DT_DOUBLE);
GENERATE_AND_REGISTER_BINARY_GPU_KERNEL(Pow, DT_INT64);
GENERATE_BINARY_GPU_KERNEL(Pow, DT_INT64);
using Int64GpuPowOp =
IntegerPowGpuOp<int64_t, MLIR_OP(Pow, GPU, DT_INT64, DT_INT64)>;
REGISTER_KERNEL_BUILDER(
Name("Pow").Device(DEVICE_GPU).TypeConstraint<int64_t>("T"), Int64GpuPowOp);

// These kernels are JIT-compiled.
GENERATE_AND_REGISTER_BINARY_JIT_GPU_KERNEL(Pow, DT_INT8);
GENERATE_AND_REGISTER_BINARY_JIT_GPU_KERNEL(Pow, DT_INT16);
GENERATE_BINARY_GPU_KERNEL(Pow, DT_INT8);
using Int8GpuPowOp =
IntegerPowGpuOp<int8_t, MLIR_OP(Pow, GPU, DT_INT8, DT_INT8)>;
REGISTER_KERNEL_BUILDER(Name("Pow")
.Device(DEVICE_GPU)
.TypeConstraint<int8_t>("T")
.Label(kJitKernelLabel),
Int8GpuPowOp);

GENERATE_BINARY_GPU_KERNEL(Pow, DT_INT16);
using Int16GpuPowOp =
IntegerPowGpuOp<int16_t, MLIR_OP(Pow, GPU, DT_INT16, DT_INT16)>;
REGISTER_KERNEL_BUILDER(Name("Pow")
.Device(DEVICE_GPU)
.TypeConstraint<int16_t>("T")
.Label(kJitKernelLabel),
Int16GpuPowOp);

} // namespace tensorflow
7 changes: 7 additions & 0 deletions tensorflow/lite/kernels/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -2527,10 +2527,17 @@ cc_test(
deps = [
":test_main",
":test_util",
"//tensorflow/lite:string_util",
"//tensorflow/lite/core/c:common",
"//tensorflow/lite/kernels/internal:reference_base",
"//tensorflow/lite/kernels/internal:tensor",
"//tensorflow/lite/kernels/internal:types",
"//tensorflow/lite/schema:schema_fbs",
"//tensorflow/lite/types:half",
"@com_google_benchmark//:benchmark",
"@com_google_googletest//:gtest",
"@eigen_archive//:eigen3",
"@ruy//ruy/profiler:instrumentation",
],
)

Expand Down
Loading
Loading