Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
wants to merge 31 commits into
base: main
Choose a base branch
from

Conversation

dhermes
Copy link
Owner

@dhermes dhermes commented May 27, 2020

No description provided.

@dhermes
Copy link
Owner Author

dhermes commented May 30, 2020

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
Copy link
Owner Author

dhermes commented May 30, 2020

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

Using it to implement `bbox`. Also in the process
fixing TODO to return a `tuple` in `wiggle_interval`.
Also fixing missing `;` and unnecessary use of `.shape(1)`
instead of template variable in `bbox`.
@dhermes
Copy link
Owner Author

dhermes commented May 31, 2020

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

@dhermes dhermes changed the base branch from master to main June 20, 2020 22:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant