1 | /* Copyright 2019 The TensorFlow Authors. All Rights Reserved. |
2 | |
3 | Licensed under the Apache License, Version 2.0 (the "License"); |
4 | you may not use this file except in compliance with the License. |
5 | You may obtain a copy of the License at |
6 | |
7 | http://www.apache.org/licenses/LICENSE-2.0 |
8 | |
9 | Unless required by applicable law or agreed to in writing, software |
10 | distributed under the License is distributed on an "AS IS" BASIS, |
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | See the License for the specific language governing permissions and |
13 | limitations under the License. |
14 | ==============================================================================*/ |
15 | |
16 | #ifndef TENSORFLOW_C_TF_TENSOR_H_ |
17 | #define TENSORFLOW_C_TF_TENSOR_H_ |
18 | |
19 | #include <stdbool.h> |
20 | #include <stdint.h> |
21 | |
22 | #include "tensorflow/c/c_api_macros.h" |
23 | #include "tensorflow/c/tf_datatype.h" |
24 | #include "tensorflow/c/tf_status.h" |
25 | |
26 | // Macro to control visibility of exported symbols in the shared library (.so, |
27 | // .dylib, .dll). |
28 | // This duplicates the TF_EXPORT macro definition in |
29 | // tensorflow/core/platform/macros.h in order to keep this .h file independent |
30 | // of any other includes. |
31 | #ifdef SWIG |
32 | #define TF_CAPI_EXPORT |
33 | #else |
34 | #if defined(_WIN32) |
35 | #ifdef TF_COMPILE_LIBRARY |
36 | #define TF_CAPI_EXPORT __declspec(dllexport) |
37 | #else |
38 | #define TF_CAPI_EXPORT __declspec(dllimport) |
39 | #endif // TF_COMPILE_LIBRARY |
40 | #else |
41 | #define TF_CAPI_EXPORT __attribute__((visibility("default"))) |
42 | #endif // _WIN32 |
43 | #endif // SWIG |
44 | |
45 | #ifdef __cplusplus |
46 | extern "C" { |
47 | #endif |
48 | |
49 | // Allocator Attributes used for tensor allocation. |
50 | typedef struct TF_AllocatorAttributes { |
51 | size_t struct_size; |
52 | // Set boolean to 1 for CPU allocation, else 0. |
53 | TF_Bool on_host; |
54 | } TF_AllocatorAttributes; |
55 | |
56 | #define TF_ALLOCATOR_ATTRIBUTES_STRUCT_SIZE \ |
57 | TF_OFFSET_OF_END(TF_AllocatorAttributes, on_host) |
58 | |
59 | // -------------------------------------------------------------------------- |
60 | // TF_Tensor holds a multi-dimensional array of elements of a single data type. |
61 | // For all types other than TF_STRING, the data buffer stores elements |
62 | // in row major order. E.g. if data is treated as a vector of TF_DataType: |
63 | // |
64 | // element 0: index (0, ..., 0) |
65 | // element 1: index (0, ..., 1) |
66 | // ... |
67 | // |
68 | // The format for TF_STRING tensors is: |
69 | // start_offset: array[uint64] |
70 | // data: byte[...] |
71 | // |
72 | // The string length (as a varint, start_offset[i + 1] - start_offset[i]), |
73 | // followed by the contents of the string is encoded at data[start_offset[i]]. |
74 | // TF_StringEncode and TF_StringDecode facilitate this encoding. |
75 | |
76 | typedef struct TF_Tensor TF_Tensor; |
77 | |
78 | // Return a new tensor that holds the bytes data[0,len-1]. |
79 | // |
80 | // The data will be deallocated by a subsequent call to TF_DeleteTensor via: |
81 | // (*deallocator)(data, len, deallocator_arg) |
82 | // Clients must provide a custom deallocator function so they can pass in |
83 | // memory managed by something like numpy. |
84 | // |
85 | // May return NULL (and invoke the deallocator) if the provided data buffer |
86 | // (data, len) is inconsistent with a tensor of the given TF_DataType |
87 | // and the shape specified by (dima, num_dims). |
88 | TF_CAPI_EXPORT extern TF_Tensor* TF_NewTensor( |
89 | TF_DataType, const int64_t* dims, int num_dims, void* data, size_t len, |
90 | void (*deallocator)(void* data, size_t len, void* arg), |
91 | void* deallocator_arg); |
92 | |
93 | // Allocate and return a new Tensor. |
94 | // |
95 | // This function is an alternative to TF_NewTensor and should be used when |
96 | // memory is allocated to pass the Tensor to the C API. The allocated memory |
97 | // satisfies TensorFlow's memory alignment preferences and should be preferred |
98 | // over calling malloc and free. |
99 | // |
100 | // The caller must set the Tensor values by writing them to the pointer returned |
101 | // by TF_TensorData with length TF_TensorByteSize. |
102 | TF_CAPI_EXPORT extern TF_Tensor* TF_AllocateTensor(TF_DataType, |
103 | const int64_t* dims, |
104 | int num_dims, size_t len); |
105 | |
106 | // Deletes `tensor` and returns a new TF_Tensor with the same content if |
107 | // possible. Returns nullptr and leaves `tensor` untouched if not. |
108 | TF_CAPI_EXPORT extern TF_Tensor* TF_TensorMaybeMove(TF_Tensor* tensor); |
109 | |
110 | // Destroy a tensor. |
111 | TF_CAPI_EXPORT extern void TF_DeleteTensor(TF_Tensor*); |
112 | |
113 | // Return the type of a tensor element. |
114 | TF_CAPI_EXPORT extern TF_DataType TF_TensorType(const TF_Tensor*); |
115 | |
116 | // Set a new shape for the Tensor. |
117 | TF_CAPI_EXPORT extern void TF_SetShape(TF_Tensor* tensor, const int64_t* dims, |
118 | int num_dims); |
119 | |
120 | // Return the number of dimensions that the tensor has. |
121 | TF_CAPI_EXPORT extern int TF_NumDims(const TF_Tensor*); |
122 | |
123 | // Return the length of the tensor in the "dim_index" dimension. |
124 | // REQUIRES: 0 <= dim_index < TF_NumDims(tensor) |
125 | TF_CAPI_EXPORT extern int64_t TF_Dim(const TF_Tensor* tensor, int dim_index); |
126 | |
127 | // Return the size of the underlying data in bytes. |
128 | TF_CAPI_EXPORT extern size_t TF_TensorByteSize(const TF_Tensor*); |
129 | |
130 | // Return a pointer to the underlying data buffer. |
131 | TF_CAPI_EXPORT extern void* TF_TensorData(const TF_Tensor*); |
132 | |
133 | // Returns the number of elements in the tensor. |
134 | TF_CAPI_EXPORT extern int64_t TF_TensorElementCount(const TF_Tensor* tensor); |
135 | |
136 | // Copy the internal data representation of `from` to `to`. `new_dims` and |
137 | // `num_new_dims` specify the new shape of the `to` tensor, `type` specifies its |
138 | // data type. On success, *status is set to TF_OK and the two tensors share the |
139 | // same data buffer. |
140 | // |
141 | // This call requires that the `from` tensor and the given type and shape (dims |
142 | // and num_dims) are "compatible" (i.e. they occupy the same number of bytes). |
143 | // Specifically, given from_type_size = TF_DataTypeSize(TF_TensorType(from)): |
144 | // |
145 | // ShapeElementCount(dims, num_dims) * TF_DataTypeSize(type) |
146 | // |
147 | // must equal |
148 | // |
149 | // TF_TensorElementCount(from) * from_type_size |
150 | // |
151 | // where TF_ShapeElementCount would be the number of elements in a tensor with |
152 | // the given shape. |
153 | // |
154 | // In addition, this function requires: |
155 | // * TF_DataTypeSize(TF_TensorType(from)) != 0 |
156 | // * TF_DataTypeSize(type) != 0 |
157 | // |
158 | // If any of the requirements are not met, *status is set to |
159 | // TF_INVALID_ARGUMENT. |
160 | TF_CAPI_EXPORT extern void TF_TensorBitcastFrom(const TF_Tensor* from, |
161 | TF_DataType type, TF_Tensor* to, |
162 | const int64_t* new_dims, |
163 | int num_new_dims, |
164 | TF_Status* status); |
165 | |
166 | // Returns bool iff this tensor is aligned. |
167 | TF_CAPI_EXPORT extern bool TF_TensorIsAligned(const TF_Tensor*); |
168 | |
169 | #ifdef __cplusplus |
170 | } /* end extern "C" */ |
171 | #endif |
172 | |
173 | #endif // TENSORFLOW_C_TF_TENSOR_H_ |
174 | |