3030 --num-workers 8 # The number of GPUs
3131"""
3232
33- # pyre-ignore-all-errors
33+ # pyre-strict
3434
35+ import argparse
3536import logging
3637import signal
3738import time
39+ from argparse import Namespace
3840from collections .abc import Iterator
3941from dataclasses import dataclass
42+ from functools import partial
4043from pathlib import Path
4144from threading import Event
4245
4750from spdl .pipeline import Pipeline , PipelineBuilder
4851from torch import Tensor
4952
50- _LG = logging .getLogger (__name__ )
53+ _LG : logging . Logger = logging .getLogger (__name__ )
5154
5255__all__ = [
5356 "entrypoint" ,
6063]
6164
6265
63- def _parse_args (args ):
64- import argparse
65-
66+ def _parse_args (args : list [str ]) -> Namespace :
6667 parser = argparse .ArgumentParser (
6768 description = __doc__ ,
6869 formatter_class = argparse .RawDescriptionHelpFormatter ,
6970 )
7071 parser .add_argument ("--debug" , action = "store_true" )
7172 parser .add_argument ("--input-flist" , type = Path , required = True )
7273 parser .add_argument ("--max-samples" , type = int )
73- parser .add_argument ("--prefix" )
74+ parser .add_argument ("--prefix" , required = True )
7475 parser .add_argument ("--batch-size" , type = int , default = 32 )
7576 parser .add_argument ("--trace" , type = Path )
7677 parser .add_argument ("--buffer-size" , type = int , default = 16 )
7778 parser .add_argument ("--num-threads" , type = int , default = 16 )
7879 parser .add_argument ("--worker-id" , type = int , required = True )
7980 parser .add_argument ("--num-workers" , type = int , required = True )
80- args = parser .parse_args (args )
81- if args .trace :
82- args .max_samples = args .batch_size * 40
83- return args
81+ ns = parser .parse_args (args )
82+ if ns .trace :
83+ ns .max_samples = ns .batch_size * 40
84+ return ns
8485
8586
8687def source (
@@ -108,11 +109,11 @@ def source(
108109 yield prefix + line
109110
110111
111- async def batch_decode (
112+ def batch_decode (
112113 srcs : list [str ],
114+ device_config : spdl .io .CUDAConfig ,
113115 width : int = 224 ,
114116 height : int = 224 ,
115- device_config : spdl .io .CUDAConfig | None = None ,
116117) -> Tensor :
117118 """Given image paths, decode, resize, batch and optionally send them to GPU.
118119
@@ -124,7 +125,7 @@ async def batch_decode(
124125 Returns:
125126 The batch tensor.
126127 """
127- buffer = await spdl .io .async_load_image_batch (
128+ buffer = spdl .io .load_image_batch (
128129 srcs ,
129130 width = width ,
130131 height = height ,
@@ -158,29 +159,25 @@ def get_pipeline(
158159 Returns:
159160 The pipeline that performs batch image decoding and device transfer.
160161 """
161-
162- async def _batch_decode (srcs ):
163- return await batch_decode (srcs , device_config = device_config )
162+ decode = partial (batch_decode , device_config = device_config )
164163
165164 pipeline = (
166165 PipelineBuilder ()
167166 .add_source (src )
168167 .aggregate (batch_size )
169- .pipe (_batch_decode , concurrency = num_threads , report_stats_interval = 15 )
168+ .pipe (decode , concurrency = num_threads )
170169 .add_sink (buffer_size )
171- .build (num_threads = num_threads )
170+ .build (num_threads = num_threads , report_stats_interval = 15 )
172171 )
173172 return pipeline
174173
175174
176- def _get_pipeline (args ) :
175+ def _get_pipeline (args : Namespace ) -> Pipeline :
177176 return get_pipeline (
178177 source (args .input_flist , args .prefix , args .num_workers , args .worker_id ),
179178 args .batch_size ,
180179 device_config = (
181- None
182- if args .worker_id is None
183- else spdl .io .cuda_config (
180+ spdl .io .cuda_config (
184181 device_index = args .worker_id ,
185182 allocator = (
186183 torch .cuda .caching_allocator_alloc ,
@@ -207,13 +204,13 @@ class PerfResult:
207204 """The number of frames processed."""
208205
209206
210- def worker_entrypoint (args : list [str ]) -> PerfResult :
207+ def worker_entrypoint (args_ : list [str ]) -> PerfResult :
211208 """Entrypoint for worker process. Load images to a GPU and measure its performance.
212209
213210 It builds a :py:class:`~spdl.pipeline.Pipeline` object using :py:func:`get_pipeline`
214211 function and run it with :py:func:`benchmark` function.
215212 """
216- args = _parse_args (args )
213+ args = _parse_args (args_ )
217214 _init (args .debug , args .worker_id )
218215
219216 _LG .info (args )
@@ -223,9 +220,9 @@ def worker_entrypoint(args: list[str]) -> PerfResult:
223220
224221 device = torch .device (f"cuda:{ args .worker_id } " )
225222
226- ev = Event ()
223+ ev : Event = Event ()
227224
228- def handler_stop_signals (_signum , _frame ):
225+ def handler_stop_signals (_signum , _frame ) -> None :
229226 ev .set ()
230227
231228 signal .signal (signal .SIGTERM , handler_stop_signals )
@@ -267,21 +264,19 @@ def benchmark(loader: Iterator[Tensor], stop_requested: Event) -> PerfResult:
267264 return PerfResult (elapsed , num_batches , num_frames )
268265
269266
270- def _init_logging (debug = False , worker_id = None ):
267+ def _init_logging (debug : bool = False , worker_id : int | None = None ) -> None :
271268 fmt = "%(asctime)s [%(filename)s:%(lineno)d] [%(levelname)s] %(message)s"
272269 if worker_id is not None :
273270 fmt = f"[{ worker_id } :%(thread)d] { fmt } "
274271 level = logging .DEBUG if debug else logging .INFO
275272 logging .basicConfig (format = fmt , level = level )
276273
277274
278- def _init (debug , worker_id ) :
275+ def _init (debug : bool , worker_id : int ) -> None :
279276 _init_logging (debug , worker_id )
280277
281278
282- def _parse_process_args (args ):
283- import argparse
284-
279+ def _parse_process_args (args : list [str ] | None ) -> tuple [Namespace , list [str ]]:
285280 parser = argparse .ArgumentParser (
286281 description = __doc__ ,
287282 formatter_class = argparse .RawDescriptionHelpFormatter ,
@@ -290,7 +285,7 @@ def _parse_process_args(args):
290285 return parser .parse_known_args (args )
291286
292287
293- def entrypoint (args : list [str ] | None = None ):
288+ def entrypoint (args : list [str ] | None = None ) -> None :
294289 """CLI entrypoint. Launch the worker processes,
295290 each of which load images and send them to GPU."""
296291 ns , args = _parse_process_args (args )
0 commit comments