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 // Return the number of dimensions that the tensor has. 117 TF_CAPI_EXPORT extern int TF_NumDims(const TF_Tensor*); 118 119 // Return the length of the tensor in the "dim_index" dimension. 120 // REQUIRES: 0 <= dim_index < TF_NumDims(tensor) 121 TF_CAPI_EXPORT extern int64_t TF_Dim(const TF_Tensor* tensor, int dim_index); 122 123 // Return the size of the underlying data in bytes. 124 TF_CAPI_EXPORT extern size_t TF_TensorByteSize(const TF_Tensor*); 125 126 // Return a pointer to the underlying data buffer. 127 TF_CAPI_EXPORT extern void* TF_TensorData(const TF_Tensor*); 128 129 // Returns the number of elements in the tensor. 130 TF_CAPI_EXPORT extern int64_t TF_TensorElementCount(const TF_Tensor* tensor); 131 132 // Copy the internal data representation of `from` to `to`. `new_dims` and 133 // `num_new_dims` specify the new shape of the `to` tensor, `type` specifies its 134 // data type. On success, *status is set to TF_OK and the two tensors share the 135 // same data buffer. 136 // 137 // This call requires that the `from` tensor and the given type and shape (dims 138 // and num_dims) are "compatible" (i.e. they occupy the same number of bytes). 139 // Specifically, given from_type_size = TF_DataTypeSize(TF_TensorType(from)): 140 // 141 // ShapeElementCount(dims, num_dims) * TF_DataTypeSize(type) 142 // 143 // must equal 144 // 145 // TF_TensorElementCount(from) * from_type_size 146 // 147 // where TF_ShapeElementCount would be the number of elements in a tensor with 148 // the given shape. 149 // 150 // In addition, this function requires: 151 // * TF_DataTypeSize(TF_TensorType(from)) != 0 152 // * TF_DataTypeSize(type) != 0 153 // 154 // If any of the requirements are not met, *status is set to 155 // TF_INVALID_ARGUMENT. 156 TF_CAPI_EXPORT extern void TF_TensorBitcastFrom(const TF_Tensor* from, 157 TF_DataType type, TF_Tensor* to, 158 const int64_t* new_dims, 159 int num_new_dims, 160 TF_Status* status); 161 162 // Returns bool iff this tensor is aligned. 163 TF_CAPI_EXPORT extern bool TF_TensorIsAligned(const TF_Tensor*); 164 165 #ifdef __cplusplus 166 } /* end extern "C" */ 167 #endif 168 169 #endif // TENSORFLOW_C_TF_TENSOR_H_ 170