От циклов for к матричным вычислениям - PullRequest
0 голосов
/ 31 мая 2018

У меня есть фрагмент кода, берущий ввод и проверяющий, соответствует ли ввод требованиям.Входные данные состоят из list объектов, называемых S.

class S:
    def __init__(self, f, t, tf, timeline):
        self.f = f
        self.t = t
        self.tf = tf
        self.timeline = timeline

Чтобы узнать, удовлетворяет ли комбинация объектов требованиям, у меня есть функции, принимающие list размера N изобъекты и возврат True или False.

input1 = [S_1, ..., S_N]

def c1(input1):
    if condition_c1_valid:
        return True
    else:
        return False

Теперь давайте рассмотрим этот пример:

import itertools

possible_objects = [S(f, t, tf, timeline) for f in [...] for t in [..] ...]
inputs_to_check = list(itertools.combination_with_replacement(possible_objects, 5)

results = list()
for inp in inputs_to_check:
    if c1(inp):
         results.append(inp)

В настоящее время мое решение использует цикл for для условия N, которое я проверяю каждый раз.Код сохраняет входные данные, которые удовлетворяют условию.

Может ли это быть вычислено сразу матричным способом? (Векторизация)

Я думал о чем-то вроде этого:(псевдокод)

Data[input, c1, ..., cN]
return where(all(c1, ..., cN) is True)

Может кто-нибудь сказать мне, достижимо ли это, и может указать мне на примеры?В конце мой список входных данных для проверки очень большой.Таким образом, было бы интересно отправить вычисления в графический процессор.Я думал, что, возможно, этого можно достичь с помощью Tensorflow ...

Спасибо за советы:)

РЕДАКТИРОВАТЬ: Пример выше далек от реальности.Я использую вложенные for петли на большом set, со сложностью 6-й или 7-й степени.Текущее решение оптимизировано для генераторов, но я хотел бы продвинуть это дальше.

1 Ответ

0 голосов
/ 31 мая 2018

В самом общем смысле вы не сможете векторизовать это.Известно, что CPython плохо справляется с параллельной обработкой из-за GIL, и его библиотека векторизации первичной матрицы (numpy) предназначена для работы с примитивными типами (целыми числами, числами с плавающей точкой и т. Д.), А не с объектами Python, такими как S.

Есть несколько вещей, которые могут помочь:

  1. Если f, t, tf, timeline - это числа (на которые они похожиони могут быть), тогда вы могли бы сформировать четыре массива этих значений и передать их через векторизованную версию c1, которая возвращает логический массив.Затем вы можете сделать np.asarray(input1)[c1_vec(f_vec, t_vec, tf_vec, timeline_vec)]

  2. Вы сказали, что использовали списки вместо списков, но просто чтобы быть особенно уверенным, ваш пример должен выглядеть так:

    possible_objects = (S(f, t, tf, timeline) for f in (...) for t in (...) ...) inputs_to_check = itertools.combination_with_replacement(possible_objects, 5) results = [inp for inp in inputs_to_check if c1(inp)]

    Это экономит много времени записи объектов в память, чего можно избежать.

  3. Использовать PyPy.Он использует JIT-компилятор, чтобы значительно ускорить цикл для python.Для очень больших циклов скорость увеличивается почти до C.


Вы упоминаете об использовании графического процессора.CPython даже не работает на более чем одном ядре процессора, запускать его на GPU бессмысленно, если не использовать другую реализацию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...