Skip to content

Support allocatable in lpython #1815

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

Merged
merged 3 commits into from
May 18, 2023
Merged

Conversation

Smit-create
Copy link
Collaborator

@Smit-create Smit-create commented May 16, 2023

@certik
Copy link
Contributor

certik commented May 17, 2023

Looks good so far. Tests need to be added.

@Smit-create
Copy link
Collaborator Author

Thanks. We need to figure out a syntax to support allocating the Allocatable arrays equivalent to Allocate in ASR. So do we want to support that using the empty() function itself? or do we want to have a subroutine just for allocating just like the allocate keyword in Fortran?

@certik
Copy link
Contributor

certik commented May 17, 2023

I think the syntax you chose is fine. This:

    a: Allocatable[f64[:]] = empty((n,), dtype=float64)

is equivalent to:

real(dp), allocatable :: a(:)
allocate(a(n))

And this:

    b: Allocatable[i32[:]]
    n = 10
    b = empty((n,), dtype=int32)

is equivalent to:

integer, allocatable :: b(:)
n = 10
allocate(b(n))

I think the deallocation is also equivalent, when the array goes out of scope it gets deallocated (both in Python and Fortran).

The alternative design is to do something like:

a: Allocatable[f64[:]] = allocate((n,), dtype=float64)

And somehow mark the array as "allocatable".

In the design of this PR, the array in CPython looks exactly like any other numpy array. In ASR it is "allocatable".

Let me ask this: do we currently have any way to do the following:

n = 10
a: f64[n] = empty((n,), dtype=float64)

Here f64[n] is not allowed, since "n" is a local variable. If it was a function argument, then it is allowed and the array is a local stack array, not allocatable. So allocatable in ASR seems to be the only way to declare a local runtime array, correct? I think starting with explicit Allocatable[f64[:]] is the way to go for now.

Another common use case is:

integer, allocatable :: x(:)
do i = 1, 10
    allocate(x(i))
    x = ...
    print *, x
    deallocate(x)
end do

which in Python would become:

for i in range(1, 11):
    x: Allocatable[i32[:]] = empty((i,), dtype=int32)
    x[:] = ...
    print(x)

When it goes out of scope, it gets deallocated, so we can allocate it again in the next iteration. Although here one issue is that for local variables in a loop there might be slightly different semantics. This however should be equivalent:

integer, allocatable :: x(:)
allocate(x(10))
x = ...
print *, x
deallocate(x)
do i = 1, 10
    allocate(x(i))
    x = ...
    print *, x
    deallocate(x)
end do

which in Python would become:

x: Allocatable[i32[:]] = empty((10,), dtype=int32)
x[:] = ...
print(x)
for i in range(1, 11):
    x = empty((i,), dtype=int32)
    x[:] = ...
    print(x)

It's a bit confusing to me, since in Fortran you need to explicitly deallocate if you want to allocate the same array again. It gets automatically deallocated when it goes out of scope. In Python I guess we would insert a deallocate before x = empty((i,), dtype=int32).

Copy link
Contributor

@certik certik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks good as a start.

@Smit-create Smit-create marked this pull request as ready for review May 18, 2023 03:29
@Smit-create
Copy link
Collaborator Author

Let me ask this: do we currently have any way to do the following:

No, we don't support that at present and will raise the following error:

semantic error: Only those local variables which can be reduced to compile time constant should be used in dimensions of an array.
 --> b.py:8:12
  |
8 |     a: f64[n] = empty((n,), dtype=float64)
  |   

So allocatable in ASR seems to be the only way to declare a local runtime array, correct? I think starting with explicit Allocatable[f64[:]] is the way to go for now.

Yes, that's right.

@Smit-create
Copy link
Collaborator Author

I'm adding this to auto-merge and will add the allocatable support for C backend in a new PR.

@Smit-create Smit-create enabled auto-merge May 18, 2023 03:38
@certik
Copy link
Contributor

certik commented May 18, 2023

Thanks!

@Smit-create Smit-create merged commit e487d07 into lcompilers:main May 18, 2023
@Smit-create Smit-create deleted the i-1785 branch May 18, 2023 04:02
This was referenced May 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants