123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- // -*- mode: c++; coding: utf-8 -*-
- /// @file old.H
- /// @brief Bits and pieces that aren't used but that I still want to test.
- // (c) Daniel Llorens - 2019
- // This library is free software; you can redistribute it and/or modify it under
- // the terms of the GNU Lesser General Public License as published by the Free
- // Software Foundation; either version 3 of the License, or (at your option) any
- // later version.
- // Eventually move this to test/.
- #pragma once
- #include "ra/ply.H"
- #define CHECK_BOUNDS( cond ) RA_ASSERT( cond, 0 )
- namespace ra {
- // 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).
- // OldTensorIndex is a prototype of such a T.
- template <class X> constexpr bool by_index_def = false;
- template <class T> constexpr bool by_index = by_index_def<std::decay_t<T>>;
- template <class Op, class ... Ti, class K>
- constexpr bool by_index_def<Expr<Op, std::tuple<Ti ...>, K>> = (by_index<Ti> || ...);
- template <class ... Ti, class K>
- constexpr bool by_index_def<Pick<std::tuple<Ti ...>, K>> = (by_index<Ti> || ...);
- template <class LiveAxes, int depth, class A>
- constexpr bool by_index_def<ApplyFrames<LiveAxes, depth, A>> = by_index<A>;
- template <class FM, class Op, class ... Ti, class K>
- constexpr bool by_index_def<Ryn<FM, Op, std::tuple<Ti ...>, K>> = (by_index<Ti> || ...);
- // value_type may be needed to avoid conversion issues.
- template <int w_, class value_type=ra::dim_t>
- struct OldTensorIndex
- {
- static_assert(w_>=0, "bad OldTensorIndex");
- constexpr static int w = w_;
- constexpr static dim_t size(int k) { return DIM_BAD; } // used in shape checks with dyn. rank.
- constexpr static dim_t size_s() { return DIM_BAD; }
- constexpr static rank_t rank_s() { return w+1; }
- constexpr static rank_t rank() { return w+1; }
- constexpr static dim_t size_s(int k) { CHECK_BOUNDS(k<=w); return DIM_BAD; }
- template <class I> constexpr static value_type at(I const & i) { return value_type(i[w]); }
- constexpr static dim_t stride(int k) { assert(0); return 0; } // used by Expr::stride_t.
- constexpr static value_type * flat() { assert(0); return nullptr; } // used by type signatures.
- };
- template <int w, class value_type> constexpr bool by_index_def<OldTensorIndex<w, value_type>> = true;
- // --------------
- // Alternative to ply_ravel for Iterators that have at() instead of flat()/etc (e.g. OldTensorIndex).
- // --------------
- // This doesn't unravel and carries the indices whether they are used or not, so ply_ravel should generally be faster.
- // It was used as alternate to ply_ravel before TensorIndex replaced OldTensorIndex.
- // TODO See ply_ravel() for traversal order.
- // TODO A(i0, i1 ...) could be partial-applied as A(i0)(i1 ...) for faster indexing
- // TODO Traversal order should be a parameter, since some operations (e.g. output, ravel) require a specific order.
- template <class A> inline
- void ply_index(A && a)
- {
- rank_t const rank = a.rank();
- auto ind = with_same_shape(ra::shape(a), 0);
- dim_t sha[rank];
- rank_t order[rank];
- for (rank_t k=0; k<rank; ++k) {
- order[k] = rank-1-k;
- sha[k] = a.size(order[k]);
- if (sha[k]==0) {
- return;
- }
- }
- for (;;) {
- a.at(ind);
- for (int k=0; ; ++k) {
- if (k==rank) {
- return;
- } else if (++ind[order[k]]<sha[k]) {
- break;
- } else {
- ind[order[k]] = 0;
- }
- }
- }
- }
- // -------------------------
- // Compile time order; alt. to plyf for by_index. See bench-dot.C for use. Index version.
- // -------------------------
- template <class order, class A, class S>
- inline void
- subindexf(A & a, S & i_)
- {
- if constexpr (mp::len<order> == 0) {
- a.at(i_);
- } else if constexpr (mp::len<order> > 0) {
- dim_t & i = i_[mp::first<order>::value];
- // on every subloop, but not worth caching
- dim_t const /* constexpr */ s = a.size(mp::first<order>::value);
- for (i=0; i<s; ++i) {
- subindexf<mp::drop1<order>>(a, i_);
- }
- } else {
- abort();
- }
- }
- template <class A> inline
- void plyf_index(A && a)
- {
- auto i = with_same_shape(ra::shape(a), 0);
- subindexf<mp::iota<std::decay_t<A>::rank_s()>>(a, i); // cf with ply_index() for C order.
- }
- } // namespace ra
|