Fortran Assign 2D Array with Reals in Fortran - Help Needed

Click For Summary
The discussion revolves around troubleshooting a Fortran subroutine designed to assign values to a 2D array, specifically `gradmat`. The user encounters segmentation faults and memory access errors when attempting to reshape an array of constants into `gradmat`. Key issues identified include incorrect syntax in subroutine calls, potential misuse of global variables, and the need for proper declarations and allocations of variables like `coords` and `gradvec`. A suggestion to explicitly declare an intermediate array for reshaping was made, but the user ultimately resolved the issue by ensuring that all necessary variables were correctly declared and allocated outside the subroutine.
davidfur
Messages
18
Reaction score
2
Hi guys,
On with my Fortran adventures...I'm trying to accomplish a simple task: assign a 2D array with some reals. Here's an excerpt from the code:

Fortran:
subroutine get_energy_and_grad(natoms_,coords,ereal,gradmat)

    include 'cbka.blk'
    include 'opt.blk'
    integer, intent(in)    :: natoms_
    double precision, intent(in)    :: coords(3*natoms_)
    real*8, intent(out)    :: ereal    ! total energy
    real*8, dimension(3,3), intent(out)    :: gradmat

    call vlist
    call srtbon1
    call encalc
     
    ereal = estrc ! total energy

!    write (*,*) 'natoms_ is: ', natoms_

    write (*,*) 'size of gradmat is:', size(gradmat)
    write (*,*) 'size of d is:', size(d)
    write (*,*) 'shape of gradmat is:', shape(gradmat)
    write (*,*) 'shape of d is:', shape(d)

    gradmat = reshape((/ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 /),(/3, 3/))

    write(*,*) 'gradmat is: ', gradmat(2,3)

end subroutine get_energy_and_grad

This just won't assign the 1.0-9.0 reals into gradmat and throws out the following:

Code:
 size of gradmat is:           9
 size of d is:        7500
 shape of gradmat is:           3           3
 shape of d is:           3        2500

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0  0x7F3B8F78EE08
#1  0x7F3B8F78DF90
#2  0x7F3B8F0D54AF
#3  0x40151C in __reaxff_interface_MOD_get_energy_and_grad
#4  0x402C5E in MAIN__ at main.f90:?
Segmentation fault (core dumped)

I'm obviously doing something really stupid, but I just can't figure out what's wrong... need help!

Dave
 
Last edited:
Technology news on Phys.org
Here's a tutorial on the reshape function:

https://www.tutorialspoint.com/fortran/reshape.htm

I don't see what wrong but a memory error often indicates referencing an element outside the array bounds.

Perhaps, you could try being more explicit and breaking the statement up a bit:

Fortran:
 real*8, dimension (1:9) :: b = (/ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 /)

 gradmat = reshape( b , (/3, 3/) )
 
Thanks jedishrfu, but it doesn't work either. I suspect there's something wrong with my declarations...
I post here the full code if this helps

Main program

Fortran:
program main

use reaxff_interface
implicit none

integer natoms_
real*8 ereal
real*8, allocatable :: coords(:,:)
real*8, allocatable :: gradvec(:,:)

call get_energy_and_grad(gradvec)

write (*,*) "This is main. grad(3,3) is : ", gradvec(3,3)

end program main

Module

Fortran:
    module reaxff_interface
    implicit none

subroutine get_energy_and_grad(grad)
    include 'cbka.blk'
    include 'opt.blk'
    real*8, dimension(3,3), intent(out)     :: grad
    real*8, dimension (1:9) :: b

    b = (/ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 /)
    grad = reshape( b , (/3, 3/) ) 
end subroutine get_energy_and_grad

end module reaxff_interface

output:
Code:
Program received signal SIGBUS: Access to an undefined portion of a memory object.

Backtrace for this error:
#0  0x7F4FB566DE08
#1  0x7F4FB566CF90
#2  0x7F4FB4FB44AF
#3  0x7F4FB574563F
#4  0x7F4FB5748154
#5  0x7F4FB5748D3E
#6  0x402DBF in MAIN__ at main.f90:?
Bus error (core dumped)
 
davidfur said:
Here's an excerpt from the code:
Fortran:
subroutine get_energy_and_grad(natoms_,coords,ereal,gradmat)

    include 'cbka.blk'
    include 'opt.blk'
    integer, intent(in)    :: natoms_
    double precision, intent(in)    :: coords(3*natoms_)
    real*8, intent(out)    :: ereal    ! total energy
    real*8, dimension(3,3), intent(out)    :: gradmat

    call vlist
    call srtbon1
    call encalc
    
    ereal = estrc ! total energy

!    write (*,*) 'natoms_ is: ', natoms_

    write (*,*) 'size of gradmat is:', size(gradmat)
    write (*,*) 'size of d is:', size(d)
    write (*,*) 'shape of gradmat is:', shape(gradmat)
    write (*,*) 'shape of d is:', shape(d)

    gradmat = reshape((/ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 /),(/3, 3/))

    write(*,*) 'gradmat is: ', gradmat(2,3)

end subroutine get_energy_and_grad
I see two or maybe three problems:
1. In your three call statements, none of the subroutine calls is written correctly. The syntax for a call statement is
call SubName(argument1, argument2, ...). If a subroutine has no parameters, the parentheses still must be used. See http://pages.mtu.edu/~shene/COURSES/cs201/NOTES/F90-Subprograms.pdf, on page titled "Subroutines: 2/2".
You don't show the definitions for the three subroutines, so I can't tell if any of them takes any arguments.

2. What is d? There is no declaration for d in either the parameter list or in the declarations for local variables, so d apparently is a global variable. It's very bad practice for a function of subroutine to access global variables. At the very least, doing this makes debugging much more difficult.

3. I'm not sure that reshape will take a list of constants as its first argument. Per the GNU Fortran Compiler man page for reshape (https://gcc.gnu.org/onlinedocs/gfortran/RESHAPE.html), it appears to me that the first argument has to be a variable, but I'm not certain of this.
 
  • Like
Likes jim mcnamara
Thanks Mark44 for your help!
I managed to solve the problem by properly declaring and allocating coords and gradvec variables outside the get_energy_and_grad subroutine.

Cheers!
 
Learn If you want to write code for Python Machine learning, AI Statistics/data analysis Scientific research Web application servers Some microcontrollers JavaScript/Node JS/TypeScript Web sites Web application servers C# Games (Unity) Consumer applications (Windows) Business applications C++ Games (Unreal Engine) Operating systems, device drivers Microcontrollers/embedded systems Consumer applications (Linux) Some more tips: Do not learn C++ (or any other dialect of C) as a...

Similar threads

  • · Replies 20 ·
Replies
20
Views
3K
  • · Replies 11 ·
Replies
11
Views
3K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 5 ·
Replies
5
Views
8K
  • · Replies 13 ·
Replies
13
Views
2K
  • · Replies 5 ·
Replies
5
Views
13K
  • · Replies 8 ·
Replies
8
Views
3K
  • · Replies 10 ·
Replies
10
Views
26K
  • · Replies 5 ·
Replies
5
Views
9K
  • · Replies 5 ·
Replies
5
Views
3K