Как запустить пертикулярный код в gpu с помощью PyTorch?

#multiprocessing #gpu #pytorch

#многопроцессорность #графический процессор #pytorch

Вопрос:

Я использую код обработки изображений в python opencv. Поскольку этот процесс занимает много времени для обработки, скажем, 30 изображений. Я попытался обработать эти изображения параллельно, используя многопроцессорную обработку. Многопроцессорная часть работает хорошо в CPU, но я хочу использовать эту многопроцессорную функцию в GPU (cuda).

Я использую torch.multiprocessing для параллельного выполнения задачи. Итак, я использую torch.device (‘cuda’) для нашего класса, чтобы запустить все это на этом пертикулярном устройстве. Когда я запускаю код, он показывает устройство, использующее «cuda», но не использующее никакой обработки на GPU.

 import cv2
import numpy as np
import torch
import torch.nn as nn
from torch.multiprocessing import Process, Pool, Manager, set_start_method
import sys
import os

class RoadShoulderWidth(nn.Module):
    def __init__(self):  
        super(RoadShoulderWidth, self).__init__()
        pass

    // Want to run below method in parallel for 30 images.
    @staticmethod   
    def get_dim(image, road_shoulder_width_list):
        ..... code

    def get_road_shoulder_width(self, _root_dir, _img_path_list):

    manager = Manager()
    road_shoulder_width_list = manager.list()
    processes = []
    for img_path in img_path_list[:30]:
        img = cv2.imread(_root_dir   '/'   img_path)
        img = img[72 * 5:72 * 6, 0:1280]
        # Do work
        p = Process(target=self.get_dim,args=(img,road_shoulder_width_list))
        p.start()
        processes.append(p)

    for p in processes:
        p.join()
    return road_shoulder_width_list 
  

Используйте приведенный ниже набор кода для запуска вашего класса

 if __name__ == '__main__':
    root_dir = '/home/nikhil_m/r'
    img_path_list = os.listdir(root_dir)

    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    print('Using device:', device)
    dataloader_kwargs = {'pin_memory': True} 
    set_start_method('fork')   
    obj = RoadShoulderWidth().to(device)
    val = obj.get_road_shoulder_width(str(root_dir), img_path_list)
    print(val)
    print(torch.cuda.is_available())
  

Кто-нибудь может подсказать мне, как это исправить?

Ответ №1:

Ваш класс RoadShoulderWidth равен nn.Подкласс модуля, который позволяет использовать .to (устройство). Это означает только то, что все остальные объекты nn.Module или nn.Parameters, которые являются членами вашего объекта RoadShoulderWidth, перемещаются на устройство. Как видно из вашего примера, их нет, поэтому ничего не происходит.

В общем случае PyTorch перемещает на GPU не код, а данные. Если все данные операции pytorch находятся на GPU (например, a b, a и b находятся на GPU), то операция выполняется на GPU. Вы можете перемещать данные с a.to (устройство), заданное a, является факелом.Тензорный объект.

PyTorch может выполнять только свои собственные операции на GPU. Он не может выполнить код OpenCV на GPU.

Комментарии:

1. Итак, я должен преобразовать этот код OpenCV в тензор pytorch?

2. Вы можете преобразовывать данные только в тензор (это просто причудливое название для массива с несколькими размерами). Вы могли бы попробовать переписать код OpenCV в PyTorch, но я не уверен, что это будет работать быстрее. Не все работает быстрее на GPU.