1/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
2
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9Unless required by applicable law or agreed to in writing, software
10distributed under the License is distributed on an "AS IS" BASIS,
11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12See the License for the specific language governing permissions and
13limitations under the License.
14==============================================================================*/
15#ifndef TENSORFLOW_C_EAGER_IMMEDIATE_EXECUTION_TENSOR_HANDLE_H_
16#define TENSORFLOW_C_EAGER_IMMEDIATE_EXECUTION_TENSOR_HANDLE_H_
17
18#include "tensorflow/c/eager/abstract_tensor_handle.h"
19#include "tensorflow/c/tensor_interface.h"
20#include "tensorflow/core/framework/types.pb.h"
21#include "tensorflow/core/platform/status.h"
22
23namespace tensorflow {
24
25// Abstract interface to a TensorHandle.
26//
27// A TensorHandle is management class around a Tensor which may track additional
28// metadata and synchronization.
29//
30// This allows us to hide concrete implementations of TensorHandle from header
31// files. The interface lists the common functionality that must be provided by
32// any concrete implementation. However, in cases where the true concrete class
33// is needed a static_cast can be applied.
34class ImmediateExecutionTensorHandle : public AbstractTensorHandle {
35 public:
36 // Returns number of dimensions.
37 virtual Status NumDims(int* num_dims) const = 0;
38 // Returns number of elements across all dimensions.
39 virtual Status NumElements(int64_t* num_elements) const = 0;
40 // Returns size of specified dimension
41 //
42 // -1 indicates an unknown axis length; this is unreachable for most standard
43 // ImmediateExecutionTensorHandles, but comes up for example when computing
44 // the shape of a parallel tensor with component shapes differing across
45 // devices.
46 virtual Status Dim(int dim_index, int64_t* dim) const = 0;
47
48 // Returns the device which created the handle.
49 virtual const char* DeviceName(Status* status) const = 0;
50 // Returns the device where the tensor was placed.
51 virtual const char* BackingDeviceName(Status* status) const = 0;
52 // Returns the device type which created the handle.
53 virtual const char* DeviceType(Status* status) const = 0;
54 // Returns the device ID which created the handle.
55 virtual int DeviceId(Status* status) const = 0;
56 // Returns a tensor for the handle. If tensor is remote, it will be copied.
57 virtual AbstractTensorInterface* Resolve(Status* status) = 0;
58
59 // Return a copy of the handle.
60 virtual ImmediateExecutionTensorHandle* Copy() = 0;
61
62 std::string DebugString() const override;
63
64 // Returns a Boolean hint indicating whether callers should prefer
65 // `SummarizeValue` to resolving this handle and formatting the tensor.
66 //
67 // For example some tensor handles may represent distributed values, in which
68 // case placement information is lost when resolving the handle.
69 //
70 // If false, a caller might implement pretty-printing by resolving and
71 // iterating over the resulting tensor. This may still be viable if resolving
72 // the handle loses information, but `SummarizeValue` would be more precise.
73 virtual bool PreferCustomSummarizer() const { return false; }
74
75 // Returns a string which summarizes the value of this TensorHandle, for
76 // debugging. Does not include a shape or dtype.
77 //
78 // Included in the default implementation of DebugString.
79 virtual Status SummarizeValue(std::string& summary) const;
80
81 // Release any underlying resources, including the interface object.
82 //
83 // WARNING: The destructor of this class is marked as protected to disallow
84 // clients from directly destroying this object since it may manage its own
85 // lifetime through ref counting. Thus this must be allocated on the heap and
86 // clients MUST call Release() in order to destroy an instance of this class.
87 virtual void Release() = 0;
88
89 // For LLVM style RTTI.
90 static bool classof(const AbstractTensorHandle* ptr) {
91 return ptr->getKind() == kEager || ptr->getKind() == kTfrt;
92 }
93
94 protected:
95 explicit ImmediateExecutionTensorHandle(AbstractTensorHandleKind kind)
96 : AbstractTensorHandle(kind) {}
97 ~ImmediateExecutionTensorHandle() override {}
98};
99
100namespace internal {
101struct ImmediateExecutionTensorHandleDeleter {
102 void operator()(ImmediateExecutionTensorHandle* p) const {
103 if (p != nullptr) {
104 p->Release();
105 }
106 }
107};
108} // namespace internal
109
110using ImmediateTensorHandlePtr =
111 std::unique_ptr<ImmediateExecutionTensorHandle,
112 internal::ImmediateExecutionTensorHandleDeleter>;
113
114} // namespace tensorflow
115
116#endif // TENSORFLOW_C_EAGER_IMMEDIATE_EXECUTION_TENSOR_HANDLE_H_
117