Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read IO plugin configuration (openPMD plugin) from reading applications (TOML) #3720

Merged
merged 4 commits into from
Jan 28, 2022

Conversation

franzpoeschel
Copy link
Contributor

@franzpoeschel franzpoeschel commented Aug 12, 2021

Close #3717, see there for a detailed description

TODO:

  • Add thirdparty library and integrate it with the build system
  • Implement new logic in openPMD plugin
  • Actually read config from TOML files (currently, a little example is hardcoded)
  • Check that selfRegister==true is handled correctly (checkpoint writing)
    keep the .toml option out of --checkpoint.openPMD somehow?
  • Discuss command line parameter schema (may drop the --openPMD.period dynamic thing, it's easy to implement for now) Update: --openPMD.period and --openPMD.toml are now mutually exclusive. If using TOML, then the parameter must be the only parameter.
  • Logging
  • parallel reading
  • Timeout for waiting on files?
  • Add documentation
  • Merge Add optionDefined() to plugins::multi::Option struct #3906 first
  • I'd appreciate if someone could test that your multiplugin workflows still work
  • rebase after Disable hdf5 chunking by default #3919 to avoid documentation merge conflicts

@franzpoeschel
Copy link
Contributor Author

Just did a little test run with this thing:

First TOML file:

[period]
200 = ["E", "B"]
400 = "fields_all"

Second one:

[period]
500 = "species_all"

Resulting dataset:

  float     /data/0/fields/B/x                                        {32, 32, 32}
  float     /data/0/fields/B/y                                        {32, 32, 32}
  float     /data/0/fields/B/z                                        {32, 32, 32}
  float     /data/0/fields/E/x                                        {32, 32, 32}
  float     /data/0/fields/E/y                                        {32, 32, 32}
  float     /data/0/fields/E/z                                        {32, 32, 32}
  float     /data/0/fields/e_all_chargeDensity                        {32, 32, 32}
  float     /data/0/fields/e_all_energyDensity                        {32, 32, 32}
  float     /data/0/fields/e_all_particleMomentumComponent            {32, 32, 32}
  float     /data/0/fields/i_all_chargeDensity                        {32, 32, 32}
  float     /data/0/fields/i_all_energyDensity                        {32, 32, 32}
  float     /data/0/fields/i_all_particleMomentumComponent            {32, 32, 32}
  uint64_t  /data/0/fields/picongpu_idProvider/nextId                 {1, 1, 1}
  uint64_t  /data/0/fields/picongpu_idProvider/startId                {1, 1, 1}
  float     /data/0/particles/e/momentum/x                            {819200}
  float     /data/0/particles/e/momentum/y                            {819200}
  float     /data/0/particles/e/momentum/z                            {819200}
  uint64_t  /data/0/particles/e/particlePatches/extent/x              {1}
  uint64_t  /data/0/particles/e/particlePatches/extent/y              {1}
  uint64_t  /data/0/particles/e/particlePatches/extent/z              {1}
  uint64_t  /data/0/particles/e/particlePatches/numParticles          {1}
  uint64_t  /data/0/particles/e/particlePatches/numParticlesOffset    {1}
  uint64_t  /data/0/particles/e/particlePatches/offset/x              {1}
  uint64_t  /data/0/particles/e/particlePatches/offset/y              {1}
  uint64_t  /data/0/particles/e/particlePatches/offset/z              {1}
  float     /data/0/particles/e/position/x                            {819200}
  float     /data/0/particles/e/position/y                            {819200}
  float     /data/0/particles/e/position/z                            {819200}
  int32_t   /data/0/particles/e/positionOffset/x                      {819200}
  int32_t   /data/0/particles/e/positionOffset/y                      {819200}
  int32_t   /data/0/particles/e/positionOffset/z                      {819200}
  float     /data/0/particles/e/weighting                             {819200}
  float     /data/0/particles/i/momentum/x                            {819200}
  float     /data/0/particles/i/momentum/y                            {819200}
  float     /data/0/particles/i/momentum/z                            {819200}
  uint64_t  /data/0/particles/i/particlePatches/extent/x              {1}
  uint64_t  /data/0/particles/i/particlePatches/extent/y              {1}
  uint64_t  /data/0/particles/i/particlePatches/extent/z              {1}
  uint64_t  /data/0/particles/i/particlePatches/numParticles          {1}
  uint64_t  /data/0/particles/i/particlePatches/numParticlesOffset    {1}
  uint64_t  /data/0/particles/i/particlePatches/offset/x              {1}
  uint64_t  /data/0/particles/i/particlePatches/offset/y              {1}
  uint64_t  /data/0/particles/i/particlePatches/offset/z              {1}
  float     /data/0/particles/i/position/x                            {819200}
  float     /data/0/particles/i/position/y                            {819200}
  float     /data/0/particles/i/position/z                            {819200}
  int32_t   /data/0/particles/i/positionOffset/x                      {819200}
  int32_t   /data/0/particles/i/positionOffset/y                      {819200}
  int32_t   /data/0/particles/i/positionOffset/z                      {819200}
  float     /data/0/particles/i/weighting                             {819200}
  float     /data/200/fields/B/x                                      {32, 32, 32}
  float     /data/200/fields/B/y                                      {32, 32, 32}
  float     /data/200/fields/B/z                                      {32, 32, 32}
  float     /data/200/fields/E/x                                      {32, 32, 32}
  float     /data/200/fields/E/y                                      {32, 32, 32}
  float     /data/200/fields/E/z                                      {32, 32, 32}
  uint64_t  /data/200/fields/picongpu_idProvider/nextId               {1, 1, 1}
  uint64_t  /data/200/fields/picongpu_idProvider/startId              {1, 1, 1}
  float     /data/400/fields/B/x                                      {32, 32, 32}
  float     /data/400/fields/B/y                                      {32, 32, 32}
  float     /data/400/fields/B/z                                      {32, 32, 32}
  float     /data/400/fields/E/x                                      {32, 32, 32}
  float     /data/400/fields/E/y                                      {32, 32, 32}
  float     /data/400/fields/E/z                                      {32, 32, 32}
  float     /data/400/fields/e_all_chargeDensity                      {32, 32, 32}
  float     /data/400/fields/e_all_energyDensity                      {32, 32, 32}
  float     /data/400/fields/e_all_particleMomentumComponent          {32, 32, 32}
  float     /data/400/fields/i_all_chargeDensity                      {32, 32, 32}
  float     /data/400/fields/i_all_energyDensity                      {32, 32, 32}
  float     /data/400/fields/i_all_particleMomentumComponent          {32, 32, 32}
  uint64_t  /data/400/fields/picongpu_idProvider/nextId               {1, 1, 1}
  uint64_t  /data/400/fields/picongpu_idProvider/startId              {1, 1, 1}
  uint64_t  /data/500/fields/picongpu_idProvider/nextId               {1, 1, 1}
  uint64_t  /data/500/fields/picongpu_idProvider/startId              {1, 1, 1}
  uint64_t  /data/500/particles/e/particlePatches/extent/x            {1}
  uint64_t  /data/500/particles/e/particlePatches/extent/y            {1}
  uint64_t  /data/500/particles/e/particlePatches/extent/z            {1}
  uint64_t  /data/500/particles/e/particlePatches/numParticles        {1}
  uint64_t  /data/500/particles/e/particlePatches/numParticlesOffset  {1}
  uint64_t  /data/500/particles/e/particlePatches/offset/x            {1}
  uint64_t  /data/500/particles/e/particlePatches/offset/y            {1}
  uint64_t  /data/500/particles/e/particlePatches/offset/z            {1}
  uint64_t  /data/500/particles/i/particlePatches/extent/x            {1}
  uint64_t  /data/500/particles/i/particlePatches/extent/y            {1}
  uint64_t  /data/500/particles/i/particlePatches/extent/z            {1}
  uint64_t  /data/500/particles/i/particlePatches/numParticles        {1}
  uint64_t  /data/500/particles/i/particlePatches/numParticlesOffset  {1}
  uint64_t  /data/500/particles/i/particlePatches/offset/x            {1}
  uint64_t  /data/500/particles/i/particlePatches/offset/y            {1}
  uint64_t  /data/500/particles/i/particlePatches/offset/z            {1}
  float     /data/600/fields/B/x                                      {32, 32, 32}
  float     /data/600/fields/B/y                                      {32, 32, 32}
  float     /data/600/fields/B/z                                      {32, 32, 32}
  float     /data/600/fields/E/x                                      {32, 32, 32}
  float     /data/600/fields/E/y                                      {32, 32, 32}
  float     /data/600/fields/E/z                                      {32, 32, 32}
  uint64_t  /data/600/fields/picongpu_idProvider/nextId               {1, 1, 1}
  uint64_t  /data/600/fields/picongpu_idProvider/startId              {1, 1, 1}

@franzpoeschel
Copy link
Contributor Author

The latest commit fixes waiting for late files and adds logging for that:

PIConGPUVerbose INPUT_OUTPUT(32) | openPMD: Reading data requirements from TOML files:                                                                                               
        [/home/franzpoeschel/src/singularity/toml1.toml, /home/franzpoeschel/src/singularity/toml0.toml]                                                                            
PIConGPUVerbose INPUT_OUTPUT(32) | openPMD: Still waiting for TOML files:                                                                                                            
        [/home/franzpoeschel/src/singularity/toml0.toml]                                                                                                                            
PIConGPUVerbose INPUT_OUTPUT(32) | openPMD: Still waiting for TOML files:
        [/home/franzpoeschel/src/singularity/toml0.toml]
PIConGPUVerbose INPUT_OUTPUT(32) | openPMD: Still waiting for TOML files:
        [/home/franzpoeschel/src/singularity/toml0.toml]
PIConGPUVerbose INPUT_OUTPUT(32) | openPMD: opening Series openPMD/stream
PIConGPUVerbose INPUT_OUTPUT(32) | openPMD: open file: openPMD/stream.bp

Next up: parallel reading (i.e. non-parallel reading)

@franzpoeschel
Copy link
Contributor Author

(PR stalled for now until René is back from holiday to review this approach.)

@franzpoeschel
Copy link
Contributor Author

franzpoeschel commented Sep 30, 2021

Discussed offline with René:
We will change this such that one instance of the openPMD plugin can be configured entirely by one single TOML file. This file will have sections for the single reading codes' data requirements:

[openPMD]
"file" = "simOutput"
"ext" = "bp"
"backend_config" = "@./adios2_config.json"

[sink.analysis_code_name.period]
200 = ["E", "B"]
400 = "fields_all"

[sink.other_analysis_code_name.period]
500 = "species_all"

Under the openPMD group, we simply put all classical cmd line parameters of the openPMD plugin. Under [sink.<arbitrary name>.period], the single reading codes' data requirements are found. This allows us to add other sink-specific keys in future:

# this will not be part of this PR
# just demonstrating that this schema is extensible
[sink.analysis_code_name]
"logging" = true

Other points discussed: Allow time slicing syntax, Do not activate this in every step, but instead tell the plugin controller about the periods

@psychocoderHPC Any additions?

@franzpoeschel
Copy link
Contributor Author

Time slice syntax and reading of normal plugin parameters from TOML now implemented:

file = "output"
infix = ""

[sink.1.period]
"100:300:200" = ["E", "B"]
"300:10000:200" = "fields_all"
[sink.2.period]
500 = "species_all"

Result:

> bpls openPMD/output.bp/                                                                                                                                
  uint64_t  /data/0/fields/picongpu_idProvider/nextId                 {1, 1, 1}                                                                                     
  uint64_t  /data/0/fields/picongpu_idProvider/startId                {1, 1, 1}                                                                                     
  float     /data/0/particles/e/momentum/x                            {819200}                                                                                      
  float     /data/0/particles/e/momentum/y                            {819200}                                                                                      
  float     /data/0/particles/e/momentum/z                            {819200}                                                                                      
  uint64_t  /data/0/particles/e/particlePatches/extent/x              {1}                                                                                           
  uint64_t  /data/0/particles/e/particlePatches/extent/y              {1}                                                                                           
  uint64_t  /data/0/particles/e/particlePatches/extent/z              {1}                                                                                           
  uint64_t  /data/0/particles/e/particlePatches/numParticles          {1}                                                                                           
  uint64_t  /data/0/particles/e/particlePatches/numParticlesOffset    {1}                                                                                           
  uint64_t  /data/0/particles/e/particlePatches/offset/x              {1}                                                                                           
  uint64_t  /data/0/particles/e/particlePatches/offset/y              {1}                                                                                           
  uint64_t  /data/0/particles/e/particlePatches/offset/z              {1}                                                                                           
  float     /data/0/particles/e/position/x                            {819200}                                                                                      
  float     /data/0/particles/e/position/y                            {819200}                                                                                      
  float     /data/0/particles/e/position/z                            {819200}                                                                                      
  int32_t   /data/0/particles/e/positionOffset/x                      {819200}                                                                                      
  int32_t   /data/0/particles/e/positionOffset/y                      {819200}                                                                                      
  int32_t   /data/0/particles/e/positionOffset/z                      {819200}                                                                                      
  float     /data/0/particles/e/weighting                             {819200}                                                                                      
  float     /data/0/particles/i/momentum/x                            {819200}                                                                                      
  float     /data/0/particles/i/momentum/y                            {819200}                                                                                      
  float     /data/0/particles/i/momentum/z                            {819200}                                                                                      
  uint64_t  /data/0/particles/i/particlePatches/extent/x              {1}                                                                                           
  uint64_t  /data/0/particles/i/particlePatches/extent/y              {1}                                                                                           
  uint64_t  /data/0/particles/i/particlePatches/extent/z              {1}                                                                                           
  uint64_t  /data/0/particles/i/particlePatches/numParticles          {1}                                                                                           
  uint64_t  /data/0/particles/i/particlePatches/numParticlesOffset    {1}                                                                                           
  uint64_t  /data/0/particles/i/particlePatches/offset/x              {1}                                                                                           
  uint64_t  /data/0/particles/i/particlePatches/offset/y              {1}                                                                                           
  uint64_t  /data/0/particles/i/particlePatches/offset/z              {1}                                                                                           
  float     /data/0/particles/i/position/x                            {819200}                                                                                      
  float     /data/0/particles/i/position/y                            {819200}                                                                                      
  float     /data/0/particles/i/position/z                            {819200}                                                                                      
  int32_t   /data/0/particles/i/positionOffset/x                      {819200}                                                                                      
  int32_t   /data/0/particles/i/positionOffset/y                      {819200}                                                                                      
  int32_t   /data/0/particles/i/positionOffset/z                      {819200}                                                                                      
  float     /data/0/particles/i/weighting                             {819200}                                                                                      
  float     /data/100/fields/B/x                                      {32, 32, 32}                                                                                  
  float     /data/100/fields/B/y                                      {32, 32, 32}                                                                                  
  float     /data/100/fields/B/z                                      {32, 32, 32}                                                                                  
  float     /data/100/fields/E/x                                      {32, 32, 32}                                                                                  
  float     /data/100/fields/E/y                                      {32, 32, 32}                                                                                  
  float     /data/100/fields/E/z                                      {32, 32, 32}                                                                                  
  uint64_t  /data/100/fields/picongpu_idProvider/nextId               {1, 1, 1}                                                                                     
  uint64_t  /data/100/fields/picongpu_idProvider/startId              {1, 1, 1}
  float     /data/300/fields/B/x                                      {32, 32, 32}
  float     /data/300/fields/B/y                                      {32, 32, 32}
  float     /data/300/fields/B/z                                      {32, 32, 32}
  float     /data/300/fields/E/x                                      {32, 32, 32}
  float     /data/300/fields/E/y                                      {32, 32, 32}
  float     /data/300/fields/E/z                                      {32, 32, 32}
  float     /data/300/fields/e_all_chargeDensity                      {32, 32, 32}
  float     /data/300/fields/e_all_energyDensity                      {32, 32, 32}
  float     /data/300/fields/e_all_particleMomentumComponent          {32, 32, 32}
  float     /data/300/fields/i_all_chargeDensity                      {32, 32, 32}
  float     /data/300/fields/i_all_energyDensity                      {32, 32, 32}
  float     /data/300/fields/i_all_particleMomentumComponent          {32, 32, 32}
  uint64_t  /data/300/fields/picongpu_idProvider/nextId               {1, 1, 1}
  uint64_t  /data/300/fields/picongpu_idProvider/startId              {1, 1, 1}
  float     /data/500/fields/B/x                                      {32, 32, 32}
  float     /data/500/fields/B/y                                      {32, 32, 32}
  float     /data/500/fields/B/z                                      {32, 32, 32}
  float     /data/500/fields/E/x                                      {32, 32, 32}
  float     /data/500/fields/E/y                                      {32, 32, 32}
  float     /data/500/fields/E/z                                      {32, 32, 32}
  float     /data/500/fields/e_all_chargeDensity                      {32, 32, 32}
  float     /data/500/fields/e_all_energyDensity                      {32, 32, 32}
  float     /data/500/fields/e_all_particleMomentumComponent          {32, 32, 32}
  float     /data/500/fields/i_all_chargeDensity                      {32, 32, 32}
  float     /data/500/fields/i_all_energyDensity                      {32, 32, 32}
  float     /data/500/fields/i_all_particleMomentumComponent          {32, 32, 32}
  uint64_t  /data/500/fields/picongpu_idProvider/nextId               {1, 1, 1}
  uint64_t  /data/500/fields/picongpu_idProvider/startId              {1, 1, 1}
  uint64_t  /data/500/particles/e/particlePatches/extent/x            {1}
  uint64_t  /data/500/particles/e/particlePatches/extent/y            {1}
  uint64_t  /data/500/particles/e/particlePatches/extent/z            {1}
  uint64_t  /data/500/particles/e/particlePatches/numParticles        {1}
  uint64_t  /data/500/particles/e/particlePatches/numParticlesOffset  {1}
  uint64_t  /data/500/particles/e/particlePatches/offset/x            {1}
  uint64_t  /data/500/particles/e/particlePatches/offset/y            {1}
  uint64_t  /data/500/particles/e/particlePatches/offset/z            {1}
  uint64_t  /data/500/particles/i/particlePatches/extent/x            {1}
  uint64_t  /data/500/particles/i/particlePatches/extent/y            {1}
  uint64_t  /data/500/particles/i/particlePatches/extent/z            {1}
  uint64_t  /data/500/particles/i/particlePatches/numParticles        {1}
  uint64_t  /data/500/particles/i/particlePatches/numParticlesOffset  {1}
  uint64_t  /data/500/particles/i/particlePatches/offset/x            {1}
  uint64_t  /data/500/particles/i/particlePatches/offset/y            {1}
  uint64_t  /data/500/particles/i/particlePatches/offset/z            {1}
  float     /data/700/fields/B/x                                      {32, 32, 32}
  float     /data/700/fields/B/y                                      {32, 32, 32}
  float     /data/700/fields/B/z                                      {32, 32, 32}
  float     /data/700/fields/E/x                                      {32, 32, 32}
  float     /data/700/fields/E/y                                      {32, 32, 32}
  float     /data/700/fields/E/z                                      {32, 32, 32}
  float     /data/700/fields/e_all_chargeDensity                      {32, 32, 32}
  float     /data/700/fields/e_all_energyDensity                      {32, 32, 32}
  float     /data/700/fields/e_all_particleMomentumComponent          {32, 32, 32}
  float     /data/700/fields/i_all_chargeDensity                      {32, 32, 32}
  float     /data/700/fields/i_all_energyDensity                      {32, 32, 32}
  float     /data/700/fields/i_all_particleMomentumComponent          {32, 32, 32}
  uint64_t  /data/700/fields/picongpu_idProvider/nextId               {1, 1, 1}
  uint64_t  /data/700/fields/picongpu_idProvider/startId              {1, 1, 1}

@franzpoeschel
Copy link
Contributor Author

Alright, command line parameter handling should now work. Still need to test that checkpoint/restarting is handled correctly, and I might need some help so that this PR does not also add a parameter --checkpoint.openPMD.toml. The plugin checks that toml is the only parameter specifies and fails if any other parameter has been passed.

include/picongpu/plugins/openPMD/openPMDWriter.hpp Outdated Show resolved Hide resolved
include/picongpu/plugins/openPMD/openPMDWriter.hpp Outdated Show resolved Hide resolved
include/picongpu/plugins/openPMD/openPMDWriter.hpp Outdated Show resolved Hide resolved
include/picongpu/plugins/openPMD/openPMDWriter.hpp Outdated Show resolved Hide resolved
include/picongpu/plugins/openPMD/toml.cpp Outdated Show resolved Hide resolved
include/picongpu/plugins/openPMD/toml.cpp Outdated Show resolved Hide resolved
include/picongpu/plugins/openPMD/toml.hpp Show resolved Hide resolved
@franzpoeschel
Copy link
Contributor Author

Did some thorough cleanup, including commit history

@PrometheusPi
Copy link
Member

@franzpoeschel What is the status of this pul request?

@franzpoeschel
Copy link
Contributor Author

@PrometheusPi I meet with René next week to discuss the current status. If we agree that the approach taken by this is ok, I expect it can be merged soon.

Note that this PR is not about TOML configuration for the openPMD-api, but for PIConGPU's openPMD plugin.

@franzpoeschel franzpoeschel force-pushed the toml branch 7 times, most recently from 2a35873 to c12249e Compare November 10, 2021 15:27
@franzpoeschel
Copy link
Contributor Author

franzpoeschel commented Nov 10, 2021

I added the things we talked about yesterday @psychocoderHPC:

  • Allow to call the openPMD plugin with --openPMD.toml "" --openPMD.file output --openPMD.period 100, e.g. consider empty strings as equivalent to no passed parameters
    I'd generally appreciate if someone who uses the openPMD plugin as a multi plugin could check if things are still running.
  • Added documentation. I've documented most of it with inline comments inside a sample .toml file
  • Make the toml::DataSources class stateless

@psychocoderHPC psychocoderHPC added component: plugin in PIConGPU plugin refactoring code change to improve performance or to unify a concept but does not change public API labels Nov 25, 2021
@psychocoderHPC
Copy link
Member

I tested that multi-plugin usage with command line parameters still works.
We need to rebase this PR after #3919 is merged because of conflicts in the documentation.

@franzpoeschel franzpoeschel force-pushed the toml branch 2 times, most recently from 9508fce to 6df554a Compare November 25, 2021 10:31
@psychocoderHPC
Copy link
Member

PR can be rebased

@franzpoeschel
Copy link
Contributor Author

PR can be rebased

done

@psychocoderHPC
Copy link
Member

@franzpoeschel What do you mean by Timeout for waiting on files?

@franzpoeschel
Copy link
Contributor Author

@franzpoeschel What do you mean by Timeout for waiting on files?

In our intended workflows, the TOML file is created asynchronously by the reading codes. So, as long as the file is not there yet, these lines here will sleep until the file is found. Should I keep that part? If yes, I think I should add a timeout. @psychocoderHPC

@psychocoderHPC
Copy link
Member

@franzpoeschel What do you mean by Timeout for waiting on files?

In our intended workflows, the TOML file is created asynchronously by the reading codes. So, as long as the file is not there yet, these lines here will sleep until the file is found. Should I keep that part? If yes, I think I should add a timeout. @psychocoderHPC

Ohh yes, a timeout makes sense. IMO set as default 5min.

@franzpoeschel
Copy link
Contributor Author

@franzpoeschel What do you mean by Timeout for waiting on files?

In our intended workflows, the TOML file is created asynchronously by the reading codes. So, as long as the file is not there yet, these lines here will sleep until the file is found. Should I keep that part? If yes, I think I should add a timeout. @psychocoderHPC

Ohh yes, a timeout makes sense. IMO set as default 5min.

Done and tested

ToruNiina and others added 4 commits January 27, 2022 11:14
Move collective file reading to a common header

Add TOML header and implementation

Without using it yet though

Use TOML stuff in openPMD plugin

Use stateless DataSources class

Accept empty string as unspecified parameter for toml option

Timeout 5min: If toml file is not there, throw an error
@steindev steindev dismissed psychocoderHPC’s stale review January 28, 2022 16:31

All comments adressed. Offline discussed to merge now.

@steindev steindev merged commit 67ec75d into ComputationalRadiationPhysics:dev Jan 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: plugin in PIConGPU plugin refactoring code change to improve performance or to unify a concept but does not change public API
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants