Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29255 Discussions

Passing non-consecutive array indicies

gtopo30
Beginner
958 Views

I am working on porting code I didn't write from pgf90 to ifort and I have run into a difference between the two compilers I don't know how to fix.

Here is an example. I have a matrix A which is 5 by 7 elements. Based on tests elsewhere in the code, I construct a vector of "good" rows. So I have good_rows who's values are {1,2,4,5}.

Now, with pgf90 I can pass just the good elements via something like this

call workfn(A(good_rows,:),...)

However, when I compile with ifort (v9 build 20051201) I do not get an error but I will get a segmentation fault at run time.

I hope this is enough info. Any thoughts?

Case

0 Kudos
9 Replies
Steven_L_Intel1
Employee
958 Views
It's not enough info, because we would also need to see:

1. Any explicit interface for workfn visible to the caller
2. The subroutine statement and declaration section from routine workfn

Let me suggest, though, that you may be encountering a bug which was fixed a few months ago. The compiler you are using is six months old. Please download and install 9.1.032 from Intel Premier Support File Downloads and see if that helps. After installing, be sure to invoke the proper ifortvars.sh so that you get the newer compiler.
0 Kudos
gtopo30
Beginner
958 Views
Thanks Steve,

I upgraded to 9.1.032 and that didn't change the behavior.

A is declared as a double precision, allocatable, pointer.

good_index is declared as integer, allocatable, pointer.

The subroutine workfn is pretty simple:

subroutine workfn(mat, sum)
implicit none

double precision, dimension(0:,0:), intent(in) :: mat
double precision, dimension(0:), intent(out) :: sum

The routine runs through a series of mostly simple math to fill out the vector 'sum' based on the "good indicies" of 'mat'.

I hope this helps.

Case
0 Kudos
Steven_L_Intel1
Employee
958 Views
Is an explicit interface for workfn visible to the caller? It needs to be as the routine has assumed-shape array arguments.

If that's not the problem, then please submit an example to Intel Premier Support and we'll be glad to look into it.
0 Kudos
gtopo30
Beginner
958 Views
Unfortunately, when I try to log in to "Premier Support", all I get is this page:

https://premier.intel.com/scripts-util/quaderror.htm

However, I was able to duplicate the problem in the following manner:

Main Program :

program main

use hmatrix_mod

implicit none


type (HMatrix) :: This

double precision :: ds

integer, allocatable, dimension(:) :: mIndex
integer :: i, j, k, good_ind

good_ind = 1400

allocate(mIndex(0:good_ind-2))

do i=0,49
mIndex(i) = i
end do

do i=51,good_ind-2
mIndex(i-1) = i
end do

call init_hmatrix(This,good_ind)

call workfn(This%HMatrixValues, ds)

print*,'Passing all, ds = ',ds

call workfn(This%HMatrixValues(mIndex,:),ds)

print*,'Passing some, ds = ',ds

nullify(This%HMatrixValues)

deallocate(mIndex)

end

With one subroutine:

module hmatrix_mod
implicit none

type HMatrix
double precision :: HMatrixMinValue
double precision :: HMatrixResolution
integer :: HMatrixNumColumns
integer :: HMatrixNumRows
double precision, dimension(:,:), pointer :: HMatrixValues
integer, dimension(:,:), pointer :: HMatrixValueRowIndex
integer, dimension(:), pointer :: HMatrixNum
end type HMatrix

double precision, allocatable, target, save :: HMatrixValues_mat(:,:)
integer, allocatable, target, save :: HMatrixValuesRowIndex_mat(:,:)
integer, allocatable, target, save :: HMatrixNum_mat(:)

contains

subroutine workfn(matVal, sum)
implicit none

double precision, dimension (0:,0:), intent(in) :: matVal
double precision :: sum

integer :: i, j, k

sum = 0.d0

do i=0,size(matVal,1)-1
do j=0,size(matVal,2)-1
sum = sum + matVal(i,j)
end do
end do

return

end subroutine workfn

subroutine init_hmatrix(HM, indx)
implicit none

type(HMatrix), intent(out) :: HM

integer :: indx, i, j, k

&nbs p; if(allocated(HMatrixValues_mat)) then
deallocate(HMatrixValues_mat)
endif

if(allocated(HMatrixValuesRowIndex_mat)) then
deallocate(HMatrixValuesRowIndex_mat)
endif

if(allocated(HMatrixNum_mat)) then
deallocate(HMatrixNum_mat)
endif

allocate(HMatrixNum_mat(0:indx-1))
allocate(HMatrixValuesRowIndex_mat(0:indx-1,0:indx-1))
allocate(HMatrixValues_mat(0:indx-1,0:indx-1))

HMatrixNum_mat = 0
HMatrixValuesRowIndex_mat = -1
HMatrixValues_mat = 1.d0

HM%HMatrixValues => HMatrixValues_mat
HM%HMatrixValueRowIndex => HMatrixValuesRowIndex_mat
HM%HMatrixNum => HMatrixNum_mat


end subroutine init_hmatrix

end module hmatrix_mod


Everything was compiled with

ifort -mcmodel=medium -g -CB -i-dynamic -fpic main.f90 hmatrix_mod.f90 -o Main

This causes the same behavior (segmentation fault) as the program earlier.

Case


0 Kudos
jimdempseyatthecove
Honored Contributor III
958 Views

Case,

You have a programming error:

allocate(mIndex(0:good_ind-2))

do i=0,49
mIndex(i) = i
end do

do i=51,good_ind-2
mIndex(i-1) = i
end do

Allocates from mIndex(0) thru mIndex(good_ind-2)
The second do loop finishes up at
mIndex(good_ind-2-1)
where the array mIndex ends at good_ind-2. This results in mIndex(good_ind-2) being undefined.

Don't know if this is causes the error message you are seeing. But using an initialized index is not good.

Jim Dempsey

0 Kudos
jimdempseyatthecove
Honored Contributor III
958 Views

One more thing.

The way you havethe calls to workfn coded will result in a temporary array being created. It may be more efficient to pass in the entire array plus an integer array of the selected rows (using -1 to indicate end of list or row not selected). In this manner a temporary array is not created. This results in faster runtimes as well as reducing stack requirements for temporary arrays.

Jim Dempsey

0 Kudos
gtopo30
Beginner
958 Views
Jim,

Thanks for catching that error.

It appears the error is due to the temp array and the stack size (ulimit -s unlimited fixes the problem).

Unfortunately, I inherited this project and its going to be a mess to fix it.

Thanks again for all the help!!

Case
0 Kudos
Ron_Green
Moderator
958 Views

Case,

You might try options -O0 -g -traceback -check bounds

this will help catch other array bounds issues that might be hiding in the code.

0 Kudos
jimdempseyatthecove
Honored Contributor III
958 Views

Case,

The stack size issue is a build and run environment issue and other than for performance and memory capacity requirement is not a fundimental problem with the old code you inherited.

Invalid subscripting though is a fundimental problem with the old code you inherited. As suggested in another reply, it would be well worth your time to make a few runs with the array subscript checks as well as the uninitialized variable checkoptions enabled. "A stitch in time saves nine."

Jim Dempsey

0 Kudos
Reply