Skip to content

Enforce memory contiguity of input numpy array

Kevin" Seung Whan Chung edited this page Aug 10, 2023 · 2 revisions

Our current convention for double * is to handle them in the form of numpy.array. One issue with this is that numpy.array sometimes does not necessarily have a contiguous memory. libROM's implementation with double * is predicated upon the assumption that the array memory is always contiguous, thus requiring an enforcement at pybind interface.

For example, the numpy array col_vec in the following examples is contiguous in memory:

Valid case 1 Column vectors from fortran-contiguous 2d numpy array

import numpy as np
input_snapshot = np.array([[ 0.5377, -1.3077, -1.3499],
                           [ 1.8339, -0.4336,  3.0349],
                           [-2.2588,  0.3426,  0.7254],
                           [ 0.8622,  3.5784, -0.0631],
                           [ 0.3188,  2.7694,  0.7147]], order = 'F') # <- note the order = 'F'
idx = 1 # some random column index between 0 - 2
col_vec = input_snapshot[:, idx]

Valid case 2 The transpose of the matrix is constructed first then transposed back to the original shape. Its column vector is then contiguous in memory

input_snapshot = np.array([[0.5377, 1.8339, -2.2588, 0.8622, 0.3188],
                           [-1.3077, -0.4336, 0.3426, 3.5784, 2.7694],
                           [-1.3499, 3.0349, 0.7254, -0.0631, 0.7147]]) # <- note the order is default
input_snapshot = input_snapshot.T # <- note this transpose does not change the memory contiguity
idx = 1 # some random column index between 0 - 2
col_vec = input_snapshot[:, idx]

However, the following examples are not contiguous in memory:

Invalid case 1 Column vectors from the default 2d numpy array (row-major order)

input_snapshot = np.array([[ 0.5377, -1.3077, -1.3499],
                           [ 1.8339, -0.4336,  3.0349],
                           [-2.2588,  0.3426,  0.7254],
                           [ 0.8622,  3.5784, -0.0631],
                           [ 0.3188,  2.7694,  0.7147]]) # <- note the order is default
idx = 1 # some random column index between 0 - 2
col_vec = input_snapshot[:, idx]

Invalid case 2 Row vectors of the transposed matrix, which originally constructed in default row-major order

input_snapshot = np.array([[ 0.5377, -1.3077, -1.3499],
                           [ 1.8339, -0.4336,  3.0349],
                           [-2.2588,  0.3426,  0.7254],
                           [ 0.8622,  3.5784, -0.0631],
                           [ 0.3188,  2.7694,  0.7147]]) # <- note the order is default
input_snapshot = input_snapshot.T # <- note this transpose does not change the memory contiguity
idx = 1 # some random column index between 0 - 2
col_vec = input_snapshot[idx, :] # <- even though it's a row vector, it is still not contiguous in memory.
Clone this wiki locally