@@ -2344,27 +2344,36 @@ def testScalarHdf5Fields(self):
23442344
23452345 def testKeepaliveComponentExtraction (self ):
23462346 """Test that keepalive specifications guard root objects from garbage collection."""
2347+ self .testKeepaliveMeshComponent ()
2348+ self .testKeepaliveParticlePosition ()
2349+ self .testKeepaliveParticlePatches ()
2350+
2351+ def testKeepaliveMeshComponent (self ):
2352+ """Test keepalive for mesh component extraction."""
2353+ for ext in tested_file_extensions :
2354+ self .backend_keepalive_mesh_component (ext )
2355+
2356+ def testKeepaliveParticlePosition (self ):
2357+ """Test keepalive for particle position component extraction."""
2358+ for ext in tested_file_extensions :
2359+ self .backend_keepalive_particle_position (ext )
2360+
2361+ def testKeepaliveParticlePatches (self ):
2362+ """Test keepalive for particle patches component extraction."""
23472363 for ext in tested_file_extensions :
2348- self .backend_keepalive_component_extraction (ext )
2364+ self .backend_keepalive_particle_patches (ext )
23492365
2350- def backend_keepalive_component_extraction (self , file_ending ):
2351- """Helper function that creates an openPMD Series, extracts a component,
2352- discards the parent objects, forces garbage collection, and then writes data
2353- using only the returned component."""
2366+ def backend_keepalive_mesh_component (self , file_ending ):
2367+ """Helper function that tests keepalive for mesh component extraction."""
23542368 import gc
23552369
2356- filename = "../samples/unittest_py_keepalive ." + file_ending
2370+ filename = "unittest_py_keepalive_mesh ." + file_ending
23572371 path = filename
23582372
23592373 def get_component_only ():
2360- """
2361- Create a Series, access a component, discard the Series and Iteration,
2362- and return only the component. The keepalive specification should
2363- guard the root objects from garbage collection.
2364- """
2365- series = io .Series (path , io .Access .create )
2374+ series = io .Series (path , io .Access .create_linear )
23662375 backend = series .backend
2367- iteration = series .iterations [0 ]
2376+ iteration = series .snapshots () [0 ]
23682377 mesh = iteration .meshes ["E" ]
23692378 component = mesh ["x" ]
23702379
@@ -2388,20 +2397,108 @@ def get_component_only():
23882397
23892398 component .series_flush ()
23902399 if backend == "ADIOS2" :
2391- # need to close the step for data to become visible in ADIOS2
2392- # cant close the step since we threw away the Iteration, so we need
2393- # to trigger the GC here
23942400 del component
23952401 gc .collect ()
23962402
23972403 read = io .Series (path , io .Access .read_only )
2398- loaded = read .iterations [0 ].meshes ["E" ]["x" ][:]
2404+ loaded = read .snapshots () [0 ].meshes ["E" ]["x" ][:]
23992405 read .flush ()
24002406 np .testing .assert_array_equal (
24012407 loaded ,
24022408 np .reshape (np .arange (100 , dtype = np .dtype ("float" )), [10 , 10 ])
24032409 )
24042410
2411+ def backend_keepalive_particle_position (self , file_ending ):
2412+ """Helper function that tests keepalive for particle position component extraction."""
2413+ import gc
2414+
2415+ filename = "unittest_py_keepalive_particle." + file_ending
2416+ path = filename
2417+ num_particles = 100
2418+
2419+ def get_component_only ():
2420+ series = io .Series (path , io .Access .create_linear )
2421+ backend = series .backend
2422+ iteration = series .snapshots ()[0 ]
2423+ particles = iteration .particles ["electrons" ]
2424+ position = particles ["position" ]["x" ]
2425+
2426+ position .reset_dataset (io .Dataset (np .dtype ("float" ), [num_particles ]))
2427+
2428+ del iteration
2429+ del particles
2430+ del series
2431+ gc .collect ()
2432+
2433+ return position , backend
2434+
2435+ position , backend = get_component_only ()
2436+ gc .collect ()
2437+
2438+ position [:] = np .arange (num_particles , dtype = np .dtype ("float" ))
2439+
2440+ position .series_flush ()
2441+ if backend == "ADIOS2" :
2442+ del position
2443+ gc .collect ()
2444+
2445+ read = io .Series (path , io .Access .read_only )
2446+ loaded = read .snapshots ()[0 ].particles ["electrons" ]["position" ]["x" ][:]
2447+ read .flush ()
2448+ np .testing .assert_array_equal (
2449+ loaded ,
2450+ np .arange (num_particles , dtype = np .dtype ("float" ))
2451+ )
2452+
2453+ def backend_keepalive_particle_patches (self , file_ending ):
2454+ """Helper function that tests keepalive for particle patches extraction."""
2455+ import gc
2456+
2457+ filename = "unittest_py_keepalive_patches." + file_ending
2458+ path = filename
2459+
2460+ def get_component_only ():
2461+ series = io .Series (path , io .Access .create_linear )
2462+ backend = series .backend
2463+ iteration = series .snapshots ()[0 ]
2464+ particles = iteration .particles ["electrons" ]
2465+
2466+ dset = io .Dataset (np .dtype ("float" ), [30 ])
2467+ position_x = particles ["position" ]["x" ]
2468+ position_x .reset_dataset (dset )
2469+ position_x [:] = np .arange (30 , dtype = np .float32 )
2470+
2471+ dset = io .Dataset (np .dtype ("uint64" ), [2 ])
2472+ num_particles_comp = particles .particle_patches ["numParticles" ]
2473+ num_particles_comp .reset_dataset (dset )
2474+ num_particles_comp .store (0 , np .uint64 (10 ))
2475+ num_particles_comp .store (1 , np .uint64 (20 ))
2476+
2477+ del iteration
2478+ del particles
2479+ del series
2480+ gc .collect ()
2481+
2482+ return num_particles_comp , backend
2483+
2484+ component , backend = get_component_only ()
2485+ gc .collect ()
2486+
2487+ component .store (0 , np .uint64 (50 ))
2488+
2489+ component .series_flush ()
2490+ if backend == "ADIOS2" :
2491+ del component
2492+ gc .collect ()
2493+
2494+ read = io .Series (path , io .Access .read_only )
2495+ loaded = read .snapshots ()[0 ].particles ["electrons" ].particle_patches ["numParticles" ].load ()
2496+ read .flush ()
2497+ np .testing .assert_array_equal (
2498+ loaded [0 ],
2499+ np .uint64 (50 )
2500+ )
2501+
24052502
24062503if __name__ == '__main__' :
24072504 unittest .main ()
0 commit comments