Skip to content

Commit bc670da

Browse files
committed
Move some files
1 parent a82b1d6 commit bc670da

File tree

4 files changed

+929
-897
lines changed

4 files changed

+929
-897
lines changed

TensorFlowSharp/Buffer.cs

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

0 commit comments

Comments
 (0)