ra-0.cc 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820
  1. // -*- mode: c++; coding: utf-8 -*-
  2. /// @file ra-0.cc
  3. /// @brief Checks for ra:: arrays, iterators.
  4. // (c) Daniel Llorens - 2013-2015
  5. // This library is free software; you can redistribute it and/or modify it under
  6. // the terms of the GNU Lesser General Public License as published by the Free
  7. // Software Foundation; either version 3 of the License, or (at your option) any
  8. // later version.
  9. #include <iostream>
  10. #include <iterator>
  11. #include <numeric>
  12. #include "ra/test.hh"
  13. #include "ra/ra.hh"
  14. #include "ra/mpdebug.hh"
  15. using std::cout, std::endl, std::flush, ra::TestRecorder;
  16. template <int i> using TI = ra::TensorIndex<i, int>;
  17. template <class A>
  18. void CheckArrayOutput(TestRecorder & tr, A const & a, double * begin)
  19. {
  20. std::ostringstream o;
  21. o << a;
  22. cout << "a: " << o.str() << endl;
  23. std::istringstream i(o.str());
  24. std::istream_iterator<double> iend;
  25. std::istream_iterator<double> ibegin(i);
  26. tr.test(std::equal(ibegin, iend, begin));
  27. }
  28. template <class A>
  29. void CheckArrayIO(TestRecorder & tr, A const & a, double * begin)
  30. {
  31. std::ostringstream o;
  32. o << a;
  33. {
  34. std::istringstream i(o.str());
  35. std::istream_iterator<double> iend;
  36. std::istream_iterator<double> ibegin(i);
  37. tr.info("reading back from '", o.str(), "'").test(std::equal(ibegin, iend, begin));
  38. }
  39. {
  40. std::istringstream i(o.str());
  41. A b;
  42. tr.test(bool(i));
  43. i >> b;
  44. auto as = ra::shape(a);
  45. auto bs = ra::shape(b);
  46. tr.info("shape from '", o.str(), "'").test(std::equal(as.begin(), as.end(), bs.begin()));
  47. tr.info("content").test(std::equal(a.begin(), a.begin(), b.begin()));
  48. }
  49. }
  50. int main()
  51. {
  52. TestRecorder tr(std::cout);
  53. tr.section("concepts");
  54. {
  55. ra::Small<int, 2> a(0.), b(0.);
  56. auto e0 = ra::expr([](int a, int b) { return a+b; }, start(a), start(b));
  57. static_assert(std::is_literal_type_v<decltype(e0)>);
  58. auto e1 = ra::expr([](int a, int b) { return a+b; }, start(a), ra::scalar(0.));
  59. static_assert(std::is_literal_type_v<decltype(e1)>);
  60. auto e2 = ra::expr([](int a, int b) { return a+b; }, start(a), ra::iota(2));
  61. static_assert(std::is_literal_type_v<decltype(e2)>);
  62. }
  63. tr.section("internal fields");
  64. {
  65. {
  66. double aa[10];
  67. aa[0] = 99;
  68. ra::View<double *, 1> a { {{10, 1}}, aa }; // [ra36] FIXME [ra28]
  69. tr.test_eq(99., a.p[0]);
  70. }
  71. {
  72. double aa[6] = { 1, 2, 3, 4, 5, 6 };
  73. aa[0] = 99;
  74. ra::View<double *, 2> a { { {3, 2}, {2, 1}}, aa }; // FIXME [ra28]
  75. tr.test_eq(4., a(1, 1));
  76. tr.test_eq(99., a.p[0]);
  77. }
  78. {
  79. double aa[20];
  80. aa[19] = 77;
  81. ra::View<double *> a = { {{10, 2}, {2, 1}}, aa }; // FIXME [ra28]
  82. tr.test_eq(10, a.dim[0].size);
  83. tr.test_eq(2, a.dim[1].size);
  84. cout << "a.p(3, 4): " << a.p[19] << endl;
  85. tr.test_eq(77, a.p[19]);
  86. }
  87. {
  88. auto pp = std::unique_ptr<double []>(new double[10]);
  89. pp[9] = 77;
  90. double * p = pp.get();
  91. ra::Unique<double> a {};
  92. a.store = std::move(pp);
  93. a.view().p = p;
  94. a.view().dim = {{5, 2}, {2, 1}};
  95. tr.test_eq(5, a.view().dim[0].size);
  96. tr.test_eq(2, a.view().dim[1].size);
  97. cout << "a.view().p(3, 4): " << a.view().p[9] << endl;
  98. tr.test_eq(77, a.view().p[9]);
  99. }
  100. {
  101. auto pp = std::shared_ptr<double>(new double[10]);
  102. pp.get()[9] = 88;
  103. double * p = pp.get();
  104. ra::Shared<double> a {};
  105. a.store = pp;
  106. a.view().p = p;
  107. a.view().dim = {{5, 2}, {2, 1}};
  108. tr.test_eq(5, a.view().dim[0].size);
  109. tr.test_eq(2, a.view().dim[1].size);
  110. cout << "a.view().p(3, 4): " << a.view().p[9] << endl;
  111. tr.test_eq(88, a.view().p[9]);
  112. }
  113. {
  114. decltype(std::declval<ra::Big<double>>().store) pp(10);
  115. pp[9] = 99;
  116. double * p = pp.data();
  117. ra::Big<double> a {};
  118. a.store = pp;
  119. a.view().p = p;
  120. a.view().dim = {{5, 2}, {2, 1}};
  121. tr.test_eq(5, a.view().dim[0].size);
  122. tr.test_eq(2, a.view().dim[1].size);
  123. cout << "a.p(3, 4): " << a.view().p[9] << endl;
  124. tr.test_eq(99, a.view().p[9]);
  125. }
  126. }
  127. tr.section("rank 0 -> scalar with Small");
  128. {
  129. auto rank0test0 = [](double & a) { a *= 2; };
  130. auto rank0test1 = [](double const & a) { return a*2; };
  131. ra::Small<double> a { 33 };
  132. static_assert(sizeof(a)==sizeof(double), "bad assumption");
  133. rank0test0(a);
  134. tr.test_eq(66, a);
  135. double b = rank0test1(a);
  136. tr.test_eq(66, a);
  137. tr.test_eq(132, b);
  138. }
  139. tr.section("(170) rank 0 -> scalar with View");
  140. {
  141. auto rank0test0 = [](double & a) { a *= 2; };
  142. auto rank0test1 = [](double const & a) { return a*2; };
  143. double x { 99 };
  144. ra::View<double *, 0> a { {}, &x }; // FIXME [ra28]
  145. tr.test_eq(1, a.size());
  146. // ra::View<T *, 0> contains T * plus the dope vector of type Small<Dim, 0>. But after I put the data of Small in Small itself instead of in SmallBase, sizeof(Small<T, 0>) is no longer 0. That was specific of gcc, so better not to depend on it anyway...
  147. cout << "a()" << a() << endl;
  148. cout << "sizeof(a())" << sizeof(a()) << endl;
  149. cout << "sizeof(double *)" << sizeof(double *) << endl;
  150. // static_assert(sizeof(a())==sizeof(double *), "bad assumption");
  151. rank0test0(a);
  152. tr.test_eq(198, a);
  153. double b = rank0test1(a);
  154. tr.test_eq(198, a);
  155. tr.test_eq(396, b);
  156. }
  157. tr.section("rank 0 and rank 1 constructors with RANK_ANY");
  158. {
  159. ra::Big<int> x {9};
  160. tr.test_eq(9, x(0));
  161. tr.test_eq(1, x.size());
  162. tr.test_eq(1, x.size(0));
  163. tr.test_eq(1, x.rank());
  164. ra::Big<int> y = 9;
  165. tr.test_eq(9, y());
  166. tr.test_eq(1, y.size());
  167. tr.test_eq(0, y.rank());
  168. // // FIXME ra::Big<int> x {} is WHO NOSE territory, but should probably be rank 1, size 0
  169. // ra::Big<int> z {};
  170. // tr.test_eq(0, z.size());
  171. // tr.test_eq(1, z.rank());
  172. }
  173. tr.section("generic container functions");
  174. {
  175. {
  176. using double2x3 = ra::Small<double, 2, 3>;
  177. double2x3 r { 1, 2, 3, 4, 5, 6 };
  178. tr.test_eq(2, rank(r));
  179. // Not sure why Koenig doesn't work here, might be library defect [ra10].
  180. tr.test_eq(6, ra::size(r));
  181. }
  182. {
  183. double pool[6] = { 1, 2, 3, 4, 5, 6 };
  184. ra::View<double *> r { {{3, 2}, {2, 1}}, pool }; // FIXME [ra28]
  185. tr.test_eq(2, rank(r));
  186. tr.test_eq(6, size(r));
  187. }
  188. {
  189. double pool[6] = { 1, 2, 3, 4, 5, 6 };
  190. ra::View<double *, 2> r {{ra::Dim {3, 2}, ra::Dim {2, 1}}, pool }; // FIXME [ra28]
  191. tr.test_eq(2, rank(r));
  192. tr.test_eq(6, size(r));
  193. }
  194. }
  195. tr.section("iterator for View (I)");
  196. {
  197. double chk[6] = { 0, 0, 0, 0, 0, 0 };
  198. double pool[6] = { 1, 2, 3, 4, 5, 6 };
  199. ra::View<double *> r { {{3, 2}, {2, 1}}, pool }; // FIXME [ra28]
  200. ra::cell_iterator<ra::View<double *>> it(r.dim, r.p); // FIXME [ra28]
  201. tr.test(r.data()==it.c.p);
  202. std::copy(r.begin(), r.end(), chk);
  203. tr.test(std::equal(pool, pool+6, r.begin()));
  204. }
  205. tr.section("iterator for View (II)");
  206. {
  207. double chk[6] = { 0, 0, 0, 0, 0, 0 };
  208. double pool[6] = { 1, 2, 3, 4, 5, 6 };
  209. ra::View<double *, 1> r { { ra::Dim {6, 1}}, pool }; // FIXME [ra28]
  210. ra::cell_iterator<ra::View<double *, 1>> it(r.dim, r.p); // FIXME [ra28]
  211. cout << "View<double *, 1> it.c.p: " << it.c.p << endl;
  212. std::copy(r.begin(), r.end(), chk);
  213. tr.test(std::equal(pool, pool+6, r.begin()));
  214. }
  215. // some of these tests are disabled depending on cell_iterator::operator=.
  216. tr.section("[ra11a] (skipped) cell_iterator operator= (from cell_iterator) does NOT copy contents");
  217. {
  218. double a[6] = { 0, 0, 0, 0, 0, 0 };
  219. double b[6] = { 1, 2, 3, 4, 5, 6 };
  220. ra::View<double *> ra { {{3, 2}, {2, 1}}, a }; // FIXME [ra28]
  221. ra::View<double *> rb { {{3, 2}, {2, 1}}, b }; // FIXME [ra28]
  222. auto aiter = ra.iter();
  223. {
  224. auto biter = rb.iter();
  225. aiter = biter;
  226. tr.skip().test_eq(0, ra);
  227. tr.skip().test_eq(rb, aiter);
  228. }
  229. {
  230. aiter = rb.iter();
  231. tr.skip().test_eq(0, ra);
  232. tr.skip().test_eq(rb, aiter);
  233. }
  234. }
  235. tr.section("[ra11b] cell_iterator operator= (from cell_iterator) DOES copy contents");
  236. {
  237. ra::Unique<double, 2> A({6, 7}, ra::_0 - ra::_1);
  238. ra::Unique<double, 2> AA({6, 7}, 0.);
  239. AA.iter<1>() = A.iter<1>();
  240. tr.test_eq(ra::_0 - ra::_1, AA);
  241. tr.test_eq(A, AA);
  242. }
  243. tr.section("[ra11b] cell_iterator operator= (from cell_iterator) DOES copy contents");
  244. {
  245. ra::Small<double, 6, 7> A = ra::_0 - ra::_1;
  246. ra::Small<double, 6, 7> AA = 0.;
  247. AA.iter<1>() = A.iter<1>();
  248. tr.test_eq(ra::_0 - ra::_1, AA);
  249. tr.test_eq(A, AA);
  250. }
  251. tr.section("[ra11c] STL-type iterators never copy contents");
  252. {
  253. double a[6] = { 0, 0, 0, 0, 0, 0 };
  254. double b[6] = { 1, 2, 3, 4, 5, 6 };
  255. ra::View<double *> ra { {{3, 2}, {2, 1}}, a }; // FIXME [ra28]
  256. ra::View<double *> rb { {{3, 2}, {2, 1}}, b }; // FIXME [ra28]
  257. auto aiter = ra.begin();
  258. {
  259. auto biter = rb.begin();
  260. aiter = biter;
  261. tr.test_eq(0, ra); // ra unchanged
  262. tr.test(std::equal(rb.begin(), rb.end(), aiter)); // aiter changed
  263. }
  264. {
  265. aiter = rb.begin();
  266. tr.test_eq(0, ra); // ra unchanged
  267. tr.test(std::equal(rb.begin(), rb.end(), aiter)); // aiter changed
  268. }
  269. }
  270. tr.section("shape of .iter()");
  271. {
  272. auto test = [&tr](auto && A)
  273. {
  274. tr.test_eq(ra::Small<ra::dim_t, 2> {6, 7}, ra::shape(A));
  275. tr.test_eq(ra::Small<ra::dim_t, 2> {6, 7}, shape(A.iter()));
  276. tr.test_eq(ra::Small<ra::dim_t, 2> {6, 7}, shape(iter<0>(A)));
  277. tr.test_eq(ra::Small<ra::dim_t, 2> {6, 7}, shape(iter<-2>(A)));
  278. tr.test_eq(ra::Small<ra::dim_t, 1> {6}, shape(iter<1>(A)));
  279. tr.test_eq(ra::Small<ra::dim_t, 1> {6}, shape(iter<-1>(A)));
  280. tr.test_eq(ra::Small<ra::dim_t, 0> {}, shape(iter<2>(A)));
  281. };
  282. test(ra::Unique<double, 2>({6, 7}, ra::_0 - ra::_1));
  283. test(ra::Unique<double>({6, 7}, ra::_0 - ra::_1));
  284. }
  285. tr.section("STL-type iterators");
  286. {
  287. double rpool[6] = { 1, 2, 3, 4, 5, 6 };
  288. ra::View<double *, 1> r { {ra::Dim {6, 1}}, rpool }; // FIXME [ra28]
  289. double spool[6] = { 0, 0, 0, 0, 0, 0 };
  290. ra::View<double *> s { {{3, 1}, {2, 3}}, spool }; // FIXME [ra28]
  291. std::copy(r.begin(), r.end(), s.begin());
  292. double cpool[6] = { 1, 3, 5, 2, 4, 6 };
  293. tr.test(std::equal(cpool, cpool+6, spool));
  294. }
  295. tr.section("storage types");
  296. {
  297. double pool[6] = { 1, 2, 3, 4, 5, 6 };
  298. ra::Shared<double> s({3, 2}, pool, pool+6);
  299. tr.test_eq(2, s.rank());
  300. tr.test(std::equal(pool, pool+6, s.begin()));
  301. ra::Unique<double> u({3, 2}, pool, pool+6);
  302. tr.test_eq(2, u.rank());
  303. tr.test(std::equal(pool, pool+6, u.begin()));
  304. ra::Big<double> o({3, 2}, pool, pool+6);
  305. tr.test_eq(2, o.rank());
  306. tr.test(std::equal(pool, pool+6, o.begin()));
  307. }
  308. tr.section("copy between arrays, construct from iterator pair");
  309. {
  310. // copy from Fortran order to C order.
  311. double rpool[6] = { 1, 2, 3, 4, 5, 6 };
  312. double check[6] = { 1, 4, 2, 5, 3, 6 };
  313. ra::View<double *> r { {{3, 1}, {2, 3}}, rpool }; // FIXME [ra28]
  314. std::copy(r.begin(), r.end(), std::ostream_iterator<double>(cout, " ")); cout << endl;
  315. tr.test(std::equal(check, check+6, r.begin()));
  316. ra::Unique<double> u({3, 2}, r.begin(), r.end());
  317. std::copy(u.begin(), u.end(), std::ostream_iterator<double>(cout, " ")); cout << endl;
  318. tr.test(std::equal(check, check+6, u.begin()));
  319. // Small strides are tested in test/small-0.cc, test/small-1.cc.
  320. ra::Small<double, 3, 2> s { 1, 4, 2, 5, 3, 6 };
  321. std::copy(s.begin(), s.end(), std::ostream_iterator<double>(cout, " ")); cout << endl;
  322. tr.test(std::equal(check, check+6, s.begin()));
  323. // construct Small from pointers / iterators. These still work by prefix match.
  324. // If you want row major fill, use std::copy() after construction.
  325. double rrcheck[6] = { 1, 1, 2, 2, 3, 3 };
  326. auto check_ptr
  327. = [&](auto && rr)
  328. {
  329. ra::Small<double, 3, 2> z(ra::ptr(rr));
  330. std::copy(z.begin(), z.end(), std::ostream_iterator<double>(cout, " ")); cout << endl;
  331. tr.test(std::equal(rrcheck, rrcheck+6, z.begin()));
  332. };
  333. {
  334. std::vector<double> rr { 1, 2, 3, 4, 5, 6 };
  335. check_ptr(rr.begin());
  336. }
  337. {
  338. double rr[6] { 1, 2, 3, 4, 5, 6 };
  339. check_ptr(rr);
  340. }
  341. {
  342. ra::Unique<double, 1> rr = { 1, 2, 3, 4, 5, 6 };
  343. check_ptr(rr.begin());
  344. }
  345. }
  346. // In this case, the View + shape provides the driver.
  347. tr.section("construct View from shape + driverless xpr");
  348. {
  349. {
  350. int checkb[6] = { 0, 0, 1, 1, 2, 2 };
  351. ra::Unique<int, 2> b({3, 2}, ra::_0);
  352. tr.test(std::equal(checkb, checkb+6, b.begin()));
  353. }
  354. // This requires the driverless xpr dyn(scalar, tensorindex) to be constructible.
  355. {
  356. int checkb[6] = { 3, 3, 4, 4, 5, 5 };
  357. ra::Unique<int, 2> b({3, 2}, ra::expr([](int a, int b) { return a+b; }, ra::scalar(3), start(ra::_0)));
  358. tr.test(std::equal(checkb, checkb+6, b.begin()));
  359. }
  360. {
  361. int checkb[6] = { 0, -1, 1, 0, 2, 1 };
  362. ra::Unique<int, 2> b({3, 2}, ra::expr([](int a, int b) { return a-b; }, start(ra::_0), start(ra::_1)));
  363. tr.test(std::equal(checkb, checkb+6, b.begin()));
  364. }
  365. // TODO Check this is an error (chosen driver is TI<2>, that can't drive) [ra42]
  366. // {
  367. // ra::Unique<int, 2> b({3, 2}, ra::expr([](int a, int b) { return a-b; }, ra::TI<2>, ra::TI<1>));
  368. // cout << b << endl;
  369. // }
  370. // TODO Could this be made to bomb at compile time? [ra42]
  371. // {
  372. // ra::Unique<int> b({3, 2}, ra::expr([](int a, int b) { return a-b; }, ra::TI<2>, ra::TI<1>));
  373. // cout << b << endl;
  374. // }
  375. }
  376. tr.section("construct View from shape + xpr");
  377. {
  378. double checka[6] = { 9, 9, 9, 9, 9, 9 };
  379. ra::Unique<double, 2> a({3, 2}, ra::scalar(9));
  380. tr.test(std::equal(checka, checka+6, a.begin()));
  381. double checkb[6] = { 11, 11, 22, 22, 33, 33 };
  382. ra::Unique<double, 2> b({3, 2}, ra::Small<double, 3> { 11, 22, 33 });
  383. tr.test(std::equal(checkb, checkb+6, b.begin()));
  384. }
  385. tr.section("construct Unique from Unique");
  386. {
  387. double check[6] = { 2, 3, 1, 4, 8, 9 };
  388. ra::Unique<double, 2> a({3, 2}, { 2, 3, 1, 4, 8, 9 });
  389. // ra::Unique<double, 2> b(a); // error; need temp
  390. ra::Unique<double, 2> c(ra::Unique<double, 2>({3, 2}, { 2, 3, 1, 4, 8, 9 })); // ok; from actual temp
  391. tr.test(std::equal(check, check+6, c.begin()));
  392. ra::Unique<double, 2> d(std::move(a)); // ok; from fake temp
  393. tr.test(std::equal(check, check+6, d.begin()));
  394. }
  395. tr.section("construct from xpr having its own shape");
  396. {
  397. ra::Unique<double, 0> a(ra::scalar(33));
  398. ra::Unique<double> b(ra::scalar(44));
  399. // b.rank() is runtime, so b()==44. and the whole assert argument become array xprs when operators.hh is included.
  400. tr.test_eq(0, b.rank());
  401. tr.test_eq(1, b.size());
  402. tr.test_eq(44, b());
  403. b = 55.;
  404. cout << "b: " << b << endl;
  405. // see above for b.rank().
  406. tr.test_eq(0, b.rank());
  407. tr.test_eq(1, b.size());
  408. tr.test_eq(55., b());
  409. }
  410. tr.section("rank 0 -> scalar with storage type");
  411. {
  412. auto rank0test0 = [](double & a) { a *= 2; };
  413. auto rank0test1 = [](double const & a) { return a*2; };
  414. ra::Unique<double, 0> a(ra::scalar(33));
  415. tr.test_eq(1, a.size());
  416. // See note in (170).
  417. // static_assert(sizeof(a())==sizeof(double *), "bad assumption");
  418. rank0test0(a);
  419. tr.test_eq(66, a);
  420. double b = rank0test1(a);
  421. tr.test_eq(66, a);
  422. tr.test_eq(132, b);
  423. }
  424. tr.section("rank 0 -> scalar with storage type, explicit size");
  425. {
  426. auto rank0test0 = [](double & a) { a *= 2; };
  427. auto rank0test1 = [](double const & a) { return a*2; };
  428. ra::Unique<double, 0> a({}, ra::scalar(33));
  429. tr.test_eq(1, a.size());
  430. // See note in (170).
  431. // static_assert(sizeof(a())==sizeof(double *), "bad assumption");
  432. rank0test0(a);
  433. tr.test_eq(66, a);
  434. double b = rank0test1(a);
  435. tr.test_eq(66, a);
  436. tr.test_eq(132, b);
  437. }
  438. tr.section("constructors from data in initializer_list");
  439. {
  440. double checka[6] = { 2, 3, 1, 4, 8, 9 };
  441. {
  442. ra::Unique<double, 2> a({2, 3}, { 2, 3, 1, 4, 8, 9 });
  443. tr.test_eq(2, a.view().dim[0].size);
  444. tr.test_eq(3, a.view().dim[1].size);
  445. tr.test(std::equal(a.begin(), a.end(), checka));
  446. }
  447. {
  448. ra::Unique<double> a { 2, 3, 1, 4, 8, 9 };
  449. tr.test_eq(6, a.size());
  450. tr.test_eq(1, a.rank());
  451. tr.test(std::equal(a.begin(), a.end(), checka));
  452. ra::Unique<double> b ({ 2, 3, 1, 4, 8, 9 });
  453. tr.test_eq(6, b.size());
  454. tr.test_eq(1, b.rank());
  455. tr.test(std::equal(b.begin(), b.end(), checka));
  456. }
  457. {
  458. ra::Unique<double, 1> a { 2, 3, 1, 4, 8, 9 };
  459. tr.test_eq(6, a.size());
  460. tr.test_eq(1, a.rank());
  461. tr.test(std::equal(a.begin(), a.end(), checka));
  462. ra::Unique<double, 1> b ({ 2, 3, 1, 4, 8, 9 });
  463. tr.test_eq(6, b.size());
  464. tr.test_eq(1, b.rank());
  465. tr.test(std::equal(b.begin(), b.end(), checka));
  466. }
  467. }
  468. tr.section("row-major assignment from initializer_list, rank 2");
  469. {
  470. ra::Unique<double, 2> a({3, 2}, ra::none);
  471. a = { 2, 3, 1, 4, 8, 9 };
  472. tr.test_eq(2, a(0, 0));
  473. tr.test_eq(3, a(0, 1));
  474. tr.test_eq(1, a(1, 0));
  475. tr.test_eq(4, a(1, 1));
  476. tr.test_eq(8, a(2, 0));
  477. tr.test_eq(9, a(2, 1));
  478. auto b = transpose({1, 0}, a);
  479. b = { 2, 3, 1, 4, 8, 9 };
  480. tr.test_eq(2, b(0, 0));
  481. tr.test_eq(3, b(0, 1));
  482. tr.test_eq(1, b(0, 2));
  483. tr.test_eq(4, b(1, 0));
  484. tr.test_eq(8, b(1, 1));
  485. tr.test_eq(9, b(1, 2));
  486. tr.test_eq(2, a(0, 0));
  487. tr.test_eq(4, a(0, 1));
  488. tr.test_eq(3, a(1, 0));
  489. tr.test_eq(8, a(1, 1));
  490. tr.test_eq(1, a(2, 0));
  491. tr.test_eq(9, a(2, 1));
  492. auto c = transpose({1, 0}, a);
  493. tr.test(a.data()==c.data()); // pointers are not ra::scalars. Dunno if this deserves fixing.
  494. tr.test_eq(a.size(0), c.size(1));
  495. tr.test_eq(a.size(1), c.size(0));
  496. tr.test_eq(b, c);
  497. }
  498. tr.section("row-major assignment from initializer_list, rank 1");
  499. {
  500. ra::Big<double, 1> a({5}, ra::none);
  501. a = { 2, 3, 1, 4, 8 };
  502. tr.test_eq(2, a(0));
  503. tr.test_eq(3, a(1));
  504. tr.test_eq(1, a(2));
  505. tr.test_eq(4, a(3));
  506. tr.test_eq(8, a(4));
  507. }
  508. tr.section("subscripts");
  509. {
  510. tr.section("View fixed rank == 0");
  511. {
  512. double x = 99;
  513. ra::View<double *, 0> y(ra::Small<int, 0>{}, &x); // FIXME [ra28]
  514. tr.test_eq(99, y());
  515. tr.test_eq(99, y);
  516. double u = 77.;
  517. ra::View<double *, 0> v(ra::Small<int, 0>{}, &u); // FIXME [ra28]
  518. y = v;
  519. tr.test_eq(77, u);
  520. tr.test_eq(77, v);
  521. tr.test_eq(77, x);
  522. tr.test_eq(77, y);
  523. }
  524. tr.section("View fixed rank > 0");
  525. {
  526. double rpool[6] = { 1, 2, 3, 4, 5, 6 };
  527. ra::View<double *, 2> r { {ra::Dim {3, 1}, ra::Dim {2, 3}}, rpool }; // FIXME [ra28]
  528. cout << "org" << endl;
  529. std::copy(r.begin(), r.end(), std::ostream_iterator<double>(cout, " ")); cout << endl;
  530. {
  531. double rcheck[6] = { 1, 4, 2, 5, 3, 6 };
  532. auto r0 = r();
  533. tr.test(std::equal(r0.begin(), r0.end(), rcheck));
  534. ra::Small<int, 0> i0 {};
  535. tr.info("ra::Small<int, 0> rank").test_eq(1, i0.rank());
  536. auto r0a = r.at(ra::Small<int, 0> {});
  537. tr.info("fix size").test(std::equal(r0a.begin(), r0a.end(), rcheck));
  538. auto r0b = r.at(ra::Big<int, 1> {});
  539. tr.info("fix rank").test(std::equal(r0b.begin(), r0b.end(), rcheck));
  540. auto r0c = r.at(0+ra::Big<int, 1> {});
  541. tr.info("fix rank expr").test(std::equal(r0c.begin(), r0c.end(), rcheck));
  542. auto r0d = r.at(0+ra::Big<int>({0}, {}));
  543. tr.info("r0d: [", r0d, "]").test(std::equal(r0d.begin(), r0d.end(), rcheck));
  544. }
  545. {
  546. double rcheck[2] = { 2, 5 };
  547. auto r1 = r(1);
  548. tr.test_eq(ra::ptr(rcheck), r1);
  549. auto r1a = r.at(ra::Small<int, 1> {1});
  550. tr.test_eq(ra::ptr(rcheck), r1a);
  551. auto r1b = r.at(ra::Big<int, 1> {1});
  552. tr.test_eq(ra::ptr(rcheck), r1b);
  553. auto r1c = r.at(0+ra::Big<int, 1> {1});
  554. tr.test_eq(ra::ptr(rcheck), r1c);
  555. auto r1d = r.at(0+ra::Big<int> {1});
  556. tr.test_eq(ra::ptr(rcheck), r1d);
  557. }
  558. {
  559. double rcheck[2] = { 5 };
  560. // Does r(1, 1) return rank 0, or a scalar directly?
  561. // std::copy(r2.begin(), r2.end(), std::ostream_iterator<double>(cout, " ")); cout << endl;
  562. // tr.test(std::equal(r2.begin(), r2.end(), rcheck));
  563. auto r2 = r(1, 1);
  564. tr.test_eq(5, r2);
  565. auto r2a = r.at(ra::Small<int, 2> {1, 1});
  566. tr.info("r2a 1)").test(std::equal(r2a.begin(), r2a.end(), rcheck));
  567. auto r2b = r.at(ra::Big<int, 1> {1, 1});
  568. tr.info("r2a 2)").test(std::equal(r2a.begin(), r2a.end(), rcheck));
  569. auto r2c = r.at(0+ra::Big<int, 1> {1, 1});
  570. tr.info("r2a 3)").test(std::equal(r2c.begin(), r2c.end(), rcheck));
  571. auto r2d = r.at(0+ra::Big<int> {1, 1});
  572. tr.info("r2a 4)").test(std::equal(r2d.begin(), r2d.end(), rcheck));
  573. }
  574. }
  575. // TODO Subscript a rank>1 array, multiple selectors, mixed beatable & unbeatable selectors.
  576. tr.section("View fixed rank, unbeatable subscripts");
  577. {
  578. ra::Unique<double, 1> a = {1, 2, 3, 4};
  579. ra::Unique<int, 1> i = {3, 1, 2};
  580. cout << a(i) << endl;
  581. ra::Unique<double, 1> ai = a(i);
  582. tr.test_eq(i.size(), ai.size());
  583. tr.test_eq(a[i[0]], ai[0]);
  584. tr.test_eq(a[i[1]], ai[1]);
  585. tr.test_eq(a[i[2]], ai[2]);
  586. a(i) = ra::Unique<double, 1> {7, 8, 9};
  587. cout << a << endl;
  588. tr.test_eq(4, a.size());
  589. tr.test_eq(1, a[0]);
  590. tr.test_eq(a[i[0]], 7);
  591. tr.test_eq(a[i[1]], 8);
  592. tr.test_eq(a[i[2]], 9);
  593. }
  594. tr.section("View var rank");
  595. {
  596. double rpool[6] = { 1, 2, 3, 4, 5, 6 };
  597. ra::View<double *> r { {ra::Dim {3, 1}, ra::Dim {2, 3}}, rpool }; // FIXME [ra28]
  598. tr.test_eq(2, r.rank());
  599. cout << "org" << endl;
  600. std::copy(r.begin(), r.end(), std::ostream_iterator<double>(cout, " ")); cout << endl;
  601. double rcheck0[6] = { 1, 4, 2, 5, 3, 6 };
  602. auto r0 = r();
  603. auto r0a = r.at(ra::Small<int, 0> {});
  604. tr.test_eq(2, r0a.rank());
  605. tr.test_eq(2, r0.rank());
  606. cout << "r0" << endl;
  607. std::copy(r0.begin(), r0.end(), std::ostream_iterator<double>(cout, " ")); cout << endl;
  608. tr.test(std::equal(r0.begin(), r0.end(), rcheck0));
  609. tr.test(std::equal(r0a.begin(), r0a.end(), rcheck0));
  610. double rcheck1[2] = { 2, 5 };
  611. auto r1 = r(1);
  612. auto r1a = r.at(ra::Small<int, 1> {1});
  613. tr.test_eq(1, r1a.rank());
  614. tr.test_eq(1, r1.rank());
  615. cout << "r1" << endl;
  616. std::copy(r1.begin(), r1.end(), std::ostream_iterator<double>(cout, " ")); cout << endl;
  617. tr.test(std::equal(r1.begin(), r1.end(), rcheck1));
  618. tr.test(std::equal(r1a.begin(), r1a.end(), rcheck1));
  619. double rcheck2[2] = { 5 };
  620. auto r2 = r(1, 1);
  621. auto r2a = r.at(ra::Small<int, 2> {1, 1});
  622. tr.test_eq(0, r2a.rank());
  623. cout << "r2" << endl;
  624. std::copy(r2.begin(), r2.end(), std::ostream_iterator<double>(cout, " ")); cout << endl;
  625. tr.test(std::equal(r2.begin(), r2.end(), rcheck2));
  626. tr.test(std::equal(r2a.begin(), r2a.end(), rcheck2));
  627. }
  628. // TODO Make sure that this is double & = 99, etc. and not View<double *, 0> = 99, etc.
  629. tr.section("assign to rank-0 result of subscript");
  630. {
  631. double check[6] = {99, 88, 77, 66, 55, 44};
  632. ra::Unique<double> a({2, 3}, 11.);
  633. a(0, 0) = 99; a(0, 1) = 88; a(0, 2) = 77;
  634. a(1, 0) = 66; a(1, 1) = 55; a(1, 2) = 44;
  635. std::copy(a.begin(), a.end(), std::ostream_iterator<double>(cout, " ")); cout << endl;
  636. tr.test(std::equal(check, check+6, a.begin()));
  637. }
  638. }
  639. tr.section("construct from shape");
  640. {
  641. ra::Unique<double> a(std::vector<ra::dim_t> {3, 2, 4}, ra::none);
  642. std::iota(a.begin(), a.end(), 0);
  643. auto sa = ra::shape(a);
  644. tr.test_eq(3, sa[0]);
  645. tr.test_eq(2, sa[1]);
  646. tr.test_eq(4, sa[2]);
  647. double check[24];
  648. std::iota(check, check+24, 0);
  649. tr.test(std::equal(check, check+24, a.begin()));
  650. }
  651. tr.section("I/O");
  652. {
  653. tr.section("1");
  654. {
  655. ra::Small<double, 3, 2> s { 1, 4, 2, 5, 3, 6 };
  656. double check[6] = { 1, 4, 2, 5, 3, 6 };
  657. CheckArrayIO(tr, s, check);
  658. }
  659. tr.section("2");
  660. {
  661. ra::Small<double, 3> s { 1, 4, 2 };
  662. double check[3] = { 1, 4, 2 };
  663. CheckArrayIO(tr, s, check);
  664. }
  665. tr.section("3");
  666. {
  667. ra::Small<double> s { 77 };
  668. double check[1] = { 77 };
  669. CheckArrayIO(tr, s, check);
  670. }
  671. tr.section("4. View<> can't allocate, so have no istream >>. Check output only.");
  672. {
  673. double rpool[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
  674. ra::View<double *, 3> r { {ra::Dim {2, 4}, ra::Dim {2, 2}, ra::Dim {2, 1}}, rpool }; // FIXME [ra28]
  675. double check[11] = { 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8 };
  676. CheckArrayOutput(tr, r, check);
  677. }
  678. tr.section("5");
  679. {
  680. double rpool[6] = { 1, 2, 3, 4, 5, 6 };
  681. ra::View<double *, 2> r { {ra::Dim {3, 1}, ra::Dim {2, 3}}, rpool }; // FIXME [ra28]
  682. double check[8] = { 3, 2, 1, 4, 2, 5, 3, 6 };
  683. CheckArrayOutput(tr, r, check);
  684. }
  685. tr.section("6");
  686. {
  687. double rpool[3] = { 1, 2, 3 };
  688. ra::View<double *, 1> r { {ra::Dim {3, 1}}, rpool }; // FIXME [ra28]
  689. double check[4] = { 3, 1, 2, 3 };
  690. CheckArrayOutput(tr, r, check);
  691. }
  692. tr.section("7");
  693. {
  694. double rpool[1] = { 88 };
  695. ra::View<double *, 0> r { {}, rpool }; // FIXME [ra28]
  696. double check[1] = { 88 };
  697. CheckArrayOutput(tr, r, check);
  698. tr.test_eq(1, r.size());
  699. // See note in (170).
  700. // static_assert(sizeof(r)==sizeof(double *), "bad assumption");
  701. tr.test_eq(88, r);
  702. }
  703. tr.section("8");
  704. {
  705. double rpool[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
  706. ra::View<double *> a { {ra::Dim {2, 4}, ra::Dim {2, 2}, ra::Dim {2, 1}}, rpool }; // FIXME [ra28]
  707. double check[12] = { 3, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8 };
  708. CheckArrayOutput(tr, a, check);
  709. // default strides.
  710. ra::View<double *> b { {2, 2, 2}, rpool }; // FIXME [ra28]
  711. CheckArrayOutput(tr, b, check);
  712. }
  713. tr.section("9");
  714. {
  715. ra::Unique<double, 3> a(std::vector<ra::dim_t> {3, 2, 4}, ra::none);
  716. std::iota(a.begin(), a.end(), 0);
  717. double check[3+24] = { 3, 2, 4 };
  718. std::iota(check+3, check+3+24, 0);
  719. CheckArrayIO(tr, a, check);
  720. }
  721. tr.section("10");
  722. {
  723. ra::Unique<double> a(std::vector<ra::dim_t> {3, 2, 4}, ra::none);
  724. std::iota(a.begin(), a.end(), 0);
  725. double check[4+24] = { 3, 3, 2, 4 };
  726. std::iota(check+4, check+4+24, 0);
  727. CheckArrayIO(tr, a, check);
  728. }
  729. }
  730. tr.section("ply - xpr types - Scalar");
  731. {
  732. {
  733. auto s = ra::scalar(7);
  734. cout << "s: " << s.c << endl;
  735. }
  736. {
  737. auto s = ra::scalar(ra::Small<int, 2> {11, 12});
  738. cout << "s: " << s.c << endl;
  739. }
  740. {
  741. ra::Unique<double> a(std::vector<ra::dim_t> {3, 2, 4}, ra::none);
  742. std::iota(a.begin(), a.end(), 0);
  743. auto s = ra::scalar(a);
  744. cout << "s: " << s.c << endl;
  745. }
  746. }
  747. tr.section("scalar as reference");
  748. {
  749. int a = 3;
  750. ra::scalar(a) += ra::Small<int, 3> {4, 5, 6};
  751. tr.test_eq(18, a);
  752. // beware: throws away 3+4,3+5, only 3+6 is left. [ma107]
  753. ra::scalar(a) = 3 + ra::Small<int, 3> {4, 5, 6};
  754. tr.test_eq(9, a);
  755. }
  756. tr.section("ra::iota");
  757. {
  758. static_assert(ra::RaIterator<decltype(ra::iota(10))>, "bad type pred for iota");
  759. tr.section("straight cases");
  760. {
  761. ra::Big<int, 1> a = ra::iota(4, 1);
  762. assert(a[0]==1 && a[1]==2 && a[2]==3 && a[3]==4);
  763. }
  764. tr.section("work with operators");
  765. {
  766. tr.test(every(ra::iota(4)==ra::Big<int, 1> {0, 1, 2, 3}));
  767. tr.test(every(ra::iota(4, 1)==ra::Big<int, 1> {1, 2, 3, 4}));
  768. tr.test(every(ra::iota(4, 1, 2)==ra::Big<int, 1> {1, 3, 5, 7}));
  769. }
  770. // TODO actually whether unroll is avoided depends on ply(), have a way to require it [ra03]
  771. tr.section("frame-matching, forbidding unroll");
  772. {
  773. ra::Big<int, 3> b ({3, 4, 2}, ra::none);
  774. transpose({0, 2, 1}, b) = ra::iota(3, 1);
  775. cout << b << endl;
  776. tr.test(every(b(0)==1));
  777. tr.test(every(b(1)==2));
  778. tr.test(every(b(2)==3));
  779. }
  780. {
  781. ra::Big<int, 3> b ({3, 4, 2}, ra::none);
  782. transpose<0, 2, 1>(b) = ra::iota(3, 1);
  783. cout << b << endl;
  784. tr.test(every(b(0)==1));
  785. tr.test(every(b(1)==2));
  786. tr.test(every(b(2)==3));
  787. }
  788. }
  789. return tr.summary();
  790. }