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

Replace another FORTRAN test program with gfortran -Wall certified test program. #1736

Merged
merged 2 commits into from
Nov 10, 2024

Conversation

pratyai
Copy link
Collaborator

@pratyai pratyai commented Nov 6, 2024

A follow up of #1733 that took a bit longer to figure out.

This change breaks the test on multi_sdfg branch, but there the front-end is doing something additionally wrong (it somehow promotes nclv into a input parameter for the whole program) -- but it will even take longer to figure out why.

@pratyai pratyai requested a review from acalotoiu November 6, 2024 17:08
@pratyai pratyai marked this pull request as ready for review November 6, 2024 17:08
Copy link
Contributor

@acalotoiu acalotoiu left a comment

Choose a reason for hiding this comment

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

Can you please check what happens if we try to receive a bool from an external Fortran code (via slotting in our function as an external C call in a F code). I think from there we receive bools either as int or char values. That is why multi_sdfg has a different behavior. If so, can you please make it a config option whether the frontend parses bools as bools or ints (to ensure compatibility with external functions?) Please also add such a test if possible - it will need a different style of calling it too.

values into real array, which `gfortran` doesn't like. So, changed the
array type into logical (and same on the external numpy array too).
@pratyai pratyai force-pushed the fix-another-fortran-language-test branch from 3b3550d to 450d4c1 Compare November 7, 2024 06:28
@pratyai
Copy link
Collaborator Author

pratyai commented Nov 7, 2024

Can you please check what happens if we try to receive a bool from an external Fortran code (via slotting in our function as an external C call in a F code). I think from there we receive bools either as int or char values. That is why multi_sdfg has a different behavior.

Thanks for pointing this out. The logical array d is exposed on the generated header as int * __restrict__ d anyway. So, we do need to pass 32bit integer arrays, which works just fine. However, turns out that the d = np.full([3, 4, 5], np.True_, order="F", dtype=np.bool_) line is wrong, because numpy constructs d as an 8bit array, as I only notice just now here.

If so, can you please make it a config option whether the frontend parses bools as bools or ints (to ensure compatibility with external functions?) Please also add such a test if possible - it will need a different style of calling it too.

Can I defer it for a separate future PR? Making it configurable means having to wire through the entire stack of the frontend, which is difficult to do without diverging multi_sdfg from main even more.


Calling the C SDFG interface from Fortran works as follows

  1. a checkerboard-pattern program:
program loop1_test
  implicit none
  logical :: d(3, 4, 5)
  call loop1_test_function(d)
end

subroutine loop1_test_function(d)
  logical :: d(3, 4, 5), ZFAC(10)
  integer :: a, JK, JL, JM
  integer, parameter :: KLEV = 10, N = 10, NCLV = 3

  integer :: tmp

  do I = 1, 3
    do J = 1, 4
      do K = 1, 5
        tmp = I+J+K-3
        tmp = mod(tmp, 2)
        if (tmp == 1) then
          d(I, J, K) = .true.
        else
          d(I, J, K) = .false.
        end if
      end do
    end do
  end do
end subroutine loop1_test_function
  1. a c++ wrapper:
#include "loop1_test_function.h"

extern "C" int foo_(int * __restrict__ d) {
  auto handle = __dace_init_loop1_test_function();
  __program_loop1_test_function(handle, d);
  return __dace_exit_loop1_test_function(handle);
}
  1. a f90 tester:
program main
  implicit none
  external foo

  logical :: d(3, 4, 5) = .false.
  print *, d
  call foo(d)
  print *, d
  print *, d(1, 1, 1)
  print *, d(1, 1, 2)
  stop
end program main
  1. some compiler/linker flags

This gets me a pattern like expected:

T F T F T F T F T F T F F T F T F T F T F T F T T F T F T F T F T F T F F T F T F T F T F T F T T F T F T F T F T F T F

I think that's because the kind() of both logical and integer are all 4 (i.e., 4 bytes), so it happens to behave nicely (although not sure that's always true for fortran).

@acalotoiu
Copy link
Contributor

LGTM

@acalotoiu acalotoiu self-requested a review November 7, 2024 09:14
@tbennun tbennun added this pull request to the merge queue Nov 10, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Nov 10, 2024
@tbennun tbennun added this pull request to the merge queue Nov 10, 2024
Merged via the queue into spcl:main with commit 1b99fe2 Nov 10, 2024
10 checks passed
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