1/* Copyright 2019 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
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
46extern "C" {
47#endif
48
49// Allocator Attributes used for tensor allocation.
50typedef 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
76typedef 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).
88TF_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.
102TF_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.
108TF_CAPI_EXPORT extern TF_Tensor* TF_TensorMaybeMove(TF_Tensor* tensor);
109
110// Destroy a tensor.
111TF_CAPI_EXPORT extern void TF_DeleteTensor(TF_Tensor*);
112
113// Return the type of a tensor element.
114TF_CAPI_EXPORT extern TF_DataType TF_TensorType(const TF_Tensor*);
115
116// Set a new shape for the Tensor.
117TF_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.
121TF_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)
125TF_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.
128TF_CAPI_EXPORT extern size_t TF_TensorByteSize(const TF_Tensor*);
129
130// Return a pointer to the underlying data buffer.
131TF_CAPI_EXPORT extern void* TF_TensorData(const TF_Tensor*);
132
133// Returns the number of elements in the tensor.
134TF_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.
160TF_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.
167TF_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