Some tests reset the global context, and TensorHandleCache was incorrectly shared across different context before.
PiperOrigin-RevId: 334870644
Change-Id: I6159ca89d67b3939e98d7b43ce847ac205abf650
Since the struct lifetime is bound to the wrapped pointer this is fine.
PiperOrigin-RevId: 308941521
Change-Id: I0604fff4fcba6a03cc4a2242ab9f182fbfbf8bae
Abstract interface objects such as AbstractContextInterface,
AbstractOperationInterface & AbstractTensorHandleInterface were added to
decouple client code from the underlying implementation and allow for
easy switching to TFRT. Unfortunately the interface implementations had
to live in their own objects due to circular dependencies. This change
hopes to address most of them with the following changes & clean-ups:
* Move abstract interface definitions into separate build targets
* Make EagerContext implement AbstractContextInterface.
* Make EagerOperation implement AbstractOperationInterface.
* Make TensorHandle implement AbstractTensorHandleInterface.
* Use tensorflow::DataType instead of TF_DataType in interfaces.
* Replace unique_ptr with raw pointer and expose Release() function in
abstract interfaces while making the destructor protected. This allows
interface implementations to control their life-cycle, enabling
EagerContext and TensorHandle which are reference counted to implement
the interfaces directly.
* Make TensorHandle & EagerContext destructors private since the objects
are reference counted.
* Move out interface methods from c_api.cc
* Use absl::Span instead of absl::FixedArray in operation interface.
* Make CustomDeviceAPI use TFE_DeleteTensorHandle instead of directly
deleting the object.
* Remove unused TensorHandle::OnHostCPU method.
* Move remaining circular dependencies into core.cc.
PiperOrigin-RevId: 304269288
Change-Id: I2cced4a21ece708f413182b43f47e4891654901e
We add the TensorInterface & TensorHandleInterface classes and keep them
as the sole member of TF_Tensor and TFE_TensorHandle structs to keep
those structs simple. This allows us to keep most of the C API functions
as simple wrappers around C++ classes.
PiperOrigin-RevId: 288903948
Change-Id: I9f4d8914c447145df63c8518bcde60656f7098f9
Note that cache key contains PyObject* and is therefore not easily reusable
from other languages.
CPU
| Benchmark | Before (calls/sec) | After (calls/sec) |
|---------------------------------+--------------------+-------------------|
| benchmark_add_float_scalars | 96697.1650772 | 122549.093512 |
| benchmark_add_int_scalars | 100551.000642 | 124905.320251 |
| benchmark_create_float_constant | 269135.927106 | 368643.600035 |
| benchmark_create_int32_constant | 250023.088998 | 347383.13732 |
GPU
| Benchmark | Before (calls/sec) | After (calls/sec) |
|---------------------------------+--------------------+-------------------|
| benchmark_add_float_scalars | 9478.74450315 | 17181.8063021 |
| benchmark_add_int_scalars | 99584.0439651 | 117965.869066 |
| benchmark_create_float_constant | 275277.007219 | 381577.874818 |
Notes:
* The timings between CPU and GPU are incomparable because they were measured
on different hardware;
* I suspect that benchmark_add_int_scalars on GPU does addition on CPU and
copies to GPU after, therefore the gap between *_add_float_* and *_add_int_*.
PiperOrigin-RevId: 261293772