c_api.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. /* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
  2. Licensed under the Apache License, Version 2.0 (the "License");
  3. you may not use this file except in compliance with the License.
  4. You may obtain a copy of the License at
  5. http://www.apache.org/licenses/LICENSE-2.0
  6. Unless required by applicable law or agreed to in writing, software
  7. distributed under the License is distributed on an "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. See the License for the specific language governing permissions and
  10. limitations under the License.
  11. ==============================================================================*/
  12. #ifndef TENSORFLOW_C_EAGER_C_API_H_
  13. #define TENSORFLOW_C_EAGER_C_API_H_
  14. // C API extensions to experiment with eager execution of kernels.
  15. // WARNING: Unlike tensorflow/c/c_api.h, the API here is not guaranteed to be
  16. // stable and can change without notice.
  17. #include "tensorflow/c/c_api.h"
  18. // Macro to control visibility of exported symbols in the shared library (.so,
  19. // .dylib, .dll).
  20. // This duplicates the TF_EXPORT macro definition in
  21. // tensorflow/core/platform/macros.h in order to keep this .h file independent
  22. // of any other includes.$a
  23. #ifdef SWIG
  24. #define TF_CAPI_EXPORT
  25. #else
  26. #if defined(_WIN32)
  27. #ifdef TF_COMPILE_LIBRARY
  28. #define TF_CAPI_EXPORT __declspec(dllexport)
  29. #else
  30. #define TF_CAPI_EXPORT __declspec(dllimport)
  31. #endif // TF_COMPILE_LIBRARY
  32. #else
  33. #define TF_CAPI_EXPORT __attribute__((visibility("default")))
  34. #endif // _WIN32
  35. #endif // SWIG
  36. #ifdef __cplusplus
  37. extern "C" {
  38. #endif
  39. typedef struct TFE_ContextOptions TFE_ContextOptions;
  40. // Return a new options object.
  41. TF_CAPI_EXPORT extern TFE_ContextOptions* TFE_NewContextOptions(void);
  42. // Set the config in TF_ContextOptions.options.
  43. // config should be a serialized tensorflow.ConfigProto proto.
  44. // If config was not parsed successfully as a ConfigProto, record the
  45. // error information in *status.
  46. TF_CAPI_EXPORT extern void TFE_ContextOptionsSetConfig(
  47. TFE_ContextOptions* options, const void* proto, size_t proto_len,
  48. TF_Status* status);
  49. // Controls how to act when we try to run an operation on a given device but
  50. // some input tensors are not on that device.
  51. // LINT.IfChange
  52. // Note: Keep in sync with internal copy of enum in eager/context.h.
  53. typedef enum TFE_ContextDevicePlacementPolicy {
  54. // Running operations with input tensors on the wrong device will fail.
  55. TFE_DEVICE_PLACEMENT_EXPLICIT = 0,
  56. // Copy the tensor to the right device but log a warning.
  57. TFE_DEVICE_PLACEMENT_WARN = 1,
  58. // Silently copy the tensor, which has a performance cost since the operation
  59. // will be blocked till the copy completes. This is the default placement
  60. // policy.
  61. TFE_DEVICE_PLACEMENT_SILENT = 2,
  62. // Placement policy which silently copies int32 tensors but not other dtypes.
  63. TFE_DEVICE_PLACEMENT_SILENT_FOR_INT32 = 3,
  64. } TFE_ContextDevicePlacementPolicy;
  65. // LINT.ThenChange(//tensorflow/c/eager/immediate_execution_context.h)
  66. // Sets the default execution mode (sync/async). Note that this can be
  67. // overridden per thread using TFE_ContextSetExecutorForThread.
  68. TF_CAPI_EXPORT extern void TFE_ContextOptionsSetAsync(TFE_ContextOptions*,
  69. unsigned char enable);
  70. TF_CAPI_EXPORT extern void TFE_ContextOptionsSetDevicePlacementPolicy(
  71. TFE_ContextOptions*, TFE_ContextDevicePlacementPolicy);
  72. // Destroy an options object.
  73. TF_CAPI_EXPORT extern void TFE_DeleteContextOptions(TFE_ContextOptions*);
  74. // "Context" under which operations/functions are executed. It encapsulates
  75. // things like the available devices, resource manager etc.
  76. // TFE_Context must outlive all tensor handles created using it. In other
  77. // words, TFE_DeleteContext() must be called after all tensor handles have
  78. // been deleted (with TFE_DeleteTensorHandle).
  79. //
  80. // TODO(ashankar): Merge with TF_Session?
  81. typedef struct TFE_Context TFE_Context;
  82. TF_CAPI_EXPORT extern TFE_Context* TFE_NewContext(
  83. const TFE_ContextOptions* opts, TF_Status* status);
  84. TF_CAPI_EXPORT extern void TFE_DeleteContext(TFE_Context* ctx);
  85. TF_CAPI_EXPORT extern TF_DeviceList* TFE_ContextListDevices(TFE_Context* ctx,
  86. TF_Status* status);
  87. // Clears the internal caches in the TFE context. Useful when reseeding random
  88. // ops.
  89. TF_CAPI_EXPORT extern void TFE_ContextClearCaches(TFE_Context* ctx);
  90. // Sets a thread-local device placement policy. After this call, other calls to
  91. // TFE_Execute in the same thread will use the device policy specified here
  92. // instead of the device policy used to construct the context. This has no
  93. // effect on the device policy used by other program threads.
  94. TF_CAPI_EXPORT extern void TFE_ContextSetThreadLocalDevicePlacementPolicy(
  95. TFE_Context* ctx, TFE_ContextDevicePlacementPolicy policy);
  96. // Returns the device placement policy to be used by this context in the current
  97. // thread.
  98. TF_CAPI_EXPORT extern TFE_ContextDevicePlacementPolicy
  99. TFE_ContextGetDevicePlacementPolicy(TFE_Context* ctx);
  100. // A tensorflow.ServerDef specifies remote workers (in addition to the current
  101. // workers name). Operations created on this context can then be executed on
  102. // any of these remote workers by setting an appropriate device.
  103. //
  104. // If the following is set, all servers identified by the
  105. // ServerDef must be up when the context is created.
  106. TF_CAPI_EXPORT extern void TFE_ContextSetServerDef(TFE_Context* ctx,
  107. int keep_alive_secs,
  108. const void* proto,
  109. size_t proto_len,
  110. TF_Status* status);
  111. // A handle to a tensor on a device.
  112. //
  113. // Like a TF_Tensor, a TFE_TensorHandle refers to a tensor with a value, shape,
  114. // type etc. Unlike a TF_Tensor, a TFE_TensorHandle may refer to such tensors
  115. // placed in memory of different devices or remote address spaces.
  116. typedef struct TFE_TensorHandle TFE_TensorHandle;
  117. TF_CAPI_EXPORT extern TFE_TensorHandle* TFE_NewTensorHandle(const TF_Tensor* t,
  118. TF_Status* status);
  119. // Indicates that the caller will not be using `h` any more.
  120. TF_CAPI_EXPORT extern void TFE_DeleteTensorHandle(TFE_TensorHandle* h);
  121. TF_CAPI_EXPORT extern TF_DataType TFE_TensorHandleDataType(TFE_TensorHandle* h);
  122. // This function will block till the operation that produces `h` has completed.
  123. TF_CAPI_EXPORT extern int TFE_TensorHandleNumDims(TFE_TensorHandle* h,
  124. TF_Status* status);
  125. TF_CAPI_EXPORT extern int64_t TFE_TensorHandleNumElements(TFE_TensorHandle* h,
  126. TF_Status* status);
  127. // This function will block till the operation that produces `h` has completed.
  128. TF_CAPI_EXPORT extern int64_t TFE_TensorHandleDim(TFE_TensorHandle* h,
  129. int dim_index,
  130. TF_Status* status);
  131. // Returns the device of the operation that produced `h`. If `h` was produced by
  132. // a copy, returns the destination device of the copy. Note that the returned
  133. // device name is not always the device holding the tensor handle's memory. If
  134. // you want the latter, use TFE_TensorHandleBackingDeviceName. This function
  135. // will block till the operation that produces `h` has completed.
  136. TF_CAPI_EXPORT extern const char* TFE_TensorHandleDeviceName(
  137. TFE_TensorHandle* h, TF_Status* status);
  138. // Returns the name of the device in whose memory `h` resides.
  139. //
  140. // This function will block till the operation that produces `h` has completed.
  141. TF_CAPI_EXPORT extern const char* TFE_TensorHandleBackingDeviceName(
  142. TFE_TensorHandle* h, TF_Status* status);
  143. // Return a pointer to a new TFE_TensorHandle that shares the underlying tensor
  144. // with `h`. On success, `status` is set to OK. On failure, `status` reflects
  145. // the error and a nullptr is returned.
  146. TF_CAPI_EXPORT extern TFE_TensorHandle* TFE_TensorHandleCopySharingTensor(
  147. TFE_TensorHandle* h, TF_Status* status);
  148. // This function will block till the operation that produces `h` has
  149. // completed. The memory returned might alias the internal memory used by
  150. // TensorFlow. Hence, callers should not mutate this memory (for example by
  151. // modifying the memory region pointed to by TF_TensorData() on the returned
  152. // TF_Tensor).
  153. TF_CAPI_EXPORT extern TF_Tensor* TFE_TensorHandleResolve(TFE_TensorHandle* h,
  154. TF_Status* status);
  155. // Create a new TFE_TensorHandle with the same contents as 'h' but placed
  156. // in the memory of the device name 'device_name'.
  157. // If source and destination are the same device, then this creates a new handle
  158. // that shares the underlying buffer. Otherwise, it currently requires at least
  159. // one of the source or destination devices to be CPU (i.e., for the source or
  160. // destination tensor to be placed in host memory).
  161. // If async execution is enabled, the copy may be enqueued and the call will
  162. // return "non-ready" handle. Else, this function returns after the copy has
  163. // been done.
  164. TF_CAPI_EXPORT extern TFE_TensorHandle* TFE_TensorHandleCopyToDevice(
  165. TFE_TensorHandle* h, TFE_Context* ctx, const char* device_name,
  166. TF_Status* status);
  167. // Debugging/Profiling information for TFE_TensorHandle
  168. //
  169. // TFE_TensorDebugInfo contains information useful for debugging and
  170. // profiling tensors.
  171. typedef struct TFE_TensorDebugInfo TFE_TensorDebugInfo;
  172. // Retrieves TFE_TensorDebugInfo for `handle`.
  173. // If TFE_TensorHandleTensorDebugInfo succeeds, `status` is set to OK and caller
  174. // is responsible for deleting returned TFE_TensorDebugInfo.
  175. // If TFE_TensorHandleTensorDebugInfo fails, `status` is set to appropriate
  176. // error and nullptr is returned. This function can block till the operation
  177. // that produces `handle` has completed.
  178. TF_CAPI_EXPORT extern TFE_TensorDebugInfo* TFE_TensorHandleTensorDebugInfo(
  179. TFE_TensorHandle* h, TF_Status* status);
  180. // Deletes `debug_info`.
  181. TF_CAPI_EXPORT extern void TFE_DeleteTensorDebugInfo(
  182. TFE_TensorDebugInfo* debug_info);
  183. // Returns the number of dimensions used to represent the tensor on its device.
  184. // The number of dimensions used to represent the tensor on device can be
  185. // different from the number returned by TFE_TensorHandleNumDims.
  186. // The return value was current at the time of TFE_TensorDebugInfo creation.
  187. TF_CAPI_EXPORT extern int TFE_TensorDebugInfoOnDeviceNumDims(
  188. TFE_TensorDebugInfo* debug_info);
  189. // Returns the number of elements in dimension `dim_index`.
  190. // Tensor representation on device can be transposed from its representation
  191. // on host. The data contained in dimension `dim_index` on device
  192. // can correspond to the data contained in another dimension in on-host
  193. // representation. The dimensions are indexed using the standard TensorFlow
  194. // major-to-minor order (slowest varying dimension first),
  195. // not the XLA's minor-to-major order.
  196. // On-device dimensions can be padded. TFE_TensorDebugInfoOnDeviceDim returns
  197. // the number of elements in a dimension after padding.
  198. // The return value was current at the time of TFE_TensorDebugInfo creation.
  199. TF_CAPI_EXPORT extern int64_t TFE_TensorDebugInfoOnDeviceDim(
  200. TFE_TensorDebugInfo* debug_info, int dim_index);
  201. // Description of the TensorFlow op to execute.
  202. //
  203. // Assumes that the provided 'ctx' outlives the returned TFE_Op, i.e.,
  204. // TFE_DeleteOp() is called before TFE_DeleteContext().
  205. //
  206. // Very similar to TF_OperationDescription with some differences:
  207. // (1) TF_Output or TFE_TensorHandle* as arguments to TF_AddInput,
  208. // TF_AddInputList
  209. // (2) TF_ColocateWith, TF_AddControlInput etc. do not make sense.
  210. // (3) Implementation detail: Avoid use of NodeBuilder/NodeDefBuilder since
  211. // the additional sanity checks there seem unnecessary;
  212. typedef struct TFE_Op TFE_Op;
  213. TF_CAPI_EXPORT extern TFE_Op* TFE_NewOp(TFE_Context* ctx,
  214. const char* op_or_function_name,
  215. TF_Status* status);
  216. TF_CAPI_EXPORT extern void TFE_DeleteOp(TFE_Op* op);
  217. // Returns the op or function name `op` will execute.
  218. //
  219. // The returned string remains valid throughout the lifetime of 'op'.
  220. TF_CAPI_EXPORT extern const char* TFE_OpGetName(const TFE_Op* op,
  221. TF_Status* status);
  222. TF_CAPI_EXPORT extern TFE_Context* TFE_OpGetContext(const TFE_Op* op,
  223. TF_Status* status);
  224. TF_CAPI_EXPORT extern void TFE_OpSetDevice(TFE_Op* op, const char* device_name,
  225. TF_Status* status);
  226. // The returned string remains valid throughout the lifetime of 'op'.
  227. TF_CAPI_EXPORT extern const char* TFE_OpGetDevice(const TFE_Op* op,
  228. TF_Status* status);
  229. TF_CAPI_EXPORT extern void TFE_OpAddInput(TFE_Op* op, TFE_TensorHandle* input,
  230. TF_Status* status);
  231. TF_CAPI_EXPORT extern void TFE_OpAddInputList(TFE_Op* op,
  232. TFE_TensorHandle** inputs,
  233. int num_inputs,
  234. TF_Status* status);
  235. // Fetches the current number of inputs attached to `op`.
  236. //
  237. // Does not use the operation's definition to determine how many inputs should
  238. // be attached. It is intended for use with TFE_OpGetFlatInput to inspect an
  239. // already-finalized operation.
  240. //
  241. // Note that TFE_OpGetFlatInputCount and TFE_OpGetFlatInput operate on a flat
  242. // sequence of inputs, unlike TFE_OpGetInputLength (for getting the length of a
  243. // particular named input list, which may only be part of the op's inputs).
  244. TF_CAPI_EXPORT extern int TFE_OpGetFlatInputCount(const TFE_Op* op,
  245. TF_Status* status);
  246. // Returns a borrowed reference to one of `op`'s inputs. Use
  247. // `TFE_TensorHandleCopySharingTensor` to make a new reference.
  248. TF_CAPI_EXPORT extern TFE_TensorHandle* TFE_OpGetFlatInput(const TFE_Op* op,
  249. int index,
  250. TF_Status* status);
  251. TF_CAPI_EXPORT extern TF_AttrType TFE_OpGetAttrType(TFE_Op* op,
  252. const char* attr_name,
  253. unsigned char* is_list,
  254. TF_Status* status);
  255. // Get an attribute type given an op name; a fusion of TFE_NewOp and
  256. // TFE_OpGetAttrType for use from Python without the overhead of the individual
  257. // calls and memory management of TFE_Op.
  258. TF_CAPI_EXPORT extern TF_AttrType TFE_OpNameGetAttrType(
  259. TFE_Context* ctx, const char* op_or_function_name, const char* attr_name,
  260. unsigned char* is_list, TF_Status* status);
  261. TF_CAPI_EXPORT extern void TFE_OpSetAttrString(TFE_Op* op,
  262. const char* attr_name,
  263. const void* value,
  264. size_t length);
  265. TF_CAPI_EXPORT extern void TFE_OpSetAttrInt(TFE_Op* op, const char* attr_name,
  266. int64_t value);
  267. TF_CAPI_EXPORT extern void TFE_OpSetAttrFloat(TFE_Op* op, const char* attr_name,
  268. float value);
  269. TF_CAPI_EXPORT extern void TFE_OpSetAttrBool(TFE_Op* op, const char* attr_name,
  270. unsigned char value);
  271. TF_CAPI_EXPORT extern void TFE_OpSetAttrType(TFE_Op* op, const char* attr_name,
  272. TF_DataType value);
  273. // If the number of dimensions is unknown, `num_dims` must be set to
  274. // -1 and `dims` can be null. If a dimension is unknown, the
  275. // corresponding entry in the `dims` array must be -1.
  276. TF_CAPI_EXPORT extern void TFE_OpSetAttrShape(TFE_Op* op, const char* attr_name,
  277. const int64_t* dims,
  278. const int num_dims,
  279. TF_Status* out_status);
  280. // Sets the attribute attr_name to be a function specified by 'function'.
  281. //
  282. // TODO(ashankar,iga): Add this functionality to the C API for graph
  283. // construction. Perhaps we want an AttrValueMap equivalent in the C API?
  284. TF_CAPI_EXPORT extern void TFE_OpSetAttrFunction(TFE_Op* op,
  285. const char* attr_name,
  286. const TFE_Op* value);
  287. TF_CAPI_EXPORT void TFE_OpSetAttrFunctionName(TFE_Op* op, const char* attr_name,
  288. const char* data, size_t length);
  289. TF_CAPI_EXPORT extern void TFE_OpSetAttrTensor(TFE_Op* op,
  290. const char* attr_name,
  291. TF_Tensor* tensor,
  292. TF_Status* status);
  293. TF_CAPI_EXPORT extern void TFE_OpSetAttrStringList(TFE_Op* op,
  294. const char* attr_name,
  295. const void* const* values,
  296. const size_t* lengths,
  297. int num_values);
  298. TF_CAPI_EXPORT extern void TFE_OpSetAttrIntList(TFE_Op* op,
  299. const char* attr_name,
  300. const int64_t* values,
  301. int num_values);
  302. TF_CAPI_EXPORT extern void TFE_OpSetAttrFloatList(TFE_Op* op,
  303. const char* attr_name,
  304. const float* values,
  305. int num_values);
  306. TF_CAPI_EXPORT extern void TFE_OpSetAttrBoolList(TFE_Op* op,
  307. const char* attr_name,
  308. const unsigned char* values,
  309. int num_values);
  310. TF_CAPI_EXPORT extern void TFE_OpSetAttrTypeList(TFE_Op* op,
  311. const char* attr_name,
  312. const TF_DataType* values,
  313. int num_values);
  314. TF_CAPI_EXPORT extern void TFE_OpSetAttrShapeList(
  315. TFE_Op* op, const char* attr_name, const int64_t** dims,
  316. const int* num_dims, int num_values, TF_Status* out_status);
  317. TF_CAPI_EXPORT extern void TFE_OpSetAttrFunctionList(TFE_Op* op,
  318. const char* attr_name,
  319. const TFE_Op** value,
  320. int num_values);
  321. // Returns the length (number of tensors) of the input argument `input_name`
  322. // found in the provided `op`.
  323. TF_CAPI_EXPORT extern int TFE_OpGetInputLength(TFE_Op* op,
  324. const char* input_name,
  325. TF_Status* status);
  326. // Returns the length (number of tensors) of the output argument `output_name`
  327. // found in the provided `op`.
  328. TF_CAPI_EXPORT extern int TFE_OpGetOutputLength(TFE_Op* op,
  329. const char* output_name,
  330. TF_Status* status);
  331. // Execute the operation defined by 'op' and return handles to computed
  332. // tensors in `retvals`.
  333. //
  334. // 'retvals' must point to a pre-allocated array of TFE_TensorHandle* and
  335. // '*num_retvals' should be set to the size of this array. It is an error if
  336. // the size of 'retvals' is less than the number of outputs. This call sets
  337. // *num_retvals to the number of outputs.
  338. //
  339. // If async execution is enabled, the call may simply enqueue the execution
  340. // and return "non-ready" handles in `retvals`. Note that any handles contained
  341. // in 'op' should not be mutated till the kernel execution actually finishes.
  342. //
  343. // For sync execution, if any of the inputs to `op` are not ready, this call
  344. // will block till they become ready and then return when the kernel execution
  345. // is done.
  346. // TODO(agarwal): change num_retvals to int from int*.
  347. TF_CAPI_EXPORT extern void TFE_Execute(TFE_Op* op, TFE_TensorHandle** retvals,
  348. int* num_retvals, TF_Status* status);
  349. // Add a function (serialized FunctionDef protocol buffer) to ctx so
  350. // that it can be invoked using TFE_Execute.
  351. TF_CAPI_EXPORT extern void TFE_ContextAddFunctionDef(
  352. TFE_Context* ctx, const char* serialized_function_def, size_t size,
  353. TF_Status* status);
  354. // Adds a function (created from TF_GraphToFunction or
  355. // TF_FunctionImportFunctionDef) to the context, allowing it to be executed with
  356. // TFE_Execute by creating an op with the same name as the function.
  357. TF_CAPI_EXPORT extern void TFE_ContextAddFunction(TFE_Context* ctx,
  358. TF_Function* function,
  359. TF_Status* status);
  360. // Removes a function from the context. Once removed, you can no longer
  361. // TFE_Execute it or TFE_Execute any TFE_Op which has it as an attribute or any
  362. // other function which calls it as an attribute.
  363. TF_CAPI_EXPORT extern void TFE_ContextRemoveFunction(TFE_Context* ctx,
  364. const char* name,
  365. TF_Status* status);
  366. // Checks whether a function is registered under `name`.
  367. TF_CAPI_EXPORT unsigned char TFE_ContextHasFunction(TFE_Context* ctx,
  368. const char* name);
  369. // Enables tracing of RunMetadata on the ops executed from this context.
  370. TF_CAPI_EXPORT extern void TFE_ContextEnableRunMetadata(TFE_Context* ctx);
  371. // Disables tracing of RunMetadata on the ops executed from this context.
  372. TF_CAPI_EXPORT extern void TFE_ContextDisableRunMetadata(TFE_Context* ctx);
  373. // Populates the passed-in buffer with a serialized RunMetadata protocol buffer
  374. // containing any run metadata information accumulated so far and clears this
  375. // information.
  376. // If async mode is enabled, this call blocks till all currently pending ops are
  377. // done.
  378. TF_CAPI_EXPORT extern void TFE_ContextExportRunMetadata(TFE_Context* ctx,
  379. TF_Buffer* buf,
  380. TF_Status* status);
  381. // Some TF ops need a step container to be set to limit the lifetime of some
  382. // resources (mostly TensorArray and Stack, used in while loop gradients in
  383. // graph mode). Calling this on a context tells it to start a step.
  384. TF_CAPI_EXPORT extern void TFE_ContextStartStep(TFE_Context* ctx);
  385. // Ends a step. When there is no active step (that is, every started step has
  386. // been ended) step containers will be cleared. Note: it is not safe to call
  387. // TFE_ContextEndStep while ops which rely on the step container may be running.
  388. TF_CAPI_EXPORT extern void TFE_ContextEndStep(TFE_Context* ctx);
  389. #ifdef __cplusplus
  390. } /* end extern "C" */
  391. #endif
  392. #ifdef __cplusplus
  393. // A workaround to ease conversion to and from numpy objects and
  394. // TFE_TensorHandle's.
  395. //
  396. // TODO(ashankar): Figure out an alternative scheme that precludes the need for
  397. // these API-boundary breaking methods.
  398. namespace tensorflow {
  399. class Tensor;
  400. } // namespace tensorflow
  401. TFE_TensorHandle* TFE_NewTensorHandle(const tensorflow::Tensor& t,
  402. TF_Status* status);
  403. #endif
  404. #endif // TENSORFLOW_C_EAGER_C_API_H_
粤ICP备19079148号