Каков наиболее «изящный» способ реализовать класс с параллелизацией как CPU, так и GPU в Numba? - PullRequest
0 голосов
/ 03 марта 2020

Давайте просто предположим, что я реализовал две разные версии одного и того же класса с Numba:

class cpu_foo(object):
    def init(self, data):
        # initialize the class...

    def compute(self, parameters):
        call_to_parallel_cpu_function(parameters)

class gpu_foo(object):
    def init(self, data):
        # initialize the class...
        # ...with some fine tunings for the gpu computation

    def compute(self, parameters):
        call_to_parallel_cuda_function(parameters)

И затем, в зависимости от машины, на которой я работаю, я вызываю либо одну версию, либо другую.

Я знаю, что иметь две отдельные версии одного и того же кода - ужасная практика, но я не уверен, какой самый «стандартный» способ реализовать класс, способный:

  • определить, есть ли устройство с поддержкой CUDA
  • , если да, инициализировать как класс gpu
  • , если нет, инициализировать как класс cpu

In В общем, я не смог найти никаких указаний дизайна для какого-либо языка об этом топи c ... я что-то упустил?

1 Ответ

1 голос
/ 04 марта 2020

Я думаю, что ваш вопрос был больше связан с дизайном. Возможный вариант может быть следующим:

class Gen(object):
    def __init__(self):
        pass

    def compute(self, parameters):
        # call_to_parallel_cpu_function(parameters)
        pass

    @staticmethod
    def generate_instance(_data):
        # code to detect if there is a cuda capable device
        # and return true/false and store it in cuda_device variable
        cuda_device = True 
        if cuda_device:
            return GpuFoo(_data)
        else:
            return CpuFoo(_data)


class CpuFoo(Gen):
    def __init__(self, data):
        super(CpuFoo, self).__init__()
        self.data = data

    def compute(self, parameters):
        # call_to_parallel_cpu_function(parameters)
        pass


class GpuFoo(Gen):
    def __init__(self, data):
        super(GpuFoo, self).__init__()
        self.data = data

    def compute(self, parameters):
        # call_to_parallel_cuda_function(parameters)
        pass

Gen.generate_instance([1]).compute([2])  # an example of how to use

Gen - это базовый класс, который имеет метод c stati generate_instance, который сгенерировал требуемый экземпляр в соответствии с возможностями устройства. CpuFoo и GpuFoo являются двумя подклассами и наследуют базовый класс Gen и предоставляют собственную реализацию метода compute.

Дайте мне знать, если это поможет !!

PS. Gen.generate_instance([1]) определяет, является ли устройство устройством с поддержкой CUDA, и, если оно установлено, возвращает экземпляр класса GpuFoo, в противном случае возвращается экземпляр CpuFoo.

...