Skip to content

Commit 989e61b

Browse files
committed
Bring over copy of TF# source
*NOT BUILDING*
1 parent 1d4c58f commit 989e61b

File tree

4 files changed

+5485
-7
lines changed

4 files changed

+5485
-7
lines changed
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
//
2+
// TensorFlow.cs; Bindings to the TensorFlow C API for .NET
3+
//
4+
// Authors:
5+
// Miguel de Icaza (miguel@microsoft.com)
6+
//
7+
using System;
8+
using System.Runtime.InteropServices;
9+
using System.Text;
10+
using size_t = System.UIntPtr;
11+
12+
namespace TensorFlow
13+
{
14+
/// <summary>
15+
/// This attribute can be applied to callback functions that will be invoked
16+
/// from unmanaged code to managed code.
17+
/// </summary>
18+
/// <remarks>
19+
/// <code>
20+
/// [TensorFlow.MonoPInvokeCallback (typeof (BufferReleaseFunc))]
21+
/// internal static void MyFreeFunc (IntPtr data, IntPtr length){..}
22+
/// </code>
23+
/// </remarks>
24+
public sealed class MonoPInvokeCallbackAttribute : Attribute
25+
{
26+
/// <summary>
27+
/// Use this constructor to annotate the type of the callback function that
28+
/// will be invoked from unmanaged code.
29+
/// </summary>
30+
/// <param name="t">T.</param>
31+
public MonoPInvokeCallbackAttribute (Type t) { }
32+
}
33+
34+
[StructLayout (LayoutKind.Sequential)]
35+
internal struct LLBuffer
36+
{
37+
internal IntPtr data;
38+
internal size_t length;
39+
internal IntPtr data_deallocator;
40+
}
41+
42+
/// <summary>
43+
/// Holds a block of data, suitable to pass, or retrieve from TensorFlow.
44+
/// </summary>
45+
/// <remarks>
46+
/// <para>
47+
/// Use the TFBuffer to blobs of data into TensorFlow, or to retrieve blocks
48+
/// of data out of TensorFlow.
49+
/// </para>
50+
/// <para>
51+
/// There are two constructors to wrap existing data, one to wrap blocks that are
52+
/// pointed to by an IntPtr and one that takes a byte array that we want to wrap.
53+
/// </para>
54+
/// <para>
55+
/// The empty constructor can be used to create a new TFBuffer that can be populated
56+
/// by the TensorFlow library and returned to user code.
57+
/// </para>
58+
/// <para>
59+
/// Typically, the data consists of a serialized protocol buffer, but other data
60+
/// may also be held in a buffer.
61+
/// </para>
62+
/// </remarks>
63+
// TODO: the string ctor
64+
// TODO: perhaps we should have an implicit byte [] conversion that just calls ToArray?
65+
public class TFBuffer : TFDisposable
66+
{
67+
// extern TF_Buffer * TF_NewBufferFromString (const void *proto, size_t proto_len);
68+
[DllImport (NativeBinding.TensorFlowLibrary)]
69+
static extern unsafe LLBuffer* TF_NewBufferFromString (IntPtr proto, IntPtr proto_len);
70+
71+
// extern TF_Buffer * TF_NewBuffer ();
72+
[DllImport (NativeBinding.TensorFlowLibrary)]
73+
static extern unsafe LLBuffer* TF_NewBuffer ();
74+
75+
internal TFBuffer (IntPtr handle) : base (handle) { }
76+
77+
/// <summary>
78+
/// Initializes a new instance of the <see cref="T:TensorFlow.TFBuffer"/> class.
79+
/// </summary>
80+
unsafe public TFBuffer () : base ((IntPtr)TF_NewBuffer ())
81+
{
82+
}
83+
84+
/// <summary>
85+
/// Signature of the method that is invoked to release the data.
86+
/// </summary>
87+
/// <remarks>
88+
/// Methods of this signature are invoked with the data pointer and the
89+
/// lenght pointer when then TFBuffer no longer needs to hold on to the
90+
/// data. If you are using this on platforms with static compilation
91+
/// like iOS, you need to annotate your callback with the MonoPInvokeCallbackAttribute,
92+
/// like this:
93+
///
94+
/// <code>
95+
/// [TensorFlow.MonoPInvokeCallback (typeof (BufferReleaseFunc))]
96+
/// internal static void MyFreeFunc (IntPtr data, IntPtr length){..}
97+
/// </code>
98+
/// </remarks>
99+
public delegate void BufferReleaseFunc (IntPtr data, IntPtr lenght);
100+
101+
/// <summary>
102+
/// Initializes a new instance of the <see cref="T:TensorFlow.TFBuffer"/> by wrapping the unmanaged resource pointed by the buffer.
103+
/// </summary>
104+
/// <param name="buffer">Pointer to the data that will be wrapped.</param>
105+
/// <param name="size">The size of the buffer to wrap.</param>
106+
/// <param name="release">Optional, if not null, this method will be invoked to release the block.</param>
107+
/// <remarks>
108+
/// This constructor wraps the buffer as a the data to be held by the <see cref="T:TensorFlow.TFBuffer"/>,
109+
/// if the release parameter is null, then you must ensure that the data is not released before the TFBuffer
110+
/// is no longer in use. If the value is not null, the provided method will be invoked to release
111+
/// the data when the TFBuffer is disposed, or the contents of the buffer replaced.
112+
/// </remarks>
113+
unsafe public TFBuffer (IntPtr buffer, long size, BufferReleaseFunc release) : base ((IntPtr)TF_NewBuffer ())
114+
{
115+
LLBuffer* buf = (LLBuffer*)handle;
116+
buf->data = buffer;
117+
buf->length = (size_t)size;
118+
if (release == null)
119+
buf->data_deallocator = IntPtr.Zero;
120+
else
121+
buf->data_deallocator = Marshal.GetFunctionPointerForDelegate (release);
122+
}
123+
124+
[MonoPInvokeCallback (typeof (BufferReleaseFunc))]
125+
internal static void FreeBlock (IntPtr data, IntPtr length)
126+
{
127+
Marshal.FreeHGlobal (data);
128+
}
129+
130+
static IntPtr FreeBufferFunc;
131+
static BufferReleaseFunc FreeBlockDelegate;
132+
133+
static TFBuffer ()
134+
{
135+
FreeBlockDelegate = FreeBlock;
136+
FreeBufferFunc = Marshal.GetFunctionPointerForDelegate<BufferReleaseFunc> (FreeBlockDelegate);
137+
}
138+
139+
140+
/// <summary>
141+
/// Initializes a new instance of the <see cref="T:TensorFlow.TFBuffer"/> by making a copy of the provided byte array.
142+
/// </summary>
143+
/// <param name="buffer">Buffer of data that will be wrapped.</param>
144+
/// <remarks>
145+
/// This constructor makes a copy of the data into an unmanaged buffer,
146+
/// so the byte array is not pinned.
147+
/// </remarks>
148+
public TFBuffer (byte [] buffer) : this (buffer, 0, buffer.Length) { }
149+
150+
/// <summary>
151+
/// Initializes a new instance of the <see cref="T:TensorFlow.TFBuffer"/> by making a copy of the provided byte array.
152+
/// </summary>
153+
/// <param name="buffer">Buffer of data that will be wrapped.</param>
154+
/// <param name="start">Starting offset into the buffer to wrap.</param>
155+
/// <param name="count">Number of bytes from the buffer to keep.</param>
156+
/// <remarks>
157+
/// This constructor makes a copy of the data into an unmanaged buffer,
158+
/// so the byte array is not pinned.
159+
/// </remarks>
160+
public TFBuffer (byte [] buffer, int start, int count) : this ()
161+
{
162+
if (start < 0 || start >= buffer.Length)
163+
throw new ArgumentException ("start");
164+
if (count < 0 || count > buffer.Length - start)
165+
throw new ArgumentException ("count");
166+
unsafe
167+
{
168+
LLBuffer* buf = LLBuffer;
169+
buf->data = Marshal.AllocHGlobal (count);
170+
Marshal.Copy (buffer, start, buf->data, count);
171+
buf->length = (size_t)count;
172+
buf->data_deallocator = FreeBufferFunc;
173+
}
174+
}
175+
176+
unsafe internal LLBuffer* LLBuffer => (LLBuffer*)handle;
177+
178+
// extern void TF_DeleteBuffer (TF_Buffer *);
179+
[DllImport (NativeBinding.TensorFlowLibrary)]
180+
static extern unsafe void TF_DeleteBuffer (LLBuffer* buffer);
181+
182+
internal override void NativeDispose (IntPtr handle)
183+
{
184+
unsafe { TF_DeleteBuffer ((LLBuffer*)handle); }
185+
}
186+
187+
// extern TF_Buffer TF_GetBuffer (TF_Buffer *buffer);
188+
[DllImport (NativeBinding.TensorFlowLibrary)]
189+
static extern unsafe LLBuffer TF_GetBuffer (LLBuffer* buffer);
190+
191+
/// <summary>
192+
/// Returns a byte array representing the data wrapped by this buffer.
193+
/// </summary>
194+
/// <returns>The array.</returns>
195+
public byte [] ToArray ()
196+
{
197+
if (handle == IntPtr.Zero)
198+
return null;
199+
200+
unsafe
201+
{
202+
var lb = (LLBuffer*)handle;
203+
204+
var result = new byte [(int)lb->length];
205+
Marshal.Copy (lb->data, result, 0, (int)lb->length);
206+
207+
return result;
208+
}
209+
}
210+
}
211+
}

src/Microsoft.ML.TensorFlow/Microsoft.ML.Tensorflow.csproj

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,8 @@
77
<UseMLCodeAnalyzer>false</UseMLCodeAnalyzer>
88
<UseStyleCopAnalyzer>false</UseStyleCopAnalyzer>
99
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
10-
<TFSharpPath>F:\tensorflow\TensorFlowSharp\TensorFlowSharp</TFSharpPath>
1110
</PropertyGroup>
1211

13-
<ItemGroup>
14-
<Compile Include="$(TFSharpPath)\Tensorflow.cs" Link="Tensorflow.cs" />
15-
<Compile Include="$(TFSharpPath)\Tensor.cs" Link="Tensor.cs" />
16-
<Compile Include="$(TFSharpPath)\Buffer.cs" Link="Buffer.cs" />
17-
</ItemGroup>
18-
1912
<ItemGroup>
2013
<!-- Grab TF#'s native bins temporarily -->
2114
<PackageReference Include="TensorFlowSharp" Version="1.9.0" ExcludeAssets="Compile;Runtime" />

0 commit comments

Comments
 (0)