bezier icon indicating copy to clipboard operation
bezier copied to clipboard

Adding idiomatic C++ equivalents for each subroutine in `helpers.h`.

Open dhermes opened this issue 4 years ago • 3 comments

dhermes avatar May 27 '20 07:05 dhermes

An example that hits on all parts of the xtensor / xarray API we'll need:

#include "xtensor/xadapt.hpp"
#include "xtensor/xfixed.hpp"
#include "xtensor/xio.hpp"
#include "xtensor/xtensor.hpp"
#include <iostream>

int main(int argc, char* argv[])
{
    // H/T: https://xtensor.readthedocs.io/en/latest/container.html
    xt::xtensor<double, 2, xt::layout_type::column_major> arr1 {
        { 1.0, 2.0, 3.0 },
        { 4.0, 5.0, 6.0 },
        { 7.0, 8.0, 9.0 },
    };
    double* p1 = arr1.data();
    for (std::size_t i = 0; i < arr1.size(); ++i) {
        std::cout << p1[i] << " ";
    }
    std::cout << std::endl;
    std::cout << "arr1.dimension(): " << arr1.dimension() << std::endl;
    std::cout << "arr1.shape(0): " << arr1.shape(0) << std::endl;
    std::cout << "arr1.shape(1): " << arr1.shape(1) << std::endl;
    std::cout << "arr1.shape(2): " << arr1.shape(2) << std::endl;
    std::cout << "arr1.shape(): " << xt::adapt(arr1.shape()) << std::endl;

    std::cout << "========================================" << std::endl;

    xt::xtensor<double, 2, xt::layout_type::row_major> arr2 {
        { 1.0, 2.0, 3.0 },
        { 4.0, 5.0, 6.0 },
        { 7.0, 8.0, 9.0 },
    };
    double* p2 = arr2.data();
    for (std::size_t i = 0; i < arr2.size(); ++i) {
        std::cout << p2[i] << " ";
    }
    std::cout << std::endl;
    std::cout << "arr2.dimension(): " << arr2.dimension() << std::endl;
    std::cout << "arr2.shape(0): " << arr2.shape(0) << std::endl;
    std::cout << "arr2.shape(1): " << arr2.shape(1) << std::endl;

    std::cout << "========================================" << std::endl;

    xt::xtensor_fixed<double, xt::xshape<3, 2>, xt::layout_type::column_major>
        arr3 {
            { 1.0, 2.0 },
            { 4.0, 5.0 },
            { 7.0, 8.0 },
        };
    double* p3 = arr3.data();
    for (std::size_t i = 0; i < arr3.size(); ++i) {
        std::cout << p3[i] << " ";
    }
    std::cout << std::endl;
    std::cout << "arr3.dimension(): " << arr3.dimension() << std::endl;
    std::cout << "arr3.shape(0): " << arr3.shape(0) << std::endl;
    std::cout << "arr3.shape(1): " << arr3.shape(1) << std::endl;

    std::cout << "========================================" << std::endl;

    xt::xarray<double, xt::layout_type::column_major> arr4 {
        { 1.0, 2.0, 3.0 },
        { 4.0, 5.0, 6.0 },
        { 7.0, 8.0, 9.0 },
    };
    double* p4 = arr4.data();
    for (std::size_t i = 0; i < arr4.size(); ++i) {
        std::cout << p4[i] << " ";
    }
    std::cout << std::endl;
    std::cout << "arr4.dimension(): " << arr4.dimension() << std::endl;
    std::cout << "arr4.shape(): " << xt::adapt(arr4.shape()) << std::endl;
    for (std::size_t i = 0; i < arr4.dimension(); ++i) {
        std::cout << "arr4.shape(" << i << "): " << arr4.shape(i) << std::endl;
    }

    return 0;
}

Some things to take away from this:

  • Any of xarray, xtensor, xtensor_fixed will work (though we should prefer xtensor_fixed)
  • arr.shape(N) == 1 when N is too large (this avoid runtime "problems")
  • Fortran order need be specified in the type as xt::layout_type::column_major
  • We can get rows = arr.shape(0) and cols = arr.shape(1) and if we want to do runtime type assertions (e.g. in the presence of xarray where number of dimensions isn't known at compile time) we can check arr.dimension()
  • A raw pointer exists are arr.data() (like a vector<double>) and arr.size() returns the number of elements in this raw pointer (though we'll likely not need it to invoke libbezier)

dhermes avatar May 30 '20 20:05 dhermes

Possibly relevant for performance when building xtensor: https://xtensor.readthedocs.io/en/latest/build-options.html#external-dependencies

  • XTENSOR_USE_XSIMD
  • XTENSOR_USE_TBB
  • XTENSOR_DISABLE_EXCEPTIONS
  • XTENSOR_USE_OPENMP

dhermes avatar May 30 '20 20:05 dhermes

Another thing worth checking / requiring (if we allow generic types, e.g. views) is that the raw .data() pointers are contiguous.

dhermes avatar May 31 '20 06:05 dhermes