Skip to content

Commit

Permalink
WIP: nagfor/gfortran internal compiler error (ICE)
Browse files Browse the repository at this point in the history
gfortran 13.2.0
---------------
The following command reproduces the ICE:

gfortran test

NAG 7.1 (Build 7143)
--------------------
The following command reproduces the ICE:

fpm test --compiler nagfor --flag "-fpp -f2018"
  • Loading branch information
rouson committed Jan 2, 2024
1 parent 86593b2 commit 0858130
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 98 deletions.
20 changes: 9 additions & 11 deletions src/matcha/do_concurrent_s.f90
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pure module subroutine do_concurrent_my_velocities(nsteps, dir, sampled_speeds,

call assert(all([size(my_velocities,1),size(sampled_speeds,2)] == shape(sampled_speeds)), &
"do_concurrent_my_velocities: argument size match")
call assert(all(shape(my_velocities,1)==shape(dir)), "do_concurrent_my_velocities: argument shape match")
call assert(all(size(my_velocities,1)==shape(dir)), "do_concurrent_my_velocities: argument shape match")

do concurrent(step=1:nsteps)
my_velocities(:,step,1) = sampled_speeds(:,step)*dir(:,step,1)
Expand Down Expand Up @@ -82,16 +82,14 @@ module subroutine do_concurrent_speeds(history, speeds) bind(C)
x(i,:,:) = positions
end do

associate(t => history%time)
do concurrent(i = 1:npositions-1, j = 1:ncells)
associate( &
u => (x(i+1,j,:) - x(i,j,:))/(t(i+1) - t(i)), &
ij => i + (j-1)*(npositions-1) &
)
speeds(ij) = sqrt(sum([(u(k)**2, k=1,nspacedims)]))
end associate
end do
end associate
do concurrent(i = 1:npositions-1, j = 1:ncells)
associate( &
u => (x(i+1,j,:) - x(i,j,:))/(history(i+1)%time - history(i)%time), &
ij => i + (j-1)*(npositions-1) &
)
speeds(ij) = sqrt(sum([(u(k)**2, k=1,nspacedims)]))
end associate
end do
end associate

end subroutine
Expand Down
15 changes: 9 additions & 6 deletions src/matcha/output_s.f90
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,26 @@

integer, parameter :: speed=1, freq=2 ! subscripts for speeds and frequencies

associate(npositions => size(history), ncells => history(1)%positions_shape(1))
allocate(speeds(ncells*(npositions-1)))
associate(npositions => size(self%history_))
allocate(speeds(self%my_num_cells()*(npositions-1)))
end associate
call do_concurrent_speeds(t_cell_collection_bind_C_t(self%history_), speeds)

associate(emp_distribution => self%input_%sample_distribution())
block
real(c_double), allocatable :: emp_distribution(:,:)

emp_distribution = self%input_%sample_distribution()
associate(nintervals => size(emp_distribution(:,1)), dvel_half => (emp_distribution(2,speed)-emp_distribution(1,speed))/2.d0)
vel = [emp_distribution(1,speed) - dvel_half, [(emp_distribution(i,speed) + dvel_half, i=1,nintervals)]]
if (allocated(k)) deallocate(k)
allocate(k(nspeeds))
allocate(k(size(speeds)))
call do_concurrent_k(speeds, vel, k)
if(allocated(output_distribution)) deallocate(output_distribution)
allocate(output_distribution(nintervals,2))
call do_concurrent_output_distribution(nintervals, speed, freq, emp_distribution, k, output_distribution)
call do_concurrent_output_distribution(speed, freq, emp_distribution, k, output_distribution)
output_distribution(:,freq) = output_distribution(:,freq)/sum(output_distribution(:,freq))
end associate
end associate
end block

end procedure

Expand Down
88 changes: 12 additions & 76 deletions src/matcha/subdomain_m.f90
Original file line number Diff line number Diff line change
@@ -1,42 +1,36 @@
module subdomain_m
use assert_m, only : assert
implicit none

private
public :: subdomain_t
public :: operator(.laplacian.)
public :: step

type subdomain_t
private
real, allocatable :: s_(:,:,:)
contains
procedure, pass(self) :: define
procedure, pass(rhs) :: multiply
generic :: operator(*) => multiply
generic :: operator(+) => add
generic :: assignment(=) => assign_
procedure dx
procedure dy
procedure dz
procedure values
generic :: operator(*) => multiply
generic :: operator(+) => add
generic :: operator(.laplacian.) => laplacian
generic :: assignment(=) => assign_
procedure, private, pass(rhs) :: multiply
procedure, private :: laplacian
procedure, private :: add
procedure, private :: assign_
end type

interface operator(.laplacian.)

module procedure laplacian
!pure module function laplacian(rhs) result(laplacian_rhs)
! implicit none
! type(subdomain_t), intent(in) :: rhs[*]
! type(subdomain_t) laplacian_rhs
!end function

end interface

interface

pure module function laplacian(rhs) result(laplacian_rhs)
implicit none
class(subdomain_t), intent(in) :: rhs[*]
type(subdomain_t) laplacian_rhs
end function

module subroutine define(side, boundary_val, internal_val, n, self)
implicit none
real, intent(in) :: side, boundary_val, internal_val
Expand Down Expand Up @@ -96,62 +90,4 @@ module subroutine assign_(lhs, rhs)

end interface

real dx_, dy_, dz_
integer my_nx, nx, ny, nz, me, num_subdomains, my_internal_west, my_internal_east

contains

pure module function laplacian(rhs) result(laplacian_rhs)
type(subdomain_t), intent(in) :: rhs[*]
type(subdomain_t) laplacian_rhs

integer i, j, k
real, allocatable :: halo_west(:,:), halo_east(:,:)

call assert(allocated(rhs%s_), "subdomain_t%laplacian: allocated(rhs%s_)")

allocate(laplacian_rhs%s_, mold=rhs%s_)

if (me==1) then
halo_west = rhs%s_(1,:,:)
else
halo_west = rhs[me-1]%s_(ubound(rhs[me-1]%s_,1),:,:)
end if
i = my_internal_west
call assert(i+1<=my_nx,"laplacian: westernmost subdomain too small")
do concurrent(j=2:ny-1, k=2:nz-1)
laplacian_rhs%s_(i,j,k) = ( halo_west(j,k ) - 2*rhs%s_(i,j,k) + rhs%s_(i+1,j ,k ))/dx_**2 + &
(rhs%s_(i,j-1,k ) - 2*rhs%s_(i,j,k) + rhs%s_(i ,j+1,k ))/dy_**2 + &
(rhs%s_(i,j ,k-1) - 2*rhs%s_(i,j,k) + rhs%s_(i ,j ,k+1))/dz_**2
end do

do concurrent(i=my_internal_west+1:my_internal_east-1, j=2:ny-1, k=2:nz-1)
laplacian_rhs%s_(i,j,k) = (rhs%s_(i-1,j ,k ) - 2*rhs%s_(i,j,k) + rhs%s_(i+1,j ,k ))/dx_**2 + &
(rhs%s_(i ,j-1,k ) - 2*rhs%s_(i,j,k) + rhs%s_(i ,j+1,k ))/dy_**2 + &
(rhs%s_(i ,j ,k-1) - 2*rhs%s_(i,j,k) + rhs%s_(i ,j ,k+1))/dz_**2
end do

if (me==1) then
halo_east = rhs%s_(1,:,:)
else
halo_east = rhs[me+1]%s_(lbound(rhs[me+1]%s_,1),:,:)
end if
i = my_internal_east
call assert(i-1>0,"laplacian: easternmost subdomain too small")
do concurrent(j=2:ny-1, k=2:nz-1)
laplacian_rhs%s_(i,j,k) = (rhs%s_(i-1,j ,k ) - 2*rhs%s_(i,j,k) + halo_east(j ,k ))/dx_**2 + &
(rhs%s_(i ,j-1,k ) - 2*rhs%s_(i,j,k) + rhs%s_(i ,j+1,k ))/dy_**2 + &
(rhs%s_(i ,j ,k-1) - 2*rhs%s_(i,j,k) + rhs%s_(i ,j ,k+1))/dz_**2
end do

laplacian_rhs%s_(:, 1,:) = 0.
laplacian_rhs%s_(:,ny,:) = 0.
laplacian_rhs%s_(:,:, 1) = 0.
laplacian_rhs%s_(:,:,nz) = 0.
if (me==1) laplacian_rhs%s_(1,:,:) = 0.
if (me==num_subdomains) laplacian_rhs%s_(my_nx,:,:) = 0.

end function


end module
59 changes: 56 additions & 3 deletions src/matcha/subdomain_s.f90
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
submodule(subdomain_m) subdomain_s
use assert_m, only : assert, intrinsic_array_t
use sourcery_m, only : data_partition_t
use intrinsic_array_m, only : intrinsic_array_t
implicit none

type(data_partition_t) data_partition

real dx_, dy_, dz_
integer my_nx, nx, ny, nz, me, num_subdomains, my_internal_west, my_internal_east
real, allocatable :: increment(:,:,:)

contains
Expand Down Expand Up @@ -144,4 +145,56 @@ subroutine apply_boundary_condition(ds)

end procedure

end submodule subdomain_s
pure module function laplacian(rhs) result(laplacian_rhs)
class(subdomain_t), intent(in) :: rhs[*]
type(subdomain_t) laplacian_rhs

integer i, j, k
real, allocatable :: halo_west(:,:), halo_east(:,:)

call assert(allocated(rhs%s_), "subdomain_t%laplacian: allocated(rhs%s_)")

allocate(laplacian_rhs%s_, mold=rhs%s_)

if (me==1) then
halo_west = rhs%s_(1,:,:)
else
halo_west = rhs[me-1]%s_(ubound(rhs[me-1]%s_,1),:,:)
end if
i = my_internal_west
call assert(i+1<=my_nx,"laplacian: westernmost subdomain too small")
do concurrent(j=2:ny-1, k=2:nz-1)
laplacian_rhs%s_(i,j,k) = ( halo_west(j,k ) - 2*rhs%s_(i,j,k) + rhs%s_(i+1,j ,k ))/dx_**2 + &
(rhs%s_(i,j-1,k ) - 2*rhs%s_(i,j,k) + rhs%s_(i ,j+1,k ))/dy_**2 + &
(rhs%s_(i,j ,k-1) - 2*rhs%s_(i,j,k) + rhs%s_(i ,j ,k+1))/dz_**2
end do

do concurrent(i=my_internal_west+1:my_internal_east-1, j=2:ny-1, k=2:nz-1)
laplacian_rhs%s_(i,j,k) = (rhs%s_(i-1,j ,k ) - 2*rhs%s_(i,j,k) + rhs%s_(i+1,j ,k ))/dx_**2 + &
(rhs%s_(i ,j-1,k ) - 2*rhs%s_(i,j,k) + rhs%s_(i ,j+1,k ))/dy_**2 + &
(rhs%s_(i ,j ,k-1) - 2*rhs%s_(i,j,k) + rhs%s_(i ,j ,k+1))/dz_**2
end do

if (me==1) then
halo_east = rhs%s_(1,:,:)
else
halo_east = rhs[me+1]%s_(lbound(rhs[me+1]%s_,1),:,:)
end if
i = my_internal_east
call assert(i-1>0,"laplacian: easternmost subdomain too small")
do concurrent(j=2:ny-1, k=2:nz-1)
laplacian_rhs%s_(i,j,k) = (rhs%s_(i-1,j ,k ) - 2*rhs%s_(i,j,k) + halo_east(j ,k ))/dx_**2 + &
(rhs%s_(i ,j-1,k ) - 2*rhs%s_(i,j,k) + rhs%s_(i ,j+1,k ))/dy_**2 + &
(rhs%s_(i ,j ,k-1) - 2*rhs%s_(i,j,k) + rhs%s_(i ,j ,k+1))/dz_**2
end do

laplacian_rhs%s_(:, 1,:) = 0.
laplacian_rhs%s_(:,ny,:) = 0.
laplacian_rhs%s_(:,:, 1) = 0.
laplacian_rhs%s_(:,:,nz) = 0.
if (me==1) laplacian_rhs%s_(1,:,:) = 0.
if (me==num_subdomains) laplacian_rhs%s_(my_nx,:,:) = 0.

end function

end submodule subdomain_s
4 changes: 2 additions & 2 deletions src/matcha/t_cell_collection_m.f90
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ pure module function construct(positions, time) result(t_cell_collection)

interface t_cell_collection_bind_C_t

elemental module function construct_bind_C(t_cell_collection) result(t_cell_collection_bind_C)
impure elemental module function construct_bind_C(t_cell_collection) result(t_cell_collection_bind_C)
!! Result is bind(C) representation of the data inside a t_cell_collection_t object
!! This function is impure because it invokes c_loc. Fortran 2023 compliance will allow this function to be pure.
implicit none
type(t_cell_collection_t), intent(in), target :: t_cell_collection
type(t_cell_collection_bind_C_t) t_cell_collection_bind_C
Expand All @@ -60,7 +61,6 @@ pure module function positions(self) result(my_positions)
double precision, allocatable :: my_positions(:,:)
end function


elemental module function time(self) result(my_time)
!! Return the t_cell_collection_t object's time stamp
implicit none
Expand Down
2 changes: 2 additions & 0 deletions src/matcha_s.f90 → src/matcha_s.F90
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
associate(me => this_image())
associate(my_num_cells => data_partition%last(me) - data_partition%first(me) + 1)

#ifndef NAGFOR
call random_init(repeatable=.true., image_distinct=.true.)
#endif

allocate(random_positions(my_num_cells,ndim))
call random_number(random_positions)
Expand Down

0 comments on commit 0858130

Please sign in to comment.