@@ -112,6 +112,21 @@ public class TFException : Exception {
112112 public TFException ( string message ) : base ( message ) { }
113113 }
114114
115+ /// <summary>
116+ /// Used to track the result of TensorFlow operations.
117+ /// </summary>
118+ /// <remarks>
119+ /// TFStatus is used to track the status of a call to some TensorFlow
120+ /// operations. Instances of this object are passed to various
121+ /// TensorFlow operations and you can use the <see cref="P:TensorFlow.TFStatus.Ok"/>
122+ /// to quickly check if the operation succeeded, or get more detail from the
123+ /// <see cref="P:TensorFlow.TFStatus.StatusCode"/> and a human-readable text
124+ /// using the <see cref="P:TensorFlow.TFStatus.StatusMessage"/> property.
125+ ///
126+ /// The convenience <see cref="M:TensorFlow.TFStatus.Raise"/> can be used
127+ /// to raise a <see cref="P:TensorFlow.TFException"/> if the status of the
128+ /// operation did not succeed.
129+ /// </remarks>
115130 public class TFStatus : TFDisposable
116131 {
117132 // extern TF_Status * TF_NewStatus ();
@@ -120,6 +135,9 @@ public class TFStatus : TFDisposable
120135
121136 [ ThreadStatic ] public static TFStatus Default = new TFStatus ( ) ;
122137
138+ /// <summary>
139+ /// Initializes a new instance of the <see cref="T:TensorFlow.TFStatus"/> class.
140+ /// </summary>
123141 public TFStatus ( ) : base ( TF_NewStatus ( ) )
124142 {
125143 }
@@ -138,6 +156,11 @@ internal override void NativeDispose (IntPtr handle)
138156 [ DllImport ( NativeBinding . TensorFlowLibrary ) ]
139157 static extern unsafe void TF_SetStatus ( TF_Status s , TFCode code , string msg ) ;
140158
159+ /// <summary>
160+ /// Sets the status code on this TFStatus.
161+ /// </summary>
162+ /// <param name="code">Code.</param>
163+ /// <param name="msg">Message.</param>
141164 public void SetStatusCode ( TFCode code , string msg )
142165 {
143166 TF_SetStatus ( handle , code , msg ) ;
@@ -147,6 +170,10 @@ public void SetStatusCode (TFCode code, string msg)
147170 [ DllImport ( NativeBinding . TensorFlowLibrary ) ]
148171 internal static extern unsafe TFCode TF_GetCode ( TF_Status s ) ;
149172
173+ /// <summary>
174+ /// Gets the status code for the status code.
175+ /// </summary>
176+ /// <value>The status code as an enumeration.</value>
150177 public TFCode StatusCode {
151178 get {
152179 return TF_GetCode ( handle ) ;
@@ -157,16 +184,41 @@ public TFCode StatusCode {
157184 [ DllImport ( NativeBinding . TensorFlowLibrary ) ]
158185 static extern unsafe IntPtr TF_Message ( TF_Status s ) ;
159186
187+ /// <summary>
188+ /// Gets a human-readable status message.
189+ /// </summary>
190+ /// <value>The status message.</value>
160191 public string StatusMessage => TF_Message ( handle ) . GetStr ( ) ;
161192
193+ /// <summary>
194+ /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:TensorFlow.TFStatus"/>.
195+ /// </summary>
196+ /// <returns>A <see cref="T:System.String"/> that represents the current <see cref="T:TensorFlow.TFStatus"/>.</returns>
162197 public override string ToString ( )
163198 {
164199 return string . Format ( "[TFStatus: StatusCode={0}, StatusMessage={1}]" , StatusCode , StatusMessage ) ;
165200 }
166201
202+
203+ /// <summary>
204+ /// Gets a value indicating whether this <see cref="T:TensorFlow.TFStatus"/> state has been set to ok.
205+ /// </summary>
206+ /// <value><c>true</c> if ok; otherwise, <c>false</c>.</value>
167207 public bool Ok => StatusCode == TFCode . Ok ;
208+
209+ /// <summary>
210+ /// Gets a value indicating whether this <see cref="T:TensorFlow.TFStatus"/> state has been set to an error.
211+ /// </summary>
212+ /// <value><c>true</c> if error; otherwise, <c>false</c>.</value>
168213 public bool Error => StatusCode != TFCode . Ok ;
169214
215+ /// <summary>
216+ /// Convenience method that raises an exception if the current status is an error.
217+ /// </summary>
218+ /// <remarks>
219+ /// You can use this method as a convenience to raise an exception after you
220+ /// invoke an operation if the operation did not succeed.
221+ /// </remarks>
170222 public void Raise ( )
171223 {
172224 if ( TF_GetCode ( handle ) != TFCode . Ok )
@@ -211,7 +263,24 @@ internal struct LLBuffer
211263 internal IntPtr data_deallocator ;
212264 }
213265
266+ /// <summary>
267+ /// Holds a block of data.
268+ /// </summary>
269+ /// <remarks>
270+ /// Use the TFBuffer to blobs of data into TensorFlow, or to retrieve blocks
271+ /// of data out of TensorFlow.
272+ ///
273+ /// There are two constructors to wrap existing data, one to wrap blocks that are
274+ /// pointed to by an IntPtr and one that takes a byte array that we want to wrap.
275+ ///
276+ /// The empty constructor can be used to create a new TFBuffer that can be populated
277+ /// by the TensorFlow library and returned to user code.
278+ ///
279+ /// Typically, the data consists of a serialized protocol buffer, but other data
280+ /// may also be held in a buffer.
281+ /// </remarks>
214282 // TODO: the string ctor
283+ // TODO: perhaps we should have an implicit byte [] conversion that just calls ToArray?
215284 public class TFBuffer : TFDisposable
216285 {
217286 // extern TF_Buffer * TF_NewBufferFromString (const void *proto, size_t proto_len);
@@ -228,12 +297,37 @@ unsafe public TFBuffer () : base ((IntPtr)TF_NewBuffer ())
228297 {
229298 }
230299
231- unsafe public TFBuffer ( IntPtr buffer , long size ) : base ( ( IntPtr ) TF_NewBuffer ( ) )
300+ /// <summary>
301+ /// Signature of the method that is invoked to release the data.
302+ /// </summary>
303+ /// <remarks>
304+ /// Methods of this signature are invoked with the data pointer and the
305+ /// lenght pointer when then TFBuffer no longer needs to hold on to the
306+ /// data.
307+ /// </remarks>
308+ public delegate void BufferReleaseFunc ( IntPtr data , IntPtr lenght ) ;
309+
310+ /// <summary>
311+ /// Initializes a new instance of the <see cref="T:TensorFlow.TFBuffer"/> by wrapping the unmanaged resource pointed by the buffer.
312+ /// </summary>
313+ /// <param name="buffer">Pointer to the data that will be wrapped.</param>
314+ /// <param name="size">The size of the buffer to wrap.</param>
315+ /// <param name="release">Optional, if not null, this method will be invoked to release the block.</param>
316+ /// <remarks>
317+ /// This constructor wraps the buffer as a the data to be held by the <see cref="T:TensorFlow.TFBuffer"/>,
318+ /// if the release parameter is null, then you must ensure that the data is not released before the TFBuffer
319+ /// is no longer in use. If the value is not null, the provided method will be invoked to release
320+ /// the data when the TFBuffer is disposed, or the contents of the buffer replaced.
321+ /// </remarks>
322+ unsafe public TFBuffer ( IntPtr buffer , long size , BufferReleaseFunc release ) : base ( ( IntPtr ) TF_NewBuffer ( ) )
232323 {
233324 LLBuffer * buf = ( LLBuffer * ) handle ;
234325 buf ->data = buffer ;
235326 buf ->length = ( size_t ) size ;
236- buf ->data_deallocator = IntPtr . Zero ;
327+ if ( release == null )
328+ buf ->data_deallocator = IntPtr . Zero ;
329+ else
330+ buf ->data_deallocator = Marshal . GetFunctionPointerForDelegate ( release ) ;
237331 }
238332
239333 internal static void FreeBlock ( IntPtr data , IntPtr lenght )
@@ -245,13 +339,30 @@ internal static void FreeBlock (IntPtr data, IntPtr lenght)
245339
246340 static TFBuffer ( )
247341 {
248- FreeBufferFunc = Marshal . GetFunctionPointerForDelegate < Action < IntPtr , IntPtr > > ( FreeBlock ) ;
342+ FreeBufferFunc = Marshal . GetFunctionPointerForDelegate < BufferReleaseFunc > ( FreeBlock ) ;
249343 }
250344
251- // This constructor makes a copy of the data
345+
346+ /// <summary>
347+ /// Initializes a new instance of the <see cref="T:TensorFlow.TFBuffer"/> by making a copy of the provided byte array.
348+ /// </summary>
349+ /// <param name="buffer">Buffer of data that will be wrapped.</param>
350+ /// <remarks>
351+ /// This constructor makes a copy of the data into an unmanaged buffer,
352+ /// so the byte array is not pinned.
353+ /// </remarks>
252354 public TFBuffer ( byte [ ] buffer ) : this ( buffer , 0 , buffer . Length ) { }
253355
254- // This constructor makes a copy of the data
356+ /// <summary>
357+ /// Initializes a new instance of the <see cref="T:TensorFlow.TFBuffer"/> by making a copy of the provided byte array.
358+ /// </summary>
359+ /// <param name="buffer">Buffer of data that will be wrapped.</param>
360+ /// <param name="start">Starting offset into the buffer to wrap.</param>
361+ /// <param name="count">Number of bytes from the buffer to keep.</param>
362+ /// <remarks>
363+ /// This constructor makes a copy of the data into an unmanaged buffer,
364+ /// so the byte array is not pinned.
365+ /// </remarks>
255366 public TFBuffer ( byte [ ] buffer , int start , int count ) : this ( )
256367 {
257368 if ( start < 0 || start >= buffer . Length )
@@ -283,6 +394,10 @@ internal override void NativeDispose (IntPtr handle)
283394 [ DllImport ( NativeBinding . TensorFlowLibrary ) ]
284395 static extern unsafe LLBuffer TF_GetBuffer ( LLBuffer * buffer ) ;
285396
397+ /// <summary>
398+ /// Returns a byte array representing the data wrapped by this buffer.
399+ /// </summary>
400+ /// <returns>The array.</returns>
286401 public byte [ ] ToArray ( )
287402 {
288403 if ( handle == IntPtr . Zero )
@@ -300,17 +415,31 @@ public byte [] ToArray ()
300415 }
301416 }
302417
303-
304- public delegate void TFTensorDeallocator ( IntPtr data , IntPtr size , IntPtr deallocatorData ) ;
305-
418+ /// <summary>
419+ /// TFTensor holds a multi-dimensional array of elements of a single data type.
420+ /// </summary>
421+ /// <remarks>
422+ /// You can create tensors with the various constructors in this class, or using
423+ /// the implicit conversions from various data types into a TFTensor.
424+ ///
425+ /// The implicit conversions for basic types produce tensors of one dimesion with
426+ /// a single element, while the implicit conversion from an array, expects a multi-dimensional
427+ /// array that is converted into a tensor of the right dimensions.
428+ ///
429+ /// The special "String" tensor data type that you will find in TensorFlow documentation
430+ /// really represents a byte array. You can create string tensors by using the <see cref="M:TensorFlow.TFTensor.CreateString"/>
431+ /// method that takes a byte array buffer as input.
432+ /// </remarks>
306433 public class TFTensor : TFDisposable
307434 {
435+ public delegate void Deallocator ( IntPtr data , IntPtr size , IntPtr deallocatorData ) ;
436+
308437 // extern TF_Tensor * TF_NewTensor (TF_DataType, const int64_t *dims, int num_dims, void *data, size_t len, void (* deallocator)(void *, size_t, void *), void *deallocator_arg);
309438 [ DllImport ( NativeBinding . TensorFlowLibrary ) ]
310- static extern unsafe TF_Tensor TF_NewTensor ( TFDataType dataType , long [ ] dims , int num_dims , IntPtr data , size_t len , TFTensorDeallocator deallocator , IntPtr deallocator_arg ) ;
439+ static extern unsafe TF_Tensor TF_NewTensor ( TFDataType dataType , long [ ] dims , int num_dims , IntPtr data , size_t len , Deallocator deallocator , IntPtr deallocator_arg ) ;
311440
312441 [ DllImport ( NativeBinding . TensorFlowLibrary ) ]
313- static extern unsafe TF_Tensor TF_NewTensor ( TFDataType dataType , IntPtr zeroDims , int num_dims , IntPtr data , size_t len , TFTensorDeallocator deallocator , IntPtr deallocator_arg ) ;
442+ static extern unsafe TF_Tensor TF_NewTensor ( TFDataType dataType , IntPtr zeroDims , int num_dims , IntPtr data , size_t len , Deallocator deallocator , IntPtr deallocator_arg ) ;
314443
315444 internal TFTensor ( IntPtr handle ) : base ( handle ) { }
316445 internal static void FreeTensorData ( IntPtr data , IntPtr len , IntPtr closure )
@@ -516,7 +645,7 @@ unsafe public static implicit operator TFTensor (Array array)
516645
517646 // General purpose constructor, specifies data type and gets pointer to buffer
518647 // Is the default good, one where we let the user provide their own deallocator, or should we make a copy in that case?
519- public TFTensor ( TFDataType dataType , long [ ] dims , IntPtr data , size_t dataSize , TFTensorDeallocator deallocator , IntPtr deallocatorData ) : base ( IntPtr . Zero )
648+ public TFTensor ( TFDataType dataType , long [ ] dims , IntPtr data , size_t dataSize , Deallocator deallocator , IntPtr deallocatorData ) : base ( IntPtr . Zero )
520649 {
521650 if ( dims == null )
522651 throw new ArgumentNullException ( "dims" ) ;
@@ -557,12 +686,28 @@ public TFTensor (TFDataType dataType, long [] dims, int size) : base (IntPtr.Zer
557686 [ DllImport ( NativeBinding . TensorFlowLibrary ) ]
558687 static extern unsafe int TF_NumDims ( TF_Tensor tensor ) ;
559688
689+ /// <summary>
690+ /// Returns the number of dimensions in the tensor.
691+ /// </summary>
692+ /// <remarks>
693+ /// For single-dimension tensors the return is 1, 2 dimensions is 2 and so on.
694+ /// </remarks>
560695 public int NumDims => TF_NumDims ( handle ) ;
561696
562697 // extern int64_t TF_Dim (const TF_Tensor *tensor, int dim_index);
563698 [ DllImport ( NativeBinding . TensorFlowLibrary ) ]
564699 static extern unsafe long TF_Dim ( TF_Tensor tensor , int dim_index ) ;
565700
701+ /// <summary>
702+ /// Returns the number of elements on a specific dimension in the tensor.
703+ /// </summary>
704+ /// <returns>The tensor dimension.</returns>
705+ /// <param name="dimIndex">Dimension that you are querying.</param>
706+ /// <remarks>
707+ /// If you have a tensor of 3 elements by 5, represented by [3 5],
708+ /// the GetTensorDimension(0) will return 3, the GetTensorDimension(1)
709+ /// will return 5.
710+ /// </remarks>
566711 public long GetTensorDimension ( int dimIndex )
567712 {
568713 return TF_Dim ( handle , dimIndex ) ;
@@ -919,7 +1064,7 @@ public object GetValue (bool jagged = false)
9191064 }
9201065 }
9211066
922- public class TFString
1067+ internal class TFString
9231068 {
9241069 // extern size_t TF_StringEncode (const char *src, size_t src_len, char *dst, size_t dst_len, TF_Status *status);
9251070 [ DllImport ( NativeBinding . TensorFlowLibrary ) ]
@@ -979,12 +1124,20 @@ public void SetConfig (IntPtr protoData, int length, TFStatus status = null)
9791124
9801125 }
9811126
1127+ /// <summary>
1128+ /// Represents a computation graph. Graphs may be shared between sessions and are thread safe.
1129+ /// </summary>
1130+ /// <remarks>
1131+ /// </remarks>
9821132 public partial class TFGraph : TFDisposable
9831133 {
9841134 // extern TF_Graph * TF_NewGraph ();
9851135 [ DllImport ( NativeBinding . TensorFlowLibrary ) ]
9861136 static extern unsafe TF_Graph TF_NewGraph ( ) ;
9871137
1138+ /// <summary>
1139+ /// Initializes a new instance of the <see cref="T:TensorFlow.TFGraph"/> class.
1140+ /// </summary>
9881141 public TFGraph ( ) : base ( TF_NewGraph ( ) )
9891142 {
9901143 }
@@ -1160,10 +1313,10 @@ public IEnumerable<TFOperation> GetEnumerator ()
11601313 }
11611314
11621315 /// <summary>
1163- ///
1316+ /// Returns the tensor shape for the specific output pparameters as an array of longs.
11641317 /// </summary>
11651318 /// <returns>null for single dimension, .</returns>
1166- /// <param name="output">Operation .</param>
1319+ /// <param name="output">The output operation to probe .</param>
11671320 /// <param name="status">Status.</param>
11681321 public long [ ] GetShape ( TFOutput output , TFStatus status = null )
11691322 {
@@ -1183,6 +1336,18 @@ public long [] GetShape (TFOutput output, TFStatus status = null)
11831336 }
11841337 }
11851338
1339+ /// <summary>
1340+ /// Low-level TensorFlow operation builder
1341+ /// </summary>
1342+ /// <remarks>
1343+ /// This is the low-level API that is used to create operations by manually specificying all
1344+ /// the parameters of an operation (inputs, outputs, attribute descriptions) that can then
1345+ /// be attached into a graph.
1346+ ///
1347+ /// Generally, you will instead be using the methods surfaced in <see cref="T:TensorFlow.TFGraph"/>
1348+ /// that surfaces a C# high-level API that has already been bound to the built-in TensorFlow
1349+ /// nodes.
1350+ /// </remarks>
11861351 public class TFOperationDesc : TFDisposable
11871352 {
11881353 string opType , operName ;
@@ -2099,6 +2264,9 @@ public enum TFDataType : uint
20992264 Resource = 20
21002265 }
21012266
2267+ /// <summary>
2268+ /// Status code for invoking a tensorflow operation.
2269+ /// </summary>
21022270 public enum TFCode : uint
21032271 {
21042272 Ok = 0 ,
0 commit comments