mkql_flatmap_ut.cpp 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853
  1. #include "mkql_computation_node_ut.h"
  2. #include <yql/essentials/minikql/mkql_runtime_version.h>
  3. namespace NKikimr {
  4. namespace NMiniKQL {
  5. Y_UNIT_TEST_SUITE(TMiniKQLFlatMapTest) {
  6. Y_UNIT_TEST_LLVM(TestOverListAndPartialLists) {
  7. TSetup<LLVM> setup;
  8. TProgramBuilder& pb = *setup.PgmBuilder;
  9. const auto data1 = pb.NewDataLiteral<ui32>(1);
  10. const auto data2 = pb.NewDataLiteral<ui32>(2);
  11. const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
  12. const auto list = pb.NewList(dataType, {data1, data2});
  13. const auto pgmReturn = pb.FlatMap(list,
  14. [&](TRuntimeNode item) {
  15. return pb.NewList(dataType, {pb.Add(item, data1), pb.Mul(item, data2)});
  16. });
  17. const auto graph = setup.BuildGraph(pgmReturn);
  18. const auto iterator = graph->GetValue().GetListIterator();
  19. NUdf::TUnboxedValue item;
  20. UNIT_ASSERT(iterator.Next(item));
  21. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
  22. UNIT_ASSERT(iterator.Next(item));
  23. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
  24. UNIT_ASSERT(iterator.Next(item));
  25. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
  26. UNIT_ASSERT(iterator.Next(item));
  27. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 4);
  28. UNIT_ASSERT(!iterator.Next(item));
  29. UNIT_ASSERT(!iterator.Next(item));
  30. }
  31. Y_UNIT_TEST_LLVM(TestOverListAndStreams) {
  32. TSetup<LLVM> setup;
  33. TProgramBuilder& pb = *setup.PgmBuilder;
  34. const auto data1 = pb.NewDataLiteral<i8>(3);
  35. const auto data2 = pb.NewDataLiteral<i8>(-7);
  36. const auto dataType = pb.NewDataType(NUdf::TDataType<i8>::Id);
  37. const auto list = pb.NewList(dataType, {data1, data2});
  38. const auto pgmReturn = pb.FlatMap(list,
  39. [&](TRuntimeNode item) {
  40. return pb.Iterator(pb.NewList(dataType, {pb.Plus(item), pb.Minus(item)}), {});
  41. });
  42. const auto graph = setup.BuildGraph(pgmReturn);
  43. const auto iterator = graph->GetValue().GetListIterator();
  44. NUdf::TUnboxedValue item;
  45. UNIT_ASSERT(iterator.Next(item));
  46. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), 3);
  47. UNIT_ASSERT(iterator.Next(item));
  48. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), -3);
  49. UNIT_ASSERT(iterator.Next(item));
  50. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), -7);
  51. UNIT_ASSERT(iterator.Next(item));
  52. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i8>(), 7);
  53. UNIT_ASSERT(!iterator.Next(item));
  54. UNIT_ASSERT(!iterator.Next(item));
  55. }
  56. Y_UNIT_TEST_LLVM(TestOverStreamAndPartialLists) {
  57. TSetup<LLVM> setup;
  58. TProgramBuilder& pb = *setup.PgmBuilder;
  59. const auto data1 = pb.NewDataLiteral<ui16>(10);
  60. const auto data2 = pb.NewDataLiteral<ui16>(20);
  61. const auto dataType = pb.NewDataType(NUdf::TDataType<ui16>::Id);
  62. const auto list = pb.NewList(dataType, {data1, data2});
  63. const auto pgmReturn = pb.FlatMap(pb.Iterator(list, {}),
  64. [&](TRuntimeNode item) {
  65. return pb.NewList(dataType, {pb.Sub(item, data1), pb.Unwrap(pb.Div(item, data2), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0)});
  66. });
  67. const auto graph = setup.BuildGraph(pgmReturn);
  68. const auto iterator = graph->GetValue();
  69. NUdf::TUnboxedValue item;
  70. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  71. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0);
  72. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  73. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0);
  74. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  75. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 10);
  76. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  77. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 1);
  78. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  79. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  80. }
  81. Y_UNIT_TEST_LLVM(TestOverFlowAndPartialLists) {
  82. TSetup<LLVM> setup;
  83. TProgramBuilder& pb = *setup.PgmBuilder;
  84. const auto data1 = pb.NewDataLiteral<ui16>(10);
  85. const auto data2 = pb.NewDataLiteral<ui16>(20);
  86. const auto dataType = pb.NewDataType(NUdf::TDataType<ui16>::Id);
  87. const auto list = pb.NewList(dataType, {data1, data2});
  88. const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(pb.Iterator(list, {})),
  89. [&](TRuntimeNode item) {
  90. return pb.NewList(dataType, {pb.Sub(item, data1), pb.Unwrap(pb.Div(item, data2), pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0)});
  91. }));
  92. const auto& graph = setup.BuildGraph(pgmReturn);
  93. const NUdf::TUnboxedValue& iterator = graph->GetValue();
  94. NUdf::TUnboxedValue item;
  95. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  96. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0);
  97. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  98. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 0);
  99. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  100. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 10);
  101. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  102. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui16>(), 1);
  103. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  104. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  105. }
  106. Y_UNIT_TEST_LLVM(TestOverStreamAndStreams) {
  107. TSetup<LLVM> setup;
  108. TProgramBuilder& pb = *setup.PgmBuilder;
  109. const auto data = pb.NewDataLiteral<i32>(-100);
  110. const auto data0 = pb.NewDataLiteral<i32>(0);
  111. const auto data1 = pb.NewDataLiteral<i32>(3);
  112. const auto data2 = pb.NewDataLiteral<i32>(7);
  113. const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
  114. const auto list = pb.NewList(dataType, {data0, data1, data2});
  115. const auto pgmReturn = pb.FlatMap(pb.Iterator(list, {}),
  116. [&](TRuntimeNode item) {
  117. return pb.Iterator(pb.NewList(pb.NewOptionalType(dataType),
  118. {pb.Mod(data, item), pb.Div(data, item)}), {});
  119. });
  120. const auto graph = setup.BuildGraph(pgmReturn);
  121. const auto iterator = graph->GetValue();
  122. NUdf::TUnboxedValue item;
  123. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  124. UNIT_ASSERT(!item);
  125. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  126. UNIT_ASSERT(!item);
  127. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  128. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
  129. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  130. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -33);
  131. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  132. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -2);
  133. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  134. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -14);
  135. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  136. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  137. }
  138. Y_UNIT_TEST_LLVM(TestOverFlowAndStreams) {
  139. TSetup<LLVM> setup;
  140. TProgramBuilder& pb = *setup.PgmBuilder;
  141. const auto data = pb.NewDataLiteral<i32>(-100);
  142. const auto data0 = pb.NewDataLiteral<i32>(0);
  143. const auto data1 = pb.NewDataLiteral<i32>(3);
  144. const auto data2 = pb.NewDataLiteral<i32>(7);
  145. const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
  146. const auto list = pb.NewList(dataType, {data0, data1, data2});
  147. const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(list),
  148. [&](TRuntimeNode item) {
  149. return pb.Iterator(pb.NewList(pb.NewOptionalType(dataType),
  150. {pb.Mod(data, item), pb.Div(data, item)}), {});
  151. }));
  152. const auto graph = setup.BuildGraph(pgmReturn);
  153. const auto iterator = graph->GetValue();
  154. NUdf::TUnboxedValue item;
  155. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  156. UNIT_ASSERT(!item);
  157. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  158. UNIT_ASSERT(!item);
  159. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  160. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
  161. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  162. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -33);
  163. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  164. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -2);
  165. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  166. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -14);
  167. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  168. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  169. }
  170. Y_UNIT_TEST_LLVM(TestOverFlowAndFlows) {
  171. TSetup<LLVM> setup;
  172. TProgramBuilder& pb = *setup.PgmBuilder;
  173. const auto data = pb.NewDataLiteral<i32>(-100);
  174. const auto data0 = pb.NewDataLiteral<i32>(0);
  175. const auto data1 = pb.NewDataLiteral<i32>(3);
  176. const auto data2 = pb.NewDataLiteral<i32>(7);
  177. const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
  178. const auto list = pb.NewList(dataType, {data0, data1, data2});
  179. const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(list),
  180. [&](TRuntimeNode item) {
  181. return pb.ToFlow(pb.NewList(pb.NewOptionalType(dataType),
  182. {pb.Mod(data, item), pb.Div(data, item)}));
  183. }));
  184. const auto graph = setup.BuildGraph(pgmReturn);
  185. const auto iterator = graph->GetValue();
  186. NUdf::TUnboxedValue item;
  187. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  188. UNIT_ASSERT(!item);
  189. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  190. UNIT_ASSERT(!item);
  191. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  192. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
  193. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  194. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -33);
  195. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  196. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -2);
  197. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  198. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -14);
  199. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  200. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  201. }
  202. Y_UNIT_TEST_LLVM(TestOverListAndFlows) {
  203. TSetup<LLVM> setup;
  204. TProgramBuilder& pb = *setup.PgmBuilder;
  205. const auto data = pb.NewDataLiteral<i32>(-100);
  206. const auto data0 = pb.NewDataLiteral<i32>(0);
  207. const auto data1 = pb.NewDataLiteral<i32>(3);
  208. const auto data2 = pb.NewDataLiteral<i32>(7);
  209. const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
  210. const auto list = pb.NewList(dataType, {data0, data1, data2});
  211. const auto pgmReturn = pb.FromFlow(pb.FlatMap(list,
  212. [&](TRuntimeNode item) {
  213. return pb.ToFlow(pb.NewList(pb.NewOptionalType(dataType),
  214. {pb.Mod(data, item), pb.Div(data, item)}));
  215. }));
  216. const auto graph = setup.BuildGraph(pgmReturn);
  217. const auto iterator = graph->GetValue();
  218. NUdf::TUnboxedValue item;
  219. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  220. UNIT_ASSERT(!item);
  221. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  222. UNIT_ASSERT(!item);
  223. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  224. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
  225. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  226. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -33);
  227. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  228. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -2);
  229. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  230. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -14);
  231. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  232. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  233. }
  234. Y_UNIT_TEST_LLVM(TestOverFlowAndIndependentFlows) {
  235. TSetup<LLVM> setup;
  236. TProgramBuilder& pb = *setup.PgmBuilder;
  237. const auto data = pb.NewDataLiteral<i32>(-100);
  238. const auto data0 = pb.NewDataLiteral<i32>(0);
  239. const auto data1 = pb.NewDataLiteral<i32>(3);
  240. const auto data2 = pb.NewDataLiteral<i32>(7);
  241. const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
  242. const auto list = pb.NewList(dataType, {data0, data1, data2});
  243. const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(list),
  244. [&](TRuntimeNode) {
  245. return pb.Map(pb.ToFlow(pb.NewList(dataType, {data, data})), [&](TRuntimeNode it) { return pb.Abs(it); });
  246. }));
  247. const auto graph = setup.BuildGraph(pgmReturn);
  248. const auto iterator = graph->GetValue();
  249. NUdf::TUnboxedValue item;
  250. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  251. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
  252. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  253. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
  254. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  255. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
  256. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  257. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
  258. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  259. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
  260. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  261. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
  262. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  263. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  264. }
  265. Y_UNIT_TEST_LLVM(TestOverListAndIndependentFlows) {
  266. TSetup<LLVM> setup;
  267. TProgramBuilder& pb = *setup.PgmBuilder;
  268. const auto data = pb.NewDataLiteral<i32>(-100);
  269. const auto data0 = pb.NewDataLiteral<i32>(0);
  270. const auto data1 = pb.NewDataLiteral<i32>(3);
  271. const auto data2 = pb.NewDataLiteral<i32>(7);
  272. const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
  273. const auto list = pb.NewList(dataType, {data0, data1, data2});
  274. const auto pgmReturn = pb.FromFlow(pb.FlatMap(list,
  275. [&](TRuntimeNode) {
  276. return pb.Map(pb.ToFlow(pb.NewList(dataType, {data, data})), [&](TRuntimeNode it) { return pb.Minus(it); });
  277. }));
  278. const auto graph = setup.BuildGraph(pgmReturn);
  279. const auto iterator = graph->GetValue();
  280. NUdf::TUnboxedValue item;
  281. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  282. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
  283. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  284. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
  285. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  286. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
  287. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  288. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
  289. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  290. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
  291. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  292. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 100);
  293. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  294. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  295. }
  296. Y_UNIT_TEST_LLVM(TestOverFlowAndPartialOptionals) {
  297. TSetup<LLVM> setup;
  298. TProgramBuilder& pb = *setup.PgmBuilder;
  299. const auto data = pb.NewDataLiteral<i64>(-100);
  300. const auto data0 = pb.NewDataLiteral<i64>(0);
  301. const auto data1 = pb.NewDataLiteral<i64>(3);
  302. const auto data2 = pb.NewDataLiteral<i64>(7);
  303. const auto dataType = pb.NewDataType(NUdf::TDataType<i64>::Id);
  304. const auto list = pb.NewList(dataType, {data0, data1, data2});
  305. const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(pb.Iterator(list, {})),
  306. [&](TRuntimeNode item) {
  307. return pb.Div(data, item);
  308. }));
  309. const auto graph = setup.BuildGraph(pgmReturn);
  310. const auto iterator = graph->GetValue();
  311. NUdf::TUnboxedValue item;
  312. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  313. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), -33);
  314. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  315. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), -14);
  316. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  317. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  318. }
  319. Y_UNIT_TEST_LLVM(TestOverStreamAndPartialOptionals) {
  320. TSetup<LLVM> setup;
  321. TProgramBuilder& pb = *setup.PgmBuilder;
  322. const auto data = pb.NewDataLiteral<i64>(-100);
  323. const auto data0 = pb.NewDataLiteral<i64>(0);
  324. const auto data1 = pb.NewDataLiteral<i64>(3);
  325. const auto data2 = pb.NewDataLiteral<i64>(7);
  326. const auto dataType = pb.NewDataType(NUdf::TDataType<i64>::Id);
  327. const auto list = pb.NewList(dataType, {data0, data1, data2});
  328. const auto pgmReturn = pb.FlatMap(pb.Iterator(list, {}),
  329. [&](TRuntimeNode item) {
  330. return pb.Div(data, item);
  331. });
  332. const auto graph = setup.BuildGraph(pgmReturn);
  333. const auto iterator = graph->GetValue();
  334. NUdf::TUnboxedValue item;
  335. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  336. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), -33);
  337. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  338. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i64>(), -14);
  339. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  340. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  341. }
  342. Y_UNIT_TEST_LLVM(TestOverListAndPartialOptionals) {
  343. TSetup<LLVM> setup;
  344. TProgramBuilder& pb = *setup.PgmBuilder;
  345. const auto data0 = pb.NewDataLiteral<ui32>(0);
  346. const auto data1 = pb.NewDataLiteral<ui32>(1);
  347. const auto data2 = pb.NewDataLiteral<ui32>(2);
  348. const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
  349. const auto list = pb.NewList(dataType, {data0, data1, data2});
  350. const auto pgmReturn = pb.FlatMap(list,
  351. [&](TRuntimeNode item) {
  352. return pb.Div(data2, item);
  353. });
  354. const auto graph = setup.BuildGraph(pgmReturn);
  355. const auto iterator = graph->GetValue().GetListIterator();
  356. NUdf::TUnboxedValue item;
  357. UNIT_ASSERT(iterator.Next(item));
  358. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
  359. UNIT_ASSERT(iterator.Next(item));
  360. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1);
  361. UNIT_ASSERT(!iterator.Next(item));
  362. UNIT_ASSERT(!iterator.Next(item));
  363. }
  364. Y_UNIT_TEST_LLVM(TestOverListAndDoubleOptionals) {
  365. TSetup<LLVM> setup;
  366. TProgramBuilder& pb = *setup.PgmBuilder;
  367. const auto data0 = pb.NewDataLiteral<ui32>(0);
  368. const auto data1 = pb.NewDataLiteral<ui32>(1);
  369. const auto data2 = pb.NewDataLiteral<ui32>(2);
  370. const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
  371. const auto list = pb.NewList(dataType, {data0, data1, data2});
  372. const auto pgmReturn = pb.FlatMap(list,
  373. [&](TRuntimeNode item) {
  374. return pb.NewOptional(pb.Div(data2, item));
  375. });
  376. const auto graph = setup.BuildGraph(pgmReturn);
  377. const auto iterator = graph->GetValue().GetListIterator();
  378. NUdf::TUnboxedValue item;
  379. UNIT_ASSERT(iterator.Next(item));
  380. UNIT_ASSERT(!item);
  381. UNIT_ASSERT(iterator.Next(item));
  382. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
  383. UNIT_ASSERT(iterator.Next(item));
  384. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1);
  385. UNIT_ASSERT(!iterator.Next(item));
  386. UNIT_ASSERT(!iterator.Next(item));
  387. }
  388. Y_UNIT_TEST_LLVM(TestOverOptionalAndPartialOptionals) {
  389. TSetup<LLVM> setup;
  390. TProgramBuilder& pb = *setup.PgmBuilder;
  391. const auto data2 = pb.NewDataLiteral<ui32>(2);
  392. const auto list = pb.NewOptional(data2);
  393. const auto pgmReturn = pb.FlatMap(list,
  394. [&](TRuntimeNode item) {
  395. return pb.Div(item, data2);
  396. });
  397. const auto graph = setup.BuildGraph(pgmReturn);
  398. const auto value = graph->GetValue();
  399. UNIT_ASSERT(value);
  400. UNIT_ASSERT_VALUES_EQUAL(value.template Get<ui32>(), 1);
  401. }
  402. Y_UNIT_TEST_LLVM(TestOverOptionalAndPartialLists) {
  403. TSetup<LLVM> setup;
  404. TProgramBuilder& pb = *setup.PgmBuilder;
  405. const auto data1 = pb.NewDataLiteral<ui32>(1);
  406. const auto data2 = pb.NewDataLiteral<ui32>(2);
  407. const auto list = pb.NewOptional(data2);
  408. const auto pgmReturn = pb.FlatMap(list,
  409. [&](TRuntimeNode item) {
  410. return pb.Append(pb.AsList(item), data1);
  411. });
  412. const auto graph = setup.BuildGraph(pgmReturn);
  413. const auto iterator = graph->GetValue().GetListIterator();
  414. NUdf::TUnboxedValue item;
  415. UNIT_ASSERT(iterator.Next(item));
  416. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
  417. UNIT_ASSERT(iterator.Next(item));
  418. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1);
  419. UNIT_ASSERT(!iterator.Next(item));
  420. UNIT_ASSERT(!iterator.Next(item));
  421. }
  422. Y_UNIT_TEST_LLVM(TestOverListAndPartialListsLazy) {
  423. TSetup<LLVM> setup;
  424. TProgramBuilder& pb = *setup.PgmBuilder;
  425. const auto data1 = pb.NewDataLiteral<ui32>(1U);
  426. const auto data2 = pb.NewDataLiteral<ui32>(2U);
  427. const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
  428. const auto list = pb.NewList(dataType, {data1, data2});
  429. const auto pgmReturn = pb.FlatMap(pb.LazyList(list),
  430. [&](TRuntimeNode item) {
  431. return pb.NewList(dataType, {pb.Add(item, data1), pb.Mul(item, data2)});
  432. });
  433. const auto graph = setup.BuildGraph(pgmReturn);
  434. const auto iterator = graph->GetValue().GetListIterator();
  435. NUdf::TUnboxedValue item;
  436. UNIT_ASSERT(iterator.Next(item));
  437. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
  438. UNIT_ASSERT(iterator.Next(item));
  439. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 2);
  440. UNIT_ASSERT(iterator.Next(item));
  441. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 3);
  442. UNIT_ASSERT(iterator.Next(item));
  443. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 4);
  444. UNIT_ASSERT(!iterator.Next(item));
  445. UNIT_ASSERT(!iterator.Next(item));
  446. }
  447. Y_UNIT_TEST_LLVM(TestOverListAndPartialOptionalsLazy) {
  448. TSetup<LLVM> setup;
  449. TProgramBuilder& pb = *setup.PgmBuilder;
  450. const auto data0 = pb.NewDataLiteral<ui32>(0U);
  451. const auto data2 = pb.NewDataLiteral<ui32>(2U);
  452. const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
  453. const auto list = pb.NewList(dataType, {data0, data2});
  454. const auto pgmReturn = pb.FlatMap(pb.LazyList(list),
  455. [&](TRuntimeNode item) { return pb.Div(data2, item); }
  456. );
  457. const auto graph = setup.BuildGraph(pgmReturn);
  458. const auto iterator = graph->GetValue().GetListIterator();
  459. NUdf::TUnboxedValue item;
  460. UNIT_ASSERT(iterator.Next(item));
  461. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1);
  462. UNIT_ASSERT(!iterator.Next(item));
  463. UNIT_ASSERT(!iterator.Next(item));
  464. }
  465. #if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
  466. Y_UNIT_TEST_LLVM(TestNarrowWithList) {
  467. TSetup<LLVM> setup;
  468. TProgramBuilder& pb = *setup.PgmBuilder;
  469. const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
  470. const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
  471. const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
  472. const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
  473. const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
  474. const auto list = pb.NewList(tupleType, {data1, data2, data3});
  475. const auto pgmReturn = pb.Collect(pb.NarrowFlatMap(pb.ExpandMap(pb.ToFlow(list),
  476. [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U),pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
  477. [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.FlatMap(pb.NewList(dataType, items), [](TRuntimeNode item){ return item; }); }
  478. ));
  479. const auto graph = setup.BuildGraph(pgmReturn);
  480. const auto iterator = graph->GetValue().GetListIterator();
  481. NUdf::TUnboxedValue item;
  482. UNIT_ASSERT(iterator.Next(item));
  483. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 1);
  484. UNIT_ASSERT(iterator.Next(item));
  485. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
  486. UNIT_ASSERT(iterator.Next(item));
  487. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 2);
  488. UNIT_ASSERT(iterator.Next(item));
  489. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -2);
  490. UNIT_ASSERT(iterator.Next(item));
  491. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 3);
  492. UNIT_ASSERT(iterator.Next(item));
  493. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -3);
  494. UNIT_ASSERT(!iterator.Next(item));
  495. UNIT_ASSERT(!iterator.Next(item));
  496. }
  497. Y_UNIT_TEST_LLVM(TestNarrowWithFlow) {
  498. TSetup<LLVM> setup;
  499. TProgramBuilder& pb = *setup.PgmBuilder;
  500. const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
  501. const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
  502. const auto data1 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
  503. const auto data2 = pb.NewTuple(tupleType, {pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(2)), pb.NewOptional(pb.NewDataLiteral<i32>(-2))});
  504. const auto data3 = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(3)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-3))});
  505. const auto list = pb.NewList(tupleType, {data1, data2, data3});
  506. const auto pgmReturn = pb.Collect(pb.NarrowFlatMap(pb.ExpandMap(pb.ToFlow(list),
  507. [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U),pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
  508. [&](TRuntimeNode::TList items) -> TRuntimeNode { return pb.FlatMap(pb.ToFlow(pb.NewList(dataType, items)), [](TRuntimeNode item){ return item; }); }
  509. ));
  510. const auto graph = setup.BuildGraph(pgmReturn);
  511. const auto iterator = graph->GetValue().GetListIterator();
  512. NUdf::TUnboxedValue item;
  513. UNIT_ASSERT(iterator.Next(item));
  514. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 1);
  515. UNIT_ASSERT(iterator.Next(item));
  516. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
  517. UNIT_ASSERT(iterator.Next(item));
  518. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 2);
  519. UNIT_ASSERT(iterator.Next(item));
  520. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -2);
  521. UNIT_ASSERT(iterator.Next(item));
  522. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 3);
  523. UNIT_ASSERT(iterator.Next(item));
  524. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -3);
  525. UNIT_ASSERT(!iterator.Next(item));
  526. UNIT_ASSERT(!iterator.Next(item));
  527. }
  528. Y_UNIT_TEST_LLVM(TestNarrowWithIndependentFlow) {
  529. TSetup<LLVM> setup;
  530. TProgramBuilder& pb = *setup.PgmBuilder;
  531. const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<i32>::Id));
  532. const auto tupleType = pb.NewTupleType({dataType, dataType, dataType});
  533. const auto data = pb.NewTuple(tupleType, {pb.NewOptional(pb.NewDataLiteral<i32>(1)), pb.NewEmptyOptional(dataType), pb.NewOptional(pb.NewDataLiteral<i32>(-1))});
  534. const auto list = pb.NewList(tupleType, {data, data, data});
  535. const auto pgmReturn = pb.Collect(pb.NarrowFlatMap(pb.ExpandMap(pb.ToFlow(list),
  536. [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U),pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
  537. [&](TRuntimeNode::TList) { return pb.Map(
  538. pb.ToFlow(pb.NewList(pb.NewDataType(NUdf::TDataType<float>::Id), {pb.NewDataLiteral<float>(+1.f), pb.NewDataLiteral<float>(-1.f)})),
  539. [&](TRuntimeNode item) { return pb.Minus(item); }); }
  540. ));
  541. const auto graph = setup.BuildGraph(pgmReturn);
  542. const auto iterator = graph->GetValue().GetListIterator();
  543. NUdf::TUnboxedValue item;
  544. UNIT_ASSERT(iterator.Next(item));
  545. UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -1.f);
  546. UNIT_ASSERT(iterator.Next(item));
  547. UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), +1.f);
  548. UNIT_ASSERT(iterator.Next(item));
  549. UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -1.f);
  550. UNIT_ASSERT(iterator.Next(item));
  551. UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), +1.f);
  552. UNIT_ASSERT(iterator.Next(item));
  553. UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), -1.f);
  554. UNIT_ASSERT(iterator.Next(item));
  555. UNIT_ASSERT_VALUES_EQUAL(item.template Get<float>(), +1.f);
  556. UNIT_ASSERT(!iterator.Next(item));
  557. UNIT_ASSERT(!iterator.Next(item));
  558. }
  559. Y_UNIT_TEST_LLVM(TestThinNarrowWithList) {
  560. TSetup<LLVM> setup;
  561. TProgramBuilder& pb = *setup.PgmBuilder;
  562. const auto tupleType = pb.NewTupleType({});
  563. const auto data = pb.NewTuple(tupleType, {});
  564. const auto list = pb.NewList(tupleType, {data, data, data});
  565. const auto pgmReturn = pb.Collect(pb.NarrowFlatMap(pb.ExpandMap(pb.ToFlow(list),
  566. [&](TRuntimeNode) -> TRuntimeNode::TList { return {}; }),
  567. [&](TRuntimeNode::TList) -> TRuntimeNode { return pb.Replicate(pb.NewDataLiteral<i32>(7), pb.NewDataLiteral<ui64>(3), __FILE__, __LINE__, 0); }
  568. ));
  569. const auto graph = setup.BuildGraph(pgmReturn);
  570. const auto iterator = graph->GetValue().GetListIterator();
  571. NUdf::TUnboxedValue item;
  572. UNIT_ASSERT(iterator.Next(item));
  573. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
  574. UNIT_ASSERT(iterator.Next(item));
  575. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
  576. UNIT_ASSERT(iterator.Next(item));
  577. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
  578. UNIT_ASSERT(iterator.Next(item));
  579. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
  580. UNIT_ASSERT(iterator.Next(item));
  581. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
  582. UNIT_ASSERT(iterator.Next(item));
  583. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
  584. UNIT_ASSERT(iterator.Next(item));
  585. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
  586. UNIT_ASSERT(iterator.Next(item));
  587. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
  588. UNIT_ASSERT(iterator.Next(item));
  589. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
  590. UNIT_ASSERT(!iterator.Next(item));
  591. UNIT_ASSERT(!iterator.Next(item));
  592. }
  593. Y_UNIT_TEST_LLVM(TestOverFlowAndWideFlows) {
  594. TSetup<LLVM> setup;
  595. TProgramBuilder& pb = *setup.PgmBuilder;
  596. const auto data = pb.NewDataLiteral<i32>(-100);
  597. const auto data0 = pb.NewDataLiteral<i32>(0);
  598. const auto data1 = pb.NewDataLiteral<i32>(3);
  599. const auto data2 = pb.NewDataLiteral<i32>(7);
  600. const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
  601. const auto list = pb.NewList(dataType, {data0, data1, data2});
  602. const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.FlatMap(pb.ToFlow(list),
  603. [&](TRuntimeNode item) {
  604. return pb.ExpandMap(pb.ToFlow(pb.NewList(pb.NewOptionalType(dataType),
  605. {pb.Mod(data, item), pb.Div(data, item)})),
  606. [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Plus(item), pb.Minus(item)}; });
  607. }),
  608. [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
  609. ));
  610. const auto graph = setup.BuildGraph(pgmReturn);
  611. const auto iterator = graph->GetValue();
  612. NUdf::TUnboxedValue item;
  613. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  614. UNIT_ASSERT(!item.GetElement(0));
  615. UNIT_ASSERT(!item.GetElement(1));
  616. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  617. UNIT_ASSERT(!item.GetElement(0));
  618. UNIT_ASSERT(!item.GetElement(1));
  619. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  620. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -1);
  621. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +1);
  622. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  623. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -33);
  624. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +33);
  625. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  626. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -2);
  627. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +2);
  628. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  629. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -14);
  630. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +14);
  631. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  632. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  633. }
  634. Y_UNIT_TEST_LLVM(TestOverListAndWideFlows) {
  635. TSetup<LLVM> setup;
  636. TProgramBuilder& pb = *setup.PgmBuilder;
  637. const auto data = pb.NewDataLiteral<i32>(-100);
  638. const auto data0 = pb.NewDataLiteral<i32>(0);
  639. const auto data1 = pb.NewDataLiteral<i32>(3);
  640. const auto data2 = pb.NewDataLiteral<i32>(7);
  641. const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
  642. const auto list = pb.NewList(dataType, {data0, data1, data2});
  643. const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.FlatMap(list,
  644. [&](TRuntimeNode item) {
  645. return pb.ExpandMap(pb.ToFlow(pb.NewList(pb.NewOptionalType(dataType),
  646. {pb.Mod(data, item), pb.Div(data, item)})),
  647. [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Minus(item), pb.Plus(item)}; });
  648. }),
  649. [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
  650. ));
  651. const auto graph = setup.BuildGraph(pgmReturn);
  652. const auto iterator = graph->GetValue();
  653. NUdf::TUnboxedValue item;
  654. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  655. UNIT_ASSERT(!item.GetElement(0));
  656. UNIT_ASSERT(!item.GetElement(1));
  657. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  658. UNIT_ASSERT(!item.GetElement(0));
  659. UNIT_ASSERT(!item.GetElement(1));
  660. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  661. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +1);
  662. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -1);
  663. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  664. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +33);
  665. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -33);
  666. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  667. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +2);
  668. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -2);
  669. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  670. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +14);
  671. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -14);
  672. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  673. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  674. }
  675. Y_UNIT_TEST_LLVM(TestOverFlowAndIndependentWideFlows) {
  676. TSetup<LLVM> setup;
  677. TProgramBuilder& pb = *setup.PgmBuilder;
  678. const auto data = pb.NewDataLiteral<i32>(-100);
  679. const auto data0 = pb.NewDataLiteral<i32>(0);
  680. const auto data1 = pb.NewDataLiteral<i32>(3);
  681. const auto data2 = pb.NewDataLiteral<i32>(7);
  682. const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
  683. const auto list = pb.NewList(dataType, {data0, data1, data2});
  684. const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.FlatMap(pb.ToFlow(list),
  685. [&](TRuntimeNode) {
  686. return pb.ExpandMap(pb.ToFlow(pb.NewList(dataType, {data, data})),
  687. [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Plus(item), pb.Minus(item)}; });
  688. }),
  689. [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
  690. ));
  691. const auto graph = setup.BuildGraph(pgmReturn);
  692. const auto iterator = graph->GetValue();
  693. NUdf::TUnboxedValue item;
  694. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  695. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -100);
  696. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +100);
  697. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  698. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -100);
  699. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +100);
  700. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  701. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -100);
  702. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +100);
  703. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  704. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -100);
  705. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +100);
  706. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  707. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -100);
  708. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +100);
  709. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  710. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -100);
  711. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), +100);
  712. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  713. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  714. }
  715. Y_UNIT_TEST_LLVM(TestOverListAndIndependentWideFlows) {
  716. TSetup<LLVM> setup;
  717. TProgramBuilder& pb = *setup.PgmBuilder;
  718. const auto data = pb.NewDataLiteral<i32>(-100);
  719. const auto data0 = pb.NewDataLiteral<i32>(0);
  720. const auto data1 = pb.NewDataLiteral<i32>(3);
  721. const auto data2 = pb.NewDataLiteral<i32>(7);
  722. const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
  723. const auto list = pb.NewList(dataType, {data0, data1, data2});
  724. const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.FlatMap(list,
  725. [&](TRuntimeNode) {
  726. return pb.ExpandMap(pb.ToFlow(pb.NewList(dataType, {data, data})),
  727. [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Minus(item), pb.Plus(item)}; });
  728. }),
  729. [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
  730. ));
  731. const auto graph = setup.BuildGraph(pgmReturn);
  732. const auto iterator = graph->GetValue();
  733. NUdf::TUnboxedValue item;
  734. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  735. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +100);
  736. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -100);
  737. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  738. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +100);
  739. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -100);
  740. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  741. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +100);
  742. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -100);
  743. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  744. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +100);
  745. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -100);
  746. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  747. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +100);
  748. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -100);
  749. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  750. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), +100);
  751. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<i32>(), -100);
  752. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  753. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  754. }
  755. #endif
  756. }
  757. }
  758. }