Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SLICOT routines alter input parameters #208

Open
bnavigator opened this issue Aug 26, 2023 · 2 comments
Open

SLICOT routines alter input parameters #208

bnavigator opened this issue Aug 26, 2023 · 2 comments
Labels
Milestone

Comments

@bnavigator
Copy link
Collaborator

Opening a new issue because the wrapper function specific issue and the PR are closed already.

Slycot must be more careful with F2PY mappings of in/out parameters. See #200 for discussion.

@bnavigator bnavigator added this to the 0.6.0 milestone Aug 26, 2023
@bnavigator bnavigator added the bug label Jan 8, 2024
@bnavigator bnavigator modified the milestones: 0.6.0, 0.7 Jan 28, 2024
@KybernetikJo
Copy link
Contributor

KybernetikJo commented Jan 28, 2024

I was investigating this quite a bit. The behavior of f2py can be surprising.

I still think

intent(in,out,copy)

is the best option. It makes the API save and clean. However, a downside is that all arrays are copied. These could lead to a drop in runtime performance, especially for very big arrays.

Another option could be to use

intent(in,overwrite)

Now the behavior depends on the memory order of the arrays. In numpy there are two memory types of arrays:

The f2py behavior depends on the memory order. The underlying SLICOT routines need FORTRAN-contiguous arrays. Without intent(copy) FORTRAN-contiguous numpy arrays go through without a copy. These arrays are altered by Slycot routines.
C-contiguous arrays will trigger a copy, in order to get FORTRAN-contiguous arrays. These arrays are NOT altered by Slycot routines.
All numpy vectors (pure, row, column) are both FORTRAN-contiguous and C-contiguous at the same time. These vectors are altered by Slycot routines.

There are more things, that must be considered, like data type mismatch (e.g. np.float32 and FORTRAN double precision), which can also trigger a copy.

Maybe I will reach out to the f2py developers at some point, in order to full grasp the details.

I will do a detail analysis at some point in the future and sum it up in a report.

@ilayn
Copy link

ilayn commented Jan 28, 2024

The Fortran behavior is always pass by reference. Hence you have to give the right order and right dtype to have the bindings to work correctly. You can't escape the in-between copies when you are using Python. Unless you specifically start with Fortran arrays with exact dtypes according to <s, d, c, z> flavors.

If the target routine and the call argument does not match and/or the layout is not Fortran contiguous (note that A[1:3, 1:3] is not contiguous even if A is), f2py up/down casts (if possible) and creates a copy of the array. Even if you write overwrite it will overwrite this interim array and you get the eventual copy back.

This is the price we pay for using Fortran in Python via f2py. SLICOT routines have no inherent performance considerations and typically a copy is a negligible cost compared to other, very often O(n**3) operations.

Like we discussed elsewhere previously, I am seriously considering rewriting SLICOT in a different language possibly in pure Python even which I did some already in harold without sacrificing too much performance. The initial response is always that's a lot of work or that's a bad idea and so on. I am aware. But once you start doing it it gets going, see scipy/scipy#18566 for 30K LOC of F77 already converted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants