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

Generic processing of assumed rank objects #144

Open
reinh-bader opened this issue Feb 14, 2020 · 12 comments
Open

Generic processing of assumed rank objects #144

reinh-bader opened this issue Feb 14, 2020 · 12 comments
Labels
Clause 9 Standard Clause 9: Use of data objects

Comments

@reinh-bader
Copy link

The concept of assumed rank permits definition of interfaces that are rank-agnostic.
The addition of the SELECT RANK block construct permits definitions and references to the object by resolving at run time to whatever rank the actual argument has. This is fine in case the array rank e.g. reflects different problem dimensions, requiring different algorithms for its solution. However, there are also cases in which uniform treatment of the argument's data irrespective of its rank is required. This is currently cumbersome to do.

This proposal suggests supporting this at least for the case of a CONTIGUOUS argument by remapping to a suitable rank-1 entity.

Variant 1: Permit pointer assignment

Assuming declarations
REAL, CONTIGUOUS, TARGET :: X(..)
REAL, POINTER :: XP(:)
it should be permissible to write
XP(1:SIZE(X)) => X
Note that for X assumed shape and any rank, this is already permitted. Some words would be needed to treat the rank 0 and rank "*" cases. The data in X could then be processed via XP.

Variant 2: Extend ASSOCIATE semantics

Assuming a declaration
REAL, CONTIGUOUS :: X(..)
it should be permissible to write
ASSOCIATE(XA(1:SIZE(X)) => X)
... ! definitions and references to XA
END ASSOCIATE

This variant would not require the TARGET attribute on X. Inside the ASSOCIATE block, the data could be processed via XA.

Requiring the CONTIGUOUS attribute imposes no limitation on functionality. Users need to be made aware of the potential performance impact for copy-in/out.

@arjenmarkus
Copy link

Having read your proposal, I am inclined towards the ASSOCIATE alternative - it feels more inline with the newer constructs. I guess it also be possible to do:
M = 10 N = SIZE(X)/M ASSOCIATE( XA(1:N,1:M) => X)
irrespective of the rank of X.
Otherwise, if the ASSOCIATE is limited to one-dimensional "mappings", the "(1:SIZE(X)" could be replaced by "(:)" to indicate that a one-dimensional mapping is required. (I am sure I do not oversee all ramifications)

@reinh-bader
Copy link
Author

reinh-bader commented Feb 14, 2020

While permission of multi-rank mappings could certainly be allowed, it is not really germane to the use-case at hand. I also prefer the ASSOCIATE, but the rank-remapped pointer conveys the idea, since it is already in the language. The bounds specs, I think, are necessary. Especially for the rank "*" case.

@aradi
Copy link
Contributor

aradi commented Feb 24, 2020

I think, this possibility could/should be combined with the possibility of returning an array of arbitrary rank in a function, and a generic way to access the indexing of the arrays, similar how it can be already in C since Fortran 2018.

module test
  implicit none

contains

  function sum_wrapper(array, dim) result(redarray)
    real, dimension(..), intent(in) :: array
    integer, intent(in) :: dim
    ! Dimension would be an array of "slice-types" allowing dynamic
    ! determination of the shape of the returned array
    real, dimension(get_redarray_shape(array, dim)) :: redarray

    redarray(get_redarray_shape(array, dim)) = sum(array, dim=dim)

  end function sum_wrapper


  pure function get_redarray_shape(array, dim) result(redshape)
    real, dimension(..), intent(in) :: array
    integer, intent(in) :: dim
    type(slice), dimension(rank(array) - 1) :: redshape
    integer :: ii

    do ii = 1, dim - 1
      ! With the intrinsic function get_slices, we should get access to the
      ! slicing parameters of the array (similar, how you can do it in C since
      ! Fortran 2018)
      redshape(ii) = get_slices(array, dim=ii)
    end do
    do ii = dim + 1, rank(array)
      redshape(ii - 1) = get_slices(array, dim=ii)
    end do

  end function get_redarray_shape

end module test

This possibility, combined with the multi-rank mapping as suggested by @arjenmarkus would eliminate a lot of the Fypp-magic in the stdlib-statistical functions.

@reinh-bader
Copy link
Author

Has the concept of type(slice) already been submitted as an issue?
Further, how do you invoke sum_wrapper? Fortran currently defines no semantics for array expressions whose rank is not determined at compile time.

@aradi
Copy link
Contributor

aradi commented Feb 24, 2020

I've now created issue #153 for that in order not to pollute this issue.

@certik certik added the Clause 9 Standard Clause 9: Use of data objects label Apr 23, 2022
@reinh-bader
Copy link
Author

Paul Thomas has suggested to also permit RESHAPE with an assumed-rank argument. For this, the CONTIGUOUS attribute would not be needed.

Also, it appears that the feature is relatively easy to implement, so would give good bang for the buck.

@PaulThomas1000
Copy link

Poor Reinhold did not have time enough on this Earth to continue the conversation. May he rest in peace.

I have attached the files that I sent him, including a provisional implementation for gfortran. I intend to take this further since I find this approach to generic rank objects to be highly intuitive.

I had been testing the algorithm for the reduce intrinsic function, which is not yet implemented in gfortran. The commented out rank-ology has been neatly replaced by reshape.

redinproposalforassumedrankentities.zip

@certik
Copy link
Member

certik commented Jul 3, 2024

@PaulThomas1000 excellent. If you know how to prototype this in GFortran, please go ahead and definitely pursue that. That is what we need to be doing for every proposed feature. It will also greatly improve the chances of it being accepted.

@PaulThomas1000
Copy link

PaulThomas1000 commented Jul 3, 2024 via email

@certik
Copy link
Member

certik commented Jul 3, 2024

@PaulThomas1000 Perfect, I think that's a great plan. Thank you for doing that.

@FortranFan
Copy link
Member

FortranFan commented Jul 6, 2024 via email

@PaulThomas1000
Copy link

PaulThomas1000 commented Jul 16, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Clause 9 Standard Clause 9: Use of data objects
Projects
None yet
Development

No branches or pull requests

6 participants