@@ -2344,27 +2344,37 @@ 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
2368+ for mesh component extraction."""
23542369 import gc
23552370
2356- filename = "../samples/unittest_py_keepalive ." + file_ending
2371+ filename = "unittest_py_keepalive_mesh ." + file_ending
23572372 path = filename
23582373
23592374 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 )
2375+ series = io .Series (path , io .Access .create_linear )
23662376 backend = series .backend
2367- iteration = series .iterations [0 ]
2377+ iteration = series .snapshots () [0 ]
23682378 mesh = iteration .meshes ["E" ]
23692379 component = mesh ["x" ]
23702380
@@ -2388,20 +2398,113 @@ def get_component_only():
23882398
23892399 component .series_flush ()
23902400 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
23942401 del component
23952402 gc .collect ()
23962403
23972404 read = io .Series (path , io .Access .read_only )
2398- loaded = read .iterations [0 ].meshes ["E" ]["x" ][:]
2405+ loaded = read .snapshots () [0 ].meshes ["E" ]["x" ][:]
23992406 read .flush ()
24002407 np .testing .assert_array_equal (
24012408 loaded ,
24022409 np .reshape (np .arange (100 , dtype = np .dtype ("float" )), [10 , 10 ])
24032410 )
24042411
2412+ def backend_keepalive_particle_position (self , file_ending ):
2413+ """Helper function that tests keepalive
2414+ for particle position component extraction."""
2415+ import gc
2416+
2417+ filename = "unittest_py_keepalive_particle." + file_ending
2418+ path = filename
2419+ num_particles = 100
2420+
2421+ def get_component_only ():
2422+ series = io .Series (path , io .Access .create_linear )
2423+ backend = series .backend
2424+ iteration = series .snapshots ()[0 ]
2425+ particles = iteration .particles ["electrons" ]
2426+ position = particles ["position" ]["x" ]
2427+
2428+ position .reset_dataset (
2429+ io .Dataset (np .dtype ("float" ), [num_particles ]))
2430+
2431+ del iteration
2432+ del particles
2433+ del series
2434+ gc .collect ()
2435+
2436+ return position , backend
2437+
2438+ position , backend = get_component_only ()
2439+ gc .collect ()
2440+
2441+ position [:] = np .arange (num_particles , dtype = np .dtype ("float" ))
2442+
2443+ position .series_flush ()
2444+ if backend == "ADIOS2" :
2445+ del position
2446+ gc .collect ()
2447+
2448+ read = io .Series (path , io .Access .read_only )
2449+ loaded = read .snapshots ()[0 ] \
2450+ .particles ["electrons" ]["position" ]["x" ][:]
2451+ read .flush ()
2452+ np .testing .assert_array_equal (
2453+ loaded ,
2454+ np .arange (num_particles , dtype = np .dtype ("float" ))
2455+ )
2456+
2457+ def backend_keepalive_particle_patches (self , file_ending ):
2458+ """Helper function that tests keepalive
2459+ for particle patches extraction."""
2460+ import gc
2461+
2462+ filename = "unittest_py_keepalive_patches." + file_ending
2463+ path = filename
2464+
2465+ def get_component_only ():
2466+ series = io .Series (path , io .Access .create_linear )
2467+ backend = series .backend
2468+ iteration = series .snapshots ()[0 ]
2469+ particles = iteration .particles ["electrons" ]
2470+
2471+ dset = io .Dataset (np .dtype ("float" ), [30 ])
2472+ position_x = particles ["position" ]["x" ]
2473+ position_x .reset_dataset (dset )
2474+ position_x [:] = np .arange (30 , dtype = np .float32 )
2475+
2476+ dset = io .Dataset (np .dtype ("uint64" ), [2 ])
2477+ num_particles_comp = particles .particle_patches ["numParticles" ]
2478+ num_particles_comp .reset_dataset (dset )
2479+ num_particles_comp .store (0 , np .uint64 (10 ))
2480+ num_particles_comp .store (1 , np .uint64 (20 ))
2481+
2482+ del iteration
2483+ del particles
2484+ del series
2485+ gc .collect ()
2486+
2487+ return num_particles_comp , backend
2488+
2489+ component , backend = get_component_only ()
2490+ gc .collect ()
2491+
2492+ component .store (0 , np .uint64 (50 ))
2493+
2494+ component .series_flush ()
2495+ if backend == "ADIOS2" :
2496+ del component
2497+ gc .collect ()
2498+
2499+ read = io .Series (path , io .Access .read_only )
2500+ loaded = read .snapshots ()[0 ] \
2501+ .particles ["electrons" ].particle_patches ["numParticles" ].load ()
2502+ read .flush ()
2503+ np .testing .assert_array_equal (
2504+ loaded [0 ],
2505+ np .uint64 (50 )
2506+ )
2507+
24052508
24062509if __name__ == '__main__' :
24072510 unittest .main ()
0 commit comments