WedX - журнал о программировании и компьютерных науках

Вернуть указатель 2D Cython на массив Python

В настоящее время я передаю из Cython в C следующий указатель указателя:

    #convert the input Python 2D array to a memory view
    cdef double[:,:] a_cython= np.asarray(a,order="C")
    #define a pointer of a pointer with dimensions of a
    cdef double** point_to_a = <double **>malloc(N * sizeof(double*))
    #initialize the pointer
    if not point_to_a: raise MemoryError
    #try:
    for i in range(N):
        point_to_a[i] = &a_cython[i, 0]

    #pass this double pointer to a C function
    logistic_sigmoid(&point_to_a[0], N,M)

где a — массив numpy, размеры которого равны N x M, point_to_a — это указатель Cython на указатель, который ссылается на представление памяти Cython a_cython. Поскольку ввод a из Python представляет собой двумерный массив, я подумал, что это лучший подход для передачи информации непосредственно в C. Переход проходит гладко, и вычисления выполняются правильно. Однако сейчас я пытаюсь повторно преобразовать обратно point_to_a в массив numpy, но я немного борюсь.

Я рассматриваю различные решения. Я хотел бы изучить, возможно ли сохранить N-мерный массив на протяжении всего процесса, поэтому я экспериментировал с этим подходом в Cython:

    #define a integer array for dimensions
    cdef np.npy_intp dims[2]
    dims[0]=  N
    dims[1] = M
    #create a new memory view and PyArray_SimpleNewFromData to deal with the pointer
    cdef np.ndarray[double, ndim=2] new_a =  np.PyArray_SimpleNewFromData(2, &dims[0], np.NPY_DOUBLE, point_to_a)

однако, когда я преобразовываю new_a в np.array как array = np.asarray(new_a), у меня есть массив только с 0. У тебя есть идеи?

Спасибо большое

29.05.2020

Ответы:


1

Как только вы используете int** (или аналогичный), ваши данные находятся в так называемой непрямой структуре памяти. Типизированные представления памяти Cython поддерживают непрямую компоновку памяти (см., например, Cython: понимание типизированного представления памяти с косвенной_непрерывной компоновкой памяти), однако классов, реализующих этот интерфейс, не так много.

Ndarrays Numpy не реализуют непрямую компоновку памяти — они поддерживают только прямую компоновку памяти (например, указатель типа int*, а не int**), поэтому передача int** в массив numpy не принесет пользы.

Хорошо то, что, поскольку вы разделяете память с a_cython, значения уже были обновлены на месте. Вы можете получить базовый массив numpy, вернув base-объект типизированного представления памяти, т.е.

return a_cython.base # returns 2d-numpy array.

нет необходимости копировать память вообще!


Однако есть некоторые проблемы с управлением памятью (например, вам нужно освободить point_to_a).

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

С indirect_buffer ваша функция может выглядеть следующим образом:

%%cython
#just an example for a c-function
cdef extern from *:
    """
    void fillit(int** ptr, int N, int M){
       int cnt=0;
       for(int i=0;i<N;i++){
          for(int j=0;j<M;j++){
            ptr[i][j]=cnt++;
          }
       }
    }
    """
    void fillit(int** ptr, int N, int M)

from indirect_buffer.buffer_impl cimport IndirectMemory2D
def py_fillit(a):
    #create collection, it is a view of a
    indirect_view=IndirectMemory2D.cy_view_from_rows(a, readonly=False)
    fillit(<int**>indirect_view.ptr, indirect_view.shape[0], indirect_view.shape[1])
    # values are updated directly in a

который теперь можно использовать, например:

import numpy as np
a=np.zeros((3,4), dtype=np.int32)
py_fillit(a)
print(a)
# prints as expected:
#  array([[ 0,  1,  2,  3],
#         [ 4,  5,  6,  7],
#         [ 8,  9, 10, 11]])

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

29.05.2020
  • a_cython._base Я совсем забыл об этом! и большое спасибо за вашу тяжелую работу в репозитории косвенного_буфера. Определенно супер-ресурс для регулярного использования. Бесконечно благодарен! 29.05.2020
  • Новые материалы

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..


    Для любых предложений по сайту: [email protected]