template struct functor::DenseUpdate<GPUDevice, T, ADD>; \
template struct functor::DenseUpdate<GPUDevice, T, SUB>;
TF_CALL_GPU_NUMBER_TYPES(DEFINE_GPU_KERNELS);
+TF_CALL_int32(DEFINE_GPU_KERNELS);
TF_CALL_int64(DEFINE_GPU_KERNELS);
#undef DEFINE_GPU_KERNELS
DECLARE_GPU_SPECS_INDEX(T, int32); \
DECLARE_GPU_SPECS_INDEX(T, int64)
+TF_CALL_int64(DECLARE_GPU_SPECS);
TF_CALL_GPU_NUMBER_TYPES(DECLARE_GPU_SPECS);
TF_CALL_complex64(DECLARE_GPU_SPECS);
TF_CALL_complex128(DECLARE_GPU_SPECS);
DEFINE_GPU_SPECS_INDEX(T, int32); \
DEFINE_GPU_SPECS_INDEX(T, int64);
+TF_CALL_int64(DEFINE_GPU_SPECS);
TF_CALL_GPU_NUMBER_TYPES(DEFINE_GPU_SPECS);
TF_CALL_complex64(DEFINE_GPU_SPECS);
TF_CALL_complex128(DEFINE_GPU_SPECS);
DECLARE_GPU_SPECS_INDEX(T, int32); \
DECLARE_GPU_SPECS_INDEX(T, int64)
+TF_CALL_int32(DECLARE_GPU_SPECS);
+TF_CALL_int64(DECLARE_GPU_SPECS);
TF_CALL_GPU_NUMBER_TYPES(DECLARE_GPU_SPECS);
TF_CALL_complex64(DECLARE_GPU_SPECS);
TF_CALL_complex128(DECLARE_GPU_SPECS);
// Registration of the GPU implementations.
#define REGISTER_GATHER_ND_GPU(type) REGISTER_GATHER_ND_ALL_INDICES(GPU, type)
+TF_CALL_int32(REGISTER_GATHER_ND_GPU);
+TF_CALL_int64(REGISTER_GATHER_ND_GPU);
TF_CALL_GPU_NUMBER_TYPES(REGISTER_GATHER_ND_GPU);
TF_CALL_complex64(REGISTER_GATHER_ND_GPU);
TF_CALL_complex128(REGISTER_GATHER_ND_GPU);
DEFINE_GPU_SPECS_INDEX(T, int32); \
DEFINE_GPU_SPECS_INDEX(T, int64);
+TF_CALL_int32(DEFINE_GPU_SPECS);
+TF_CALL_int64(DEFINE_GPU_SPECS);
TF_CALL_GPU_NUMBER_TYPES(DEFINE_GPU_SPECS);
TF_CALL_complex64(DEFINE_GPU_SPECS);
TF_CALL_complex128(DEFINE_GPU_SPECS);
// Registration of the GPU implementations.
#define REGISTER_GATHER_GPU(type) REGISTER_GATHER_ALL_INDICES(GPU, type)
+TF_CALL_int64(REGISTER_GATHER_GPU);
TF_CALL_GPU_NUMBER_TYPES(REGISTER_GATHER_GPU);
TF_CALL_complex64(REGISTER_GATHER_GPU);
TF_CALL_complex128(REGISTER_GATHER_GPU);
REGISTER_SCATTER_ND_UPDATE_GPU(type); \
REGISTER_SCATTER_ND_GPU(type);
+TF_CALL_int32(REGISTER_SCATTER_ND_ALL_GPU);
// TODO(b/66916790): Support half types in ScatterNd.
TF_CALL_GPU_NUMBER_TYPES_NO_HALF(REGISTER_SCATTER_ND_ALL_GPU);
TF_CALL_complex64(REGISTER_SCATTER_ND_ALL_GPU);
#define REGISTER_SCATTER_ND_UPDATE_SYCL(type) \
REGISTER_SCATTER_ND_UPDATE(type, SYCL);
+TF_CALL_int32(REGISTER_SCATTER_ND_ADD_SUB_SYCL);
+TF_CALL_int32(REGISTER_SCATTER_ND_UPDATE_SYCL);
TF_CALL_GPU_NUMBER_TYPES_NO_HALF(REGISTER_SCATTER_ND_ADD_SUB_SYCL);
TF_CALL_GPU_NUMBER_TYPES_NO_HALF(REGISTER_SCATTER_ND_UPDATE_SYCL);
#undef REGISTER_SCATTER_ND_ADD_SUB_SYCL
DECLARE_GPU_SPECS_INDEX(T, int32); \
DECLARE_GPU_SPECS_INDEX(T, int64)
+TF_CALL_int32(DECLARE_GPU_SPECS);
// TODO(b/66916790): Support half types in ScatterNd.
TF_CALL_GPU_NUMBER_TYPES(DECLARE_GPU_SPECS);
TF_CALL_complex64(DECLARE_GPU_SPECS);
DECLARE_GPU_SPECS_INDEX(T, int32); \
DECLARE_GPU_SPECS_INDEX(T, int64)
+TF_CALL_int32(DECLARE_GPU_SPECS);
TF_CALL_GPU_NUMBER_TYPES(DECLARE_GPU_SPECS);
TF_CALL_complex64(DECLARE_GPU_SPECS);
TF_CALL_complex128(DECLARE_GPU_SPECS);
self.assertEqual(None, shape.ndims)
self.assertEqual(None, shape[0].value)
- def testBadIndices(self):
+ def testBadIndicesCPU(self):
+ with self.test_session(use_gpu=False):
+ params = [0, 1, 2]
+ indices = [[[0], [7]]] # Make this one higher rank
+ gather_nd = array_ops.gather_nd(params, indices)
+ with self.assertRaisesOpError(
+ r"flat indices\[1, :\] = \[7\] does not index into param "
+ r"\(shape: \[3\]\)"):
+ gather_nd.eval()
+
+ def _disabledTestBadIndicesGPU(self):
+ # TODO disabled due to different behavior on GPU and CPU
+ # On GPU the bad indices do not raise error but fetch 0 values
+ if not test.is_gpu_available():
+ return
with self.test_session(use_gpu=True):
params = [0, 1, 2]
indices = [[[0], [7]]] # Make this one higher rank
r"\(shape: \[3\]\)"):
gather_nd.eval()
- def testBadIndicesWithSlices(self):
+ def testBadIndicesWithSlicesCPU(self):
+ with self.test_session(use_gpu=False):
+ params = [[0, 1, 2]]
+ indices = [[[0], [0], [1]]] # Make this one higher rank
+ gather_nd = array_ops.gather_nd(params, indices)
+ with self.assertRaisesOpError(
+ r"flat indices\[2, :\] = \[1\] does not index into param "
+ r"\(shape: \[1,3\]\)"):
+ gather_nd.eval()
+
+ def _disabledTestBadIndicesWithSlicesGPU(self):
+ # TODO disabled due to different behavior on GPU and CPU
+ # On GPU the bad indices do not raise error but fetch 0 values
+ if not test.is_gpu_available():
+ return
with self.test_session(use_gpu=True):
params = [[0, 1, 2]]
indices = [[[0], [0], [1]]] # Make this one higher rank
from tensorflow.python.ops import gradients_impl
from tensorflow.python.platform import test
-_TEST_TYPES = (dtypes.float32, dtypes.complex64, dtypes.complex128)
+_TEST_TYPES = (dtypes.int64, dtypes.float32,
+ dtypes.complex64, dtypes.complex128)
class GatherTest(test.TestCase):
gather, [tf_params, tf_indices, tf_axis], gather_grad)
self.assertEqual(indices_grad, None)
self.assertEqual(axis_grad, None)
+ if dtype.is_integer:
+ self.assertEqual(params_grad, None)
+ continue
# For axis 0, we are able to create an efficient IndexedSlices for
# the gradient.
if axis == 0:
gather_t = array_ops.gather(params, indices, axis=axis)
self.assertEqual(None, gather_t.shape)
- def testBadIndices(self):
+ def testBadIndicesCPU(self):
+ with self.test_session(use_gpu=False):
+ params = [[0, 1, 2], [3, 4, 5]]
+ with self.assertRaisesOpError(r"indices\[0,0\] = 7 is not in \[0, 2\)"):
+ array_ops.gather(params, [[7]], axis=0).eval()
+ with self.assertRaisesOpError(r"indices\[0,0\] = 7 is not in \[0, 3\)"):
+ array_ops.gather(params, [[7]], axis=1).eval()
+
+ def _disabledTestBadIndicesGPU(self):
+ # TODO disabled due to different behavior on GPU and CPU
+ # On GPU the bad indices do not raise error but fetch 0 values
+ if not test.is_gpu_available():
+ return
with self.test_session(use_gpu=True):
params = [[0, 1, 2], [3, 4, 5]]
with self.assertRaisesOpError(r"indices\[0,0\] = 7 is not in \[0, 2\)"):
self.assertAllClose(new, ref_var.eval())
def _VariableRankTests(self, np_scatter, tf_scatter):
- for vtype in (np.float32, np.float64, np.complex64, np.complex128):
+ for vtype in (np.int32,
+ np.float32, np.float64,
+ np.complex64, np.complex128):
for itype in (np.int32, np.int64):
self._VariableRankTest(np_scatter, tf_scatter, vtype, itype)
# self._VariableRankTests(_NumpyDiv, state_ops.scatter_nd_div)
def _ScatterRepeatIndicesTest(self, np_scatter, tf_scatter):
- for vtype in (np.float32, np.float64):
+ for vtype in (np.int32, np.float32, np.float64):
for itype in (np.int32, np.int64):
self._VariableRankTest(
np_scatter, tf_scatter, vtype, itype, repeat_indices=True)
# Clips small values to avoid division by zero.
def clip_small_values(x):
- return 1e-4 * np.sign(x) if np.abs(x) < 1e-4 else x
+ threshold = 1e-4
+ sign = np.sign(x)
+
+ if isinstance(x, np.int32):
+ threshold = 1
+ sign = np.random.choice([-1, 1])
+ return threshold * sign if np.abs(x) < threshold else x
updates = np.vectorize(clip_small_values)(updates)
old = _AsType(np.random.randn(*((first_dim,) + extra_shape)), vtype)
tf_scatter,
repeat_indices=False,
updates_are_scalar=False):
- for vtype in (np.float32, np.float64):
+ vtypes = [np.float32, np.float64]
+ if tf_scatter != state_ops.scatter_div:
+ vtypes.append(np.int32)
+
+ for vtype in vtypes:
for itype in (np.int32, np.int64):
self._VariableRankTest(tf_scatter, vtype, itype, repeat_indices,
updates_are_scalar)