conduit icon indicating copy to clipboard operation
conduit copied to clipboard

Set and get interleaved arrays

Open tmarrinan opened this issue 8 months ago • 4 comments

I have interleaved x,y,z data that I insert into a Conduit Blueprint. Currently, I create separate arrays to store the x, y, and z data, then set them as values in the Conduit Node. I also see that I can use set_external with a stride to set each component without needing to copy the data. Is there an equivalent to get data back out into an interleaved array?

Example:

// Create array for 4 vertices: (1.0, 1.0, 1.0), (2.0, 2.0, 2.0), (3.0, 3.0, 3.0), and (4.0, 4.0, 4.0)
double data[12] = {
    1.0, 1.0, 1.0, 1.0, // pt0: x, y, z
    2.0, 2.0, 2.0, 2.0, // pt1: x, y, z
    3.0, 3.0, 3.0, 3.0, // pt2: x, y, z
    4.0, 4.0, 4.0, 4.0  // pt3: x, y, z
};

Node n;
// would love to do the following in one step (just set the array rather than each component), but not sure if possible
n["x"].set_external(&data[0], 4, 0, 3 * sizeof(double));
n["y"].set_external(&data[1], 4, 0, 3 * sizeof(double));
n["z"].set_external(&data[2], 4, 0, 3 * sizeof(double));

// want to do something like the following:
//double *out = n.as_float64_ptr();

Note: I see that I can check if the data is interleaved using conduit::blueprint::mcarray::is_interleaved() and convert it to an interleaved layout if needed using conduit::blueprint::mcarray::to_interleaved()

tmarrinan avatar Apr 10 '25 20:04 tmarrinan

I don't think this is possible inside of Conduit. The only way I can think of to support this case is to create another entry in your node n["data"].set(&data, 12); (or set_external) and then n["x"], n["y"], and n["z"] could be set_external to that data already stored in n["data"]. Then you can pull that data back out at will and still use it inside of whatever value arrays you need.

Let me know if that answers your question.

JustinPrivitera avatar Apr 11 '25 00:04 JustinPrivitera

If I confirm that the underlying data is interleaved, can I just do n["x"].as_float64_ptr()? Would that be guaranteed to point to the start of the full interleaved array?

tmarrinan avatar Apr 11 '25 13:04 tmarrinan

Well yes, I suppose you can. I wasn't reading carefully.

JustinPrivitera avatar Apr 11 '25 15:04 JustinPrivitera

You can actually check for interleaved data:

https://github.com/LLNL/conduit/blob/80bddf8f651f009fad8a9574e6df8803cb99628c/src/libs/blueprint/conduit_blueprint_mcarray.hpp#L61

(There are also helpers that convert to interleaved for a multi component array)

If you have the same data type and the data is interleaved you can just grab the pointer to the first entry of the first component. That will usually be n["x"].as_float64_ptr() unless the first component has an additional offset.

cyrush avatar Apr 14 '25 15:04 cyrush