The negative influence of directly converting inputs to tensors and transferring back to CPU
Open
@szkarpinski is already working on this.
Since Oct 4, 2024.
question
- Dominant language
- C++
- Stars
- 5.8k
- Forks
- 678
- Avg merge
- 3d 1h
- Merged PRs (30d)
- 27
Description
Describe the question.
Hi, recently I want to run DALI for some preprocessing pipelines in GPU and I find some problems which are very weird.
My pipeline is like this:
class SimCLR_DALIPipeline(Pipeline):
def __init__(self, batch_size, num_threads, device_id, size, s=1, prefetch_queue_depth=1, py_num_workers=1, device='gpu'):
super(SimCLR_DALIPipeline, self).__init__(batch_size, num_threads, device_id, seed=12, prefetch_queue_depth=prefetch_queue_depth, py_num_workers=py_num_workers)
self.size = size
self.s = s
self.loader = load_binary_images(batch_size)
self.input = fn.external_source(source=self.loader, device=device)
self.resized_crop = fn.random_resized_crop(self.input, size=(size, size), device=device)
flip_coin = fn.random.coin_flip(probability=0.5)
self.horizontal_flip = fn.flip(self.resized_crop, horizontal=flip_coin, device=device)
self.color_jitter = fn.color_twist(self.horizontal_flip,
brightness=0.8 * s,
contrast=0.8 * s,
saturation=0.8 * s,
hue=0.2 * s,
device=device)
self.random_grayscale = fn.color_space_conversion(self.color_jitter, image_type=types.RGB, output_type=types.GRAY, device=device)
self.gaussian_blur = fn.gaussian_blur(self.random_grayscale, window_size=int(0.1 * size), device=device)
self.to_tensor = fn.cast(self.gaussian_blur, dtype=types.FLOAT, device=device)
def define_graph(self):
images = self.input[0]
return self.to_tensor
And this is how I access the data in this pipeline (preprocessed_images is not in use):
pipeline = SimCLR_DALIPipeline(batch_size=args.batch_size, num_threads=args.num_thread, device_id=args.gpu_index, size=96, prefetch_queue_depth=args.prefetch_queue_depth, py_num_workers=args.py_num_workers, device=args.device)
pipeline.build()
dali_iterator = DALIGenericIteratorWithViews([pipeline], size=args.dataset_size, n_views=args.n_views)
# Iterate over DALI preprocessed images
start_time = time.time()
for epoch in range(args.epochs):
for batch in tqdm(dali_iterator, total=len(dali_iterator), desc=f"Epoch {epoch + 1}"):
for views in batch:
for elem in views:
# preprocessed_images = elem['data'].cpu().numpy()
preprocessed_images = elem['data']
dali_iterator.reset()
stats = pipeline.executor_statistics()
print(stats)
The problem is that:
- If I remove all operators (directly convert from self.input to self.to_tensor) and leave the final tensors in GPU, its performance is simlilar to containing these operators (this is expected).
- If I remove all operators and transfer the final tensors back to CPU, for different batch size, the time varies significantly and can be much larger than keeping these tensors in GPU.
- If I contain these operators in the pipeline and transfer the final tensors back to CPU, its performance is a bit better but still larger than keeping tensors in GPU.
- pipeline.executor_statistics() does not work and there is no output.
Here is the plot:
In the command, I fix some other parameters, like num_threads, prefetch_queue_depth, py_num_workers.
I test in 3090 in local machine and in Nvidia V100 in google cloud and observe similar phenomenon.
Check for duplicates
- I have searched the open bugs/issues and have found no duplicates for this bug report
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.