2

I am writing some generic code that would process Eigen expression differently for those that hold continuous data in memory and those do not.

I know that at run time, this can be done by checking expr.innerSize() == expr.outerStride() && expr.innerStride() == 1 but I was wondering if this could be done at compile time?

== Edit == The purpose of this check is to allow performing the following in generic code for expression xpr:

// c++20
if (is_linear_accessible(xpr.data(), size)) {
    auto buffer = std::span(xpr.data(), size);
    // work with buffer safely
    // ...
} else {
   auto tmp = xpr.eval();
   // work with tmp.data()
   // ...
}

This way I can pass data to other libraries that work on raw buffer. As @JaMiT pointed out, since it involves run-time information, this can only be done in runtime, but I would like to utilize as many as possible the compile time information to "short curciut" the process.

Jerry Ma
  • 511
  • 4
  • 15
  • Are you asking if you can learn (potentially) run-time information at compile time? – JaMiT Apr 02 '19 at 23:40
  • Sure not, but my feeling on this is that there at least exist some level of short cut from compile-time traits/machinery. An obvious one is to check `is_base_of, T>`, since a plain object is always continuous in memory. Another example is a segment/map of vector, which should be always contiguous. – Jerry Ma Apr 03 '19 at 00:32
  • Sounds like you are interested in finding *some* cases where the data is contiguous, whereas the question as it stands asks to find *all* cases. (As I understand it, there is an option to specify the strides at runtime, so finding all cases could be problematic.) – JaMiT Apr 03 '19 at 15:30

1 Answers1

2

The flag you are looking for is the LinearAccessBit of DenseBase<>::Flags, and as @ggael pointed out, make sure that InnerStrideAtCompileTime equals 1.

chtz
  • 17,329
  • 4
  • 26
  • 56
  • 1
    You also need to check that `InnerStrideAtCompileTime==1` because any 1D expression (aka compile-time vector) has `LinearAccessBit` which essentially means that calling `operator()(Index)` on it is allowed. – ggael Apr 03 '19 at 08:20
  • @ggael Maybe additionally checking `DirectAccessBit` (instead of `InnerStrideAtCompileTime`) would work as well, right? This would additionally rule out expressions which must be computed (e.g., `A+B`), but that actually seems like a thing the OP would want. – chtz Apr 03 '19 at 08:58
  • The purpose of this check I was asking is to allow performing the following in generic code for expression `xpr`: (c++20) `std::span data(xpr.data(), size)` when `is_linear_accessble(xpr.data(), size)` evaluates to `true`, so that I can interface with other libraries that work on raw buffer. As @JaMiT pointed out, since it involves run-time information, this can only be done in runtime, but I would like to utilize as many as possible the compile time information to "short curciut" the process. In that regard, `(A+B).data()` does not make sense, hence it does not matter. – Jerry Ma Apr 04 '19 at 19:19