NDArray memory layout

Saw the implementation of this OffSet() function: https://github.com/apache/incubator-mxnet/blob/master/cpp-package/include/mxnet-cpp/ndarray.hpp#L387

Is this correct? If I use a vector of float to construct a ndarray with three channels whose shape is like [3, h, w], should I arrange my vector as [r, g, b, r, g, b, …] ?!

I don’t think the vector should be arranged as [r, g, b, r, g, b …]. Looking at the example from https://mxnet.incubator.apache.org/versions/master/tutorials/c++/mxnet_cpp_inference_tutorial.html, image data is loaded the following way:

std::vector<float> array;
[...]
for (int c = 0; c < channels; ++c) {
    for (int i = 0; i < height; ++i) {
      for (int j = 0; j < width; ++j) {
        array.push_back(static_cast<float>(mat.data[(i * height + j) * 3 + c]));
      } } }

They loop first over the channels, then height and width. So the layout is [r, r, r, r, g, g, g, g, b, b, b, b]

Nevertheless here

  return h * shape[0] * shape[2] + w * shape[0] + c;

suggests an HWC (?) underlying layout.
If it was CHW, we would expect

c * shape[1] * shape[2] + h * shape[2] + w 

Do you know how this Offset function is supposed to be used?

1 Like

I would guess this is probably a bug if the memory layout is expected to be [r, r, r, r, g, g, g, g, b, b, b, b]