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.

OperationsTest.cs 65 kB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518
  1. using Microsoft.VisualStudio.TestTools.UnitTesting;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using NumSharp;
  6. using Tensorflow;
  7. using Tensorflow.Util;
  8. using Buffer = Tensorflow.Buffer;
  9. using static Tensorflow.Binding;
  10. using Tensorflow.UnitTest;
  11. namespace TensorFlowNET.UnitTest.Basics
  12. {
  13. [TestClass]
  14. public class OperationsTest : GraphModeTestBase
  15. {
  16. /// <summary>
  17. /// Port from tensorflow\c\c_api_test.cc
  18. /// `TEST(CAPI, GetAllOpList)`
  19. /// </summary>
  20. [TestMethod]
  21. public void GetAllOpList()
  22. {
  23. var handle = c_api.TF_GetAllOpList();
  24. using var buffer = new Buffer(handle);
  25. var op_list = OpList.Parser.ParseFrom(buffer.DangerousMemoryBlock.Stream());
  26. var _registered_ops = new Dictionary<string, OpDef>();
  27. foreach (var op_def in op_list.Op)
  28. _registered_ops[op_def.Name] = op_def;
  29. // r1.14 added NN op
  30. var op = _registered_ops.FirstOrDefault(x => x.Key == "NearestNeighbors");
  31. Assert.IsTrue(op_list.Op.Count > 1000);
  32. }
  33. [TestMethod]
  34. public void addInPlaceholder()
  35. {
  36. var a = tf.placeholder(tf.float32);
  37. var b = tf.placeholder(tf.float32);
  38. var c = tf.add(a, b);
  39. using(var sess = tf.Session())
  40. {
  41. var o = sess.run(c,
  42. new FeedItem(a, 3.0f),
  43. new FeedItem(b, 2.0f));
  44. Assert.AreEqual((float)o, 5.0f);
  45. }
  46. }
  47. [TestMethod]
  48. public void addInConstant()
  49. {
  50. var a = tf.constant(4.0f);
  51. var b = tf.constant(5.0f);
  52. var c = tf.add(a, b);
  53. using (var sess = tf.Session())
  54. {
  55. var o = sess.run(c);
  56. Assert.AreEqual((float)o, 9.0f);
  57. }
  58. }
  59. [TestMethod]
  60. public void isFinite()
  61. {
  62. var a = tf.constant(new[] { 1, np.nan, 2, np.nan, 3, np.nan, 4, np.nan });
  63. var b = tf.cast(tf.is_finite(a), tf.float32);
  64. var check = np.array(1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);
  65. using (var sess = tf.Session())
  66. {
  67. var o = sess.run(b);
  68. Assert.IsTrue(o.array_equal(check));
  69. }
  70. }
  71. [TestMethod]
  72. public void isNan()
  73. {
  74. var a = tf.constant(new[] { 1, np.nan, 2, np.nan, 3, np.nan, 4, np.nan });
  75. var b = tf.cast(tf.is_nan(a), tf.float32);
  76. var check = np.array(0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f);
  77. using (var sess = tf.Session())
  78. {
  79. var o = sess.run(b);
  80. Assert.IsTrue(o.array_equal(check));
  81. }
  82. }
  83. [TestMethod]
  84. public void cumSumTest()
  85. {
  86. var a = tf.constant(new[] { 1, 1, 2, 3, 4, 5 });
  87. var b = tf.cumsum(a);
  88. var check = np.array(1, 2, 4, 7, 11, 16);
  89. using (var sess = tf.Session())
  90. {
  91. var o = sess.run(b);
  92. Assert.IsTrue(o.array_equal(check));
  93. }
  94. b = tf.cumsum(a, exclusive: true);
  95. check = np.array(0, 1, 2, 4, 7, 11);
  96. using (var sess = tf.Session())
  97. {
  98. var o = sess.run(b);
  99. Assert.IsTrue(o.array_equal(check));
  100. }
  101. b = tf.cumsum(a, reverse: true);
  102. check = np.array(16, 15, 14, 12, 9, 5);
  103. using (var sess = tf.Session())
  104. {
  105. var o = sess.run(b);
  106. Assert.IsTrue(o.array_equal(check));
  107. }
  108. b = tf.cumsum(a, exclusive:true, reverse: true);
  109. check = np.array(15, 14, 12, 9, 5, 0);
  110. using (var sess = tf.Session())
  111. {
  112. var o = sess.run(b);
  113. Assert.IsTrue(o.array_equal(check));
  114. }
  115. }
  116. [TestMethod]
  117. public void logicalOpsTest()
  118. {
  119. var a = tf.constant(new[] {1f, 2f, 3f, 4f, -4f, -3f, -2f, -1f});
  120. var b = tf.less(a, 0f);
  121. var c = tf.greater(a, 0f);
  122. var d = tf.cast(tf.logical_and(b, c), tf.int32);
  123. var check = np.array(new[] { 0, 0, 0, 0, 0, 0, 0, 0 });
  124. using (var sess = tf.Session())
  125. {
  126. var o = sess.run(d);
  127. Assert.IsTrue(o.array_equal(check));
  128. }
  129. d = tf.cast(tf.logical_not(b), tf.int32);
  130. check = np.array(new[] { 1, 1, 1, 1, 0, 0, 0, 0 });
  131. using (var sess = tf.Session())
  132. {
  133. var o = sess.run(d);
  134. Assert.IsTrue(o.array_equal(check));
  135. }
  136. d = tf.cast(tf.logical_or(b, c), tf.int32);
  137. check = np.array(new[] { 1, 1, 1, 1, 1, 1, 1, 1 });
  138. using (var sess = tf.Session())
  139. {
  140. var o = sess.run(d);
  141. Assert.IsTrue(o.array_equal(check));
  142. }
  143. d = tf.cast(tf.logical_xor(b, c), tf.int32);
  144. check = np.array(new[] { 1, 1, 1, 1, 1, 1, 1, 1 });
  145. using (var sess = tf.Session())
  146. {
  147. var o = sess.run(d);
  148. Assert.IsTrue(o.array_equal(check));
  149. }
  150. }
  151. [TestMethod]
  152. public void addOpTests()
  153. {
  154. const int rows = 2; // to avoid broadcasting effect
  155. const int cols = 10;
  156. #region intTest
  157. const int firstIntVal = 2;
  158. const int secondIntVal = 3;
  159. var firstIntFeed = Enumerable.Repeat(firstIntVal, rows * cols).ToArray();
  160. var secondIntFeed = Enumerable.Repeat(secondIntVal, rows * cols).ToArray();
  161. var intResult = firstIntFeed.Sum() + secondIntFeed.Sum();
  162. var a = tf.placeholder(tf.int32, shape: new TensorShape(rows, cols));
  163. var b = tf.placeholder(tf.int32, shape: new TensorShape(rows, cols));
  164. var c = tf.reduce_sum(tf.reduce_sum(tf.add(a, b), 1));
  165. using (var sess = tf.Session())
  166. {
  167. var o = sess.run(c,
  168. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))),
  169. new FeedItem(b, new NDArray(secondIntFeed, new Shape(rows, cols))));
  170. Assert.AreEqual((int)o, intResult);
  171. }
  172. // Testing `operator +(Tensor x, Tensor y)`
  173. c = tf.reduce_sum(tf.reduce_sum(a + b, 1));
  174. using (var sess = tf.Session())
  175. {
  176. var o = sess.run(c,
  177. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))),
  178. new FeedItem(b, new NDArray(secondIntFeed, new Shape(rows, cols))));
  179. Assert.AreEqual((int)o, intResult);
  180. }
  181. // Testing `operator +(Tensor x, int y)`
  182. c = tf.reduce_sum(tf.reduce_sum(a + secondIntVal, 1));
  183. using (var sess = tf.Session())
  184. {
  185. var o = sess.run(c,
  186. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))));
  187. Assert.AreEqual((int)o, intResult);
  188. }
  189. // Testing `operator +(int x, Tensor y)`
  190. c = tf.reduce_sum(tf.reduce_sum(secondIntVal + a, 1));
  191. using (var sess = tf.Session())
  192. {
  193. var o = sess.run(c,
  194. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))));
  195. Assert.AreEqual((int)o, intResult);
  196. }
  197. #endregion
  198. #region floatTest
  199. const float firstFloatVal = 2.0f;
  200. const float secondFloatVal = 3.0f;
  201. var firstFloatFeed = Enumerable.Repeat(firstFloatVal, rows * cols).ToArray();
  202. var secondFloatFeed = Enumerable.Repeat(secondFloatVal, rows * cols).ToArray();
  203. var floatResult = firstFloatFeed.Sum() + secondFloatFeed.Sum();
  204. a = tf.placeholder(tf.float32, shape: new TensorShape(rows, cols));
  205. b = tf.placeholder(tf.float32, shape: new TensorShape(rows, cols));
  206. c = tf.reduce_sum(tf.reduce_sum(tf.add(a, b), 1));
  207. using (var sess = tf.Session())
  208. {
  209. var o = sess.run(c,
  210. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))),
  211. new FeedItem(b, new NDArray(secondFloatFeed, new Shape(rows, cols))));
  212. Assert.AreEqual((float)o, floatResult);
  213. }
  214. // Testing `operator +(Tensor x, Tensor y)
  215. c = tf.reduce_sum(tf.reduce_sum(a + b, 1));
  216. using (var sess = tf.Session())
  217. {
  218. var o = sess.run(c,
  219. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))),
  220. new FeedItem(b, new NDArray(secondFloatFeed, new Shape(rows, cols))));
  221. Assert.AreEqual((float)o, floatResult);
  222. }
  223. // Testing `operator +(Tensor x, float y)
  224. c = tf.reduce_sum(tf.reduce_sum(a + secondFloatVal, 1));
  225. using (var sess = tf.Session())
  226. {
  227. var o = sess.run(c,
  228. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))));
  229. Assert.AreEqual((float)o, floatResult);
  230. }
  231. // Testing `operator +(float x, Tensor y)
  232. c = tf.reduce_sum(tf.reduce_sum(secondFloatVal + a, 1));
  233. using (var sess = tf.Session())
  234. {
  235. var o = sess.run(c,
  236. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))));
  237. Assert.AreEqual((float)o, floatResult);
  238. }
  239. #endregion
  240. #region doubleTest
  241. const double firstDoubleVal = 2.0;
  242. const double secondDoubleVal = 3.0;
  243. var firstDoubleFeed = Enumerable.Repeat(firstDoubleVal, rows * cols).ToArray();
  244. var secondDoubleFeed = Enumerable.Repeat(secondDoubleVal, rows * cols).ToArray();
  245. var doubleResult = firstDoubleFeed.Sum() + secondDoubleFeed.Sum();
  246. a = tf.placeholder(tf.float64, shape: new TensorShape(rows, cols));
  247. b = tf.placeholder(tf.float64, shape: new TensorShape(rows, cols));
  248. c = tf.reduce_sum(tf.reduce_sum(tf.add(a, b), 1));
  249. using (var sess = tf.Session())
  250. {
  251. var o = sess.run(c,
  252. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))),
  253. new FeedItem(b, new NDArray(secondDoubleFeed, new Shape(rows, cols))));
  254. Assert.AreEqual((double)o, doubleResult);
  255. }
  256. // Testing `operator +(Tensor x, Tensor y)
  257. c = tf.reduce_sum(tf.reduce_sum(a + b, 1));
  258. using (var sess = tf.Session())
  259. {
  260. var o = sess.run(c,
  261. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))),
  262. new FeedItem(b, new NDArray(secondDoubleFeed, new Shape(rows, cols))));
  263. Assert.AreEqual((double)o, doubleResult);
  264. }
  265. // Testing `operator +(Tensor x, double y)
  266. c = tf.reduce_sum(tf.reduce_sum(a + secondFloatVal, 1));
  267. using (var sess = tf.Session())
  268. {
  269. var o = sess.run(c,
  270. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))));
  271. Assert.AreEqual((double)o, doubleResult);
  272. }
  273. // Testing `operator +(double x, Tensor y)
  274. c = tf.reduce_sum(tf.reduce_sum(secondFloatVal + a, 1));
  275. using (var sess = tf.Session())
  276. {
  277. var o = sess.run(c,
  278. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))));
  279. Assert.AreEqual((double)o, doubleResult);
  280. }
  281. #endregion
  282. }
  283. [TestMethod]
  284. public void subOpTests()
  285. {
  286. const int rows = 2; // to avoid broadcasting effect
  287. const int cols = 10;
  288. #region intTest
  289. const int firstIntVal = -2;
  290. const int secondIntVal = 3;
  291. var firstIntFeed = Enumerable.Repeat(firstIntVal, rows * cols).ToArray();
  292. var secondIntFeed = Enumerable.Repeat(secondIntVal, rows * cols).ToArray();
  293. var intResult = firstIntFeed.Sum() - secondIntFeed.Sum();
  294. var intResultTwo = -firstIntFeed.Sum();
  295. var a = tf.placeholder(tf.int32, shape: new TensorShape(rows, cols));
  296. var b = tf.placeholder(tf.int32, shape: new TensorShape(rows, cols));
  297. var c = tf.reduce_sum(tf.reduce_sum(tf.sub(a, b), 1));
  298. using (var sess = tf.Session())
  299. {
  300. var o = sess.run(c,
  301. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))),
  302. new FeedItem(b, new NDArray(secondIntFeed, new Shape(rows, cols))));
  303. Assert.AreEqual((int)o, intResult);
  304. }
  305. // Testing `operator -(Tensor x, Tensor y)
  306. c = tf.reduce_sum(tf.reduce_sum(a - b, 1));
  307. using (var sess = tf.Session())
  308. {
  309. var o = sess.run(c,
  310. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))),
  311. new FeedItem(b, new NDArray(secondIntFeed, new Shape(rows, cols))));
  312. Assert.AreEqual((int)o, intResult);
  313. }
  314. // Testing `operator -(Tensor x, int y)
  315. c = tf.reduce_sum(tf.reduce_sum(a - secondIntVal, 1));
  316. using (var sess = tf.Session())
  317. {
  318. var o = sess.run(c,
  319. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))));
  320. Assert.AreEqual((int)o, intResult);
  321. }
  322. // Testing `operator -(int x, Tensor y)
  323. c = tf.reduce_sum(tf.reduce_sum(secondIntVal - a, 1));
  324. using (var sess = tf.Session())
  325. {
  326. var o = sess.run(c,
  327. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))));
  328. Assert.AreEqual((int)o, Math.Abs(intResult));
  329. }
  330. // Testing `operator -(Tensor x)
  331. c = tf.reduce_sum(tf.reduce_sum(-a, 1));
  332. using (var sess = tf.Session())
  333. {
  334. var o = sess.run(c,
  335. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))));
  336. Assert.AreEqual((int)o, intResultTwo);
  337. }
  338. #endregion
  339. #region floatTest
  340. const float firstFloatVal = -2.0f;
  341. const float secondFloatVal = 3.0f;
  342. var firstFloatFeed = Enumerable.Repeat(firstFloatVal, rows * cols).ToArray();
  343. var secondFloatFeed = Enumerable.Repeat(secondFloatVal, rows * cols).ToArray();
  344. var floatResult = firstFloatFeed.Sum() - secondFloatFeed.Sum();
  345. var floatResultTwo = -firstFloatFeed.Sum();
  346. a = tf.placeholder(tf.float32, shape: new TensorShape(rows, cols));
  347. b = tf.placeholder(tf.float32, shape: new TensorShape(rows, cols));
  348. c = tf.reduce_sum(tf.reduce_sum(tf.sub(a, b), 1));
  349. using (var sess = tf.Session())
  350. {
  351. var o = sess.run(c,
  352. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))),
  353. new FeedItem(b, new NDArray(secondFloatFeed, new Shape(rows, cols))));
  354. Assert.AreEqual((float)o, floatResult);
  355. }
  356. // Testing `operator -(Tensor x, Tensor y)
  357. c = tf.reduce_sum(tf.reduce_sum(a - b, 1));
  358. using (var sess = tf.Session())
  359. {
  360. var o = sess.run(c,
  361. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))),
  362. new FeedItem(b, new NDArray(secondFloatFeed, new Shape(rows, cols))));
  363. Assert.AreEqual((float)o, floatResult);
  364. }
  365. // Testing `operator -(Tensor x, float y)
  366. c = tf.reduce_sum(tf.reduce_sum(a - secondFloatVal, 1));
  367. using (var sess = tf.Session())
  368. {
  369. var o = sess.run(c,
  370. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))));
  371. Assert.AreEqual((float)o, floatResult);
  372. }
  373. // Testing `operator -(float x, Tensor y)
  374. c = tf.reduce_sum(tf.reduce_sum(secondFloatVal - a, 1));
  375. using (var sess = tf.Session())
  376. {
  377. var o = sess.run(c,
  378. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))));
  379. Assert.AreEqual((float)o, Math.Abs(floatResult));
  380. }
  381. // Testing `operator -(Tensor x)
  382. c = tf.reduce_sum(tf.reduce_sum(-a, 1));
  383. using (var sess = tf.Session())
  384. {
  385. var o = sess.run(c,
  386. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))));
  387. Assert.AreEqual((float)o, floatResultTwo);
  388. }
  389. #endregion
  390. #region doubleTest
  391. const double firstDoubleVal = -2.0;
  392. const double secondDoubleVal = 3.0;
  393. var firstDoubleFeed = Enumerable.Repeat(firstDoubleVal, rows * cols).ToArray();
  394. var secondDoubleFeed = Enumerable.Repeat(secondDoubleVal, rows * cols).ToArray();
  395. var doubleResult = firstDoubleFeed.Sum() - secondDoubleFeed.Sum();
  396. var doubleResultTwo = -firstDoubleFeed.Sum();
  397. a = tf.placeholder(tf.float64, shape: new TensorShape(rows, cols));
  398. b = tf.placeholder(tf.float64, shape: new TensorShape(rows, cols));
  399. c = tf.reduce_sum(tf.reduce_sum(tf.sub(a, b), 1));
  400. using (var sess = tf.Session())
  401. {
  402. var o = sess.run(c,
  403. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))),
  404. new FeedItem(b, new NDArray(secondDoubleFeed, new Shape(rows, cols))));
  405. Assert.AreEqual((double)o, doubleResult);
  406. }
  407. // Testing `operator -(Tensor x, Tensor y)
  408. c = tf.reduce_sum(tf.reduce_sum(a - b, 1));
  409. using (var sess = tf.Session())
  410. {
  411. var o = sess.run(c,
  412. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))),
  413. new FeedItem(b, new NDArray(secondDoubleFeed, new Shape(rows, cols))));
  414. Assert.AreEqual((double)o, doubleResult);
  415. }
  416. // Testing `operator -(Tensor x, double y)
  417. c = tf.reduce_sum(tf.reduce_sum(a - secondFloatVal, 1));
  418. using (var sess = tf.Session())
  419. {
  420. var o = sess.run(c,
  421. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))));
  422. Assert.AreEqual((double)o, doubleResult);
  423. }
  424. // Testing `operator -(double x, Tensor y)
  425. c = tf.reduce_sum(tf.reduce_sum(secondFloatVal - a, 1));
  426. using (var sess = tf.Session())
  427. {
  428. var o = sess.run(c,
  429. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))));
  430. Assert.AreEqual((double)o, Math.Abs(doubleResult));
  431. }
  432. // Testing `operator -(Tensor x)
  433. c = tf.reduce_sum(tf.reduce_sum(-a, 1));
  434. using (var sess = tf.Session())
  435. {
  436. var o = sess.run(c,
  437. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))));
  438. Assert.AreEqual((double)o, doubleResultTwo);
  439. }
  440. #endregion
  441. }
  442. private IEnumerable<int> MultiplyArray(IReadOnlyCollection<int> first, IReadOnlyCollection<int> second)
  443. {
  444. if(first.Count != second.Count)
  445. throw new ArgumentException("Arrays should be of equal size!");
  446. var firstEnumerator = first.GetEnumerator();
  447. var secondEnumerator = second.GetEnumerator();
  448. var result = new List<int>();
  449. while (firstEnumerator.MoveNext())
  450. {
  451. secondEnumerator.MoveNext();
  452. result.Add(firstEnumerator.Current * secondEnumerator.Current);
  453. }
  454. firstEnumerator.Dispose();
  455. secondEnumerator.Dispose();
  456. return result;
  457. }
  458. private IEnumerable<float> MultiplyArray(IReadOnlyCollection<float> first, IReadOnlyCollection<float> second)
  459. {
  460. if(first.Count != second.Count)
  461. throw new ArgumentException("Arrays should be of equal size!");
  462. var firstEnumerator = first.GetEnumerator();
  463. var secondEnumerator = second.GetEnumerator();
  464. var result = new List<float>();
  465. while (firstEnumerator.MoveNext())
  466. {
  467. secondEnumerator.MoveNext();
  468. result.Add(firstEnumerator.Current * secondEnumerator.Current);
  469. }
  470. firstEnumerator.Dispose();
  471. secondEnumerator.Dispose();
  472. return result;
  473. }
  474. private IEnumerable<double> MultiplyArray(IReadOnlyCollection<double> first, IReadOnlyCollection<double> second)
  475. {
  476. if(first.Count != second.Count)
  477. throw new ArgumentException("Arrays should be of equal size!");
  478. var firstEnumerator = first.GetEnumerator();
  479. var secondEnumerator = second.GetEnumerator();
  480. var result = new List<double>();
  481. while (firstEnumerator.MoveNext())
  482. {
  483. secondEnumerator.MoveNext();
  484. result.Add(firstEnumerator.Current * secondEnumerator.Current);
  485. }
  486. firstEnumerator.Dispose();
  487. secondEnumerator.Dispose();
  488. return result;
  489. }
  490. [TestMethod]
  491. public void mulOpTests()
  492. {
  493. const int rows = 2; // to avoid broadcasting effect
  494. const int cols = 10;
  495. #region intTest
  496. const int firstIntVal = 2;
  497. const int secondIntVal = 3;
  498. var firstIntFeed = Enumerable.Repeat(firstIntVal, rows * cols).ToArray();
  499. var secondIntFeed = Enumerable.Repeat(secondIntVal, rows * cols).ToArray();
  500. var intResult = MultiplyArray(firstIntFeed, secondIntFeed).Sum();
  501. var a = tf.placeholder(tf.int32, shape: new TensorShape(rows, cols));
  502. var b = tf.placeholder(tf.int32, shape: new TensorShape(rows, cols));
  503. var c = tf.reduce_sum(tf.reduce_sum(tf.multiply(a, b), 1));
  504. using (var sess = tf.Session())
  505. {
  506. var o = sess.run(c,
  507. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))),
  508. new FeedItem(b, new NDArray(secondIntFeed, new Shape(rows, cols))));
  509. Assert.AreEqual((int)o, intResult);
  510. }
  511. // Testing `operator *(Tensor x, Tensor y)
  512. c = tf.reduce_sum(tf.reduce_sum(a * b, 1));
  513. using (var sess = tf.Session())
  514. {
  515. var o = sess.run(c,
  516. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))),
  517. new FeedItem(b, new NDArray(secondIntFeed, new Shape(rows, cols))));
  518. Assert.AreEqual((int)o, intResult);
  519. }
  520. // Testing `operator *(Tensor x, int y)
  521. c = tf.reduce_sum(tf.reduce_sum(a * secondIntVal, 1));
  522. using (var sess = tf.Session())
  523. {
  524. var o = sess.run(c,
  525. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))));
  526. Assert.AreEqual((int)o, intResult);
  527. }
  528. // Testing `operator *(int x, Tensor y)
  529. c = tf.reduce_sum(tf.reduce_sum(firstIntVal * b, 1));
  530. using (var sess = tf.Session())
  531. {
  532. var o = sess.run(c,
  533. new FeedItem(b, new NDArray(secondIntFeed, new Shape(rows, cols))));
  534. Assert.AreEqual((int)o, intResult);
  535. }
  536. #endregion
  537. #region floatTest
  538. const float firstFloatVal = 2.0f;
  539. const float secondFloatVal = 3.0f;
  540. var firstFloatFeed = Enumerable.Repeat(firstFloatVal, rows * cols).ToArray();
  541. var secondFloatFeed = Enumerable.Repeat(secondFloatVal, rows * cols).ToArray();
  542. var floatResult = MultiplyArray(firstFloatFeed, secondFloatFeed).Sum();
  543. a = tf.placeholder(tf.float32, shape: new TensorShape(rows, cols));
  544. b = tf.placeholder(tf.float32, shape: new TensorShape(rows, cols));
  545. c = tf.reduce_sum(tf.reduce_sum(tf.multiply(a, b), 1));
  546. using (var sess = tf.Session())
  547. {
  548. var o = sess.run(c,
  549. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))),
  550. new FeedItem(b, new NDArray(secondFloatFeed, new Shape(rows, cols))));
  551. Assert.AreEqual((float)o, floatResult);
  552. }
  553. // Testing `operator *(Tensor x, Tensor y)
  554. c = tf.reduce_sum(tf.reduce_sum(a * b, 1));
  555. using (var sess = tf.Session())
  556. {
  557. var o = sess.run(c,
  558. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))),
  559. new FeedItem(b, new NDArray(secondFloatFeed, new Shape(rows, cols))));
  560. Assert.AreEqual((float)o, floatResult);
  561. }
  562. // Testing `operator *(Tensor x, float y)
  563. c = tf.reduce_sum(tf.reduce_sum(a * secondFloatVal, 1));
  564. using (var sess = tf.Session())
  565. {
  566. var o = sess.run(c,
  567. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))));
  568. Assert.AreEqual((float)o, floatResult);
  569. }
  570. // Testing `operator *(float x, Tensor y)
  571. c = tf.reduce_sum(tf.reduce_sum(firstFloatVal * b, 1));
  572. using (var sess = tf.Session())
  573. {
  574. var o = sess.run(c,
  575. new FeedItem(b, new NDArray(secondFloatFeed, new Shape(rows, cols))));
  576. Assert.AreEqual((float)o, floatResult);
  577. }
  578. #endregion
  579. #region doubleTest
  580. const double firstDoubleVal = 2.0;
  581. const double secondDoubleVal = 3.0;
  582. var firstDoubleFeed = Enumerable.Repeat(firstDoubleVal, rows * cols).ToArray();
  583. var secondDoubleFeed = Enumerable.Repeat(secondDoubleVal, rows * cols).ToArray();
  584. var doubleResult = MultiplyArray(firstDoubleFeed, secondDoubleFeed).Sum();
  585. a = tf.placeholder(tf.float64, shape: new TensorShape(rows, cols));
  586. b = tf.placeholder(tf.float64, shape: new TensorShape(rows, cols));
  587. c = tf.reduce_sum(tf.reduce_sum(tf.multiply(a, b), 1));
  588. using (var sess = tf.Session())
  589. {
  590. var o = sess.run(c,
  591. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))),
  592. new FeedItem(b, new NDArray(secondDoubleFeed, new Shape(rows, cols))));
  593. Assert.AreEqual((double)o, doubleResult);
  594. }
  595. // Testing `operator *(Tensor x, Tensor y)
  596. c = tf.reduce_sum(tf.reduce_sum(a * b, 1));
  597. using (var sess = tf.Session())
  598. {
  599. var o = sess.run(c,
  600. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))),
  601. new FeedItem(b, new NDArray(secondDoubleFeed, new Shape(rows, cols))));
  602. Assert.AreEqual((double)o, doubleResult);
  603. }
  604. // Testing `operator *(Tensor x, double y)
  605. c = tf.reduce_sum(tf.reduce_sum(a * secondFloatVal, 1));
  606. using (var sess = tf.Session())
  607. {
  608. var o = sess.run(c,
  609. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))));
  610. Assert.AreEqual((double)o, doubleResult);
  611. }
  612. // Testing `operator *(double x, Tensor y)
  613. c = tf.reduce_sum(tf.reduce_sum(firstFloatVal * b, 1));
  614. using (var sess = tf.Session())
  615. {
  616. var o = sess.run(c,
  617. new FeedItem(b, new NDArray(secondDoubleFeed, new Shape(rows, cols))));
  618. Assert.AreEqual((double)o, doubleResult);
  619. }
  620. #endregion
  621. }
  622. [Ignore]
  623. [TestMethod]
  624. public void divOpTests()
  625. {
  626. const int rows = 2; // to avoid broadcasting effect
  627. const int cols = 10;
  628. #region intTest
  629. const int firstIntVal = 6;
  630. const int secondIntVal = 3;
  631. var firstIntFeed = Enumerable.Repeat(firstIntVal, rows * cols).ToArray();
  632. var secondIntFeed = Enumerable.Repeat(secondIntVal, rows * cols).ToArray();
  633. var intResult = (int)(firstIntFeed.Sum() / (float)secondIntVal);
  634. var a = tf.placeholder(tf.int32, shape: new TensorShape(rows, cols));
  635. var b = tf.placeholder(tf.int32, shape: new TensorShape(rows, cols));
  636. var c = tf.reduce_sum(tf.reduce_sum(gen_math_ops.floor_div(a, b), 1));
  637. using (var sess = tf.Session())
  638. {
  639. var o = sess.run(c,
  640. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))),
  641. new FeedItem(b, new NDArray(secondIntFeed, new Shape(rows, cols))));
  642. Assert.AreEqual((int)o, intResult);
  643. }
  644. // Testing `operator /(Tensor x, Tensor y)
  645. c = tf.reduce_sum(tf.reduce_sum(a / b, 1));
  646. using (var sess = tf.Session())
  647. {
  648. var o = sess.run(c,
  649. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))),
  650. new FeedItem(b, new NDArray(secondIntFeed, new Shape(rows, cols))));
  651. Assert.AreEqual((int)o, intResult);
  652. }
  653. // Testing `operator /(Tensor x, int y)
  654. c = tf.reduce_sum(tf.reduce_sum(a / secondIntVal, 1));
  655. using (var sess = tf.Session())
  656. {
  657. var o = sess.run(c,
  658. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))));
  659. Assert.AreEqual((int)o, intResult);
  660. }
  661. // Testing `operator /(int x, Tensor y)
  662. c = tf.reduce_sum(tf.reduce_sum(firstIntVal / b, 1));
  663. using (var sess = tf.Session())
  664. {
  665. var o = sess.run(c,
  666. new FeedItem(b, new NDArray(secondIntFeed, new Shape(rows, cols))));
  667. Assert.AreEqual((int)o, intResult);
  668. }
  669. #endregion
  670. #region floatTest
  671. const float firstFloatVal = 6.0f;
  672. const float secondFloatVal = 3.0f;
  673. var firstFloatFeed = Enumerable.Repeat(firstFloatVal, rows * cols).ToArray();
  674. var secondFloatFeed = Enumerable.Repeat(secondFloatVal, rows * cols).ToArray();
  675. var floatResult = MultiplyArray(firstFloatFeed, secondFloatFeed.Select(x => 1/x).ToArray()).Sum();
  676. a = tf.placeholder(tf.float32, shape: new TensorShape(rows, cols));
  677. b = tf.placeholder(tf.float32, shape: new TensorShape(rows, cols));
  678. c = tf.reduce_sum(tf.reduce_sum(tf.divide(a, b), 1));
  679. using (var sess = tf.Session())
  680. {
  681. var o = sess.run(c,
  682. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))),
  683. new FeedItem(b, new NDArray(secondFloatFeed, new Shape(rows, cols))));
  684. Assert.AreEqual((float)o, floatResult);
  685. }
  686. // Testing `operator /(Tensor x, Tensor y)
  687. c = tf.reduce_sum(tf.reduce_sum(a / b, 1));
  688. using (var sess = tf.Session())
  689. {
  690. var o = sess.run(c,
  691. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))),
  692. new FeedItem(b, new NDArray(secondFloatFeed, new Shape(rows, cols))));
  693. Assert.AreEqual((float)o, floatResult);
  694. }
  695. // Testing `operator /(Tensor x, float y)
  696. c = tf.reduce_sum(tf.reduce_sum(a / secondFloatVal, 1));
  697. using (var sess = tf.Session())
  698. {
  699. var o = sess.run(c,
  700. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))));
  701. Assert.AreEqual((float)o, floatResult);
  702. }
  703. // Testing `operator /(float x, Tensor y)
  704. c = tf.reduce_sum(tf.reduce_sum(firstFloatVal / b, 1));
  705. using (var sess = tf.Session())
  706. {
  707. var o = sess.run(c,
  708. new FeedItem(b, new NDArray(secondFloatFeed, new Shape(rows, cols))));
  709. Assert.AreEqual((float)o, floatResult);
  710. }
  711. #endregion
  712. #region doubleTest
  713. const double firstDoubleVal = 6.0;
  714. const double secondDoubleVal = 3.0;
  715. var firstDoubleFeed = Enumerable.Repeat(firstDoubleVal, rows * cols).ToArray();
  716. var secondDoubleFeed = Enumerable.Repeat(secondDoubleVal, rows * cols).ToArray();
  717. var doubleResult = MultiplyArray(firstDoubleFeed, secondDoubleFeed.Select(x => 1/x).ToArray()).Sum();
  718. a = tf.placeholder(tf.float64, shape: new TensorShape(rows, cols));
  719. b = tf.placeholder(tf.float64, shape: new TensorShape(rows, cols));
  720. c = tf.reduce_sum(tf.reduce_sum(tf.divide(a, b), 1));
  721. using (var sess = tf.Session())
  722. {
  723. var o = sess.run(c,
  724. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))),
  725. new FeedItem(b, new NDArray(secondDoubleFeed, new Shape(rows, cols))));
  726. Assert.AreEqual((double)o, doubleResult);
  727. }
  728. // Testing `operator /(Tensor x, Tensor y)
  729. c = tf.reduce_sum(tf.reduce_sum(a / b, 1));
  730. using (var sess = tf.Session())
  731. {
  732. var o = sess.run(c,
  733. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))),
  734. new FeedItem(b, new NDArray(secondDoubleFeed, new Shape(rows, cols))));
  735. Assert.AreEqual((double)o, doubleResult);
  736. }
  737. // Testing `operator /(Tensor x, double y)
  738. c = tf.reduce_sum(tf.reduce_sum(a / secondFloatVal, 1));
  739. using (var sess = tf.Session())
  740. {
  741. var o = sess.run(c,
  742. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))));
  743. Assert.AreEqual((double)o, doubleResult);
  744. }
  745. // Testing `operator /(double x, Tensor y)
  746. c = tf.reduce_sum(tf.reduce_sum(firstFloatVal / b, 1));
  747. using (var sess = tf.Session())
  748. {
  749. var o = sess.run(c,
  750. new FeedItem(b, new NDArray(secondDoubleFeed, new Shape(rows, cols))));
  751. Assert.AreEqual((double)o, doubleResult);
  752. }
  753. #endregion
  754. }
  755. [TestMethod]
  756. public void greaterThanOpTests()
  757. {
  758. const int rows = 2; // to avoid broadcasting effect
  759. const int cols = 10;
  760. #region intTest
  761. const int intThreshold = 10;
  762. var firstIntFeed = Enumerable.Range(0, rows * cols).ToArray();
  763. var secondIntFeed = Enumerable.Repeat(intThreshold, rows * cols).ToArray();
  764. var intResult = firstIntFeed.Count(elem => elem > intThreshold);
  765. var intResultTwo = firstIntFeed.Count(elem => elem < intThreshold);
  766. var a = tf.placeholder(tf.int32, shape: new TensorShape(rows, cols));
  767. var b = tf.placeholder(tf.int32, shape: new TensorShape(rows, cols));
  768. var c = tf.reduce_sum(tf.reduce_sum(tf.cast(tf.greater(a, b), tf.int32), 1));
  769. using (var sess = tf.Session())
  770. {
  771. var o = sess.run(c,
  772. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))),
  773. new FeedItem(b, new NDArray(secondIntFeed, new Shape(rows, cols))));
  774. Assert.AreEqual((int)o, intResult);
  775. }
  776. // Testing `operator >(Tensor x, Tensor y)
  777. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a > b, tf.int32), 1));
  778. using (var sess = tf.Session())
  779. {
  780. var o = sess.run(c,
  781. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))),
  782. new FeedItem(b, new NDArray(secondIntFeed, new Shape(rows, cols))));
  783. Assert.AreEqual((int)o, intResult);
  784. }
  785. // Testing `operator >(Tensor x, int y)
  786. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a > intThreshold, tf.int32), 1));
  787. using (var sess = tf.Session())
  788. {
  789. var o = sess.run(c,
  790. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))));
  791. Assert.AreEqual((int)o, intResult);
  792. }
  793. // Testing `operator >(int x, Tensor y)
  794. c = tf.reduce_sum(tf.reduce_sum(tf.cast(intThreshold > a, tf.int32), 1));
  795. using (var sess = tf.Session())
  796. {
  797. var o = sess.run(c,
  798. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))));
  799. Assert.AreEqual((int)o, intResultTwo);
  800. }
  801. #endregion
  802. #region floatTest
  803. const float floatThreshold = 10.0f;
  804. var firstFloatFeed = Enumerable.Range(0, rows * cols).Select(elem => (float)elem).ToArray();
  805. var secondFloatFeed = Enumerable.Repeat(floatThreshold, rows * cols).ToArray();
  806. var floatResult = firstFloatFeed.Count(elem => elem > floatThreshold);
  807. var floatResultTwo = firstFloatFeed.Count(elem => elem < floatThreshold);
  808. a = tf.placeholder(tf.float32, shape: new TensorShape(rows, cols));
  809. b = tf.placeholder(tf.float32, shape: new TensorShape(rows, cols));
  810. c = tf.reduce_sum(tf.reduce_sum(tf.cast(tf.greater(a, b), tf.int32), 1));
  811. using (var sess = tf.Session())
  812. {
  813. var o = sess.run(c,
  814. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))),
  815. new FeedItem(b, new NDArray(secondFloatFeed, new Shape(rows, cols))));
  816. Assert.AreEqual((int)o, floatResult);
  817. }
  818. // Testing `operator >(Tensor x, Tensor y)
  819. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a > b, tf.int32), 1));
  820. using (var sess = tf.Session())
  821. {
  822. var o = sess.run(c,
  823. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))),
  824. new FeedItem(b, new NDArray(secondFloatFeed, new Shape(rows, cols))));
  825. Assert.AreEqual((int)o, floatResult);
  826. }
  827. // Testing `operator >(Tensor x, float y)
  828. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a > floatThreshold, tf.int32), 1));
  829. using (var sess = tf.Session())
  830. {
  831. var o = sess.run(c,
  832. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))));
  833. Assert.AreEqual((int)o, floatResult);
  834. }
  835. // Testing `operator >(float x, Tensor y)
  836. c = tf.reduce_sum(tf.reduce_sum(tf.cast(floatThreshold > a, tf.int32), 1));
  837. using (var sess = tf.Session())
  838. {
  839. var o = sess.run(c,
  840. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))));
  841. Assert.AreEqual((int)o, floatResultTwo);
  842. }
  843. #endregion
  844. #region doubleTest
  845. const double doubleThreshold = 10.0;
  846. var firstDoubleFeed = Enumerable.Repeat(0, rows * cols).Select(elem => (double)elem).ToArray();
  847. var secondDoubleFeed = Enumerable.Repeat(doubleThreshold, rows * cols).ToArray();
  848. var doubleResult = firstDoubleFeed.Count(elem => elem > doubleThreshold);
  849. var doubleResultTwo = firstDoubleFeed.Count(elem => elem < doubleThreshold);
  850. a = tf.placeholder(tf.float64, shape: new TensorShape(rows, cols));
  851. b = tf.placeholder(tf.float64, shape: new TensorShape(rows, cols));
  852. c = tf.reduce_sum(tf.reduce_sum(tf.cast(tf.greater(a, b), tf.int32), 1));
  853. using (var sess = tf.Session())
  854. {
  855. var o = sess.run(c,
  856. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))),
  857. new FeedItem(b, new NDArray(secondDoubleFeed, new Shape(rows, cols))));
  858. Assert.AreEqual((int)o, doubleResult);
  859. }
  860. // Testing `operator >(Tensor x, Tensor y)
  861. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a > b, tf.int32), 1));
  862. using (var sess = tf.Session())
  863. {
  864. var o = sess.run(c,
  865. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))),
  866. new FeedItem(b, new NDArray(secondDoubleFeed, new Shape(rows, cols))));
  867. Assert.AreEqual((int)o, doubleResult);
  868. }
  869. // Testing `operator >(Tensor x, double y)
  870. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a > doubleThreshold, tf.int32), 1));
  871. using (var sess = tf.Session())
  872. {
  873. var o = sess.run(c,
  874. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))));
  875. Assert.AreEqual((int)o, doubleResult);
  876. }
  877. // Testing `operator >(double x, Tensor y)
  878. c = tf.reduce_sum(tf.reduce_sum(tf.cast(doubleThreshold > a, tf.int32), 1));
  879. using (var sess = tf.Session())
  880. {
  881. var o = sess.run(c,
  882. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))));
  883. Assert.AreEqual((int)o, doubleResultTwo);
  884. }
  885. #endregion
  886. }
  887. [TestMethod]
  888. public void lessThanOpTests()
  889. {
  890. const int rows = 2; // to avoid broadcasting effect
  891. const int cols = 10;
  892. #region intTest
  893. const int intThreshold = 10;
  894. var firstIntFeed = Enumerable.Range(0, rows * cols).ToArray();
  895. var secondIntFeed = Enumerable.Repeat(intThreshold, rows * cols).ToArray();
  896. var intResult = firstIntFeed.Count(elem => elem < intThreshold);
  897. var intResultTwo = firstIntFeed.Count(elem => elem > intThreshold);
  898. var a = tf.placeholder(tf.int32, shape: new TensorShape(rows, cols));
  899. var b = tf.placeholder(tf.int32, shape: new TensorShape(rows, cols));
  900. var c = tf.reduce_sum(tf.reduce_sum(tf.cast(tf.less(a, b), tf.int32), 1));
  901. using (var sess = tf.Session())
  902. {
  903. var o = sess.run(c,
  904. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))),
  905. new FeedItem(b, new NDArray(secondIntFeed, new Shape(rows, cols))));
  906. Assert.AreEqual((int)o, intResult);
  907. }
  908. // Testing `operator <(Tensor x, Tensor y)
  909. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a < b, tf.int32), 1));
  910. using (var sess = tf.Session())
  911. {
  912. var o = sess.run(c,
  913. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))),
  914. new FeedItem(b, new NDArray(secondIntFeed, new Shape(rows, cols))));
  915. Assert.AreEqual((int)o, intResult);
  916. }
  917. // Testing `operator <(Tensor x, int y)
  918. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a < intThreshold, tf.int32), 1));
  919. using (var sess = tf.Session())
  920. {
  921. var o = sess.run(c,
  922. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))));
  923. Assert.AreEqual((int)o, intResult);
  924. }
  925. // Testing `operator <(int x, Tensor y)
  926. c = tf.reduce_sum(tf.reduce_sum(tf.cast(intThreshold < a, tf.int32), 1));
  927. using (var sess = tf.Session())
  928. {
  929. var o = sess.run(c,
  930. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))));
  931. Assert.AreEqual((int)o, intResultTwo);
  932. }
  933. #endregion
  934. #region floatTest
  935. const float floatThreshold = 10.0f;
  936. var firstFloatFeed = Enumerable.Range(0, rows * cols).Select(elem => (float)elem).ToArray();
  937. var secondFloatFeed = Enumerable.Repeat(floatThreshold, rows * cols).ToArray();
  938. var floatResult = firstFloatFeed.Count(elem => elem < floatThreshold);
  939. var floatResultTwo = firstFloatFeed.Count(elem => elem > floatThreshold);
  940. a = tf.placeholder(tf.float32, shape: new TensorShape(rows, cols));
  941. b = tf.placeholder(tf.float32, shape: new TensorShape(rows, cols));
  942. c = tf.reduce_sum(tf.reduce_sum(tf.cast(tf.less(a, b), tf.int32), 1));
  943. using (var sess = tf.Session())
  944. {
  945. var o = sess.run(c,
  946. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))),
  947. new FeedItem(b, new NDArray(secondFloatFeed, new Shape(rows, cols))));
  948. Assert.AreEqual((int)o, floatResult);
  949. }
  950. // Testing `operator <(Tensor x, Tensor y)
  951. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a < b, tf.int32), 1));
  952. using (var sess = tf.Session())
  953. {
  954. var o = sess.run(c,
  955. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))),
  956. new FeedItem(b, new NDArray(secondFloatFeed, new Shape(rows, cols))));
  957. Assert.AreEqual((int)o, floatResult);
  958. }
  959. // Testing `operator <(Tensor x, float y)
  960. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a < floatThreshold, tf.int32), 1));
  961. using (var sess = tf.Session())
  962. {
  963. var o = sess.run(c,
  964. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))));
  965. Assert.AreEqual((int)o, floatResult);
  966. }
  967. // Testing `operator <(float x, Tensor y)
  968. c = tf.reduce_sum(tf.reduce_sum(tf.cast(floatThreshold < a, tf.int32), 1));
  969. using (var sess = tf.Session())
  970. {
  971. var o = sess.run(c,
  972. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))));
  973. Assert.AreEqual((int)o, floatResultTwo);
  974. }
  975. #endregion
  976. #region doubleTest
  977. const double doubleThreshold = 10.0;
  978. var firstDoubleFeed = Enumerable.Repeat(0, rows * cols).Select(elem => (double)elem).ToArray();
  979. var secondDoubleFeed = Enumerable.Repeat(doubleThreshold, rows * cols).ToArray();
  980. var doubleResult = firstDoubleFeed.Count(elem => elem < doubleThreshold);
  981. var doubleResultTwo = firstDoubleFeed.Count(elem => elem > doubleThreshold);
  982. a = tf.placeholder(tf.float64, shape: new TensorShape(rows, cols));
  983. b = tf.placeholder(tf.float64, shape: new TensorShape(rows, cols));
  984. c = tf.reduce_sum(tf.reduce_sum(tf.cast(tf.less(a, b), tf.int32), 1));
  985. using (var sess = tf.Session())
  986. {
  987. var o = sess.run(c,
  988. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))),
  989. new FeedItem(b, new NDArray(secondDoubleFeed, new Shape(rows, cols))));
  990. Assert.AreEqual((int)o, doubleResult);
  991. }
  992. // Testing `operator <(Tensor x, Tensor y)
  993. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a < b, tf.int32), 1));
  994. using (var sess = tf.Session())
  995. {
  996. var o = sess.run(c,
  997. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))),
  998. new FeedItem(b, new NDArray(secondDoubleFeed, new Shape(rows, cols))));
  999. Assert.AreEqual((int)o, doubleResult);
  1000. }
  1001. // Testing `operator <(Tensor x, double y)
  1002. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a < doubleThreshold, tf.int32), 1));
  1003. using (var sess = tf.Session())
  1004. {
  1005. var o = sess.run(c,
  1006. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))));
  1007. Assert.AreEqual((int)o, doubleResult);
  1008. }
  1009. // Testing `operator <(double x, Tensor y)
  1010. c = tf.reduce_sum(tf.reduce_sum(tf.cast(doubleThreshold < a, tf.int32), 1));
  1011. using (var sess = tf.Session())
  1012. {
  1013. var o = sess.run(c,
  1014. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))));
  1015. Assert.AreEqual((int)o, doubleResultTwo);
  1016. }
  1017. #endregion
  1018. }
  1019. [TestMethod]
  1020. public void greaterOrEqualThanOpTests()
  1021. {
  1022. const int rows = 2; // to avoid broadcasting effect
  1023. const int cols = 10;
  1024. #region intTest
  1025. const int intThreshold = 10;
  1026. var firstIntFeed = Enumerable.Range(0, rows * cols).ToArray();
  1027. var secondIntFeed = Enumerable.Repeat(intThreshold, rows * cols).ToArray();
  1028. var intResult = firstIntFeed.Count(elem => elem >= intThreshold);
  1029. var intResultTwo = firstIntFeed.Count(elem => elem <= intThreshold);
  1030. var a = tf.placeholder(tf.int32, shape: new TensorShape(rows, cols));
  1031. var b = tf.placeholder(tf.int32, shape: new TensorShape(rows, cols));
  1032. var c = tf.reduce_sum(tf.reduce_sum(tf.cast(tf.greater_equal(a, b), tf.int32), 1));
  1033. using (var sess = tf.Session())
  1034. {
  1035. var o = sess.run(c,
  1036. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))),
  1037. new FeedItem(b, new NDArray(secondIntFeed, new Shape(rows, cols))));
  1038. Assert.AreEqual((int)o, intResult);
  1039. }
  1040. // Testing `operator >=(Tensor x, Tensor y)
  1041. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a >= b, tf.int32), 1));
  1042. using (var sess = tf.Session())
  1043. {
  1044. var o = sess.run(c,
  1045. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))),
  1046. new FeedItem(b, new NDArray(secondIntFeed, new Shape(rows, cols))));
  1047. Assert.AreEqual((int)o, intResult);
  1048. }
  1049. // Testing `operator >=(Tensor x, int y)
  1050. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a >= intThreshold, tf.int32), 1));
  1051. using (var sess = tf.Session())
  1052. {
  1053. var o = sess.run(c,
  1054. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))));
  1055. Assert.AreEqual((int)o, intResult);
  1056. }
  1057. // Testing `operator >=(int x, Tensor y)
  1058. c = tf.reduce_sum(tf.reduce_sum(tf.cast(intThreshold >= a, tf.int32), 1));
  1059. using (var sess = tf.Session())
  1060. {
  1061. var o = sess.run(c,
  1062. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))));
  1063. Assert.AreEqual((int)o, intResultTwo);
  1064. }
  1065. #endregion
  1066. #region floatTest
  1067. const float floatThreshold = 10.0f;
  1068. var firstFloatFeed = Enumerable.Range(0, rows * cols).Select(elem => (float)elem).ToArray();
  1069. var secondFloatFeed = Enumerable.Repeat(floatThreshold, rows * cols).ToArray();
  1070. var floatResult = firstFloatFeed.Count(elem => elem >= floatThreshold);
  1071. var floatResultTwo = firstFloatFeed.Count(elem => elem <= floatThreshold);
  1072. a = tf.placeholder(tf.float32, shape: new TensorShape(rows, cols));
  1073. b = tf.placeholder(tf.float32, shape: new TensorShape(rows, cols));
  1074. c = tf.reduce_sum(tf.reduce_sum(tf.cast(tf.greater_equal(a, b), tf.int32), 1));
  1075. using (var sess = tf.Session())
  1076. {
  1077. var o = sess.run(c,
  1078. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))),
  1079. new FeedItem(b, new NDArray(secondFloatFeed, new Shape(rows, cols))));
  1080. Assert.AreEqual((int)o, floatResult);
  1081. }
  1082. // Testing `operator >=(Tensor x, Tensor y)
  1083. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a >= b, tf.int32), 1));
  1084. using (var sess = tf.Session())
  1085. {
  1086. var o = sess.run(c,
  1087. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))),
  1088. new FeedItem(b, new NDArray(secondFloatFeed, new Shape(rows, cols))));
  1089. Assert.AreEqual((int)o, floatResult);
  1090. }
  1091. // Testing `operator >=(Tensor x, float y)
  1092. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a >= floatThreshold, tf.int32), 1));
  1093. using (var sess = tf.Session())
  1094. {
  1095. var o = sess.run(c,
  1096. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))));
  1097. Assert.AreEqual((int)o, floatResult);
  1098. }
  1099. // Testing `operator >=(float x, Tensor y)
  1100. c = tf.reduce_sum(tf.reduce_sum(tf.cast(floatThreshold >= a, tf.int32), 1));
  1101. using (var sess = tf.Session())
  1102. {
  1103. var o = sess.run(c,
  1104. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))));
  1105. Assert.AreEqual((int)o, floatResultTwo);
  1106. }
  1107. #endregion
  1108. #region doubleTest
  1109. const double doubleThreshold = 10.0;
  1110. var firstDoubleFeed = Enumerable.Repeat(0, rows * cols).Select(elem => (double)elem).ToArray();
  1111. var secondDoubleFeed = Enumerable.Repeat(doubleThreshold, rows * cols).ToArray();
  1112. var doubleResult = firstDoubleFeed.Count(elem => elem >= doubleThreshold);
  1113. var doubleResultTwo = firstDoubleFeed.Count(elem => elem <= doubleThreshold);
  1114. a = tf.placeholder(tf.float64, shape: new TensorShape(rows, cols));
  1115. b = tf.placeholder(tf.float64, shape: new TensorShape(rows, cols));
  1116. c = tf.reduce_sum(tf.reduce_sum(tf.cast(tf.greater_equal(a, b), tf.int32), 1));
  1117. using (var sess = tf.Session())
  1118. {
  1119. var o = sess.run(c,
  1120. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))),
  1121. new FeedItem(b, new NDArray(secondDoubleFeed, new Shape(rows, cols))));
  1122. Assert.AreEqual((int)o, doubleResult);
  1123. }
  1124. // Testing `operator >=(Tensor x, Tensor y)
  1125. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a >= b, tf.int32), 1));
  1126. using (var sess = tf.Session())
  1127. {
  1128. var o = sess.run(c,
  1129. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))),
  1130. new FeedItem(b, new NDArray(secondDoubleFeed, new Shape(rows, cols))));
  1131. Assert.AreEqual((int)o, doubleResult);
  1132. }
  1133. // Testing `operator >=(Tensor x, double y)
  1134. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a >= doubleThreshold, tf.int32), 1));
  1135. using (var sess = tf.Session())
  1136. {
  1137. var o = sess.run(c,
  1138. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))));
  1139. Assert.AreEqual((int)o, doubleResult);
  1140. }
  1141. // Testing `operator >=(double x, Tensor y)
  1142. c = tf.reduce_sum(tf.reduce_sum(tf.cast(doubleThreshold >= a, tf.int32), 1));
  1143. using (var sess = tf.Session())
  1144. {
  1145. var o = sess.run(c,
  1146. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))));
  1147. Assert.AreEqual((int)o, doubleResultTwo);
  1148. }
  1149. #endregion
  1150. }
  1151. [TestMethod]
  1152. public void lessOrEqualThanOpTests()
  1153. {
  1154. const int rows = 2; // to avoid broadcasting effect
  1155. const int cols = 10;
  1156. #region intTest
  1157. const int intThreshold = 10;
  1158. var firstIntFeed = Enumerable.Range(0, rows * cols).ToArray();
  1159. var secondIntFeed = Enumerable.Repeat(intThreshold, rows * cols).ToArray();
  1160. var intResult = firstIntFeed.Count(elem => elem <= intThreshold);
  1161. var intResultTwo = firstIntFeed.Count(elem => elem >= intThreshold);
  1162. var a = tf.placeholder(tf.int32, shape: new TensorShape(rows, cols));
  1163. var b = tf.placeholder(tf.int32, shape: new TensorShape(rows, cols));
  1164. var c = tf.reduce_sum(tf.reduce_sum(tf.cast(tf.less_equal(a, b), tf.int32), 1));
  1165. using (var sess = tf.Session())
  1166. {
  1167. var o = sess.run(c,
  1168. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))),
  1169. new FeedItem(b, new NDArray(secondIntFeed, new Shape(rows, cols))));
  1170. Assert.AreEqual((int)o, intResult);
  1171. }
  1172. // Testing `operator <=(Tensor x, Tensor y)
  1173. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a <= b, tf.int32), 1));
  1174. using (var sess = tf.Session())
  1175. {
  1176. var o = sess.run(c,
  1177. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))),
  1178. new FeedItem(b, new NDArray(secondIntFeed, new Shape(rows, cols))));
  1179. Assert.AreEqual((int)o, intResult);
  1180. }
  1181. // Testing `operator <=(Tensor x, int y)
  1182. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a <= intThreshold, tf.int32), 1));
  1183. using (var sess = tf.Session())
  1184. {
  1185. var o = sess.run(c,
  1186. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))));
  1187. Assert.AreEqual((int)o, intResult);
  1188. }
  1189. // Testing `operator <=(int x, Tensor y)
  1190. c = tf.reduce_sum(tf.reduce_sum(tf.cast(intThreshold <= a, tf.int32), 1));
  1191. using (var sess = tf.Session())
  1192. {
  1193. var o = sess.run(c,
  1194. new FeedItem(a, new NDArray(firstIntFeed, new Shape(rows, cols))));
  1195. Assert.AreEqual((int)o, intResultTwo);
  1196. }
  1197. #endregion
  1198. #region floatTest
  1199. const float floatThreshold = 10.0f;
  1200. var firstFloatFeed = Enumerable.Range(0, rows * cols).Select(elem => (float)elem).ToArray();
  1201. var secondFloatFeed = Enumerable.Repeat(floatThreshold, rows * cols).ToArray();
  1202. var floatResult = firstFloatFeed.Count(elem => elem <= floatThreshold);
  1203. var floatResultTwo = firstFloatFeed.Count(elem => elem >= floatThreshold);
  1204. a = tf.placeholder(tf.float32, shape: new TensorShape(rows, cols));
  1205. b = tf.placeholder(tf.float32, shape: new TensorShape(rows, cols));
  1206. c = tf.reduce_sum(tf.reduce_sum(tf.cast(tf.less_equal(a, b), tf.int32), 1));
  1207. using (var sess = tf.Session())
  1208. {
  1209. var o = sess.run(c,
  1210. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))),
  1211. new FeedItem(b, new NDArray(secondFloatFeed, new Shape(rows, cols))));
  1212. Assert.AreEqual((int)o, floatResult);
  1213. }
  1214. // Testing `operator <=(Tensor x, Tensor y)
  1215. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a <= b, tf.int32), 1));
  1216. using (var sess = tf.Session())
  1217. {
  1218. var o = sess.run(c,
  1219. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))),
  1220. new FeedItem(b, new NDArray(secondFloatFeed, new Shape(rows, cols))));
  1221. Assert.AreEqual((int)o, floatResult);
  1222. }
  1223. // Testing `operator <=(Tensor x, float y)
  1224. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a <= floatThreshold, tf.int32), 1));
  1225. using (var sess = tf.Session())
  1226. {
  1227. var o = sess.run(c,
  1228. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))));
  1229. Assert.AreEqual((int)o, floatResult);
  1230. }
  1231. // Testing `operator <=(float x, Tensor y)
  1232. c = tf.reduce_sum(tf.reduce_sum(tf.cast(floatThreshold <= a, tf.int32), 1));
  1233. using (var sess = tf.Session())
  1234. {
  1235. var o = sess.run(c,
  1236. new FeedItem(a, new NDArray(firstFloatFeed, new Shape(rows, cols))));
  1237. Assert.AreEqual((int)o, floatResultTwo);
  1238. }
  1239. #endregion
  1240. #region doubleTest
  1241. const double doubleThreshold = 10.0;
  1242. var firstDoubleFeed = Enumerable.Repeat(0, rows * cols).Select(elem => (double)elem).ToArray();
  1243. var secondDoubleFeed = Enumerable.Repeat(doubleThreshold, rows * cols).ToArray();
  1244. var doubleResult = firstDoubleFeed.Count(elem => elem <= doubleThreshold);
  1245. var doubleResultTwo = firstDoubleFeed.Count(elem => elem >= doubleThreshold);
  1246. a = tf.placeholder(tf.float64, shape: new TensorShape(rows, cols));
  1247. b = tf.placeholder(tf.float64, shape: new TensorShape(rows, cols));
  1248. c = tf.reduce_sum(tf.reduce_sum(tf.cast(tf.less_equal(a, b), tf.int32), 1));
  1249. using (var sess = tf.Session())
  1250. {
  1251. var o = sess.run(c,
  1252. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))),
  1253. new FeedItem(b, new NDArray(secondDoubleFeed, new Shape(rows, cols))));
  1254. Assert.AreEqual((int)o, doubleResult);
  1255. }
  1256. // Testing `operator <=(Tensor x, Tensor y)
  1257. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a <= b, tf.int32), 1));
  1258. using (var sess = tf.Session())
  1259. {
  1260. var o = sess.run(c,
  1261. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))),
  1262. new FeedItem(b, new NDArray(secondDoubleFeed, new Shape(rows, cols))));
  1263. Assert.AreEqual((int)o, doubleResult);
  1264. }
  1265. // Testing `operator <=(Tensor x, double y)
  1266. c = tf.reduce_sum(tf.reduce_sum(tf.cast(a <= doubleThreshold, tf.int32), 1));
  1267. using (var sess = tf.Session())
  1268. {
  1269. var o = sess.run(c,
  1270. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))));
  1271. Assert.AreEqual((int)o, doubleResult);
  1272. }
  1273. // Testing `operator <=(double x, Tensor y)
  1274. c = tf.reduce_sum(tf.reduce_sum(tf.cast(doubleThreshold <= a, tf.int32), 1));
  1275. using (var sess = tf.Session())
  1276. {
  1277. var o = sess.run(c,
  1278. new FeedItem(a, new NDArray(firstDoubleFeed, new Shape(rows, cols))));
  1279. Assert.AreEqual((int)o, doubleResultTwo);
  1280. }
  1281. #endregion
  1282. }
  1283. [Ignore("Not finished yet")]
  1284. [TestMethod]
  1285. public void map_fn()
  1286. {
  1287. var a = tf.constant(new[] { 1, 2, 3, 4 });
  1288. var b = tf.constant(new[] { 17, 12, 11, 10 });
  1289. var ab = tf.stack(new[] { a, b }, 1);
  1290. Func<Tensor, Tensor> map_operation = (value_ab) =>
  1291. {
  1292. var value_a = value_ab[0];
  1293. var value_b = value_ab[1];
  1294. return value_a + value_b;
  1295. };
  1296. var map_result = tf.map_fn(map_operation, ab);
  1297. }
  1298. }
  1299. }