You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

TensorTest.cs 7.9 kB

Performance optimization, refactoring and revamping. (#362) * Refactored DisposableObject * Added different build directory for TensorflowNET.Examples.GPU * _FetchHandler: Switched to NPTypeCode * gfile.cs, Walk(...): Handle case when directory top doesn't exist. * Tensor.Creation: Perf-opted when creating tensor from NDArray of string * Graph.cs: refactor and added docs * Tensor.Creation.cs: perf-ops * Tensor.Explicit.cs: perf-ops * Copied globals.regen from NumSharp - Added supported_numericals_TF_DataType * Tensor perf-ops and cleanup, Revamped dtypes.cs, some renames. - Cleanup and docs to all Tensor.cs files - Changed all uses of System.Convert to NumSharp.Utilities.Converts - Added all missing types in dtypes.cs - Renamed tensor.Data<T> to tensor.ToArray<T>, added obsolete message - Renamed tensor.Data() to tensor.BufferToArray(), added obsolete message - Made GraphKeys to use const string instead allocating strings at every use of GraphKeys. * Tensor: Added guards for explicit casts. * Tensor: Added explicit cast to string * Tensor.ToArray<T>(): Added support for cases when tensor is scalar. * Tensor.BufferToArray(): Fixed to use long instead of int. * TensorShape: Revamped and documented. * BaseSession: Added Session.run(ITensorOrOperation fetche, params FeedItem[] feed_dict) * Tensor: renamed _dtype to _override_dtype - Fixed all locations _dtype is used incorrectly. * Fixed unit tests * Tensor.Operations: Reverted commit * DisposableObject: sorted internal_dispose to properly handle Dispose() calls * Tensor.DisposeUnmanagedResources: Nullify _handle after delete. * TensorShape.this[...]: fixed guard check. * DisposableObject #362
6 years ago
6 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. using Microsoft.VisualStudio.TestTools.UnitTesting;
  2. using NumSharp;
  3. using System;
  4. using System.Linq;
  5. using System.Runtime.InteropServices;
  6. using System.Threading;
  7. using FluentAssertions;
  8. using Tensorflow;
  9. using static Tensorflow.Binding;
  10. namespace TensorFlowNET.UnitTest
  11. {
  12. [TestClass]
  13. public class TensorTest : CApiTest
  14. {
  15. [TestMethod]
  16. public unsafe void TensorFromFixed()
  17. {
  18. var array = new float[1000];
  19. var span = new Span<float>(array, 100, 500);
  20. fixed (float* ptr = &MemoryMarshal.GetReference(span))
  21. {
  22. using (var t = new Tensor((IntPtr) ptr, new long[] {span.Length}, tf.float32, 4 * span.Length))
  23. {
  24. Assert.IsFalse(t.IsDisposed);
  25. Assert.AreEqual(2000, (int) t.bytesize);
  26. }
  27. }
  28. fixed (float* ptr = &array[0])
  29. {
  30. using (var t = new Tensor((IntPtr) ptr, new long[] {array.Length}, tf.float32, 4 * array.Length))
  31. {
  32. Assert.IsFalse(t.IsDisposed);
  33. Assert.AreEqual(4000, (int) t.bytesize);
  34. }
  35. }
  36. }
  37. [TestMethod]
  38. public unsafe void TensorFromArray()
  39. {
  40. var array = new float[1000];
  41. using (var t = new Tensor(array, new long[] {array.Length}, tf.float32))
  42. {
  43. Assert.IsFalse(t.IsDisposed);
  44. Assert.AreEqual(1000 * sizeof(float), (int) t.bytesize);
  45. }
  46. using (var t = new Tensor(new float[] {1}, new long[] {1}, tf.float32))
  47. {
  48. Assert.IsFalse(t.IsDisposed);
  49. Assert.AreEqual(1 * sizeof(float), (int) t.bytesize);
  50. }
  51. using (var t = new Tensor(new float[] {1}, null, tf.float32))
  52. {
  53. Assert.IsFalse(t.IsDisposed);
  54. Assert.AreEqual(1 * sizeof(float), (int) t.bytesize);
  55. t.shape.Should().BeEmpty();
  56. }
  57. }
  58. [TestMethod]
  59. public void AllocateTensor()
  60. {
  61. ulong num_bytes = 6 * sizeof(float);
  62. long[] dims = {2, 3};
  63. Tensor t = c_api.TF_AllocateTensor(TF_DataType.TF_FLOAT, dims, 2, num_bytes);
  64. EXPECT_EQ(TF_DataType.TF_FLOAT, t.dtype);
  65. EXPECT_EQ(2, t.NDims);
  66. EXPECT_EQ((int) dims[0], t.shape[0]);
  67. EXPECT_EQ(num_bytes, t.bytesize);
  68. t.Dispose();
  69. }
  70. /// <summary>
  71. /// Port from c_api_test.cc
  72. /// `TEST(CAPI, MaybeMove)`
  73. /// </summary>
  74. [TestMethod]
  75. public void MaybeMove()
  76. {
  77. NDArray nd = np.array(2, 3);
  78. Tensor t = new Tensor(nd);
  79. Tensor o = t.MaybeMove();
  80. ASSERT_TRUE(o == IntPtr.Zero); // It is unsafe to move memory TF might not own.
  81. t.Dispose();
  82. }
  83. /// <summary>
  84. /// Port from c_api_test.cc
  85. /// `TEST(CAPI, Tensor)`
  86. /// </summary>
  87. [TestMethod]
  88. public void Tensor()
  89. {
  90. var nd = np.array(1f, 2f, 3f, 4f, 5f, 6f).reshape(2, 3);
  91. var tensor = new Tensor(nd);
  92. var array = tensor.ToArray<float>();
  93. EXPECT_EQ(tensor.dtype, TF_DataType.TF_FLOAT);
  94. EXPECT_EQ(tensor.rank, nd.ndim);
  95. EXPECT_EQ((int) tensor.shape[0], nd.shape[0]);
  96. EXPECT_EQ((int) tensor.shape[1], nd.shape[1]);
  97. EXPECT_EQ(tensor.bytesize, (ulong) nd.size * sizeof(float));
  98. Assert.IsTrue(Enumerable.SequenceEqual(nd.Data<float>(), new float[] {1, 2, 3, 4, 5, 6}));
  99. }
  100. /// <summary>
  101. /// Port from tensorflow\c\c_api_test.cc
  102. /// `TEST(CAPI, SetShape)`
  103. /// </summary>
  104. [TestMethod]
  105. public void SetShape()
  106. {
  107. var s = new Status();
  108. var graph = new Graph().as_default();
  109. var feed = c_test_util.Placeholder(graph, s);
  110. var feed_out_0 = new TF_Output(feed, 0);
  111. // Fetch the shape, it should be completely unknown.
  112. int num_dims = c_api.TF_GraphGetTensorNumDims(graph, feed_out_0, s);
  113. Assert.IsTrue(s.Code == TF_Code.TF_OK);
  114. EXPECT_EQ(-1, num_dims);
  115. // Set the shape to be unknown, expect no change.
  116. c_api.TF_GraphSetTensorShape(graph, feed_out_0, null, -1, s);
  117. Assert.IsTrue(s.Code == TF_Code.TF_OK);
  118. num_dims = c_api.TF_GraphGetTensorNumDims(graph, feed_out_0, s);
  119. EXPECT_EQ(-1, num_dims);
  120. // Set the shape to be 2 x Unknown
  121. long[] dims = {2, -1};
  122. c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, dims.Length, s);
  123. Assert.IsTrue(s.Code == TF_Code.TF_OK);
  124. num_dims = c_api.TF_GraphGetTensorNumDims(graph, feed_out_0, s);
  125. EXPECT_EQ(2, num_dims);
  126. // Get the dimension vector appropriately.
  127. var returned_dims = new long[dims.Length];
  128. c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s);
  129. Assert.IsTrue(s.Code == TF_Code.TF_OK);
  130. Assert.IsTrue(Enumerable.SequenceEqual(dims, returned_dims));
  131. // Set to a new valid shape: [2, 3]
  132. dims[1] = 3;
  133. c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, dims.Length, s);
  134. Assert.IsTrue(s.Code == TF_Code.TF_OK);
  135. // Fetch and see that the new value is returned.
  136. c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s);
  137. Assert.IsTrue(s.Code == TF_Code.TF_OK);
  138. Assert.IsTrue(Enumerable.SequenceEqual(dims, returned_dims));
  139. // Try to set 'unknown' with unknown rank on the shape and see that
  140. // it doesn't change.
  141. c_api.TF_GraphSetTensorShape(graph, feed_out_0, null, -1, s);
  142. Assert.IsTrue(s.Code == TF_Code.TF_OK);
  143. c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s);
  144. Assert.IsTrue(s.Code == TF_Code.TF_OK);
  145. EXPECT_EQ(2, num_dims);
  146. EXPECT_EQ(2, (int) returned_dims[0]);
  147. EXPECT_EQ(3, (int) returned_dims[1]);
  148. // Try to set 'unknown' with same rank on the shape and see that
  149. // it doesn't change.
  150. dims[0] = -1;
  151. dims[1] = -1;
  152. c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, 2, s);
  153. Assert.IsTrue(s.Code == TF_Code.TF_OK);
  154. c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, num_dims, s);
  155. Assert.IsTrue(s.Code == TF_Code.TF_OK);
  156. EXPECT_EQ(2, num_dims);
  157. EXPECT_EQ(2, (int) returned_dims[0]);
  158. EXPECT_EQ(3, (int) returned_dims[1]);
  159. // Try to fetch a shape with the wrong num_dims
  160. c_api.TF_GraphGetTensorShape(graph, feed_out_0, returned_dims, 5, s);
  161. Assert.IsTrue(s.Code == TF_Code.TF_INVALID_ARGUMENT);
  162. // Try to set an invalid shape (cannot change 2x3 to a 2x5).
  163. dims[1] = 5;
  164. c_api.TF_GraphSetTensorShape(graph, feed_out_0, dims, 2, s);
  165. Assert.IsTrue(s.Code == TF_Code.TF_INVALID_ARGUMENT);
  166. // Test for a scalar.
  167. var three = c_test_util.ScalarConst(3, graph, s);
  168. Assert.IsTrue(s.Code == TF_Code.TF_OK);
  169. var three_out_0 = new TF_Output(three, 0);
  170. num_dims = c_api.TF_GraphGetTensorNumDims(graph, three_out_0, s);
  171. Assert.IsTrue(s.Code == TF_Code.TF_OK);
  172. EXPECT_EQ(0, num_dims);
  173. c_api.TF_GraphGetTensorShape(graph, feed_out_0, null, num_dims, s);
  174. //Assert.IsTrue(s.Code == TF_Code.TF_OK);
  175. // graph.Dispose();
  176. s.Dispose();
  177. }
  178. }
  179. }