xtensor-stack / xtensor

C++ tensors with broadcasting and lazy computing
BSD 3-Clause "New" or "Revised" License
3.36k stars 398 forks source link

View sizes mismatch when assigning view to another view #2761

Open AurusHuang opened 10 months ago

AurusHuang commented 10 months ago

Consider the following code:

auto vw = view(delta_sigx_l1b, ii, xt::range(0, nx(ii, beam)), beam);
vw_delta_sigx_l1b = dsigma0_g_ii;

where delta_sigx_l1b is a X by 4096 by X matrix, nx(ii, beam) is 4052 and dsigma0_g_ii is a 4052 by 1 vector. I printed vw.size(), nx(ii,beam) and delta_sigx_l1b.size() in the console, and it returns 4096, 4052, 4052. The expected result is 4052, 4052, 4052. Therefore, assigning dsigma0_g_ii to vw_delta_sigx_l1b results in "incompatible dimension of arrays".

JohanMabille commented 10 months ago

Can you please post a complete minimal reproducer? A lot of information is missing from your initial post. From what I understand:

This looks like incorrectly initialized variables

The expected result is 4052, 4052, 4052

What is the expected result? The shape of vw? (It Should be vw_delta_sigx_l1b btw, right?)

EDIT: I fixed the shape of vw which should be (4052) and not (1, 4052, 1)

AurusHuang commented 10 months ago

Let me rephrase... delta_sigx_l1b is a X by 4096 by X tensor, dsigma0_g_ii is a 4052 by 1 vector. nx(ii, beam) is a scalar value and is equal to 4052. Therefore, vw as stated above should be a 1 by 4052 by 1 vector. But vw.size() returns 4096, which means it is a 1 by 4096 by 1 vector, not 4052. This is not what I expect. Sorry for no minimal reproducer available for now.

JohanMabille commented 10 months ago

With the master branch, the following code:

auto t = xtensor<double, 3>::from_shape({1, 4096, 1});
auto v = xt::view(t, 0, xt::range(0, 4052), 0);
std::cout << "size = " << v.size() << std::endl;
std::cout << "shape = " << xt::adapt(v.shape(), {v.dimension()}) << std::endl;

gives the expected output:

size = 4052
shape = {4052}
JohanMabille commented 10 months ago

vw as stated above should be a 1 by 4052 by 1 vector

Actually it should not, it should be a 1-D vector with 4052 elements. If you want a 1x4052x1 tensor, you should initialize vwas following:

vw = xt::view(delta_sigx_l1b, xt::all(), xt::range(0, 4052), xt::all());
AurusHuang commented 10 months ago

The following code works:

int main()
{
    xtensor<int, 1> nx = { 4052,4052,4052 };
    auto shape_t = xt::shape({ 3,4096,3 });
    xtensor<float, 3> delta_sigx_l1b = xt::eval(xt::random::rand<float>(shape_t));
    xtensor<float, 1> dsigma0_g_ii = xt::eval(xt::random::rand<float>({ 4052 }));
    view(delta_sigx_l1b, 0, xt::all(), 0).fill(std::numeric_limits<float>::quiet_NaN());
    view(delta_sigx_l1b, 0, xt::range(0, nx(1)), 0) = dsigma0_g_ii;

    return 0;
}

I'll dig in deeper to see where the problem is.