Skip to content

feat: writing/reading to parquet - #1002

Merged
tmadlener merged 24 commits into
AIDASoft:masterfrom
arnavdham:arrow-parquet-writer
Aug 26, 2026
Merged

feat: writing/reading to parquet#1002
tmadlener merged 24 commits into
AIDASoft:masterfrom
arnavdham:arrow-parquet-writer

Conversation

@arnavdham

@arnavdham arnavdham commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Closes #1006

This PR extends the existing Arrow backend in Podio by adding the capability to write and read datamodels directly to and from Apache Parquet files. This significantly improves data interoperability with Python ecosystems and column-oriented analysis workflows.

Key Features & Additions:

  • ArrowWriter & ArrowReader: Implemented robust C++ classes to handle serialization of the Arrow backend's Frame objects to Parquet (saving one .parquet file per category) alongside a metadata.json for configuration and format tracking.
  • podioArrow Target: Expanded the existing core Arrow processing logic. Populated the ArrowTypeRegistry and ArrowConverterRegistry with primitive type converters to support translating built-in types for file I/O operations.
  • Build System Integration: Fixed the existing PODIO_ADD_ARROW macro in podioMacros.cmake to ensure downstream datamodel targets correctly link against podio::podioArrow (resolving undefined references).
  • Comprehensive Testing: Added a full suite of tests in tests/arrow_io/ mirroring the existing I/O tests. This includes Python/C++ interoperability tests, multithreaded read/write testing, and interface roundtripping for the Parquet files.

BEGINRELEASENOTES

  • Add Parquet file reading and writing capabilities to the Arrow backend (ArrowWriter and ArrowReader).
  • Populate ArrowTypeRegistry and ArrowConverterRegistry with primitive type converters for file I/O.
  • Fix missing linking dependencies in podioMacros.cmake for downstream datamodel targets using the Arrow backend.

ENDRELEASENOTES

@arnavdham
arnavdham marked this pull request as draft August 14, 2026 08:20
@arnavdham
arnavdham marked this pull request as ready for review August 14, 2026 08:41
@arnavdham
arnavdham marked this pull request as draft August 16, 2026 16:16

@tmadlener tmadlener left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't looked into any of the details so far. I have a conceptual question; Currently this would create directories with files. Would it make sense to grab libarchive and "tar those up" on the fly so that in the end we deal with one "file" again?

@arnavdham
arnavdham marked this pull request as ready for review August 19, 2026 09:42
@arnavdham

Copy link
Copy Markdown
Contributor Author

I haven't looked into any of the details so far. I have a conceptual question; Currently this would create directories with files. Would it make sense to grab libarchive and "tar those up" on the fly so that in the end we deal with one "file" again?

I am not sure why this would help. From a user perspective, a directory with multiple files would be easier to use directly in python environments.

@tmadlener tmadlener left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your point, fair enough. It would in any case be fairly straight forward to fix that later.

I have had a first look and in general there seem to be mainly minor things. Just to confirm: The tests are essentially copies from the other I/O backends just using the Arrow{Writer,Reader} instead, right?

Final question, is Arrow{Reader,Writer} the best name, or should it also contain Parquet somehow?

Comment thread include/podio/ArrowReader.h Outdated
Comment thread include/podio/ArrowWriter.h Outdated
Comment thread python/podio/arrow_io.py Outdated
Comment thread src/ArrowWriter.cc Outdated
Comment thread src/ArrowWriter.cc
Comment thread CMakeLists.txt Outdated
Comment thread include/podio/ArrowReader.h Outdated
Comment thread src/ArrowReader.cc
Comment thread src/ArrowReader.cc Outdated
Comment thread src/ArrowFrameData.cc Outdated
@arnavdham

Copy link
Copy Markdown
Contributor Author

I see your point, fair enough. It would in any case be fairly straight forward to fix that later.

I have had a first look and in general there seem to be mainly minor things. Just to confirm: The tests are essentially copies from the other I/O backends just using the Arrow{Writer,Reader} instead, right?

Final question, is Arrow{Reader,Writer} the best name, or should it also contain Parquet somehow?

Yes tests are copies from other backends. Have no strong opinion on the name though cause my initial thought was ParquetWriter/Reader itself but that didn't have Arrow so I wasn't a fan.

@arnavdham

Copy link
Copy Markdown
Contributor Author

Have addressed all the comments.

Comment thread .github/workflows/pre-commit.yml
Comment thread src/ArrowReader.cc
Comment thread CMakeLists.txt Outdated
Comment thread include/podio/ArrowWriter.h Outdated
Comment thread src/CMakeLists.txt
Comment thread src/CMakeLists.txt
Comment thread src/CMakeLists.txt Outdated
Comment thread src/ArrowReader.cc
Comment thread tests/write_frame.py Outdated
Comment thread cmake/podioConfig.cmake.in Outdated
Comment thread src/Writer.cc Outdated
@jmcarcell

Copy link
Copy Markdown
Member

I don't know if this is elsewhere but there are a few things that would be good or necessary to have:

  • Documentation (docs folder)
  • podio-dump working with parquet files

@arnavdham

Copy link
Copy Markdown
Contributor Author

I don't know if this is elsewhere but there are a few things that would be good or necessary to have:

  • Documentation (docs folder)
  • podio-dump working with parquet files

I think podio-dump already works with parquet files will check this regardless.
For documentation will adding a section in doc/reading_writing.md for Arrow would be enough?

@arnavdham

Copy link
Copy Markdown
Contributor Author

I don't know if this is elsewhere but there are a few things that would be good or necessary to have:

  • Documentation (docs folder)
  • podio-dump working with parquet files

I think podio-dump already works with parquet files will check this regardless. For documentation will adding a section in doc/reading_writing.md for Arrow would be enough?

jug_dev> arnavdham@ARNAVDesktop:~/gsoc/podio$ LD_PRELOAD=$PWD/build/tests/libTestDataModelPodioArrow.so ./install/bin/podio-dump example_frame_zstd.arrow
input file: example_frame_zstd.arrow
            (written with podio version: 1.7.99)

datamodel model definitions stored in this file:
 - datamodel (1.7.99)

Frame categories in this file:
Name    Entries  
------  -------  
events  10       
################################### events: 0 ####################################
Collections:
Name (s = subset collection)  ValueType                                   Size  ID          
----------------------------  ------------------------------------------  ----  --------    
arrays                        ExampleWithArray                            1     d5f00a11    
clusters                      ExampleCluster                              3     05393275    
emptyCollection               ExampleCluster                              0     35ddd2cf    
emptySubsetColl (s)           ExampleHit                                  0     d76d338d    
fixedWidthInts                ExampleWithFixedWidthIntegers               3     62b8b748    
hitRefs (s)                   ExampleHit                                  2     96140608    
hits                          ExampleHit                                  2     fb2c5a48    
info                          EventInfo                                   1     66667806    
links                         podio::Link<ExampleHit,ExampleCluster>      2     1e2dcdb5    
links_with_interfaces         podio::Link<ExampleCluster,TypeWithEnergy>  3     2c119831    
mcParticleRefs (s)            ExampleMC                                   10    b7f1d19b    
mcparticles                   ExampleMC                                   10    7e15ccd5    
moreMCs                       ExampleMC                                   10    ae0f2334    
OneRelation                   ExampleWithOneRelation                      2     a1c1a57f    
refs                          ExampleReferencingType                      2     3443cc91    
refs2                         ExampleReferencingType                      1     15966606    
userDoubles                   double                                      100   3a47f784    
userInts                      uint64_t                                    1     ceb7bde4    
WithNamespaceMember           ex42::ExampleWithNamespace                  25    6b99e124    
WithNamespaceRelation         ex42::ExampleWithARelation                  5     3d3e8081    
WithNamespaceRelationCopy     ex42::ExampleWithARelation                  5     d57c3b9e    
WithVectorMember              ExampleWithVectorMember                     2     2ce6aaf8    

Parameters:
Name             Type         Elements  
---------------  -----------  --------  
anInt            int          1         
SomeValue        int          1         
SomeVectorData   int          4         
UserEventWeight  float        1         
SomeVectorData   double       2         
SomeValue        std::string  1         
SomeVectorData   std::string  3         
UserEventName    std::string  1  

Podio dump does work.

@veprbl veprbl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, meant to post this earlier.

});

registry.registerReader(typeName,
[](const std::shared_ptr<arrow::Array>& array, int64_t rowIndex, bool isSubset,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline and reformat?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is clang formattted. The rules come up as errors in pre-commit so nothing much I can do about it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect if you add a newline after ( it won't undo it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could try that, but otherwise clang-format decides here, I would say.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried and clang format just un-did my changes so I don't think this would be possible.

Comment thread src/Writer.cc Outdated
#else
throw std::runtime_error("SIO writer not available. Please recompile with SIO support.");
#endif
} else if (endsWith(filename, ".arrow") || lower(type) == "arrow") {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
} else if (endsWith(filename, ".arrow") || lower(type) == "arrow") {
} else if (endsWith(filename, ".podio_parquet") || lower(type) == "parquet") {

Does it make sense to be explicit about the flavor of arrow format?
Also I would not simply say "arrow" without denoting that this is a podio layout.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#1002 (comment) I just changed this to arrow. Also btw, this is the directory name in Arrow's case so arrow should suffice. The files inside are category_name.parquet and metadata.json.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is the suggestion to the current state.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have changed this.

@arnavdham

Copy link
Copy Markdown
Contributor Author

@tmadlener @jmcarcell @veprbl Can I get a list of things to be resolved/added so that this could be moved to closure? I am a bit confused with so many comments still open.

@tmadlener

Copy link
Copy Markdown
Collaborator

I have resolved a few of the conversations that you addressed. From my point of view there is essentially nothing left to do here apart from some minor things where @veprbl and @jmcarcell have originally commented. (I have added a suggestion from my side to those, but will let them have the final say).

@arnavdham

Copy link
Copy Markdown
Contributor Author

Have addressed everything now.

@tmadlener

Copy link
Copy Markdown
Collaborator

Looks like everyone is happy now. I will merge this later today, unless there are last minute comments. I have created an issue to keep track of the potential optimisation (#1009).

@tmadlener
tmadlener force-pushed the arrow-parquet-writer branch from 4b03b36 to 0a3eef6 Compare August 26, 2026 11:24
@tmadlener
tmadlener enabled auto-merge (squash) August 26, 2026 11:26
@tmadlener
tmadlener merged commit 123b156 into AIDASoft:master Aug 26, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Parquet file I/O for the Arrow backend

4 participants