Skip to content

Is it possible to xt::adapt a buffer with strides? #2705

@themightyoarfish

Description

@themightyoarfish

I have an array of data elements of some size with padding, which I want to wrap with xt::adapt() such that the padding column is ignored. Context: each element is 3 floats for XYZ data, plus 1 float of padding for more efficient access.

I've tried a minimal program to get this to work, but it always terminates with

libc++abi: terminating with uncaught exception of type std::runtime_error: xbuffer_storage not resizable

Code:

#include <iomanip>
#include <vector>
#include <xtensor/xadapt.hpp>

int main(int argc, char *argv[]) {
  std::cout << std::fixed << std::setw(3) << std::setprecision(6)
            << std::setfill(' ');

  // make a vector of n_elems blocks with floats_per_elem * sizeof(float) bytes
  // each. Only the first n-1 of these are significant
  // Storage is row major, so elements are laid our one by one
  size_t n_elems = 5;
  size_t floats_per_elem = 4;
  std::vector<float> v(floats_per_elem * n_elems);
  std::cout << "Input array" << std::endl;
  for (int i = 0; i < v.size(); ++i) {
    // keep ever n-1th element at 0 and put some value in the others
    if (((i + 1) % floats_per_elem) != 0) {
      v[i] = 1 + 0.1 * i;
    }
    std::cout << v[i] << " ";
  }
  std::cout << std::endl;

  // desired xtensor shape: n_elems x floats_per_elem - 1, ignoring the padding
  // bytes
  std::vector<size_t> shape = {n_elems, floats_per_elem - 1};
  // rows are floats_per_elem elements apart
  std::vector<size_t> strides = {floats_per_elem, 1};

  auto adapted =
      xt::adapt(v.data(), v.size(), xt::no_ownership(), shape, strides);

  std::cout << "Adapted array" << std::endl;
  for (int i = 0; i < adapted.shape()[0]; ++i) {
    for (int j = 0; j < adapted.shape()[1]; ++j) {
      std::cout << adapted(i, j) << " ";
    }
    std::cout << std::endl;
  }
  return 0;
}

I build with

clang++ -o xtensor_test -I <deps>/include/ -std=c++20 xtensor_test.cpp  && ./xtensor_test

Do all xtensor arrays have to be contiguous, or is it possible to set up strides and shapes so that padding bytes are ignored?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions