You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[C++][IPC][Tensor] Incorrect SparseTensorIndexCSF IPC format #47613
Describe the bug, including details regarding any error messages, version, and platform.
In the following schema file, it is assumed that there is a single type for all indptr buffers and another single type for all indices buffers. However, in the C++ implementation, each indptr and indices buffer can have its own type.
as: indptrType is a required 8-64bit integer type and indicesType is a required 8-64bit integer type. (Note Int maps to integer while int means 32 bit integer). I don't see anywhere stated that these are the same integer type, so C++ implementation seems consistent with the flatbuffers definition. See Int definition:
I mean that the same integer type is assumed for every indptr buffer in the C++ IPC implementation, but in reality, each indptr buffer can have its own integer type. For example, one indptr buffer could be int32, while another could be int64. However, in the C++ IPC implementation, only a single integer type is considered for all indptr buffers:
C++implementation
This happens because only one type is maintained for all indptr buffers. However, each buffer actually has its own type. The same issue also exists for the indices buffers.
I see, you're saying buffers in indptrBuffers: [Buffer] (required);[1] could have different types? I don't think generated flatbuffers deserializer would provide that option. Also - mixing types here would not make much sense application-wise.
I'm looking at the SparseCSFIndex::Make and it will make std::vector<std::shared_ptr<Buffer>>& indptr_data with a single integer type. However one could construct a CSFIndex directly with different integer types as you're suggesting. We could add a check for this in CheckSparseCSFIndexValidity so constructor and SparseCSFIndex::Make would throw an error. Thanks for noticing and explaining @andishgar !
@rok, your suggestion to enforce using the same type is fine. However, this module has existed for more than five years. Would it be safe to change its behavior now? I’m concerned about potential compatibility issues. (I’m aware that Arrow has a major release every three months and that backward compatibility is not guaranteed for major releases—I just want to be sure.)
@andishgar In my view indptr and indices were designed to contain only one datatype and this wouldn't be a change in behavior, just a stricter validity check. Buffers containing different datatypes read through arrow-cpp would return bad data or trigger segfaults. So I don't think adding an extra validity check would be an issue.
We have (to my knowledge) never heard from any CSF index users. Are you aware of anyone using it in the wild?
I haven’t heard of CSF with different indptr types. Actually, I’m only concerned with memory access. :-).
So, in summary, we should enforce—and document—that there is only one type for all indptr buffers and another single type for all index buffers
Activity
andishgar commentedon Sep 22, 2025
@rok I’m not familiar with FlatBuffers at all, so I may be misunderstanding. Could you confirm whether this is correct?
rok commentedon Sep 22, 2025
I would read
arrow/format/SparseTensor.fbs
Line 160 in d803afc
arrow/format/SparseTensor.fbs
Line 179 in d803afc
as:
indptrTypeis a required 8-64bit integer type andindicesTypeis a required 8-64bit integer type. (NoteIntmaps to integer whileintmeans 32 bit integer). I don't see anywhere stated that these are the same integer type, so C++ implementation seems consistent with the flatbuffers definition. SeeIntdefinition:arrow/format/Schema.fbs
Lines 159 to 162 in d803afc
That said it might make sense that the two are always the same type. Would you like to discuss that?
andishgar commentedon Sep 22, 2025
I mean that the same integer type is assumed for every
indptrbuffer in the C++ IPC implementation, but in reality, eachindptrbuffer can have its own integer type. For example, oneindptrbuffer could beint32, while another could beint64. However, in the C++ IPC implementation, only a single integer type is considered for allindptrbuffers:C++implementation
arrow/cpp/src/arrow/ipc/metadata_internal.cc
Lines 1169 to 1175 in d803afc
This happens because only one type is maintained for all indptr buffers. However, each buffer actually has its own type. The same issue also exists for the
indicesbuffers.andishgar commentedon Sep 22, 2025
The above explanation may be unclear. I provide a C++ implementation example to demonstrate that the
.fbs schemaforSparseCSFIndexis invalid.rok commentedon Sep 22, 2025
I see, you're saying buffers in
indptrBuffers: [Buffer] (required);[1] could have different types? I don't think generated flatbuffers deserializer would provide that option. Also - mixing types here would not make much sense application-wise.andishgar commentedon Sep 22, 2025
I have no idea about this.
However, I think it could be a potential bug that may cause illegal memory access
rok commentedon Sep 22, 2025
I'm looking at the
SparseCSFIndex::Makeand it will makestd::vector<std::shared_ptr<Buffer>>& indptr_datawith a single integer type. However one could construct aCSFIndexdirectly with different integer types as you're suggesting. We could add a check for this inCheckSparseCSFIndexValidityso constructor andSparseCSFIndex::Makewould throw an error. Thanks for noticing and explaining @andishgar !andishgar commentedon Sep 22, 2025
@rok, your suggestion to enforce using the same type is fine. However, this module has existed for more than five years. Would it be safe to change its behavior now? I’m concerned about potential compatibility issues. (I’m aware that Arrow has a major release every three months and that backward compatibility is not guaranteed for major releases—I just want to be sure.)
rok commentedon Sep 22, 2025
@andishgar In my view
indptrandindiceswere designed to contain only one datatype and this wouldn't be a change in behavior, just a stricter validity check. Buffers containing different datatypes read through arrow-cpp would return bad data or trigger segfaults. So I don't think adding an extra validity check would be an issue.We have (to my knowledge) never heard from any CSF index users. Are you aware of anyone using it in the wild?
andishgar commentedon Sep 22, 2025
I haven’t heard of CSF with different indptr types. Actually, I’m only concerned with memory access. :-).
So, in summary, we should enforce—and document—that there is only one type for all indptr buffers and another single type for all index buffers
rok commentedon Sep 22, 2025
That seems like the thing to do. Something like this would be needed for enforcement:
andishgar commentedon Oct 8, 2025
This issue will be resolved in #47586.