Feature request: tf.gather which returns 0 on invalid indices
@SuryanarayanaY 
I was able to replicate the issue on Colab using TF v2.11 and tf-nightly-2.13.0.dev20230221. Please find the gist of [2.11](https://colab.research.google.com/gist/tiruk007/a657e62ad14d253d0cd2dd2775bb4f2b/untitled137.ipynb) and [tf.nightly](https://colab.research.google.com/gist/tiruk007/c9e2511f3ed3733828e8f2f200177d2c/untitled138.ipynb).

Thank you! Hi @albertz ,

The indices are validated on CPU but not GPU.Hence CPU code throws an User error.This is intended behaviour.
Please refer attached [source](https://www.tensorflow.org/api_docs/python/tf/gather#:~:text=Deprecated%3A%20SOME%20ARGUMENTS%20ARE%20DEPRECATED%3A%20(validate_indices).%20They%20will%20be%20removed%20in%20a%20future%20version.%20Instructions%20for%20updating%3A%20The%20validate_indices%20argument%20has%20no%20effect.%20Indices%20are%20always%20validated%20on%20CPU%20and%20never%20validated%20on%20GPU.).

Would you please elaborate how your Feature request beneficial over current behaviour ? That helps in providing more context to consider the request.

Thanks!

 I know that this is the documented behavior.

But I request for a feature here where the CPU behavior is just the same as the GPU behavior. I have a use case where the GPU behavior is totally fine, and I don't want the CPU behavior to be inconsistent but rather behave exactly the same. The use case is probably also not too rare: I just happen to have a few indices which might be out-of-range, and I want to get 0s returned for them. Exactly like what the GPU behavior does. But when I run it on CPU, I want it to behave in the same way as the GPU.
 Hi @ albertz,

Unfortunately this can't be considered as Feature now.With invalid data the behaviour is expected and also documented. 

Please refer the Developer [comment-1439267105](https://github.com/tensorflow/tensorflow/issues/59750#issuecomment-1439267105) regarding similar issue with same Op where it was clearly mentioned that it won't be considered for fix and closed the issue well. Maybe you misunderstood what I wrote. I did not say that the behavior is unexpected or not documented. I know that it is exactly as expected. But I'm not really asking about `tf.gather` here at all.

I'm asking for a **separate** new `tf.gather_with_fallback` or whatever you want to name it. Or maybe a new **option** for `tf.gather`.

I don't want to change any existing behavior.
 Hi @albertz ,

Could you please elaborate more ? You want the proposed API should work like same as tf.gather without raising error in validating indices.If Indices is large, is that not resource intensive on CPU ? What are the use cases for this feature and how community will get benefit from this ? The proposed API should work exactly like `tf.gather` does currently on GPU. I.e. on invalid indices, it would not raise an error but just return 0 (or maybe some configurable tensor). Pseudo code (per element):
```python
if 0 <= index < dim:
  return x[index]
else:
  return fallback
```
In most of my (more dynamic) use of `tf.gather`, I actually need to have this behavior. Using an embedding where I can make sure the indices should be valid is actually more like the exception.

I don't see why this should be resource intensive.
 Hi @albertz ,

I tried a demo example on a 2D tensor using your workaround code but getting error.Please refer the attached [gist](https://colab.research.google.com/gist/SuryanarayanaY/53a7d2cfa5c51567aff97b73934b1909/59724.ipynb) and confirm us the way you want to implement it and revert us with the gist. That provide me more context. Thanks!  I think there was a small error in my workaround code as I posted it here. I corrected it. Anyway, this workaround code was just for demonstration purpose. (In our internal code, the workaround code is a bit more involved, that's why I did not copy it here.)

But anyway, I did not say you should use my workaround code. When implementing that inside TF, it is much easier to implement it just following the pseudo code above, directly in C++. I assume your current GPU implementation actually is already like that. @albertz , 

I just want to understand the requirement and implementation thoroughly and provide complete context to the next level. Hence i tried your code. Anyway the implementation has to be done at C++ level only for this API.

I will escalate the issue to next level and will comeback.

Thanks! We won't do this internally - it's not highly requested, and there are potential work-arounds that use combinations of ops (or a single custom op if it is a performance bottleneck).
This is about `tf.gather`. The wanted behavior could be added directly, or maybe via a new option, or maybe via a separate op.

Actually, on GPU (at least where I tested it), the behavior of `tf.gather` is already as I want it:

- It returns 0 for invalid indices.
- I think (not really verified): gradients for those 0s back to the `param` would go nowhere. (This is important though.)

On CPU, the current behavior is:

- An exception is raised.

I basically want the same behavior on CPU as we currently have it on GPU.

My current workaround is sth like:
```python
# need to extend param such that we can lead gradients to nowhere
zeros = tf.zeros([tf.shape(param)[i] if i != axis else 1 for i in range(param.ndim)], dtype=param.dtype)
param = tf.concat([param, zeros], axis=axis)
indices = tf.where(indices >= 0 and indices < tf.shape(param)[axis], indices, tf.shape(param)[axis] - 1)
gather = tf.gather(param, indices, axis=axis)
```
