diff --git a/The Definitive Guide to Tensorflow.NET/CH_1 Tensor.md b/The Definitive Guide to Tensorflow.NET/CH_1 Tensor.md
index b499c6ec..1d09ba42 100644
--- a/The Definitive Guide to Tensorflow.NET/CH_1 Tensor.md
+++ b/The Definitive Guide to Tensorflow.NET/CH_1 Tensor.md
@@ -10,6 +10,16 @@
##### Tensor 是什么?
+Tensor holds a multi-dimensional array of elements of a single data type which is very similar with numpy's ndarray.
+
+Tensor是一个具有单一数据类型的多维数组容器,非常类似于numpy里的ndarray。如果你对numpy非常熟悉的话,那么对Tensor的理解会相当容易。
+
+
+
+##### How to create a Tensor?
+
+##### 如何创建一个Tensor?
+
@@ -26,6 +36,6 @@ var nd = np.array(1f, 2f, 3f, 4f, 5f, 6f).reshape(2, 3);
-
+
-
+
diff --git a/The Definitive Guide to Tensorflow.NET/Foreword.md b/The Definitive Guide to Tensorflow.NET/Foreword.md
new file mode 100644
index 00000000..0a5232f9
--- /dev/null
+++ b/The Definitive Guide to Tensorflow.NET/Foreword.md
@@ -0,0 +1,9 @@
+# Foreword 前言
+
+One of the most nerve-wracking periods when releasing the first version of an open source project occurs when the gitter community is created. You are all alone, eagerly hoping and wishing for the first user to come along. I still vividly remember those days.
+
+
+
+当我开始写这个项目的时候,我同时也在整理编码过程时候的想法,Tensorflow是个巨大最复杂的工程,很容易超出个人能力范围,所以想尽可能地把当时的思路记录下来,也想趁着记录整理的过程把思路理清。
+
+When I started writing this project, I was also sorting out the idea of the coding process. Tensorflow is a huge and complicated project, and it is easy to go beyond the scope of personal ability. Therefore, I want to record the thoughts at the time as much as possible. The process of recording and sorting clears the way of thinking.
\ No newline at end of file
diff --git a/The Definitive Guide to Tensorflow.NET/INTRO.md b/The Definitive Guide to Tensorflow.NET/Preface.md
similarity index 96%
rename from The Definitive Guide to Tensorflow.NET/INTRO.md
rename to The Definitive Guide to Tensorflow.NET/Preface.md
index 79be7c83..ad91bf5c 100644
--- a/The Definitive Guide to Tensorflow.NET/INTRO.md
+++ b/The Definitive Guide to Tensorflow.NET/Preface.md
@@ -1,5 +1,7 @@
+# Preface 序
+
diff --git a/The Definitive Guide to Tensorflow.NET/Table of Contents.md b/The Definitive Guide to Tensorflow.NET/Table of Contents.md
new file mode 100644
index 00000000..6551e926
--- /dev/null
+++ b/The Definitive Guide to Tensorflow.NET/Table of Contents.md
@@ -0,0 +1,18 @@
+# Table of Contents
+
+### Foreword...........................................................................................xxi
+
+### Preface..............................................................................................xxiii
+
+## Part I. Getting Started
+
+##### 1. You Know, for Machine Learning............................................................................................ 3
+
+ Installing Tensorflow.NET
+ Running Tensorflow.NET
+ Talking to Tensorflow.NET
+
+## Part II. Tensorflow.NET in Depth
+
+## Part III. Dealing with Human Language
+
diff --git a/The Definitive Guide to Tensorflow.NET/assets/column-major order.png b/The Definitive Guide to Tensorflow.NET/assets/column-major-order.png
similarity index 100%
rename from The Definitive Guide to Tensorflow.NET/assets/column-major order.png
rename to The Definitive Guide to Tensorflow.NET/assets/column-major-order.png
diff --git a/The Definitive Guide to Tensorflow.NET/assets/row-major order.png b/The Definitive Guide to Tensorflow.NET/assets/row-major-order.png
similarity index 100%
rename from The Definitive Guide to Tensorflow.NET/assets/row-major order.png
rename to The Definitive Guide to Tensorflow.NET/assets/row-major-order.png
diff --git a/src/TensorFlowNET.Core/c_api.cs b/src/TensorFlowNET.Core/c_api.cs
index c1d30a86..f89ded8a 100644
--- a/src/TensorFlowNET.Core/c_api.cs
+++ b/src/TensorFlowNET.Core/c_api.cs
@@ -28,6 +28,13 @@ namespace Tensorflow
[DllImport(TensorFlowLibName)]
public static unsafe extern void TF_DeleteSessionOptions(IntPtr opts);
+ ///
+ /// Destroy a tensor.
+ ///
+ ///
+ [DllImport(TensorFlowLibName)]
+ public static unsafe extern void TF_DeleteTensor(IntPtr tensor);
+
[DllImport(TensorFlowLibName)]
public static extern unsafe long TF_Dim(IntPtr tensor, int dim_index);
@@ -66,7 +73,7 @@ namespace Tensorflow
///
///
///
- [DllImport(TensorFlowLibName)]
+ [DllImport(TensorFlowLibName, CallingConvention = CallingConvention.StdCall)]
public static extern unsafe IntPtr TF_NewTensor(TF_DataType dataType, long[] dims, int num_dims, IntPtr data, UIntPtr len, tf.Deallocator deallocator, IntPtr deallocator_arg);
///
diff --git a/src/TensorFlowNET.Core/tf.cs b/src/TensorFlowNET.Core/tf.cs
index e661fbda..0d8449e1 100644
--- a/src/TensorFlowNET.Core/tf.cs
+++ b/src/TensorFlowNET.Core/tf.cs
@@ -52,14 +52,6 @@ namespace Tensorflow
context.default_execution_mode = Context.EAGER_MODE;
}
- public static Deallocator FreeTensorDataDelegate = FreeTensorData;
-
- [MonoPInvokeCallback(typeof(Deallocator))]
- public static void FreeTensorData(IntPtr data, IntPtr len, IntPtr closure)
- {
- Marshal.FreeHGlobal(data);
- }
-
public static string VERSION => Marshal.PtrToStringAnsi(c_api.TF_Version());
public static Graph get_default_graph()
diff --git a/test/TensorFlowNET.UnitTest/TensorTest.cs b/test/TensorFlowNET.UnitTest/TensorTest.cs
index f337b583..519b7c86 100644
--- a/test/TensorFlowNET.UnitTest/TensorTest.cs
+++ b/test/TensorFlowNET.UnitTest/TensorTest.cs
@@ -13,20 +13,28 @@ namespace TensorFlowNET.UnitTest
public class TensorTest
{
[TestMethod]
- public void TF_NewTensor()
+ public unsafe void TF_NewTensor()
{
var nd = np.array(1f, 2f, 3f, 4f, 5f, 6f).reshape(2, 3);
var data = Marshal.AllocHGlobal(sizeof(float) * nd.size);
Marshal.Copy(nd.Data(), 0, data, nd.size);
+ var deallocator_called = Marshal.AllocHGlobal(sizeof(bool));
+ Assert.AreEqual(*(bool*)deallocator_called, false);
+
var handle = c_api.TF_NewTensor(TF_DataType.TF_FLOAT,
nd.shape.Select(x => (long)x).ToArray(), // shape
nd.ndim,
data,
(UIntPtr)(nd.size * sizeof(float)),
- tf.FreeTensorData,
- IntPtr.Zero);
+ (IntPtr values, IntPtr len, IntPtr closure) =>
+ {
+ // Free the original buffer and set flag
+ Marshal.FreeHGlobal(data);
+ *(bool*)closure = true;
+ },
+ deallocator_called);
Assert.AreNotEqual(handle, IntPtr.Zero);
@@ -37,6 +45,7 @@ namespace TensorFlowNET.UnitTest
Assert.AreEqual(nd.shape[0], c_api.TF_Dim(handle, 0));
Assert.AreEqual(nd.shape[1], c_api.TF_Dim(handle, 1));
Assert.AreEqual(tensor.bytesize, (uint)nd.size * sizeof(float));
+ Assert.AreEqual(*(bool*)deallocator_called, true);
// Column major order
// https://en.wikipedia.org/wiki/File:Row_and_column_major_order.svg
@@ -45,6 +54,9 @@ namespace TensorFlowNET.UnitTest
// result: 1 4 2 5 3 6
var array = tensor.Data();
Assert.IsTrue(Enumerable.SequenceEqual(nd.Data(), array));
+
+ c_api.TF_DeleteTensor(handle);
+ Assert.AreEqual(*(bool *)deallocator_called, true);
}
}
}