Assign 2D Array with Reals in Fortran - Help Needed

  • Context: Fortran 
  • Thread starter Thread starter davidfur
  • Start date Start date
  • Tags Tags
    2d Array Assignment
Click For Summary

Discussion Overview

The discussion revolves around issues encountered while assigning a 2D array with real numbers in Fortran. Participants are troubleshooting segmentation faults and memory access errors in their code related to subroutine calls and array reshaping. The scope includes programming challenges and debugging techniques in Fortran.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Homework-related

Main Points Raised

  • One participant shares a code excerpt and describes a segmentation fault occurring when attempting to assign values to a 2D array.
  • Another participant suggests that memory errors may indicate referencing an element outside the array bounds and proposes breaking the assignment into smaller steps.
  • A participant expresses suspicion about the correctness of their variable declarations and shares additional code for context.
  • Another participant identifies potential issues with subroutine call syntax and the use of global variables, questioning the declaration of an undeclared variable 'd'.
  • One participant mentions uncertainty about whether the reshape function can accept a list of constants as its first argument.
  • A later reply indicates that the original poster resolved their issues by properly declaring and allocating variables outside the subroutine.

Areas of Agreement / Disagreement

Participants express various viewpoints on the causes of the errors, with no consensus reached on the specific issues until the original poster resolves their problem independently.

Contextual Notes

Limitations include missing declarations for certain variables and the potential impact of global variables on debugging. The discussion also highlights uncertainty regarding the usage of the reshape function with constant lists.

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   Reactions: 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!
 

Similar threads

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