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

Incorrect semantics of WHERE in some cases #2722

Open
sergisiso opened this issue Sep 25, 2024 · 3 comments
Open

Incorrect semantics of WHERE in some cases #2722

sergisiso opened this issue Sep 25, 2024 · 3 comments

Comments

@sergisiso
Copy link
Collaborator

sergisiso commented Sep 25, 2024

For this program (with #2687 merged to support non-elementals and array notation):

program where_test
    integer, dimension(10) :: a, b = 0, c = 0
    a = (/1, 2, 3, 4, 5, 6, 7, 8, 9 ,10 /)

    where(a > 5)
        b = sum(a)
        c = b(7) + 1
    elsewhere(a > 5)
        c = a
    elsewhere
        b = 1
        c = b(7) + 1
    end where

    write(*,*) c
end program

compiled with gfortran prints:

./a.out
           1           2           3           4          56          56          56          56          56          56

if I do psyclone->gfortran it prints:

./a.out
           1           2           3           4           1           1          56          56          56          56

The reason I believe is that we always create the fused version of the where bodies, but the semantics imply that each array statement is evaluated one by one for each index before moving to the next, and the fusing is just an optimisation that most of the times can be done but not always.

@sergisiso
Copy link
Collaborator Author

Also psyclone is happy to take non array expression like:

    where(a > 5)
        b(1) = 1
    endwhere

and cannonicalise them to some valid code with different meaning. While gfortran says:

   16 |         b(1) = 1
      |        1
Error: WHERE assignment target at (1) has inconsistent shape

I know that we assume we get valid Fortran, but since we now require to know the type of the symbols. Maybe we should check it has the valid type-rank and fail otherwise.

@sergisiso
Copy link
Collaborator Author

We do not need multiple statements to get it wrong, see below:

~/workspace/psyclone via 🐍 v3.12.1 (.venv)
❯ cat where_test.f90
program where_test
    integer, dimension(4) :: a = (/1,2,3,4/)
    integer, dimension(4) :: b = (/1,2,3,4/)

    where(a > 2)
        a = sum(sum(a) + b)
    end where

    write(*,*) a
end program

~/workspace/psyclone via 🐍 v3.12.1 (.venv)
❯ gfortran where_test.f90

~/workspace/psyclone via 🐍 v3.12.1 (.venv)
❯ ./a.out
           1           2          50          50

~/workspace/psyclone via 🐍 v3.12.1 (.venv)
❯ psyclone where_test.f90 | tee output.f90
program where_test
  integer, dimension(4), save :: a = (/1, 2, 3, 4/)
  integer, dimension(4), save :: b = (/1, 2, 3, 4/)
  integer :: widx1

  do widx1 = 1, 4, 1
    if (a(widx1) > 2) then
      a(widx1) = SUM(SUM(a) + b)
    end if
  enddo
  ! PSyclone CodeBlock (unsupported code) reason:
  !  - Unsupported statement: Write_Stmt
  WRITE(*, *) a

end program where_test


~/workspace/psyclone via 🐍 v3.12.1 (.venv)
❯ gfortran output.f90

~/workspace/psyclone via 🐍 v3.12.1 (.venv)
❯ ./a.out
           1           2          50         238

@sergisiso sergisiso changed the title Incorrect semantics of WHERE with multiple statements Incorrect semantics of WHERE in some cases Sep 30, 2024
@sergisiso
Copy link
Collaborator Author

We are also currently not testing the conditional expression for UnresolvedInterfaces and Elemental Calls as we do inside the where body, e.g. for where (a < my_elemental(a)), that could be a problem.

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

No branches or pull requests

1 participant