0

I have a Fortran 90 program formatted in the following way

program main
<bulk of code that uses update_board>
end program main

integer function update_board(board, tochange, N) result(tochange)
    integer, dimension(:, :) :: board, tochange
    integer N
    
    do i=2,N+1
        do j=2,(N+2)/2
            nna = board(i+1, j+1) + board(i, j+1) + board(i-1, j+1) &
            + board(i-1, j) + board(i-1, j-1) + board(i, j-1) &
            + board(i+1, j-1) + board(i+1,j)
            
            if (nna .eq. 3) then
                tochange(i, j) = 1
            else if (nna .eq. 2) then
                tochange(i, j) = board(i, j) 
            else
                tochange(i, j) = 0
            end if
        end do
    end do
end function update_board

However, when I run the code, I get the compilation error of

integer function update_board(board, tochange, N) result(tochange)
                                                                  1
Error: DUMMY attribute conflicts with RESULT attribute in 'tochange' at (1)
parallel_game_of_life.f90:1.12:

program main
            1
parallel_game_of_life.f90:144.47:

    integer, dimension(:, :) :: board, tochange
                                               2
Error: Two main PROGRAMs at (1) and (2)

I'm sure the latter two main PROGRAMs error is a direct result of the first. However, I am pretty stuck here. I would like to update an input variable and use that as the result ,since I can't declare a function like integer, dimension(:, :) function ...

1 Answers1

1

You are declaring the function output incorrectly in your code. You have declared the output type twice, but also have it both as input and output. If you want it as input, then use subroutine instead of function. Here is a fix to your code based on what I understood from it,

function update_board(board, n) result(tochange)
    integer, intent(in) :: n
    integer, intent(in) :: board(n,(n+2)/2+1)
    integer             :: tochange(n,(n+2)/2+1)
    
    do i=2,N+1
        do j=2,(N+2)/2
            nna = board(i+1, j+1) + board(i, j+1) + board(i-1, j+1) &
            + board(i-1, j) + board(i-1, j-1) + board(i, j-1) &
            + board(i+1, j-1) + board(i+1,j)
            
            if (nna .eq. 3) then
                tochange(i, j) = 1
            else if (nna .eq. 2) then
                tochange(i, j) = board(i, j) 
            else
                tochange(i, j) = 0
            end if
        end do
    end do
end function update_board

An equivalent subroutine implementation would be the following,

subroutine update_board(n, board, tochange)
    integer, intent(in)  :: n
    integer, intent(in)  :: board(n,(n+2)/2+1)
    integer, intent(out) :: tochange(n,(n+2)/2+1)
    
    do i=2,N+1
        do j=2,(N+2)/2
            nna = board(i+1, j+1) + board(i, j+1) + board(i-1, j+1) &
            + board(i-1, j) + board(i-1, j-1) + board(i, j-1) &
            + board(i+1, j-1) + board(i+1,j)
            
            if (nna .eq. 3) then
                tochange(i, j) = 1
            else if (nna .eq. 2) then
                tochange(i, j) = board(i, j) 
            else
                tochange(i, j) = 0
            end if
        end do
    end do
end function update_board

Then, call subroutine(n, board, tochange) instead of tochange = function(board, n).

Scientist
  • 1,767
  • 2
  • 12
  • 20
  • Thank you. Is it not possible to use `tochange` as both input and output? I don't know in the function what the exact shape of `tochange` will be, and I cannot allocate a new array in the function because then I would not be able to deallocate it after returning. – blueteethbass Jun 07 '21 at 21:18
  • Why do you think you would not be able to deallocate it when out of function? Just declare it as an allocatable instead of the explicit shape that I have specified: `integer, allocatable :: to change(:,:)`, in which case, the variable assigned to the function output must be also an allocatable. Then you can deallocate it whenever needed out of this function. – Scientist Jun 07 '21 at 21:37
  • If that is really a concern for you, or if you need `tochange` also as input within the function, then declare it as `intent(inout)` and list it as a dummy argument. But in that case, you cannot have it as function output anymore. If there is no other function output (other than `tochange`), then simply change `function` to `subroutine` and remove `result(tochange)` from the function header. – Scientist Jun 07 '21 at 21:39
  • I added a subroutine implementation example to the above answer . – Scientist Jun 07 '21 at 21:44