What ChatGPT says about Fortran

The Fortran community may want to gradually educate ChatGPT about Fortran, because currently it sometimes gives plausible answers to questions that are misleading or incorrect. Since there is a current thread about a program hanging with DEALLOCATED, I had the following chat:

When is explicit deallocation necessary in a Fortran program?

In Fortran, explicit deallocation of memory is only necessary if you have previously allocated memory dynamically using an ALLOCATE statement. If you have not dynamically allocated memory in your program, then you do not need to worry about explicit deallocation.

Here is an example of how to dynamically allocate and deallocate an array in Fortran:

real, allocatable :: a(:)

! Allocate memory for the array
allocate(a(10))

! Use the array
a = 1.0

! Deallocate the array
deallocate(a)

It is important to deallocate memory when you are finished using it to avoid memory leaks. Otherwise, the memory that was allocated for the array will continue to be reserved for the program, even after it is no longer needed.

Note that in Fortran, an allocatable array is deallocated when it goes out of scope. Therefore explicit deallocation is often not needed. One case where it is needed is when an array is allocated and you want to use the ALLOCATE statement to resize it.

That is correct. In Fortran, allocatable arrays are automatically deallocated when they go out of scope, so you do not need to worry about explicitly deallocating them in those cases. However, if you want to resize an allocatable array, you will need to use the ALLOCATE statement to do so. This will require you to deallocate the array first, before reallocating it to a new size. Here is an example of how to do this:

real, allocatable :: a(:)

! Allocate memory for the array
allocate(a(10))

! Use the array
a = 1.0

! Deallocate the array
deallocate(a)

! Reallocate the array to a new size
allocate(a(20))

! Use the resized array
a = 2.0

! Deallocate the array when it is no longer needed
deallocate(a)

It is important to remember to deallocate the array after you have finished using it, to avoid memory leaks.

That statement by ChatGPT is incorrect in several ways. First, as you point out, it is not always necessary to deallocate previously allocated arrays, regardless of how they were allocated originally. Allocatable arrays are deallocated automatically when they go out of scope or as part of a defined finalization. Second, regarding the “only” qualifier, it is sometimes necessary to deallocate arrays that were not allocated with an allocate() statement. Allocatable arrays can be created in other ways, such as allocation on assignment, either with intrinsic assignment (which works for the arrays themselves, or as members of a derived type), or with a user-defined assignment, or with move_alloc().

However, if you want to resize an allocatable array, you will need to use the ALLOCATE statement to do so.

The programmer can also resize an allocatable array with assignment.

If it were possible to declare an allocatable array with initialization (I still do not know why this is not allowed in the language), then it would be possible to write entire programs with allocatable scalars and arrays that never use either ALLOCATE() or DEALLOCATE(). All the operations involving allocation, resizing, move_alloc, and deallocation could all occur automatically, eliminating many sources of programmer errors.

You.com also offers an AI tool:

The Wikipedia page says:

In December 2022, the company launched YouChat, a Generative Pre-trained Transformer-based chat bot, primarily based on OpenAI’s GPT-3.5. It uses Google search for general search results and Microsoft Bing for more specific searches, such as code snippets.

1 Like

Nice, I tried to find product of two matrices using Fortran: here is what it gives

program matrix_multiplication
  implicit none
  real, dimension(2,2) :: A, B, C
  A = [1,2,3,4]
  B = [5,6,7,8]
  C = MATMUL(A,B)
  print *, C
end program matrix_multiplication

which is not correct.

The shapes of the array expressions do not conform.

The error is in the two assignment statements, not with the matmul() call, which is otherwise correct. In order to specify a 2x2 matrix, chatGPT needs to use the reshape() intrinsic.

Well it’s not that “smart”
 I don’t use ChatGPT (I wanted to try it out of curiosity, but it asked for an account, so
 no.)
I wonder what it will do if you ask it to write a procedure that returns multiple values of different types. Will it “think” to use a subroutine with multiple intent(out)s instead of a function (since we asked for a procedure, not specifically a function?) And what if we insist it has to be a function? Will it “think” to use a derived type as the result of the function, or it will just add intent(out)s to the function. And if it does that, what it will do if you tell it this is bad practice, also giving it a hint that derived types are a thing?

There are many ways to trick the AI and see how it will react. For now, I’m not worried. Obviously, the AI cannot replace a human brain, however “smart” it might seem already. And I hope I won’t be around when (if) it will be able to do so


With You.com, you don’t need an account.

A fun question to ask to an AI chatbot is: “who is first name last name?” If you have homonyms (dead or alive?), it will mix all their biographies and activities and will generate a plausible paragraph for people that don’t know you. Plausible, although you may look also like a kind of superman with many many skills
 :grin: Know thyself and you will know the Universe and the Gods?

I asked You.com to write a Fortran function that returns two integers and gave me a function that returns an integer named “TwoIntegers” :laughing:
Admittedly, the question was a bit generic, but a smart AI would either ask me to be more specific or give me a function that does return two random integers somehow. However it also gave me a list of useful links in SlackOverflow and elsewhere, which did answer the question. So a student can’t really cheat with this thing but they can get some useful information.

P.S.: Try to ask “what is the meaning of life”
 it gives a surprisingly decent answer (and it’s not 42).

1 Like

It looks like it has “read” J.P. Sartre


I listened to that radio podcast about ChatGPT:

To vulgarize about what is a language model, they take the example of word completion when you send an SMS. Depending on the context, each word can be followed with a certain probability by other words. Imagine such an algorithm to a higher level, and you have a partial idea of what is doing an AI chatbot.

1 Like

James Reinders of HPCWire asked ChatGPT similar questions but in a light-hearted way. ChatGPT explains how Fortran and Python are complementary.

James Reinders of HPCWire asked ChatGPT

These are (partly) some highly relevant questions there:

Q: Are Intel FPGAs the best?

Q: Should I switch from FORTRAN to a new modern popular efficient programming language


Q: What is the best way to get high performance for an HPC application?

Q: Do you have advice for programmers wanting to do parallel programming with heterogeneous systems?

Q: Should I ignore CUDA and SYCL and wait for standard C++?

Q: Tell me why I should use SYCL.

Q: Should I learn to program using C++ with SYCL ?

Q: What predictions do you have for HPC and AI?

I am trying to find answers myself to such and to similar questions. Still under construction, but here is what I have so far: GitHub - MichaelSiehl/Spatial_Fortran_1

You may be interested by the Société Informatique de France press release
on ChatGPT and generative models (2 pages):

It is of course in French, but with DeepL you can easily translate the whole PDF:

I have tried it and the translation looks good.

Provide some good insights about the core algorithm and its limitations.

I am writing a Fortran tutorial in which ChatGPT-4 answers the questions I pose. ChatGPT is patient, polite, articulate, and sometimes wrong. Overall it impresses. I add corrections and fix codes as needed, documenting those edits. Suggestions on how to structure and format the tutorial are welcome.

6 Likes

It looked good until its last program, which was supposed not to define any variables but did define one, result. I would have written print *, '2 + 4 =',2+4 etc. Also I’m not sure whether @Beliavsky was hoping for real as well as integer arithmetic: I think of 10.0 as an ordinary number as well as 10 without the .0, and the difference between 10/3 and 10.0/3.0 is important, though perhaps not in one’s first introduction to Fortran.

I wonder if we can improve ChatGPTs Fortran skills by using them frequently while giving feedback.
E.g. I like to copy questions asked in this forum (example) to ChatGPT and see if it could solve these questions/problems.
In this case, ChatGPT 3.5 didn’t know anything about a third index argument and simply guessed that it may be a flag for toggling case-insensitive search. ChatGPT 4, in turn, knew it is the back argument, but it thought it is an unofficial extension. In both cases I clicked the :-1:-button, and pasted the formal definition of the index-function, hoping that this will somewhen improve the model.
I think it is crucial for Fortran’s future, that LLM know how to program Fortran because this could become an important argument for selecting a new language to learn.

3 Likes

In Computing the mean: accuracy and speed @urbanjost asked,

I am wondering how far away AI is from being able to refactor netlib into modern code structure

If you want a modern Fortran procedure that solves a linear algebra problem, ChatGPT-4 will write a LAPACK wrapper for you. I asked it to

Write a self-contained Fortran to solve the set of linear equations A*x = b, where matrix A and vector b are given. Fill in the following code:

module solve_lapack_mod
implicit none
integer, parameter :: dp = kind(1.0d0)
contains
subroutine solve_eq(a, b, x, ierr)
real(kind=dp), intent(in)  :: a(:,:) ! (nobs, ncol) -- LHS matrix
real(kind=dp), intent(in)  :: b(:)   ! (nobs)       -- RHS vector
real(kind=dp), intent(out) :: x(:)   ! (ncol)       -- solution vector
integer      , intent(out) :: ierr   ! returned nonzero if error encountered
end subroutine solve_eq
end module solve_lapack_mod

It produced

module solve_lapack_mod
    use, intrinsic :: iso_fortran_env, only : dp => real64
    implicit none
    contains
    subroutine solve_eq(a, b, x, ierr)
        real(dp), intent(in)    :: a(:,:)  ! LHS matrix
        real(dp), intent(in)    :: b(:)    ! RHS vector
        real(dp), intent(out)   :: x(:)    ! solution vector
        integer   , intent(out) :: ierr    ! returned nonzero if error encountered
        integer :: n, nrhs, lda, ldb, info
        integer, allocatable :: ipiv(:)
        
        n = size(a, dim=1)   ! dimension of the matrix A
        nrhs = 1             ! number of right hand side vectors
        lda = size(a, dim=1) ! leading dimension of the matrix A
        ldb = max(1, n)      ! leading dimension of the matrix B
        allocate(ipiv(n))    ! allocate space for pivot indices

        x = b                ! copy b into x as dgesv overwrites b with the solution
        a = a                ! copy a into a as dgesv overwrites a with the LU factors

        ! Call LAPACK routine to solve the system
        call dgesv(n, nrhs, a, lda, ipiv, x, ldb, info)

        if (info /= 0) then
            ierr = info
        else
            ierr = 0
        end if

        deallocate(ipiv)      ! deallocate pivot indices array
    end subroutine solve_eq
end module solve_lapack_mod

which is invalid because of the line a = a since a is intent(in). When fed the error message of gfortran, it produces

module solve_lapack_mod
    use kind_mod, only: dp
    implicit none
    contains
subroutine solve_eq(a, b, x, ierr)
    use, intrinsic :: iso_fortran_env, only: dp => real64
    real(kind=dp), intent(in) :: a(:,:), b(:)
    real(kind=dp), intent(out) :: x(:)
    integer, intent(out) :: ierr
    integer :: n, lda, nrhs, ldb
    integer, allocatable :: ipiv(:)
    real(kind=dp), allocatable :: a_copy(:,:), b_copy(:)
    n = size(a, 1)
    lda = size(a, 1)
    nrhs = 1
    ldb = size(b)
    allocate(ipiv(n))
    allocate(a_copy(n, n))
    allocate(b_copy(n))

    a_copy = a
    b_copy = b
    call dgesv(n, nrhs, a_copy, lda, ipiv, b_copy, ldb, ierr)
    x = b_copy

    deallocate(ipiv, a_copy, b_copy)
end subroutine solve_eq
end module solve_lapack_mod

which compiles and runs with the main program

program main
use solve_lapack_mod, only: solve_eq
integer, parameter :: n = 1000, dp = kind(1.0d0)
real(kind=dp) :: a(n, n), x(n), b(n), bchk(n)
integer :: ierr
logical, parameter :: print_b = .false.
call random_seed()
call random_number(a)
call random_number(b)
call solve_eq(a, b, x, ierr)
if (print_b) then
   bchk = matmul(a, x)
   print*,b
   print*,bchk
   print*,b - bchk
end if
print*,maxval(abs(matmul(a,x) - b))
end program main

If you install the RunGPT Chrome extension, when ChatGPT generates computer code, you get a run button at the top of code boxes. It works for at least Python and Fortran. When I asked ChatGPT to simulate pi using Fortran and print the compiler version (it needed to be told that the compiler_version function is in the iso_fortran_env module) it gave code

program estimate_pi
    use iso_fortran_env
    implicit none
    integer, parameter :: dp = kind(1.d0)
    integer, parameter :: n = 10000000
    integer :: i, count
    real(dp) :: x, y, pi_estimate
    count = 0

    print*, 'Compiler version: ', compiler_version()

    call random_seed()  ! Initialize the random number generator.

    do i = 1, n
        call random_number(x)
        call random_number(y)
        if (x*x + y*y <= 1._dp) then
            count = count + 1
        end if
    end do

    pi_estimate = 4._dp * count / n
    print*, 'Estimated value of pi is ', pi_estimate
end program estimate_pi

and clicking run gave

Compiler version: GCC version 9.2.0
 Estimated value of pi is    3.1415532000000002

So we now have an AI-enabled development environment that will generate code given a natural language prompt, compile it, and run it for you.

For beginners, even installing a compiler and using it from the command line (what’s that?) can be a hurdle. On Windows, they type gfortran hello.f90, get command not found, are told to add a directory to their path, wonder what a path is, etc. Such things should be learned eventually but are a distraction at the beginning.

The plugin also obviates the need for separate compile and execute steps – there is just a run button whether it’s Python or Fortran. There is some brittleness. When asked to write a function to compute the area of a circle, ChatGPT puts the module containing the function in one window and the main program in another. The plugin cannot handle that yet, but if ChatGPT is asked to put the module and main program in the same code window, it does so.

1 Like

A question not related to ChatGPT, can I expect that the following code:

if (x*x + y*y <= 1) then

will be equivalent to:

if (x*x + y*y <= 1._dp) then

in every compiler? x*x + y*y begin dp, I expect 1 to be converted to dp.