Skip to content

Commit 6e49346

Browse files
committed
Lazily create one decoder per worker thread and fail on fork detection
1 parent dc6244e commit 6e49346

1 file changed

Lines changed: 26 additions & 5 deletions

File tree

src/megatron/energon/flavors/webdataset/nvimagecodec_decoder.py

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Copyright (c) 2025, NVIDIA CORPORATION.
22
# SPDX-License-Identifier: BSD-3-Clause
3+
import os
4+
import threading
35
import warnings
46
from typing import Literal
57

@@ -70,10 +72,10 @@ def __init__(
7072
self.decode_params = nvimgcodec.DecodeParams(
7173
color_spec=color_space_map[color_space.replace("8", "")]
7274
)
73-
self.decoder = nvimgcodec.Decoder(
74-
device_id=device,
75-
max_num_cpu_threads=1,
76-
)
75+
self.device = device
76+
77+
self._thread_local = threading.local()
78+
self._creator_pid = os.getpid()
7779

7880
def __call__(self, key: str, data: bytes) -> torch.Tensor | None:
7981
"""Decode image data using the GPU accelerated decoder
@@ -106,7 +108,26 @@ def __call__(self, key: str, data: bytes) -> torch.Tensor | None:
106108
)
107109
):
108110
return None
109-
nv_img = self.decoder.decode(data, params=self.decode_params)
111+
112+
if os.getpid() != self._creator_pid:
113+
raise RuntimeError(
114+
"GPU image decoding requires thread-based dataloader workers, set worker_type='thread' or worker_type='main'."
115+
)
116+
117+
decoder = getattr(self._thread_local, "decoder", None)
118+
if decoder is None:
119+
decoder = self._thread_local.decoder = nvimgcodec.Decoder(
120+
device_id=self.device,
121+
max_num_cpu_threads=1,
122+
)
123+
self.thread_local.stream = torch.cuda.Stream(self.device)
124+
125+
stream = self._thread_local.stream
126+
127+
nv_img = self.decoder.decode(
128+
data, params=self.decode_params, cuda_stream=stream.cuda_stream
129+
)
130+
stream.synchronize() # ensure nv_img lands on the default cuda stream
110131

111132
if hasattr(nv_img, "__dlpack__"):
112133
tensor_img = torch.from_dlpack(nv_img).permute(2, 0, 1)

0 commit comments

Comments
 (0)