Search code examples
c++tensorc++23mdspan

get the indices in a C++ mdspan from a reference by arithmetic


#include <https://raw.githubusercontent.com/kokkos/mdspan/single-header/mdspan.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
#include <ranges>

int main(){
    std::vector vec = {1, 2, 3, 4, 5, 6, 7, 88, 9, 10, 11, 12};
    auto ms = std::mdspan(vec.data(), 2, 6);

//given the indices in the tensor, get the position in contiguous memory
    {
        const int position = std::distance(vec.data(), &ms[1, 3]);
        std::cout << position << '\n';
    }
//given the position in contiguous memory, get the indices in the tensor by direct access ?
    {    
        const int position = 9;
        //I wanted to avoid doing the arithmetic myself ? something like auto [i, j] = ms.indices_from_pos(position) ?
    }
}

Solution

  • If there is no better way to get the tensor indices from a position, a possibility is to store them with the data itself.

    #include <mdspan>
    #include <vector>
    #include <algorithm>
    #include <iostream>
    #include <ranges>
    using namespace std;
    using namespace std::ranges;
    
    struct MDItem
    {
        int i, j;
        int value;
    };
    
    int main(){
    
        const vector v1 = {1, 2, 3, 4, 5, 6, 7, 88, 9, 10, 11, 12};
        vector<MDItem> v2(v1.size());
        auto ms = std::mdspan(v2.data(), 2, 6);
        
        for (int i=0; i<2; i++)
            for (int j=0; j<6; j++)
            {
                const int position = ms.mapping()(i,j);
                ms[i, j] = MDItem{.i=i, .j=j, .value=v1[position]};
            }
        
        const int position = 9;
        const auto [i,j,value] = v2[position];
        printf("i=%d, j=%d", i, j);
        return 0;
    }