old.H 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // -*- mode: c++; coding: utf-8 -*-
  2. /// @file old.H
  3. /// @brief Bits and pieces that aren't used but that I still want to test.
  4. // (c) Daniel Llorens - 2019
  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. // Eventually move this to test/.
  10. #pragma once
  11. #include "ra/ply.H"
  12. #define CHECK_BOUNDS( cond ) RA_ASSERT( cond, 0 )
  13. namespace ra {
  14. // if by_index<T> is true, then T must be traversed by at() (as in ply_index) and not by flat() (as in ply_ravel).
  15. // OldTensorIndex is a prototype of such a T.
  16. template <class X> constexpr bool by_index_def = false;
  17. template <class T> constexpr bool by_index = by_index_def<std::decay_t<T>>;
  18. template <class Op, class ... Ti, class K>
  19. constexpr bool by_index_def<Expr<Op, std::tuple<Ti ...>, K>> = (by_index<Ti> || ...);
  20. template <class ... Ti, class K>
  21. constexpr bool by_index_def<Pick<std::tuple<Ti ...>, K>> = (by_index<Ti> || ...);
  22. template <class LiveAxes, int depth, class A>
  23. constexpr bool by_index_def<ApplyFrames<LiveAxes, depth, A>> = by_index<A>;
  24. template <class FM, class Op, class ... Ti, class K>
  25. constexpr bool by_index_def<Ryn<FM, Op, std::tuple<Ti ...>, K>> = (by_index<Ti> || ...);
  26. // value_type may be needed to avoid conversion issues.
  27. template <int w_, class value_type=ra::dim_t>
  28. struct OldTensorIndex
  29. {
  30. static_assert(w_>=0, "bad OldTensorIndex");
  31. constexpr static int w = w_;
  32. constexpr static dim_t size(int k) { return DIM_BAD; } // used in shape checks with dyn. rank.
  33. constexpr static dim_t size_s() { return DIM_BAD; }
  34. constexpr static rank_t rank_s() { return w+1; }
  35. constexpr static rank_t rank() { return w+1; }
  36. constexpr static dim_t size_s(int k) { CHECK_BOUNDS(k<=w); return DIM_BAD; }
  37. template <class I> constexpr static value_type at(I const & i) { return value_type(i[w]); }
  38. constexpr static dim_t stride(int k) { assert(0); return 0; } // used by Expr::stride_t.
  39. constexpr static value_type * flat() { assert(0); return nullptr; } // used by type signatures.
  40. };
  41. template <int w, class value_type> constexpr bool by_index_def<OldTensorIndex<w, value_type>> = true;
  42. // --------------
  43. // Alternative to ply_ravel for Iterators that have at() instead of flat()/etc (e.g. OldTensorIndex).
  44. // --------------
  45. // This doesn't unravel and carries the indices whether they are used or not, so ply_ravel should generally be faster.
  46. // It was used as alternate to ply_ravel before TensorIndex replaced OldTensorIndex.
  47. // TODO See ply_ravel() for traversal order.
  48. // TODO A(i0, i1 ...) could be partial-applied as A(i0)(i1 ...) for faster indexing
  49. // TODO Traversal order should be a parameter, since some operations (e.g. output, ravel) require a specific order.
  50. template <class A> inline
  51. void ply_index(A && a)
  52. {
  53. rank_t const rank = a.rank();
  54. auto ind = with_same_shape(ra::shape(a), 0);
  55. dim_t sha[rank];
  56. rank_t order[rank];
  57. for (rank_t k=0; k<rank; ++k) {
  58. order[k] = rank-1-k;
  59. sha[k] = a.size(order[k]);
  60. if (sha[k]==0) {
  61. return;
  62. }
  63. }
  64. for (;;) {
  65. a.at(ind);
  66. for (int k=0; ; ++k) {
  67. if (k==rank) {
  68. return;
  69. } else if (++ind[order[k]]<sha[k]) {
  70. break;
  71. } else {
  72. ind[order[k]] = 0;
  73. }
  74. }
  75. }
  76. }
  77. // -------------------------
  78. // Compile time order; alt. to plyf for by_index. See bench-dot.C for use. Index version.
  79. // -------------------------
  80. template <class order, class A, class S>
  81. inline void
  82. subindexf(A & a, S & i_)
  83. {
  84. if constexpr (mp::len<order> == 0) {
  85. a.at(i_);
  86. } else if constexpr (mp::len<order> > 0) {
  87. dim_t & i = i_[mp::first<order>::value];
  88. // on every subloop, but not worth caching
  89. dim_t const /* constexpr */ s = a.size(mp::first<order>::value);
  90. for (i=0; i<s; ++i) {
  91. subindexf<mp::drop1<order>>(a, i_);
  92. }
  93. } else {
  94. abort();
  95. }
  96. }
  97. template <class A> inline
  98. void plyf_index(A && a)
  99. {
  100. auto i = with_same_shape(ra::shape(a), 0);
  101. subindexf<mp::iota<std::decay_t<A>::rank_s()>>(a, i); // cf with ply_index() for C order.
  102. }
  103. } // namespace ra