tensorflow 0.1.0.2 → 0.2.0.0
raw patch · 11 files changed
+1683/−1071 lines, 11 filesdep −proto-lens-protocdep ~tensorflow-protonew-uploader
Dependencies removed: proto-lens-protoc
Dependency ranges changed: tensorflow-proto
Files
- src/TensorFlow/Build.hs +0/−1
- src/TensorFlow/BuildOp.hs +2/−2
- src/TensorFlow/Internal/FFI.hs +13/−11
- src/TensorFlow/Nodes.hs +6/−0
- src/TensorFlow/Orphans.hs +0/−46
- src/TensorFlow/Output.hs +0/−1
- src/TensorFlow/Session.hs +20/−14
- src/TensorFlow/Tensor.hs +23/−16
- src/TensorFlow/Types.hs +83/−10
- tensorflow.cabal +2/−5
- third_party/tensorflow/c/c_api.h +1534/−965
src/TensorFlow/Build.hs view
@@ -91,7 +91,6 @@ , op ) -import TensorFlow.Orphans () import TensorFlow.Output newtype Unique = Unique Int
src/TensorFlow/BuildOp.hs view
@@ -126,13 +126,13 @@ put $! ResultState (i+1) ns return $! output i o -instance Rendered v => BuildResult (Tensor v a) where+instance (TensorKind v, Rendered (Tensor v)) => BuildResult (Tensor v a) where buildResult = Tensor . pure <$> recordResult instance BuildResult ControlNode where buildResult = ControlNode <$> ask -instance (Rendered v, TensorTypes as) => BuildResult (TensorList v as) where+instance (TensorKind v, Rendered (Tensor v), TensorTypes as) => BuildResult (TensorList v as) where buildResult = loop (tensorTypes :: TensorTypeList as) where loop :: TensorTypeList bs -> Result (TensorList v bs)
src/TensorFlow/Internal/FFI.hs view
@@ -33,8 +33,9 @@ import Control.Concurrent.Async (Async, async, cancel, waitCatch) import Control.Concurrent.MVar (MVar, modifyMVarMasked_, newMVar, takeMVar)-import Control.Exception (Exception, throwIO, bracket, finally, mask_) import Control.Monad (when)+import Control.Monad.Catch (MonadMask, Exception, throwM, bracket, finally, mask_)+import Control.Monad.IO.Class (MonadIO, liftIO) import Data.Bits (Bits, toIntegralSized) import Data.Int (Int64) import Data.Maybe (fromMaybe)@@ -75,13 +76,14 @@ -- | Runs the given action after creating a session with options -- populated by the given optionSetter.-withSession :: (Raw.SessionOptions -> IO ())- -> ((IO () -> IO ()) -> Raw.Session -> IO a)+withSession :: (MonadIO m, MonadMask m)+ => (Raw.SessionOptions -> IO ())+ -> ((IO () -> IO ()) -> Raw.Session -> m a) -- ^ The action can spawn concurrent tasks which will -- be canceled before withSession returns.- -> IO a+ -> m a withSession optionSetter action = do- drain <- newMVar []+ drain <- liftIO $ newMVar [] let cleanup s = -- Closes the session to nudge the pending run calls to fail and exit. finally (checkStatus (Raw.closeSession s)) $ do@@ -89,10 +91,10 @@ -- Collects all runners before deleting the session. mapM_ shutDownRunner runners checkStatus (Raw.deleteSession s)- bracket Raw.newSessionOptions Raw.deleteSessionOptions $ \options -> do- optionSetter options- bracket- (checkStatus (Raw.newSession options))+ let bracketIO x y = bracket (liftIO x) (liftIO . y)+ bracketIO Raw.newSessionOptions Raw.deleteSessionOptions $ \options -> do+ bracketIO+ (optionSetter options >> checkStatus (Raw.newSession options)) cleanup (action (asyncCollector drain)) @@ -225,7 +227,7 @@ when (code /= Raw.TF_OK) $ do msg <- T.decodeUtf8With T.lenientDecode <$> (Raw.message status >>= B.packCString)- throwIO $ TensorFlowException code msg+ throwM $ TensorFlowException code msg return result setSessionConfig :: ConfigProto -> Raw.SessionOptions -> IO ()@@ -258,7 +260,7 @@ where checkCall = do p <- Raw.getAllOpList- when (p == nullPtr) (throwIO exception)+ when (p == nullPtr) (throwM exception) return p exception = TensorFlowException Raw.TF_UNKNOWN "GetAllOpList failure, check logs"
src/TensorFlow/Nodes.hs view
@@ -89,6 +89,12 @@ instance Fetchable t a => Fetchable [t] [a] where getFetch ts = sequenceA <$> mapM getFetch ts +instance Nodes t => Nodes (Maybe t) where+ getNodes = nodesUnion . fmap getNodes++instance Fetchable t a => Fetchable (Maybe t) (Maybe a) where+ getFetch = fmap sequenceA . mapM getFetch+ instance Nodes ControlNode where getNodes (ControlNode o) = pure $ Set.singleton o
− src/TensorFlow/Orphans.hs
@@ -1,46 +0,0 @@--- Copyright 2016 TensorFlow authors.------ Licensed under the Apache License, Version 2.0 (the "License");--- you may not use this file except in compliance with the License.--- You may obtain a copy of the License at------ http://www.apache.org/licenses/LICENSE-2.0------ Unless required by applicable law or agreed to in writing, software--- distributed under the License is distributed on an "AS IS" BASIS,--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.--- See the License for the specific language governing permissions and--- limitations under the License.---{-# LANGUAGE StandaloneDeriving #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}--- Orphan instances for certain proto messages/enums, used internally.--- TODO(judahjacobson): consider making proto-lens generate some or all of--- these automatically; or, alternately, make new Haskell datatypes.-module TensorFlow.Orphans() where--import Proto.Tensorflow.Core.Framework.AttrValue- ( AttrValue(..)- , AttrValue'ListValue(..)- , NameAttrList(..)- )-import Proto.Tensorflow.Core.Framework.NodeDef- ( NodeDef(..))-import Proto.Tensorflow.Core.Framework.ResourceHandle- ( ResourceHandle(..))-import Proto.Tensorflow.Core.Framework.Tensor- (TensorProto(..))-import Proto.Tensorflow.Core.Framework.TensorShape- (TensorShapeProto(..), TensorShapeProto'Dim(..))-import Proto.Tensorflow.Core.Framework.Types (DataType(..))--deriving instance Ord AttrValue-deriving instance Ord AttrValue'ListValue-deriving instance Ord DataType-deriving instance Ord NameAttrList-deriving instance Ord NodeDef-deriving instance Ord ResourceHandle-deriving instance Ord TensorProto-deriving instance Ord TensorShapeProto-deriving instance Ord TensorShapeProto'Dim
src/TensorFlow/Output.hs view
@@ -44,7 +44,6 @@ import Proto.Tensorflow.Core.Framework.AttrValue (AttrValue(..)) import Data.Default (def) import TensorFlow.Types (Attribute, attrLens)-import TensorFlow.Orphans () -- | A type of graph node which has no outputs. These nodes are -- valuable for causing side effects when they are run.
src/TensorFlow/Session.hs view
@@ -20,6 +20,7 @@ module TensorFlow.Session ( Session,+ SessionT, Options, sessionConfig, sessionTarget,@@ -39,7 +40,7 @@ import Control.Monad (forever, unless, void) import Control.Monad.Catch (MonadThrow, MonadCatch, MonadMask) import Control.Monad.IO.Class (MonadIO, liftIO)-import Control.Monad.Trans.Class (lift)+import Control.Monad.Trans.Class (MonadTrans, lift) import Control.Monad.Trans.Reader (ReaderT(..), ask, asks) import Data.ByteString (ByteString) import Data.Default (Default, def)@@ -73,13 +74,18 @@ , tracer :: Tracer } -newtype Session a- = Session (ReaderT SessionState (BuildT IO) a)+newtype SessionT m a+ = Session (ReaderT SessionState (BuildT m) a) deriving (Functor, Applicative, Monad, MonadIO, MonadThrow, MonadCatch, MonadMask) +instance MonadTrans SessionT where+ lift = Session . lift . lift++type Session = SessionT IO+ -- | Run 'Session' actions in a new TensorFlow session.-runSession :: Session a -> IO a+runSession :: (MonadMask m, MonadIO m) => SessionT m a -> m a runSession = runSessionWithOptions def -- | Customization for session. Use the lenses to update:@@ -112,7 +118,7 @@ -- | Run 'Session' actions in a new TensorFlow session created with -- the given option setter actions ('sessionTarget', 'sessionConfig').-runSessionWithOptions :: Options -> Session a -> IO a+runSessionWithOptions :: (MonadMask m, MonadIO m) => Options -> SessionT m a -> m a runSessionWithOptions options (Session m) = FFI.withSession applyOptions $ \as rs ->@@ -122,14 +128,14 @@ FFI.setSessionTarget (options ^. sessionTarget) opt FFI.setSessionConfig (options ^. sessionConfig) opt -instance MonadBuild Session where+instance Monad m => MonadBuild (SessionT m) where build = Session . lift . build -- | Add all pending rendered nodes to the TensorFlow graph and runs -- any pending initializers. -- -- Note that run, runWithFeeds, etc. will all call this function implicitly.-extend :: Session ()+extend :: MonadIO m => SessionT m () extend = do session <- Session (asks rawSession) trace <- Session (asks tracer)@@ -145,13 +151,13 @@ -- | Run a subgraph 't', rendering any dependent nodes that aren't already -- rendered, and fetch the corresponding values for 'a'.-run :: Fetchable t a => t -> Session a+run :: (MonadIO m, Fetchable t a) => t -> SessionT m a run = runWithFeeds [] -- | Run a subgraph 't', rendering any dependent nodes that aren't already -- rendered, feed the given input values, and fetch the corresponding result -- values for 'a'.-runWithFeeds :: Fetchable t a => [Feed] -> t -> Session a+runWithFeeds :: (MonadIO m, Fetchable t a) => [Feed] -> t -> SessionT m a runWithFeeds feeds t = do ns <- build $ getNodes t -- Note that this call to "fetch" shouldn't affect the following "extend"@@ -160,7 +166,7 @@ fetch <- build $ getFetch t runFetchWithFeeds feeds ns fetch -runFetchWithFeeds :: [Feed] -> Set NodeName -> Fetch a -> Session a+runFetchWithFeeds :: MonadIO m => [Feed] -> Set NodeName -> Fetch a -> SessionT m a runFetchWithFeeds feeds target (Fetch fetch restore) = do extend let feeds' = fixFeeds feeds@@ -180,14 +186,14 @@ -- | Run a subgraph 't', rendering and extending any dependent nodes that aren't -- already rendered. This behaves like 'run' except that it doesn't do any -- fetches.-run_ :: Nodes t => t -> Session ()+run_ :: (MonadIO m, Nodes t) => t -> SessionT m () run_ = runWithFeeds_ [] -- | Run a subgraph 't', rendering any dependent nodes that aren't already -- rendered, feed the given input values, and fetch the corresponding result -- values for 'a'. This behaves like 'runWithFeeds' except that it doesn't do -- any fetches.-runWithFeeds_ :: Nodes t => [Feed] -> t -> Session ()+runWithFeeds_ :: (MonadIO m, Nodes t) => [Feed] -> t -> SessionT m () runWithFeeds_ feeds t = do ns <- build $ getNodes t runFetchWithFeeds feeds ns (pure ())@@ -199,9 +205,9 @@ -- forever until runSession exits or an exception occurs. Graph -- extension happens synchronously, but the resultant run proceeds as -- a separate thread.-asyncProdNodes :: Nodes t+asyncProdNodes :: (MonadIO m, Nodes t) => t -- ^ Node to evaluate concurrently.- -> Session ()+ -> SessionT m () asyncProdNodes nodes = do target <- build (getNodes nodes) extend
src/TensorFlow/Tensor.hs view
@@ -13,6 +13,7 @@ -- limitations under the License. {-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE GADTs #-}@@ -37,7 +38,8 @@ import TensorFlow.Build import TensorFlow.Output (Output, NodeName, outputNodeName, Device(..)) import TensorFlow.Types- ( TensorData(..)+ ( TensorType+ , TensorData(..) , ListOf(..) ) import qualified TensorFlow.Internal.FFI as FFI@@ -89,19 +91,16 @@ -- | A class ensuring that a given tensor is rendered, i.e., has a fixed -- name, device, etc.-class TensorKind v => Rendered v where- rendered :: v a -> a--instance Rendered Value where- rendered = runValue+class Rendered t where+ renderedOutput :: t a -> Output -instance Rendered Ref where- rendered = runRef+instance Rendered (Tensor Value) where+ renderedOutput = runValue . tensorOutput -renderedOutput :: Rendered v => Tensor v a -> Output-renderedOutput = rendered . tensorOutput+instance Rendered (Tensor Ref) where+ renderedOutput = runRef . tensorOutput -tensorNodeName :: Rendered v => Tensor v a -> NodeName+tensorNodeName :: Rendered t => t a -> NodeName tensorNodeName = outputNodeName . renderedOutput @@ -110,7 +109,7 @@ -- -- Note that if a 'Tensor' is rendered, its identity may change; so feeding the -- rendered 'Tensor' may be different than feeding the original 'Tensor'.-feed :: Rendered v => Tensor v a -> TensorData a -> Feed+feed :: Rendered t => t a -> TensorData a -> Feed feed t (TensorData td) = Feed (renderedOutput t) td -- | Create a 'Tensor' for a given name. This can be used to reference nodes@@ -129,7 +128,7 @@ type TensorList v = ListOf (Tensor v) -tensorListOutputs :: Rendered v => TensorList v as -> [Output]+tensorListOutputs :: Rendered (Tensor v) => TensorList v as -> [Output] tensorListOutputs Nil = [] tensorListOutputs (t :/ ts) = renderedOutput t : tensorListOutputs ts @@ -137,7 +136,7 @@ -- device as the given Tensor (see also 'withDevice'). Make sure that -- the action has side effects of rendering the desired tensors. A pure -- return would not have the desired effect.-colocateWith :: (MonadBuild m, Rendered v) => Tensor v b -> m a -> m a+colocateWith :: (MonadBuild m, Rendered t) => t b -> m a -> m a colocateWith t x = do d <- build $ Device . (^. device) <$> lookupNode (outputNodeName $ renderedOutput t)@@ -184,10 +183,18 @@ toBuild :: v a -> Build a instance TensorKind Value where- toBuild = return . rendered+ toBuild = return . runValue instance TensorKind Ref where- toBuild = return . rendered+ toBuild = return . runRef instance TensorKind Build where toBuild = id+++-- | Types which can be converted to `Tensor`.+class ToTensor t where+ toTensor :: TensorType a => t a -> Tensor Build a++instance TensorKind v => ToTensor (Tensor v) where+ toTensor = expr
src/TensorFlow/Types.hs view
@@ -19,6 +19,7 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MonoLocalBinds #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RankNTypes #-}@@ -40,6 +41,7 @@ , Attribute(..) , DataType(..) , ResourceHandle+ , Variant -- * Lists , ListOf(..) , List@@ -66,13 +68,15 @@ import Data.Complex (Complex) import Data.Default (def) import Data.Int (Int8, Int16, Int32, Int64)+import Data.Maybe (fromMaybe) import Data.Monoid ((<>))+import Data.ProtoLens.TextFormat (showMessageShort) import Data.Proxy (Proxy(..)) import Data.String (IsString)-import Data.Word (Word8, Word16, Word64)+import Data.Word (Word8, Word16, Word32, Word64) import Foreign.Storable (Storable) import GHC.Exts (Constraint, IsList(..))-import Lens.Family2 (Lens', view, (&), (.~))+import Lens.Family2 (Lens', view, (&), (.~), (^..)) import Lens.Family2.Unchecked (iso) import Text.Printf (printf) import qualified Data.Attoparsec.ByteString as Atto@@ -96,7 +100,7 @@ , tensor ) import Proto.Tensorflow.Core.Framework.ResourceHandle- (ResourceHandle)+ (ResourceHandleProto) import Proto.Tensorflow.Core.Framework.Tensor as Tensor ( TensorProto(..) , boolVal@@ -106,18 +110,27 @@ , int64Val , resourceHandleVal , stringVal- , stringVal+ , uint32Val+ , uint64Val ) import Proto.Tensorflow.Core.Framework.TensorShape ( TensorShapeProto(..) , dim , size+ , unknownRank ) import Proto.Tensorflow.Core.Framework.Types (DataType(..)) import TensorFlow.Internal.VarInt (getVarInt, putVarInt) import qualified TensorFlow.Internal.FFI as FFI +type ResourceHandle = ResourceHandleProto++-- | Dynamic type.+-- TensorFlow variants aren't supported yet. This type acts a placeholder to+-- simplify op generation.+data Variant+ -- | The class of scalar types supported by tensorflow. class TensorType a where tensorType :: a -> DataType@@ -157,6 +170,16 @@ tensorRefType _ = DT_UINT16_REF tensorVal = intVal . integral +instance TensorType Word32 where+ tensorType _ = DT_UINT32+ tensorRefType _ = DT_UINT32_REF+ tensorVal = uint32Val++instance TensorType Word64 where+ tensorType _ = DT_UINT64+ tensorRefType _ = DT_UINT64_REF+ tensorVal = uint64Val+ instance TensorType Int16 where tensorType _ = DT_INT16 tensorRefType _ = DT_INT16_REF@@ -192,6 +215,11 @@ tensorRefType _ = DT_RESOURCE_REF tensorVal = resourceHandleVal +instance TensorType Variant where+ tensorType _ = DT_VARIANT+ tensorRefType _ = DT_VARIANT_REF+ tensorVal = error "TODO Variant"+ -- | Tensor data with the correct memory layout for tensorflow. newtype TensorData a = TensorData { unTensorData :: FFI.TensorData } @@ -350,6 +378,9 @@ -- | Shape (dimensions) of a tensor.+--+-- TensorFlow supports shapes of unknown rank, which are represented as+-- @Nothing :: Maybe Shape@ in Haskell. newtype Shape = Shape [Int64] deriving Show instance IsList Shape where@@ -360,10 +391,26 @@ protoShape :: Lens' TensorShapeProto Shape protoShape = iso protoToShape shapeToProto where- protoToShape = Shape . fmap (view size) . view dim- shapeToProto (Shape ds) = (def :: TensorShapeProto) & dim .~ fmap (\d -> def & size .~ d) ds+ protoToShape p = fromMaybe (error msg) (view protoMaybeShape p)+ where msg = "Can't convert TensorShapeProto with unknown rank to Shape: "+ ++ showMessageShort p+ shapeToProto s' = def & protoMaybeShape .~ Just s' +protoMaybeShape :: Lens' TensorShapeProto (Maybe Shape)+protoMaybeShape = iso protoToShape shapeToProto+ where+ protoToShape :: TensorShapeProto -> Maybe Shape+ protoToShape p =+ if view unknownRank p+ then Nothing+ else Just (Shape (p ^.. dim . traverse . size))+ shapeToProto :: Maybe Shape -> TensorShapeProto+ shapeToProto Nothing =+ def & unknownRank .~ True+ shapeToProto (Just (Shape ds)) =+ def & dim .~ fmap (\d -> def & size .~ d) ds + class Attribute a where attrLens :: Lens' AttrValue a @@ -388,6 +435,9 @@ instance Attribute Shape where attrLens = shape . protoShape +instance Attribute (Maybe Shape) where+ attrLens = shape . protoMaybeShape+ -- TODO(gnezdo): support generating list(Foo) from [Foo]. instance Attribute AttrValue'ListValue where attrLens = list@@ -453,10 +503,10 @@ -- -- using an enumeration of all the possible 'TensorType's. type OneOf ts a- -- Assert `TensorTypes ts` to make error messages a little better.- = (TensorType a, TensorTypes ts, NoneOf (AllTensorTypes \\ ts) a)+ -- Assert `TensorTypes' ts` to make error messages a little better.+ = (TensorType a, TensorTypes' ts, NoneOf (AllTensorTypes \\ ts) a) -type OneOfs ts as = (TensorTypes as, TensorTypes ts,+type OneOfs ts as = (TensorTypes as, TensorTypes' ts, NoneOfs (AllTensorTypes \\ ts) as) type family NoneOfs ts as :: Constraint where@@ -486,6 +536,29 @@ instance (TensorType t, TensorTypes ts) => TensorTypes (t ': ts) where tensorTypes = TensorTypeProxy :/ tensorTypes +-- | A simpler version of the 'TensorTypes' class, that doesn't run+-- afoul of @-Wsimplifiable-class-constraints@.+--+-- In more detail: the constraint @OneOf '[Double, Float] a@ leads+-- to the constraint @TensorTypes' '[Double, Float]@, as a safety-check+-- to give better error messages. However, if @TensorTypes'@ were a class,+-- then GHC 8.2.1 would complain with the above warning unless @NoMonoBinds@+-- were enabled. So instead, we use a separate type family for this purpose.+-- For more details: https://ghc.haskell.org/trac/ghc/ticket/11948+type family TensorTypes' (ts :: [*]) :: Constraint where+ -- Specialize this type family when `ts` is a long list, to avoid deeply+ -- nested tuples of constraints. Works around a bug in ghc-8.0:+ -- https://ghc.haskell.org/trac/ghc/ticket/12175+ TensorTypes' (t1 ': t2 ': t3 ': t4 ': ts)+ = (TensorType t1, TensorType t2, TensorType t3, TensorType t4+ , TensorTypes' ts)+ TensorTypes' (t1 ': t2 ': t3 ': ts)+ = (TensorType t1, TensorType t2, TensorType t3, TensorTypes' ts)+ TensorTypes' (t1 ': t2 ': ts)+ = (TensorType t1, TensorType t2, TensorTypes' ts)+ TensorTypes' (t ': ts) = (TensorType t, TensorTypes' ts)+ TensorTypes' '[] = ()+ -- | A constraint checking that two types are different. type family a /= b :: Constraint where a /= a = TypeError a ~ ExcludedCase@@ -529,7 +602,7 @@ -- Assumes that @a@ and each of the elements of @ts@ are 'TensorType's. type family NoneOf ts a :: Constraint where -- Specialize this type family when `ts` is a long list, to avoid deeply- -- nested tuples of constraints. Works around a bug in ghc-8:+ -- nested tuples of constraints. Works around a bug in ghc-8.0: -- https://ghc.haskell.org/trac/ghc/ticket/12175 NoneOf (t1 ': t2 ': t3 ': t4 ': ts) a = (a /= t1, a /= t2, a /= t3, a /= t4, NoneOf ts a)
tensorflow.cabal view
@@ -1,5 +1,5 @@ name: tensorflow-version: 0.1.0.2+version: 0.2.0.0 synopsis: TensorFlow bindings. description: This library provides an interface to the TensorFlow@@ -35,12 +35,9 @@ , TensorFlow.Tensor , TensorFlow.Types other-modules: TensorFlow.Internal.Raw- , TensorFlow.Orphans build-tools: c2hs build-depends: proto-lens == 0.2.*- -- Used by the custom Setup script (for the test-suite).- , proto-lens-protoc == 0.2.*- , tensorflow-proto == 0.1.*+ , tensorflow-proto == 0.2.* , base >= 4.7 && < 5 , async , attoparsec
third_party/tensorflow/c/c_api.h view
@@ -64,971 +64,1540 @@ // and the API just provides high level controls over the number of // devices of each type. -#ifdef __cplusplus-extern "C" {-#endif--// ---------------------------------------------------------------------------// TF_Version returns a string describing version information of the-// TensorFlow library. TensorFlow using semantic versioning.-extern const char* TF_Version();--// ---------------------------------------------------------------------------// TF_DataType holds the type for a scalar value. E.g., one slot in a tensor.-// The enum values here are identical to corresponding values in types.proto.-typedef enum {- TF_FLOAT = 1,- TF_DOUBLE = 2,- TF_INT32 = 3, // Int32 tensors are always in 'host' memory.- TF_UINT8 = 4,- TF_INT16 = 5,- TF_INT8 = 6,- TF_STRING = 7,- TF_COMPLEX64 = 8, // Single-precision complex- TF_COMPLEX = 8, // Old identifier kept for API backwards compatibility- TF_INT64 = 9,- TF_BOOL = 10,- TF_QINT8 = 11, // Quantized int8- TF_QUINT8 = 12, // Quantized uint8- TF_QINT32 = 13, // Quantized int32- TF_BFLOAT16 = 14, // Float32 truncated to 16 bits. Only for cast ops.- TF_QINT16 = 15, // Quantized int16- TF_QUINT16 = 16, // Quantized uint16- TF_UINT16 = 17,- TF_COMPLEX128 = 18, // Double-precision complex- TF_HALF = 19,- TF_RESOURCE = 20,-} TF_DataType;--// TF_DataTypeSize returns the sizeof() for the underlying type corresponding-// to the given TF_DataType enum value. Returns 0 for variable length types-// (eg. TF_STRING) or on failure.-extern size_t TF_DataTypeSize(TF_DataType dt);--// ---------------------------------------------------------------------------// TF_Code holds an error code. The enum values here are identical to-// corresponding values in error_codes.proto.-typedef enum {- TF_OK = 0,- TF_CANCELLED = 1,- TF_UNKNOWN = 2,- TF_INVALID_ARGUMENT = 3,- TF_DEADLINE_EXCEEDED = 4,- TF_NOT_FOUND = 5,- TF_ALREADY_EXISTS = 6,- TF_PERMISSION_DENIED = 7,- TF_UNAUTHENTICATED = 16,- TF_RESOURCE_EXHAUSTED = 8,- TF_FAILED_PRECONDITION = 9,- TF_ABORTED = 10,- TF_OUT_OF_RANGE = 11,- TF_UNIMPLEMENTED = 12,- TF_INTERNAL = 13,- TF_UNAVAILABLE = 14,- TF_DATA_LOSS = 15,-} TF_Code;--// ---------------------------------------------------------------------------// TF_Status holds error information. It either has an OK code, or-// else an error code with an associated error message.-typedef struct TF_Status TF_Status;--// Return a new status object.-extern TF_Status* TF_NewStatus();--// Delete a previously created status object.-extern void TF_DeleteStatus(TF_Status*);--// Record <code, msg> in *s. Any previous information is lost.-// A common use is to clear a status: TF_SetStatus(s, TF_OK, "");-extern void TF_SetStatus(TF_Status* s, TF_Code code, const char* msg);--// Return the code record in *s.-extern TF_Code TF_GetCode(const TF_Status* s);--// Return a pointer to the (null-terminated) error message in *s. The-// return value points to memory that is only usable until the next-// mutation to *s. Always returns an empty string if TF_GetCode(s) is-// TF_OK.-extern const char* TF_Message(const TF_Status* s);--// ---------------------------------------------------------------------------// TF_Buffer holds a pointer to a block of data and its associated length.-// Typically, the data consists of a serialized protocol buffer, but other data-// may also be held in a buffer.-//-// By default, TF_Buffer itself does not do any memory management of the-// pointed-to block. If need be, users of this struct should specify how to-// deallocate the block by setting the `data_deallocator` function pointer.-typedef struct {- const void* data;- size_t length;- void (*data_deallocator)(void* data, size_t length);-} TF_Buffer;--// Makes a copy of the input and sets an appropriate deallocator. Useful for-// passing in read-only, input protobufs.-extern TF_Buffer* TF_NewBufferFromString(const void* proto, size_t proto_len);--// Useful for passing *out* a protobuf.-extern TF_Buffer* TF_NewBuffer();--extern void TF_DeleteBuffer(TF_Buffer*);--extern TF_Buffer TF_GetBuffer(TF_Buffer* buffer);--// ---------------------------------------------------------------------------// TF_Tensor holds a multi-dimensional array of elements of a single data type.-// For all types other than TF_STRING, the data buffer stores elements-// in row major order. E.g. if data is treated as a vector of TF_DataType:-//-// element 0: index (0, ..., 0)-// element 1: index (0, ..., 1)-// ...-//-// The format for TF_STRING tensors is:-// start_offset: array[uint64]-// data: byte[...]-//-// The string length (as a varint), followed by the contents of the string-// is encoded at data[start_offset[i]]]. TF_StringEncode and TF_StringDecode-// facilitate this encoding.--typedef struct TF_Tensor TF_Tensor;--// Return a new tensor that holds the bytes data[0,len-1].-//-// The data will be deallocated by a subsequent call to TF_DeleteTensor via:-// (*deallocator)(data, len, deallocator_arg)-// Clients must provide a custom deallocator function so they can pass in-// memory managed by something like numpy.-extern TF_Tensor* TF_NewTensor(TF_DataType, const int64_t* dims, int num_dims,- void* data, size_t len,- void (*deallocator)(void* data, size_t len,- void* arg),- void* deallocator_arg);--// Allocate and return a new Tensor.-//-// This function is an alternative to TF_NewTensor and should be used when-// memory is allocated to pass the Tensor to the C API. The allocated memory-// satisfies TensorFlow's memory alignment preferences and should be preferred-// over calling malloc and free.-//-// The caller must set the Tensor values by writing them to the pointer returned-// by TF_TensorData with length TF_TensorByteSize.-extern TF_Tensor* TF_AllocateTensor(TF_DataType, const int64_t* dims,- int num_dims, size_t len);--// Destroy a tensor.-extern void TF_DeleteTensor(TF_Tensor*);--// Return the type of a tensor element.-extern TF_DataType TF_TensorType(const TF_Tensor*);--// Return the number of dimensions that the tensor has.-extern int TF_NumDims(const TF_Tensor*);--// Return the length of the tensor in the "dim_index" dimension.-// REQUIRES: 0 <= dim_index < TF_NumDims(tensor)-extern int64_t TF_Dim(const TF_Tensor* tensor, int dim_index);--// Return the size of the underlying data in bytes.-extern size_t TF_TensorByteSize(const TF_Tensor*);--// Return a pointer to the underlying data buffer.-extern void* TF_TensorData(const TF_Tensor*);--// ---------------------------------------------------------------------------// Encode the string `src` (`src_len` bytes long) into `dst` in the format-// required by TF_STRING tensors. Does not write to memory more than `dst_len`-// bytes beyond `*dst`. `dst_len` should be at least-// TF_StringEncodedSize(src_len).-//-// On success returns the size in bytes of the encoded string.-// Returns an error into `status` otherwise.-extern size_t TF_StringEncode(const char* src, size_t src_len, char* dst,- size_t dst_len, TF_Status* status);--// Decode a string encoded using TF_StringEncode.-//-// On success, sets `*dst` to the start of the decoded string and `*dst_len` to-// its length. Returns the number of bytes starting at `src` consumed while-// decoding. `*dst` points to memory within the encoded buffer. On failure,-// `*dst` and `*dst_len` are undefined and an error is set in `status`.-//-// Does not read memory more than `src_len` bytes beyond `src`.-extern size_t TF_StringDecode(const char* src, size_t src_len, const char** dst,- size_t* dst_len, TF_Status* status);--// Return the size in bytes required to encode a string `len` bytes long into a-// TF_STRING tensor.-extern size_t TF_StringEncodedSize(size_t len);--// ---------------------------------------------------------------------------// TF_SessionOptions holds options that can be passed during session creation.-typedef struct TF_SessionOptions TF_SessionOptions;--// Return a new options object.-extern TF_SessionOptions* TF_NewSessionOptions();--// Set the target in TF_SessionOptions.options.-// target can be empty, a single entry, or a comma separated list of entries.-// Each entry is in one of the following formats :-// "local"-// ip:port-// host:port-extern void TF_SetTarget(TF_SessionOptions* options, const char* target);--// Set the config in TF_SessionOptions.options.-// config should be a serialized tensorflow.ConfigProto proto.-// If config was not parsed successfully as a ConfigProto, record the-// error information in *status.-extern void TF_SetConfig(TF_SessionOptions* options, const void* proto,- size_t proto_len, TF_Status* status);--// Destroy an options object.-extern void TF_DeleteSessionOptions(TF_SessionOptions*);--// TODO(jeff,sanjay):-// - export functions to set Config fields--// ---------------------------------------------------------------------------// The new graph construction API, still under development.--// Represents a computation graph. Graphs may be shared between sessions.-// Graphs are thread-safe when used as directed below.-typedef struct TF_Graph TF_Graph;--// Return a new graph object.-extern TF_Graph* TF_NewGraph();--// Destroy an options object. Graph will be deleted once no more-// TFSession's are referencing it.-extern void TF_DeleteGraph(TF_Graph*);--// Operation being built. The underlying graph must outlive this.-typedef struct TF_OperationDescription TF_OperationDescription;--// Operation that has been added to the graph. Valid until the graph is-// deleted -- in particular adding a new operation to the graph does not-// invalidate old TF_Operation* pointers.-typedef struct TF_Operation TF_Operation;--// Represents a specific input of an operation.-typedef struct TF_Input {- TF_Operation* oper;- int index; // The index of the input within oper.-} TF_Input;--// Represents a specific output of an operation.-typedef struct TF_Output {- TF_Operation* oper;- int index; // The index of the output within oper.-} TF_Output;--// Sets the shape of the Tensor referenced by `output` in `graph` to-// the shape described by `dims` and `num_dims`.-//-// If the number of dimensions is unknown, `num_dims` must be-// set to -1 and dims can be null. If a dimension is unknown,-// the corresponding entry in the `dims` array must be -1.-//-// This does not overwrite the existing shape associated with `output`,-// but merges the input shape with the existing shape. For example,-// setting a shape of [-1, 2] with an existing shape [2, -1] would set-// a final shape of [2, 2] based on shape merging semantics.-//-// Returns an error into `status` if:-// * `output` is not in `graph`.-// * An invalid shape is being set (e.g., the shape being set-// is incompatible with the existing shape).-extern void TF_GraphSetTensorShape(TF_Graph* graph, TF_Output output,- const int64_t* dims, const int num_dims,- TF_Status* status);--// Returns the number of dimensions of the Tensor referenced by `output`-// in `graph`.-//-// If the number of dimensions in the shape is unknown, returns -1.-//-// Returns an error into `status` if:-// * `output` is not in `graph`.-extern int TF_GraphGetTensorNumDims(TF_Graph* graph, TF_Output output,- TF_Status* status);--// Returns the shape of the Tensor referenced by `output` in `graph`-// into `dims`. `dims` must be an array large enough to hold `num_dims`-// entries (e.g., the return value of TF_GraphGetTensorNumDims).-//-// If the number of dimensions in the shape is unknown or the shape is-// a scalar, `dims` will remain untouched. Otherwise, each element of-// `dims` will be set corresponding to the size of the dimension. An-// unknown dimension is represented by `-1`.-//-// Returns an error into `status` if:-// * `output` is not in `graph`.-// * `num_dims` does not match the actual number of dimensions.-extern void TF_GraphGetTensorShape(TF_Graph* graph, TF_Output output,- int64_t* dims, int num_dims,- TF_Status* status);--// Operation will only be added to *graph when TF_FinishOperation() is-// called (assuming TF_FinishOperation() does not return an error).-// *graph must not be deleted until after TF_FinishOperation() is-// called.-extern TF_OperationDescription* TF_NewOperation(TF_Graph* graph,- const char* op_type,- const char* oper_name);--// Specify the device for `desc`. Defaults to empty, meaning unconstrained.-extern void TF_SetDevice(TF_OperationDescription* desc, const char* device);--// The calls to TF_AddInput and TF_AddInputList must match (in number,-// order, and type) the op declaration. For example, the "Concat" op-// has registration:-// REGISTER_OP("Concat")-// .Input("concat_dim: int32")-// .Input("values: N * T")-// .Output("output: T")-// .Attr("N: int >= 2")-// .Attr("T: type");-// that defines two inputs, "concat_dim" and "values" (in that order).-// You must use TF_AddInput() for the first input (since it takes a-// single tensor), and TF_AddInputList() for the second input (since-// it takes a list, even if you were to pass a list with a single-// tensor), as in:-// TF_OperationDescription* desc = TF_NewOperation(graph, "Concat", "c");-// TF_Output concat_dim_input = {...};-// TF_AddInput(desc, concat_dim_input);-// TF_Output values_inputs[5] = {{...}, ..., {...}};-// TF_AddInputList(desc, values_inputs, 5);--// For inputs that take a single tensor.-extern void TF_AddInput(TF_OperationDescription* desc, TF_Output input);--// For inputs that take a list of tensors.-// inputs must point to TF_Output[num_inputs].-extern void TF_AddInputList(TF_OperationDescription* desc,- const TF_Output* inputs, int num_inputs);--// Call once per control input to `desc`.-extern void TF_AddControlInput(TF_OperationDescription* desc,- TF_Operation* input);--// Request that `desc` be co-located on the device where `op`-// is placed.-//-// Use of this is discouraged since the implementation of device placement is-// subject to change. Primarily intended for internal libraries-extern void TF_ColocateWith(TF_OperationDescription* desc, TF_Operation* op);--// Call some TF_SetAttr*() function for every attr that is not-// inferred from an input and doesn't have a default value you wish to-// keep.--// `value` must point to a string of length `length` bytes.-extern void TF_SetAttrString(TF_OperationDescription* desc,- const char* attr_name, const void* value,- size_t length);-// `values` and `lengths` each must have lengths `num_values`.-// `values[i]` must point to a string of length `lengths[i]` bytes.-extern void TF_SetAttrStringList(TF_OperationDescription* desc,- const char* attr_name,- const void* const* values,- const size_t* lengths, int num_values);-extern void TF_SetAttrInt(TF_OperationDescription* desc, const char* attr_name,- int64_t value);-extern void TF_SetAttrIntList(TF_OperationDescription* desc,- const char* attr_name, const int64_t* values,- int num_values);-extern void TF_SetAttrFloat(TF_OperationDescription* desc,- const char* attr_name, float value);-extern void TF_SetAttrFloatList(TF_OperationDescription* desc,- const char* attr_name, const float* values,- int num_values);-extern void TF_SetAttrBool(TF_OperationDescription* desc, const char* attr_name,- unsigned char value);-extern void TF_SetAttrBoolList(TF_OperationDescription* desc,- const char* attr_name,- const unsigned char* values, int num_values);-extern void TF_SetAttrType(TF_OperationDescription* desc, const char* attr_name,- TF_DataType value);-extern void TF_SetAttrTypeList(TF_OperationDescription* desc,- const char* attr_name, const TF_DataType* values,- int num_values);--// Set `num_dims` to -1 to represent "unknown rank". Otherwise,-// `dims` points to an array of length `num_dims`. `dims[i]` must be-// >= -1, with -1 meaning "unknown dimension".-extern void TF_SetAttrShape(TF_OperationDescription* desc,- const char* attr_name, const int64_t* dims,- int num_dims);-// `dims` and `num_dims` must point to arrays of length `num_shapes`.-// Set `num_dims[i]` to -1 to represent "unknown rank". Otherwise,-// `dims[i]` points to an array of length `num_dims[i]`. `dims[i][j]`-// must be >= -1, with -1 meaning "unknown dimension".-extern void TF_SetAttrShapeList(TF_OperationDescription* desc,- const char* attr_name,- const int64_t* const* dims, const int* num_dims,- int num_shapes);-// `proto` must point to an array of `proto_len` bytes representing a-// binary-serialized TensorShapeProto.-extern void TF_SetAttrTensorShapeProto(TF_OperationDescription* desc,- const char* attr_name, const void* proto,- size_t proto_len, TF_Status* status);-// `protos` and `proto_lens` must point to arrays of length `num_shapes`.-// `protos[i]` must point to an array of `proto_lens[i]` bytes-// representing a binary-serialized TensorShapeProto.-extern void TF_SetAttrTensorShapeProtoList(TF_OperationDescription* desc,- const char* attr_name,- const void* const* protos,- const size_t* proto_lens,- int num_shapes, TF_Status* status);--extern void TF_SetAttrTensor(TF_OperationDescription* desc,- const char* attr_name, TF_Tensor* value,- TF_Status* status);-extern void TF_SetAttrTensorList(TF_OperationDescription* desc,- const char* attr_name,- TF_Tensor* const* values, int num_values,- TF_Status* status);--// `proto` should point to a sequence of bytes of length `proto_len`-// representing a binary serialization of an AttrValue protocol-// buffer.-extern void TF_SetAttrValueProto(TF_OperationDescription* desc,- const char* attr_name, const void* proto,- size_t proto_len, TF_Status* status);--// If this function succeeds:-// * *status is set to an OK value,-// * a TF_Operation is added to the graph,-// * a non-null value pointing to the added operation is returned ---// this value is valid until the underlying graph is deleted.-// Otherwise:-// * *status is set to a non-OK value,-// * the graph is not modified,-// * a null value is returned.-// In either case, it deletes `desc`.-extern TF_Operation* TF_FinishOperation(TF_OperationDescription* desc,- TF_Status* status);--// TF_Operation functions. Operations are immutable once created, so-// these are all query functions.--extern const char* TF_OperationName(TF_Operation* oper);-extern const char* TF_OperationOpType(TF_Operation* oper);-extern const char* TF_OperationDevice(TF_Operation* oper);--extern int TF_OperationNumOutputs(TF_Operation* oper);-extern TF_DataType TF_OperationOutputType(TF_Output oper_out);-extern int TF_OperationOutputListLength(TF_Operation* oper,- const char* arg_name,- TF_Status* status);--extern int TF_OperationNumInputs(TF_Operation* oper);-extern TF_DataType TF_OperationInputType(TF_Input oper_in);-extern int TF_OperationInputListLength(TF_Operation* oper, const char* arg_name,- TF_Status* status);--// In this code:-// TF_Output producer = TF_OperationInput(consumer);-// There is an edge from producer.oper's output (given by-// producer.index) to consumer.oper's input (given by consumer.index).-extern TF_Output TF_OperationInput(TF_Input oper_in);--// Get the number of current consumers of a specific output of an-// operation. Note that this number can change when new operations-// are added to the graph.-extern int TF_OperationOutputNumConsumers(TF_Output oper_out);--// Get list of all current consumers of a specific output of an-// operation. `consumers` must point to an array of length at least-// `max_consumers` (ideally set to-// TF_OperationOutputNumConsumers(oper_out)). Beware that a concurrent-// modification of the graph can increase the number of consumers of-// an operation. Returns the number of output consumers (should match-// TF_OperationOutputNumConsumers(oper_out)).-extern int TF_OperationOutputConsumers(TF_Output oper_out, TF_Input* consumers,- int max_consumers);--// Get the number of control inputs to an operation.-extern int TF_OperationNumControlInputs(TF_Operation* oper);--// Get list of all control inputs to an operation. `control_inputs` must-// point to an array of length `max_control_inputs` (ideally set to-// TF_OperationNumControlInputs(oper)). Returns the number of control-// inputs (should match TF_OperationNumControlInputs(oper)).-extern int TF_OperationGetControlInputs(TF_Operation* oper,- TF_Operation** control_inputs,- int max_control_inputs);--// Get the number of operations that have `*oper` as a control input.-// Note that this number can change when new operations are added to-// the graph.-extern int TF_OperationNumControlOutputs(TF_Operation* oper);--// Get the list of operations that have `*oper` as a control input.-// `control_outputs` must point to an array of length at least-// `max_control_outputs` (ideally set to-// TF_OperationNumControlOutputs(oper)). Beware that a concurrent-// modification of the graph can increase the number of control-// outputs. Returns the number of control outputs (should match-// TF_OperationNumControlOutputs(oper)).-extern int TF_OperationGetControlOutputs(TF_Operation* oper,- TF_Operation** control_outputs,- int max_control_outputs);--// TF_AttrType describes the type of the value of an attribute on an operation.-typedef enum {- TF_ATTR_STRING = 0,- TF_ATTR_INT = 1,- TF_ATTR_FLOAT = 2,- TF_ATTR_BOOL = 3,- TF_ATTR_TYPE = 4,- TF_ATTR_SHAPE = 5,- TF_ATTR_TENSOR = 6,- TF_ATTR_PLACEHOLDER = 7,- TF_ATTR_FUNC = 8,-} TF_AttrType;--// TF_AttrMetadata describes the value of an attribute on an operation.-typedef struct {- // A boolean: 1 if the attribute value is a list, 0 otherwise.- unsigned char is_list;-- // Length of the list if is_list is true. Undefined otherwise.- int64_t list_size;-- // Type of elements of the list if is_list != 0.- // Type of the single value stored in the attribute if is_list == 0.- TF_AttrType type;-- // Total size the attribute value.- // The units of total_size depend on is_list and type.- // (1) If type == TF_ATTR_STRING and is_list == 0- // then total_size is the byte size of the string- // valued attribute.- // (2) If type == TF_ATTR_STRING and is_list == 1- // then total_size is the cumulative byte size- // of all the strings in the list.- // (3) If type == TF_ATTR_SHAPE and is_list == 0- // then total_size is the number of dimensions- // of the shape valued attribute, or -1- // if its rank is unknown.- // (4) If type == TF_ATTR_SHAPE and is_list == 1- // then total_size is the cumulative number- // of dimensions of all shapes in the list.- // (5) Otherwise, total_size is undefined.- int64_t total_size;-} TF_AttrMetadata;--// Returns metadata about the value of the attribute `attr_name` of `oper`.-extern TF_AttrMetadata TF_OperationGetAttrMetadata(TF_Operation* oper,- const char* attr_name,- TF_Status* status);--// Fills in `value` with the value of the attribute `attr_name`. `value` must-// point to an array of length at least `max_length` (ideally set to-// TF_AttrMetadata.total_size from TF_OperationGetAttrMetadata(oper,-// attr_name)).-extern void TF_OperationGetAttrString(TF_Operation* oper, const char* attr_name,- void* value, size_t max_length,- TF_Status* status);--// Get the list of strings in the value of the attribute `attr_name`. Fills in-// `values` and `lengths`, each of which must point to an array of length at-// least `max_values`.-//-// The elements of values will point to addresses in `storage` which must be at-// least `storage_size` bytes in length. Ideally, max_values would be set to-// TF_AttrMetadata.list_size and `storage` would be at least-// TF_AttrMetadata.total_size, obtained from TF_OperationGetAttrMetadata(oper,-// attr_name).-//-// Fails if storage_size is too small to hold the requested number of strings.-extern void TF_OperationGetAttrStringList(TF_Operation* oper,- const char* attr_name, void** values,- size_t* lengths, int max_values,- void* storage, size_t storage_size,- TF_Status* status);--extern void TF_OperationGetAttrInt(TF_Operation* oper, const char* attr_name,- int64_t* value, TF_Status* status);--// Fills in `values` with the value of the attribute `attr_name` of `oper`.-// `values` must point to an array of length at least `max_values` (ideally set-// TF_AttrMetadata.list_size from TF_OperationGetAttrMetadata(oper,-// attr_name)).-extern void TF_OperationGetAttrIntList(TF_Operation* oper,- const char* attr_name, int64_t* values,- int max_values, TF_Status* status);--extern void TF_OperationGetAttrFloat(TF_Operation* oper, const char* attr_name,- float* value, TF_Status* status);--// Fills in `values` with the value of the attribute `attr_name` of `oper`.-// `values` must point to an array of length at least `max_values` (ideally set-// to TF_AttrMetadata.list_size from TF_OperationGetAttrMetadata(oper,-// attr_name)).-extern void TF_OperationGetAttrFloatList(TF_Operation* oper,- const char* attr_name, float* values,- int max_values, TF_Status* status);--extern void TF_OperationGetAttrBool(TF_Operation* oper, const char* attr_name,- unsigned char* value, TF_Status* status);--// Fills in `values` with the value of the attribute `attr_name` of `oper`.-// `values` must point to an array of length at least `max_values` (ideally set-// to TF_AttrMetadata.list_size from TF_OperationGetAttrMetadata(oper,-// attr_name)).-extern void TF_OperationGetAttrBoolList(TF_Operation* oper,- const char* attr_name,- unsigned char* values, int max_values,- TF_Status* status);--extern void TF_OperationGetAttrType(TF_Operation* oper, const char* attr_name,- TF_DataType* value, TF_Status* status);--// Fills in `values` with the value of the attribute `attr_name` of `oper`.-// `values` must point to an array of length at least `max_values` (ideally set-// to TF_AttrMetadata.list_size from TF_OperationGetAttrMetadata(oper,-// attr_name)).-extern void TF_OperationGetAttrTypeList(TF_Operation* oper,- const char* attr_name,- TF_DataType* values, int max_values,- TF_Status* status);--// Fills in `value` with the value of the attribute `attr_name` of `oper`.-// `values` must point to an array of length at least `num_dims` (ideally set to-// TF_Attr_Meta.size from TF_OperationGetAttrMetadata(oper, attr_name)).-extern void TF_OperationGetAttrShape(TF_Operation* oper, const char* attr_name,- int64_t* value, int num_dims,- TF_Status* status);--// Fills in `dims` with the list of shapes in the attribute `attr_name` of-// `oper` and `num_dims` with the corresponding number of dimensions. On return,-// for every i where `num_dims[i]` > 0, `dims[i]` will be an array of-// `num_dims[i]` elements. A value of -1 for `num_dims[i]` indicates that the-// i-th shape in the list is unknown.-//-// The elements of `dims` will point to addresses in `storage` which must be-// large enough to hold at least `storage_size` int64_ts. Ideally, `num_shapes`-// would be set to TF_AttrMetadata.list_size and `storage_size` would be set to-// TF_AttrMetadata.total_size from TF_OperationGetAttrMetadata(oper,-// attr_name).-//-// Fails if storage_size is insufficient to hold the requested shapes.-extern void TF_OperationGetAttrShapeList(TF_Operation* oper,- const char* attr_name, int64_t** dims,- int* num_dims, int num_shapes,- int64_t* storage, int storage_size,- TF_Status* status);--// Sets `value` to the binary-serialized TensorShapeProto of the value of-// `attr_name` attribute of `oper`'.-extern void TF_OperationGetAttrTensorShapeProto(TF_Operation* oper,- const char* attr_name,- TF_Buffer* value,- TF_Status* status);--// Fills in `values` with binary-serialized TensorShapeProto values of the-// attribute `attr_name` of `oper`. `values` must point to an array of length at-// least `num_values` (ideally set to TF_AttrMetadata.list_size from-// TF_OperationGetAttrMetadata(oper, attr_name)).-extern void TF_OperationGetAttrTensorShapeProtoList(TF_Operation* oper,- const char* attr_name,- TF_Buffer** values,- int max_values,- TF_Status* status);--// Gets the TF_Tensor valued attribute of `attr_name` of `oper`.-//-// Allocates a new TF_Tensor which the caller is expected to take-// ownership of (and can deallocate using TF_DeleteTensor).-extern void TF_OperationGetAttrTensor(TF_Operation* oper, const char* attr_name,- TF_Tensor** value, TF_Status* status);--// Fills in `values` with the TF_Tensor values of the attribute `attr_name` of-// `oper`. `values` must point to an array of TF_Tensor* of length at least-// `max_values` (ideally set to TF_AttrMetadata.list_size from-// TF_OperationGetAttrMetadata(oper, attr_name)).-//-// The caller takes ownership of all the non-null TF_Tensor* entries in `values`-// (which can be deleted using TF_DeleteTensor(values[i])).-extern void TF_OperationGetAttrTensorList(TF_Operation* oper,- const char* attr_name,- TF_Tensor** values, int max_values,- TF_Status* status);--// Sets `output_attr_value` to the binary-serialized AttrValue proto-// representation of the value of the `attr_name` attr of `oper`.-extern void TF_OperationGetAttrValueProto(TF_Operation* oper,- const char* attr_name,- TF_Buffer* output_attr_value,- TF_Status* status);--// Returns the operation in the graph with `oper_name`. Returns nullptr if-// no operation found.-extern TF_Operation* TF_GraphOperationByName(TF_Graph* graph,- const char* oper_name);--// Iterate through the operations of a graph. To use:-// size_t pos = 0;-// TF_Operation* oper;-// while ((oper = TF_GraphNextOperation(graph, &pos)) != nullptr) {-// DoSomethingWithOperation(oper);-// }-extern TF_Operation* TF_GraphNextOperation(TF_Graph* graph, size_t* pos);--// Write out a serialized representation of `graph` (as a GraphDef protocol-// message) to `output_graph_def` (allocated by TF_NewBuffer()).-//-// May fail on very large graphs in the future.-extern void TF_GraphToGraphDef(TF_Graph* graph, TF_Buffer* output_graph_def,- TF_Status* status);--// TF_ImportGraphDefOptions holds options that can be passed to-// TF_GraphImportGraphDef.-typedef struct TF_ImportGraphDefOptions TF_ImportGraphDefOptions;--extern TF_ImportGraphDefOptions* TF_NewImportGraphDefOptions();-extern void TF_DeleteImportGraphDefOptions(TF_ImportGraphDefOptions* opts);--// Set the prefix to be prepended to the names of nodes in `graph_def` that will-// be imported into `graph`.-extern void TF_ImportGraphDefOptionsSetPrefix(TF_ImportGraphDefOptions* opts,- const char* prefix);--// Import the graph serialized in `graph_def` into `graph`.-extern void TF_GraphImportGraphDef(TF_Graph* graph, const TF_Buffer* graph_def,- const TF_ImportGraphDefOptions* options,- TF_Status* status);--// Note: The following function may fail on very large protos in the future.--extern void TF_OperationToNodeDef(TF_Operation* oper,- TF_Buffer* output_node_def,- TF_Status* status);--// TODO(andydavis): Function to add gradients to a graph.--// TODO(josh11b): Register OpDef, available to all operations added-// to this graph.--// The following two may both benefit from a subgraph-definition API-// that re-uses most of the graph-definition API.-// TODO(andydavis): Add functions to a graph.-// TODO(yuanbyu): Add while loop to graph.--// ---------------------------------------------------------------------------// API for driving Graph execution.--typedef struct TF_Session TF_Session;--// Return a new execution session with the associated graph, or NULL on error.-//-// *graph must be a valid graph (not deleted or nullptr). This function will-// prevent the graph from being deleted until TF_DeleteSession() is called.-// Does not take ownership of opts.-extern TF_Session* TF_NewSession(TF_Graph* graph, const TF_SessionOptions* opts,- TF_Status* status);--#ifndef __ANDROID__-// TODO(ashankar): Remove the __ANDROID__ guard. This will require ensuring that-// the tensorflow/cc/saved_model:loader build target is Android friendly.--// This function creates a new TF_Session (which is created on success) using-// `session_options`, and then initializes state (restoring tensors and other-// assets) using `run_options`.-//-// Any NULL and non-NULL value combinations for (`run_options, `meta_graph_def`)-// are valid.-//-// - `export_dir` must be set to the path of the exported SavedModel.-// - `tags` must include the set of tags used to identify one MetaGraphDef in-// the SavedModel.-// - `graph` must be a graph newly allocated with TF_NewGraph().-//-// If successful, populates `graph` with the contents of the Graph and-// `meta_graph_def` with the MetaGraphDef of the loaded model.-TF_Session* TF_LoadSessionFromSavedModel(- const TF_SessionOptions* session_options, const TF_Buffer* run_options,- const char* export_dir, const char* const* tags, int tags_len,- TF_Graph* graph, TF_Buffer* meta_graph_def, TF_Status* status);-#endif // __ANDROID__--// Close a session.-//-// Contacts any other processes associated with the session, if applicable.-// May not be called after TF_DeleteSession().-extern void TF_CloseSession(TF_Session*, TF_Status* status);--// Destroy a session object.-//-// Even if error information is recorded in *status, this call discards all-// local resources associated with the session. The session may not be used-// during or after this call (and the session drops its reference to the-// corresponding graph).-extern void TF_DeleteSession(TF_Session*, TF_Status* status);--// Run the graph associated with the session starting with the supplied inputs-// (inputs[0,ninputs-1] with corresponding values in input_values[0,ninputs-1]).-//-// Any NULL and non-NULL value combinations for (`run_options`,-// `run_metadata`) are valid.-//-// - `run_options` may be NULL, in which case it will be ignored; or-// non-NULL, in which case it must point to a `TF_Buffer` containing the-// serialized representation of a `RunOptions` protocol buffer.-// - `run_metadata` may be NULL, in which case it will be ignored; or-// non-NULL, in which case it must point to an empty, freshly allocated-// `TF_Buffer` that may be updated to contain the serialized representation-// of a `RunMetadata` protocol buffer.-//-// The caller retains ownership of `input_values` (which can be deleted using-// TF_DeleteTensor). The caller also retains ownership of `run_options` and/or-// `run_metadata` (when not NULL) and should manually call TF_DeleteBuffer on-// them.-//-// On success, the tensors corresponding to outputs[0,noutputs-1] are placed in-// output_values[]. Ownership of the elements of output_values[] is transferred-// to the caller, which must eventually call TF_DeleteTensor on them.-//-// On failure, output_values[] contains NULLs.-extern void TF_SessionRun(TF_Session* session,- // RunOptions- const TF_Buffer* run_options,- // Input tensors- const TF_Output* inputs,- TF_Tensor* const* input_values, int ninputs,- // Output tensors- const TF_Output* outputs, TF_Tensor** output_values,- int noutputs,- // Target operations- const TF_Operation* const* target_opers, int ntargets,- // RunMetadata- TF_Buffer* run_metadata,- // Output status- TF_Status*);--// Set up the graph with the intended feeds (inputs) and fetches (outputs) for a-// sequence of partial run calls.-//-// On success, returns a handle that is used for subsequent PRun calls.-//-// On failure, out_status contains a tensorflow::Status with an error-// message.-// NOTE: This is EXPERIMENTAL and subject to change.-extern void TF_SessionPRunSetup(TF_Session*,- // Input names- const TF_Output* inputs, int ninputs,- // Output names- const TF_Output* outputs, int noutputs,- // Target operations- const TF_Operation* const* target_opers,- int ntargets,- // Output handle- const char** handle,- // Output status- TF_Status*);--// Continue to run the graph with additional feeds and fetches. The-// execution state is uniquely identified by the handle.-// NOTE: This is EXPERIMENTAL and subject to change.-extern void TF_SessionPRun(TF_Session*, const char* handle,- // Input tensors- const TF_Output* inputs,- TF_Tensor* const* input_values, int ninputs,- // Output tensors- const TF_Output* outputs, TF_Tensor** output_values,- int noutputs,- // Target operations- const TF_Operation* const* target_opers,- int ntargets,- // Output status- TF_Status*);--// ---------------------------------------------------------------------------// The deprecated session API. Please switch to the above instead of-// TF_ExtendGraph(). This deprecated API can be removed at any time without-// notice.--typedef struct TF_DeprecatedSession TF_DeprecatedSession;--extern TF_DeprecatedSession* TF_NewDeprecatedSession(const TF_SessionOptions*,- TF_Status* status);-extern void TF_CloseDeprecatedSession(TF_DeprecatedSession*, TF_Status* status);-extern void TF_DeleteDeprecatedSession(TF_DeprecatedSession*,- TF_Status* status);-extern void TF_Reset(const TF_SessionOptions* opt, const char** containers,- int ncontainers, TF_Status* status);-// Treat the bytes proto[0,proto_len-1] as a serialized GraphDef and-// add the nodes in that GraphDef to the graph for the session.-//-// Prefer use of TF_Session and TF_GraphImportGraphDef over this.-extern void TF_ExtendGraph(TF_DeprecatedSession*, const void* proto,- size_t proto_len, TF_Status*);--// See TF_SessionRun() above.-extern void TF_Run(TF_DeprecatedSession*, const TF_Buffer* run_options,- const char** input_names, TF_Tensor** inputs, int ninputs,- const char** output_names, TF_Tensor** outputs, int noutputs,- const char** target_oper_names, int ntargets,- TF_Buffer* run_metadata, TF_Status*);--// See TF_SessionPRunSetup() above.-extern void TF_PRunSetup(TF_DeprecatedSession*, const char** input_names,- int ninputs, const char** output_names, int noutputs,- const char** target_oper_names, int ntargets,- const char** handle, TF_Status*);--// See TF_SessionPRun above.-extern void TF_PRun(TF_DeprecatedSession*, const char* handle,- const char** input_names, TF_Tensor** inputs, int ninputs,- const char** output_names, TF_Tensor** outputs,- int noutputs, const char** target_oper_names, int ntargets,- TF_Status*);--// ---------------------------------------------------------------------------// Load plugins containing custom ops and kernels--// TF_Library holds information about dynamically loaded TensorFlow plugins.-typedef struct TF_Library TF_Library;--// Load the library specified by library_filename and register the ops and-// kernels present in that library.-//-// Pass "library_filename" to a platform-specific mechanism for dynamically-// loading a library. The rules for determining the exact location of the-// library are platform-specific and are not documented here.-//-// On success, place OK in status and return the newly created library handle.-// The caller owns the library handle.-//-// On failure, place an error status in status and return NULL.-extern TF_Library* TF_LoadLibrary(const char* library_filename,- TF_Status* status);--// Get the OpList of OpDefs defined in the library pointed by lib_handle.-//-// Returns a TF_Buffer. The memory pointed to by the result is owned by-// lib_handle. The data in the buffer will be the serialized OpList proto for-// ops defined in the library.-extern TF_Buffer TF_GetOpList(TF_Library* lib_handle);--// Frees the memory associated with the library handle.-// Does NOT unload the library.-extern void TF_DeleteLibraryHandle(TF_Library* lib_handle);--// Get the OpList of all OpDefs defined in this address space.-// Returns a TF_Buffer, ownership of which is transferred to the caller-// (and can be freed using TF_DeleteBuffer).-//-// The data in the buffer will be the serialized OpList proto for ops registered-// in this address space.-extern TF_Buffer* TF_GetAllOpList();+// Macro to control visibility of exported symbols in the shared library (.so,+// .dylib, .dll).+// This duplicates the TF_EXPORT macro definition in+// tensorflow/core/platform/macros.h in order to keep this .h file independent+// of any other includes.$a+#ifdef SWIG+#define TF_CAPI_EXPORT+#else+#if defined(_WIN32)+#ifdef TF_COMPILE_LIBRARY+#define TF_CAPI_EXPORT __declspec(dllexport)+#else+#define TF_CAPI_EXPORT __declspec(dllimport)+#endif // TF_COMPILE_LIBRARY+#else+#define TF_CAPI_EXPORT __attribute__((visibility("default")))+#endif // _WIN32+#endif // SWIG++#ifdef __cplusplus+extern "C" {+#endif++// --------------------------------------------------------------------------+// TF_Version returns a string describing version information of the+// TensorFlow library. TensorFlow using semantic versioning.+TF_CAPI_EXPORT extern const char* TF_Version();++// --------------------------------------------------------------------------+// TF_DataType holds the type for a scalar value. E.g., one slot in a tensor.+// The enum values here are identical to corresponding values in types.proto.+typedef enum TF_DataType {+ TF_FLOAT = 1,+ TF_DOUBLE = 2,+ TF_INT32 = 3, // Int32 tensors are always in 'host' memory.+ TF_UINT8 = 4,+ TF_INT16 = 5,+ TF_INT8 = 6,+ TF_STRING = 7,+ TF_COMPLEX64 = 8, // Single-precision complex+ TF_COMPLEX = 8, // Old identifier kept for API backwards compatibility+ TF_INT64 = 9,+ TF_BOOL = 10,+ TF_QINT8 = 11, // Quantized int8+ TF_QUINT8 = 12, // Quantized uint8+ TF_QINT32 = 13, // Quantized int32+ TF_BFLOAT16 = 14, // Float32 truncated to 16 bits. Only for cast ops.+ TF_QINT16 = 15, // Quantized int16+ TF_QUINT16 = 16, // Quantized uint16+ TF_UINT16 = 17,+ TF_COMPLEX128 = 18, // Double-precision complex+ TF_HALF = 19,+ TF_RESOURCE = 20,+ TF_VARIANT = 21,+ TF_UINT32 = 22,+ TF_UINT64 = 23,+} TF_DataType;++// TF_DataTypeSize returns the sizeof() for the underlying type corresponding+// to the given TF_DataType enum value. Returns 0 for variable length types+// (eg. TF_STRING) or on failure.+TF_CAPI_EXPORT extern size_t TF_DataTypeSize(TF_DataType dt);++// --------------------------------------------------------------------------+// TF_Code holds an error code. The enum values here are identical to+// corresponding values in error_codes.proto.+typedef enum TF_Code {+ TF_OK = 0,+ TF_CANCELLED = 1,+ TF_UNKNOWN = 2,+ TF_INVALID_ARGUMENT = 3,+ TF_DEADLINE_EXCEEDED = 4,+ TF_NOT_FOUND = 5,+ TF_ALREADY_EXISTS = 6,+ TF_PERMISSION_DENIED = 7,+ TF_UNAUTHENTICATED = 16,+ TF_RESOURCE_EXHAUSTED = 8,+ TF_FAILED_PRECONDITION = 9,+ TF_ABORTED = 10,+ TF_OUT_OF_RANGE = 11,+ TF_UNIMPLEMENTED = 12,+ TF_INTERNAL = 13,+ TF_UNAVAILABLE = 14,+ TF_DATA_LOSS = 15,+} TF_Code;++// --------------------------------------------------------------------------+// TF_Status holds error information. It either has an OK code, or+// else an error code with an associated error message.+typedef struct TF_Status TF_Status;++// Return a new status object.+TF_CAPI_EXPORT extern TF_Status* TF_NewStatus();++// Delete a previously created status object.+TF_CAPI_EXPORT extern void TF_DeleteStatus(TF_Status*);++// Record <code, msg> in *s. Any previous information is lost.+// A common use is to clear a status: TF_SetStatus(s, TF_OK, "");+TF_CAPI_EXPORT extern void TF_SetStatus(TF_Status* s, TF_Code code,+ const char* msg);++// Return the code record in *s.+TF_CAPI_EXPORT extern TF_Code TF_GetCode(const TF_Status* s);++// Return a pointer to the (null-terminated) error message in *s. The+// return value points to memory that is only usable until the next+// mutation to *s. Always returns an empty string if TF_GetCode(s) is+// TF_OK.+TF_CAPI_EXPORT extern const char* TF_Message(const TF_Status* s);++// --------------------------------------------------------------------------+// TF_Buffer holds a pointer to a block of data and its associated length.+// Typically, the data consists of a serialized protocol buffer, but other data+// may also be held in a buffer.+//+// By default, TF_Buffer itself does not do any memory management of the+// pointed-to block. If need be, users of this struct should specify how to+// deallocate the block by setting the `data_deallocator` function pointer.+typedef struct TF_Buffer {+ const void* data;+ size_t length;+ void (*data_deallocator)(void* data, size_t length);+} TF_Buffer;++// Makes a copy of the input and sets an appropriate deallocator. Useful for+// passing in read-only, input protobufs.+TF_CAPI_EXPORT extern TF_Buffer* TF_NewBufferFromString(const void* proto,+ size_t proto_len);++// Useful for passing *out* a protobuf.+TF_CAPI_EXPORT extern TF_Buffer* TF_NewBuffer();++TF_CAPI_EXPORT extern void TF_DeleteBuffer(TF_Buffer*);++TF_CAPI_EXPORT extern TF_Buffer TF_GetBuffer(TF_Buffer* buffer);++// --------------------------------------------------------------------------+// TF_Tensor holds a multi-dimensional array of elements of a single data type.+// For all types other than TF_STRING, the data buffer stores elements+// in row major order. E.g. if data is treated as a vector of TF_DataType:+//+// element 0: index (0, ..., 0)+// element 1: index (0, ..., 1)+// ...+//+// The format for TF_STRING tensors is:+// start_offset: array[uint64]+// data: byte[...]+//+// The string length (as a varint), followed by the contents of the string+// is encoded at data[start_offset[i]]]. TF_StringEncode and TF_StringDecode+// facilitate this encoding.++typedef struct TF_Tensor TF_Tensor;++// Return a new tensor that holds the bytes data[0,len-1].+//+// The data will be deallocated by a subsequent call to TF_DeleteTensor via:+// (*deallocator)(data, len, deallocator_arg)+// Clients must provide a custom deallocator function so they can pass in+// memory managed by something like numpy.+//+// May return NULL (and invoke the deallocator) if the provided data buffer+// (data, len) is inconsistent with a tensor of the given TF_DataType+// and the shape specified by (dima, num_dims).+TF_CAPI_EXPORT extern TF_Tensor* TF_NewTensor(+ TF_DataType, const int64_t* dims, int num_dims, void* data, size_t len,+ void (*deallocator)(void* data, size_t len, void* arg),+ void* deallocator_arg);++// Allocate and return a new Tensor.+//+// This function is an alternative to TF_NewTensor and should be used when+// memory is allocated to pass the Tensor to the C API. The allocated memory+// satisfies TensorFlow's memory alignment preferences and should be preferred+// over calling malloc and free.+//+// The caller must set the Tensor values by writing them to the pointer returned+// by TF_TensorData with length TF_TensorByteSize.+TF_CAPI_EXPORT extern TF_Tensor* TF_AllocateTensor(TF_DataType,+ const int64_t* dims,+ int num_dims, size_t len);++// Deletes `tensor` and returns a new TF_Tensor with the same content if+// possible. Returns nullptr and leaves `tensor` untouched if not.+TF_CAPI_EXPORT extern TF_Tensor* TF_TensorMaybeMove(TF_Tensor* tensor);++// Destroy a tensor.+TF_CAPI_EXPORT extern void TF_DeleteTensor(TF_Tensor*);++// Return the type of a tensor element.+TF_CAPI_EXPORT extern TF_DataType TF_TensorType(const TF_Tensor*);++// Return the number of dimensions that the tensor has.+TF_CAPI_EXPORT extern int TF_NumDims(const TF_Tensor*);++// Return the length of the tensor in the "dim_index" dimension.+// REQUIRES: 0 <= dim_index < TF_NumDims(tensor)+TF_CAPI_EXPORT extern int64_t TF_Dim(const TF_Tensor* tensor, int dim_index);++// Return the size of the underlying data in bytes.+TF_CAPI_EXPORT extern size_t TF_TensorByteSize(const TF_Tensor*);++// Return a pointer to the underlying data buffer.+TF_CAPI_EXPORT extern void* TF_TensorData(const TF_Tensor*);++// --------------------------------------------------------------------------+// Encode the string `src` (`src_len` bytes long) into `dst` in the format+// required by TF_STRING tensors. Does not write to memory more than `dst_len`+// bytes beyond `*dst`. `dst_len` should be at least+// TF_StringEncodedSize(src_len).+//+// On success returns the size in bytes of the encoded string.+// Returns an error into `status` otherwise.+TF_CAPI_EXPORT extern size_t TF_StringEncode(const char* src, size_t src_len,+ char* dst, size_t dst_len,+ TF_Status* status);++// Decode a string encoded using TF_StringEncode.+//+// On success, sets `*dst` to the start of the decoded string and `*dst_len` to+// its length. Returns the number of bytes starting at `src` consumed while+// decoding. `*dst` points to memory within the encoded buffer. On failure,+// `*dst` and `*dst_len` are undefined and an error is set in `status`.+//+// Does not read memory more than `src_len` bytes beyond `src`.+TF_CAPI_EXPORT extern size_t TF_StringDecode(const char* src, size_t src_len,+ const char** dst, size_t* dst_len,+ TF_Status* status);++// Return the size in bytes required to encode a string `len` bytes long into a+// TF_STRING tensor.+TF_CAPI_EXPORT extern size_t TF_StringEncodedSize(size_t len);++// --------------------------------------------------------------------------+// TF_SessionOptions holds options that can be passed during session creation.+typedef struct TF_SessionOptions TF_SessionOptions;++// Return a new options object.+TF_CAPI_EXPORT extern TF_SessionOptions* TF_NewSessionOptions();++// Set the target in TF_SessionOptions.options.+// target can be empty, a single entry, or a comma separated list of entries.+// Each entry is in one of the following formats :+// "local"+// ip:port+// host:port+TF_CAPI_EXPORT extern void TF_SetTarget(TF_SessionOptions* options,+ const char* target);++// Set the config in TF_SessionOptions.options.+// config should be a serialized tensorflow.ConfigProto proto.+// If config was not parsed successfully as a ConfigProto, record the+// error information in *status.+TF_CAPI_EXPORT extern void TF_SetConfig(TF_SessionOptions* options,+ const void* proto, size_t proto_len,+ TF_Status* status);++// Destroy an options object.+TF_CAPI_EXPORT extern void TF_DeleteSessionOptions(TF_SessionOptions*);++// TODO(jeff,sanjay):+// - export functions to set Config fields++// --------------------------------------------------------------------------+// The new graph construction API, still under development.++// Represents a computation graph. Graphs may be shared between sessions.+// Graphs are thread-safe when used as directed below.+typedef struct TF_Graph TF_Graph;++// Return a new graph object.+TF_CAPI_EXPORT extern TF_Graph* TF_NewGraph();++// Destroy an options object. Graph will be deleted once no more+// TFSession's are referencing it.+TF_CAPI_EXPORT extern void TF_DeleteGraph(TF_Graph*);++// Operation being built. The underlying graph must outlive this.+typedef struct TF_OperationDescription TF_OperationDescription;++// Operation that has been added to the graph. Valid until the graph is+// deleted -- in particular adding a new operation to the graph does not+// invalidate old TF_Operation* pointers.+typedef struct TF_Operation TF_Operation;++// Represents a specific input of an operation.+typedef struct TF_Input {+ TF_Operation* oper;+ int index; // The index of the input within oper.+} TF_Input;++// Represents a specific output of an operation.+typedef struct TF_Output {+ TF_Operation* oper;+ int index; // The index of the output within oper.+} TF_Output;++// TF_Function is a grouping of operations with defined inputs and outputs.+// Once created and added to graphs, functions can be invoked by creating an+// operation whose operation type matches the function name.+typedef struct TF_Function TF_Function;++// Function definition options. TODO(iga): Define and implement+typedef struct TF_FunctionOptions TF_FunctionOptions;++// Sets the shape of the Tensor referenced by `output` in `graph` to+// the shape described by `dims` and `num_dims`.+//+// If the number of dimensions is unknown, `num_dims` must be set to+// -1 and `dims` can be null. If a dimension is unknown, the+// corresponding entry in the `dims` array must be -1.+//+// This does not overwrite the existing shape associated with `output`,+// but merges the input shape with the existing shape. For example,+// setting a shape of [-1, 2] with an existing shape [2, -1] would set+// a final shape of [2, 2] based on shape merging semantics.+//+// Returns an error into `status` if:+// * `output` is not in `graph`.+// * An invalid shape is being set (e.g., the shape being set+// is incompatible with the existing shape).+TF_CAPI_EXPORT extern void TF_GraphSetTensorShape(TF_Graph* graph,+ TF_Output output,+ const int64_t* dims,+ const int num_dims,+ TF_Status* status);++// Returns the number of dimensions of the Tensor referenced by `output`+// in `graph`.+//+// If the number of dimensions in the shape is unknown, returns -1.+//+// Returns an error into `status` if:+// * `output` is not in `graph`.+TF_CAPI_EXPORT extern int TF_GraphGetTensorNumDims(TF_Graph* graph,+ TF_Output output,+ TF_Status* status);++// Returns the shape of the Tensor referenced by `output` in `graph`+// into `dims`. `dims` must be an array large enough to hold `num_dims`+// entries (e.g., the return value of TF_GraphGetTensorNumDims).+//+// If the number of dimensions in the shape is unknown or the shape is+// a scalar, `dims` will remain untouched. Otherwise, each element of+// `dims` will be set corresponding to the size of the dimension. An+// unknown dimension is represented by `-1`.+//+// Returns an error into `status` if:+// * `output` is not in `graph`.+// * `num_dims` does not match the actual number of dimensions.+TF_CAPI_EXPORT extern void TF_GraphGetTensorShape(TF_Graph* graph,+ TF_Output output,+ int64_t* dims, int num_dims,+ TF_Status* status);++// Operation will only be added to *graph when TF_FinishOperation() is+// called (assuming TF_FinishOperation() does not return an error).+// *graph must not be deleted until after TF_FinishOperation() is+// called.+TF_CAPI_EXPORT extern TF_OperationDescription* TF_NewOperation(+ TF_Graph* graph, const char* op_type, const char* oper_name);++// Specify the device for `desc`. Defaults to empty, meaning unconstrained.+TF_CAPI_EXPORT extern void TF_SetDevice(TF_OperationDescription* desc,+ const char* device);++// The calls to TF_AddInput and TF_AddInputList must match (in number,+// order, and type) the op declaration. For example, the "Concat" op+// has registration:+// REGISTER_OP("Concat")+// .Input("concat_dim: int32")+// .Input("values: N * T")+// .Output("output: T")+// .Attr("N: int >= 2")+// .Attr("T: type");+// that defines two inputs, "concat_dim" and "values" (in that order).+// You must use TF_AddInput() for the first input (since it takes a+// single tensor), and TF_AddInputList() for the second input (since+// it takes a list, even if you were to pass a list with a single+// tensor), as in:+// TF_OperationDescription* desc = TF_NewOperation(graph, "Concat", "c");+// TF_Output concat_dim_input = {...};+// TF_AddInput(desc, concat_dim_input);+// TF_Output values_inputs[5] = {{...}, ..., {...}};+// TF_AddInputList(desc, values_inputs, 5);++// For inputs that take a single tensor.+TF_CAPI_EXPORT extern void TF_AddInput(TF_OperationDescription* desc,+ TF_Output input);++// For inputs that take a list of tensors.+// inputs must point to TF_Output[num_inputs].+TF_CAPI_EXPORT extern void TF_AddInputList(TF_OperationDescription* desc,+ const TF_Output* inputs,+ int num_inputs);++// Call once per control input to `desc`.+TF_CAPI_EXPORT extern void TF_AddControlInput(TF_OperationDescription* desc,+ TF_Operation* input);++// Request that `desc` be co-located on the device where `op`+// is placed.+//+// Use of this is discouraged since the implementation of device placement is+// subject to change. Primarily intended for internal libraries+TF_CAPI_EXPORT extern void TF_ColocateWith(TF_OperationDescription* desc,+ TF_Operation* op);++// Call some TF_SetAttr*() function for every attr that is not+// inferred from an input and doesn't have a default value you wish to+// keep.++// `value` must point to a string of length `length` bytes.+TF_CAPI_EXPORT extern void TF_SetAttrString(TF_OperationDescription* desc,+ const char* attr_name,+ const void* value, size_t length);+// `values` and `lengths` each must have lengths `num_values`.+// `values[i]` must point to a string of length `lengths[i]` bytes.+TF_CAPI_EXPORT extern void TF_SetAttrStringList(TF_OperationDescription* desc,+ const char* attr_name,+ const void* const* values,+ const size_t* lengths,+ int num_values);+TF_CAPI_EXPORT extern void TF_SetAttrInt(TF_OperationDescription* desc,+ const char* attr_name, int64_t value);+TF_CAPI_EXPORT extern void TF_SetAttrIntList(TF_OperationDescription* desc,+ const char* attr_name,+ const int64_t* values,+ int num_values);+TF_CAPI_EXPORT extern void TF_SetAttrFloat(TF_OperationDescription* desc,+ const char* attr_name, float value);+TF_CAPI_EXPORT extern void TF_SetAttrFloatList(TF_OperationDescription* desc,+ const char* attr_name,+ const float* values,+ int num_values);+TF_CAPI_EXPORT extern void TF_SetAttrBool(TF_OperationDescription* desc,+ const char* attr_name,+ unsigned char value);+TF_CAPI_EXPORT extern void TF_SetAttrBoolList(TF_OperationDescription* desc,+ const char* attr_name,+ const unsigned char* values,+ int num_values);+TF_CAPI_EXPORT extern void TF_SetAttrType(TF_OperationDescription* desc,+ const char* attr_name,+ TF_DataType value);+TF_CAPI_EXPORT extern void TF_SetAttrTypeList(TF_OperationDescription* desc,+ const char* attr_name,+ const TF_DataType* values,+ int num_values);+// Set a 'func' attribute to the specified name.+// `value` must point to a string of length `length` bytes.+TF_CAPI_EXPORT extern void TF_SetAttrFuncName(TF_OperationDescription* desc,+ const char* attr_name,+ const char* value, size_t length);++// Set `num_dims` to -1 to represent "unknown rank". Otherwise,+// `dims` points to an array of length `num_dims`. `dims[i]` must be+// >= -1, with -1 meaning "unknown dimension".+TF_CAPI_EXPORT extern void TF_SetAttrShape(TF_OperationDescription* desc,+ const char* attr_name,+ const int64_t* dims, int num_dims);+// `dims` and `num_dims` must point to arrays of length `num_shapes`.+// Set `num_dims[i]` to -1 to represent "unknown rank". Otherwise,+// `dims[i]` points to an array of length `num_dims[i]`. `dims[i][j]`+// must be >= -1, with -1 meaning "unknown dimension".+TF_CAPI_EXPORT extern void TF_SetAttrShapeList(TF_OperationDescription* desc,+ const char* attr_name,+ const int64_t* const* dims,+ const int* num_dims,+ int num_shapes);+// `proto` must point to an array of `proto_len` bytes representing a+// binary-serialized TensorShapeProto.+TF_CAPI_EXPORT extern void TF_SetAttrTensorShapeProto(+ TF_OperationDescription* desc, const char* attr_name, const void* proto,+ size_t proto_len, TF_Status* status);+// `protos` and `proto_lens` must point to arrays of length `num_shapes`.+// `protos[i]` must point to an array of `proto_lens[i]` bytes+// representing a binary-serialized TensorShapeProto.+TF_CAPI_EXPORT extern void TF_SetAttrTensorShapeProtoList(+ TF_OperationDescription* desc, const char* attr_name,+ const void* const* protos, const size_t* proto_lens, int num_shapes,+ TF_Status* status);++TF_CAPI_EXPORT extern void TF_SetAttrTensor(TF_OperationDescription* desc,+ const char* attr_name,+ TF_Tensor* value,+ TF_Status* status);+TF_CAPI_EXPORT extern void TF_SetAttrTensorList(TF_OperationDescription* desc,+ const char* attr_name,+ TF_Tensor* const* values,+ int num_values,+ TF_Status* status);++// `proto` should point to a sequence of bytes of length `proto_len`+// representing a binary serialization of an AttrValue protocol+// buffer.+TF_CAPI_EXPORT extern void TF_SetAttrValueProto(TF_OperationDescription* desc,+ const char* attr_name,+ const void* proto,+ size_t proto_len,+ TF_Status* status);++// If this function succeeds:+// * *status is set to an OK value,+// * a TF_Operation is added to the graph,+// * a non-null value pointing to the added operation is returned --+// this value is valid until the underlying graph is deleted.+// Otherwise:+// * *status is set to a non-OK value,+// * the graph is not modified,+// * a null value is returned.+// In either case, it deletes `desc`.+TF_CAPI_EXPORT extern TF_Operation* TF_FinishOperation(+ TF_OperationDescription* desc, TF_Status* status);++// TF_Operation functions. Operations are immutable once created, so+// these are all query functions.++TF_CAPI_EXPORT extern const char* TF_OperationName(TF_Operation* oper);+TF_CAPI_EXPORT extern const char* TF_OperationOpType(TF_Operation* oper);+TF_CAPI_EXPORT extern const char* TF_OperationDevice(TF_Operation* oper);++TF_CAPI_EXPORT extern int TF_OperationNumOutputs(TF_Operation* oper);+TF_CAPI_EXPORT extern TF_DataType TF_OperationOutputType(TF_Output oper_out);+TF_CAPI_EXPORT extern int TF_OperationOutputListLength(TF_Operation* oper,+ const char* arg_name,+ TF_Status* status);++TF_CAPI_EXPORT extern int TF_OperationNumInputs(TF_Operation* oper);+TF_CAPI_EXPORT extern TF_DataType TF_OperationInputType(TF_Input oper_in);+TF_CAPI_EXPORT extern int TF_OperationInputListLength(TF_Operation* oper,+ const char* arg_name,+ TF_Status* status);++// In this code:+// TF_Output producer = TF_OperationInput(consumer);+// There is an edge from producer.oper's output (given by+// producer.index) to consumer.oper's input (given by consumer.index).+TF_CAPI_EXPORT extern TF_Output TF_OperationInput(TF_Input oper_in);++// Get the number of current consumers of a specific output of an+// operation. Note that this number can change when new operations+// are added to the graph.+TF_CAPI_EXPORT extern int TF_OperationOutputNumConsumers(TF_Output oper_out);++// Get list of all current consumers of a specific output of an+// operation. `consumers` must point to an array of length at least+// `max_consumers` (ideally set to+// TF_OperationOutputNumConsumers(oper_out)). Beware that a concurrent+// modification of the graph can increase the number of consumers of+// an operation. Returns the number of output consumers (should match+// TF_OperationOutputNumConsumers(oper_out)).+TF_CAPI_EXPORT extern int TF_OperationOutputConsumers(TF_Output oper_out,+ TF_Input* consumers,+ int max_consumers);++// Get the number of control inputs to an operation.+TF_CAPI_EXPORT extern int TF_OperationNumControlInputs(TF_Operation* oper);++// Get list of all control inputs to an operation. `control_inputs` must+// point to an array of length `max_control_inputs` (ideally set to+// TF_OperationNumControlInputs(oper)). Returns the number of control+// inputs (should match TF_OperationNumControlInputs(oper)).+TF_CAPI_EXPORT extern int TF_OperationGetControlInputs(+ TF_Operation* oper, TF_Operation** control_inputs, int max_control_inputs);++// Get the number of operations that have `*oper` as a control input.+// Note that this number can change when new operations are added to+// the graph.+TF_CAPI_EXPORT extern int TF_OperationNumControlOutputs(TF_Operation* oper);++// Get the list of operations that have `*oper` as a control input.+// `control_outputs` must point to an array of length at least+// `max_control_outputs` (ideally set to+// TF_OperationNumControlOutputs(oper)). Beware that a concurrent+// modification of the graph can increase the number of control+// outputs. Returns the number of control outputs (should match+// TF_OperationNumControlOutputs(oper)).+TF_CAPI_EXPORT extern int TF_OperationGetControlOutputs(+ TF_Operation* oper, TF_Operation** control_outputs,+ int max_control_outputs);++// TF_AttrType describes the type of the value of an attribute on an operation.+typedef enum TF_AttrType {+ TF_ATTR_STRING = 0,+ TF_ATTR_INT = 1,+ TF_ATTR_FLOAT = 2,+ TF_ATTR_BOOL = 3,+ TF_ATTR_TYPE = 4,+ TF_ATTR_SHAPE = 5,+ TF_ATTR_TENSOR = 6,+ TF_ATTR_PLACEHOLDER = 7,+ TF_ATTR_FUNC = 8,+} TF_AttrType;++// TF_AttrMetadata describes the value of an attribute on an operation.+typedef struct TF_AttrMetadata {+ // A boolean: 1 if the attribute value is a list, 0 otherwise.+ unsigned char is_list;++ // Length of the list if is_list is true. Undefined otherwise.+ int64_t list_size;++ // Type of elements of the list if is_list != 0.+ // Type of the single value stored in the attribute if is_list == 0.+ TF_AttrType type;++ // Total size the attribute value.+ // The units of total_size depend on is_list and type.+ // (1) If type == TF_ATTR_STRING and is_list == 0+ // then total_size is the byte size of the string+ // valued attribute.+ // (2) If type == TF_ATTR_STRING and is_list == 1+ // then total_size is the cumulative byte size+ // of all the strings in the list.+ // (3) If type == TF_ATTR_SHAPE and is_list == 0+ // then total_size is the number of dimensions+ // of the shape valued attribute, or -1+ // if its rank is unknown.+ // (4) If type == TF_ATTR_SHAPE and is_list == 1+ // then total_size is the cumulative number+ // of dimensions of all shapes in the list.+ // (5) Otherwise, total_size is undefined.+ int64_t total_size;+} TF_AttrMetadata;++// Returns metadata about the value of the attribute `attr_name` of `oper`.+TF_CAPI_EXPORT extern TF_AttrMetadata TF_OperationGetAttrMetadata(+ TF_Operation* oper, const char* attr_name, TF_Status* status);++// Fills in `value` with the value of the attribute `attr_name`. `value` must+// point to an array of length at least `max_length` (ideally set to+// TF_AttrMetadata.total_size from TF_OperationGetAttrMetadata(oper,+// attr_name)).+TF_CAPI_EXPORT extern void TF_OperationGetAttrString(TF_Operation* oper,+ const char* attr_name,+ void* value,+ size_t max_length,+ TF_Status* status);++// Get the list of strings in the value of the attribute `attr_name`. Fills in+// `values` and `lengths`, each of which must point to an array of length at+// least `max_values`.+//+// The elements of values will point to addresses in `storage` which must be at+// least `storage_size` bytes in length. Ideally, max_values would be set to+// TF_AttrMetadata.list_size and `storage` would be at least+// TF_AttrMetadata.total_size, obtained from TF_OperationGetAttrMetadata(oper,+// attr_name).+//+// Fails if storage_size is too small to hold the requested number of strings.+TF_CAPI_EXPORT extern void TF_OperationGetAttrStringList(+ TF_Operation* oper, const char* attr_name, void** values, size_t* lengths,+ int max_values, void* storage, size_t storage_size, TF_Status* status);++TF_CAPI_EXPORT extern void TF_OperationGetAttrInt(TF_Operation* oper,+ const char* attr_name,+ int64_t* value,+ TF_Status* status);++// Fills in `values` with the value of the attribute `attr_name` of `oper`.+// `values` must point to an array of length at least `max_values` (ideally set+// TF_AttrMetadata.list_size from TF_OperationGetAttrMetadata(oper,+// attr_name)).+TF_CAPI_EXPORT extern void TF_OperationGetAttrIntList(TF_Operation* oper,+ const char* attr_name,+ int64_t* values,+ int max_values,+ TF_Status* status);++TF_CAPI_EXPORT extern void TF_OperationGetAttrFloat(TF_Operation* oper,+ const char* attr_name,+ float* value,+ TF_Status* status);++// Fills in `values` with the value of the attribute `attr_name` of `oper`.+// `values` must point to an array of length at least `max_values` (ideally set+// to TF_AttrMetadata.list_size from TF_OperationGetAttrMetadata(oper,+// attr_name)).+TF_CAPI_EXPORT extern void TF_OperationGetAttrFloatList(TF_Operation* oper,+ const char* attr_name,+ float* values,+ int max_values,+ TF_Status* status);++TF_CAPI_EXPORT extern void TF_OperationGetAttrBool(TF_Operation* oper,+ const char* attr_name,+ unsigned char* value,+ TF_Status* status);++// Fills in `values` with the value of the attribute `attr_name` of `oper`.+// `values` must point to an array of length at least `max_values` (ideally set+// to TF_AttrMetadata.list_size from TF_OperationGetAttrMetadata(oper,+// attr_name)).+TF_CAPI_EXPORT extern void TF_OperationGetAttrBoolList(TF_Operation* oper,+ const char* attr_name,+ unsigned char* values,+ int max_values,+ TF_Status* status);++TF_CAPI_EXPORT extern void TF_OperationGetAttrType(TF_Operation* oper,+ const char* attr_name,+ TF_DataType* value,+ TF_Status* status);++// Fills in `values` with the value of the attribute `attr_name` of `oper`.+// `values` must point to an array of length at least `max_values` (ideally set+// to TF_AttrMetadata.list_size from TF_OperationGetAttrMetadata(oper,+// attr_name)).+TF_CAPI_EXPORT extern void TF_OperationGetAttrTypeList(TF_Operation* oper,+ const char* attr_name,+ TF_DataType* values,+ int max_values,+ TF_Status* status);++// Fills in `value` with the value of the attribute `attr_name` of `oper`.+// `values` must point to an array of length at least `num_dims` (ideally set to+// TF_Attr_Meta.size from TF_OperationGetAttrMetadata(oper, attr_name)).+TF_CAPI_EXPORT extern void TF_OperationGetAttrShape(TF_Operation* oper,+ const char* attr_name,+ int64_t* value,+ int num_dims,+ TF_Status* status);++// Fills in `dims` with the list of shapes in the attribute `attr_name` of+// `oper` and `num_dims` with the corresponding number of dimensions. On return,+// for every i where `num_dims[i]` > 0, `dims[i]` will be an array of+// `num_dims[i]` elements. A value of -1 for `num_dims[i]` indicates that the+// i-th shape in the list is unknown.+//+// The elements of `dims` will point to addresses in `storage` which must be+// large enough to hold at least `storage_size` int64_ts. Ideally, `num_shapes`+// would be set to TF_AttrMetadata.list_size and `storage_size` would be set to+// TF_AttrMetadata.total_size from TF_OperationGetAttrMetadata(oper,+// attr_name).+//+// Fails if storage_size is insufficient to hold the requested shapes.+TF_CAPI_EXPORT extern void TF_OperationGetAttrShapeList(+ TF_Operation* oper, const char* attr_name, int64_t** dims, int* num_dims,+ int num_shapes, int64_t* storage, int storage_size, TF_Status* status);++// Sets `value` to the binary-serialized TensorShapeProto of the value of+// `attr_name` attribute of `oper`'.+TF_CAPI_EXPORT extern void TF_OperationGetAttrTensorShapeProto(+ TF_Operation* oper, const char* attr_name, TF_Buffer* value,+ TF_Status* status);++// Fills in `values` with binary-serialized TensorShapeProto values of the+// attribute `attr_name` of `oper`. `values` must point to an array of length at+// least `num_values` (ideally set to TF_AttrMetadata.list_size from+// TF_OperationGetAttrMetadata(oper, attr_name)).+TF_CAPI_EXPORT extern void TF_OperationGetAttrTensorShapeProtoList(+ TF_Operation* oper, const char* attr_name, TF_Buffer** values,+ int max_values, TF_Status* status);++// Gets the TF_Tensor valued attribute of `attr_name` of `oper`.+//+// Allocates a new TF_Tensor which the caller is expected to take+// ownership of (and can deallocate using TF_DeleteTensor).+TF_CAPI_EXPORT extern void TF_OperationGetAttrTensor(TF_Operation* oper,+ const char* attr_name,+ TF_Tensor** value,+ TF_Status* status);++// Fills in `values` with the TF_Tensor values of the attribute `attr_name` of+// `oper`. `values` must point to an array of TF_Tensor* of length at least+// `max_values` (ideally set to TF_AttrMetadata.list_size from+// TF_OperationGetAttrMetadata(oper, attr_name)).+//+// The caller takes ownership of all the non-null TF_Tensor* entries in `values`+// (which can be deleted using TF_DeleteTensor(values[i])).+TF_CAPI_EXPORT extern void TF_OperationGetAttrTensorList(TF_Operation* oper,+ const char* attr_name,+ TF_Tensor** values,+ int max_values,+ TF_Status* status);++// Sets `output_attr_value` to the binary-serialized AttrValue proto+// representation of the value of the `attr_name` attr of `oper`.+TF_CAPI_EXPORT extern void TF_OperationGetAttrValueProto(+ TF_Operation* oper, const char* attr_name, TF_Buffer* output_attr_value,+ TF_Status* status);++// Returns the operation in the graph with `oper_name`. Returns nullptr if+// no operation found.+TF_CAPI_EXPORT extern TF_Operation* TF_GraphOperationByName(+ TF_Graph* graph, const char* oper_name);++// Iterate through the operations of a graph. To use:+// size_t pos = 0;+// TF_Operation* oper;+// while ((oper = TF_GraphNextOperation(graph, &pos)) != nullptr) {+// DoSomethingWithOperation(oper);+// }+TF_CAPI_EXPORT extern TF_Operation* TF_GraphNextOperation(TF_Graph* graph,+ size_t* pos);++// Write out a serialized representation of `graph` (as a GraphDef protocol+// message) to `output_graph_def` (allocated by TF_NewBuffer()).+// `output_graph_def`'s underlying buffer will be freed when TF_DeleteBuffer()+// is called.+//+// May fail on very large graphs in the future.+TF_CAPI_EXPORT extern void TF_GraphToGraphDef(TF_Graph* graph,+ TF_Buffer* output_graph_def,+ TF_Status* status);++// Returns the serialized OpDef proto with name `op_name`, or a bad status if no+// such op exists. This can return OpDefs of functions copied into the graph.+TF_CAPI_EXPORT extern void TF_GraphGetOpDef(TF_Graph* graph,+ const char* op_name,+ TF_Buffer* output_op_def,+ TF_Status* status);++// Returns the serialized VersionDef proto for this graph.+TF_CAPI_EXPORT extern void TF_GraphVersions(TF_Graph* graph,+ TF_Buffer* output_version_def,+ TF_Status* status);++// TF_ImportGraphDefOptions holds options that can be passed to+// TF_GraphImportGraphDef.+typedef struct TF_ImportGraphDefOptions TF_ImportGraphDefOptions;++TF_CAPI_EXPORT extern TF_ImportGraphDefOptions* TF_NewImportGraphDefOptions();+TF_CAPI_EXPORT extern void TF_DeleteImportGraphDefOptions(+ TF_ImportGraphDefOptions* opts);++// Set the prefix to be prepended to the names of nodes in `graph_def` that will+// be imported into `graph`.+TF_CAPI_EXPORT extern void TF_ImportGraphDefOptionsSetPrefix(+ TF_ImportGraphDefOptions* opts, const char* prefix);++// Set whether to uniquify imported operation names. If true, imported operation+// names will be modified if their name already exists in the graph. If false,+// conflicting names will be treated as an error. Note that this option has no+// effect if a prefix is set, since the prefix will guarantee all names are+// unique. Defaults to false.+TF_CAPI_EXPORT extern void TF_ImportGraphDefOptionsSetUniquifyNames(+ TF_ImportGraphDefOptions* opts, unsigned char uniquify_names);++// If true, the specified prefix will be modified if it already exists as an+// operation name or prefix in the graph. If false, a conflicting prefix will be+// treated as an error. This option has no effect if no prefix is specified.+TF_CAPI_EXPORT extern void TF_ImportGraphDefOptionsSetUniquifyPrefix(+ TF_ImportGraphDefOptions* opts, unsigned char uniquify_prefix);++// Set any imported nodes with input `src_name:src_index` to have that input+// replaced with `dst`. `src_name` refers to a node in the graph to be imported,+// `dst` references a node already existing in the graph being imported into.+TF_CAPI_EXPORT extern void TF_ImportGraphDefOptionsAddInputMapping(+ TF_ImportGraphDefOptions* opts, const char* src_name, int src_index,+ TF_Output dst);++// Set any imported nodes with control input `src_name` to have that input+// replaced with `dst`. `src_name` refers to a node in the graph to be imported,+// `dst` references an operation already existing in the graph being imported+// into.+TF_CAPI_EXPORT extern void TF_ImportGraphDefOptionsRemapControlDependency(+ TF_ImportGraphDefOptions* opts, const char* src_name, TF_Operation* dst);++// Cause the imported graph to have a control dependency on `oper`. `oper`+// should exist in the graph being imported into.+TF_CAPI_EXPORT extern void TF_ImportGraphDefOptionsAddControlDependency(+ TF_ImportGraphDefOptions* opts, TF_Operation* oper);++// Add an output in `graph_def` to be returned via the `return_outputs` output+// parameter of TF_GraphImportGraphDef(). If the output is remapped via an input+// mapping, the corresponding existing tensor in `graph` will be returned.+TF_CAPI_EXPORT extern void TF_ImportGraphDefOptionsAddReturnOutput(+ TF_ImportGraphDefOptions* opts, const char* oper_name, int index);++// Returns the number of return outputs added via+// TF_ImportGraphDefOptionsAddReturnOutput().+TF_CAPI_EXPORT extern int TF_ImportGraphDefOptionsNumReturnOutputs(+ const TF_ImportGraphDefOptions* opts);++// Add an operation in `graph_def` to be returned via the `return_opers` output+// parameter of TF_GraphImportGraphDef().+TF_CAPI_EXPORT extern void TF_ImportGraphDefOptionsAddReturnOperation(+ TF_ImportGraphDefOptions* opts, const char* oper_name);++// Returns the number of return operations added via+// TF_ImportGraphDefOptionsAddReturnOperation().+TF_CAPI_EXPORT extern int TF_ImportGraphDefOptionsNumReturnOperations(+ const TF_ImportGraphDefOptions* opts);++// TF_ImportGraphDefResults holds results that are generated by+// TF_GraphImportGraphDefWithResults().+typedef struct TF_ImportGraphDefResults TF_ImportGraphDefResults;++// Fetches the return outputs requested via+// TF_ImportGraphDefOptionsAddReturnOutput(). The number of fetched outputs is+// returned in `num_outputs`. The array of return outputs is returned in+// `outputs`. `*outputs` is owned by and has the lifetime of `results`.+TF_CAPI_EXPORT extern void TF_ImportGraphDefResultsReturnOutputs(+ TF_ImportGraphDefResults* results, int* num_outputs, TF_Output** outputs);++// Fetches the return operations requested via+// TF_ImportGraphDefOptionsAddReturnOperation(). The number of fetched+// operations is returned in `num_opers`. The array of return operations is+// returned in `opers`. `*opers` is owned by and has the lifetime of `results`.+TF_CAPI_EXPORT extern void TF_ImportGraphDefResultsReturnOperations(+ TF_ImportGraphDefResults* results, int* num_opers, TF_Operation*** opers);++// Fetches any input mappings requested via+// TF_ImportGraphDefOptionsAddInputMapping() that didn't appear in the GraphDef+// and weren't used as input to any node in the imported graph def. The number+// of fetched mappings is returned in `num_missing_unused_input_mappings`. The+// array of each mapping's source node name is returned in `src_names`, and the+// array of each mapping's source index is returned in `src_indexes`.+//+// `*src_names`, `*src_indexes`, and the memory backing each string in+// `src_names` are owned by and have the lifetime of `results`.+TF_CAPI_EXPORT extern void TF_ImportGraphDefResultsMissingUnusedInputMappings(+ TF_ImportGraphDefResults* results, int* num_missing_unused_input_mappings,+ const char*** src_names, int** src_indexes);++// Deletes a results object returned by TF_GraphImportGraphDefWithResults().+TF_CAPI_EXPORT extern void TF_DeleteImportGraphDefResults(+ TF_ImportGraphDefResults* results);++// Import the graph serialized in `graph_def` into `graph`. Returns nullptr and+// a bad status on error. Otherwise, returns a populated+// TF_ImportGraphDefResults instance. The returned instance must be deleted via+// TF_DeleteImportGraphDefResults().+TF_CAPI_EXPORT extern TF_ImportGraphDefResults*+TF_GraphImportGraphDefWithResults(TF_Graph* graph, const TF_Buffer* graph_def,+ const TF_ImportGraphDefOptions* options,+ TF_Status* status);++// Import the graph serialized in `graph_def` into `graph`.+// Convenience function for when only return outputs are needed.+//+// `num_return_outputs` must be the number of return outputs added (i.e. the+// result of TF_ImportGraphDefOptionsNumReturnOutputs()). If+// `num_return_outputs` is non-zero, `return_outputs` must be of length+// `num_return_outputs`. Otherwise it can be null.+TF_CAPI_EXPORT extern void TF_GraphImportGraphDefWithReturnOutputs(+ TF_Graph* graph, const TF_Buffer* graph_def,+ const TF_ImportGraphDefOptions* options, TF_Output* return_outputs,+ int num_return_outputs, TF_Status* status);++// Import the graph serialized in `graph_def` into `graph`.+// Convenience function for when no results are needed.+TF_CAPI_EXPORT extern void TF_GraphImportGraphDef(+ TF_Graph* graph, const TF_Buffer* graph_def,+ const TF_ImportGraphDefOptions* options, TF_Status* status);++// Adds a copy of function `func` and optionally its gradient function `grad`+// to `g`. Once `func`/`grad` is added to `g`, it can be called by creating+// an operation using the function's name.+// Any changes to `func`/`grad` (including deleting it) done after this method+// returns, won't affect the copy of `func`/`grad` in `g`.+// If `func` or `grad` are already in `g`, TF_GraphCopyFunction has no+// effect on them, but can establish the function->gradient relationship+// between them if `func` does not already have a gradient. If `func` already+// has a gradient different from `grad`, an error is returned.+//+// `func` must not be null.+// If `grad` is null and `func` is not in `g`, `func` is added without a+// gradient.+// If `grad` is null and `func` is in `g`, TF_GraphCopyFunction is a noop.+// `grad` must have appropriate signature as described in the doc of+// GradientDef in tensorflow/core/framework/function.proto.+//+// If successful, status is set to OK and `func` and `grad` are added to `g`.+// Otherwise, status is set to the encountered error and `g` is unmodified.+TF_CAPI_EXPORT extern void TF_GraphCopyFunction(TF_Graph* g,+ const TF_Function* func,+ const TF_Function* grad,+ TF_Status* status);++// Returns the number of TF_Functions registered in `g`.+TF_CAPI_EXPORT extern int TF_GraphNumFunctions(TF_Graph* g);++// Fills in `funcs` with the TF_Function* registered in `g`.+// `funcs` must point to an array of TF_Function* of length at least+// `max_func`. In usual usage, max_func should be set to the result of+// TF_GraphNumFunctions(g). In this case, all the functions registered in+// `g` will be returned. Else, an unspecified subset.+//+// If successful, returns the number of TF_Function* successfully set in+// `funcs` and sets status to OK. The caller takes ownership of+// all the returned TF_Functions. They must be deleted with TF_DeleteFunction.+// On error, returns 0, sets status to the encountered error, and the contents+// of funcs will be undefined.+TF_CAPI_EXPORT extern int TF_GraphGetFunctions(TF_Graph* g, TF_Function** funcs,+ int max_func, TF_Status* status);++// Note: The following function may fail on very large protos in the future.++TF_CAPI_EXPORT extern void TF_OperationToNodeDef(TF_Operation* oper,+ TF_Buffer* output_node_def,+ TF_Status* status);++typedef struct TF_WhileParams {+ // The number of inputs to the while loop, i.e. the number of loop variables.+ // This is the size of cond_inputs, body_inputs, and body_outputs.+ const int ninputs;++ // The while condition graph. The inputs are the current values of the loop+ // variables. The output should be a scalar boolean.+ TF_Graph* const cond_graph;+ const TF_Output* const cond_inputs;+ TF_Output cond_output;++ // The loop body graph. The inputs are the current values of the loop+ // variables. The outputs are the updated values of the loop variables.+ TF_Graph* const body_graph;+ const TF_Output* const body_inputs;+ TF_Output* const body_outputs;++ // Unique null-terminated name for this while loop. This is used as a prefix+ // for created operations.+ const char* name;+} TF_WhileParams;++// Creates a TF_WhileParams for creating a while loop in `g`. `inputs` are+// outputs that already exist in `g` used as initial values for the loop+// variables.+//+// The returned TF_WhileParams will have all fields initialized except+// `cond_output`, `body_outputs`, and `name`. The `body_outputs` buffer will be+// allocated to size `ninputs`. The caller should build `cond_graph` and+// `body_graph` starting from the inputs, and store the final outputs in+// `cond_output` and `body_outputs`.+//+// If `status` is OK, the caller must call either TF_FinishWhile or+// TF_AbortWhile on the returned TF_WhileParams. If `status` isn't OK, the+// returned TF_WhileParams is not valid, and the caller should not call+// TF_FinishWhile() or TF_AbortWhile().+//+// Missing functionality (TODO):+// - Gradients+// - Reference-type inputs+// - Directly referencing external tensors from the cond/body graphs (this is+// possible in the Python API)+TF_CAPI_EXPORT extern TF_WhileParams TF_NewWhile(TF_Graph* g, TF_Output* inputs,+ int ninputs,+ TF_Status* status);++// Builds the while loop specified by `params` and returns the output tensors of+// the while loop in `outputs`. `outputs` should be allocated to size+// `params.ninputs`.+//+// `params` is no longer valid once this returns.+//+// Either this or TF_AbortWhile() must be called after a successful+// TF_NewWhile() call.+TF_CAPI_EXPORT extern void TF_FinishWhile(const TF_WhileParams* params,+ TF_Status* status,+ TF_Output* outputs);++// Frees `params`s resources without building a while loop. `params` is no+// longer valid after this returns. Either this or TF_FinishWhile() must be+// called after a successful TF_NewWhile() call.+TF_CAPI_EXPORT extern void TF_AbortWhile(const TF_WhileParams* params);++// Adds operations to compute the partial derivatives of sum of `y`s w.r.t `x`s,+// i.e., d(y_1 + y_2 + ...)/dx_1, d(y_1 + y_2 + ...)/dx_2...+// `dx` are used as initial gradients (which represent the symbolic partial+// derivatives of some loss function `L` w.r.t. `y`).+// `dx` must be nullptr or have size `ny`.+// If `dx` is nullptr, the implementation will use dx of `OnesLike` for all+// shapes in `y`.+// The partial derivatives are returned in `dy`. `dy` should be allocated to+// size `nx`.+//+// WARNING: This function does not yet support all the gradients that python+// supports. See+// https://www.tensorflow.org/code/tensorflow/cc/gradients/README.md+// for instructions on how to add C++ more gradients.+TF_CAPI_EXPORT void TF_AddGradients(TF_Graph* g, TF_Output* y, int ny,+ TF_Output* x, int nx, TF_Output* dx,+ TF_Status* status, TF_Output* dy);++// Create a TF_Function from a TF_Graph+//+// Params:+// fn_body - the graph whose operations (or subset of whose operations) will be+// converted to TF_Function.+// fn_name - the name of the new TF_Function. Should match the operation+// name (OpDef.name) regexp [A-Z][A-Za-z0-9_.\\-/]*.+// If `append_hash_to_fn_name` is false, `fn_name` must be distinct+// from other function and operation names (at least those+// registered in graphs where this function will be used).+// append_hash_to_fn_name - Must be 0 or 1. If set to 1, the actual name+// of the function will be `fn_name` appended with+// '_<hash_of_this_function's_definition>'.+// If set to 0, the function's name will be `fn_name`.+// num_opers - `num_opers` contains the number of elements in the `opers` array+// or a special value of -1 meaning that no array is given.+// The distinction between an empty array of operations and no+// array of operations is necessary to distinguish the case of+// creating a function with no body (e.g. identity or permutation)+// and the case of creating a function whose body contains all+// the nodes in the graph (except for the automatic skipping, see+// below).+// opers - Array of operations to become the body of the function or null.+// - If no array is given (`num_opers` = -1), all the+// operations in `fn_body` will become part of the function+// except operations referenced in `inputs`. These operations+// must have a single output (these operations are typically+// placeholders created for the sole purpose of representing+// an input. We can relax this constraint if there are+// compelling use cases).+// - If an array is given (`num_opers` >= 0), all operations+// in it will become part of the function. In particular, no+// automatic skipping of dummy input operations is performed.+// ninputs - number of elements in `inputs` array+// inputs - array of TF_Outputs that specify the inputs to the function.+// If `ninputs` is zero (the function takes no inputs), `inputs`+// can be null. The names used for function inputs are normalized+// names of the operations (usually placeholders) pointed to by+// `inputs`. These operation names should start with a letter.+// Normalization will convert all letters to lowercase and+// non-alphanumeric characters to '_' to make resulting names match+// the "[a-z][a-z0-9_]*" pattern for operation argument names.+// `inputs` cannot contain the same tensor twice.+// noutputs - number of elements in `outputs` array+// outputs - array of TF_Outputs that specify the outputs of the function.+// If `noutputs` is zero (the function returns no outputs), `outputs`+// can be null. `outputs` can contain the same tensor more than once.+// output_names - The names of the function's outputs. `output_names` array+// must either have the same length as `outputs`+// (i.e. `noutputs`) or be null. In the former case,+// the names should match the regular expression for ArgDef+// names - "[a-z][a-z0-9_]*". In the latter case,+// names for outputs will be generated automatically.+// opts - various options for the function, e.g. XLA's inlining control.+// description - optional human-readable description of this function.+// status - Set to OK on success and an appropriate error on failure.+//+// Note that when the same TF_Output is listed as both an input and an output,+// the corresponding function's output will equal to this input,+// instead of the original node's output.+//+// Callers must also satisfy the following constraints:+// - `inputs` cannot refer to TF_Outputs within a control flow context. For+// example, one cannot use the output of "switch" node as input.+// - `inputs` and `outputs` cannot have reference types. Reference types are+// not exposed through C API and are being replaced with Resources. We support+// reference types inside function's body to support legacy code. Do not+// use them in new code.+// - Every node in the function's body must have all of its inputs (including+// control inputs). In other words, for every node in the body, each input+// must be either listed in `inputs` or must come from another node in+// the body. In particular, it is an error to have a control edge going from+// a node outside of the body into a node in the body. This applies to control+// edges going from nodes referenced in `inputs` to nodes in the body when+// the former nodes are not in the body (automatically skipped or not+// included in explicitly specified body).+//+// Returns:+// On success, a newly created TF_Function instance. It must be deleted by+// calling TF_DeleteFunction.+//+// On failure, null.+TF_CAPI_EXPORT extern TF_Function* TF_GraphToFunction(+ const TF_Graph* fn_body, const char* fn_name,+ unsigned char append_hash_to_fn_name, int num_opers,+ const TF_Operation* const* opers, int ninputs, const TF_Output* inputs,+ int noutputs, const TF_Output* outputs, const char* const* output_names,+ const TF_FunctionOptions* opts, const char* description, TF_Status* status);++// Write out a serialized representation of `func` (as a FunctionDef protocol+// message) to `output_func_def` (allocated by TF_NewBuffer()).+// `output_func_def`'s underlying buffer will be freed when TF_DeleteBuffer()+// is called.+//+// May fail on very large graphs in the future.+TF_CAPI_EXPORT extern void TF_FunctionToFunctionDef(TF_Function* func,+ TF_Buffer* output_func_def,+ TF_Status* status);++// Construct and return the function whose FunctionDef representation is+// serialized in `proto`. `proto_len` must equal the number of bytes+// pointed to by `proto`.+// Returns:+// On success, a newly created TF_Function instance. It must be deleted by+// calling TF_DeleteFunction.+//+// On failure, null.+TF_CAPI_EXPORT extern TF_Function* TF_FunctionImportFunctionDef(+ const void* proto, size_t proto_len, TF_Status* status);++// Sets function attribute named `attr_name` to value stored in `proto`.+// If this attribute is already set to another value, it is overridden.+// `proto` should point to a sequence of bytes of length `proto_len`+// representing a binary serialization of an AttrValue protocol+// buffer.+TF_CAPI_EXPORT extern void TF_FunctionSetAttrValueProto(TF_Function* func,+ const char* attr_name,+ const void* proto,+ size_t proto_len,+ TF_Status* status);++// Sets `output_attr_value` to the binary-serialized AttrValue proto+// representation of the value of the `attr_name` attr of `func`.+// If `attr_name` attribute is not present, status is set to an error.+TF_CAPI_EXPORT extern void TF_FunctionGetAttrValueProto(+ TF_Function* func, const char* attr_name, TF_Buffer* output_attr_value,+ TF_Status* status);++// Frees the memory used by the `func` struct.+// TF_DeleteFunction is a noop if `func` is null.+// Deleting a function does not remove it from any graphs it was copied to.+TF_CAPI_EXPORT extern void TF_DeleteFunction(TF_Function* func);++// Attempts to evaluate `output`. This will only be possible if `output` doesn't+// depend on any graph inputs (this function is safe to call if this isn't the+// case though).+//+// If the evaluation is successful, this function returns true and `output`s+// value is returned in `result`. Otherwise returns false. An error status is+// returned if something is wrong with the graph or input. Note that this may+// return false even if no error status is set.+TF_CAPI_EXPORT extern unsigned char TF_TryEvaluateConstant(TF_Graph* graph,+ TF_Output output,+ TF_Tensor** result,+ TF_Status* status);++// TODO(josh11b): Register OpDef, available to all operations added+// to this graph.++// --------------------------------------------------------------------------+// API for driving Graph execution.++typedef struct TF_Session TF_Session;++// Return a new execution session with the associated graph, or NULL on+// error. Does not take ownership of any input parameters.+//+// *`graph` must be a valid graph (not deleted or nullptr). `graph` will be be+// kept alive for the lifetime of the returned TF_Session. New nodes can still+// be added to `graph` after this call.+TF_CAPI_EXPORT extern TF_Session* TF_NewSession(TF_Graph* graph,+ const TF_SessionOptions* opts,+ TF_Status* status);++// This function creates a new TF_Session (which is created on success) using+// `session_options`, and then initializes state (restoring tensors and other+// assets) using `run_options`.+//+// Any NULL and non-NULL value combinations for (`run_options, `meta_graph_def`)+// are valid.+//+// - `export_dir` must be set to the path of the exported SavedModel.+// - `tags` must include the set of tags used to identify one MetaGraphDef in+// the SavedModel.+// - `graph` must be a graph newly allocated with TF_NewGraph().+//+// If successful, populates `graph` with the contents of the Graph and+// `meta_graph_def` with the MetaGraphDef of the loaded model.+TF_CAPI_EXPORT extern TF_Session* TF_LoadSessionFromSavedModel(+ const TF_SessionOptions* session_options, const TF_Buffer* run_options,+ const char* export_dir, const char* const* tags, int tags_len,+ TF_Graph* graph, TF_Buffer* meta_graph_def, TF_Status* status);++// Close a session.+//+// Contacts any other processes associated with the session, if applicable.+// May not be called after TF_DeleteSession().+TF_CAPI_EXPORT extern void TF_CloseSession(TF_Session*, TF_Status* status);++// Destroy a session object.+//+// Even if error information is recorded in *status, this call discards all+// local resources associated with the session. The session may not be used+// during or after this call (and the session drops its reference to the+// corresponding graph).+TF_CAPI_EXPORT extern void TF_DeleteSession(TF_Session*, TF_Status* status);++// Run the graph associated with the session starting with the supplied inputs+// (inputs[0,ninputs-1] with corresponding values in input_values[0,ninputs-1]).+//+// Any NULL and non-NULL value combinations for (`run_options`,+// `run_metadata`) are valid.+//+// - `run_options` may be NULL, in which case it will be ignored; or+// non-NULL, in which case it must point to a `TF_Buffer` containing the+// serialized representation of a `RunOptions` protocol buffer.+// - `run_metadata` may be NULL, in which case it will be ignored; or+// non-NULL, in which case it must point to an empty, freshly allocated+// `TF_Buffer` that may be updated to contain the serialized representation+// of a `RunMetadata` protocol buffer.+//+// The caller retains ownership of `input_values` (which can be deleted using+// TF_DeleteTensor). The caller also retains ownership of `run_options` and/or+// `run_metadata` (when not NULL) and should manually call TF_DeleteBuffer on+// them.+//+// On success, the tensors corresponding to outputs[0,noutputs-1] are placed in+// output_values[]. Ownership of the elements of output_values[] is transferred+// to the caller, which must eventually call TF_DeleteTensor on them.+//+// On failure, output_values[] contains NULLs.+TF_CAPI_EXPORT extern void TF_SessionRun(+ TF_Session* session,+ // RunOptions+ const TF_Buffer* run_options,+ // Input tensors+ const TF_Output* inputs, TF_Tensor* const* input_values, int ninputs,+ // Output tensors+ const TF_Output* outputs, TF_Tensor** output_values, int noutputs,+ // Target operations+ const TF_Operation* const* target_opers, int ntargets,+ // RunMetadata+ TF_Buffer* run_metadata,+ // Output status+ TF_Status*);++// Set up the graph with the intended feeds (inputs) and fetches (outputs) for a+// sequence of partial run calls.+//+// On success, returns a handle that is used for subsequent PRun calls. The+// handle should be deleted with TF_DeletePRunHandle when it is no longer+// needed.+//+// On failure, out_status contains a tensorflow::Status with an error+// message. *handle is set to nullptr.+TF_CAPI_EXPORT extern void TF_SessionPRunSetup(+ TF_Session*,+ // Input names+ const TF_Output* inputs, int ninputs,+ // Output names+ const TF_Output* outputs, int noutputs,+ // Target operations+ const TF_Operation* const* target_opers, int ntargets,+ // Output handle+ const char** handle,+ // Output status+ TF_Status*);++// Continue to run the graph with additional feeds and fetches. The+// execution state is uniquely identified by the handle.+TF_CAPI_EXPORT extern void TF_SessionPRun(+ TF_Session*, const char* handle,+ // Input tensors+ const TF_Output* inputs, TF_Tensor* const* input_values, int ninputs,+ // Output tensors+ const TF_Output* outputs, TF_Tensor** output_values, int noutputs,+ // Target operations+ const TF_Operation* const* target_opers, int ntargets,+ // Output status+ TF_Status*);++// Deletes a handle allocated by TF_SessionPRunSetup.+// Once called, no more calls to TF_SessionPRun should be made.+TF_CAPI_EXPORT extern void TF_DeletePRunHandle(const char* handle);++// --------------------------------------------------------------------------+// The deprecated session API. Please switch to the above instead of+// TF_ExtendGraph(). This deprecated API can be removed at any time without+// notice.++typedef struct TF_DeprecatedSession TF_DeprecatedSession;++TF_CAPI_EXPORT extern TF_DeprecatedSession* TF_NewDeprecatedSession(+ const TF_SessionOptions*, TF_Status* status);+TF_CAPI_EXPORT extern void TF_CloseDeprecatedSession(TF_DeprecatedSession*,+ TF_Status* status);+TF_CAPI_EXPORT extern void TF_DeleteDeprecatedSession(TF_DeprecatedSession*,+ TF_Status* status);+TF_CAPI_EXPORT extern void TF_Reset(const TF_SessionOptions* opt,+ const char** containers, int ncontainers,+ TF_Status* status);+// Treat the bytes proto[0,proto_len-1] as a serialized GraphDef and+// add the nodes in that GraphDef to the graph for the session.+//+// Prefer use of TF_Session and TF_GraphImportGraphDef over this.+TF_CAPI_EXPORT extern void TF_ExtendGraph(TF_DeprecatedSession*,+ const void* proto, size_t proto_len,+ TF_Status*);++// See TF_SessionRun() above.+TF_CAPI_EXPORT extern void TF_Run(TF_DeprecatedSession*,+ const TF_Buffer* run_options,+ const char** input_names, TF_Tensor** inputs,+ int ninputs, const char** output_names,+ TF_Tensor** outputs, int noutputs,+ const char** target_oper_names, int ntargets,+ TF_Buffer* run_metadata, TF_Status*);++// See TF_SessionPRunSetup() above.+TF_CAPI_EXPORT extern void TF_PRunSetup(TF_DeprecatedSession*,+ const char** input_names, int ninputs,+ const char** output_names, int noutputs,+ const char** target_oper_names,+ int ntargets, const char** handle,+ TF_Status*);++// See TF_SessionPRun above.+TF_CAPI_EXPORT extern void TF_PRun(TF_DeprecatedSession*, const char* handle,+ const char** input_names, TF_Tensor** inputs,+ int ninputs, const char** output_names,+ TF_Tensor** outputs, int noutputs,+ const char** target_oper_names, int ntargets,+ TF_Status*);++typedef struct TF_DeviceList TF_DeviceList;++// Lists all devices in a TF_Session.+//+// Caller takes ownership of the returned TF_DeviceList* which must eventually+// be freed with a call to TF_DeleteDeviceList.+TF_CAPI_EXPORT extern TF_DeviceList* TF_SessionListDevices(TF_Session* session,+ TF_Status* status);++// Lists all devices in a TF_Session.+//+// Caller takes ownership of the returned TF_DeviceList* which must eventually+// be freed with a call to TF_DeleteDeviceList.+TF_CAPI_EXPORT extern TF_DeviceList* TF_DeprecatedSessionListDevices(+ TF_DeprecatedSession* session, TF_Status* status);++// Deallocates the device list.+TF_CAPI_EXPORT extern void TF_DeleteDeviceList(TF_DeviceList* list);++// Counts the number of elements in the device list.+TF_CAPI_EXPORT extern int TF_DeviceListCount(const TF_DeviceList* list);++// Retrieves the full name of the device (e.g. /job:worker/replica:0/...)+// The return value will be a pointer to a null terminated string. The caller+// must not modify or delete the string. It will be deallocated upon a call to+// TF_DeleteDeviceList.+//+// If index is out of bounds, an error code will be set in the status object,+// and a null pointer will be returned.+TF_CAPI_EXPORT extern const char* TF_DeviceListName(const TF_DeviceList* list,+ int index,+ TF_Status* status);++// Retrieves the type of the device at the given index.+//+// The caller must not modify or delete the string. It will be deallocated upon+// a call to TF_DeleteDeviceList.+//+// If index is out of bounds, an error code will be set in the status object,+// and a null pointer will be returned.+TF_CAPI_EXPORT extern const char* TF_DeviceListType(const TF_DeviceList* list,+ int index,+ TF_Status* status);++// Retrieve the amount of memory associated with a given device.+//+// If index is out of bounds, an error code will be set in the status object,+// and -1 will be returned.+TF_CAPI_EXPORT extern int64_t TF_DeviceListMemoryBytes(+ const TF_DeviceList* list, int index, TF_Status* status);++// --------------------------------------------------------------------------+// Load plugins containing custom ops and kernels++// TF_Library holds information about dynamically loaded TensorFlow plugins.+typedef struct TF_Library TF_Library;++// Load the library specified by library_filename and register the ops and+// kernels present in that library.+//+// Pass "library_filename" to a platform-specific mechanism for dynamically+// loading a library. The rules for determining the exact location of the+// library are platform-specific and are not documented here.+//+// On success, place OK in status and return the newly created library handle.+// The caller owns the library handle.+//+// On failure, place an error status in status and return NULL.+TF_CAPI_EXPORT extern TF_Library* TF_LoadLibrary(const char* library_filename,+ TF_Status* status);++// Get the OpList of OpDefs defined in the library pointed by lib_handle.+//+// Returns a TF_Buffer. The memory pointed to by the result is owned by+// lib_handle. The data in the buffer will be the serialized OpList proto for+// ops defined in the library.+TF_CAPI_EXPORT extern TF_Buffer TF_GetOpList(TF_Library* lib_handle);++// Frees the memory associated with the library handle.+// Does NOT unload the library.+TF_CAPI_EXPORT extern void TF_DeleteLibraryHandle(TF_Library* lib_handle);++// Get the OpList of all OpDefs defined in this address space.+// Returns a TF_Buffer, ownership of which is transferred to the caller+// (and can be freed using TF_DeleteBuffer).+//+// The data in the buffer will be the serialized OpList proto for ops registered+// in this address space.+TF_CAPI_EXPORT extern TF_Buffer* TF_GetAllOpList();++// TF_ApiDefMap encapsulates a collection of API definitions for an operation.+//+// This object maps the name of a TensorFlow operation to a description of the+// API to generate for it, as defined by the ApiDef protocol buffer (+// https://www.tensorflow.org/code/tensorflow/core/framework/api_def.proto)+//+// The ApiDef messages are typically used to generate convenience wrapper+// functions for TensorFlow operations in various language bindings.+typedef struct TF_ApiDefMap TF_ApiDefMap;++// Creates a new TF_ApiDefMap instance.+//+// Params:+// op_list_buffer - TF_Buffer instance containing serialized OpList+// protocol buffer. (See+// https://www.tensorflow.org/code/tensorflow/core/framework/op_def.proto+// for the OpList proto definition).+// status - Set to OK on success and an appropriate error on failure.+TF_CAPI_EXPORT extern TF_ApiDefMap* TF_NewApiDefMap(TF_Buffer* op_list_buffer,+ TF_Status* status);++// Deallocates a TF_ApiDefMap.+TF_CAPI_EXPORT extern void TF_DeleteApiDefMap(TF_ApiDefMap* apimap);++// Add ApiDefs to the map.+//+// `text` corresponds to a text representation of an ApiDefs protocol message.+// (https://www.tensorflow.org/code/tensorflow/core/framework/api_def.proto).+//+// The provided ApiDefs will be merged with existing ones in the map, with+// precedence given to the newly added version in case of conflicts with+// previous calls to TF_ApiDefMapPut.+TF_CAPI_EXPORT extern void TF_ApiDefMapPut(TF_ApiDefMap* api_def_map,+ const char* text, size_t text_len,+ TF_Status* status);++// Returns a serialized ApiDef protocol buffer for the TensorFlow operation+// named `name`.+TF_CAPI_EXPORT extern TF_Buffer* TF_ApiDefMapGet(TF_ApiDefMap* api_def_map,+ const char* name,+ size_t name_len,+ TF_Status* status); #ifdef __cplusplus } /* end extern "C" */