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

AI Thread 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!
 
Thread 'Is this public key encryption?'
I've tried to intuit public key encryption but never quite managed. But this seems to wrap it up in a bow. This seems to be a very elegant way of transmitting a message publicly that only the sender and receiver can decipher. Is this how PKE works? No, it cant be. In the above case, the requester knows the target's "secret" key - because they have his ID, and therefore knows his birthdate.
I tried a web search "the loss of programming ", and found an article saying that all aspects of writing, developing, and testing software programs will one day all be handled through artificial intelligence. One must wonder then, who is responsible. WHO is responsible for any problems, bugs, deficiencies, or whatever malfunctions which the programs make their users endure? Things may work wrong however the "wrong" happens. AI needs to fix the problems for the users. Any way to...

Similar threads

Replies
11
Views
3K
Replies
5
Views
8K
Replies
13
Views
2K
Replies
5
Views
13K
Replies
8
Views
3K
Replies
10
Views
25K
Replies
5
Views
9K
Back
Top