Инициализация большого общего массива - PullRequest
0 голосов
/ 13 февраля 2019

Мне нужно инициализировать общий массив размером> 2 ^ 32 (multiprocessing.sharedctypes.RawArray).

Наиболее рекомендуемый способ (насколько я могу судить) дляинициализировать общий массив и использовать его как ndarray by numpy следующим образом:

arr = np.array(data)
shared_arr = RawArray(type, arr.size)
shared_ndarr = np.ctypeslib.as_array(shared_arr).reshape(arr.shape)
np.copyto(shared_ndarr, arr)

Однако это вызывает следующее исключение: (я скопировал соответствующий код RawArray в конце вопроса в качестве приложения)

Файл "...", строка 67, в RawArray
type_ = type_ * size_or_initializer
OverflowError: Атрибут _length_ слишком велик

Я читал, что это может произойти из-за преобразований из целочисленного типа Python в целочисленный тип C.Я проверял, это исключение выдается только в том случае, если второй аргумент RawArray () больше, чем 2.147.483.647 (максимальное значение со знаком int32).

Мой вопрос:
Есть ли способ сказать,компилятор C для использования int64 для второго аргумента?
Или возможно объединить общие массивы?Поэтому я мог бы инициализировать их небольшими блоками, а затем объединить их.( Этот ТАК вопрос о том, что это невозможно без перемещения массивов из общей памяти.)

Также приветствуются другие идеи и решения!

Приложение:

typecode_to_type = {
    'c': ctypes.c_char,  'u': ctypes.c_wchar,
    'b': ctypes.c_byte,  'B': ctypes.c_ubyte,
    'h': ctypes.c_short, 'H': ctypes.c_ushort,
    'i': ctypes.c_int,   'I': ctypes.c_uint,
    'l': ctypes.c_long,  'L': ctypes.c_ulong,
    'f': ctypes.c_float, 'd': ctypes.c_double
    }

def RawArray(typecode_or_type, size_or_initializer):
    '''
    Returns a ctypes array allocated from shared memory
    '''
    type_ = typecode_to_type.get(typecode_or_type, typecode_or_type)
    if isinstance(size_or_initializer, int):
        type_ = type_ * size_or_initializer
        obj = _new_value(type_)
        ctypes.memset(ctypes.addressof(obj), 0, ctypes.sizeof(obj))
        return obj
    else:
        type_ = type_ * len(size_or_initializer)
        result = _new_value(type_)
        result.__init__(*size_or_initializer)
        return result
...