Skip to content

Commit 92dbd3e

Browse files
committed
Some docs
1 parent 79b17b9 commit 92dbd3e

File tree

2 files changed

+183
-15
lines changed

2 files changed

+183
-15
lines changed

Examples/ExampleInceptionInference/ExampleInceptionInference.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<ItemGroup>
3030
<Reference Include="System" />
3131
<Reference Include="Mono.Options">
32-
<HintPath>..\packages\Mono.Options.4.4.0.0\lib\net4-client\Mono.Options.dll</HintPath>
32+
<HintPath>..\..\packages\Mono.Options.4.4.0.0\lib\net4-client\Mono.Options.dll</HintPath>
3333
</Reference>
3434
<Reference Include="System.IO.Compression" />
3535
<Reference Include="System.IO.Compression.FileSystem" />

TensorFlowSharp/Tensorflow.cs

Lines changed: 182 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)