Hi all,

I am having trouble using the function VecGetArrayReadF90 under gfortran. I
have created a minimal example and put it in the attachment. Basically, it
appears that the input pointer is empty upon return from
VecGetArrayReadF90. The code runs fine, when compiled with ifort, so I
don't know what's going on.

I am attaching the code and makefile that I used, as well as the command
line output that I can see. Though the errors are just to do with the fact
that the output pointer is empty, so the command line output is not all
that helpful...

Thanks in advance for your help!
Sam
 setting values
 assembling vector
 copying vector to array
 N =           10
 m =           10
 getting vecX size
 getting ownership range
 ownership range:            0          10
 copy values to global array
 vecX_pt:
 SIZE =            0
At line 127 of file allreduce.f90
Fortran runtime error: Array bound mismatch for dimension 1 of array 
'copy_buffer' (10/0)

Error termination. Backtrace:
#0  0x402621 in petscvec2array_
        at /home/lanthale/Progs/test_PetscVec2Array/allreduce.f90:127
#1  0x403550 in allreduce
        at /home/lanthale/Progs/test_PetscVec2Array/allreduce.f90:58
#2  0x4035d8 in main
        at /home/lanthale/Progs/test_PetscVec2Array/allreduce.f90:4

Attachment: makefile
Description: Binary data

PROGRAM allreduce
#include "slepc/finclude/slepc.h"
  ! ------
  USE slepcsys
  USE slepceps
  IMPLICIT NONE
  
  ! --- pure PETSc
  PetscErrorCode :: ierr
  PetscScalar, ALLOCATABLE :: vals(:)
  PetscInt, ALLOCATABLE :: idxn(:)
  PetscInt :: m,i
  ! --- SLEPc
  Vec :: vecX                ! eigenvector (real/imaginary parts)
  !
  COMPLEX, ALLOCATABLE :: vecXcopy(:)
  INTEGER :: N

  ! initialize SLEPc
  CALL SlepcInitialize(PETSC_NULL_CHARACTER,ierr)

  ! Set up a new matrix
  m = 10
  ALLOCATE(vals(10),idxn(10))

  !
  CALL VecCreate(PETSC_COMM_WORLD,vecX,ierr); 
  CALL VecSetType(vecX,VECMPI,ierr); 
  CALL VecSetSizes(vecX,PETSC_DECIDE,m,ierr); 

  ! set values of vector
  DO i=1,m
     vals(i) = i
     idxn(i) = i-1
  END DO
  !
  PRINT*,'setting values'
  CALL VecSetValues(vecX,m,idxn,vals,INSERT_VALUES,ierr); 

  ! assemble vector
  PRINT*,'assembling vector'
  CALL VecAssemblyBegin(vecX,ierr); 
  CALL VecAssemblyEnd(vecX,ierr); 

  ! 
  PRINT*,'copying vector to array'
  N = m
  PRINT*,'N = ',N
  PRINT*,'m = ',m
  ALLOCATE(vecXcopy(N))
  CALL PetscVec2Array(vecX,vecXcopy,N)

  !
  CALL VecDestroy(vecX,ierr); 
  CALL SlepcFinalize(ierr); 


END PROGRAM allreduce


  !> Copy Petsc vector to fortran array
  SUBROUTINE PetscVec2Array(vecX,buffer,N)
#include "slepc/finclude/slepc.h"
    ! ------
!    USE petscsys
!    USE petscvec
    ! ------
    USE slepcsys
    USE slepceps
    IMPLICIT NONE
    Vec, INTENT(in) :: vecX
    COMPLEX, INTENT(inout) :: buffer(0:N-1)
    INTEGER, INTENT(in) :: N
    !
    INTEGER :: istart, iend, Np, i,j
    INTEGER :: me2,nprocs
    COMPLEX, ALLOCATABLE :: copy_buffer(:), copy_buffer2(:)
    !
    PetscScalar, POINTER :: vecX_pt(:) => NULL()
    PetscInt :: petsc_istart, petsc_iend, petsc_N
    PetscErrorCode :: ierr

    !
    CALL MPI_COMM_RANK(MPI_COMM_WORLD,me2,ierr);
    CALL MPI_COMM_SIZE(MPI_COMM_WORLD,Nprocs,ierr);

    ! initailize buffer to 0.
    buffer = 0.
    ALLOCATE(copy_buffer(0:N-1))
   

    ! check length of petsc vector is N
    PRINT*,'getting vecX size'
    CALL VecGetSize(vecX,petsc_N,ierr); CHKERRQ(ierr)
    Np = petsc_N
    IF(N.NE.Np) THEN
       PRINT*,'ERROR: In PetscVec2Array:'
       PRINT*,'petsc_N = ',petsc_N, Np
       PRINT*,'N       = ',N
       CALL ABORT
    END IF

    ! vecX_pt will contain the element in the local range [istart,iend-1]
    PRINT*,'getting ownership range'
    CALL VecGetOwnershipRange(vecX,istart,iend,ierr); CHKERRQ(ierr)
    PRINT*,'ownership range: ',istart,iend

    ! initialize the pointer
    CALL VecGetArrayReadF90(vecX,vecX_pt,ierr); CHKERRQ(ierr)
    ! copy values to global array
    PRINT*,'copy values to global array'

    DO i=1,Nprocs
       !
       CALL MPI_BARRIER(MPI_COMM_WORLD,ierr)
       !
       IF(me2.EQ.i-1) THEN
          PRINT*,'vecX_pt:'
          PRINT*,'SIZE = ',SIZE(VecX_pt)
          DO j=1,SIZE(vecX_pt)
             PRINT*,'  ',vecX_pt(j)
          END DO
       END IF
    END DO


    copy_buffer(istart:iend-1) = vecX_pt(:)
    ! free pointer
    CALL VecRestoreArrayReadF90(vecX,vecX_pt,ierr); CHKERRQ(ierr)

    CALL MPI_BARRIER(MPI_COMM_WORLD,ierr)

    DO i=1,Nprocs
       !
       CALL MPI_BARRIER(MPI_COMM_WORLD,ierr)
       !
       IF(me2.EQ.i-1) THEN
          PRINT*,'copy_buffer = '
          DO j=istart,iend-1
             PRINT*,'  ',copy_buffer(j)
          END DO
       END IF
    END DO

    CALL MPI_BARRIER(MPI_COMM_WORLD,ierr)

    ! combine all components from all processes
    PRINT*,'calling allreduce'
    CALL MPI_ALLREDUCE(copy_buffer,buffer,N,MPI_DOUBLE_COMPLEX,MPI_SUM,MPI_COMM_WORLD,ierr)
    CALL MPI_BARRIER(MPI_COMM_WORLD,ierr)

    DO i=1,Nprocs
       !
       CALL MPI_BARRIER(MPI_COMM_WORLD,ierr)
       !
       IF(me2.EQ.i-1) THEN
          PRINT*,'buffer = '
          DO j=0,N-1
             PRINT*,'  ',buffer(j)
          END DO
       END IF
    END DO

    
    ! free local memory
    DEALLOCATE(copy_buffer)

  END SUBROUTINE PetscVec2Array

Reply via email to