Accepting F-contiguous arrays and passing them to C is questionable
The following code shows that F-contiguous arrays can cause to a user big pain. It is questionable whether they should be accepted by petsc4py.
Passing F-contiguous array to Vec.__getitem__
goes seemsingly fine, the returned array has the same shape. One would intuitively expect the failing assert to pass.
from petsc4py import PETSc
import numpy as np
# Create Vec = 0, 1, 2, ...
v = PETSc.Vec().create(PETSc.COMM_SELF)
v.setSizes(8)
v.setType(PETSc.Vec.Type.SEQ)
idx = np.arange(v.size, dtype=PETSc.IntType)
val = np.arange(v.size, dtype=PETSc.ScalarType)
v.setValues(idx, val)
# All arrays in C-ordering
I = np.arange(6, dtype=PETSc.IntType).reshape(2, 3)
V = v[I]
assert np.allclose(I, V) # Ok
# Index by F-ordered array
I = I.T
V = v[I]
assert I.shape, V.shape # Ok
assert np.allclose(I, V) # Fails because of mixed orderings!
# This is what petsc4py client has to do now
V = v[np.ascontiguousarray(I)]
assert np.allclose(I, V) # Ok
assert np.allclose(np.ascontiguousarray(I), V) # Ok
Comments (10)
-
reporter -
Well, you are indexing a PETSc vector with an index array of dim larger than one. I never expected Vec's to work as full fledged array containers. I hope you are not expecting me to provide the full set of indexing a broadcasting rules NumPy has! Maybe the right thing to do would be to error if the index array has dim > 1. Or try to propagate ordering and shape from indices to values. Patches welcome.
About F-arrays, well we have them there, NumPy/SciPy is sometimes not careful enough to return them consistently. In PETSc we have things like
MAT_ROW_ORIENTED
to set values in matrices using Fortran order. How should we handle that case? -
reporter Would it make sense to insist that values and indices passed in have the same ordering (resp. allocate values of the same ordering in the case of
__getitem__
)? -
Mmm, yes, I think that would make total sense, though it may prove tricky to implement the right way. For the allocation part, we could use
PyArray_NewLikeArray
, for the checks, well, I'm not sure how deep to go (just order? order and shapes? order and shapes, with special handling of 1D arrays?). -
reporter 1D does not need special handling; 1D array is both C and F:
assert np.arange(8).flags['C'] assert np.arange(8).flags['F']
-
I was talking about adding checking for shapes. Because right now petsc4py does not check for equal shapes, just that the array sizes match. So, for examples, in
vec.getValues(idx,val)
, ifidx
is a 2D array, butval
is a 1D array (or the other way around), should that be an error? -
reporter Technically checking size and ordering is enough. On the other hand if petsc4py insisted on matching shape, user can always pass in reshaped array (which is a view) to conform.
-
OK, all right. Let's keep it simple and go for sizes and orderings. I'm not sure when I'll have time to work on this, though.
-
reporter Ok, if I found a time, I would reassign to myself.
-
- changed status to closed
- Log in to comment
Offending code is here and here.