@@ -242,35 +242,40 @@ def _record_logical_metrics(
242242 logical_bytes : int ,
243243 duration : float ,
244244 storage_type : str ,
245+ custom_prefix : str = '' ,
245246):
246247 """Records logical bytes, throughput, and duration to JAX monitoring."""
247248 logical_throughput = logical_bytes / duration if duration > 0 else 0
248249
249250 logging .info (
250251 '[process=%d] %s throughput: %s/s (total gbytes: %s) (time elapsed: %s s)'
251- ' (per-host)' ,
252+ ' (per-host)%s ' ,
252253 multihost .process_index (),
253254 f'/jax/orbax/{ direction .value } /worker/io/requested' ,
254255 humanize .naturalsize (logical_throughput , binary = True , format = '%.3f' ),
255256 humanize .naturalsize (logical_bytes , binary = True ),
256257 duration ,
258+ f' (prefix: { custom_prefix } )' if custom_prefix else '' ,
257259 )
258260
259261 jax .monitoring .record_event_duration_secs (
260262 f'/jax/orbax/{ direction .value } /worker/total_duration_secs' ,
261263 duration ,
262264 storage_type = storage_type ,
265+ custom_prefix = custom_prefix ,
263266 )
264267
265268 jax .monitoring .record_scalar (
266269 f'/jax/orbax/{ direction .value } /worker/io/requested/gbytes' ,
267270 logical_bytes / (1024 ** 3 ),
268271 storage_type = storage_type ,
272+ custom_prefix = custom_prefix ,
269273 )
270274 jax .monitoring .record_scalar (
271275 f'/jax/orbax/{ direction .value } /worker/io/requested/throughput/gbytes_per_sec' ,
272276 logical_throughput / (1024 ** 3 ),
273277 storage_type = storage_type ,
278+ custom_prefix = custom_prefix ,
274279 )
275280
276281
@@ -280,6 +285,7 @@ def _record_raw_metrics(
280285 duration : float ,
281286 storage_type : str ,
282287 initial_ts_metrics : Sequence [dict [str , Any ]] | None = None ,
288+ custom_prefix : str = '' ,
283289):
284290 """Records raw metrics collected from TensorStore."""
285291 if initial_ts_metrics is None :
@@ -307,22 +313,25 @@ def _record_raw_metrics(
307313 raw_throughput = raw_bytes / duration if duration > 0 else 0
308314 logging .info (
309315 '[process=%d] Raw %s throughput: %s/s (total gbytes: %s) (time elapsed:'
310- ' %s s) (per-host)' ,
316+ ' %s s) (per-host)%s ' ,
311317 multihost .process_index (),
312318 f'/jax/orbax/{ direction .value } /worker/io/raw' ,
313319 humanize .naturalsize (raw_throughput , binary = True , format = '%.3f' ),
314320 humanize .naturalsize (raw_bytes , binary = True ),
315321 duration ,
322+ f' (prefix: { custom_prefix } )' if custom_prefix else '' ,
316323 )
317324 jax .monitoring .record_scalar (
318325 f'/jax/orbax/{ direction .value } /worker/io/raw/gbytes' ,
319326 raw_bytes / (1024 ** 3 ),
320327 storage_type = storage_type ,
328+ custom_prefix = custom_prefix ,
321329 )
322330 jax .monitoring .record_scalar (
323331 f'/jax/orbax/{ direction .value } /worker/io/raw/throughput/gbytes_per_sec' ,
324332 raw_throughput / (1024 ** 3 ),
325333 storage_type = storage_type ,
334+ custom_prefix = custom_prefix ,
326335 )
327336
328337 if logical_bytes > 0 :
@@ -339,12 +348,14 @@ def _record_raw_metrics(
339348 f'/jax/orbax/{ direction .value } /worker/io/compression_ratio' ,
340349 ratio ,
341350 storage_type = storage_type ,
351+ custom_prefix = custom_prefix ,
342352 )
343353 if direction == types .IoDirection .WRITE :
344354 jax .monitoring .record_scalar (
345355 '/jax/orbax/write/worker/io/compressed_gbytes' ,
346356 raw_bytes / (1024 ** 3 ),
347357 storage_type = storage_type ,
358+ custom_prefix = custom_prefix ,
348359 )
349360
350361
@@ -354,6 +365,7 @@ def _log_io_metrics(
354365 start_time : float ,
355366 parent_dir : epath .Path ,
356367 initial_ts_metrics : Sequence [dict [str , Any ]] | None = None ,
368+ custom_prefix : str = '' ,
357369):
358370 """Logs and records IO telemetry metrics for array serialization/deserialization."""
359371 duration = time .time () - start_time
@@ -364,13 +376,15 @@ def _log_io_metrics(
364376 logical_bytes ,
365377 duration ,
366378 storage_type ,
379+ custom_prefix = custom_prefix ,
367380 )
368381 _record_raw_metrics (
369382 direction ,
370383 logical_bytes ,
371384 duration ,
372385 storage_type ,
373386 initial_ts_metrics = initial_ts_metrics ,
387+ custom_prefix = custom_prefix ,
374388 )
375389
376390
@@ -664,6 +678,7 @@ def _serialize_batch(
664678 batch_infos : Sequence [types .ParamInfo ],
665679 batch_args : Sequence [types .SaveArgs ],
666680 batch_arrays : Sequence [jax .Array ],
681+ d2h_start_time : float | None = None ,
667682 ):
668683 ret = dispatcher .dispatch (
669684 _worker_serialize_arrays ,
@@ -688,13 +703,24 @@ def _serialize_batch(
688703 'ext_metadata' : ext_metadata ,
689704 },
690705 )
706+ if d2h_start_time is not None :
707+ jax .block_until_ready (batch_arrays )
708+ _log_io_metrics (
709+ direction = types .IoDirection .WRITE ,
710+ logical_bytes = sum (v .nbytes for v in batch_arrays ),
711+ start_time = d2h_start_time ,
712+ parent_dir = batch_infos [0 ].parent_dir ,
713+ custom_prefix = 'd2h' ,
714+ )
715+
691716 _on_batch_callback (batch_infos , callback .on_transfer_end )
692717
693718 jax .block_until_ready (ret )
694719
695720 _on_batch_callback (batch_infos , callback .on_write_end )
696721
697722 # Enqueue D2H operation for prioritized values.
723+ d2h_start_time = None
698724 if prioritized :
699725 logging .info (
700726 'Scheduling D2H of %d prioritized jax.Array.' ,
@@ -703,6 +729,7 @@ def _serialize_batch(
703729 prioritized_arrays , prioritized_infos , prioritized_args = zip (
704730 * prioritized
705731 )
732+ d2h_start_time = time .time ()
706733 prioritized_arrays = dispatcher .device_to_host (prioritized_arrays )
707734 prioritized = [
708735 (v , i , a )
@@ -723,7 +750,7 @@ async def _serialize():
723750 await info .await_path_creation ()
724751 if prioritized :
725752 arrays , infos , args = zip (* prioritized )
726- _serialize_batch (infos , args , arrays )
753+ _serialize_batch (infos , args , arrays , d2h_start_time )
727754 if deprioritized :
728755 assert device_host_max_bytes is not None
729756 for (
0 commit comments