Started playing around with type extensions and typebound
procedures. Merged performance fixes from trunk.
@@ -1,6 +1,33 @@
|
||||
Changelog. A lot less detailed than usual, at least for past
|
||||
history.
|
||||
|
||||
2008/09/18: Defined psb_sizeof to be integer(8). Added support
|
||||
into psb_sum, psb_amx and other reductions for long int
|
||||
scalars.
|
||||
|
||||
2008/09/16: Implemented new scheme for index conversion.
|
||||
Changed cdall with an option to suppress global checks.
|
||||
|
||||
2008/09/02: Improved psi_fnd_owner performace.
|
||||
|
||||
2008/09/01: Better timings in the pargen test cases.
|
||||
|
||||
2008/08/28: Changed CDALL in case of VL to handle overlapped indices.
|
||||
|
||||
2008/07/28: New sorting/reordering modules.
|
||||
|
||||
2008/07/24: Addded HTML version of user's guide.
|
||||
|
||||
2008/07/22: Fixed I/O for Harwell-Boeing and Matrix Market examples
|
||||
|
||||
2008/05/27: Merged single precision branch.
|
||||
|
||||
2008/04/28: Fixed trimming space in sparse matrix conversion.
|
||||
Fixed performance issue in cdins.
|
||||
|
||||
2008/03/25: Fix performance bug in psi_idx_ins_cnv. Changed names of
|
||||
some internal components of preconditioner data structure.
|
||||
|
||||
2008/03/27: Merged the experimental branch for implementing the AVL tree
|
||||
data structure in Fortran instead of relying on C and passing
|
||||
functions around to perform comparisons. There seems to be
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Parallel Sparse BLAS v2.2
|
||||
Parallel Sparse BLAS v2.3
|
||||
(C) Copyright 2006/2007/2008
|
||||
Salvatore Filippone University of Rome Tor Vergata
|
||||
Alfredo Buttari University of Rome Tor Vergata
|
||||
|
||||
@@ -48,8 +48,9 @@ FFLAGS=@FFLAGS@
|
||||
INSTALL=@INSTALL@
|
||||
INSTALL_DATA=@INSTALL_DATA@
|
||||
INSTALL_DIR=@INSTALL_DIR@
|
||||
INSTALL_LIBDIR=$(INSTALL_DIR)/lib
|
||||
INSTALL_INCLUDEDIR=$(INSTALL_DIR)/include
|
||||
INSTALL_LIBDIR=@INSTALL_LIBDIR@
|
||||
INSTALL_INCLUDEDIR=@INSTALL_INCLUDEDIR@
|
||||
INSTALL_DOCSDIR=@INSTALL_DOCSDIR@
|
||||
|
||||
LIBDIR=@LIBDIR@
|
||||
BASELIBNAME=@BASELIBNAME@
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
.mod=.mod
|
||||
.fh=.fh
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .f90 .F90 $(.mod) .F .f .c .o
|
||||
|
||||
|
||||
####################### Section 1 #######################
|
||||
# Define your compilers and compiler flags here #
|
||||
##########################################################
|
||||
F90=/usr/local/bin/g95
|
||||
FC=/usr/local/bin/g95
|
||||
F77=$(FC)
|
||||
F90COPT= -O3
|
||||
FCOPT=-O3
|
||||
CCOPT=-O3
|
||||
#
|
||||
# Which flag does your compiler use for module inclusion?
|
||||
# Most compilers use -I but Sun uses -M
|
||||
# FIFLAG is for INCLUDE
|
||||
FMFLAG=-I
|
||||
FIFLAG=-I
|
||||
|
||||
####################### Section 2 #######################
|
||||
# Define your linker and linker flags here #
|
||||
# Does your MPI provide mpi.mod or mpif.h? #
|
||||
# MPI_FINC=-DMPI_H or MPI_FINC=-DMPI_MOD #
|
||||
# If necessary add MPIINCDIR #
|
||||
##########################################################
|
||||
F90LINK=/usr/local/mpich-g95/bin/mpif90
|
||||
FLINK=/usr/local/mpich-g95/bin/mpif77
|
||||
MPF90=/usr/local/mpich-g95/bin/mpif90
|
||||
MPF77=/usr/local/mpich-g95/bin/mpif77
|
||||
MPCC=/usr/local/mpich-g95/bin/mpicc
|
||||
MPI_FINC=-DMPI_MOD
|
||||
#$(FIFLAG)/opt/SUNWhpc/include
|
||||
|
||||
####################### Section 3 #######################
|
||||
# Specify paths to libraries #
|
||||
##########################################################
|
||||
BLAS=-lblasg95 -L$(HOME)/LIB
|
||||
BLACS=-lmpiblacsg95 -L$(HOME)/LIB
|
||||
|
||||
|
||||
####################### Section 4 #######################
|
||||
# Other useful tools&defines #
|
||||
##########################################################
|
||||
#
|
||||
# The examples can make use of METIS from U. Minnesota.
|
||||
# http://www.cs.umn.edu:~karypis
|
||||
# but it's optional
|
||||
#
|
||||
#METIS_LIB = -L$(HOME)/NUMERICAL/metis-4.0 -lmetis
|
||||
PSBLDLIBS=$(BLACS) $(BLAS) $(METIS_LIB)
|
||||
|
||||
# Add -DPtr64Bits if needed
|
||||
PSBCDEFINES=-DLowerUnderscore
|
||||
#
|
||||
PSBFDEFINES=-DHAVE_KSENDID $(MPI_FINC) -DHAVE_MOVE_ALLOC
|
||||
# -DHAVE_METIS
|
||||
|
||||
AR=ar -cur
|
||||
RANLIB=ranlib
|
||||
|
||||
|
||||
|
||||
####################### Section 5 #######################
|
||||
# Do not edit this #
|
||||
##########################################################
|
||||
LIBDIR=lib
|
||||
BASELIBNAME=libpsb_base.a
|
||||
PRECLIBNAME=libpsb_prec.a
|
||||
METHDLIBNAME=libpsb_krylov.a
|
||||
UTILLIBNAME=libpsb_util.a
|
||||
|
||||
CDEFINES=$(PSBCDEFINES)
|
||||
FDEFINES=$(PSBFDEFINES)
|
||||
|
||||
$(.mod).o:
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CCOPT) $(CINCLUDES) $(CDEFINES) -c $<
|
||||
.f.o:
|
||||
$(FC) $(FCOPT) $(FINCLUDES) -c $<
|
||||
.f$(.mod):
|
||||
$(FC) $(FCOPT) $(FINCLUDES) -c $<
|
||||
.f90$(.mod):
|
||||
$(F90) $(F90COPT) $(FINCLUDES) -c $<
|
||||
.f90.o:
|
||||
$(F90) $(F90COPT) $(FINCLUDES) -c $<
|
||||
.F.o:
|
||||
$(FC) $(FCOPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
.F90.o:
|
||||
$(F90) $(F90COPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
.F90$(.mod):
|
||||
$(F90) $(F90COPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
.mod=.mod
|
||||
.fh=.fh
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .f90 .F90 $(.mod) .F .f .c .o
|
||||
|
||||
|
||||
####################### Section 1 #######################
|
||||
# Define your compilers and compiler flags here #
|
||||
##########################################################
|
||||
GNU42BIN=/usr/local/gcc42/bin
|
||||
F90=$(GNU42BIN)/gfortran
|
||||
FC=$(GNU42BIN)/gfortran
|
||||
F77=$(FC)
|
||||
CC=$(GNU42BIN)/gcc
|
||||
F90COPT=-O3 -march=native
|
||||
FCOPT=-O3 -march=native
|
||||
CCOPT=-O3 -march=native
|
||||
#
|
||||
# Which flag does your compiler use for module inclusion?
|
||||
# Most compilers use -I but Sun uses -M
|
||||
# FIFLAG is for INCLUDE
|
||||
FMFLAG=-I
|
||||
FIFLAG=-I
|
||||
|
||||
####################### Section 2 #######################
|
||||
# Define your linker and linker flags here #
|
||||
# Does your MPI provide mpi.mod or mpif.h? #
|
||||
# MPI_FINC=-DMPI_H or MPI_FINC=-DMPI_MOD #
|
||||
# If necessary add MPIINCDIR #
|
||||
##########################################################
|
||||
MPIDIR=/usr/local/mpich-gcc42
|
||||
MPIBIN=$(MPIDIR)/bin
|
||||
F90LINK=$(MPIBIN)/mpif90
|
||||
FLINK=$(MPIBIN)/mpif77
|
||||
MPF90=$(MPIBIN)/mpif90
|
||||
MPF77=$(MPIBIN)/mpif77
|
||||
MPCC=$(MPIBIN)/mpicc
|
||||
MPI_FINC=-DMPI_MOD
|
||||
#$(FIFLAG)/opt/SUNWhpc/include
|
||||
|
||||
####################### Section 3 #######################
|
||||
# Specify paths to libraries #
|
||||
##########################################################
|
||||
BLAS=-lblas-gcc42 -L$(HOME)/LIB
|
||||
BLACS=-lmpiblacs-gcc42 -L$(HOME)/LIB
|
||||
|
||||
|
||||
####################### Section 4 #######################
|
||||
# Other useful tools&defines #
|
||||
##########################################################
|
||||
#
|
||||
# The examples can make use of METIS from U. Minnesota.
|
||||
# http://www.cs.umn.edu:~karypis
|
||||
# but it's optional
|
||||
#
|
||||
#METIS_LIB = -L$(HOME)/NUMERICAL/metis-4.0 -lmetis
|
||||
PSBLDLIBS=$(BLACS) $(BLAS) $(METIS_LIB)
|
||||
|
||||
# Add -DPtr64Bits if needed
|
||||
PSBCDEFINES=-DLowerUnderscore
|
||||
#
|
||||
PSBFDEFINES=-DHAVE_KSENDID $(MPI_FINC) -DHAVE_MOVE_ALLOC
|
||||
# -DHAVE_METIS
|
||||
|
||||
AR=ar -cur
|
||||
RANLIB=ranlib
|
||||
|
||||
|
||||
|
||||
####################### Section 5 #######################
|
||||
# Do not edit this #
|
||||
##########################################################
|
||||
LIBDIR=lib
|
||||
BASELIBNAME=libpsb_base.a
|
||||
PRECLIBNAME=libpsb_prec.a
|
||||
METHDLIBNAME=libpsb_krylov.a
|
||||
UTILLIBNAME=libpsb_util.a
|
||||
|
||||
CDEFINES=$(PSBCDEFINES)
|
||||
FDEFINES=$(PSBFDEFINES)
|
||||
|
||||
$(.mod).o:
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CCOPT) $(CINCLUDES) $(CDEFINES) -c $<
|
||||
.f.o:
|
||||
$(FC) $(FCOPT) $(FINCLUDES) -c $<
|
||||
.f$(.mod):
|
||||
$(FC) $(FCOPT) $(FINCLUDES) -c $<
|
||||
.f90$(.mod):
|
||||
$(F90) $(F90COPT) $(FINCLUDES) -c $<
|
||||
.f90.o:
|
||||
$(F90) $(F90COPT) $(FINCLUDES) -c $<
|
||||
.F.o:
|
||||
$(FC) $(FCOPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
.F90.o:
|
||||
$(F90) $(F90COPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
.F90$(.mod):
|
||||
$(F90) $(F90COPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
.mod=.mod
|
||||
.fh=.fh
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .f90 .F90 $(.mod) .F .f .c .o
|
||||
|
||||
|
||||
####################### Section 1 #######################
|
||||
# Define your compilers and compiler flags here #
|
||||
##########################################################
|
||||
F90=/usr/local/gcc42/bin/gfortran
|
||||
FC=/usr/local/gcc42/bin/gfortran
|
||||
F77=$(FC)
|
||||
CC=/usr/local/gcc42/bin/gcc
|
||||
F90COPT=-O3
|
||||
FCOPT=-O3
|
||||
CCOPT=-O3
|
||||
#
|
||||
# Which flag does your compiler use for module inclusion?
|
||||
# Most compilers use -I but Sun uses -M
|
||||
# FIFLAG is for INCLUDE
|
||||
FMFLAG=-I
|
||||
FIFLAG=-I
|
||||
|
||||
####################### Section 2 #######################
|
||||
# Define your linker and linker flags here #
|
||||
# Does your MPI provide mpi.mod or mpif.h? #
|
||||
# MPI_FINC=-DMPI_H or MPI_FINC=-DMPI_MOD #
|
||||
# If necessary add MPIINCDIR #
|
||||
##########################################################
|
||||
F90LINK=$(FC)
|
||||
FLINK=$(FC)
|
||||
MPF90=$(FC)
|
||||
MPF77=$(FC)
|
||||
MPCC=$(CC)
|
||||
MPI_FINC=-DMPI_MOD
|
||||
#$(FIFLAG)/opt/SUNWhpc/include
|
||||
|
||||
####################### Section 3 #######################
|
||||
# Specify paths to libraries #
|
||||
##########################################################
|
||||
BLAS=-lblas-gcc42 -L$(HOME)/LIB
|
||||
# No BLACS in serialMPI. But we need the fakempi.o
|
||||
#BLACS=-lmpiblacs-gcc42 -L$(HOME)/LIB
|
||||
EXTRA_COBJS=fakempi.o
|
||||
|
||||
|
||||
####################### Section 4 #######################
|
||||
# Other useful tools&defines #
|
||||
##########################################################
|
||||
#
|
||||
# The examples can make use of METIS from U. Minnesota.
|
||||
# http://www.cs.umn.edu:~karypis
|
||||
# but it's optional
|
||||
#
|
||||
#METIS_LIB = -L$(HOME)/NUMERICAL/metis-4.0 -lmetis
|
||||
PSBLDLIBS=$(BLACS) $(BLAS) $(METIS_LIB)
|
||||
|
||||
# Add -DPtr64Bits if needed
|
||||
PSBCDEFINES=-DLowerUnderscore
|
||||
#
|
||||
PSBFDEFINES=-DHAVE_MOVE_ALLOC -DSERIAL_MPI $(MPI_FINC)
|
||||
# -DHAVE_METIS
|
||||
|
||||
AR=ar -cur
|
||||
RANLIB=ranlib
|
||||
|
||||
|
||||
|
||||
####################### Section 5 #######################
|
||||
# Do not edit this #
|
||||
##########################################################
|
||||
LIBDIR=lib
|
||||
BASELIBNAME=libpsb_base.a
|
||||
PRECLIBNAME=libpsb_prec.a
|
||||
METHDLIBNAME=libpsb_krylov.a
|
||||
UTILLIBNAME=libpsb_util.a
|
||||
|
||||
CDEFINES=$(PSBCDEFINES)
|
||||
FDEFINES=$(PSBFDEFINES)
|
||||
|
||||
$(.mod).o:
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CCOPT) $(CINCLUDES) $(CDEFINES) -c $<
|
||||
.f.o:
|
||||
$(FC) $(FCOPT) $(FINCLUDES) -c $<
|
||||
.f$(.mod):
|
||||
$(FC) $(FCOPT) $(FINCLUDES) -c $<
|
||||
.f90$(.mod):
|
||||
$(F90) $(F90COPT) $(FINCLUDES) -c $<
|
||||
.f90.o:
|
||||
$(F90) $(F90COPT) $(FINCLUDES) -c $<
|
||||
.F.o:
|
||||
$(FC) $(FCOPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
.F90.o:
|
||||
$(F90) $(F90COPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
.F90$(.mod):
|
||||
$(F90) $(F90COPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
.mod=.mod
|
||||
.fh=.fh
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .f90 .F90 $(.mod) .F .f .c .o
|
||||
|
||||
|
||||
####################### Section 1 #######################
|
||||
# Define your compilers and compiler flags here #
|
||||
##########################################################
|
||||
GNU43BIN=/usr/local/gcc43/bin
|
||||
F90=$(GNU43BIN)/gfortran
|
||||
FC=$(GNU43BIN)/gfortran
|
||||
F77=$(FC)
|
||||
CC=$(GNU43BIN)/gcc
|
||||
F90COPT=-O3 -march=native
|
||||
FCOPT=-O3 -march=native
|
||||
CCOPT=-O3 -march=native
|
||||
#
|
||||
# Which flag does your compiler use for module inclusion?
|
||||
# Most compilers use -I but Sun uses -M
|
||||
# FIFLAG is for INCLUDE
|
||||
FMFLAG=-I
|
||||
FIFLAG=-I
|
||||
|
||||
####################### Section 2 #######################
|
||||
# Define your linker and linker flags here #
|
||||
# Does your MPI provide mpi.mod or mpif.h? #
|
||||
# MPI_FINC=-DMPI_H or MPI_FINC=-DMPI_MOD #
|
||||
# If necessary add MPIINCDIR #
|
||||
##########################################################
|
||||
MPIDIR=/usr/local/mpich-gcc43
|
||||
MPIBIN=$(MPIDIR)/bin
|
||||
F90LINK=$(MPIBIN)/mpif90
|
||||
FLINK=$(MPIBIN)/mpif77
|
||||
MPF90=$(MPIBIN)/mpif90
|
||||
MPF77=$(MPIBIN)/mpif77
|
||||
MPCC=$(MPIBIN)/mpicc
|
||||
MPI_FINC=-DMPI_MOD
|
||||
#$(FIFLAG)/opt/SUNWhpc/include
|
||||
|
||||
####################### Section 3 #######################
|
||||
# Specify paths to libraries #
|
||||
##########################################################
|
||||
BLAS=-lblas-gcc42 -L$(HOME)/LIB
|
||||
BLACS=-lmpiblacs-gcc42 -L$(HOME)/LIB
|
||||
|
||||
|
||||
####################### Section 4 #######################
|
||||
# Other useful tools&defines #
|
||||
##########################################################
|
||||
#
|
||||
# The examples can make use of METIS from U. Minnesota.
|
||||
# http://www.cs.umn.edu:~karypis
|
||||
# but it's optional
|
||||
#
|
||||
#METIS_LIB = -L$(HOME)/NUMERICAL/metis-4.0 -lmetis
|
||||
PSBLDLIBS=$(BLACS) $(BLAS) $(METIS_LIB)
|
||||
|
||||
# Add -DPtr64Bits if needed
|
||||
PSBCDEFINES=-DLowerUnderscore
|
||||
#
|
||||
PSBFDEFINES=-DHAVE_KSENDID $(MPI_FINC) -DHAVE_MOVE_ALLOC
|
||||
# -DHAVE_METIS
|
||||
|
||||
AR=ar -cur
|
||||
RANLIB=ranlib
|
||||
|
||||
|
||||
|
||||
####################### Section 5 #######################
|
||||
# Do not edit this #
|
||||
##########################################################
|
||||
LIBDIR=lib
|
||||
BASELIBNAME=libpsb_base.a
|
||||
PRECLIBNAME=libpsb_prec.a
|
||||
METHDLIBNAME=libpsb_krylov.a
|
||||
UTILLIBNAME=libpsb_util.a
|
||||
|
||||
CDEFINES=$(PSBCDEFINES)
|
||||
FDEFINES=$(PSBFDEFINES)
|
||||
|
||||
$(.mod).o:
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CCOPT) $(CINCLUDES) $(CDEFINES) -c $<
|
||||
.f.o:
|
||||
$(FC) $(FCOPT) $(FINCLUDES) -c $<
|
||||
.f$(.mod):
|
||||
$(FC) $(FCOPT) $(FINCLUDES) -c $<
|
||||
.f90$(.mod):
|
||||
$(F90) $(F90COPT) $(FINCLUDES) -c $<
|
||||
.f90.o:
|
||||
$(F90) $(F90COPT) $(FINCLUDES) -c $<
|
||||
.F.o:
|
||||
$(FC) $(FCOPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
.F90.o:
|
||||
$(F90) $(F90COPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
.F90$(.mod):
|
||||
$(F90) $(F90COPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
.mod=.mod
|
||||
.fh=.fh
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .f90 .F90 $(.mod) .F .f .c .o
|
||||
|
||||
|
||||
####################### Section 1 #######################
|
||||
# Define your compilers and compiler flags here #
|
||||
##########################################################
|
||||
IFC9=/opt/intel/fc/9.1.033
|
||||
F90=$(IFC9)/bin/ifort
|
||||
FC=$(IFC9)/bin/ifort
|
||||
F77=$(FC)
|
||||
CC=gcc
|
||||
F90COPT=-O3
|
||||
FCOPT=-O3
|
||||
CCOPT=-O3
|
||||
#
|
||||
# Which flag does your compiler use for module inclusion?
|
||||
# Most compilers use -I but Sun uses -M
|
||||
# FIFLAG is for INCLUDE
|
||||
FMFLAG=-I
|
||||
FIFLAG=-I
|
||||
|
||||
####################### Section 2 #######################
|
||||
# Define your linker and linker flags here #
|
||||
# Does your MPI provide mpi.mod or mpif.h? #
|
||||
# MPI_FINC=-DMPI_H or MPI_FINC=-DMPI_MOD #
|
||||
# If necessary add MPIINCDIR #
|
||||
##########################################################
|
||||
MPIDIR=/usr/local/mpich-ifc91
|
||||
MPIBIN=$(MPIDIR)/bin
|
||||
F90LINK=$(MPIBIN)/mpif90
|
||||
FLINK=$(MPIBIN)/mpif77
|
||||
MPF90=$(MPIBIN)/mpif90
|
||||
MPF77=$(MPIBIN)/mpif77
|
||||
MPCC=$(MPIBIN)/mpicc
|
||||
MPI_FINC=-DMPI_MOD
|
||||
#$(FIFLAG)/opt/SUNWhpc/include
|
||||
|
||||
####################### Section 3 #######################
|
||||
# Specify paths to libraries #
|
||||
##########################################################
|
||||
BLAS=-lblas-ifort91 -L$(HOME)/LIB
|
||||
BLACS=-lmpiblacs-ifort91 -L$(HOME)/LIB
|
||||
|
||||
|
||||
|
||||
####################### Section 4 #######################
|
||||
# Other useful tools&defines #
|
||||
##########################################################
|
||||
#
|
||||
# The examples can make use of METIS from U. Minnesota.
|
||||
# http://www.cs.umn.edu:~karypis
|
||||
# but it's optional
|
||||
#
|
||||
#METIS_LIB = -L$(HOME)/NUMERICAL/metis-4.0 -lmetis
|
||||
PSBLDLIBS=$(BLACS) $(BLAS) $(METIS_LIB)
|
||||
|
||||
# Add -DPtr64Bits if needed
|
||||
PSBCDEFINES=-DLowerUnderscore
|
||||
#
|
||||
# Note: MOVE_ALLOC is only on Intel Fortran 9.1, NOT on 9.0
|
||||
PSBFDEFINES=-DHAVE_KSENDID $(MPI_FINC) -DHAVE_MOVE_ALLOC
|
||||
# -DHAVE_METIS
|
||||
|
||||
AR=ar -cur
|
||||
RANLIB=ranlib
|
||||
|
||||
|
||||
|
||||
####################### Section 5 #######################
|
||||
# Do not edit this #
|
||||
##########################################################
|
||||
LIBDIR=lib
|
||||
BASELIBNAME=libpsb_base.a
|
||||
PRECLIBNAME=libpsb_prec.a
|
||||
METHDLIBNAME=libpsb_krylov.a
|
||||
UTILLIBNAME=libpsb_util.a
|
||||
|
||||
CDEFINES=$(PSBCDEFINES)
|
||||
FDEFINES=$(PSBFDEFINES)
|
||||
|
||||
$(.mod).o:
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CCOPT) $(CINCLUDES) $(CDEFINES) -c $<
|
||||
.f.o:
|
||||
$(FC) $(FCOPT) $(FINCLUDES) -c $<
|
||||
.f$(.mod):
|
||||
$(FC) $(FCOPT) $(FINCLUDES) -c $<
|
||||
.f90$(.mod):
|
||||
$(F90) $(F90COPT) $(FINCLUDES) -c $<
|
||||
.f90.o:
|
||||
$(F90) $(F90COPT) $(FINCLUDES) -c $<
|
||||
.F.o:
|
||||
$(FC) $(FCOPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
.F90.o:
|
||||
$(F90) $(F90COPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
.F90$(.mod):
|
||||
$(F90) $(F90COPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
.mod=.mod
|
||||
.fh=.fh
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .f90 .F90 $(.mod) .F .f .c .o
|
||||
|
||||
|
||||
####################### Section 1 #######################
|
||||
# Define your compilers and compiler flags here #
|
||||
# These seems to be valid as of XLF 10.1 #
|
||||
##########################################################
|
||||
F90=xlf95 -qsuffix=f=f90:cpp=F90
|
||||
FC=xlf -qsuffix=cpp=F
|
||||
F77=$(FC)
|
||||
CC=xlc
|
||||
F90COPT= -O3
|
||||
FCOPT=-O3
|
||||
CCOPT=-O3
|
||||
#
|
||||
# Which flag does your compiler use for module inclusion?
|
||||
# Most compilers use -I but Sun uses -M
|
||||
# FIFLAG is for INCLUDE
|
||||
FMFLAG=-I
|
||||
FIFLAG=-I
|
||||
|
||||
####################### Section 2 #######################
|
||||
# Define your linker and linker flags here #
|
||||
# Does your MPI provide mpi.mod or mpif.h? #
|
||||
# MPI_FINC=-DMPI_H or MPI_FINC=-DMPI_MOD #
|
||||
# If necessary add MPIINCDIR #
|
||||
##########################################################
|
||||
MPF90=mpxlf95 -qsuffix=f=f90:cpp=F90
|
||||
F90LINK=$(MPF90)
|
||||
FLINK=$(MPF90)
|
||||
MPF77=mpxlf95 -qfixed
|
||||
MPCC=mpcc
|
||||
MPI_FINC=-WF,-DMPI_MOD
|
||||
#$(FIFLAG)/opt/SUNWhpc/include
|
||||
|
||||
####################### Section 3 #######################
|
||||
# Specify paths to libraries #
|
||||
##########################################################
|
||||
BLAS=-lessl
|
||||
BLACS=-lblacssmp
|
||||
|
||||
|
||||
####################### Section 4 #######################
|
||||
# Other useful tools&defines #
|
||||
##########################################################
|
||||
#
|
||||
# The examples can make use of METIS from U. Minnesota.
|
||||
# http://www.cs.umn.edu:~karypis
|
||||
# but it's optional
|
||||
#
|
||||
#METIS_LIB = -L$(HOME)/NUMERICAL/metis-4.0 -lmetis
|
||||
PSBLDLIBS=$(BLACS) $(BLAS) $(METIS_LIB)
|
||||
|
||||
# Add -DPtr64Bits if needed
|
||||
PSBCDEFINES=-DLowerCase -DPtr64Bits
|
||||
#
|
||||
PSBFDEFINES=-WF,-DHAVE_ESSL_BLACS $(MPI_FINC)
|
||||
# There's no MOVE_ALLOC yet in XLF 10.1.
|
||||
#-WF,-DHAVE_MOVE_ALLOC -WF,-DHAVE_METIS
|
||||
|
||||
|
||||
AR=ar -cur
|
||||
RANLIB=ranlib
|
||||
|
||||
|
||||
|
||||
####################### Section 5 #######################
|
||||
# Do not edit this #
|
||||
##########################################################
|
||||
LIBDIR=lib
|
||||
BASELIBNAME=libpsb_base.a
|
||||
PRECLIBNAME=libpsb_prec.a
|
||||
METHDLIBNAME=libpsb_krylov.a
|
||||
UTILLIBNAME=libpsb_util.a
|
||||
|
||||
CDEFINES=$(PSBCDEFINES)
|
||||
FDEFINES=$(PSBFDEFINES)
|
||||
|
||||
$(.mod).o:
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CCOPT) $(CINCLUDES) $(CDEFINES) -c $<
|
||||
.f.o:
|
||||
$(FC) $(FCOPT) $(FINCLUDES) -c $<
|
||||
.f$(.mod):
|
||||
$(FC) $(FCOPT) $(FINCLUDES) -c $<
|
||||
.f90$(.mod):
|
||||
$(F90) $(F90COPT) $(FINCLUDES) -c $<
|
||||
.f90.o:
|
||||
$(F90) $(F90COPT) $(FINCLUDES) -c $<
|
||||
.F.o:
|
||||
$(FC) $(FCOPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
.F90.o:
|
||||
$(F90) $(F90COPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
.F90$(.mod):
|
||||
$(F90) $(F90COPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
#Makefile for Sun Fortran Compiler version 6.2
|
||||
|
||||
.mod=.mod
|
||||
.fh=.fh
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .f90 .F90 $(.mod) .F .f .c .o
|
||||
|
||||
|
||||
####################### Section 1 #######################
|
||||
# Define your compilers and compiler flags here #
|
||||
##########################################################
|
||||
F90=f90
|
||||
FC=f90
|
||||
F77=$(FC)
|
||||
CC=cc
|
||||
F90COPT=-fast
|
||||
FCOPT=-fast
|
||||
CCOPT=-fast
|
||||
#
|
||||
# Which flag does your compiler use for module inclusion?
|
||||
# Most compilers use -I but Sun uses -M
|
||||
# FIFLAG is for INCLUDE
|
||||
FMFLAG=-M
|
||||
FIFLAG=-I
|
||||
|
||||
####################### Section 2 #######################
|
||||
# Define your linker and linker flags here #
|
||||
# Does your MPI provide mpi.mod or mpif.h? #
|
||||
# MPI_FINC=-DMPI_H or MPI_FINC=-DMPI_MOD #
|
||||
# If necessary add MPIINCDIR #
|
||||
##########################################################
|
||||
F90LINK=mpf90
|
||||
FLINK=mpf90 -lf77compat
|
||||
MPF90=mpf90
|
||||
MPF77=mpf90 -lf77compat
|
||||
MPCC=mpcc
|
||||
MPI_FINC=-DMPI_H $(FIFLAG)/opt/SUNWhpc/include
|
||||
|
||||
####################### Section 3 #######################
|
||||
# Specify paths to libraries #
|
||||
##########################################################
|
||||
BLAS=-lblas
|
||||
BLACS=-lblacsCinit_MPI-SUN4SOL2-0.a -lblacsF77init_MPI-SUN4SOL2-0.a -lblacs_MPI-SUN4SOL2-0.a -L$(HOME)/LIB
|
||||
BLACS=$(HOME)/LIB/libblacs_MPI-SUN4SOL2-0.a $(HOME)/LIB/libblacsCinit_MPI-SUN4SOL2-0.a $(HOME)/LIB/libblacsF77init_MPI-SUN4SOL2-0.a $(HOME)/LIB/libblacs_MPI-SUN4SOL2-0.a -lmpi
|
||||
|
||||
####################### Section 4 #######################
|
||||
# Other useful tools&defines #
|
||||
##########################################################
|
||||
#
|
||||
# The examples can make use of METIS from U. Minnesota.
|
||||
# http://www.cs.umn.edu:~karypis
|
||||
# but it's optional
|
||||
#
|
||||
#METIS_LIB = -L$(HOME)/NUMERICAL/metis-4.0 -lmetis
|
||||
PSBLDLIBS=$(BLACS) $(BLAS) $(METIS_LIB)
|
||||
|
||||
# Add -DPtr64Bits if needed
|
||||
PSBCDEFINES=-DLowerUnderscore
|
||||
# SUN compiler does not have MOVE_ALLOC.
|
||||
PSBFDEFINES=-DHAVE_KSENDID $(MPI_FINC)
|
||||
# -DHAVE_MOVE_ALLOC
|
||||
# -DHAVE_METIS
|
||||
|
||||
AR=ar -cur
|
||||
RANLIB=ranlib
|
||||
|
||||
|
||||
|
||||
####################### Section 5 #######################
|
||||
# Do not edit this #
|
||||
##########################################################
|
||||
LIBDIR=lib
|
||||
BASELIBNAME=libpsb_base.a
|
||||
PRECLIBNAME=libpsb_prec.a
|
||||
METHDLIBNAME=libpsb_krylov.a
|
||||
UTILLIBNAME=libpsb_util.a
|
||||
|
||||
CDEFINES=$(PSBCDEFINES)
|
||||
FDEFINES=$(PSBFDEFINES)
|
||||
|
||||
$(.mod).o:
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CCOPT) $(CINCLUDES) $(CDEFINES) -c $<
|
||||
.f.o:
|
||||
$(FC) $(FCOPT) $(FINCLUDES) -c $<
|
||||
.f$(.mod):
|
||||
$(FC) $(FCOPT) $(FINCLUDES) -c $<
|
||||
.f90$(.mod):
|
||||
$(F90) $(F90COPT) $(FINCLUDES) -c $<
|
||||
.f90.o:
|
||||
$(F90) $(F90COPT) $(FINCLUDES) -c $<
|
||||
.F.o:
|
||||
$(FC) $(FCOPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
.F90.o:
|
||||
$(F90) $(F90COPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
.F90$(.mod):
|
||||
$(F90) $(F90COPT) $(FINCLUDES) $(FDEFINES) -c $<
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ install:
|
||||
$(INSTALL_DATA) lib/*.a $(INSTALL_LIBDIR))
|
||||
(./mkdir.sh $(INSTALL_INCLUDEDIR) && \
|
||||
$(INSTALL_DATA) lib/*$(.mod) $(INSTALL_INCLUDEDIR))
|
||||
(./mkdir.sh $(INSTALL_DOCSDIR) && \
|
||||
/bin/cp -fr docs/*pdf docs/html $(INSTALL_DOCSDIR))
|
||||
clean:
|
||||
(cd base; make clean)
|
||||
(cd prec; make clean )
|
||||
@@ -31,4 +33,7 @@ veryclean: cleanlib
|
||||
(cd prec; make veryclean )
|
||||
(cd krylov; make veryclean)
|
||||
(cd util; make veryclean)
|
||||
(cd test/fileread; make clean)
|
||||
(cd test/pargen; make clean)
|
||||
(cd test/util; make clean)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
This directory contains the PSBLAS library, version 2.2
|
||||
This directory contains the PSBLAS library, version 2.3
|
||||
|
||||
|
||||
Version 1.0 of the library was described in:
|
||||
@@ -22,13 +22,10 @@ specified in TR15581).
|
||||
|
||||
For the Intel compilers, we recommend version 9.1 or later.
|
||||
|
||||
IBM SP.
|
||||
IBM SP:
|
||||
The library has been tested on an IBM SP5, with XLC and XLF
|
||||
version 10.1 and the IBM ESSL/PESSL versions of the BLAS and the
|
||||
BLACS.
|
||||
The setting
|
||||
F90=xlf95 -qsuffix=f=f90:cpp=F90
|
||||
in Make.inc.sp5 takes care of the f90/F90 extensions.
|
||||
|
||||
|
||||
UTILITIES
|
||||
@@ -38,7 +35,8 @@ Harwell-Boeing and MatrixMarket file formats.
|
||||
|
||||
DOCUMENTATION
|
||||
|
||||
See userguide.pdf
|
||||
See docs/psblas-2.3.pdf; an HTML version of the same document is
|
||||
available in docs/html.
|
||||
Please consult the sample programs, especially test/pargen/ppde.f90.
|
||||
|
||||
|
||||
@@ -55,11 +53,6 @@ Level 3 basic linear algebra subprograms for sparse matrices: a user
|
||||
level interface
|
||||
ACM Trans. Math. Softw., 23(3), 379-401, 1997.
|
||||
|
||||
In the multilevel preconditioners we use SMMP by Randolph E. Bank and
|
||||
Craig C. Douglas na.bank@na-net.ornl.gov and
|
||||
na.cdouglas@na-net.ornl.gov; we wrapped it in a Fortran 95 interface
|
||||
with dynamic memory allocation.
|
||||
|
||||
INSTALLING
|
||||
|
||||
To compile and run our software you will need the following
|
||||
@@ -80,8 +73,8 @@ prerequisites (see also SERIAL below):
|
||||
This is optional; it is used in the util and test/fileread
|
||||
directories but only if you define the HAVE_METIS directive.
|
||||
|
||||
We offer an experimental configure script: if everything works well,
|
||||
it will generate a Make.inc file suitable for building the library.
|
||||
The configure script will generate a Make.inc file suitable for
|
||||
building the library.
|
||||
The script is capable of recognizing the needed libraries with their
|
||||
default names; if they are in unusual places consider adding the paths
|
||||
with --with-lib, or explicitly specifying the names in --with-blas,
|
||||
@@ -89,32 +82,17 @@ with --with-lib, or explicitly specifying the names in --with-blas,
|
||||
Please note that a common way for the configure script to fail is to
|
||||
specify inconsistent MPI vs. plain compilers, either directly or
|
||||
indirectly via environment variables; e.g. specifying the Intel
|
||||
compiler with FC=ifort and the default MPIFC=mpif90 which points to
|
||||
GNU Fortran 4.1. The best way to avoid this situation is (in our
|
||||
opinion) to use the environment modules package (see
|
||||
http://modules.sourceforge.net/), and load the relevant variables with
|
||||
(e.g.)
|
||||
compiler with FC=ifort while at the same time having an MPIFC=mpif90
|
||||
which points to GNU Fortran.
|
||||
The best way to avoid this situation is (in our opinion) to use the
|
||||
environment modules package (see http://modules.sourceforge.net/), and
|
||||
load the relevant variables with (e.g.)
|
||||
module load gnu42 mpich
|
||||
This will delegate to the modules setup to make sure that the version
|
||||
of mpich in use is the one compiled with the gnu42 compilers.
|
||||
After the configure script has completed you can always tweak the
|
||||
Make.inc file yourself.
|
||||
|
||||
An annoying problem exists with some versions of MPICH: the configure
|
||||
script will set -DMPI_MOD, which is to say, the MPI call interfaces
|
||||
will be resolved by using the MPI Fortran module. However usage of the
|
||||
module may cause compilation to fail if coupled with the debugging
|
||||
option -ggdb, because the compiler complains that it cannot find any
|
||||
matching interface.
|
||||
The solution: either take out the -ggdb option, or, if you really need
|
||||
to debug, force -DMPI_H in place of -DMPI_MOD.
|
||||
|
||||
|
||||
As a backup alternative, you can always choose a Make.inc.XXX file in
|
||||
directory Make that fits your compilers, modify the paths to libraries
|
||||
to match your installation and copy it to Make.inc in the top
|
||||
directory.
|
||||
|
||||
After you have Make.inc fixed, run
|
||||
make
|
||||
to compile the library; go to the test directory and its
|
||||
@@ -134,52 +112,33 @@ coupled with the debugging option -g, because the compiler complains
|
||||
that it cannot find a matching interface for some of the
|
||||
communication routines.
|
||||
The solution: either take out the -g option, or, if you really need to
|
||||
debug, force -DMPI_H in place of -DMPI_MOD.
|
||||
debug, edit Make.inc to force -DMPI_H in place of -DMPI_MOD.
|
||||
|
||||
|
||||
|
||||
|
||||
SERIAL: We now provide an (experimental) option to run in serial
|
||||
mode. This has only been tested with GCC but it should work
|
||||
with the others as well. In serial mode you don't need the
|
||||
prereqs 1 and 2 above, and you need to use the -serialmpi
|
||||
Make.inc. BEWARE: we only provide a VERY minimal set of fake mpi
|
||||
routines that is known to work with our codes; specifically, we
|
||||
do not handle a process doing send/receives to itself, neither
|
||||
do we handle user defined data types.
|
||||
|
||||
TODO:
|
||||
Fix all reamining bugs. Bugs? We dont' have any ! ;-)
|
||||
Work on a single precision version if there is sufficient demand for
|
||||
it.
|
||||
|
||||
|
||||
The PSBLAS team.
|
||||
|
||||
RELATED SOFTWARE
|
||||
|
||||
If you are looking for more sophisticated preconditioners, you may be
|
||||
interested in the package MLD2P4 from http://www.mld2p4.it
|
||||
|
||||
|
||||
|
||||
Contact: Salvatore Filippone salvatore.filippone@uniroma2.it
|
||||
|
||||
Credits for version 2.2:
|
||||
Michele Martone contributed the configure machinery.
|
||||
Michele Martone contributed the initial version of the configure
|
||||
machinery.
|
||||
|
||||
Credits for version 2.0:
|
||||
Salvatore Filippone
|
||||
Alfredo Buttari
|
||||
|
||||
|
||||
In a sister package called MLD2P4 we are going to provide a library of
|
||||
more sophisticated preconditioners, including parallel multilevel ones
|
||||
that were developed with the contribution of:
|
||||
Pasqua D'Ambra
|
||||
Daniela di Serafino
|
||||
|
||||
In that package we will provide interfaces to the following software
|
||||
packages:
|
||||
-- SuperLU 3.0 http://crd.lbl.gov/~xiaoye/SuperLU/
|
||||
-- UMFPACK 4.4 http://www.cise.ufl.edu/research/sparse/umfpack/
|
||||
These are optional, you only need to install them if you actually want
|
||||
to use them.
|
||||
The MLD2P4 package will be published soon, watch this space!.
|
||||
|
||||
Credits for version 1.0:
|
||||
|
||||
Salvatore Filippone
|
||||
|
||||
@@ -4,7 +4,7 @@ FOBJS = psi_compute_size.o psi_crea_bnd_elem.o psi_crea_index.o \
|
||||
psi_crea_ovr_elem.o psi_bld_tmpovrl.o psi_dl_check.o \
|
||||
psi_sort_dl.o \
|
||||
psi_ldsc_pre_halo.o psi_bld_tmphalo.o psi_bld_hash.o\
|
||||
psi_sort_dl.o psi_idx_cnv.o psi_idx_ins_cnv.o psi_fnd_owner.o
|
||||
psi_sort_dl.o psi_idx_cnv.o psi_idx_ins_cnv.o
|
||||
FOBJS2 = psi_exist_ovr_elem.o psi_list_search.o srtlist.o
|
||||
#COBJS = avltree.o srcht.o
|
||||
|
||||
@@ -13,7 +13,7 @@ MPFOBJS = psi_dswapdata.o psi_dswaptran.o\
|
||||
psi_iswapdata.o psi_iswaptran.o \
|
||||
psi_cswapdata.o psi_cswaptran.o \
|
||||
psi_zswapdata.o psi_zswaptran.o \
|
||||
psi_desc_index.o psi_extrct_dl.o
|
||||
psi_desc_index.o psi_extrct_dl.o psi_fnd_owner.o
|
||||
LIBDIR=..
|
||||
MODDIR=../modules
|
||||
FINCLUDES=$(FMFLAG)$(LIBDIR) $(FMFLAG)$(MODDIR) $(FMFLAG).
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
! File: psi_bld_hash.f90
|
||||
!
|
||||
! Subroutine: psi_bld_hash
|
||||
! Convers the AVL tree data structure into the hashed list
|
||||
! of ordered sublists.
|
||||
! Build a hashed list of ordered sublists of the indices
|
||||
! contained in loc_to_glob.
|
||||
!
|
||||
!
|
||||
! Arguments:
|
||||
@@ -53,7 +53,7 @@ subroutine psi_bld_hash(desc,info)
|
||||
type(psb_desc_type), intent(inout) :: desc
|
||||
integer, intent(out) :: info
|
||||
|
||||
integer :: i,j,np,me,lhalo,nhalo,&
|
||||
integer :: i,j,np,me,lhalo,nhalo,nbits,hsize,hmask,&
|
||||
& n_col, err_act, key, ih, nh, idx, nk,icomm
|
||||
integer :: ictxt,n_row
|
||||
character(len=20) :: name,ch_err
|
||||
@@ -85,7 +85,26 @@ subroutine psi_bld_hash(desc,info)
|
||||
|
||||
nk = n_col
|
||||
call psb_realloc(nk,2,desc%glb_lc,info)
|
||||
if (info ==0) call psb_realloc(psb_hash_size+1,desc%hashv,info,lb=0)
|
||||
|
||||
nbits = psb_hash_bits
|
||||
hsize = 2**nbits
|
||||
do
|
||||
if (hsize < 0) then
|
||||
! This should never happen for sane values
|
||||
! of psb_max_hash_bits.
|
||||
write(0,*) 'Error: hash size overflow ',hsize,nbits
|
||||
info = -2
|
||||
return
|
||||
end if
|
||||
if (hsize > nk) exit
|
||||
if (nbits >= psb_max_hash_bits) exit
|
||||
nbits = nbits + 1
|
||||
hsize = hsize * 2
|
||||
end do
|
||||
hmask = hsize - 1
|
||||
desc%hashvsize = hsize
|
||||
desc%hashvmask = hmask
|
||||
if (info ==0) call psb_realloc(hsize+1,desc%hashv,info,lb=0)
|
||||
if (info /= 0) then
|
||||
ch_err='psb_realloc'
|
||||
call psb_errpush(info,name,a_err=ch_err)
|
||||
@@ -94,32 +113,32 @@ subroutine psi_bld_hash(desc,info)
|
||||
|
||||
! Build a hashed table of sorted lists to search for
|
||||
! indices.
|
||||
desc%hashv(0:psb_hash_size) = 0
|
||||
desc%hashv(0:hsize) = 0
|
||||
do i=1, nk
|
||||
key = desc%loc_to_glob(i)
|
||||
ih = iand(key,psb_hash_mask)
|
||||
ih = iand(key,hmask)
|
||||
desc%hashv(ih) = desc%hashv(ih) + 1
|
||||
end do
|
||||
nh = desc%hashv(0)
|
||||
idx = 1
|
||||
do i=1, psb_hash_size
|
||||
do i=1, hsize
|
||||
desc%hashv(i-1) = idx
|
||||
idx = idx + nh
|
||||
nh = desc%hashv(i)
|
||||
end do
|
||||
do i=1, nk
|
||||
key = desc%loc_to_glob(i)
|
||||
ih = iand(key,psb_hash_mask)
|
||||
ih = iand(key,hmask)
|
||||
idx = desc%hashv(ih)
|
||||
desc%glb_lc(idx,1) = key
|
||||
desc%glb_lc(idx,2) = i
|
||||
desc%hashv(ih) = desc%hashv(ih) + 1
|
||||
end do
|
||||
do i = psb_hash_size, 1, -1
|
||||
do i = hsize, 1, -1
|
||||
desc%hashv(i) = desc%hashv(i-1)
|
||||
end do
|
||||
desc%hashv(0) = 1
|
||||
do i=0, psb_hash_size-1
|
||||
do i=0, hsize-1
|
||||
idx = desc%hashv(i)
|
||||
nh = desc%hashv(i+1) - desc%hashv(i)
|
||||
if (nh > 1) then
|
||||
|
||||
@@ -91,53 +91,44 @@ subroutine psi_bld_tmphalo(desc,info)
|
||||
! Here we do not know yet who owns what, so we have
|
||||
! to call fnd_owner.
|
||||
nh = (n_col-n_row)
|
||||
if (nh >= 0) then
|
||||
Allocate(helem(nh),stat=info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='Allocate')
|
||||
goto 9999
|
||||
end if
|
||||
Allocate(helem(max(1,nh)),stat=info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='Allocate')
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
do i=1, nh
|
||||
helem(i) = desc%loc_to_glob(n_row+i)
|
||||
end do
|
||||
do i=1, nh
|
||||
helem(i) = desc%loc_to_glob(n_row+i)
|
||||
end do
|
||||
|
||||
call psi_fnd_owner(nh,helem,hproc,desc,info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='fnd_owner')
|
||||
goto 9999
|
||||
endif
|
||||
if (nh > size(hproc)) then
|
||||
info=4010
|
||||
call psb_errpush(4010,name,a_err='nh > size(hproc)')
|
||||
goto 9999
|
||||
end if
|
||||
allocate(tmphl((3*((n_col-n_row)+1)+1)),stat=info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='Allocate')
|
||||
goto 9999
|
||||
end if
|
||||
j = 1
|
||||
do i=1,nh
|
||||
tmphl(j+0) = hproc(i)
|
||||
if (tmphl(j+0)<0) then
|
||||
write(0,*) 'Unrecoverable error: missing proc from asb'
|
||||
end if
|
||||
tmphl(j+1) = 1
|
||||
tmphl(j+2) = n_row+i
|
||||
j = j + 3
|
||||
end do
|
||||
tmphl(j) = -1
|
||||
lhalo = j
|
||||
nhalo = (lhalo-1)/3
|
||||
else
|
||||
allocate(tmphl(1),stat=info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='Allocate')
|
||||
goto 9999
|
||||
end if
|
||||
tmphl=-1
|
||||
call psi_fnd_owner(nh,helem,hproc,desc,info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='fnd_owner')
|
||||
goto 9999
|
||||
endif
|
||||
if (nh > size(hproc)) then
|
||||
info=4010
|
||||
call psb_errpush(4010,name,a_err='nh > size(hproc)')
|
||||
goto 9999
|
||||
end if
|
||||
allocate(tmphl((3*((n_col-n_row)+1)+1)),stat=info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='Allocate')
|
||||
goto 9999
|
||||
end if
|
||||
j = 1
|
||||
do i=1,nh
|
||||
tmphl(j+0) = hproc(i)
|
||||
if (tmphl(j+0)<0) then
|
||||
write(0,*) 'Unrecoverable error: missing proc from asb'
|
||||
end if
|
||||
tmphl(j+1) = 1
|
||||
tmphl(j+2) = n_row+i
|
||||
j = j + 3
|
||||
end do
|
||||
tmphl(j) = -1
|
||||
lhalo = j
|
||||
nhalo = (lhalo-1)/3
|
||||
|
||||
call psb_transfer(tmphl,desc%halo_index,info)
|
||||
|
||||
|
||||
@@ -0,0 +1,300 @@
|
||||
!!$
|
||||
!!$ Parallel Sparse BLAS version 2.2
|
||||
!!$ (C) Copyright 2006/2007/2008
|
||||
!!$ Salvatore Filippone University of Rome Tor Vergata
|
||||
!!$ Alfredo Buttari University of Rome Tor Vergata
|
||||
!!$
|
||||
!!$ Redistribution and use in source and binary forms, with or without
|
||||
!!$ modification, are permitted provided that the following conditions
|
||||
!!$ are met:
|
||||
!!$ 1. Redistributions of source code must retain the above copyright
|
||||
!!$ notice, this list of conditions and the following disclaimer.
|
||||
!!$ 2. Redistributions in binary form must reproduce the above copyright
|
||||
!!$ notice, this list of conditions, and the following disclaimer in the
|
||||
!!$ documentation and/or other materials provided with the distribution.
|
||||
!!$ 3. The name of the PSBLAS group or the names of its contributors may
|
||||
!!$ not be used to endorse or promote products derived from this
|
||||
!!$ software without specific written permission.
|
||||
!!$
|
||||
!!$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
!!$ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
!!$ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
!!$ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
|
||||
!!$ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
!!$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
!!$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
!!$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
!!$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
!!$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
!!$ POSSIBILITY OF SUCH DAMAGE.
|
||||
!!$
|
||||
!!$
|
||||
!
|
||||
! File: psi_fnd_owner.f90
|
||||
!
|
||||
! Subroutine: psi_fnd_owner
|
||||
! Figure out who owns global indices.
|
||||
!
|
||||
! Arguments:
|
||||
! nv - integer Number of indices required on the calling
|
||||
! process
|
||||
! idx(:) - integer Required indices on the calling process.
|
||||
! Note: the indices should be unique!
|
||||
! iprc(:) - integer, allocatable Output: process identifiers for the corresponding
|
||||
! indices
|
||||
! desc_a - type(psb_desc_type). The communication descriptor.
|
||||
! info - integer. return code.
|
||||
!
|
||||
subroutine psi_fnd_owner(nv,idx,iprc,desc,info)
|
||||
use psb_descriptor_type
|
||||
use psb_serial_mod
|
||||
use psb_const_mod
|
||||
use psb_error_mod
|
||||
use psb_penv_mod
|
||||
use psb_realloc_mod
|
||||
use psi_mod, psb_protect_name => psi_fnd_owner
|
||||
#ifdef MPI_MOD
|
||||
use mpi
|
||||
#endif
|
||||
|
||||
implicit none
|
||||
#ifdef MPI_H
|
||||
include 'mpif.h'
|
||||
#endif
|
||||
integer, intent(in) :: nv
|
||||
integer, intent(in) :: idx(:)
|
||||
integer, allocatable, intent(out) :: iprc(:)
|
||||
type(psb_desc_type), intent(in) :: desc
|
||||
integer, intent(out) :: info
|
||||
|
||||
|
||||
integer, allocatable :: hsz(:),hidx(:),helem(:),hproc(:),&
|
||||
& sdsz(:),sdidx(:), rvsz(:), rvidx(:),answers(:,:),idxsrch(:,:)
|
||||
|
||||
integer :: i,n_row,n_col,err_act,ih,icomm,hsize,ip,isz,k,j,&
|
||||
& last_ih, last_j
|
||||
integer :: ictxt,np,me
|
||||
logical, parameter :: gettime=.false.
|
||||
real(psb_dpk_) :: t0, t1, t2, t3, t4, tamx, tidx
|
||||
character(len=20) :: name
|
||||
|
||||
info = 0
|
||||
name = 'psi_fnd_owner'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
ictxt = psb_cd_get_context(desc)
|
||||
icomm = psb_cd_get_mpic(desc)
|
||||
n_row = psb_cd_get_local_rows(desc)
|
||||
n_col = psb_cd_get_local_cols(desc)
|
||||
|
||||
|
||||
! check on blacs grid
|
||||
call psb_info(ictxt, me, np)
|
||||
if (np == -1) then
|
||||
info = 2010
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
if (nv < 0 ) then
|
||||
info = 2010
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
if (.not.(psb_is_ok_desc(desc))) then
|
||||
call psb_errpush(4010,name,a_err='invalid desc')
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
if (gettime) then
|
||||
t0 = psb_wtime()
|
||||
end if
|
||||
!
|
||||
! The basic idea is very simple.
|
||||
! First we collect (to all) all the requests.
|
||||
Allocate(hidx(np+1),hsz(np),&
|
||||
& sdsz(0:np-1),sdidx(0:np-1),&
|
||||
& rvsz(0:np-1),rvidx(0:np-1),&
|
||||
& stat=info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='Allocate')
|
||||
goto 9999
|
||||
end if
|
||||
hsz = 0
|
||||
hsz(me+1) = nv
|
||||
call psb_amx(ictxt,hsz,info)
|
||||
hidx(1) = 0
|
||||
do i=1, np
|
||||
hidx(i+1) = hidx(i) + hsz(i)
|
||||
end do
|
||||
hsize = hidx(np+1)
|
||||
Allocate(helem(hsize),hproc(hsize),stat=info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='Allocate')
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
if (gettime) then
|
||||
t3 = psb_wtime()
|
||||
end if
|
||||
|
||||
call mpi_allgatherv(idx,hsz(me+1),mpi_integer,&
|
||||
& hproc,hsz,hidx,mpi_integer,&
|
||||
& icomm,info)
|
||||
if (gettime) then
|
||||
tamx = psb_wtime() - t3
|
||||
end if
|
||||
|
||||
! Second, we figure out locally whether we own the indices (whoever is
|
||||
! asking for them).
|
||||
if (gettime) then
|
||||
t3 = psb_wtime()
|
||||
end if
|
||||
call psi_idx_cnv(hsize,hproc,helem,desc,info,owned=.true.)
|
||||
if (gettime) then
|
||||
tidx = psb_wtime()-t3
|
||||
end if
|
||||
if (info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='psi_idx_cnv')
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
! Third: we build the answers for those indices we own,
|
||||
! with a section for each process asking.
|
||||
hidx = hidx +1
|
||||
j = 0
|
||||
do ip = 0, np-1
|
||||
sdidx(ip) = j
|
||||
sdsz(ip) = 0
|
||||
do i=hidx(ip+1), hidx(ip+1+1)-1
|
||||
if ((0 < helem(i)).and. (helem(i) <= n_row)) then
|
||||
j = j + 1
|
||||
hproc(j) = hproc(i)
|
||||
sdsz(ip) = sdsz(ip) + 1
|
||||
end if
|
||||
end do
|
||||
end do
|
||||
|
||||
if (gettime) then
|
||||
t3 = psb_wtime()
|
||||
end if
|
||||
! Collect all the answers with alltoallv (need sizes)
|
||||
call mpi_alltoall(sdsz,1,mpi_integer,rvsz,1,mpi_integer,icomm,info)
|
||||
|
||||
isz = sum(rvsz)
|
||||
|
||||
allocate(answers(isz,2),idxsrch(nv,2),stat=info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='Allocate')
|
||||
goto 9999
|
||||
end if
|
||||
j = 0
|
||||
do ip=0, np-1
|
||||
rvidx(ip) = j
|
||||
j = j + rvsz(ip)
|
||||
end do
|
||||
call mpi_alltoallv(hproc,sdsz,sdidx,mpi_integer,&
|
||||
& answers(:,1),rvsz,rvidx,mpi_integer,&
|
||||
& icomm,info)
|
||||
if (gettime) then
|
||||
tamx = psb_wtime() - t3 + tamx
|
||||
end if
|
||||
j = 1
|
||||
do ip = 0,np-1
|
||||
do k=1,rvsz(ip)
|
||||
answers(j,2) = ip
|
||||
j = j + 1
|
||||
end do
|
||||
end do
|
||||
! Sort the answers and the requests, so we can
|
||||
! match them efficiently
|
||||
call psb_msort(answers(:,1),ix=answers(:,2),&
|
||||
& flag=psb_sort_keep_idx_)
|
||||
idxsrch(1:nv,1) = idx(1:nv)
|
||||
call psb_msort(idxsrch(1:nv,1),ix=idxsrch(1:nv,2))
|
||||
|
||||
! Now extract the answers for our local query
|
||||
call psb_realloc(nv,iprc,info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='psb_realloc')
|
||||
goto 9999
|
||||
end if
|
||||
last_ih = -1
|
||||
last_j = -1
|
||||
j = 1
|
||||
do i=1, nv
|
||||
ih = idxsrch(i,1)
|
||||
if (ih == last_ih) then
|
||||
iprc(idxsrch(i,2)) = answers(last_j,2)
|
||||
else
|
||||
|
||||
do
|
||||
if (j > size(answers,1)) then
|
||||
! Last resort attempt.
|
||||
call ibsrch(j,ih,size(answers,1),answers(:,1))
|
||||
if (j == -1) then
|
||||
write(0,*) me,'psi_fnd_owner: searching for ',ih, &
|
||||
& 'not found : ',size(answers,1),':',answers(:,1)
|
||||
info = 4001
|
||||
call psb_errpush(4001,name,a_err='out bounds srch ih')
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
if (answers(j,1) == ih) exit
|
||||
if (answers(j,1) > ih) then
|
||||
k = j
|
||||
call ibsrch(j,ih,k,answers(1:k,1))
|
||||
if (j == -1) then
|
||||
write(0,*) me,'psi_fnd_owner: searching for ',ih, &
|
||||
& 'not found : ',size(answers,1),':',answers(:,1)
|
||||
info = 4001
|
||||
call psb_errpush(4001,name,a_err='out bounds srch ih')
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
|
||||
j = j + 1
|
||||
end do
|
||||
! Note that the answers here are given in order
|
||||
! of sending process, so we are implicitly getting
|
||||
! the max process index in case of overlap.
|
||||
last_ih = ih
|
||||
do
|
||||
last_j = j
|
||||
iprc(idxsrch(i,2)) = answers(j,2)
|
||||
j = j + 1
|
||||
if (j > size(answers,1)) exit
|
||||
if (answers(j,1) /= ih) exit
|
||||
end do
|
||||
end if
|
||||
end do
|
||||
|
||||
if (gettime) then
|
||||
call psb_barrier(ictxt)
|
||||
t1 = psb_wtime()
|
||||
t1 = t1 -t0 - tamx - tidx
|
||||
call psb_amx(ictxt,tamx)
|
||||
call psb_amx(ictxt,tidx)
|
||||
call psb_amx(ictxt,t1)
|
||||
if (me==psb_root_) then
|
||||
write(*,'(" fnd_owner idx time : ",es10.4)') tidx
|
||||
write(*,'(" fnd_owner amx time : ",es10.4)') tamx
|
||||
write(*,'(" fnd_owner remainedr : ",es10.4)') t1
|
||||
endif
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 continue
|
||||
call psb_erractionrestore(err_act)
|
||||
|
||||
if (err_act == psb_act_ret_) then
|
||||
return
|
||||
else
|
||||
call psb_error(ictxt)
|
||||
end if
|
||||
return
|
||||
|
||||
end subroutine psi_fnd_owner
|
||||
@@ -1,168 +0,0 @@
|
||||
!!$
|
||||
!!$ Parallel Sparse BLAS version 2.2
|
||||
!!$ (C) Copyright 2006/2007/2008
|
||||
!!$ Salvatore Filippone University of Rome Tor Vergata
|
||||
!!$ Alfredo Buttari University of Rome Tor Vergata
|
||||
!!$
|
||||
!!$ Redistribution and use in source and binary forms, with or without
|
||||
!!$ modification, are permitted provided that the following conditions
|
||||
!!$ are met:
|
||||
!!$ 1. Redistributions of source code must retain the above copyright
|
||||
!!$ notice, this list of conditions and the following disclaimer.
|
||||
!!$ 2. Redistributions in binary form must reproduce the above copyright
|
||||
!!$ notice, this list of conditions, and the following disclaimer in the
|
||||
!!$ documentation and/or other materials provided with the distribution.
|
||||
!!$ 3. The name of the PSBLAS group or the names of its contributors may
|
||||
!!$ not be used to endorse or promote products derived from this
|
||||
!!$ software without specific written permission.
|
||||
!!$
|
||||
!!$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
!!$ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
!!$ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
!!$ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
|
||||
!!$ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
!!$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
!!$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
!!$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
!!$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
!!$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
!!$ POSSIBILITY OF SUCH DAMAGE.
|
||||
!!$
|
||||
!!$
|
||||
!
|
||||
! File: psi_fnd_owner.f90
|
||||
!
|
||||
! Subroutine: psi_fnd_owner
|
||||
! Figure out who owns global indices.
|
||||
!
|
||||
! Arguments:
|
||||
! nv - integer Number of indices required on the calling
|
||||
! process
|
||||
! idx(:) - integer Required indices on the calling process
|
||||
! iprc(:) - integer, allocatable Output: process identifiers for the corresponding
|
||||
! indices
|
||||
! desc_a - type(psb_desc_type). The communication descriptor.
|
||||
! info - integer. return code.
|
||||
!
|
||||
subroutine psi_fnd_owner(nv,idx,iprc,desc,info)
|
||||
use psb_descriptor_type
|
||||
use psb_serial_mod
|
||||
use psb_const_mod
|
||||
use psb_error_mod
|
||||
use psb_penv_mod
|
||||
use psb_realloc_mod
|
||||
use psi_mod, psb_protect_name => psi_fnd_owner
|
||||
|
||||
implicit none
|
||||
integer, intent(in) :: nv
|
||||
integer, intent(in) :: idx(:)
|
||||
integer, allocatable, intent(out) :: iprc(:)
|
||||
type(psb_desc_type), intent(in) :: desc
|
||||
integer, intent(out) :: info
|
||||
|
||||
|
||||
integer,allocatable :: hsz(:),hidx(:),helem(:),hproc(:)
|
||||
|
||||
integer :: i,n_row,n_col, err_act,ih,icomm,hsize
|
||||
integer :: ictxt,np,me
|
||||
character(len=20) :: name
|
||||
|
||||
info = 0
|
||||
name = 'psi_fnd_owner'
|
||||
call psb_erractionsave(err_act)
|
||||
|
||||
ictxt = psb_cd_get_context(desc)
|
||||
icomm = psb_cd_get_mpic(desc)
|
||||
n_row = psb_cd_get_local_rows(desc)
|
||||
n_col = psb_cd_get_local_cols(desc)
|
||||
|
||||
|
||||
! check on blacs grid
|
||||
call psb_info(ictxt, me, np)
|
||||
if (np == -1) then
|
||||
info = 2010
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
if (nv < 0 ) then
|
||||
info = 2010
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
if (.not.(psb_is_ok_desc(desc))) then
|
||||
call psb_errpush(4010,name,a_err='invalid desc')
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
!
|
||||
! The basic idea is very simple.
|
||||
! First we figure out the total number of requests.
|
||||
Allocate(hidx(np+1),hsz(np),stat=info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='Allocate')
|
||||
goto 9999
|
||||
end if
|
||||
hsz = 0
|
||||
hsz(me+1) = nv
|
||||
call psb_amx(ictxt,hsz,info)
|
||||
hidx(1) = 1
|
||||
do i=1, np
|
||||
hidx(i+1) = hidx(i) + hsz(i)
|
||||
end do
|
||||
hsize = hidx(np+1)-1
|
||||
Allocate(helem(hsize),hproc(hsize),stat=info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='Allocate')
|
||||
goto 9999
|
||||
end if
|
||||
! Second we build the aggregate list of requests (with psb_amx)
|
||||
helem(:) = 0
|
||||
ih = hidx(me+1)
|
||||
do i=1, hsz(me+1)
|
||||
helem(ih+i-1) = idx(i)
|
||||
end do
|
||||
call psb_amx(ictxt,helem,info)
|
||||
! Third, we figure out locally whether we own the indices (whoever is
|
||||
! asking for them) and build our part of the reply (we shift process
|
||||
! indices so that they're 1-based)
|
||||
call psi_idx_cnv(hsize,helem,desc,info,owned=.true.)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='psi_idx_cnv')
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
do i=1,hsize
|
||||
if ((0< helem(i)).and. (helem(i) <= n_row))then
|
||||
hproc(i) = me+1
|
||||
else
|
||||
hproc(i) = 0
|
||||
end if
|
||||
end do
|
||||
|
||||
! Fourth, we do a psb_amx on the replies so that we have everybody's answers
|
||||
call psb_amx(ictxt,hproc,info)
|
||||
|
||||
! Fifth, we extract the answers for our local query, and shift back the
|
||||
! process indices to 0-based.
|
||||
|
||||
call psb_realloc(nv,iprc,info)
|
||||
ih = hidx(me+1)
|
||||
do i=1, hsz(me+1)
|
||||
iprc(i) = hproc(ih+i-1) - 1
|
||||
end do
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 continue
|
||||
call psb_erractionrestore(err_act)
|
||||
|
||||
if (err_act == psb_act_ret_) then
|
||||
return
|
||||
else
|
||||
call psb_error(ictxt)
|
||||
end if
|
||||
return
|
||||
|
||||
end subroutine psi_fnd_owner
|
||||
@@ -56,15 +56,13 @@ subroutine psi_idx_cnv1(nv,idxin,desc,info,mask,owned)
|
||||
integer, intent(inout) :: idxin(:)
|
||||
type(psb_desc_type), intent(in) :: desc
|
||||
integer, intent(out) :: info
|
||||
logical, intent(in), optional, target :: mask(:)
|
||||
logical, intent(in), optional :: mask(:)
|
||||
logical, intent(in), optional :: owned
|
||||
integer :: ictxt,mglob, nglob
|
||||
integer :: ictxt,mglob, nglob,ip,lip,i
|
||||
integer :: np, me
|
||||
integer :: nrow,ncol, err_act
|
||||
integer, allocatable :: idxout(:)
|
||||
integer, parameter :: relocsz=200
|
||||
character(len=20) :: name
|
||||
logical, pointer :: mask_(:)
|
||||
logical :: owned_
|
||||
|
||||
info = 0
|
||||
@@ -91,7 +89,7 @@ subroutine psi_idx_cnv1(nv,idxin,desc,info,mask,owned)
|
||||
goto 9999
|
||||
end if
|
||||
if (nv == 0) return
|
||||
|
||||
|
||||
|
||||
if (size(idxin) < nv) then
|
||||
info = 1111
|
||||
@@ -106,15 +104,6 @@ subroutine psi_idx_cnv1(nv,idxin,desc,info,mask,owned)
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
mask_ => mask
|
||||
else
|
||||
allocate(mask_(nv),stat=info)
|
||||
if (info /= 0) then
|
||||
info = 4000
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
mask_ = .true.
|
||||
endif
|
||||
|
||||
if (present(owned)) then
|
||||
@@ -123,19 +112,123 @@ subroutine psi_idx_cnv1(nv,idxin,desc,info,mask,owned)
|
||||
owned_ = .false.
|
||||
endif
|
||||
|
||||
allocate(idxout(nv),stat=info)
|
||||
if (info /= 0) then
|
||||
info = 4000
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
call psi_idx_cnv2(nv,idxin,idxout,desc,info,mask_,owned_)
|
||||
idxin(1:nv) = idxout(1:nv)
|
||||
!
|
||||
! The input descriptor may be in any state
|
||||
!
|
||||
if (psb_is_large_desc(desc)) then
|
||||
!
|
||||
! Large descriptor: the size of the index space is such that
|
||||
! we decided not to allocate the glob_to_loc(:) map.
|
||||
!
|
||||
if (psb_is_bld_desc(desc)) then
|
||||
!
|
||||
! During the build phase of a large descriptor the indices
|
||||
! are kept in an AVL tree.
|
||||
!
|
||||
if (present(mask)) then
|
||||
|
||||
deallocate(idxout)
|
||||
do i = 1, nv
|
||||
if (mask(i)) then
|
||||
ip = idxin(i)
|
||||
if ((ip < 1 ).or.(ip>mglob)) then
|
||||
idxin(i) = -1
|
||||
cycle
|
||||
endif
|
||||
call psi_inner_cnv(ip,lip,desc%hashvmask,desc%hashv,desc%glb_lc)
|
||||
if ((lip < 0).and.associated(desc%hash)) &
|
||||
& call psb_hash_searchkey(ip,lip,desc%hash,info)
|
||||
if (owned_) then
|
||||
if (lip<=nrow) then
|
||||
idxin(i) = lip
|
||||
else
|
||||
idxin(i) = -1
|
||||
endif
|
||||
else
|
||||
idxin(i) = lip
|
||||
endif
|
||||
end if
|
||||
enddo
|
||||
else
|
||||
do i = 1, nv
|
||||
ip = idxin(i)
|
||||
if ((ip < 1 ).or.(ip>mglob)) then
|
||||
idxin(i) = -1
|
||||
cycle
|
||||
endif
|
||||
call psi_inner_cnv(ip,lip,desc%hashvmask,desc%hashv,desc%glb_lc)
|
||||
if ((lip < 0).and.associated(desc%hash)) &
|
||||
& call psb_hash_searchkey(ip,lip,desc%hash,info)
|
||||
if (owned_) then
|
||||
if (lip<=nrow) then
|
||||
idxin(i) = lip
|
||||
else
|
||||
idxin(i) = -1
|
||||
endif
|
||||
else
|
||||
idxin(i) = lip
|
||||
endif
|
||||
enddo
|
||||
end if
|
||||
else if (psb_is_asb_desc(desc)) then
|
||||
!
|
||||
! When a large descriptor is assembled the indices
|
||||
! are kept in a (hashed) list of ordered lists,
|
||||
! hence psi_inner_cnv does the hashing and binary search.
|
||||
!
|
||||
if (.not.allocated(desc%hashv)) then
|
||||
info = 4001
|
||||
call psb_errpush(info,name,a_err='Invalid hashv into inner_cnv')
|
||||
end if
|
||||
call psi_inner_cnv(nv,idxin,desc%hashvmask,desc%hashv,desc%glb_lc,mask=mask)
|
||||
end if
|
||||
|
||||
if (.not.present(mask)) then
|
||||
deallocate(mask_)
|
||||
else
|
||||
|
||||
!
|
||||
! Not a large descriptor, so we have the glob_to_loc(:) map
|
||||
! available.
|
||||
!
|
||||
if (present(mask)) then
|
||||
do i = 1, nv
|
||||
if (mask(i)) then
|
||||
ip = idxin(i)
|
||||
if ((ip < 1 ).or.(ip>mglob)) then
|
||||
info = 1133
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
lip = desc%glob_to_loc(ip)
|
||||
if (owned_) then
|
||||
if (lip<=nrow) then
|
||||
idxin(i) = lip
|
||||
else
|
||||
idxin(i) = -1
|
||||
endif
|
||||
else
|
||||
idxin(i) = lip
|
||||
endif
|
||||
end if
|
||||
enddo
|
||||
else
|
||||
do i = 1, nv
|
||||
ip = idxin(i)
|
||||
if ((ip < 1 ).or.(ip>mglob)) then
|
||||
info = 1133
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
lip = desc%glob_to_loc(ip)
|
||||
if (owned_) then
|
||||
if (lip<=nrow) then
|
||||
idxin(i) = lip
|
||||
else
|
||||
idxin(i) = -1
|
||||
endif
|
||||
else
|
||||
idxin(i) = lip
|
||||
endif
|
||||
enddo
|
||||
end if
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
@@ -204,18 +297,17 @@ subroutine psi_idx_cnv2(nv,idxin,idxout,desc,info,mask,owned)
|
||||
use psb_const_mod
|
||||
use psb_error_mod
|
||||
use psb_penv_mod
|
||||
use psb_avl_mod
|
||||
use psi_mod, psb_protect_name => psi_idx_cnv2
|
||||
implicit none
|
||||
integer, intent(in) :: nv, idxin(:)
|
||||
integer, intent(out) :: idxout(:)
|
||||
type(psb_desc_type), intent(in) :: desc
|
||||
integer, intent(out) :: info
|
||||
logical, intent(in), optional, target :: mask(:)
|
||||
logical, intent(in), optional :: mask(:)
|
||||
logical, intent(in), optional :: owned
|
||||
integer :: i,ictxt,mglob, nglob
|
||||
integer :: np, me
|
||||
integer :: nrow,ncol, ip, err_act,lip, lipf
|
||||
integer :: nrow,ncol, err_act
|
||||
integer, parameter :: relocsz=200
|
||||
character(len=20) :: name
|
||||
logical, pointer :: mask_(:)
|
||||
@@ -258,106 +350,9 @@ subroutine psi_idx_cnv2(nv,idxin,idxout,desc,info,mask,owned)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
if (present(mask)) then
|
||||
if (size(mask) < nv) then
|
||||
info = 1111
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
mask_ => mask
|
||||
else
|
||||
allocate(mask_(nv),stat=info)
|
||||
if (info /= 0) then
|
||||
info = 4000
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
mask_ = .true.
|
||||
endif
|
||||
|
||||
if (present(owned)) then
|
||||
owned_ = owned
|
||||
else
|
||||
owned_ = .false.
|
||||
endif
|
||||
|
||||
!
|
||||
! The input descriptor may be in any state
|
||||
!
|
||||
if (psb_is_large_desc(desc)) then
|
||||
!
|
||||
! Large descriptor: the size of the index space is such that
|
||||
! we decided not to allocate the glob_to_loc(:) map.
|
||||
!
|
||||
if (psb_is_bld_desc(desc)) then
|
||||
!
|
||||
! During the build phase of a large descriptor the indices
|
||||
! are kept in an AVL tree.
|
||||
!
|
||||
do i = 1, nv
|
||||
if (mask_(i)) then
|
||||
ip = idxin(i)
|
||||
if ((ip < 1 ).or.(ip>mglob)) then
|
||||
idxout(i) = -1
|
||||
cycle
|
||||
endif
|
||||
call SearchKey(desc%avltree,ip,lip,info)
|
||||
if (owned_) then
|
||||
if (lip<=nrow) then
|
||||
idxout(i) = lip
|
||||
else
|
||||
idxout(i) = -1
|
||||
endif
|
||||
else
|
||||
idxout(i) = lip
|
||||
endif
|
||||
end if
|
||||
enddo
|
||||
else if (psb_is_asb_desc(desc)) then
|
||||
!
|
||||
! When a large descriptor is assembled the indices
|
||||
! are kept in a (hashed) list of ordered lists,
|
||||
! hence psi_inner_cnv does the hashing and binary search.
|
||||
!
|
||||
|
||||
if (.not.allocated(desc%hashv)) then
|
||||
write(0,*) 'Inconsistent input to inner_cnv'
|
||||
end if
|
||||
call psi_inner_cnv(nv,idxin,idxout,psb_hash_mask,desc%hashv,desc%glb_lc)
|
||||
end if
|
||||
|
||||
else
|
||||
|
||||
!
|
||||
! Not a large descriptor, so we have the glob_to_loc(:) map
|
||||
! available.
|
||||
!
|
||||
do i = 1, nv
|
||||
if (mask_(i)) then
|
||||
ip = idxin(i)
|
||||
if ((ip < 1 ).or.(ip>mglob)) then
|
||||
info = 1133
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
lip = desc%glob_to_loc(ip)
|
||||
if (owned_) then
|
||||
if (lip<=nrow) then
|
||||
idxout(i) = lip
|
||||
else
|
||||
idxout(i) = -1
|
||||
endif
|
||||
else
|
||||
idxout(i) = lip
|
||||
endif
|
||||
end if
|
||||
enddo
|
||||
end if
|
||||
|
||||
|
||||
if (.not.present(mask)) then
|
||||
deallocate(mask_)
|
||||
end if
|
||||
idxout(1:nv) = idxin(1:nv)
|
||||
call psi_idx_cnv1(nv,idxout,desc,info,mask=mask,owned=owned)
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
@@ -427,24 +422,45 @@ subroutine psi_idx_cnvs(idxin,idxout,desc,info,mask,owned)
|
||||
integer, intent(out) :: idxout
|
||||
type(psb_desc_type), intent(in) :: desc
|
||||
integer, intent(out) :: info
|
||||
logical, intent(in), optional, target :: mask
|
||||
logical, intent(in), optional :: mask
|
||||
logical, intent(in), optional :: owned
|
||||
logical :: mask_(1)
|
||||
integer :: iout(1)
|
||||
logical :: mask_, owned_
|
||||
|
||||
if (present(mask)) then
|
||||
|
||||
if (present(mask)) then
|
||||
mask_ = mask
|
||||
else
|
||||
mask_ = .true.
|
||||
endif
|
||||
if (present(owned)) then
|
||||
owned_ = owned
|
||||
else
|
||||
owned_ = .true.
|
||||
endif
|
||||
call psi_idx_cnv(1,(/idxin/),iout,desc,info,(/mask_/),owned_)
|
||||
mask_=.true.
|
||||
end if
|
||||
iout = idxin
|
||||
call psi_idx_cnv(1,iout,desc,info,mask=mask_,owned=owned)
|
||||
idxout=iout(1)
|
||||
|
||||
return
|
||||
|
||||
end subroutine psi_idx_cnvs
|
||||
subroutine psi_idx_cnvs1(idxin,desc,info,mask,owned)
|
||||
|
||||
use psi_mod, psb_protect_name => psi_idx_cnvs1
|
||||
use psb_descriptor_type
|
||||
integer, intent(inout) :: idxin
|
||||
type(psb_desc_type), intent(in) :: desc
|
||||
integer, intent(out) :: info
|
||||
logical, intent(in), optional :: mask
|
||||
logical, intent(in), optional :: owned
|
||||
logical :: mask_(1)
|
||||
integer :: iout(1)
|
||||
|
||||
if (present(mask)) then
|
||||
mask_ = mask
|
||||
else
|
||||
mask_=.true.
|
||||
end if
|
||||
|
||||
iout(1) = idxin
|
||||
call psi_idx_cnv(1,iout,desc,info,mask=mask_,owned=owned)
|
||||
idxin = iout(1)
|
||||
|
||||
return
|
||||
|
||||
end subroutine psi_idx_cnvs1
|
||||
|
||||
@@ -60,14 +60,14 @@ subroutine psi_idx_ins_cnv1(nv,idxin,desc,info,mask)
|
||||
integer, intent(inout) :: idxin(:)
|
||||
type(psb_desc_type), intent(inout) :: desc
|
||||
integer, intent(out) :: info
|
||||
logical, intent(in), optional, target :: mask(:)
|
||||
logical, intent(in), optional :: mask(:)
|
||||
integer :: ictxt,mglob, nglob
|
||||
integer :: np, me
|
||||
integer :: nrow,ncol, err_act
|
||||
integer, allocatable :: idxout(:)
|
||||
integer :: pnt_halo, nh, ip, lip,nxt,lipf,i,k,isize
|
||||
logical :: pnt_h_ok
|
||||
integer, parameter :: relocsz=200
|
||||
character(len=20) :: name
|
||||
logical, pointer :: mask_(:)
|
||||
character(len=20) :: name,ch_err
|
||||
|
||||
info = 0
|
||||
name = 'psb_idx_ins_cnv'
|
||||
@@ -93,7 +93,7 @@ subroutine psi_idx_ins_cnv1(nv,idxin,desc,info,mask)
|
||||
goto 9999
|
||||
end if
|
||||
if (nv == 0) return
|
||||
|
||||
|
||||
|
||||
if (size(idxin) < nv) then
|
||||
info = 1111
|
||||
@@ -108,32 +108,237 @@ subroutine psi_idx_ins_cnv1(nv,idxin,desc,info,mask)
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
mask_ => mask
|
||||
else
|
||||
allocate(mask_(nv),stat=info)
|
||||
if (info /= 0) then
|
||||
info = 4000
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
if (psb_is_large_desc(desc)) then
|
||||
|
||||
if (present(mask)) then
|
||||
do i = 1, nv
|
||||
if (mask(i)) then
|
||||
ip = idxin(i)
|
||||
if ((ip < 1 ).or.(ip>mglob)) then
|
||||
idxin(i) = -1
|
||||
cycle
|
||||
endif
|
||||
nxt = ncol + 1
|
||||
|
||||
call psi_inner_cnv(ip,lip,desc%hashvmask,desc%hashv,desc%glb_lc)
|
||||
if (lip < 0) &
|
||||
& call psb_hash_searchinskey(ip,lip,nxt,desc%hash,info)
|
||||
if (info >=0) then
|
||||
if (nxt == lip) then
|
||||
ncol = nxt
|
||||
isize = size(desc%loc_to_glob)
|
||||
if (ncol > isize) then
|
||||
nh = ncol + max(nv,relocsz)
|
||||
call psb_realloc(nh,desc%loc_to_glob,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
info=1
|
||||
ch_err='psb_realloc'
|
||||
call psb_errpush(4013,name,a_err=ch_err,i_err=(/info,0,0,0,0/))
|
||||
goto 9999
|
||||
end if
|
||||
isize = nh
|
||||
endif
|
||||
desc%loc_to_glob(nxt) = ip
|
||||
endif
|
||||
info = 0
|
||||
else
|
||||
ch_err='SearchInsKeyVal'
|
||||
call psb_errpush(4013,name,a_err=ch_err,i_err=(/info,0,0,0,0/))
|
||||
goto 9999
|
||||
end if
|
||||
idxin(i) = lip
|
||||
info = 0
|
||||
else
|
||||
idxin(i) = -1
|
||||
end if
|
||||
enddo
|
||||
|
||||
else
|
||||
|
||||
do i = 1, nv
|
||||
ip = idxin(i)
|
||||
if ((ip < 1 ).or.(ip>mglob)) then
|
||||
idxin(i) = -1
|
||||
cycle
|
||||
endif
|
||||
nxt = ncol + 1
|
||||
|
||||
call psi_inner_cnv(ip,lip,desc%hashvmask,desc%hashv,desc%glb_lc)
|
||||
if (lip < 0) &
|
||||
& call psb_hash_searchinskey(ip,lip,nxt,desc%hash,info)
|
||||
if (info >=0) then
|
||||
if (nxt == lip) then
|
||||
ncol = nxt
|
||||
isize = size(desc%loc_to_glob)
|
||||
if (ncol > isize) then
|
||||
nh = ncol + max(nv,relocsz)
|
||||
call psb_realloc(nh,desc%loc_to_glob,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
info=1
|
||||
ch_err='psb_realloc'
|
||||
call psb_errpush(4013,name,a_err=ch_err,i_err=(/info,0,0,0,0/))
|
||||
goto 9999
|
||||
end if
|
||||
isize = nh
|
||||
endif
|
||||
desc%loc_to_glob(nxt) = ip
|
||||
endif
|
||||
info = 0
|
||||
else
|
||||
ch_err='SearchInsKeyVal'
|
||||
call psb_errpush(4013,name,a_err=ch_err,i_err=(/info,0,0,0,0/))
|
||||
goto 9999
|
||||
end if
|
||||
idxin(i) = lip
|
||||
info = 0
|
||||
enddo
|
||||
endif
|
||||
mask_ = .true.
|
||||
endif
|
||||
|
||||
allocate(idxout(nv),stat=info)
|
||||
if (info /= 0) then
|
||||
info = 4000
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
call psi_idx_ins_cnv2(nv,idxin,idxout,desc,info,mask_)
|
||||
idxin(1:nv) = idxout(1:nv)
|
||||
else
|
||||
|
||||
deallocate(idxout)
|
||||
if (.not.allocated(desc%halo_index)) then
|
||||
allocate(desc%halo_index(relocsz))
|
||||
desc%halo_index(:) = -1
|
||||
desc%matrix_data(psb_pnt_h_) = 1
|
||||
endif
|
||||
pnt_halo = desc%matrix_data(psb_pnt_h_)
|
||||
|
||||
pnt_h_ok = .false.
|
||||
isize = size(desc%halo_index)
|
||||
if ((1 <= pnt_halo).and.(pnt_halo <= isize)) then
|
||||
if (desc%halo_index(pnt_halo) == -1 ) then
|
||||
if (pnt_halo == 1) then
|
||||
pnt_h_ok = .true.
|
||||
else if (desc%halo_index(pnt_halo-1) /= -1 ) then
|
||||
pnt_h_ok = .true.
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
|
||||
if (.not.pnt_h_ok) then
|
||||
pnt_halo = 1
|
||||
do
|
||||
if (desc%halo_index(pnt_halo) == -1) exit
|
||||
if (pnt_halo == isize) exit
|
||||
pnt_halo = pnt_halo + 1
|
||||
end do
|
||||
if (desc%halo_index(pnt_halo) /= -1) then
|
||||
call psb_realloc(isize+relocsz,desc%halo_index,info,pad=-1)
|
||||
pnt_halo = pnt_halo + 1
|
||||
end if
|
||||
end if
|
||||
|
||||
if (present(mask)) then
|
||||
do i = 1, nv
|
||||
if (mask(i)) then
|
||||
ip = idxin(i)
|
||||
if ((ip < 1 ).or.(ip>mglob)) then
|
||||
idxin(i) = -1
|
||||
cycle
|
||||
endif
|
||||
k = desc%glob_to_loc(ip)
|
||||
if (k < -np) then
|
||||
k = k + np
|
||||
k = - k - 1
|
||||
ncol = ncol + 1
|
||||
lip = ncol
|
||||
desc%glob_to_loc(ip) = ncol
|
||||
isize = size(desc%loc_to_glob)
|
||||
if (ncol > isize) then
|
||||
nh = ncol + max(nv,relocsz)
|
||||
call psb_realloc(nh,desc%loc_to_glob,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
info=3
|
||||
ch_err='psb_realloc'
|
||||
call psb_errpush(4013,name,a_err=ch_err,i_err=(/info,0,0,0,0/))
|
||||
goto 9999
|
||||
end if
|
||||
isize = nh
|
||||
endif
|
||||
desc%loc_to_glob(ncol) = ip
|
||||
isize = size(desc%halo_index)
|
||||
if ((pnt_halo+3) > isize) then
|
||||
nh = isize + max(nv,relocsz)
|
||||
call psb_realloc(nh,desc%halo_index,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
info=4
|
||||
ch_err='psb_realloc'
|
||||
call psb_errpush(4013,name,a_err=ch_err,i_err=(/info,0,0,0,0/))
|
||||
goto 9999
|
||||
end if
|
||||
isize = nh
|
||||
endif
|
||||
desc%halo_index(pnt_halo) = k
|
||||
desc%halo_index(pnt_halo+1) = 1
|
||||
desc%halo_index(pnt_halo+2) = ncol
|
||||
pnt_halo = pnt_halo + 3
|
||||
else
|
||||
lip = k
|
||||
endif
|
||||
idxin(i) = lip
|
||||
else
|
||||
idxin(i) = -1
|
||||
end if
|
||||
enddo
|
||||
|
||||
else
|
||||
|
||||
do i = 1, nv
|
||||
ip = idxin(i)
|
||||
if ((ip < 1 ).or.(ip>mglob)) then
|
||||
idxin(i) = -1
|
||||
cycle
|
||||
endif
|
||||
k = desc%glob_to_loc(ip)
|
||||
if (k < -np) then
|
||||
k = k + np
|
||||
k = - k - 1
|
||||
ncol = ncol + 1
|
||||
lip = ncol
|
||||
desc%glob_to_loc(ip) = ncol
|
||||
isize = size(desc%loc_to_glob)
|
||||
if (ncol > isize) then
|
||||
nh = ncol + max(nv,relocsz)
|
||||
call psb_realloc(nh,desc%loc_to_glob,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
info=3
|
||||
ch_err='psb_realloc'
|
||||
call psb_errpush(4013,name,a_err=ch_err,i_err=(/info,0,0,0,0/))
|
||||
goto 9999
|
||||
end if
|
||||
isize = nh
|
||||
endif
|
||||
desc%loc_to_glob(ncol) = ip
|
||||
isize = size(desc%halo_index)
|
||||
if ((pnt_halo+3) > isize) then
|
||||
nh = isize + max(nv,relocsz)
|
||||
call psb_realloc(nh,desc%halo_index,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
info=4
|
||||
ch_err='psb_realloc'
|
||||
call psb_errpush(4013,name,a_err=ch_err,i_err=(/info,0,0,0,0/))
|
||||
goto 9999
|
||||
end if
|
||||
isize = nh
|
||||
endif
|
||||
desc%halo_index(pnt_halo) = k
|
||||
desc%halo_index(pnt_halo+1) = 1
|
||||
desc%halo_index(pnt_halo+2) = ncol
|
||||
pnt_halo = pnt_halo + 3
|
||||
else
|
||||
lip = k
|
||||
endif
|
||||
idxin(i) = lip
|
||||
enddo
|
||||
end if
|
||||
desc%matrix_data(psb_pnt_h_) = pnt_halo
|
||||
|
||||
if (.not.present(mask)) then
|
||||
deallocate(mask_)
|
||||
end if
|
||||
|
||||
desc%matrix_data(psb_n_col_) = ncol
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
@@ -204,21 +409,19 @@ subroutine psi_idx_ins_cnv2(nv,idxin,idxout,desc,info,mask)
|
||||
use psb_const_mod
|
||||
use psb_error_mod
|
||||
use psb_penv_mod
|
||||
use psb_avl_mod
|
||||
use psi_mod
|
||||
implicit none
|
||||
integer, intent(in) :: nv, idxin(:)
|
||||
integer, intent(out) :: idxout(:)
|
||||
type(psb_desc_type), intent(inout) :: desc
|
||||
integer, intent(out) :: info
|
||||
logical, intent(in), optional, target :: mask(:)
|
||||
logical, intent(in), optional :: mask(:)
|
||||
integer :: i,ictxt,k,mglob, nglob
|
||||
integer :: np, me, isize
|
||||
integer :: pnt_halo,nrow,ncol, nh, ip, err_act,lip,nxt,lipf
|
||||
logical :: pnt_h_ok
|
||||
integer, parameter :: relocsz=200
|
||||
character(len=20) :: name,ch_err
|
||||
logical, pointer :: mask_(:)
|
||||
|
||||
info = 0
|
||||
name = 'psb_idx_ins_cnv'
|
||||
@@ -257,160 +460,8 @@ subroutine psi_idx_ins_cnv2(nv,idxin,idxout,desc,info,mask)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
if (present(mask)) then
|
||||
if (size(mask) < nv) then
|
||||
info = 1111
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
mask_ => mask
|
||||
else
|
||||
allocate(mask_(nv),stat=info)
|
||||
if (info /= 0) then
|
||||
info = 4000
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
mask_ = .true.
|
||||
endif
|
||||
|
||||
|
||||
|
||||
if (psb_is_large_desc(desc)) then
|
||||
do i = 1, nv
|
||||
if (mask_(i)) then
|
||||
ip = idxin(i)
|
||||
if ((ip < 1 ).or.(ip>mglob)) then
|
||||
idxout(i) = -1
|
||||
cycle
|
||||
endif
|
||||
nxt = ncol + 1
|
||||
|
||||
call SearchInsKey(desc%avltree,ip,lip,nxt,info)
|
||||
if (info >=0) then
|
||||
if (nxt == lip) then
|
||||
ncol = nxt
|
||||
isize = size(desc%loc_to_glob)
|
||||
if (ncol > isize) then
|
||||
nh = ncol + max(nv,relocsz)
|
||||
call psb_realloc(nh,desc%loc_to_glob,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
info=1
|
||||
ch_err='psb_realloc'
|
||||
call psb_errpush(4013,name,a_err=ch_err,i_err=(/info,0,0,0,0/))
|
||||
goto 9999
|
||||
end if
|
||||
isize = nh
|
||||
endif
|
||||
desc%loc_to_glob(nxt) = ip
|
||||
endif
|
||||
info = 0
|
||||
else
|
||||
ch_err='SearchInsKeyVal'
|
||||
call psb_errpush(4013,name,a_err=ch_err,i_err=(/info,0,0,0,0/))
|
||||
goto 9999
|
||||
end if
|
||||
idxout(i) = lip
|
||||
info = 0
|
||||
else
|
||||
idxout(i) = -1
|
||||
end if
|
||||
enddo
|
||||
|
||||
else
|
||||
|
||||
if (.not.allocated(desc%halo_index)) then
|
||||
allocate(desc%halo_index(relocsz))
|
||||
desc%halo_index(:) = -1
|
||||
desc%matrix_data(psb_pnt_h_) = 1
|
||||
endif
|
||||
pnt_halo = desc%matrix_data(psb_pnt_h_)
|
||||
|
||||
pnt_h_ok = .false.
|
||||
isize = size(desc%halo_index)
|
||||
if ((1 <= pnt_halo).and.(pnt_halo <= isize)) then
|
||||
if (desc%halo_index(pnt_halo) == -1 ) then
|
||||
if (pnt_halo == 1) then
|
||||
pnt_h_ok = .true.
|
||||
else if (desc%halo_index(pnt_halo-1) /= -1 ) then
|
||||
pnt_h_ok = .true.
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
|
||||
if (.not.pnt_h_ok) then
|
||||
pnt_halo = 1
|
||||
do
|
||||
if (desc%halo_index(pnt_halo) == -1) exit
|
||||
if (pnt_halo == isize) exit
|
||||
pnt_halo = pnt_halo + 1
|
||||
end do
|
||||
if (desc%halo_index(pnt_halo) /= -1) then
|
||||
call psb_realloc(isize+relocsz,desc%halo_index,info,pad=-1)
|
||||
pnt_halo = pnt_halo + 1
|
||||
end if
|
||||
end if
|
||||
|
||||
|
||||
do i = 1, nv
|
||||
if (mask_(i)) then
|
||||
ip = idxin(i)
|
||||
if ((ip < 1 ).or.(ip>mglob)) then
|
||||
idxout(i) = -1
|
||||
cycle
|
||||
endif
|
||||
k = desc%glob_to_loc(ip)
|
||||
if (k < -np) then
|
||||
k = k + np
|
||||
k = - k - 1
|
||||
ncol = ncol + 1
|
||||
lip = ncol
|
||||
desc%glob_to_loc(ip) = ncol
|
||||
isize = size(desc%loc_to_glob)
|
||||
if (ncol > isize) then
|
||||
nh = ncol + max(nv,relocsz)
|
||||
call psb_realloc(nh,desc%loc_to_glob,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
info=3
|
||||
ch_err='psb_realloc'
|
||||
call psb_errpush(4013,name,a_err=ch_err,i_err=(/info,0,0,0,0/))
|
||||
goto 9999
|
||||
end if
|
||||
isize = nh
|
||||
endif
|
||||
desc%loc_to_glob(ncol) = ip
|
||||
isize = size(desc%halo_index)
|
||||
if ((pnt_halo+3) > isize) then
|
||||
nh = isize + max(nv,relocsz)
|
||||
call psb_realloc(nh,desc%halo_index,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
info=4
|
||||
ch_err='psb_realloc'
|
||||
call psb_errpush(4013,name,a_err=ch_err,i_err=(/info,0,0,0,0/))
|
||||
goto 9999
|
||||
end if
|
||||
isize = nh
|
||||
endif
|
||||
desc%halo_index(pnt_halo) = k
|
||||
desc%halo_index(pnt_halo+1) = 1
|
||||
desc%halo_index(pnt_halo+2) = ncol
|
||||
pnt_halo = pnt_halo + 3
|
||||
else
|
||||
lip = k
|
||||
endif
|
||||
idxout(i) = lip
|
||||
else
|
||||
idxout(i) = -1
|
||||
end if
|
||||
enddo
|
||||
desc%matrix_data(psb_pnt_h_) = pnt_halo
|
||||
end if
|
||||
|
||||
desc%matrix_data(psb_n_col_) = ncol
|
||||
|
||||
if (.not.present(mask)) then
|
||||
deallocate(mask_)
|
||||
end if
|
||||
idxout(1:nv) = idxin(1:nv)
|
||||
call psi_idx_ins_cnv(nv,idxout,desc,info,mask)
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
@@ -475,25 +526,97 @@ end subroutine psi_idx_ins_cnv2
|
||||
! info - integer. return code.
|
||||
! mask - logical, optional Only do the conversion for specific indices.
|
||||
!
|
||||
subroutine psi_idx_ins_cnvs(idxin,idxout,desc,info,mask)
|
||||
use psi_mod, psb_protect_name => psi_idx_ins_cnvs
|
||||
subroutine psi_idx_ins_cnvs2(idxin,idxout,desc,info,mask)
|
||||
use psi_mod, psb_protect_name => psi_idx_ins_cnvs2
|
||||
use psb_descriptor_type
|
||||
integer, intent(in) :: idxin
|
||||
integer, intent(out) :: idxout
|
||||
type(psb_desc_type), intent(inout) :: desc
|
||||
integer, intent(out) :: info
|
||||
logical, intent(in), optional, target :: mask
|
||||
logical, intent(in), optional :: mask
|
||||
integer :: iout(1)
|
||||
logical :: mask_
|
||||
|
||||
logical :: mask_(1)
|
||||
|
||||
if (present(mask)) then
|
||||
mask_ = mask
|
||||
else
|
||||
mask_ = .true.
|
||||
endif
|
||||
call psi_idx_ins_cnv(1,(/idxin/),iout,desc,info,(/mask_/))
|
||||
idxout=iout(1)
|
||||
end if
|
||||
|
||||
iout(1) = idxin
|
||||
call psi_idx_ins_cnv(1,iout,desc,info,mask_)
|
||||
idxout = iout(1)
|
||||
return
|
||||
|
||||
end subroutine psi_idx_ins_cnvs2
|
||||
!!$
|
||||
!!$ Parallel Sparse BLAS version 2.2
|
||||
!!$ (C) Copyright 2006/2007/2008
|
||||
!!$ Salvatore Filippone University of Rome Tor Vergata
|
||||
!!$ Alfredo Buttari University of Rome Tor Vergata
|
||||
!!$
|
||||
!!$ Redistribution and use in source and binary forms, with or without
|
||||
!!$ modification, are permitted provided that the following conditions
|
||||
!!$ are met:
|
||||
!!$ 1. Redistributions of source code must retain the above copyright
|
||||
!!$ notice, this list of conditions and the following disclaimer.
|
||||
!!$ 2. Redistributions in binary form must reproduce the above copyright
|
||||
!!$ notice, this list of conditions, and the following disclaimer in the
|
||||
!!$ documentation and/or other materials provided with the distribution.
|
||||
!!$ 3. The name of the PSBLAS group or the names of its contributors may
|
||||
!!$ not be used to endorse or promote products derived from this
|
||||
!!$ software without specific written permission.
|
||||
!!$
|
||||
!!$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
!!$ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
!!$ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
!!$ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
|
||||
!!$ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
!!$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
!!$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
!!$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
!!$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
!!$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
!!$ POSSIBILITY OF SUCH DAMAGE.
|
||||
!!$
|
||||
!!$
|
||||
!
|
||||
!
|
||||
! Subroutine: psi_idx_ins_cnvs
|
||||
! Converts an index from global to local numbering.
|
||||
! This routine is called while the descriptor is in the build state;
|
||||
! the idea is that if an index is not yet marked as local, it is a new
|
||||
! connection to another process, i.e. a new entry into the halo.
|
||||
! But we still need the mask, because we have to take out the column indices
|
||||
! corresponding to row indices we do not own (see psb_cdins for how this is used).
|
||||
!
|
||||
! Arguments:
|
||||
! idxin - integer Required index s
|
||||
! idxout - integer Output value (negative for masked entries)
|
||||
! desc - type(psb_desc_type). The communication descriptor.
|
||||
! info - integer. return code.
|
||||
! mask - logical, optional Only do the conversion for specific indices.
|
||||
!
|
||||
subroutine psi_idx_ins_cnvs1(idxin,desc,info,mask)
|
||||
use psi_mod, psb_protect_name => psi_idx_ins_cnvs1
|
||||
use psb_descriptor_type
|
||||
integer, intent(inout) :: idxin
|
||||
type(psb_desc_type), intent(inout) :: desc
|
||||
integer, intent(out) :: info
|
||||
logical, intent(in), optional :: mask
|
||||
integer :: iout(1)
|
||||
logical :: mask_(1)
|
||||
|
||||
if (present(mask)) then
|
||||
mask_ = mask
|
||||
else
|
||||
mask_ = .true.
|
||||
end if
|
||||
|
||||
iout(1) = idxin
|
||||
call psi_idx_ins_cnv(1,iout,desc,info,mask_)
|
||||
idxin = iout(1)
|
||||
|
||||
return
|
||||
|
||||
end subroutine psi_idx_ins_cnvs
|
||||
end subroutine psi_idx_ins_cnvs1
|
||||
|
||||
@@ -1,338 +0,0 @@
|
||||
!!$
|
||||
!!$ Parallel Sparse BLAS v2.0
|
||||
!!$ (C) Copyright 2006 Salvatore Filippone University of Rome Tor Vergata
|
||||
!!$ Alfredo Buttari University of Rome Tor Vergata
|
||||
!!$
|
||||
!!$ Redistribution and use in source and binary forms, with or without
|
||||
!!$ modification, are permitted provided that the following conditions
|
||||
!!$ are met:
|
||||
!!$ 1. Redistributions of source code must retain the above copyright
|
||||
!!$ notice, this list of conditions and the following disclaimer.
|
||||
!!$ 2. Redistributions in binary form must reproduce the above copyright
|
||||
!!$ notice, this list of conditions, and the following disclaimer in the
|
||||
!!$ documentation and/or other materials provided with the distribution.
|
||||
!!$ 3. The name of the PSBLAS group or the names of its contributors may
|
||||
!!$ not be used to endorse or promote products derived from this
|
||||
!!$ software without specific written permission.
|
||||
!!$
|
||||
!!$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
!!$ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
!!$ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
!!$ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
|
||||
!!$ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
!!$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
!!$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
!!$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
!!$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
!!$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
!!$ POSSIBILITY OF SUCH DAMAGE.
|
||||
!!$
|
||||
!!$
|
||||
!
|
||||
!
|
||||
! File: psi_inter_desc_index.f90
|
||||
!
|
||||
! Subroutine: psi_inter_desc_index
|
||||
! Converts a list of data exchanges from build format to assembled format.
|
||||
! See below for a description of the formats.
|
||||
!
|
||||
! Arguments:
|
||||
! desc_a - type(psb_desc_type) The descriptor; in this context only the index
|
||||
! mapping parts are used.
|
||||
! index_in(:) - integer The index list, build format
|
||||
! index_out(:) - integer, allocatable The index list, assembled format
|
||||
! glob_idx - logical Whether the input indices are in local or global
|
||||
! numbering; the global numbering is used when
|
||||
! converting the overlap exchange lists.
|
||||
! nxch - integer The number of data exchanges on the calling process
|
||||
! nsnd - integer Total send buffer size on the calling process
|
||||
! nrcv - integer Total receive buffer size on the calling process
|
||||
!
|
||||
! The format of the index lists. Copied from base/modules/psb_desc_type
|
||||
!
|
||||
! 7. The data exchange is based on lists of local indices to be exchanged; all the
|
||||
! lists have the same format, as follows:
|
||||
! the list is composed of variable dimension blocks, one for each process to
|
||||
! communicate with; each block contains indices of local elements to be
|
||||
! exchanged. We do choose the order of communications: do not change
|
||||
! the sequence of blocks unless you know what you're doing, or you'll
|
||||
! risk a deadlock. NOTE: This is the format when the state is PSB_ASB_.
|
||||
! See below for BLD. The end-of-list is marked with a -1.
|
||||
!
|
||||
! notation stored in explanation
|
||||
! --------------- --------------------------- -----------------------------------
|
||||
! process_id index_v(p+proc_id_) identifier of process with which
|
||||
! data is exchanged.
|
||||
! n_elements_recv index_v(p+n_elem_recv_) number of elements to receive.
|
||||
! elements_recv index_v(p+elem_recv_+i) indexes of local elements to
|
||||
! receive. these are stored in the
|
||||
! array from location p+elem_recv_ to
|
||||
! location p+elem_recv_+
|
||||
! index_v(p+n_elem_recv_)-1.
|
||||
! n_elements_send index_v(p+n_elem_send_) number of elements to send.
|
||||
! elements_send index_v(p+elem_send_+i) indexes of local elements to
|
||||
! send. these are stored in the
|
||||
! array from location p+elem_send_ to
|
||||
! location p+elem_send_+
|
||||
! index_v(p+n_elem_send_)-1.
|
||||
!
|
||||
! This organization is valid for both halo and overlap indices; overlap entries
|
||||
! need to be updated to ensure that a variable at a given global index
|
||||
! (assigned to multiple processes) has the same value. The way to resolve the
|
||||
! issue is to exchange the data and then sum (or average) the values. See
|
||||
! psb_ovrl subroutine.
|
||||
!
|
||||
! 8. When the descriptor is in the BLD state the INDEX vectors contains only
|
||||
! the indices to be received, organized as a sequence
|
||||
! of entries of the form (proc,N,(lx1,lx2,...,lxn)) with owning process,
|
||||
! number of indices (most often N=1), list of local indices.
|
||||
! This is because we only know the list of halo indices to be received
|
||||
! as we go about building the sparse matrix pattern, and we want the build
|
||||
! phase to be loosely synchronized. Thus we record the indices we have to ask
|
||||
! for, and at the time we call PSB_CDASB we match all the requests to figure
|
||||
! out who should be sending what to whom.
|
||||
! However this implies that we know who owns the indices; if we are in the
|
||||
! LARGE case (as described above) this is actually only true for the OVERLAP list
|
||||
! that is filled in at CDALL time, and not for the HALO; thus the HALO list
|
||||
! is rebuilt during the CDASB process (in the psi_ldsc_pre_halo subroutine).
|
||||
!
|
||||
!
|
||||
subroutine psi_inter_desc_index(desc,index_in,dep_list,&
|
||||
& length_dl,nsnd,nrcv,desc_index,isglob_in,info)
|
||||
use psb_descriptor_type
|
||||
use psb_realloc_mod
|
||||
use psb_error_mod
|
||||
use psb_const_mod
|
||||
#ifdef MPI_MOD
|
||||
use mpi
|
||||
#endif
|
||||
use psb_penv_mod
|
||||
use psi_mod, psb_protect_name => psi_inter_desc_index
|
||||
implicit none
|
||||
#ifdef MPI_H
|
||||
include 'mpif.h'
|
||||
#endif
|
||||
|
||||
! ...array parameters.....
|
||||
type(psb_desc_type) :: desc
|
||||
integer :: index_in(:),dep_list(:)
|
||||
integer,allocatable :: desc_index(:)
|
||||
integer :: length_dl,nsnd,nrcv,info
|
||||
logical :: isglob_in
|
||||
! ....local scalars...
|
||||
integer :: j,me,np,i,proc
|
||||
! ...parameters...
|
||||
integer :: ictxt
|
||||
integer, parameter :: no_comm=-1
|
||||
! ...local arrays..
|
||||
integer,allocatable :: brvindx(:),rvsz(:),&
|
||||
& bsdindx(:),sdsz(:), sndbuf(:), rcvbuf(:)
|
||||
|
||||
integer :: ihinsz,ntot,k,err_act,nidx,&
|
||||
& idxr, idxs, iszs, iszr, nesd, nerv, icomm
|
||||
|
||||
logical,parameter :: usempi=.true.
|
||||
integer :: debug_level, debug_unit
|
||||
character(len=20) :: name
|
||||
|
||||
info = 0
|
||||
name='psi_inter_desc_index'
|
||||
call psb_erractionsave(err_act)
|
||||
debug_unit = psb_get_debug_unit()
|
||||
debug_level = psb_get_debug_level()
|
||||
|
||||
ictxt = psb_cd_get_context(desc)
|
||||
icomm = psb_cd_get_mpic(desc)
|
||||
call psb_info(ictxt,me,np)
|
||||
if (np == -1) then
|
||||
info = 2010
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
if (debug_level >= psb_debug_inner_) then
|
||||
write(debug_unit,*) me,' ',trim(name),': start'
|
||||
call psb_barrier(ictxt)
|
||||
endif
|
||||
|
||||
!
|
||||
! first, find out the sizes to be exchanged.
|
||||
! note: things marked here as sndbuf/rcvbuf (for mpi) corresponds to things
|
||||
! to be received/sent (in the final psblas descriptor).
|
||||
! be careful of the inversion
|
||||
!
|
||||
allocate(sdsz(np),rvsz(np),bsdindx(np),brvindx(np),stat=info)
|
||||
if(info /= 0) then
|
||||
info=4000
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
sdsz(:) = 0
|
||||
rvsz(:) = 0
|
||||
bsdindx(:) = 0
|
||||
brvindx(:) = 0
|
||||
i = 1
|
||||
do
|
||||
if (index_in(i) == -1) exit
|
||||
proc = index_in(i)
|
||||
i = i + 1
|
||||
nerv = index_in(i)
|
||||
sdsz(proc+1) = sdsz(proc+1) + nerv
|
||||
i = i + nerv + 1
|
||||
end do
|
||||
ihinsz=i
|
||||
call mpi_alltoall(sdsz,1,mpi_integer,rvsz,1,mpi_integer,icomm,info)
|
||||
if(info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='mpi_alltoall')
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
i = 1
|
||||
idxs = 0
|
||||
idxr = 0
|
||||
do i=1, length_dl
|
||||
proc = dep_list(i)
|
||||
bsdindx(proc+1) = idxs
|
||||
idxs = idxs + sdsz(proc+1)
|
||||
brvindx(proc+1) = idxr
|
||||
idxr = idxr + rvsz(proc+1)
|
||||
end do
|
||||
iszs = sum(sdsz)
|
||||
iszr = sum(rvsz)
|
||||
nsnd = iszr
|
||||
nrcv = iszs
|
||||
|
||||
if ((iszs /= idxs).or.(iszr /= idxr)) then
|
||||
write(0,*) 'strange results?', iszs,idxs,iszr,idxr
|
||||
end if
|
||||
if (debug_level >= psb_debug_inner_) then
|
||||
write(debug_unit,*) me,' ',trim(name),': computed sizes ',iszr,iszs
|
||||
call psb_barrier(ictxt)
|
||||
endif
|
||||
|
||||
ntot = (3*(count((sdsz>0).or.(rvsz>0)))+ iszs + iszr) + 1
|
||||
if (allocated(desc_index)) then
|
||||
nidx = size(desc_index)
|
||||
else
|
||||
nidx = 0
|
||||
endif
|
||||
|
||||
if (nidx < ntot) then
|
||||
call psb_realloc(ntot,desc_index,info)
|
||||
endif
|
||||
if (info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='psb_realloc')
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
if (debug_level >= psb_debug_inner_) then
|
||||
write(debug_unit,*) me,' ',trim(name),': computed allocated workspace ',iszr,iszs
|
||||
call psb_barrier(ictxt)
|
||||
endif
|
||||
allocate(sndbuf(iszs),rcvbuf(iszr),stat=info)
|
||||
if(info /= 0) then
|
||||
info=4000
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
!
|
||||
! Second build the lists of requests
|
||||
!
|
||||
i = 1
|
||||
do
|
||||
if (i > ihinsz) then
|
||||
write(0,*) me,' did not find index_in end??? ',i,ihinsz
|
||||
exit
|
||||
end if
|
||||
if (index_in(i) == -1) exit
|
||||
proc = index_in(i)
|
||||
i = i + 1
|
||||
nerv = index_in(i)
|
||||
!
|
||||
! note that here bsdinx is zero-based, hence the following loop
|
||||
!
|
||||
if (isglob_in) then
|
||||
do j=1, nerv
|
||||
sndbuf(bsdindx(proc+1)+j) = (index_in(i+j))
|
||||
end do
|
||||
else
|
||||
|
||||
do j=1, nerv
|
||||
sndbuf(bsdindx(proc+1)+j) = desc%loc_to_glob(index_in(i+j))
|
||||
end do
|
||||
endif
|
||||
bsdindx(proc+1) = bsdindx(proc+1) + nerv
|
||||
i = i + nerv + 1
|
||||
end do
|
||||
|
||||
if (debug_level >= psb_debug_inner_) then
|
||||
write(debug_unit,*) me,' ',trim(name),': prepared send buffer '
|
||||
call psb_barrier(ictxt)
|
||||
endif
|
||||
!
|
||||
! now have to regenerate bsdindx
|
||||
!
|
||||
idxs = 0
|
||||
idxr = 0
|
||||
do i=1, length_dl
|
||||
proc = dep_list(i)
|
||||
bsdindx(proc+1) = idxs
|
||||
idxs = idxs + sdsz(proc+1)
|
||||
brvindx(proc+1) = idxr
|
||||
idxr = idxr + rvsz(proc+1)
|
||||
end do
|
||||
|
||||
call mpi_alltoallv(sndbuf,sdsz,bsdindx,mpi_integer,&
|
||||
& rcvbuf,rvsz,brvindx,mpi_integer,icomm,info)
|
||||
if(info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='mpi_alltoallv')
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
!
|
||||
! at this point we can finally build the output desc_index. beware
|
||||
! of snd/rcv inversion.
|
||||
!
|
||||
i = 1
|
||||
do k = 1, length_dl
|
||||
proc = dep_list(k)
|
||||
desc_index(i) = proc
|
||||
i = i + 1
|
||||
nerv = sdsz(proc+1)
|
||||
desc_index(i) = nerv
|
||||
call psi_idx_cnv(nerv,sndbuf(bsdindx(proc+1)+1:bsdindx(proc+1)+nerv),&
|
||||
& desc_index(i+1:i+nerv),desc,info)
|
||||
i = i + nerv + 1
|
||||
nesd = rvsz(proc+1)
|
||||
desc_index(i) = nesd
|
||||
call psi_idx_cnv(nesd,rcvbuf(brvindx(proc+1)+1:brvindx(proc+1)+nesd),&
|
||||
& desc_index(i+1:i+nesd),desc,info)
|
||||
i = i + nesd + 1
|
||||
end do
|
||||
desc_index(i) = - 1
|
||||
|
||||
deallocate(sdsz,rvsz,bsdindx,brvindx,sndbuf,rcvbuf,stat=info)
|
||||
if (info /= 0) then
|
||||
info=4000
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
if (debug_level >= psb_debug_inner_) then
|
||||
write(debug_unit,*) me,' ',trim(name),': done'
|
||||
call psb_barrier(ictxt)
|
||||
endif
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 continue
|
||||
call psb_erractionrestore(err_act)
|
||||
if (err_act == psb_act_abort_) then
|
||||
call psb_error(ictxt)
|
||||
return
|
||||
end if
|
||||
return
|
||||
end subroutine psi_inter_desc_index
|
||||
@@ -93,6 +93,16 @@ subroutine psi_ldsc_pre_halo(desc,ext_hv,info)
|
||||
call psb_errpush(info,name,a_err=ch_err)
|
||||
goto 9999
|
||||
end if
|
||||
! We no longer need the desc%hash structure.
|
||||
if (associated(desc%hash)) then
|
||||
deallocate(desc%hash,stat=info)
|
||||
if (info /= 0) then
|
||||
ch_err='psi_bld_tmphalo'
|
||||
info = 4010
|
||||
call psb_errpush(info,name,a_err=ch_err)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
if (.not.ext_hv) then
|
||||
call psi_bld_tmphalo(desc,info)
|
||||
if (info /= 0) then
|
||||
|
||||
@@ -2,12 +2,11 @@ include ../../Make.inc
|
||||
|
||||
MODULES = psb_realloc_mod.o psb_string_mod.o psb_spmat_type.o \
|
||||
psb_desc_type.o psb_spsb_mod.o psb_sort_mod.o\
|
||||
psb_serial_mod.o psb_tools_mod.o psb_blacs_mod.o psb_avl_mod.o\
|
||||
psb_serial_mod.o psb_tools_mod.o psb_blacs_mod.o \
|
||||
psb_error_mod.o psb_const_mod.o psb_inter_desc_type.o \
|
||||
psb_comm_mod.o psb_psblas_mod.o psi_serial_mod.o psi_mod.o \
|
||||
psb_check_mod.o psb_gps_mod.o psb_inter_desc_mod.o
|
||||
psb_check_mod.o psb_gps_mod.o psb_inter_desc_mod.o psb_hash_mod.o
|
||||
|
||||
# psb_methd_mod.o psb_prec_type.o psb_prec_mod.o blacs_env.o
|
||||
|
||||
LIBMOD=psb_base_mod$(.mod)
|
||||
MPFOBJS=psb_penv_mod.o
|
||||
@@ -30,7 +29,7 @@ psb_penv_mod.o: psb_const_mod.o psb_error_mod.o psb_realloc_mod.o psb_blacs_mod.
|
||||
psb_blacs_mod.o: psb_const_mod.o
|
||||
psi_serial_mod.o: psb_const_mod.o psb_realloc_mod.o
|
||||
psi_mod.o: psb_penv_mod.o psb_error_mod.o psb_desc_type.o psb_const_mod.o psi_serial_mod.o
|
||||
psb_desc_type.o: psb_const_mod.o psb_error_mod.o psb_penv_mod.o psb_realloc_mod.o psb_avl_mod.o
|
||||
psb_desc_type.o: psb_const_mod.o psb_error_mod.o psb_penv_mod.o psb_realloc_mod.o psb_hash_mod.o
|
||||
psb_inter_desc_type.o: psb_desc_type.o psb_spmat_type.o psb_error_mod.o psb_serial_mod.o psb_comm_mod.o
|
||||
psb_inter_desc_mod.o: psb_inter_desc_type.o
|
||||
psb_check_mod.o: psb_desc_type.o
|
||||
@@ -39,6 +38,7 @@ psb_sort_mod.o: psb_error_mod.o psb_realloc_mod.o psb_const_mod.o
|
||||
psb_methd_mod.o: psb_serial_mod.o psb_desc_type.o psb_prec_type.o
|
||||
psb_tools_mod.o: psb_spmat_type.o psb_desc_type.o psi_mod.o psb_gps_mod.o psb_inter_desc_mod.o
|
||||
psb_gps_mod.o: psb_realloc_mod.o
|
||||
psb_hash_mod.o: psb_const_mod.o psb_realloc_mod.o
|
||||
|
||||
psb_base_mod.o: $(MODULES)
|
||||
|
||||
|
||||
@@ -1,617 +0,0 @@
|
||||
!!$
|
||||
!!$ Parallel Sparse BLAS v2.0
|
||||
!!$ (C) Copyright 2006 Salvatore Filippone University of Rome Tor Vergata
|
||||
!!$ Alfredo Buttari University of Rome Tor Vergata
|
||||
!!$
|
||||
!!$ Redistribution and use in source and binary forms, with or without
|
||||
!!$ modification, are permitted provided that the following conditions
|
||||
!!$ are met:
|
||||
!!$ 1. Redistributions of source code must retain the above copyright
|
||||
!!$ notice, this list of conditions and the following disclaimer.
|
||||
!!$ 2. Redistributions in binary form must reproduce the above copyright
|
||||
!!$ notice, this list of conditions, and the following disclaimer in the
|
||||
!!$ documentation and/or other materials provided with the distribution.
|
||||
!!$ 3. The name of the PSBLAS group or the names of its contributors may
|
||||
!!$ not be used to endorse or promote products derived from this
|
||||
!!$ software without specific written permission.
|
||||
!!$
|
||||
!!$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
!!$ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
!!$ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
!!$ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
|
||||
!!$ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
!!$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
!!$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
!!$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
!!$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
!!$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
!!$ POSSIBILITY OF SUCH DAMAGE.
|
||||
!!$
|
||||
!!$
|
||||
|
||||
module psb_item_mod
|
||||
type psb_item_int2
|
||||
integer :: key, val
|
||||
end type psb_item_int2
|
||||
interface psb_sizeof
|
||||
module procedure psb_item_int2_size
|
||||
end interface
|
||||
contains
|
||||
function psb_item_int2_size(node)
|
||||
use psb_const_mod
|
||||
type(psb_item_int2) :: node
|
||||
psb_item_int2_size = psb_sizeof_int * 2
|
||||
end function psb_item_int2_size
|
||||
|
||||
subroutine psb_print_item_key_val(iout,item)
|
||||
integer, intent(in) :: iout
|
||||
type(psb_item_int2), intent(in) :: item
|
||||
write(iout,*) 'Value: ',item%key,item%val
|
||||
end subroutine psb_print_item_key_val
|
||||
end module psb_item_mod
|
||||
|
||||
module psb_avl_mod
|
||||
|
||||
use psb_item_mod
|
||||
|
||||
integer, parameter :: LeftHigh = -1, EqualHeight=0, RightHigh=1
|
||||
integer, parameter :: AVLTreeDuplicate = -123, AVLTreeOK=0, &
|
||||
& AVLTreeOutOfMemory=-512, AVLTreeFatalError=-1024
|
||||
integer :: level,outlev
|
||||
integer, parameter :: poolsize = 1024
|
||||
|
||||
type psb_treenode_int2
|
||||
type(psb_item_int2) :: item
|
||||
type(psb_treenode_int2), pointer :: left=>null(), right=>null()
|
||||
integer :: balance
|
||||
end type psb_treenode_int2
|
||||
|
||||
type psb_treevect_int2
|
||||
type(psb_treenode_int2) :: pool(poolsize)
|
||||
integer :: avail
|
||||
type(psb_treevect_int2), pointer :: next=>null(), prev=>null()
|
||||
end type psb_treevect_int2
|
||||
|
||||
type psb_tree_int2
|
||||
type(psb_treevect_int2), pointer :: head=>null(), current=>null()
|
||||
type(psb_treenode_int2), pointer :: root=>null()
|
||||
integer :: nnodes
|
||||
end type psb_tree_int2
|
||||
|
||||
interface psb_sizeof
|
||||
module procedure psb_Sizeof_Tree_int2, psb_sizeof_node_int2
|
||||
end interface
|
||||
|
||||
interface InitSearchTree
|
||||
module procedure InitSearchTree_int2
|
||||
end interface
|
||||
|
||||
interface FreeSearchTree
|
||||
module procedure FreeSearchTree_int2
|
||||
end interface
|
||||
|
||||
interface SearchKey
|
||||
module procedure SearchKey_int2
|
||||
end interface
|
||||
|
||||
interface SearchInsKey
|
||||
module procedure SearchInsKey_int2
|
||||
end interface
|
||||
|
||||
interface GetAVLTree
|
||||
module procedure GetAVLTree_int2
|
||||
end interface
|
||||
|
||||
interface CloneSearchTree
|
||||
module procedure CloneSearchTree_int2
|
||||
end interface
|
||||
|
||||
interface CloneAVLTree
|
||||
module procedure CloneAVLTree_int2
|
||||
end interface
|
||||
|
||||
interface GetAVLNode
|
||||
module procedure GetAVLNode_int2
|
||||
end interface
|
||||
interface UnGetAVLNode
|
||||
module procedure UnGetAVLNode_int2
|
||||
end interface
|
||||
|
||||
interface VisitAVLTree
|
||||
module procedure VisitAVLTree_int2, VisitAVLTreeNode_int2
|
||||
end interface
|
||||
|
||||
interface VisitAVLTreeLev
|
||||
module procedure VisitAVLTreeLev_int2, VisitAVLTreeNodeLev_int2
|
||||
end interface
|
||||
|
||||
interface AVLTreeLeftBalance
|
||||
module procedure AVLTreeLeftBalance_int2
|
||||
end interface
|
||||
|
||||
interface AVLTreeRightBalance
|
||||
module procedure AVLTreeRightBalance_int2
|
||||
end interface
|
||||
|
||||
interface AVLTreeRotateLeft
|
||||
module procedure AVLTreeRotateLeft_int2
|
||||
end interface
|
||||
|
||||
interface AVLTreeRotateRight
|
||||
module procedure AVLTreeRotateRight_int2
|
||||
end interface
|
||||
|
||||
interface AVLSearchKey
|
||||
module procedure AVLSearchKey_int2
|
||||
end interface
|
||||
|
||||
interface AVLSearchInsKey
|
||||
module procedure AVLSearchInsKey_int2
|
||||
end interface
|
||||
|
||||
interface AVLSearchInsNode
|
||||
module procedure AVLSearchInsNode_int2
|
||||
end interface
|
||||
|
||||
contains
|
||||
|
||||
subroutine InitSearchTree_int2(tree, info)
|
||||
type(psb_tree_int2), pointer :: tree
|
||||
integer :: info
|
||||
|
||||
if (associated(tree)) then
|
||||
call FreeSearchTree(tree,info)
|
||||
end if
|
||||
call GetAVLTree(tree,info)
|
||||
|
||||
end subroutine InitSearchTree_int2
|
||||
|
||||
subroutine CloneSearchTree_int2(treein, treeout)
|
||||
type(psb_tree_int2), pointer :: treein,treeout
|
||||
integer :: info
|
||||
if (.not.associated(treein)) then
|
||||
treeout => null()
|
||||
return
|
||||
endif
|
||||
call GetAVLTree(treeout,info)
|
||||
call CloneAVLTree(treein%root,treeout)
|
||||
|
||||
end subroutine CloneSearchTree_int2
|
||||
|
||||
recursive subroutine CloneAVLTree_int2(root, tree)
|
||||
type(psb_treenode_int2), pointer :: root
|
||||
type(psb_tree_int2), pointer :: tree
|
||||
integer :: info, key,val,next
|
||||
if (.not.associated(root)) return
|
||||
key = root%item%key
|
||||
next = root%item%val
|
||||
call SearchInsKey(tree,key,val,next,info)
|
||||
call CloneAVLTree(root%left,tree)
|
||||
call CloneAVLTree(root%right,tree)
|
||||
end subroutine CloneAVLTree_int2
|
||||
|
||||
subroutine FreeSearchTree_int2(tree, info)
|
||||
type(psb_tree_int2), pointer :: tree
|
||||
integer :: info
|
||||
type(psb_treevect_int2), pointer :: current,next
|
||||
|
||||
if (.not.associated(tree)) return
|
||||
current => tree%head
|
||||
do
|
||||
if (.not.associated(current)) exit
|
||||
next => current%next
|
||||
deallocate(current,stat=info)
|
||||
if (info /= 0) then
|
||||
info = AVLTreeFatalError
|
||||
return
|
||||
end if
|
||||
current => next
|
||||
end do
|
||||
deallocate(tree,stat=info)
|
||||
if (info /= 0) then
|
||||
info = AVLTreeFatalError
|
||||
return
|
||||
end if
|
||||
|
||||
end subroutine FreeSearchTree_int2
|
||||
|
||||
function psb_Sizeof_Tree_int2(tree)
|
||||
use psb_const_mod
|
||||
type(psb_tree_int2), pointer :: tree
|
||||
integer :: psb_Sizeof_Tree_int2
|
||||
integer :: val
|
||||
type(psb_treevect_int2), pointer :: current,next
|
||||
|
||||
val = 0
|
||||
if (associated(tree)) then
|
||||
current => tree%head
|
||||
do
|
||||
if (.not.associated(current)) exit
|
||||
val = val + 3*psb_sizeof_int + poolsize*psb_sizeof(current%pool(1))
|
||||
current => current%next
|
||||
end do
|
||||
end if
|
||||
psb_Sizeof_Tree_int2 = val
|
||||
end function psb_Sizeof_Tree_int2
|
||||
|
||||
function psb_sizeof_node_int2(node)
|
||||
|
||||
use psb_const_mod
|
||||
type(psb_treenode_int2) :: node
|
||||
integer :: psb_sizeof_node_int2
|
||||
integer :: val
|
||||
|
||||
|
||||
psb_sizeof_node_int2 = 3*psb_sizeof_int + psb_sizeof(node%item)
|
||||
|
||||
end function psb_sizeof_node_int2
|
||||
|
||||
subroutine SearchKey_int2(tree,key,val,info)
|
||||
type(psb_tree_int2), target :: tree
|
||||
integer :: key,val,info
|
||||
type(psb_item_int2), pointer :: retval
|
||||
info = 0
|
||||
call AVLSearchKey(tree,key,retval,info)
|
||||
if (associated(retval)) then
|
||||
val = retval%val
|
||||
else
|
||||
val = -1
|
||||
end if
|
||||
end subroutine SearchKey_int2
|
||||
|
||||
subroutine SearchInsKey_int2(tree,key,val, nextval,info)
|
||||
type(psb_tree_int2), target :: tree
|
||||
integer :: key,val,nextval,info
|
||||
|
||||
call AVLSearchInsKey(tree,key,val,nextval,info)
|
||||
|
||||
end subroutine SearchInsKey_int2
|
||||
|
||||
subroutine GetAVLTree_int2(tree, info)
|
||||
type(psb_tree_int2), pointer :: tree
|
||||
integer :: info
|
||||
|
||||
allocate(tree, stat=info)
|
||||
if (info == 0) allocate(tree%head,stat=info)
|
||||
if (info == 0) then
|
||||
tree%current => tree%head
|
||||
tree%head%avail = 0
|
||||
tree%nnodes=0
|
||||
end if
|
||||
|
||||
if (info /= 0) then
|
||||
write(0,*) 'Failed allocation 1 GetAVLTree '
|
||||
info = AVLTreeOutOfMemory
|
||||
|
||||
return
|
||||
end if
|
||||
|
||||
end subroutine GetAVLTree_int2
|
||||
|
||||
subroutine VisitAVLTree_int2(tree, info,iout)
|
||||
type(psb_tree_int2), pointer :: tree
|
||||
integer :: info
|
||||
integer, optional :: iout
|
||||
|
||||
info = 0
|
||||
if (.not.associated(tree)) return
|
||||
call VisitAVLTree(tree%root,iout)
|
||||
|
||||
end subroutine VisitAVLTree_int2
|
||||
|
||||
recursive subroutine VisitAVLTreeNode_int2(root,iout)
|
||||
type(psb_treenode_int2), pointer :: root
|
||||
integer, optional :: iout
|
||||
integer :: info
|
||||
|
||||
if (.not.associated(root)) return
|
||||
call VisitAVLTree(root%left,iout)
|
||||
if (present(iout)) then
|
||||
call psb_print_item_key_val(iout,root%item)
|
||||
else
|
||||
call psb_print_item_key_val(6,root%item)
|
||||
end if
|
||||
call VisitAVLTree(root%right,iout)
|
||||
end subroutine VisitAVLTreeNode_int2
|
||||
|
||||
subroutine VisitAVLTreeLev_int2(tree, info)
|
||||
type(psb_tree_int2), pointer :: tree
|
||||
integer :: info
|
||||
|
||||
if (.not.associated(tree)) return
|
||||
do outlev = 0, 3
|
||||
write(6,*) 'Tree level : ',outlev
|
||||
call VisitAVLTreeLev(tree%root,0)
|
||||
end do
|
||||
|
||||
end subroutine VisitAVLTreeLev_int2
|
||||
|
||||
recursive subroutine VisitAVLTreeNodeLev_int2(root,level)
|
||||
type(psb_treenode_int2), pointer :: root
|
||||
integer :: info,level
|
||||
|
||||
if (.not.associated(root)) return
|
||||
call VisitAVLTreeLev(root%left,level+1)
|
||||
if (level == outlev) call psb_print_item_key_val(6,root%item)
|
||||
call VisitAVLTreeLev(root%right,level+1)
|
||||
end subroutine VisitAVLTreeNodeLev_int2
|
||||
|
||||
|
||||
function GetAVLNode_int2(tree, info)
|
||||
type(psb_tree_int2), target :: tree
|
||||
type(psb_treenode_int2), pointer :: GetAVLNode_int2
|
||||
integer :: info
|
||||
type(psb_treevect_int2), pointer :: current, temp
|
||||
|
||||
GetAVLNode_int2 => null()
|
||||
|
||||
if (.not.associated(tree%current)) then
|
||||
allocate(tree%head,stat=info)
|
||||
if (info /= 0) then
|
||||
info = AVLTreeOutOfMemory
|
||||
return
|
||||
end if
|
||||
tree%current => tree%head
|
||||
tree%current%avail = 0
|
||||
end if
|
||||
current => tree%current
|
||||
do
|
||||
if (current%avail < poolsize) exit
|
||||
if (.not.(associated(current%next))) then
|
||||
allocate(temp,stat=info)
|
||||
if (info /= 0) then
|
||||
info = AVLTreeOutOfMemory
|
||||
return
|
||||
end if
|
||||
temp%avail = 0
|
||||
temp%prev => current
|
||||
current%next => temp
|
||||
end if
|
||||
current => current%next
|
||||
end do
|
||||
tree%current => current
|
||||
current%avail = current%avail + 1
|
||||
GetAVLNode_int2 => current%pool(current%avail)
|
||||
|
||||
end function GetAVLNode_int2
|
||||
|
||||
subroutine UnGetAVLNode_int2(tree, info)
|
||||
type(psb_tree_int2), target :: tree
|
||||
integer :: info
|
||||
|
||||
|
||||
if (.not.associated(tree%current)) then
|
||||
return
|
||||
end if
|
||||
if (tree%current%avail > 0) &
|
||||
& tree%current%avail = tree%current%avail - 1
|
||||
return
|
||||
end subroutine UnGetAVLNode_int2
|
||||
|
||||
subroutine AVLSearchKey_int2(tree,key,retval,info)
|
||||
type(psb_tree_int2), target :: tree
|
||||
integer :: key,info
|
||||
type(psb_item_int2), pointer :: retval
|
||||
type(psb_treenode_int2), pointer :: root
|
||||
|
||||
retval => null()
|
||||
root => tree%root
|
||||
do
|
||||
if (.not.associated(root)) exit
|
||||
if (key < root%item%key) then
|
||||
root => root%left
|
||||
else if (key == root%item%key) then
|
||||
retval => root%item
|
||||
exit
|
||||
else if (key > root%item%key) then
|
||||
root => root%right
|
||||
end if
|
||||
end do
|
||||
|
||||
end subroutine AVLSearchKey_int2
|
||||
|
||||
subroutine AVLSearchInsKey_int2(tree,key,val,nextval,info)
|
||||
type(psb_tree_int2), target :: tree
|
||||
integer :: key,val,nextval,info
|
||||
type(psb_treenode_int2), pointer :: itemp
|
||||
logical :: taller
|
||||
|
||||
itemp => GetAVLNode(tree,info)
|
||||
if (info /=0) then
|
||||
return
|
||||
end if
|
||||
if (.not.associated(itemp)) then
|
||||
info = -5
|
||||
return
|
||||
endif
|
||||
itemp%item%key = key
|
||||
itemp%item%val = nextval
|
||||
itemp%left => null()
|
||||
itemp%right => null()
|
||||
|
||||
call AVLSearchInsNode(tree%root,itemp,taller,info)
|
||||
val = itemp%item%val
|
||||
if (info == AVLTreeDuplicate) then
|
||||
call UnGetAVLNode(tree,info)
|
||||
!!$ write(0,*) 'From searchInsNode ',key,val,nextval
|
||||
info = 0
|
||||
return
|
||||
else if (info == AVLTreeOK) then
|
||||
tree%nnodes = tree%nnodes + 1
|
||||
info = 0
|
||||
return
|
||||
else
|
||||
write(0,*) 'Error from inner SearchInsNode '
|
||||
endif
|
||||
|
||||
end subroutine AVLSearchInsKey_int2
|
||||
|
||||
|
||||
recursive subroutine AVLSearchInsNode_int2(root,node,taller,info)
|
||||
type(psb_treenode_int2), pointer :: root, node
|
||||
integer :: info
|
||||
logical :: taller
|
||||
|
||||
info = AVLTreeOK
|
||||
taller = .false.
|
||||
if (.not.associated(root)) then
|
||||
root => node
|
||||
node%balance = EqualHeight
|
||||
node%left => null()
|
||||
node%right => null()
|
||||
taller = .true.
|
||||
else if (node%item%key == root%item%key) then
|
||||
!!$ write(0,*) 'SearchInsNode : found key',node%item%key,node%item%val,&
|
||||
!!$ &root%item%key,root%item%val
|
||||
info = AVLTreeDuplicate
|
||||
node%item%val = root%item%val
|
||||
return
|
||||
|
||||
else if (node%item%key < root%item%key) then
|
||||
|
||||
call AVLSearchInsNode(root%left,node,taller,info)
|
||||
if (info == AVLTreeDuplicate) return
|
||||
if (info == AVLTreeFatalError) return
|
||||
if (taller) then
|
||||
select case(root%balance)
|
||||
case(LeftHigh)
|
||||
call AVLTreeLeftBalance(root,taller)
|
||||
case(EqualHeight)
|
||||
root%balance = LeftHigh
|
||||
case(RightHigh)
|
||||
root%balance = EqualHeight
|
||||
taller = .false.
|
||||
case default
|
||||
info = AVLTreeFatalError
|
||||
end select
|
||||
end if
|
||||
else if (node%item%key > root%item%key) then
|
||||
call AVLSearchInsNode(root%right,node,taller,info)
|
||||
if (info == AVLTreeDuplicate) return
|
||||
if (info == AVLTreeFatalError) return
|
||||
if (taller) then
|
||||
select case(root%balance)
|
||||
case(LeftHigh)
|
||||
root%balance = EqualHeight
|
||||
taller = .false.
|
||||
case(EqualHeight)
|
||||
root%balance = RightHigh
|
||||
case(RightHigh)
|
||||
call AVLTreeRightBalance(root,taller)
|
||||
case default
|
||||
info = AVLTreeFatalError
|
||||
end select
|
||||
end if
|
||||
end if
|
||||
|
||||
end subroutine AVLSearchInsNode_int2
|
||||
|
||||
|
||||
|
||||
recursive subroutine AVLTreeLeftBalance_int2(root,taller)
|
||||
type(psb_treenode_int2), pointer :: root
|
||||
logical :: taller
|
||||
|
||||
type(psb_treenode_int2), pointer :: rs, ls
|
||||
|
||||
ls => root%left
|
||||
select case (ls%balance)
|
||||
case(LeftHigh)
|
||||
root%balance = EqualHeight
|
||||
ls%balance = EqualHeight
|
||||
call AVLTreeRotateRight(root)
|
||||
taller = .false.
|
||||
case(EqualHeight)
|
||||
write(0,*) 'Warning: balancing and already balanced left tree? '
|
||||
case(RightHigh)
|
||||
rs => ls%right
|
||||
select case(rs%balance)
|
||||
case(LeftHigh)
|
||||
root%balance = RightHigh
|
||||
ls%balance = EqualHeight
|
||||
case(EqualHeight)
|
||||
root%balance = EqualHeight
|
||||
ls%balance = EqualHeight
|
||||
case(RightHigh)
|
||||
root%balance = EqualHeight
|
||||
ls%balance = LeftHigh
|
||||
end select
|
||||
rs%balance = EqualHeight
|
||||
call AVLTreeRotateLeft(root%left)
|
||||
call AVLTreeRotateRight(root)
|
||||
taller = .false.
|
||||
end select
|
||||
|
||||
end subroutine AVLTreeLeftBalance_int2
|
||||
|
||||
|
||||
recursive subroutine AVLTreeRightBalance_int2(root,taller)
|
||||
type(psb_treenode_int2), pointer :: root
|
||||
logical :: taller
|
||||
type(psb_treenode_int2), pointer :: rs, ls
|
||||
|
||||
rs => root%right
|
||||
select case (rs%balance)
|
||||
case(RightHigh)
|
||||
root%balance = EqualHeight
|
||||
rs%balance = EqualHeight
|
||||
call AVLTreeRotateLeft(root)
|
||||
taller = .false.
|
||||
case(EqualHeight)
|
||||
write(0,*) 'Warning: balancing and already balanced right tree? '
|
||||
case(LeftHigh)
|
||||
ls => rs%left
|
||||
select case(ls%balance)
|
||||
case(RightHigh)
|
||||
root%balance = LeftHigh
|
||||
rs%balance = EqualHeight
|
||||
case(EqualHeight)
|
||||
root%balance = EqualHeight
|
||||
rs%balance = EqualHeight
|
||||
case(LeftHigh)
|
||||
root%balance = EqualHeight
|
||||
rs%balance = RightHigh
|
||||
end select
|
||||
ls%balance = EqualHeight
|
||||
call AVLTreeRotateRight(root%right)
|
||||
call AVLTreeRotateLeft(root)
|
||||
taller = .false.
|
||||
end select
|
||||
end subroutine AVLTreeRightBalance_int2
|
||||
|
||||
|
||||
|
||||
subroutine AVLTreeRotateLeft_int2(root)
|
||||
type(psb_treenode_int2), pointer :: root
|
||||
type(psb_treenode_int2), pointer :: temp
|
||||
if (.not.associated(root)) then
|
||||
return
|
||||
endif
|
||||
if (.not.associated(root%right)) then
|
||||
return
|
||||
endif
|
||||
temp => root%right
|
||||
root%right => temp%left
|
||||
temp%left => root
|
||||
root => temp
|
||||
|
||||
end subroutine AVLTreeRotateLeft_int2
|
||||
|
||||
subroutine AVLTreeRotateRight_int2(root)
|
||||
type(psb_treenode_int2), pointer :: root
|
||||
type(psb_treenode_int2), pointer :: temp
|
||||
if (.not.associated(root)) then
|
||||
return
|
||||
endif
|
||||
if (.not.associated(root%left)) then
|
||||
return
|
||||
endif
|
||||
temp => root%left
|
||||
root%left => temp%right
|
||||
temp%right => root
|
||||
root => temp
|
||||
|
||||
end subroutine AVLTreeRotateRight_int2
|
||||
|
||||
|
||||
end module psb_avl_mod
|
||||
@@ -31,13 +31,17 @@
|
||||
!!$
|
||||
|
||||
module psb_const_mod
|
||||
! This should be integer(8), and normally different from default integer.
|
||||
integer, parameter :: longndig=12
|
||||
integer, parameter :: psb_long_int_k_ = selected_int_kind(longndig)
|
||||
!
|
||||
! This must be the kind parameter corresponding to MPI_DOUBLE_PRECISION
|
||||
! These must be the kind parameter corresponding to MPI_DOUBLE_PRECISION
|
||||
! and MPI_REAL
|
||||
!
|
||||
integer, parameter :: psb_dpk_ = kind(1.d0)
|
||||
integer, parameter :: psb_spk_ = kind(1.e0)
|
||||
integer :: psb_sizeof_dp, psb_sizeof_int, psb_sizeof_sp
|
||||
integer, parameter :: psb_dpk_ = kind(1.d0)
|
||||
integer, parameter :: psb_spk_ = kind(1.e0)
|
||||
integer :: psb_sizeof_dp, psb_sizeof_sp
|
||||
integer :: psb_sizeof_int, psb_sizeof_long_int
|
||||
|
||||
!
|
||||
! Handy & miscellaneous constants
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
module psb_descriptor_type
|
||||
use psb_const_mod
|
||||
use psb_avl_mod
|
||||
use psb_hash_mod
|
||||
|
||||
implicit none
|
||||
|
||||
@@ -102,9 +102,10 @@ module psb_descriptor_type
|
||||
!
|
||||
! Constants for hashing into desc%hashv(:) and desc%glb_lc(:,:)
|
||||
!
|
||||
integer, parameter :: psb_hash_bits=14
|
||||
integer, parameter :: psb_hash_bits=16
|
||||
integer, parameter :: psb_max_hash_bits=22
|
||||
integer, parameter :: psb_hash_size=2**psb_hash_bits, psb_hash_mask=psb_hash_size-1
|
||||
integer, parameter :: psb_default_large_threshold=512*1024 ! to be reviewed
|
||||
integer, parameter :: psb_default_large_threshold=1*1024*1024
|
||||
integer, parameter :: psb_hpnt_nentries_=7
|
||||
|
||||
!
|
||||
@@ -136,6 +137,8 @@ module psb_descriptor_type
|
||||
!| integer, allocatable :: hashv(:), glb_lc(:,:)
|
||||
!| integer, allocatable :: lprm(:)
|
||||
!| integer, allocatable :: idx_space(:)
|
||||
!| type(psb_hash_type), pointer :: hash => null()
|
||||
!| type(psb_desc_type), pointer :: base_desc => null()
|
||||
!| end type psb_desc_type
|
||||
!
|
||||
!
|
||||
@@ -193,17 +196,23 @@ module psb_descriptor_type
|
||||
! will thus be N_COL + N_GLOB
|
||||
! ii. If the global index space is very large (larger than the threshold value
|
||||
! which may be set by the user), then it is not advisable to have such an
|
||||
! array. In this case we only record the global indices that do have a
|
||||
! array.
|
||||
! In this case we only record the global indices that do have a
|
||||
! local counterpart, so that the local storage will be proportional to
|
||||
! N_COL. During the build phase we keep the known global indices in an
|
||||
! AVL tree data structure whose pointer is stored in avltree, so that we
|
||||
! can do both search and insertions in log time. At assembly time, we move
|
||||
! the information into hashv(:) and glb_lc(:,:). The idea is that
|
||||
! glb_lc(:,1) will hold sorted global indices, and glb_lc(:,2) the
|
||||
! corresponding local indices, so that we may do a binary search. To cut down
|
||||
! the search time we partition glb_lc into a set of lists addressed by
|
||||
! hashv(:) based on the value of the lowest PSB_HASH_BITS bits of the
|
||||
! global index.
|
||||
! N_COL.
|
||||
! The idea is that glb_lc(:,1) will hold sorted global indices, and
|
||||
! glb_lc(:,2) the corresponding local indices, so that we may do a binary search.
|
||||
! To cut down the search time we partition glb_lc into a set of lists
|
||||
! addressed by hashv(:) based on the value of the lowest
|
||||
! PSB_HASH_BITS bits of the global index.
|
||||
! During the build phase glb_lc() will store the indices of the internal points,
|
||||
! i.e. local indices 1:NROW, since those are known ad CDALL time.
|
||||
! The halo indices that we encounter during the build phase are put in
|
||||
! a PSB_HASH_TYPE data structure, which implements a very simple hash, which will
|
||||
! nonetheless be quite fast at low occupancy rates.
|
||||
! At assembly time, we move everything into hashv(:) and glb_lc(:,:).
|
||||
! Note that the desc%hash component is a pointer, but it really should be
|
||||
! an allocatable scalar.
|
||||
!
|
||||
! 7. The data exchange is based on lists of local indices to be exchanged; all the
|
||||
! lists have the same format, as follows:
|
||||
@@ -303,11 +312,12 @@ module psb_descriptor_type
|
||||
integer, allocatable :: bnd_elem(:)
|
||||
integer, allocatable :: loc_to_glob(:)
|
||||
integer, allocatable :: glob_to_loc (:)
|
||||
integer :: hashvsize, hashvmask
|
||||
integer, allocatable :: hashv(:), glb_lc(:,:)
|
||||
type(psb_tree_int2), pointer :: avltree => null()
|
||||
integer, allocatable :: lprm(:)
|
||||
integer, allocatable :: idx_space(:)
|
||||
type(psb_desc_type), pointer :: base_desc => null()
|
||||
type(psb_hash_type), pointer :: hash => null()
|
||||
type(psb_desc_type), pointer :: base_desc => null()
|
||||
end type psb_desc_type
|
||||
|
||||
interface psb_sizeof
|
||||
@@ -354,15 +364,12 @@ module psb_descriptor_type
|
||||
|
||||
contains
|
||||
|
||||
function psb_cd_sizeof(desc)
|
||||
function psb_cd_sizeof(desc) result(val)
|
||||
implicit none
|
||||
!....Parameters...
|
||||
|
||||
Type(psb_desc_type), intent(in) :: desc
|
||||
Integer :: psb_cd_sizeof
|
||||
!locals
|
||||
integer :: val
|
||||
integer, external :: SizeofPairSearchTree
|
||||
integer(psb_long_int_k_) :: val
|
||||
|
||||
val = 0
|
||||
if (allocated(desc%matrix_data)) val = val + psb_sizeof_int*size(desc%matrix_data)
|
||||
@@ -378,9 +385,8 @@ contains
|
||||
if (allocated(desc%glb_lc)) val = val + psb_sizeof_int*size(desc%glb_lc)
|
||||
if (allocated(desc%lprm)) val = val + psb_sizeof_int*size(desc%lprm)
|
||||
if (allocated(desc%idx_space)) val = val + psb_sizeof_int*size(desc%idx_space)
|
||||
if (associated(desc%avltree)) val = val + psb_sizeof(desc%avltree)
|
||||
if (associated(desc%hash)) val = val + psb_sizeof(desc%hash)
|
||||
|
||||
psb_cd_sizeof = val
|
||||
end function psb_cd_sizeof
|
||||
|
||||
|
||||
@@ -419,7 +425,7 @@ contains
|
||||
type(psb_desc_type), intent(inout) :: desc
|
||||
! We have nothing left to do here.
|
||||
! Perhaps we should delete this subroutine?
|
||||
nullify(desc%avltree,desc%base_desc)
|
||||
nullify(desc%hash,desc%base_desc)
|
||||
|
||||
end subroutine psb_nullify_desc
|
||||
|
||||
@@ -481,7 +487,7 @@ contains
|
||||
psb_is_ok_dec = ((dectype == psb_desc_asb_).or.(dectype == psb_desc_bld_).or.&
|
||||
&(dectype == psb_cd_ovl_asb_).or.(dectype == psb_cd_ovl_bld_).or.&
|
||||
&(dectype == psb_desc_upd_).or.&
|
||||
&(dectype== psb_desc_repl_))
|
||||
&(dectype == psb_desc_repl_))
|
||||
end function psb_is_ok_dec
|
||||
|
||||
logical function psb_is_bld_dec(dectype)
|
||||
@@ -619,70 +625,6 @@ contains
|
||||
end function psb_cd_get_mpic
|
||||
|
||||
|
||||
subroutine psb_cd_set_bld(desc,info)
|
||||
!
|
||||
! Change state of a descriptor into BUILD.
|
||||
! If the descriptor is LARGE, check the AVL search tree
|
||||
! and initialize it if necessary.
|
||||
!
|
||||
use psb_const_mod
|
||||
use psb_error_mod
|
||||
use psb_penv_mod
|
||||
|
||||
implicit none
|
||||
type(psb_desc_type), intent(inout) :: desc
|
||||
integer :: info
|
||||
!locals
|
||||
integer :: np,me,ictxt, err_act,idx,gidx,lidx
|
||||
logical, parameter :: debug=.false.,debugprt=.false.
|
||||
character(len=20) :: name
|
||||
if (debug) write(0,*) me,'Entered CDCPY'
|
||||
if (psb_get_errstatus() /= 0) return
|
||||
info = 0
|
||||
call psb_erractionsave(err_act)
|
||||
name = 'psb_cd_set_bld'
|
||||
|
||||
ictxt = psb_cd_get_context(desc)
|
||||
|
||||
if (debug) write(0,*)'Entered CDSETBLD',ictxt
|
||||
! check on blacs grid
|
||||
call psb_info(ictxt, me, np)
|
||||
if (debug) write(0,*) me,'Entered CDSETBLD'
|
||||
if (psb_is_asb_desc(desc)) then
|
||||
!!$ write(0,*) 'Warning: doing setbld on an assembled descriptor'
|
||||
end if
|
||||
|
||||
if (psb_is_large_desc(desc)) then
|
||||
if (debug) write(0,*) me,'SET_BLD: alocating avltree'
|
||||
if (.not.associated(desc%avltree)) then
|
||||
call InitSearchTree(desc%avltree,info)
|
||||
do idx=1, psb_cd_get_local_cols(desc)
|
||||
gidx = desc%loc_to_glob(idx)
|
||||
call SearchInsKey(desc%avltree,gidx,lidx,idx,info)
|
||||
if (lidx /= idx) then
|
||||
write(0,*) 'Warning from cdset: mismatch in AVLTREE ',idx,lidx
|
||||
endif
|
||||
enddo
|
||||
end if
|
||||
|
||||
end if
|
||||
desc%matrix_data(psb_dec_type_) = psb_desc_bld_
|
||||
|
||||
if (debug) write(0,*) me,'SET_BLD: done'
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 continue
|
||||
call psb_erractionrestore(err_act)
|
||||
|
||||
if (err_act == psb_act_ret_) then
|
||||
return
|
||||
else
|
||||
call psb_error(ictxt)
|
||||
end if
|
||||
return
|
||||
end subroutine psb_cd_set_bld
|
||||
|
||||
subroutine psb_cd_set_ovl_asb(desc,info)
|
||||
!
|
||||
! Change state of a descriptor into ovl_build.
|
||||
@@ -695,18 +637,6 @@ contains
|
||||
|
||||
end subroutine psb_cd_set_ovl_asb
|
||||
|
||||
subroutine psb_cd_set_ovl_bld(desc,info)
|
||||
!
|
||||
! Change state of a descriptor into ovl_build.
|
||||
implicit none
|
||||
type(psb_desc_type), intent(inout) :: desc
|
||||
integer :: info
|
||||
|
||||
call psb_cd_set_bld(desc,info)
|
||||
if (info == 0) desc%matrix_data(psb_dec_type_) = psb_cd_ovl_bld_
|
||||
|
||||
end subroutine psb_cd_set_ovl_bld
|
||||
|
||||
|
||||
subroutine psb_get_xch_idx(idx,totxch,totsnd,totrcv)
|
||||
implicit none
|
||||
@@ -961,8 +891,8 @@ contains
|
||||
end if
|
||||
end if
|
||||
|
||||
if (associated(desc_a%avltree)) then
|
||||
call FreeSearchTree(desc_a%avltree,info)
|
||||
if (associated(desc_a%hash)) then
|
||||
deallocate(desc_a%hash,stat=info)
|
||||
if (info /= 0) then
|
||||
info=2060
|
||||
call psb_errpush(info,name)
|
||||
@@ -1071,7 +1001,7 @@ contains
|
||||
if (info == 0) &
|
||||
& call psb_transfer( desc_in%glb_lc , desc_out%glb_lc , info)
|
||||
|
||||
desc_out%avltree => desc_in%avltree; nullify(desc_in%avltree)
|
||||
desc_out%hash => desc_in%hash; nullify(desc_in%hash)
|
||||
|
||||
if (info /= 0) then
|
||||
info = 4010
|
||||
|
||||
@@ -0,0 +1,340 @@
|
||||
!!$
|
||||
!!$ Parallel Sparse BLAS v2.0
|
||||
!!$ (C) Copyright 2006 Salvatore Filippone University of Rome Tor Vergata
|
||||
!!$ Alfredo Buttari University of Rome Tor Vergata
|
||||
!!$
|
||||
!!$ Redistribution and use in source and binary forms, with or without
|
||||
!!$ modification, are permitted provided that the following conditions
|
||||
!!$ are met:
|
||||
!!$ 1. Redistributions of source code must retain the above copyright
|
||||
!!$ notice, this list of conditions and the following disclaimer.
|
||||
!!$ 2. Redistributions in binary form must reproduce the above copyright
|
||||
!!$ notice, this list of conditions, and the following disclaimer in the
|
||||
!!$ documentation and/or other materials provided with the distribution.
|
||||
!!$ 3. The name of the PSBLAS group or the names of its contributors may
|
||||
!!$ not be used to endorse or promote products derived from this
|
||||
!!$ software without specific written permission.
|
||||
!!$
|
||||
!!$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
!!$ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
!!$ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
!!$ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
|
||||
!!$ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
!!$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
!!$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
!!$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
!!$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
!!$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
!!$ POSSIBILITY OF SUCH DAMAGE.
|
||||
!!$
|
||||
!!$
|
||||
!
|
||||
! package: psb_hash_mod
|
||||
!
|
||||
! This module implements a very simple minded hash table.
|
||||
! The hash is based on the idea of open addressing with double hashing;
|
||||
! the primary hash function h1(K) is simply the remainder modulo 2^N, while
|
||||
! the secondary hash function is 1 if H1(k) == 0, otherwise IOR((2^N-H1(k)),1)
|
||||
! (See Knuth: TAOCP, Vol. 3, sec. 6.4)
|
||||
! These hash functions are not very smart; however they are very simple and fast.
|
||||
! The intended usage of this hash table is to store indices of halo points, which
|
||||
! are supposed to be few compared to the internal indices
|
||||
! (which are stored elsewhere), so in this context they are acceptable.
|
||||
!
|
||||
!
|
||||
!
|
||||
module psb_hash_mod
|
||||
use psb_const_mod
|
||||
|
||||
!
|
||||
! For us a hash is a Nx2 table.
|
||||
! Note: we are assuming that the keys are positive numbers.
|
||||
! Allocatable scalars would be a nice solution...
|
||||
!
|
||||
type psb_hash_type
|
||||
integer :: nbits, hsize, hmask, nk
|
||||
integer, allocatable :: table(:,:)
|
||||
integer(psb_long_int_k_) :: nsrch, nacc
|
||||
end type psb_hash_type
|
||||
|
||||
|
||||
integer, parameter :: HashDuplicate = 123, HashOK=0, HashOutOfMemory=-512,&
|
||||
& HashFreeEntry = -1, HashNotFound = -256
|
||||
|
||||
interface psb_hash_init
|
||||
module procedure psb_hash_init_v, psb_hash_init_n
|
||||
end interface
|
||||
interface psb_sizeof
|
||||
module procedure psb_sizeof_hash_type
|
||||
end interface
|
||||
|
||||
contains
|
||||
|
||||
|
||||
function hashval(key) result(val)
|
||||
integer, intent(in) :: key
|
||||
integer, parameter :: ival=5381, mask=2147483647
|
||||
integer :: key_, val, i
|
||||
|
||||
key_ = key
|
||||
val = ival
|
||||
do i=1, 4
|
||||
val = val * 33 + iand(key_,255)
|
||||
key_ = ishft(key_,-8)
|
||||
end do
|
||||
|
||||
val = val + ishft(val,-5)
|
||||
val = iand(val,mask)
|
||||
|
||||
end function hashval
|
||||
|
||||
|
||||
function psb_Sizeof_hash_type(hash) result(val)
|
||||
type(psb_hash_type), pointer :: hash
|
||||
integer(psb_long_int_k_) :: val
|
||||
val = 0
|
||||
if (associated(hash)) then
|
||||
val = val + psb_sizeof_int * size(hash%table)
|
||||
end if
|
||||
end function psb_Sizeof_hash_type
|
||||
|
||||
|
||||
function psb_hash_avg_acc(hash)
|
||||
type(psb_hash_type), intent(in) :: hash
|
||||
real(psb_dpk_) :: psb_hash_avg_acc
|
||||
|
||||
psb_hash_avg_acc = dble(hash%nacc)/dble(hash%nsrch)
|
||||
end function psb_hash_avg_acc
|
||||
|
||||
subroutine HashTransfer(hashin,hashout,info)
|
||||
use psb_realloc_mod
|
||||
type(psb_hash_type) :: hashin
|
||||
type(psb_hash_type) :: hashout
|
||||
integer, intent(out) :: info
|
||||
|
||||
info = HashOk
|
||||
hashout%nbits = hashin%nbits
|
||||
hashout%hsize = hashin%hsize
|
||||
hashout%hmask = hashin%hmask
|
||||
hashout%nk = hashin%nk
|
||||
hashout%nsrch = hashin%nsrch
|
||||
hashout%nacc = hashin%nacc
|
||||
call psb_transfer(hashin%table, hashout%table,info)
|
||||
|
||||
end subroutine HashTransfer
|
||||
|
||||
subroutine HashCopy(hashin,hashout,info)
|
||||
use psb_realloc_mod
|
||||
type(psb_hash_type) :: hashin
|
||||
type(psb_hash_type) :: hashout
|
||||
integer, intent(out) :: info
|
||||
|
||||
info = HashOk
|
||||
hashout%nbits = hashin%nbits
|
||||
hashout%hsize = hashin%hsize
|
||||
hashout%hmask = hashin%hmask
|
||||
hashout%nk = hashin%nk
|
||||
hashout%nsrch = hashin%nsrch
|
||||
hashout%nacc = hashin%nacc
|
||||
call psb_safe_ab_cpy(hashin%table, hashout%table,info)
|
||||
|
||||
end subroutine HashCopy
|
||||
|
||||
subroutine CloneHashTable(hashin,hashout,info)
|
||||
type(psb_hash_type), pointer :: hashin
|
||||
type(psb_hash_type), pointer :: hashout
|
||||
integer, intent(out) :: info
|
||||
|
||||
if (associated(hashout)) then
|
||||
deallocate(hashout,stat=info)
|
||||
!if (info /= 0) return
|
||||
end if
|
||||
if (associated(hashin)) then
|
||||
allocate(hashout,stat=info)
|
||||
if (info /= 0) return
|
||||
call HashCopy(hashin,hashout,info)
|
||||
end if
|
||||
|
||||
end subroutine CloneHashTable
|
||||
|
||||
subroutine psb_hash_init_V(v,hash,info)
|
||||
integer, intent(in) :: v(:)
|
||||
type(psb_hash_type), intent(out) :: hash
|
||||
integer, intent(out) :: info
|
||||
|
||||
integer :: i,j,k,hsize,nbits, nv
|
||||
|
||||
info = 0
|
||||
nv = size(v)
|
||||
call psb_hash_init(nv,hash,info)
|
||||
if (info /= 0) return
|
||||
do i=1,nv
|
||||
call psb_hash_searchinskey(v(i),j,i,hash,info)
|
||||
if ((j /= i).or.(info /= HashOK)) then
|
||||
write(0,*) 'Error from hash_ins',i,v(i),j,info
|
||||
info = HashNotFound
|
||||
return
|
||||
end if
|
||||
end do
|
||||
end subroutine psb_hash_init_V
|
||||
|
||||
subroutine psb_hash_init_n(nv,hash,info)
|
||||
integer, intent(in) :: nv
|
||||
type(psb_hash_type), intent(out) :: hash
|
||||
integer, intent(out) :: info
|
||||
|
||||
integer :: i,j,k,hsize,nbits
|
||||
|
||||
info = 0
|
||||
nbits = 12
|
||||
hsize = 2**nbits
|
||||
!
|
||||
! Figure out the smallest power of 2 bigger than NV
|
||||
!
|
||||
do
|
||||
if (hsize < 0) then
|
||||
write(0,*) 'Error: hash size overflow ',hsize,nbits
|
||||
info = -2
|
||||
return
|
||||
end if
|
||||
if (hsize > nv) exit
|
||||
nbits = nbits + 1
|
||||
hsize = hsize * 2
|
||||
end do
|
||||
|
||||
hash%nbits = nbits
|
||||
hash%hsize = hsize
|
||||
hash%hmask = hsize-1
|
||||
hash%nsrch = 0
|
||||
hash%nacc = 0
|
||||
allocate(hash%table(0:hsize-1,2),stat=info)
|
||||
if (info /= 0) then
|
||||
write(0,*) 'Error: memory allocation failure ',hsize
|
||||
info = HashOutOfMemory
|
||||
return
|
||||
end if
|
||||
hash%table = HashFreeEntry
|
||||
hash%nk = 0
|
||||
end subroutine psb_hash_init_n
|
||||
|
||||
|
||||
subroutine psb_hash_realloc(hash,info)
|
||||
type(psb_hash_type), intent(inout) :: hash
|
||||
integer, intent(out) :: info
|
||||
type(psb_hash_type) :: nhash
|
||||
integer :: nk, key, val, nextval,i
|
||||
|
||||
info = HashOk
|
||||
|
||||
call psb_hash_init((hash%hsize+1),nhash,info)
|
||||
|
||||
if (info /= HashOk) then
|
||||
info = HashOutOfMemory
|
||||
return
|
||||
endif
|
||||
do i=0, hash%hsize-1
|
||||
key = hash%table(i,1)
|
||||
nextval = hash%table(i,2)
|
||||
if (key /= HashFreeEntry) then
|
||||
call psb_hash_searchinskey(key,val,nextval,nhash,info)
|
||||
if (info /= 0) then
|
||||
info = HashOutOfMemory
|
||||
return
|
||||
end if
|
||||
end if
|
||||
end do
|
||||
call HashTransfer(nhash,hash,info)
|
||||
end subroutine psb_hash_realloc
|
||||
|
||||
recursive subroutine psb_hash_searchinskey(key,val,nextval,hash,info)
|
||||
integer, intent(in) :: key,nextval
|
||||
type(psb_hash_type) :: hash
|
||||
integer, intent(out) :: val, info
|
||||
|
||||
integer :: i,j,k,hsize,hmask, hk, hd
|
||||
|
||||
info = HashOK
|
||||
hsize = hash%hsize
|
||||
hmask = hash%hmask
|
||||
|
||||
hk = iand(hashval(key),hmask)
|
||||
if (hk == 0) then
|
||||
hd = 1
|
||||
else
|
||||
hd = hsize - hk
|
||||
hd = ior(hd,1)
|
||||
end if
|
||||
|
||||
hash%nsrch = hash%nsrch + 1
|
||||
do
|
||||
hash%nacc = hash%nacc + 1
|
||||
if (hash%table(hk,1) == key) then
|
||||
val = hash%table(hk,2)
|
||||
info = HashDuplicate
|
||||
return
|
||||
end if
|
||||
if (hash%table(hk,1) == HashFreeEntry) then
|
||||
if (hash%nk == hash%hsize -1) then
|
||||
!
|
||||
! Note: because of the way we allocate things at CDALL
|
||||
! time this is really unlikely; if we get here, we
|
||||
! have at least as many halo indices as internals, which
|
||||
! means we're already in trouble. But we try to keep going.
|
||||
!
|
||||
call psb_hash_realloc(hash,info)
|
||||
if (info /= HashOk) then
|
||||
info = HashOutOfMemory
|
||||
return
|
||||
else
|
||||
call psb_hash_searchinskey(key,val,nextval,hash,info)
|
||||
return
|
||||
end if
|
||||
else
|
||||
hash%nk = hash%nk + 1
|
||||
hash%table(hk,1) = key
|
||||
hash%table(hk,2) = nextval
|
||||
val = nextval
|
||||
return
|
||||
end if
|
||||
end if
|
||||
hk = hk - hd
|
||||
if (hk < 0) hk = hk + hsize
|
||||
end do
|
||||
end subroutine psb_hash_searchinskey
|
||||
|
||||
subroutine psb_hash_searchkey(key,val,hash,info)
|
||||
integer, intent(in) :: key
|
||||
type(psb_hash_type) :: hash
|
||||
integer, intent(out) :: val, info
|
||||
|
||||
integer :: i,j,k,hsize,hmask, hk, hd
|
||||
|
||||
info = HashOK
|
||||
hsize = hash%hsize
|
||||
hmask = hash%hmask
|
||||
hk = iand(hashval(key),hmask)
|
||||
if (hk == 0) then
|
||||
hd = 1
|
||||
else
|
||||
hd = hsize - hk
|
||||
hd = ior(hd,1)
|
||||
end if
|
||||
|
||||
hash%nsrch = hash%nsrch + 1
|
||||
do
|
||||
hash%nacc = hash%nacc + 1
|
||||
if (hash%table(hk,1) == key) then
|
||||
val = hash%table(hk,2)
|
||||
return
|
||||
end if
|
||||
if (hash%table(hk,1) == HashFreeEntry) then
|
||||
val = HashFreeEntry
|
||||
!!$ info = HashNotFound
|
||||
return
|
||||
end if
|
||||
hk = hk - hd
|
||||
if (hk < 0) hk = hk + hsize
|
||||
end do
|
||||
end subroutine psb_hash_searchkey
|
||||
|
||||
end module psb_hash_mod
|
||||
@@ -365,76 +365,66 @@ contains
|
||||
end function psb_is_ok_inter_desc
|
||||
|
||||
|
||||
function psb_s_map_sizeof(map)
|
||||
function psb_s_map_sizeof(map) result(val)
|
||||
implicit none
|
||||
type(psb_s_map_type), intent(in) :: map
|
||||
Integer :: psb_s_map_sizeof
|
||||
integer :: val
|
||||
integer(psb_long_int_k_) :: val
|
||||
|
||||
val = 0
|
||||
|
||||
val = val + psb_sizeof(map%map_fw)
|
||||
val = val + psb_sizeof(map%map_bk)
|
||||
psb_s_map_sizeof = val
|
||||
|
||||
end function psb_s_map_sizeof
|
||||
|
||||
function psb_d_map_sizeof(map)
|
||||
function psb_d_map_sizeof(map) result(val)
|
||||
implicit none
|
||||
type(psb_d_map_type), intent(in) :: map
|
||||
Integer :: psb_d_map_sizeof
|
||||
integer :: val
|
||||
integer(psb_long_int_k_) :: val
|
||||
|
||||
val = 0
|
||||
|
||||
val = val + psb_sizeof(map%map_fw)
|
||||
val = val + psb_sizeof(map%map_bk)
|
||||
psb_d_map_sizeof = val
|
||||
|
||||
end function psb_d_map_sizeof
|
||||
|
||||
function psb_c_map_sizeof(map)
|
||||
function psb_c_map_sizeof(map) result(val)
|
||||
implicit none
|
||||
type(psb_c_map_type), intent(in) :: map
|
||||
Integer :: psb_c_map_sizeof
|
||||
integer :: val
|
||||
integer(psb_long_int_k_) :: val
|
||||
|
||||
val = 0
|
||||
|
||||
val = val + psb_sizeof(map%map_fw)
|
||||
val = val + psb_sizeof(map%map_bk)
|
||||
psb_c_map_sizeof = val
|
||||
|
||||
end function psb_c_map_sizeof
|
||||
|
||||
function psb_z_map_sizeof(map)
|
||||
function psb_z_map_sizeof(map) result(val)
|
||||
implicit none
|
||||
type(psb_z_map_type), intent(in) :: map
|
||||
Integer :: psb_z_map_sizeof
|
||||
integer :: val
|
||||
integer(psb_long_int_k_) :: val
|
||||
|
||||
val = 0
|
||||
|
||||
val = val + psb_sizeof(map%map_fw)
|
||||
val = val + psb_sizeof(map%map_bk)
|
||||
psb_z_map_sizeof = val
|
||||
|
||||
end function psb_z_map_sizeof
|
||||
|
||||
function psb_itd_sizeof(desc)
|
||||
function psb_itd_sizeof(desc) result(val)
|
||||
implicit none
|
||||
type(psb_inter_desc_type), intent(in) :: desc
|
||||
Integer :: psb_itd_sizeof
|
||||
integer :: val
|
||||
integer(psb_long_int_k_) :: val
|
||||
|
||||
val = 0
|
||||
|
||||
if (allocated(desc%itd_data)) val = val + 4*size(desc%itd_data)
|
||||
if (allocated(desc%exch_fw_idx)) val = val + 4*size(desc%exch_fw_idx)
|
||||
if (allocated(desc%exch_bk_idx)) val = val + 4*size(desc%exch_bk_idx)
|
||||
if (allocated(desc%itd_data)) val = val + psb_sizeof_int*size(desc%itd_data)
|
||||
if (allocated(desc%exch_fw_idx)) val = val + psb_sizeof_int*size(desc%exch_fw_idx)
|
||||
if (allocated(desc%exch_bk_idx)) val = val + psb_sizeof_int*size(desc%exch_bk_idx)
|
||||
val = val + psb_sizeof(desc%desc_fw)
|
||||
val = val + psb_sizeof(desc%desc_bk)
|
||||
val = val + psb_sizeof(desc%dmap)
|
||||
val = val + psb_sizeof(desc%zmap)
|
||||
psb_itd_sizeof = val
|
||||
|
||||
end function psb_itd_sizeof
|
||||
!!$
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -100,6 +100,7 @@ module psb_penv_mod
|
||||
|
||||
interface psb_max
|
||||
module procedure psb_imaxs, psb_imaxv, psb_imaxm,&
|
||||
& psb_i8maxs, &
|
||||
& psb_smaxs, psb_smaxv, psb_smaxm,&
|
||||
& psb_dmaxs, psb_dmaxv, psb_dmaxm
|
||||
end interface
|
||||
@@ -107,6 +108,7 @@ module psb_penv_mod
|
||||
|
||||
interface psb_min
|
||||
module procedure psb_imins, psb_iminv, psb_iminm,&
|
||||
& psb_i8mins, &
|
||||
& psb_smins, psb_sminv, psb_sminm,&
|
||||
& psb_dmins, psb_dminv, psb_dminm
|
||||
end interface
|
||||
@@ -114,6 +116,7 @@ module psb_penv_mod
|
||||
|
||||
interface psb_amx
|
||||
module procedure psb_iamxs, psb_iamxv, psb_iamxm,&
|
||||
& psb_i8amxs, &
|
||||
& psb_samxs, psb_samxv, psb_samxm,&
|
||||
& psb_camxs, psb_camxv, psb_camxm,&
|
||||
& psb_damxs, psb_damxv, psb_damxm,&
|
||||
@@ -122,6 +125,7 @@ module psb_penv_mod
|
||||
|
||||
interface psb_amn
|
||||
module procedure psb_iamns, psb_iamnv, psb_iamnm,&
|
||||
& psb_i8amns, &
|
||||
& psb_samns, psb_samnv, psb_samnm,&
|
||||
& psb_camns, psb_camnv, psb_camnm,&
|
||||
& psb_damns, psb_damnv, psb_damnm,&
|
||||
@@ -130,6 +134,7 @@ module psb_penv_mod
|
||||
|
||||
interface psb_sum
|
||||
module procedure psb_isums, psb_isumv, psb_isumm,&
|
||||
& psb_i8sums, &
|
||||
& psb_ssums, psb_ssumv, psb_ssumm,&
|
||||
& psb_csums, psb_csumv, psb_csumm,&
|
||||
& psb_dsums, psb_dsumv, psb_dsumm,&
|
||||
@@ -162,10 +167,12 @@ contains
|
||||
real(psb_dpk_) :: dv(2)
|
||||
real(psb_spk_) :: sv(2)
|
||||
integer :: iv(2)
|
||||
integer(psb_long_int_k_) :: ilv(2)
|
||||
|
||||
call psi_c_diffadd(sv(1),sv(2),psb_sizeof_sp)
|
||||
call psi_c_diffadd(dv(1),dv(2),psb_sizeof_dp)
|
||||
call psi_c_diffadd(iv(1),iv(2),psb_sizeof_int)
|
||||
call psi_c_diffadd(ilv(1),ilv(2),psb_sizeof_long_int)
|
||||
|
||||
end subroutine psi_get_sizes
|
||||
|
||||
@@ -1147,6 +1154,7 @@ contains
|
||||
endif
|
||||
#endif
|
||||
end subroutine psb_imins
|
||||
|
||||
subroutine psb_iminv(ictxt,dat,root)
|
||||
use psb_realloc_mod
|
||||
#ifdef MPI_MOD
|
||||
@@ -2323,6 +2331,217 @@ contains
|
||||
|
||||
|
||||
|
||||
subroutine psb_i8sums(ictxt,dat,root)
|
||||
#ifdef MPI_MOD
|
||||
use mpi
|
||||
#endif
|
||||
#ifdef MPI_H
|
||||
include 'mpif.h'
|
||||
#endif
|
||||
integer, intent(in) :: ictxt
|
||||
integer(psb_long_int_k_), intent(inout) :: dat
|
||||
integer, intent(in), optional :: root
|
||||
integer :: mpi_int8_type, info, icomm
|
||||
|
||||
integer :: root_, iam, np
|
||||
integer(psb_long_int_k_) :: dat_
|
||||
|
||||
if (present(root)) then
|
||||
root_ = root
|
||||
else
|
||||
root_ = -1
|
||||
endif
|
||||
call psb_info(ictxt,iam,np)
|
||||
call psb_get_mpicomm(ictxt,icomm)
|
||||
mpi_int8_type = mpi_integer8
|
||||
if (root_ == -1) then
|
||||
dat_=dat
|
||||
call mpi_allreduce(dat_,dat,1,mpi_int8_type,mpi_sum,icomm,info)
|
||||
else
|
||||
if (iam==root_) then
|
||||
dat_=dat
|
||||
call mpi_reduce(dat_,dat,1,mpi_int8_type,mpi_sum,root_,icomm,info)
|
||||
else
|
||||
call mpi_reduce(dat,dat_,1,mpi_int8_type,mpi_sum,root_,icomm,info)
|
||||
end if
|
||||
endif
|
||||
|
||||
end subroutine psb_i8sums
|
||||
|
||||
subroutine psb_i8amx_mpi_user(inv, outv,len,type)
|
||||
integer(psb_long_int_k_) :: inv(*),outv(*)
|
||||
integer :: len,type
|
||||
integer :: i
|
||||
|
||||
do i=1, len
|
||||
if (abs(inv(i)) > abs(outv(i))) then
|
||||
outv(i) = inv(i)
|
||||
end if
|
||||
end do
|
||||
end subroutine psb_i8amx_mpi_user
|
||||
|
||||
subroutine psb_i8amn_mpi_user(inv, outv,len,type)
|
||||
#ifdef MPI_MOD
|
||||
use mpi
|
||||
#endif
|
||||
#ifdef MPI_H
|
||||
include 'mpif.h'
|
||||
#endif
|
||||
integer(psb_long_int_k_) :: inv(*),outv(*)
|
||||
integer :: len,type
|
||||
integer :: i
|
||||
if (type /= mpi_integer8) then
|
||||
write(0,*) 'Invalid type !!!'
|
||||
end if
|
||||
do i=1, len
|
||||
if (abs(inv(i)) < abs(outv(i))) then
|
||||
outv(i) = inv(i)
|
||||
end if
|
||||
end do
|
||||
end subroutine psb_i8amn_mpi_user
|
||||
|
||||
subroutine psb_i8amns(ictxt,dat,root)
|
||||
#ifdef MPI_MOD
|
||||
use mpi
|
||||
#endif
|
||||
#ifdef MPI_H
|
||||
include 'mpif.h'
|
||||
#endif
|
||||
integer, intent(in) :: ictxt
|
||||
integer(psb_long_int_k_), intent(inout) :: dat
|
||||
integer, intent(in), optional :: root
|
||||
integer :: root_
|
||||
integer(psb_long_int_k_) :: dat_
|
||||
integer :: iam, np, icomm,info, i8amn
|
||||
|
||||
#if !defined(SERIAL_MPI)
|
||||
|
||||
call psb_info(ictxt,iam,np)
|
||||
call psb_get_mpicomm(ictxt,icomm)
|
||||
|
||||
call mpi_op_create(psb_i8amn_mpi_user,.true.,i8amn,info)
|
||||
|
||||
if (present(root)) then
|
||||
root_ = root
|
||||
else
|
||||
root_ = -1
|
||||
endif
|
||||
if (root_ == -1) then
|
||||
call mpi_allreduce(dat,dat_,1,mpi_integer8,i8amn,icomm,info)
|
||||
dat = dat_
|
||||
else
|
||||
call mpi_reduce(dat,dat_,1,mpi_integer8,i8amn,root_,icomm,info)
|
||||
dat = dat_
|
||||
endif
|
||||
call mpi_op_free(i8amn,info)
|
||||
#endif
|
||||
end subroutine psb_i8amns
|
||||
|
||||
subroutine psb_i8amxs(ictxt,dat,root)
|
||||
#ifdef MPI_MOD
|
||||
use mpi
|
||||
#endif
|
||||
#ifdef MPI_H
|
||||
include 'mpif.h'
|
||||
#endif
|
||||
integer, intent(in) :: ictxt
|
||||
integer(psb_long_int_k_), intent(inout) :: dat
|
||||
integer, intent(in), optional :: root
|
||||
integer :: root_
|
||||
integer(psb_long_int_k_) :: dat_
|
||||
integer :: iam, np, icomm,info, i8amx
|
||||
|
||||
#if !defined(SERIAL_MPI)
|
||||
|
||||
call psb_info(ictxt,iam,np)
|
||||
call psb_get_mpicomm(ictxt,icomm)
|
||||
|
||||
call mpi_op_create(psb_i8amx_mpi_user,.true.,i8amx,info)
|
||||
|
||||
if (present(root)) then
|
||||
root_ = root
|
||||
else
|
||||
root_ = -1
|
||||
endif
|
||||
if (root_ == -1) then
|
||||
call mpi_allreduce(dat,dat_,1,mpi_integer8,i8amx,icomm,info)
|
||||
dat = dat_
|
||||
else
|
||||
call mpi_reduce(dat,dat_,1,mpi_integer8,i8amx,root_,icomm,info)
|
||||
dat = dat_
|
||||
endif
|
||||
call mpi_op_free(i8amx,info)
|
||||
#endif
|
||||
end subroutine psb_i8amxs
|
||||
|
||||
subroutine psb_i8mins(ictxt,dat,root)
|
||||
#ifdef MPI_MOD
|
||||
use mpi
|
||||
#endif
|
||||
#ifdef MPI_H
|
||||
include 'mpif.h'
|
||||
#endif
|
||||
integer, intent(in) :: ictxt
|
||||
integer(psb_long_int_k_), intent(inout) :: dat
|
||||
integer, intent(in), optional :: root
|
||||
integer :: root_
|
||||
integer(psb_long_int_k_) :: dat_
|
||||
integer :: iam, np, icomm,info
|
||||
|
||||
#if !defined(SERIAL_MPI)
|
||||
|
||||
call psb_info(ictxt,iam,np)
|
||||
call psb_get_mpicomm(ictxt,icomm)
|
||||
|
||||
if (present(root)) then
|
||||
root_ = root
|
||||
else
|
||||
root_ = -1
|
||||
endif
|
||||
if (root_ == -1) then
|
||||
call mpi_allreduce(dat,dat_,1,mpi_integer8,mpi_min,icomm,info)
|
||||
dat = dat_
|
||||
else
|
||||
call mpi_reduce(dat,dat_,1,mpi_integer8,mpi_min,root_,icomm,info)
|
||||
dat = dat_
|
||||
endif
|
||||
#endif
|
||||
end subroutine psb_i8mins
|
||||
|
||||
subroutine psb_i8maxs(ictxt,dat,root)
|
||||
#ifdef MPI_MOD
|
||||
use mpi
|
||||
#endif
|
||||
#ifdef MPI_H
|
||||
include 'mpif.h'
|
||||
#endif
|
||||
integer, intent(in) :: ictxt
|
||||
integer(psb_long_int_k_), intent(inout) :: dat
|
||||
integer, intent(in), optional :: root
|
||||
integer :: root_
|
||||
integer(psb_long_int_k_) :: dat_
|
||||
integer :: iam, np, icomm,info
|
||||
|
||||
#if !defined(SERIAL_MPI)
|
||||
|
||||
call psb_info(ictxt,iam,np)
|
||||
call psb_get_mpicomm(ictxt,icomm)
|
||||
|
||||
if (present(root)) then
|
||||
root_ = root
|
||||
else
|
||||
root_ = -1
|
||||
endif
|
||||
if (root_ == -1) then
|
||||
call mpi_allreduce(dat,dat_,1,mpi_integer8,mpi_max,icomm,info)
|
||||
dat = dat_
|
||||
else
|
||||
call mpi_reduce(dat,dat_,1,mpi_integer8,mpi_max,root_,icomm,info)
|
||||
dat = dat_
|
||||
endif
|
||||
#endif
|
||||
end subroutine psb_i8maxs
|
||||
|
||||
subroutine psb_isums(ictxt,dat,root)
|
||||
integer, intent(in) :: ictxt
|
||||
integer, intent(inout) :: dat
|
||||
|
||||
@@ -48,12 +48,12 @@ module psb_sort_mod
|
||||
! The up/down constant are defined in pairs having
|
||||
! opposite values. We make use of this fact in the heapsort routine.
|
||||
!
|
||||
integer, parameter :: psb_sort_up_=1, psb_sort_down_=-1
|
||||
integer, parameter :: psb_lsort_up_=2, psb_lsort_down_=-2
|
||||
integer, parameter :: psb_asort_up_=3, psb_asort_down_=-3
|
||||
integer, parameter :: psb_alsort_up_=4, psb_alsort_down_=-4
|
||||
integer, parameter :: psb_sort_ovw_idx_=0, psb_sort_keep_idx_=1
|
||||
integer, parameter :: psb_heap_resize=200
|
||||
integer, parameter :: psb_sort_up_ = 1, psb_sort_down_ = -1
|
||||
integer, parameter :: psb_lsort_up_ = 2, psb_lsort_down_ = -2
|
||||
integer, parameter :: psb_asort_up_ = 3, psb_asort_down_ = -3
|
||||
integer, parameter :: psb_alsort_up_ = 4, psb_alsort_down_ = -4
|
||||
integer, parameter :: psb_sort_ovw_idx_ = 0, psb_sort_keep_idx_ = 1
|
||||
integer, parameter :: psb_heap_resize = 200
|
||||
|
||||
type psb_int_heap
|
||||
integer :: last, dir
|
||||
@@ -131,9 +131,58 @@ module psb_sort_mod
|
||||
& psb_double_idx_heap_get_first, psb_dcomplex_idx_heap_get_first
|
||||
end interface
|
||||
|
||||
interface psb_ibsrch
|
||||
module procedure psb_ibsrch
|
||||
end interface
|
||||
interface psb_issrch
|
||||
module procedure psb_issrch
|
||||
end interface
|
||||
|
||||
contains
|
||||
|
||||
function psb_ibsrch(key,n,v) result(ipos)
|
||||
implicit none
|
||||
integer ipos, key, n
|
||||
integer v(n)
|
||||
|
||||
integer lb, ub, m
|
||||
|
||||
lb = 1
|
||||
ub = n
|
||||
ipos = -1
|
||||
|
||||
do while (lb.le.ub)
|
||||
m = (lb+ub)/2
|
||||
if (key.eq.v(m)) then
|
||||
ipos = m
|
||||
lb = ub + 1
|
||||
else if (key.lt.v(m)) then
|
||||
ub = m-1
|
||||
else
|
||||
lb = m + 1
|
||||
end if
|
||||
enddo
|
||||
return
|
||||
end function psb_ibsrch
|
||||
|
||||
function psb_issrch(key,n,v) result(ipos)
|
||||
implicit none
|
||||
integer ipos, key, n
|
||||
integer v(n)
|
||||
|
||||
integer i
|
||||
|
||||
ipos = -1
|
||||
do i=1,n
|
||||
if (key.eq.v(i)) then
|
||||
ipos = i
|
||||
return
|
||||
end if
|
||||
enddo
|
||||
return
|
||||
end function psb_issrch
|
||||
|
||||
|
||||
subroutine imsort(x,ix,dir,flag)
|
||||
use psb_error_mod
|
||||
implicit none
|
||||
|
||||
@@ -140,6 +140,11 @@ module psb_spmat_type
|
||||
|
||||
type, extends(psb_base_spmat_type) :: psb_dspmat_type
|
||||
real(psb_dpk_), allocatable :: aspk(:)
|
||||
|
||||
contains
|
||||
procedure, pass(a) :: i_spmv => psb_dspmv_inner
|
||||
procedure, pass(a) :: i_spmm => psb_dspmm_inner
|
||||
generic, public :: spmm => i_spmv, i_spmm
|
||||
end type psb_dspmat_type
|
||||
|
||||
type, extends(psb_base_spmat_type) :: psb_zspmat_type
|
||||
@@ -242,10 +247,28 @@ module psb_spmat_type
|
||||
& psb_dspinfo, psb_zspinfo
|
||||
end interface
|
||||
|
||||
|
||||
private psb_dspmm_inner, psb_dspmv_inner
|
||||
|
||||
contains
|
||||
|
||||
subroutine psb_dspmv_inner(alpha,a,x,beta,y,info)
|
||||
type(psb_dspmat_type), intent(in) :: a
|
||||
real(psb_dpk_), intent(in) :: alpha,beta,x(:)
|
||||
real(psb_dpk_), intent(inout) :: y(:)
|
||||
integer, intent(out) :: info
|
||||
|
||||
write(0,*) 'Inner spmv was invoked!'
|
||||
end subroutine psb_dspmv_inner
|
||||
|
||||
subroutine psb_dspmm_inner(alpha,a,x,beta,y,info)
|
||||
type(psb_dspmat_type), intent(in) :: a
|
||||
real(psb_dpk_), intent(in) :: alpha,beta,x(:,:)
|
||||
real(psb_dpk_), intent(inout) :: y(:,:)
|
||||
integer, intent(out) :: info
|
||||
|
||||
write(0,*) 'Inner spmm was invoked!'
|
||||
end subroutine psb_dspmm_inner
|
||||
|
||||
integer function psb_get_ssp_nrows(a)
|
||||
type(psb_sspmat_type), intent(in) :: a
|
||||
psb_get_ssp_nrows = a%m
|
||||
@@ -926,15 +949,12 @@ contains
|
||||
|
||||
end function psb_ssp_getifld
|
||||
|
||||
function psb_sspsizeof(a)
|
||||
function psb_sspsizeof(a) result(val)
|
||||
implicit none
|
||||
!....Parameters...
|
||||
|
||||
Type(psb_sspmat_type), intent(in) :: A
|
||||
Integer :: psb_sspsizeof
|
||||
|
||||
!locals
|
||||
integer :: val
|
||||
integer(psb_long_int_k_) :: val
|
||||
|
||||
val = psb_sizeof_int*size(a%infoa)
|
||||
|
||||
@@ -955,10 +975,6 @@ contains
|
||||
val = val + psb_sizeof_int * size(a%pr)
|
||||
endif
|
||||
|
||||
|
||||
psb_sspsizeof = val
|
||||
Return
|
||||
|
||||
end function psb_sspsizeof
|
||||
|
||||
|
||||
@@ -1462,22 +1478,17 @@ contains
|
||||
|
||||
end function psb_dsp_getifld
|
||||
|
||||
function psb_dspsizeof(a)
|
||||
function psb_dspsizeof(a) result(val)
|
||||
implicit none
|
||||
!....Parameters...
|
||||
|
||||
Type(psb_dspmat_type), intent(in) :: A
|
||||
Integer :: psb_dspsizeof
|
||||
|
||||
!locals
|
||||
integer :: val
|
||||
integer(psb_long_int_k_) :: val
|
||||
|
||||
val = psb_sizeof_int*size(a%infoa)
|
||||
|
||||
if (allocated(a%aspk)) then
|
||||
val = val + psb_sizeof_dp * size(a%aspk)
|
||||
endif
|
||||
|
||||
if (allocated(a%ia1)) then
|
||||
val = val + psb_sizeof_int * size(a%ia1)
|
||||
endif
|
||||
@@ -1491,10 +1502,6 @@ contains
|
||||
val = val + psb_sizeof_int * size(a%pr)
|
||||
endif
|
||||
|
||||
|
||||
psb_dspsizeof = val
|
||||
Return
|
||||
|
||||
end function psb_dspsizeof
|
||||
|
||||
|
||||
@@ -1971,20 +1978,15 @@ contains
|
||||
|
||||
end function psb_csp_getifld
|
||||
|
||||
function psb_cspsizeof(a)
|
||||
function psb_cspsizeof(a) result(val)
|
||||
implicit none
|
||||
!....Parameters...
|
||||
|
||||
Type(psb_cspmat_type), intent(in) :: A
|
||||
Integer :: psb_cspsizeof
|
||||
|
||||
!locals
|
||||
integer :: val
|
||||
integer(psb_long_int_k_) :: val
|
||||
|
||||
val = psb_sizeof_int*size(a%infoa)
|
||||
|
||||
if (allocated(a%aspk)) then
|
||||
val = val + 2 * psb_sizeof_dp * size(a%aspk)
|
||||
val = val + 2 * psb_sizeof_sp * size(a%aspk)
|
||||
endif
|
||||
|
||||
if (allocated(a%ia1)) then
|
||||
@@ -2000,10 +2002,6 @@ contains
|
||||
val = val + psb_sizeof_int * size(a%pr)
|
||||
endif
|
||||
|
||||
|
||||
psb_cspsizeof = val
|
||||
Return
|
||||
|
||||
end function psb_cspsizeof
|
||||
|
||||
|
||||
@@ -2473,22 +2471,18 @@ contains
|
||||
|
||||
end function psb_zsp_getifld
|
||||
|
||||
function psb_zspsizeof(a)
|
||||
function psb_zspsizeof(a) result(val)
|
||||
implicit none
|
||||
!....Parameters...
|
||||
|
||||
Type(psb_zspmat_type), intent(in) :: A
|
||||
Integer :: psb_zspsizeof
|
||||
|
||||
!locals
|
||||
integer :: val
|
||||
integer(psb_long_int_k_) :: val
|
||||
|
||||
val = psb_sizeof_int*size(a%infoa)
|
||||
|
||||
if (allocated(a%aspk)) then
|
||||
val = val + 2 * psb_sizeof_dp * size(a%aspk)
|
||||
endif
|
||||
|
||||
if (allocated(a%ia1)) then
|
||||
val = val + psb_sizeof_int * size(a%ia1)
|
||||
endif
|
||||
@@ -2502,10 +2496,6 @@ contains
|
||||
val = val + psb_sizeof_int * size(a%pr)
|
||||
endif
|
||||
|
||||
|
||||
psb_zspsizeof = val
|
||||
Return
|
||||
|
||||
end function psb_zspsizeof
|
||||
|
||||
|
||||
|
||||
@@ -44,20 +44,56 @@ module psb_string_mod
|
||||
module procedure psb_sub_toupperc
|
||||
end interface
|
||||
|
||||
private lcase, ucase, upper1c, lower1c
|
||||
private
|
||||
character(len=*), parameter :: lcase='abcdefghijklmnopqrstuvwxyz'
|
||||
character(len=*), parameter :: ucase='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
|
||||
contains
|
||||
|
||||
function idx_bsrch(key,v) result(ipos)
|
||||
|
||||
implicit none
|
||||
integer :: ipos
|
||||
character key
|
||||
character(len=*) v
|
||||
|
||||
integer lb, ub, m
|
||||
|
||||
|
||||
lb = 1
|
||||
ub = len(v)
|
||||
ipos = 0
|
||||
|
||||
do
|
||||
if (lb > ub) exit
|
||||
m = (lb+ub)/2
|
||||
if (key.eq.v(m:m)) then
|
||||
ipos = m
|
||||
exit
|
||||
else if (key.lt.v(m:m)) then
|
||||
ub = m-1
|
||||
else
|
||||
lb = m + 1
|
||||
end if
|
||||
enddo
|
||||
return
|
||||
end function idx_bsrch
|
||||
|
||||
|
||||
function psb_tolowerc(string)
|
||||
character(len=*), intent(in) :: string
|
||||
character(len=len(string)) :: psb_tolowerc
|
||||
integer :: i,k
|
||||
|
||||
do i=1,len(string)
|
||||
psb_tolowerc(i:i) = lower1c(string(i:i))
|
||||
k = idx_bsrch(string(i:i),ucase)
|
||||
if (k /= 0) then
|
||||
psb_tolowerc(i:i) = lcase(k:k)
|
||||
else
|
||||
psb_tolowerc(i:i) = string(i:i)
|
||||
end if
|
||||
enddo
|
||||
|
||||
end function psb_tolowerc
|
||||
|
||||
function psb_toupperc(string)
|
||||
@@ -66,7 +102,12 @@ contains
|
||||
integer :: i,k
|
||||
|
||||
do i=1,len(string)
|
||||
psb_toupperc(i:i) = upper1c(string(i:i))
|
||||
k = idx_bsrch(string(i:i),lcase)
|
||||
if (k /= 0) then
|
||||
psb_toupperc(i:i) = ucase(k:k)
|
||||
else
|
||||
psb_toupperc(i:i) = string(i:i)
|
||||
end if
|
||||
enddo
|
||||
end function psb_toupperc
|
||||
|
||||
@@ -76,139 +117,16 @@ contains
|
||||
integer :: i,k
|
||||
|
||||
do i=1,len(string)
|
||||
k = index(lcase,string(i:i))
|
||||
if (k /=0 ) then
|
||||
k = idx_bsrch(string(i:i),lcase)
|
||||
if (k /= 0) then
|
||||
strout(i:i) = ucase(k:k)
|
||||
else
|
||||
strout(i:i) = string(i:i)
|
||||
end if
|
||||
enddo
|
||||
|
||||
end subroutine psb_sub_toupperc
|
||||
|
||||
|
||||
function lower1c(ch)
|
||||
character(len=1), intent(in) :: ch
|
||||
character(len=1) :: lower1c
|
||||
|
||||
select case(ch)
|
||||
case ('A')
|
||||
lower1c = 'a'
|
||||
case ('B')
|
||||
lower1c = 'b'
|
||||
case ('C')
|
||||
lower1c = 'c'
|
||||
case ('D')
|
||||
lower1c = 'd'
|
||||
case ('E')
|
||||
lower1c = 'e'
|
||||
case ('F')
|
||||
lower1c = 'f'
|
||||
case ('G')
|
||||
lower1c = 'g'
|
||||
case ('H')
|
||||
lower1c = 'h'
|
||||
case ('I')
|
||||
lower1c = 'i'
|
||||
case ('J')
|
||||
lower1c = 'j'
|
||||
case ('K')
|
||||
lower1c = 'k'
|
||||
case ('L')
|
||||
lower1c = 'l'
|
||||
case ('M')
|
||||
lower1c = 'm'
|
||||
case ('N')
|
||||
lower1c = 'n'
|
||||
case ('O')
|
||||
lower1c = 'o'
|
||||
case ('P')
|
||||
lower1c = 'p'
|
||||
case ('Q')
|
||||
lower1c = 'q'
|
||||
case ('R')
|
||||
lower1c = 'r'
|
||||
case ('S')
|
||||
lower1c = 's'
|
||||
case ('T')
|
||||
lower1c = 't'
|
||||
case ('U')
|
||||
lower1c = 'u'
|
||||
case ('V')
|
||||
lower1c = 'v'
|
||||
case ('W')
|
||||
lower1c = 'w'
|
||||
case ('X')
|
||||
lower1c = 'x'
|
||||
case ('Y')
|
||||
lower1c = 'y'
|
||||
case ('Z')
|
||||
lower1c = 'z'
|
||||
case default
|
||||
lower1c = ch
|
||||
end select
|
||||
end function lower1c
|
||||
|
||||
function upper1c(ch)
|
||||
character(len=1), intent(in) :: ch
|
||||
character(len=1) :: upper1c
|
||||
|
||||
select case(ch)
|
||||
case ('a')
|
||||
upper1c = 'A'
|
||||
case ('b')
|
||||
upper1c = 'B'
|
||||
case ('c')
|
||||
upper1c = 'C'
|
||||
case ('d')
|
||||
upper1c = 'D'
|
||||
case ('e')
|
||||
upper1c = 'E'
|
||||
case ('f')
|
||||
upper1c = 'F'
|
||||
case ('g')
|
||||
upper1c = 'G'
|
||||
case ('h')
|
||||
upper1c = 'H'
|
||||
case ('i')
|
||||
upper1c = 'I'
|
||||
case ('j')
|
||||
upper1c = 'J'
|
||||
case ('k')
|
||||
upper1c = 'K'
|
||||
case ('l')
|
||||
upper1c = 'L'
|
||||
case ('m')
|
||||
upper1c = 'M'
|
||||
case ('n')
|
||||
upper1c = 'N'
|
||||
case ('o')
|
||||
upper1c = 'O'
|
||||
case ('p')
|
||||
upper1c = 'P'
|
||||
case ('q')
|
||||
upper1c = 'Q'
|
||||
case ('r')
|
||||
upper1c = 'R'
|
||||
case ('s')
|
||||
upper1c = 'S'
|
||||
case ('t')
|
||||
upper1c = 'T'
|
||||
case ('u')
|
||||
upper1c = 'U'
|
||||
case ('v')
|
||||
upper1c = 'V'
|
||||
case ('w')
|
||||
upper1c = 'W'
|
||||
case ('x')
|
||||
upper1c = 'X'
|
||||
case ('y')
|
||||
upper1c = 'Y'
|
||||
case ('z')
|
||||
upper1c = 'Z'
|
||||
case default
|
||||
upper1c = ch
|
||||
end select
|
||||
end function upper1c
|
||||
|
||||
|
||||
end module psb_string_mod
|
||||
|
||||
@@ -34,6 +34,22 @@ Module psb_tools_mod
|
||||
use psb_spmat_type
|
||||
|
||||
|
||||
interface psb_cd_set_bld
|
||||
subroutine psb_cd_set_bld(desc,info)
|
||||
use psb_descriptor_type
|
||||
type(psb_desc_type), intent(inout) :: desc
|
||||
integer :: info
|
||||
end subroutine psb_cd_set_bld
|
||||
end interface
|
||||
|
||||
interface psb_cd_set_ovl_bld
|
||||
subroutine psb_cd_set_ovl_bld(desc,info)
|
||||
use psb_descriptor_type
|
||||
type(psb_desc_type), intent(inout) :: desc
|
||||
integer :: info
|
||||
end subroutine psb_cd_set_ovl_bld
|
||||
end interface
|
||||
|
||||
interface psb_cd_reinit
|
||||
Subroutine psb_cd_reinit(desc,info)
|
||||
use psb_descriptor_type
|
||||
@@ -977,7 +993,7 @@ contains
|
||||
|
||||
end subroutine psb_get_boundary
|
||||
|
||||
subroutine psb_cdall(ictxt, desc, info,mg,ng,parts,vg,vl,flag,nl,repl)
|
||||
subroutine psb_cdall(ictxt, desc, info,mg,ng,parts,vg,vl,flag,nl,repl, globalcheck)
|
||||
use psb_descriptor_type
|
||||
use psb_serial_mod
|
||||
use psb_const_mod
|
||||
@@ -987,11 +1003,11 @@ contains
|
||||
include 'parts.fh'
|
||||
Integer, intent(in) :: mg,ng,ictxt, vg(:), vl(:),nl
|
||||
integer, intent(in) :: flag
|
||||
logical, intent(in) :: repl
|
||||
logical, intent(in) :: repl, globalcheck
|
||||
integer, intent(out) :: info
|
||||
type(psb_desc_type), intent(out) :: desc
|
||||
|
||||
optional :: mg,ng,parts,vg,vl,flag,nl,repl
|
||||
optional :: mg,ng,parts,vg,vl,flag,nl,repl, globalcheck
|
||||
|
||||
interface
|
||||
subroutine psb_cdals(m, n, parts, ictxt, desc, info)
|
||||
@@ -1008,12 +1024,13 @@ contains
|
||||
integer, intent(out) :: info
|
||||
Type(psb_desc_type), intent(out) :: desc
|
||||
end subroutine psb_cdalv
|
||||
subroutine psb_cd_inloc(v, ictxt, desc, info)
|
||||
subroutine psb_cd_inloc(v, ictxt, desc, info, globalcheck)
|
||||
use psb_descriptor_type
|
||||
implicit None
|
||||
Integer, intent(in) :: ictxt, v(:)
|
||||
integer, intent(out) :: info
|
||||
type(psb_desc_type), intent(out) :: desc
|
||||
logical, intent(in), optional :: globalcheck
|
||||
end subroutine psb_cd_inloc
|
||||
subroutine psb_cdrep(m, ictxt, desc,info)
|
||||
use psb_descriptor_type
|
||||
@@ -1079,7 +1096,7 @@ contains
|
||||
call psb_cdalv(vg, ictxt, desc, info, flag=flag_)
|
||||
|
||||
else if (present(vl)) then
|
||||
call psb_cd_inloc(vl,ictxt,desc,info)
|
||||
call psb_cd_inloc(vl,ictxt,desc,info, globalcheck=globalcheck)
|
||||
|
||||
else if (present(nl)) then
|
||||
allocate(itmpsz(0:np-1),stat=info)
|
||||
@@ -1096,7 +1113,7 @@ contains
|
||||
do i=0, me-1
|
||||
nlp = nlp + itmpsz(i)
|
||||
end do
|
||||
call psb_cd_inloc((/(i,i=nlp+1,nlp+nl)/),ictxt,desc,info)
|
||||
call psb_cd_inloc((/(i,i=nlp+1,nlp+nl)/),ictxt,desc,info,globalcheck=.false.)
|
||||
|
||||
endif
|
||||
|
||||
|
||||
@@ -502,32 +502,40 @@ module psi_mod
|
||||
|
||||
interface psi_idx_cnv
|
||||
subroutine psi_idx_cnv1(nv,idxin,desc,info,mask,owned)
|
||||
use psb_descriptor_type, only : psb_desc_type, psb_spk_, psb_dpk_
|
||||
use psb_descriptor_type, only : psb_desc_type
|
||||
integer, intent(in) :: nv
|
||||
integer, intent(inout) :: idxin(:)
|
||||
type(psb_desc_type), intent(in) :: desc
|
||||
integer, intent(out) :: info
|
||||
logical, intent(in), optional, target :: mask(:)
|
||||
logical, intent(in), optional :: mask(:)
|
||||
logical, intent(in), optional :: owned
|
||||
end subroutine psi_idx_cnv1
|
||||
subroutine psi_idx_cnv2(nv,idxin,idxout,desc,info,mask,owned)
|
||||
use psb_descriptor_type, only : psb_desc_type, psb_spk_, psb_dpk_
|
||||
use psb_descriptor_type, only : psb_desc_type
|
||||
integer, intent(in) :: nv, idxin(:)
|
||||
integer, intent(out) :: idxout(:)
|
||||
type(psb_desc_type), intent(in) :: desc
|
||||
integer, intent(out) :: info
|
||||
logical, intent(in), optional, target :: mask(:)
|
||||
logical, intent(in), optional :: mask(:)
|
||||
logical, intent(in), optional :: owned
|
||||
end subroutine psi_idx_cnv2
|
||||
subroutine psi_idx_cnvs(idxin,idxout,desc,info,mask,owned)
|
||||
use psb_descriptor_type, only : psb_desc_type, psb_spk_, psb_dpk_
|
||||
use psb_descriptor_type, only : psb_desc_type
|
||||
integer, intent(in) :: idxin
|
||||
integer, intent(out) :: idxout
|
||||
type(psb_desc_type), intent(in) :: desc
|
||||
integer, intent(out) :: info
|
||||
logical, intent(in), optional, target :: mask
|
||||
logical, intent(in), optional :: mask
|
||||
logical, intent(in), optional :: owned
|
||||
end subroutine psi_idx_cnvs
|
||||
subroutine psi_idx_cnvs1(idxin,desc,info,mask,owned)
|
||||
use psb_descriptor_type, only : psb_desc_type
|
||||
integer, intent(inout) :: idxin
|
||||
type(psb_desc_type), intent(in) :: desc
|
||||
integer, intent(out) :: info
|
||||
logical, intent(in), optional :: mask
|
||||
logical, intent(in), optional :: owned
|
||||
end subroutine psi_idx_cnvs1
|
||||
end interface
|
||||
|
||||
interface psi_idx_ins_cnv
|
||||
@@ -537,7 +545,7 @@ module psi_mod
|
||||
integer, intent(inout) :: idxin(:)
|
||||
type(psb_desc_type), intent(inout) :: desc
|
||||
integer, intent(out) :: info
|
||||
logical, intent(in), optional, target :: mask(:)
|
||||
logical, intent(in), optional :: mask(:)
|
||||
end subroutine psi_idx_ins_cnv1
|
||||
subroutine psi_idx_ins_cnv2(nv,idxin,idxout,desc,info,mask)
|
||||
use psb_descriptor_type, only : psb_desc_type, psb_spk_, psb_dpk_
|
||||
@@ -545,16 +553,23 @@ module psi_mod
|
||||
integer, intent(out) :: idxout(:)
|
||||
type(psb_desc_type), intent(inout) :: desc
|
||||
integer, intent(out) :: info
|
||||
logical, intent(in), optional, target :: mask(:)
|
||||
logical, intent(in), optional :: mask(:)
|
||||
end subroutine psi_idx_ins_cnv2
|
||||
subroutine psi_idx_ins_cnvs(idxin,idxout,desc,info,mask)
|
||||
subroutine psi_idx_ins_cnvs2(idxin,idxout,desc,info,mask)
|
||||
use psb_descriptor_type, only : psb_desc_type, psb_spk_, psb_dpk_
|
||||
integer, intent(in) :: idxin
|
||||
integer, intent(out) :: idxout
|
||||
type(psb_desc_type), intent(inout) :: desc
|
||||
integer, intent(out) :: info
|
||||
logical, intent(in), optional, target :: mask
|
||||
end subroutine psi_idx_ins_cnvs
|
||||
logical, intent(in), optional :: mask
|
||||
end subroutine psi_idx_ins_cnvs2
|
||||
subroutine psi_idx_ins_cnvs1(idxin,desc,info,mask)
|
||||
use psb_descriptor_type, only : psb_desc_type, psb_spk_, psb_dpk_
|
||||
integer, intent(inout) :: idxin
|
||||
type(psb_desc_type), intent(inout) :: desc
|
||||
integer, intent(out) :: info
|
||||
logical, intent(in), optional :: mask
|
||||
end subroutine psi_idx_ins_cnvs1
|
||||
end interface
|
||||
|
||||
interface psi_cnv_dsc
|
||||
@@ -562,7 +577,9 @@ module psi_mod
|
||||
end interface
|
||||
|
||||
interface psi_inner_cnv
|
||||
module procedure psi_inner_cnv1, psi_inner_cnv2
|
||||
module procedure psi_inner_cnv1, psi_inner_cnv2,&
|
||||
& psi_inner_cnvs, psi_inner_cnvs2
|
||||
! & psi_inner_cnv1_mask, psi_inner_cnv2_mask,&
|
||||
end interface
|
||||
|
||||
interface psi_ovrl_upd
|
||||
@@ -729,10 +746,9 @@ contains
|
||||
end subroutine psi_cnv_dsc
|
||||
|
||||
|
||||
|
||||
subroutine psi_inner_cnv1(n,x,hashmask,hashv,glb_lc)
|
||||
integer, intent(in) :: n,hashmask,hashv(0:),glb_lc(:,:)
|
||||
integer, intent(inout) :: x(:)
|
||||
subroutine psi_inner_cnvs(x,hashmask,hashv,glb_lc)
|
||||
integer, intent(in) :: hashmask,hashv(0:),glb_lc(:,:)
|
||||
integer, intent(inout) :: x
|
||||
|
||||
integer :: i, ih, key, idx,nh,tmp,lb,ub,lm
|
||||
!
|
||||
@@ -743,41 +759,164 @@ contains
|
||||
! for a width of psb_hash_bits
|
||||
!
|
||||
|
||||
do i=1, n
|
||||
key = x(i)
|
||||
ih = iand(key,hashmask)
|
||||
idx = hashv(ih)
|
||||
nh = hashv(ih+1) - hashv(ih)
|
||||
if (nh > 0) then
|
||||
tmp = -1
|
||||
lb = idx
|
||||
ub = idx+nh-1
|
||||
do
|
||||
if (lb>ub) exit
|
||||
lm = (lb+ub)/2
|
||||
if (key==glb_lc(lm,1)) then
|
||||
tmp = lm
|
||||
exit
|
||||
else if (key<glb_lc(lm,1)) then
|
||||
ub = lm - 1
|
||||
else
|
||||
lb = lm + 1
|
||||
key = x
|
||||
ih = iand(key,hashmask)
|
||||
idx = hashv(ih)
|
||||
nh = hashv(ih+1) - hashv(ih)
|
||||
if (nh > 0) then
|
||||
tmp = -1
|
||||
lb = idx
|
||||
ub = idx+nh-1
|
||||
do
|
||||
if (lb>ub) exit
|
||||
lm = (lb+ub)/2
|
||||
if (key==glb_lc(lm,1)) then
|
||||
tmp = lm
|
||||
exit
|
||||
else if (key<glb_lc(lm,1)) then
|
||||
ub = lm - 1
|
||||
else
|
||||
lb = lm + 1
|
||||
end if
|
||||
end do
|
||||
else
|
||||
tmp = -1
|
||||
end if
|
||||
if (tmp > 0) then
|
||||
x = glb_lc(tmp,2)
|
||||
else
|
||||
x = tmp
|
||||
end if
|
||||
end subroutine psi_inner_cnvs
|
||||
|
||||
subroutine psi_inner_cnvs2(x,y,hashmask,hashv,glb_lc)
|
||||
integer, intent(in) :: hashmask,hashv(0:),glb_lc(:,:)
|
||||
integer, intent(in) :: x
|
||||
integer, intent(out) :: y
|
||||
|
||||
integer :: i, ih, key, idx,nh,tmp,lb,ub,lm
|
||||
!
|
||||
! When a large descriptor is assembled the indices
|
||||
! are kept in a (hashed) list of ordered lists.
|
||||
! Thus we first hash the index, then we do a binary search on the
|
||||
! ordered sublist. The hashing is based on the low-order bits
|
||||
! for a width of psb_hash_bits
|
||||
!
|
||||
|
||||
key = x
|
||||
ih = iand(key,hashmask)
|
||||
idx = hashv(ih)
|
||||
nh = hashv(ih+1) - hashv(ih)
|
||||
if (nh > 0) then
|
||||
tmp = -1
|
||||
lb = idx
|
||||
ub = idx+nh-1
|
||||
do
|
||||
if (lb>ub) exit
|
||||
lm = (lb+ub)/2
|
||||
if (key==glb_lc(lm,1)) then
|
||||
tmp = lm
|
||||
exit
|
||||
else if (key<glb_lc(lm,1)) then
|
||||
ub = lm - 1
|
||||
else
|
||||
lb = lm + 1
|
||||
end if
|
||||
end do
|
||||
else
|
||||
tmp = -1
|
||||
end if
|
||||
if (tmp > 0) then
|
||||
y = glb_lc(tmp,2)
|
||||
else
|
||||
y = tmp
|
||||
end if
|
||||
end subroutine psi_inner_cnvs2
|
||||
|
||||
|
||||
subroutine psi_inner_cnv1(n,x,hashmask,hashv,glb_lc,mask)
|
||||
integer, intent(in) :: n,hashmask,hashv(0:),glb_lc(:,:)
|
||||
logical, intent(in), optional :: mask(:)
|
||||
integer, intent(inout) :: x(:)
|
||||
|
||||
integer :: i, ih, key, idx,nh,tmp,lb,ub,lm
|
||||
!
|
||||
! When a large descriptor is assembled the indices
|
||||
! are kept in a (hashed) list of ordered lists.
|
||||
! Thus we first hash the index, then we do a binary search on the
|
||||
! ordered sublist. The hashing is based on the low-order bits
|
||||
! for a width of psb_hash_bits
|
||||
!
|
||||
if (present(mask)) then
|
||||
do i=1, n
|
||||
if (mask(i)) then
|
||||
key = x(i)
|
||||
ih = iand(key,hashmask)
|
||||
idx = hashv(ih)
|
||||
nh = hashv(ih+1) - hashv(ih)
|
||||
if (nh > 0) then
|
||||
tmp = -1
|
||||
lb = idx
|
||||
ub = idx+nh-1
|
||||
do
|
||||
if (lb>ub) exit
|
||||
lm = (lb+ub)/2
|
||||
if (key==glb_lc(lm,1)) then
|
||||
tmp = lm
|
||||
exit
|
||||
else if (key<glb_lc(lm,1)) then
|
||||
ub = lm - 1
|
||||
else
|
||||
lb = lm + 1
|
||||
end if
|
||||
end do
|
||||
else
|
||||
tmp = -1
|
||||
end if
|
||||
end do
|
||||
else
|
||||
tmp = -1
|
||||
end if
|
||||
if (tmp > 0) then
|
||||
x(i) = glb_lc(tmp,2)
|
||||
else
|
||||
x(i) = tmp
|
||||
end if
|
||||
end do
|
||||
if (tmp > 0) then
|
||||
x(i) = glb_lc(tmp,2)
|
||||
else
|
||||
x(i) = tmp
|
||||
end if
|
||||
end if
|
||||
end do
|
||||
else
|
||||
do i=1, n
|
||||
key = x(i)
|
||||
ih = iand(key,hashmask)
|
||||
idx = hashv(ih)
|
||||
nh = hashv(ih+1) - hashv(ih)
|
||||
if (nh > 0) then
|
||||
tmp = -1
|
||||
lb = idx
|
||||
ub = idx+nh-1
|
||||
do
|
||||
if (lb>ub) exit
|
||||
lm = (lb+ub)/2
|
||||
if (key==glb_lc(lm,1)) then
|
||||
tmp = lm
|
||||
exit
|
||||
else if (key<glb_lc(lm,1)) then
|
||||
ub = lm - 1
|
||||
else
|
||||
lb = lm + 1
|
||||
end if
|
||||
end do
|
||||
else
|
||||
tmp = -1
|
||||
end if
|
||||
if (tmp > 0) then
|
||||
x(i) = glb_lc(tmp,2)
|
||||
else
|
||||
x(i) = tmp
|
||||
end if
|
||||
end do
|
||||
end if
|
||||
end subroutine psi_inner_cnv1
|
||||
|
||||
|
||||
subroutine psi_inner_cnv2(n,x,y,hashmask,hashv,glb_lc)
|
||||
subroutine psi_inner_cnv2(n,x,y,hashmask,hashv,glb_lc,mask)
|
||||
integer, intent(in) :: n, hashmask,hashv(0:),glb_lc(:,:)
|
||||
logical, intent(in),optional :: mask(:)
|
||||
integer, intent(in) :: x(:)
|
||||
integer, intent(out) :: y(:)
|
||||
|
||||
@@ -789,40 +928,77 @@ contains
|
||||
! ordered sublist. The hashing is based on the low-order bits
|
||||
! for a width of psb_hash_bits
|
||||
!
|
||||
|
||||
do i=1, n
|
||||
key = x(i)
|
||||
ih = iand(key,hashmask)
|
||||
if (ih > ubound(hashv,1) ) then
|
||||
write(0,*) ' In inner cnv: ',ih,ubound(hashv)
|
||||
end if
|
||||
idx = hashv(ih)
|
||||
nh = hashv(ih+1) - hashv(ih)
|
||||
if (nh > 0) then
|
||||
tmp = -1
|
||||
lb = idx
|
||||
ub = idx+nh-1
|
||||
do
|
||||
if (lb>ub) exit
|
||||
lm = (lb+ub)/2
|
||||
if (key==glb_lc(lm,1)) then
|
||||
tmp = lm
|
||||
exit
|
||||
else if (key<glb_lc(lm,1)) then
|
||||
ub = lm - 1
|
||||
else
|
||||
lb = lm + 1
|
||||
if (present(mask)) then
|
||||
do i=1, n
|
||||
if (mask(i)) then
|
||||
key = x(i)
|
||||
ih = iand(key,hashmask)
|
||||
if (ih > ubound(hashv,1) ) then
|
||||
write(0,*) ' In inner cnv: ',ih,ubound(hashv)
|
||||
end if
|
||||
end do
|
||||
else
|
||||
tmp = -1
|
||||
end if
|
||||
if (tmp > 0) then
|
||||
y(i) = glb_lc(tmp,2)
|
||||
else
|
||||
y(i) = tmp
|
||||
end if
|
||||
end do
|
||||
idx = hashv(ih)
|
||||
nh = hashv(ih+1) - hashv(ih)
|
||||
if (nh > 0) then
|
||||
tmp = -1
|
||||
lb = idx
|
||||
ub = idx+nh-1
|
||||
do
|
||||
if (lb>ub) exit
|
||||
lm = (lb+ub)/2
|
||||
if (key==glb_lc(lm,1)) then
|
||||
tmp = lm
|
||||
exit
|
||||
else if (key<glb_lc(lm,1)) then
|
||||
ub = lm - 1
|
||||
else
|
||||
lb = lm + 1
|
||||
end if
|
||||
end do
|
||||
else
|
||||
tmp = -1
|
||||
end if
|
||||
if (tmp > 0) then
|
||||
y(i) = glb_lc(tmp,2)
|
||||
else
|
||||
y(i) = tmp
|
||||
end if
|
||||
end if
|
||||
end do
|
||||
else
|
||||
do i=1, n
|
||||
key = x(i)
|
||||
ih = iand(key,hashmask)
|
||||
if (ih > ubound(hashv,1) ) then
|
||||
write(0,*) ' In inner cnv: ',ih,ubound(hashv)
|
||||
end if
|
||||
idx = hashv(ih)
|
||||
nh = hashv(ih+1) - hashv(ih)
|
||||
if (nh > 0) then
|
||||
tmp = -1
|
||||
lb = idx
|
||||
ub = idx+nh-1
|
||||
do
|
||||
if (lb>ub) exit
|
||||
lm = (lb+ub)/2
|
||||
if (key==glb_lc(lm,1)) then
|
||||
tmp = lm
|
||||
exit
|
||||
else if (key<glb_lc(lm,1)) then
|
||||
ub = lm - 1
|
||||
else
|
||||
lb = lm + 1
|
||||
end if
|
||||
end do
|
||||
else
|
||||
tmp = -1
|
||||
end if
|
||||
if (tmp > 0) then
|
||||
y(i) = glb_lc(tmp,2)
|
||||
else
|
||||
y(i) = tmp
|
||||
end if
|
||||
end do
|
||||
end if
|
||||
end subroutine psi_inner_cnv2
|
||||
|
||||
subroutine psi_sovrl_updr1(x,desc_a,update,info)
|
||||
@@ -1688,14 +1864,14 @@ contains
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
|
||||
if (size(x,2) /= size(xs,2)) then
|
||||
info = 4001
|
||||
call psb_errpush(info,name, a_err='Mismacth columns X vs XS')
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
|
||||
|
||||
|
||||
isz = size(desc_a%ovrlap_elem,1)
|
||||
|
||||
do i=1, isz
|
||||
@@ -1892,14 +2068,14 @@ contains
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
|
||||
if (size(x,2) /= size(xs,2)) then
|
||||
info = 4001
|
||||
call psb_errpush(info,name, a_err='Mismacth columns X vs XS')
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
|
||||
|
||||
|
||||
isz = size(desc_a%ovrlap_elem,1)
|
||||
|
||||
do i=1, isz
|
||||
@@ -1975,7 +2151,7 @@ contains
|
||||
subroutine psi_covrl_restrr1(x,xs,desc_a,info)
|
||||
|
||||
implicit none
|
||||
|
||||
|
||||
complex(psb_spk_), intent(inout) :: x(:)
|
||||
complex(psb_spk_) :: xs(:)
|
||||
type(psb_desc_type), intent(in) :: desc_a
|
||||
@@ -2095,14 +2271,14 @@ contains
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
|
||||
if (size(x,2) /= size(xs,2)) then
|
||||
info = 4001
|
||||
call psb_errpush(info,name, a_err='Mismacth columns X vs XS')
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
|
||||
|
||||
|
||||
isz = size(desc_a%ovrlap_elem,1)
|
||||
|
||||
do i=1, isz
|
||||
@@ -2180,7 +2356,7 @@ contains
|
||||
subroutine psi_zovrl_restrr1(x,xs,desc_a,info)
|
||||
|
||||
implicit none
|
||||
|
||||
|
||||
complex(psb_dpk_), intent(inout) :: x(:)
|
||||
complex(psb_dpk_) :: xs(:)
|
||||
type(psb_desc_type), intent(in) :: desc_a
|
||||
@@ -2301,14 +2477,14 @@ contains
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
|
||||
if (size(x,2) /= size(xs,2)) then
|
||||
info = 4001
|
||||
call psb_errpush(info,name, a_err='Mismacth columns X vs XS')
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
|
||||
|
||||
|
||||
isz = size(desc_a%ovrlap_elem,1)
|
||||
|
||||
do i=1, isz
|
||||
@@ -2509,14 +2685,14 @@ contains
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
|
||||
if (size(x,2) /= size(xs,2)) then
|
||||
info = 4001
|
||||
call psb_errpush(info,name, a_err='Mismacth columns X vs XS')
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
|
||||
|
||||
|
||||
isz = size(desc_a%ovrlap_elem,1)
|
||||
|
||||
do i=1, isz
|
||||
|
||||
@@ -578,6 +578,8 @@ subroutine psb_dspmv(alpha,a,x,beta,y,desc_a,info,&
|
||||
call psi_swapdata(ior(psb_swap_send_,psb_swap_recv_),&
|
||||
& dzero,x,desc_a,iwork,info,data=psb_comm_halo_)
|
||||
end if
|
||||
! Just for fun
|
||||
call a%spmm(alpha,x,beta,y,info)
|
||||
|
||||
! local Matrix-vector product
|
||||
call psb_csmm(alpha,a,x(iix:lldx),beta,y(iiy:lldy),info)
|
||||
|
||||
@@ -170,6 +170,7 @@ C
|
||||
NAME = 'CSWMM\0'
|
||||
IERROR = 0
|
||||
CALL FCPSB_ERRACTIONSAVE(ERR_ACT)
|
||||
WORK(1) = czero
|
||||
|
||||
IF (psb_toupper(FIDA(1:3)).EQ.'CSR') THEN
|
||||
C
|
||||
|
||||
@@ -177,6 +177,7 @@ C .. Executable Statements ..
|
||||
NAME = 'CSWSM\0'
|
||||
IERROR = 0
|
||||
CALL FCPSB_ERRACTIONSAVE(ERR_ACT)
|
||||
WORK(1) = czero
|
||||
C
|
||||
C Check for identity matrix
|
||||
C
|
||||
|
||||
@@ -162,7 +162,7 @@ C
|
||||
NAME = 'DSWMM\0'
|
||||
IERROR = 0
|
||||
CALL FCPSB_ERRACTIONSAVE(ERR_ACT)
|
||||
|
||||
WORK(1) = dzero
|
||||
C Switching on FIDA: proper sparse BLAS routine is selected
|
||||
C according to data structure
|
||||
C
|
||||
|
||||
@@ -181,6 +181,7 @@ C .. Executable Statements ..
|
||||
NAME = 'DSWSM'
|
||||
IERROR = 0
|
||||
CALL FCPSB_ERRACTIONSAVE(ERR_ACT)
|
||||
WORK(1) = dzero
|
||||
debug_unit = psb_get_debug_unit()
|
||||
debug_level = psb_get_debug_level()
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ C
|
||||
NAME = 'DSWMM\0'
|
||||
IERROR = 0
|
||||
CALL FCPSB_ERRACTIONSAVE(ERR_ACT)
|
||||
|
||||
WORK(1) = szero
|
||||
C Switching on FIDA: proper sparse BLAS routine is selected
|
||||
C according to data structure
|
||||
C
|
||||
|
||||
@@ -180,6 +180,7 @@ C .. Executable Statements ..
|
||||
NAME = 'DSWSM'
|
||||
IERROR = 0
|
||||
CALL FCPSB_ERRACTIONSAVE(ERR_ACT)
|
||||
work(1) = szero
|
||||
debug_unit = psb_get_debug_unit()
|
||||
debug_level = psb_get_debug_level()
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ C
|
||||
NAME = 'ZSWMM\0'
|
||||
IERROR = 0
|
||||
CALL FCPSB_ERRACTIONSAVE(ERR_ACT)
|
||||
|
||||
WORK(1) = zzero
|
||||
IF (psb_toupper(FIDA(1:3)).EQ.'CSR') THEN
|
||||
C
|
||||
C A, IA1, IA2 ---> AR, JA, IA
|
||||
|
||||
@@ -177,6 +177,7 @@ C .. Executable Statements ..
|
||||
NAME = 'ZSWSM\0'
|
||||
IERROR = 0
|
||||
CALL FCPSB_ERRACTIONSAVE(ERR_ACT)
|
||||
WORK(1) = zzero
|
||||
C
|
||||
C Check for identity matrix
|
||||
C
|
||||
|
||||
@@ -18,7 +18,7 @@ FOBJS = psb_sallc.o psb_sasb.o \
|
||||
psb_zspins.o psb_zsprn.o \
|
||||
psb_cspalloc.o psb_cspasb.o psb_cspfree.o\
|
||||
psb_callc.o psb_casb.o psb_cfree.o psb_cins.o \
|
||||
psb_cspins.o psb_csprn.o psb_map.o psb_inter_desc.o
|
||||
psb_cspins.o psb_csprn.o psb_map.o psb_inter_desc.o psb_cd_set_bld.o
|
||||
|
||||
MPFOBJS = psb_ssphalo.o psb_csphalo.o psb_dsphalo.o psb_zsphalo.o psb_icdasb.o \
|
||||
psb_dcdbldext.o psb_zcdbldext.o psb_scdbldext.o psb_ccdbldext.o
|
||||
|
||||
@@ -123,7 +123,8 @@ Subroutine psb_ccdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
Call psb_info(ictxt, me, np)
|
||||
|
||||
If (debug_level >= psb_debug_outer_) &
|
||||
& Write(debug_unit,*) me,' ',trim(name),': start',novr
|
||||
& Write(debug_unit,*) me,' ',trim(name),&
|
||||
& ': start',novr
|
||||
|
||||
if (present(extype)) then
|
||||
extype_ = extype
|
||||
@@ -145,7 +146,8 @@ Subroutine psb_ccdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
endif
|
||||
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),':Calling desccpy'
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ':Calling desccpy'
|
||||
call psb_cdcpy(desc_a,desc_ov,info)
|
||||
if (info /= 0) then
|
||||
info=4010
|
||||
@@ -154,7 +156,9 @@ Subroutine psb_ccdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),':From desccpy'
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ':From desccpy'
|
||||
|
||||
if (novr==0) then
|
||||
!
|
||||
! Just copy the input.
|
||||
@@ -165,7 +169,8 @@ Subroutine psb_ccdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
|
||||
|
||||
If (debug_level >= psb_debug_outer_)then
|
||||
Write(debug_unit,*) me,' ',trim(name),':BEGIN ',nhalo
|
||||
Write(debug_unit,*) me,' ',trim(name),&
|
||||
& ':BEGIN ',nhalo
|
||||
call psb_barrier(ictxt)
|
||||
endif
|
||||
|
||||
@@ -180,7 +185,7 @@ Subroutine psb_ccdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
lworks = ((nztot+m-1)/m)*nhalo
|
||||
lworkr = ((nztot+m-1)/m)*nhalo
|
||||
else
|
||||
info=-1
|
||||
info = -1
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
@@ -235,12 +240,12 @@ Subroutine psb_ccdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
tmp_ovr_idx(:) = -1
|
||||
orig_ovr(:) = -1
|
||||
tmp_halo(:) = -1
|
||||
counter_e = 1
|
||||
tot_recv = 0
|
||||
counter_t = 1
|
||||
counter_h = 1
|
||||
counter_o = 1
|
||||
cntov_o = 1
|
||||
counter_e = 1
|
||||
tot_recv = 0
|
||||
counter_t = 1
|
||||
counter_h = 1
|
||||
counter_o = 1
|
||||
cntov_o = 1
|
||||
! Init overlap with desc_a%ovrlap (if any)
|
||||
counter = 1
|
||||
Do While (desc_a%ovrlap_index(counter) /= -1)
|
||||
@@ -301,7 +306,8 @@ Subroutine psb_ccdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
Do i_ovr = 1, novr
|
||||
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),':Running on overlap level ',i_ovr,' of ',novr
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ':Running on overlap level ',i_ovr,' of ',novr
|
||||
|
||||
!
|
||||
! At this point, halo contains a valid halo corresponding to the
|
||||
@@ -333,7 +339,8 @@ Subroutine psb_ccdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
end If
|
||||
tot_recv=tot_recv+n_elem_recv
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),': tot_recv:',proc,n_elem_recv,tot_recv
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ': tot_recv:',proc,n_elem_recv,tot_recv
|
||||
!
|
||||
!
|
||||
! The format of the halo vector exists in two forms: 1. Temporary
|
||||
@@ -368,10 +375,10 @@ Subroutine psb_ccdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
tmp_ovr_idx(counter_o)=proc
|
||||
tmp_ovr_idx(counter_o+1)=1
|
||||
tmp_ovr_idx(counter_o+2)=gidx
|
||||
tmp_ovr_idx(counter_o+3)=-1
|
||||
tmp_ovr_idx(counter_o) = proc
|
||||
tmp_ovr_idx(counter_o+1) = 1
|
||||
tmp_ovr_idx(counter_o+2) = gidx
|
||||
tmp_ovr_idx(counter_o+3) = -1
|
||||
counter_o=counter_o+3
|
||||
call psb_ensure_size((counter_h+3),tmp_halo,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
@@ -380,10 +387,10 @@ Subroutine psb_ccdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
tmp_halo(counter_h)=proc
|
||||
tmp_halo(counter_h+1)=1
|
||||
tmp_halo(counter_h+2)=idx
|
||||
tmp_halo(counter_h+3)=-1
|
||||
tmp_halo(counter_h) = proc
|
||||
tmp_halo(counter_h+1) = 1
|
||||
tmp_halo(counter_h+2) = idx
|
||||
tmp_halo(counter_h+3) = -1
|
||||
|
||||
counter_h=counter_h+3
|
||||
|
||||
@@ -411,10 +418,10 @@ Subroutine psb_ccdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
tmp_ovr_idx(counter_o)=proc
|
||||
tmp_ovr_idx(counter_o+1)=1
|
||||
tmp_ovr_idx(counter_o+2)=gidx
|
||||
tmp_ovr_idx(counter_o+3)=-1
|
||||
tmp_ovr_idx(counter_o) = proc
|
||||
tmp_ovr_idx(counter_o+1) = 1
|
||||
tmp_ovr_idx(counter_o+2) = gidx
|
||||
tmp_ovr_idx(counter_o+3) = -1
|
||||
counter_o=counter_o+3
|
||||
|
||||
!
|
||||
@@ -466,6 +473,7 @@ Subroutine psb_ccdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ':Checktmp_o_i Loop Mid2',tmp_ovr_idx(1:10)
|
||||
|
||||
sdsz(proc+1) = tot_elem
|
||||
idxs = idxs + tot_elem
|
||||
end if
|
||||
@@ -517,7 +525,7 @@ Subroutine psb_ccdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
call psb_errpush(info,name,a_err=ch_err)
|
||||
goto 9999
|
||||
end if
|
||||
lworkr=max(iszr,1)
|
||||
lworkr = max(iszr,1)
|
||||
end if
|
||||
|
||||
call mpi_alltoallv(works,sdsz,bsdindx,mpi_integer,&
|
||||
@@ -549,12 +557,15 @@ Subroutine psb_ccdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
works(j) = workr(i)
|
||||
end if
|
||||
end do
|
||||
! Eliminate duplicates from request
|
||||
call psb_msort_unique(works(1:j),iszs)
|
||||
|
||||
!
|
||||
! fnd_owner on desc_a because we want the procs who
|
||||
! owned the rows from the beginning!
|
||||
!
|
||||
call psi_fnd_owner(iszs,works,temp,desc_a,info)
|
||||
n_col=psb_cd_get_local_cols(desc_ov)
|
||||
n_col = psb_cd_get_local_cols(desc_ov)
|
||||
|
||||
do i=1,iszs
|
||||
idx = works(i)
|
||||
@@ -575,11 +586,11 @@ Subroutine psb_ccdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
t_halo_in(counter_t)=proc_id
|
||||
t_halo_in(counter_t+1)=1
|
||||
t_halo_in(counter_t+2)=lidx
|
||||
t_halo_in(counter_t+3)=-1
|
||||
counter_t=counter_t+3
|
||||
t_halo_in(counter_t) = proc_id
|
||||
t_halo_in(counter_t+1) = 1
|
||||
t_halo_in(counter_t+2) = lidx
|
||||
t_halo_in(counter_t+3) = -1
|
||||
counter_t = counter_t+3
|
||||
endif
|
||||
end Do
|
||||
n_col = psb_cd_get_local_cols(desc_ov)
|
||||
@@ -596,8 +607,8 @@ Subroutine psb_ccdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
! we receive them guarantees that all indices for HALO(I)
|
||||
! will be less than those for HALO(J) whenever I<J
|
||||
!
|
||||
n_col=n_col+1
|
||||
proc_id=-desc_ov%glob_to_loc(idx)-np-1
|
||||
n_col = n_col+1
|
||||
proc_id = -desc_ov%glob_to_loc(idx)-np-1
|
||||
call psb_ensure_size(n_col,desc_ov%loc_to_glob,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
info=4010
|
||||
@@ -605,8 +616,8 @@ Subroutine psb_ccdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
desc_ov%glob_to_loc(idx)=n_col
|
||||
desc_ov%loc_to_glob(n_col)=idx
|
||||
desc_ov%glob_to_loc(idx) = n_col
|
||||
desc_ov%loc_to_glob(n_col) = idx
|
||||
|
||||
call psb_ensure_size((counter_t+3),t_halo_in,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
@@ -615,21 +626,23 @@ Subroutine psb_ccdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
t_halo_in(counter_t)=proc_id
|
||||
t_halo_in(counter_t+1)=1
|
||||
t_halo_in(counter_t+2)=n_col
|
||||
t_halo_in(counter_t+3)=-1
|
||||
t_halo_in(counter_t) = proc_id
|
||||
t_halo_in(counter_t+1) = 1
|
||||
t_halo_in(counter_t+2) = n_col
|
||||
t_halo_in(counter_t+3) = -1
|
||||
counter_t=counter_t+3
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),': Added into t_halo_in from recv',&
|
||||
&proc_id,n_col,idx
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ': Added into t_halo_in from recv',&
|
||||
& proc_id,n_col,idx
|
||||
else if (desc_ov%glob_to_loc(idx) < 0) Then
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),':Wrong input to cdbldextbld?',&
|
||||
&idx,desc_ov%glob_to_loc(idx)
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ':Wrong input to cdbldextbld?',&
|
||||
& idx,desc_ov%glob_to_loc(idx)
|
||||
End If
|
||||
End Do
|
||||
desc_ov%matrix_data(psb_n_col_)=n_col
|
||||
desc_ov%matrix_data(psb_n_col_) = n_col
|
||||
|
||||
end if
|
||||
|
||||
@@ -692,7 +705,7 @@ Subroutine psb_ccdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
call psb_errpush(4010,name,a_err='deallocate')
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
|
||||
case(psb_ovt_asov_)
|
||||
!
|
||||
! Build an overlapped descriptor for Additive Schwarz
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
! ictxt - integer. The communication context.
|
||||
! desc - type(psb_desc_type). The communication descriptor.
|
||||
! info - integer. Eventually returns an error code
|
||||
subroutine psb_cd_inloc(v, ictxt, desc, info)
|
||||
subroutine psb_cd_inloc(v, ictxt, desc, info, globalcheck)
|
||||
use psb_descriptor_type
|
||||
use psb_serial_mod
|
||||
use psb_const_mod
|
||||
@@ -53,14 +53,18 @@ subroutine psb_cd_inloc(v, ictxt, desc, info)
|
||||
Integer, intent(in) :: ictxt, v(:)
|
||||
integer, intent(out) :: info
|
||||
type(psb_desc_type), intent(out) :: desc
|
||||
logical, intent(in), optional :: globalcheck
|
||||
|
||||
!locals
|
||||
Integer :: counter,i,j,np,me,loc_row,err,&
|
||||
& loc_col,nprocs,n,itmpov, k,glx,&
|
||||
& l_ov_ix,l_ov_el,idx, flag_, err_act,m
|
||||
Integer :: i,j,np,me,loc_row,err,&
|
||||
& loc_col,nprocs,n, k,glx,nlu,&
|
||||
& idx, flag_, err_act,m, novrl, norphan,&
|
||||
& npr_ov, itmpov, i_pnt, nrt
|
||||
integer :: int_err(5),exch(3)
|
||||
Integer, allocatable :: temp_ovrlap(:), tmpgidx(:,:)
|
||||
Integer, allocatable :: temp_ovrlap(:), tmpgidx(:,:), vl(:),&
|
||||
& nov(:), ov_idx(:,:)
|
||||
integer :: debug_level, debug_unit
|
||||
logical :: check_, islarge
|
||||
character(len=20) :: name
|
||||
|
||||
if(psb_get_errstatus() /= 0) return
|
||||
@@ -74,18 +78,25 @@ subroutine psb_cd_inloc(v, ictxt, desc, info)
|
||||
if (debug_level >= psb_debug_ext_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),': start',np
|
||||
|
||||
|
||||
|
||||
loc_row = size(v)
|
||||
if (.false.) then
|
||||
m = loc_row
|
||||
call psb_sum(ictxt,m)
|
||||
else
|
||||
m = maxval(v)
|
||||
nrt = loc_row
|
||||
call psb_sum(ictxt,nrt)
|
||||
call psb_max(ictxt,m)
|
||||
end if
|
||||
|
||||
if (present(globalcheck)) then
|
||||
check_ = globalcheck
|
||||
else
|
||||
check_ = .true.
|
||||
end if
|
||||
|
||||
n = m
|
||||
|
||||
|
||||
!... check m and n parameters....
|
||||
if (m < 1) then
|
||||
info = 10
|
||||
@@ -124,35 +135,86 @@ subroutine psb_cd_inloc(v, ictxt, desc, info)
|
||||
|
||||
if (debug_level >= psb_debug_ext_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),': doing global checks'
|
||||
allocate(tmpgidx(m,2),stat=info)
|
||||
|
||||
islarge = psb_cd_choose_large_state(ictxt,m)
|
||||
|
||||
allocate(vl(loc_row),stat=info)
|
||||
if (info /=0) then
|
||||
info=4000
|
||||
call psb_errpush(info,name,i_err=int_err)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
!
|
||||
! Checks for valid input:
|
||||
! 1. legal range
|
||||
! 2. no orphans
|
||||
! 3. any overlap?
|
||||
! Checks 2 and 3 are controlled by globalcheck
|
||||
!
|
||||
|
||||
if (check_.or.(.not.islarge)) then
|
||||
allocate(tmpgidx(m,2),stat=info)
|
||||
if (info /=0) then
|
||||
info=4000
|
||||
call psb_errpush(info,name,i_err=int_err)
|
||||
goto 9999
|
||||
end if
|
||||
tmpgidx = 0
|
||||
flag_ = 1
|
||||
do i=1,loc_row
|
||||
if ((v(i)<1).or.(v(i)>m)) then
|
||||
info = 551
|
||||
int_err(1) = i
|
||||
int_err(2) = v(i)
|
||||
int_err(3) = loc_row
|
||||
int_err(4) = m
|
||||
else
|
||||
tmpgidx(v(i),1) = me+flag_
|
||||
tmpgidx(v(i),2) = 1
|
||||
endif
|
||||
vl(i) = v(i)
|
||||
end do
|
||||
|
||||
|
||||
tmpgidx=0
|
||||
flag_=1
|
||||
do i=1,loc_row
|
||||
if ((v(i)<1).or.(v(i)>m)) then
|
||||
info = 551
|
||||
int_err(1) = i
|
||||
int_err(2) = v(i)
|
||||
int_err(3) = loc_row
|
||||
int_err(4) = m
|
||||
else
|
||||
tmpgidx(v(i),1) = me+flag_
|
||||
tmpgidx(v(i),2) = 1
|
||||
endif
|
||||
end do
|
||||
call psb_amx(ictxt,tmpgidx)
|
||||
if (info ==0) then
|
||||
int_err(1) = count(tmpgidx(:,2) == 0)
|
||||
int_err(2) = m
|
||||
if (int_err(1)>0) then
|
||||
info = 552
|
||||
if (info ==0) then
|
||||
call psb_amx(ictxt,tmpgidx(:,1))
|
||||
call psb_sum(ictxt,tmpgidx(:,2))
|
||||
novrl = 0
|
||||
npr_ov = 0
|
||||
norphan = 0
|
||||
do i=1, m
|
||||
if (tmpgidx(i,2) < 1) then
|
||||
norphan = norphan + 1
|
||||
else if (tmpgidx(i,2) > 1) then
|
||||
novrl = novrl + 1
|
||||
npr_ov = npr_ov + tmpgidx(i,2)
|
||||
end if
|
||||
end do
|
||||
if (norphan > 0) then
|
||||
int_err(1) = norphan
|
||||
int_err(2) = m
|
||||
info = 552
|
||||
end if
|
||||
end if
|
||||
else
|
||||
novrl = 0
|
||||
norphan = 0
|
||||
npr_ov = 0
|
||||
do i=1,loc_row
|
||||
if ((v(i)<1).or.(v(i)>m)) then
|
||||
info = 551
|
||||
int_err(1) = i
|
||||
int_err(2) = v(i)
|
||||
int_err(3) = loc_row
|
||||
int_err(4) = m
|
||||
exit
|
||||
endif
|
||||
vl(i) = v(i)
|
||||
end do
|
||||
|
||||
if ((m /= nrt).and.(me==psb_root_)) then
|
||||
write(0,*) trim(name),' Warning: globalcheck=.false., but there is a mismatch'
|
||||
write(0,*) trim(name),' : in the global sizes!',m,nrt
|
||||
end if
|
||||
end if
|
||||
|
||||
@@ -161,22 +223,82 @@ subroutine psb_cd_inloc(v, ictxt, desc, info)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
!
|
||||
! Now sort the input items, and eliminate duplicates
|
||||
! (unlikely, but possible)
|
||||
!
|
||||
call psb_msort_unique(vl,nlu)
|
||||
loc_row = nlu
|
||||
|
||||
call psb_nullify_desc(desc)
|
||||
|
||||
!
|
||||
! Figure out overlap in the input
|
||||
!
|
||||
if (novrl > 0) then
|
||||
if (debug_level >= psb_debug_ext_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),': code for NOVRL>0',novrl,npr_ov
|
||||
|
||||
allocate(nov(0:np),ov_idx(npr_ov,2),stat=info)
|
||||
if (info /= 0) then
|
||||
info=4025
|
||||
int_err(1)=np + 2*npr_ov
|
||||
call psb_errpush(info,name,i_err=int_err,a_err='integer')
|
||||
goto 9999
|
||||
endif
|
||||
nov=0
|
||||
do i=1, nlu
|
||||
k = vl(i)
|
||||
if (tmpgidx(k,2) > 1) then
|
||||
nov(me) = nov(me) + 1
|
||||
end if
|
||||
end do
|
||||
call psb_sum(ictxt,nov)
|
||||
nov(1:np) = nov(0:np-1)
|
||||
nov(0) = 1
|
||||
do i=1, np
|
||||
nov(i) = nov(i) + nov(i-1)
|
||||
end do
|
||||
ov_idx = 0
|
||||
j = nov(me)
|
||||
do i=1, nlu
|
||||
k = vl(i)
|
||||
if (tmpgidx(k,2) > 1) then
|
||||
ov_idx(j,1) = k
|
||||
ov_idx(j,2) = me
|
||||
j = j + 1
|
||||
end if
|
||||
end do
|
||||
|
||||
if (j /= nov(me+1)) then
|
||||
info=4001
|
||||
call psb_errpush(info,name,a_err='overlap count')
|
||||
goto 9999
|
||||
end if
|
||||
call psb_max(ictxt,ov_idx)
|
||||
call psb_msort(ov_idx(:,1),ix=ov_idx(:,2),flag=psb_sort_keep_idx_)
|
||||
|
||||
end if
|
||||
|
||||
!count local rows number
|
||||
! allocate work vector
|
||||
if (psb_cd_choose_large_state(ictxt,m)) then
|
||||
if (islarge) then
|
||||
allocate(desc%matrix_data(psb_mdata_size_),&
|
||||
&temp_ovrlap(m),stat=info)
|
||||
desc%matrix_data(:) = 0
|
||||
desc%matrix_data(psb_desc_size_) = psb_desc_large_
|
||||
&temp_ovrlap(2*loc_row),desc%lprm(1),&
|
||||
& stat=info)
|
||||
if (info == 0) then
|
||||
desc%lprm(1) = 0
|
||||
desc%matrix_data(:) = 0
|
||||
desc%matrix_data(psb_desc_size_) = psb_desc_large_
|
||||
end if
|
||||
else
|
||||
allocate(desc%glob_to_loc(m),desc%matrix_data(psb_mdata_size_),&
|
||||
&temp_ovrlap(m),stat=info)
|
||||
desc%matrix_data(:) = 0
|
||||
desc%matrix_data(psb_desc_size_) = psb_desc_normal_
|
||||
&temp_ovrlap(2*loc_row),desc%lprm(1),&
|
||||
& stat=info)
|
||||
if (info == 0) then
|
||||
desc%lprm(1) = 0
|
||||
desc%matrix_data(:) = 0
|
||||
desc%matrix_data(psb_desc_size_) = psb_desc_normal_
|
||||
end if
|
||||
end if
|
||||
if (info /= 0) then
|
||||
info=4025
|
||||
@@ -185,6 +307,18 @@ subroutine psb_cd_inloc(v, ictxt, desc, info)
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
! estimate local cols number
|
||||
loc_col = min(2*loc_row,m)
|
||||
|
||||
allocate(desc%loc_to_glob(loc_col),stat=info)
|
||||
if (info /= 0) then
|
||||
info=4025
|
||||
int_err(1)=loc_col
|
||||
call psb_errpush(info,name,i_err=int_err,a_err='integer')
|
||||
goto 9999
|
||||
end if
|
||||
desc%loc_to_glob(:) = -1
|
||||
temp_ovrlap(:) = -1
|
||||
desc%matrix_data(psb_m_) = m
|
||||
desc%matrix_data(psb_n_) = n
|
||||
! This has to be set BEFORE any call to SET_BLD
|
||||
@@ -194,14 +328,11 @@ subroutine psb_cd_inloc(v, ictxt, desc, info)
|
||||
|
||||
if (debug_level >= psb_debug_ext_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),': starting main loop' ,info
|
||||
counter = 0
|
||||
itmpov = 0
|
||||
temp_ovrlap(:) = -1
|
||||
|
||||
!
|
||||
! We have to decide whether we have a "large" index space.
|
||||
!
|
||||
if (psb_cd_choose_large_state(ictxt,m)) then
|
||||
if (islarge) then
|
||||
!
|
||||
! Yes, we do have a large index space. Therefore we are
|
||||
! keeping on the local process a map of only the global
|
||||
@@ -211,41 +342,7 @@ subroutine psb_cd_inloc(v, ictxt, desc, info)
|
||||
! is transferred to a series of ordered linear lists,
|
||||
! hashed by the low order bits of the entries.
|
||||
!
|
||||
do i=1,m
|
||||
|
||||
if (((tmpgidx(i,1)-flag_) > np-1).or.((tmpgidx(i,1)-flag_) < 0)) then
|
||||
info=580
|
||||
int_err(1)=3
|
||||
int_err(2)=tmpgidx(i,1) - flag_
|
||||
int_err(3)=i
|
||||
exit
|
||||
end if
|
||||
|
||||
if ((tmpgidx(i,1)-flag_) == me) then
|
||||
! this point belongs to me
|
||||
counter=counter+1
|
||||
end if
|
||||
enddo
|
||||
|
||||
|
||||
loc_row=counter
|
||||
! check on parts function
|
||||
if (debug_level >= psb_debug_ext_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),': End main loop:' ,loc_row,itmpov,info
|
||||
|
||||
if (info /= 0) then
|
||||
call psb_errpush(info,name,i_err=int_err)
|
||||
goto 9999
|
||||
end if
|
||||
if (debug_level >= psb_debug_ext_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),': error check:' ,err
|
||||
|
||||
! estimate local cols number
|
||||
loc_col = min(2*loc_row,m)
|
||||
|
||||
allocate(desc%loc_to_glob(loc_col), desc%lprm(1),&
|
||||
& stat=info)
|
||||
if (info == 0) call InitSearchTree(desc%avltree,info)
|
||||
if (info /= 0) then
|
||||
info=4025
|
||||
int_err(1)=loc_col
|
||||
@@ -253,24 +350,45 @@ subroutine psb_cd_inloc(v, ictxt, desc, info)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
! set LOC_TO_GLOB array to all "-1" values
|
||||
desc%lprm(1) = 0
|
||||
desc%loc_to_glob(:) = -1
|
||||
k = 0
|
||||
do i=1,m
|
||||
if ((tmpgidx(i,1)-flag_) == me) then
|
||||
k = k + 1
|
||||
desc%loc_to_glob(k) = i
|
||||
call SearchInsKey(desc%avltree,i,glx,k,info)
|
||||
endif
|
||||
! Use sorted indices to fill in loc_to_glob
|
||||
j = 1
|
||||
itmpov = 0
|
||||
do k=1, loc_row
|
||||
i = vl(k)
|
||||
desc%loc_to_glob(k) = i
|
||||
|
||||
if (check_) then
|
||||
nprocs = tmpgidx(i,2)
|
||||
if (nprocs > 1) then
|
||||
do
|
||||
if (j > size(ov_idx,dim=1)) then
|
||||
info=4001
|
||||
call psb_errpush(info,name,a_err='search ov_idx')
|
||||
goto 9999
|
||||
end if
|
||||
if (ov_idx(j,1) == i) exit
|
||||
j = j + 1
|
||||
end do
|
||||
call psb_ensure_size((itmpov+3+nprocs),temp_ovrlap,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
info=4010
|
||||
call psb_errpush(info,name,a_err='psb_ensure_size')
|
||||
goto 9999
|
||||
end if
|
||||
itmpov = itmpov + 1
|
||||
temp_ovrlap(itmpov) = i
|
||||
itmpov = itmpov + 1
|
||||
temp_ovrlap(itmpov) = nprocs
|
||||
temp_ovrlap(itmpov+1:itmpov+nprocs) = ov_idx(j:j+nprocs-1,2)
|
||||
itmpov = itmpov + nprocs
|
||||
end if
|
||||
end if
|
||||
|
||||
enddo
|
||||
if (k /= loc_row) then
|
||||
write(0,*) 'Large cd init: ',k,loc_row
|
||||
end if
|
||||
|
||||
if (info /= 0) then
|
||||
info=4000
|
||||
call psb_errpush(info,name)
|
||||
info=4001
|
||||
call psb_errpush(info,name,a_err='insert loop')
|
||||
goto 9999
|
||||
endif
|
||||
|
||||
@@ -296,56 +414,57 @@ subroutine psb_cd_inloc(v, ictxt, desc, info)
|
||||
exit
|
||||
end if
|
||||
|
||||
if ((tmpgidx(i,1)-flag_) == me) then
|
||||
! this point belongs to me
|
||||
counter=counter+1
|
||||
desc%glob_to_loc(i) = counter
|
||||
else
|
||||
desc%glob_to_loc(i) = -(np+(tmpgidx(i,1)-flag_)+1)
|
||||
end if
|
||||
desc%glob_to_loc(i) = -(np+(tmpgidx(i,1)-flag_)+1)
|
||||
enddo
|
||||
|
||||
|
||||
loc_row=counter
|
||||
! check on parts function
|
||||
if (debug_level >= psb_debug_ext_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),': End main loop:' ,loc_row,itmpov,info
|
||||
|
||||
if (info /= 0) then
|
||||
call psb_errpush(info,name,i_err=int_err)
|
||||
goto 9999
|
||||
end if
|
||||
if (debug_level >= psb_debug_ext_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),': error check:' ,err
|
||||
|
||||
! estimate local cols number
|
||||
loc_col = min(2*loc_row,m)
|
||||
! Use sorted indices to fill in loc_to_glob
|
||||
j = 1
|
||||
itmpov = 0
|
||||
do k=1, loc_row
|
||||
i = vl(k)
|
||||
desc%loc_to_glob(k) = i
|
||||
desc%glob_to_loc(i) = k
|
||||
|
||||
allocate(desc%loc_to_glob(loc_col),&
|
||||
&desc%lprm(1),stat=info)
|
||||
if (info /= 0) then
|
||||
info=4025
|
||||
int_err(1)=loc_col
|
||||
call psb_errpush(info,name,i_err=int_err,a_err='integer')
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
! set LOC_TO_GLOB array to all "-1" values
|
||||
desc%lprm(1) = 0
|
||||
desc%loc_to_glob(:) = -1
|
||||
do i=1,m
|
||||
k = desc%glob_to_loc(i)
|
||||
if (k > 0) then
|
||||
desc%loc_to_glob(k) = i
|
||||
endif
|
||||
nprocs = tmpgidx(i,2)
|
||||
if (nprocs > 1) then
|
||||
do
|
||||
if (j > size(ov_idx,dim=1)) then
|
||||
info=4001
|
||||
call psb_errpush(info,name,a_err='search ov_idx')
|
||||
goto 9999
|
||||
end if
|
||||
if (ov_idx(j,1) == i) exit
|
||||
j = j + 1
|
||||
end do
|
||||
call psb_ensure_size((itmpov+3+nprocs),temp_ovrlap,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
info=4010
|
||||
call psb_errpush(info,name,a_err='psb_ensure_size')
|
||||
goto 9999
|
||||
end if
|
||||
itmpov = itmpov + 1
|
||||
temp_ovrlap(itmpov) = i
|
||||
itmpov = itmpov + 1
|
||||
temp_ovrlap(itmpov) = nprocs
|
||||
temp_ovrlap(itmpov+1:itmpov+nprocs) = ov_idx(j:j+nprocs-1,2)
|
||||
itmpov = itmpov + nprocs
|
||||
end if
|
||||
enddo
|
||||
|
||||
end if
|
||||
|
||||
|
||||
call psi_bld_tmpovrl(temp_ovrlap,desc,info)
|
||||
|
||||
deallocate(temp_ovrlap,stat=info)
|
||||
if (info == 0) deallocate(temp_ovrlap,vl,stat=info)
|
||||
if ((info == 0).and.(allocated(tmpgidx)))&
|
||||
& deallocate(tmpgidx,stat=info)
|
||||
if ((info == 0) .and.(allocated(ov_idx))) &
|
||||
& deallocate(ov_idx,nov,stat=info)
|
||||
if (info /= 0) then
|
||||
info=4000
|
||||
call psb_errpush(info,name)
|
||||
@@ -371,6 +490,11 @@ subroutine psb_cd_inloc(v, ictxt, desc, info)
|
||||
& write(debug_unit,*) me,' ',trim(name),': end'
|
||||
|
||||
call psb_cd_set_bld(desc,info)
|
||||
if (info /= 0) then
|
||||
info=4010
|
||||
call psb_errpush(info,name,a_err='psb_cd_set_bld')
|
||||
Goto 9999
|
||||
end if
|
||||
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
!!$
|
||||
!!$ Parallel Sparse BLAS version 2.2
|
||||
!!$ (C) Copyright 2006/2007/2008
|
||||
!!$ Salvatore Filippone University of Rome Tor Vergata
|
||||
!!$ Alfredo Buttari University of Rome Tor Vergata
|
||||
!!$
|
||||
!!$ Redistribution and use in source and binary forms, with or without
|
||||
!!$ modification, are permitted provided that the following conditions
|
||||
!!$ are met:
|
||||
!!$ 1. Redistributions of source code must retain the above copyright
|
||||
!!$ notice, this list of conditions and the following disclaimer.
|
||||
!!$ 2. Redistributions in binary form must reproduce the above copyright
|
||||
!!$ notice, this list of conditions, and the following disclaimer in the
|
||||
!!$ documentation and/or other materials provided with the distribution.
|
||||
!!$ 3. The name of the PSBLAS group or the names of its contributors may
|
||||
!!$ not be used to endorse or promote products derived from this
|
||||
!!$ software without specific written permission.
|
||||
!!$
|
||||
!!$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
!!$ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
!!$ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
!!$ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PSBLAS GROUP OR ITS CONTRIBUTORS
|
||||
!!$ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
!!$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
!!$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
!!$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
!!$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
!!$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
!!$ POSSIBILITY OF SUCH DAMAGE.
|
||||
!!$
|
||||
!!$
|
||||
subroutine psb_cd_set_ovl_bld(desc,info)
|
||||
!
|
||||
! Change state of a descriptor into ovl_build.
|
||||
use psb_const_mod
|
||||
use psb_error_mod
|
||||
use psb_penv_mod
|
||||
use psi_mod
|
||||
use psb_descriptor_type
|
||||
use psb_tools_mod, psb_protect_name => psb_cd_set_ovl_bld
|
||||
implicit none
|
||||
type(psb_desc_type), intent(inout) :: desc
|
||||
integer :: info
|
||||
|
||||
call psb_cd_set_bld(desc,info)
|
||||
if (info == 0) desc%matrix_data(psb_dec_type_) = psb_cd_ovl_bld_
|
||||
|
||||
end subroutine psb_cd_set_ovl_bld
|
||||
|
||||
subroutine psb_cd_set_bld(desc,info)
|
||||
!
|
||||
! Change state of a descriptor into BUILD.
|
||||
! If the descriptor is LARGE, check the AVL search tree
|
||||
! and initialize it if necessary.
|
||||
!
|
||||
use psb_const_mod
|
||||
use psb_error_mod
|
||||
use psb_penv_mod
|
||||
use psi_mod
|
||||
use psb_descriptor_type
|
||||
use psb_tools_mod, psb_protect_name => psb_cd_set_bld
|
||||
implicit none
|
||||
type(psb_desc_type), intent(inout) :: desc
|
||||
integer :: info
|
||||
!locals
|
||||
integer :: np,me,ictxt, err_act,idx,gidx,lidx,nc
|
||||
logical, parameter :: debug=.false.,debugprt=.false.
|
||||
character(len=20) :: name
|
||||
if (debug) write(0,*) me,'Entered CDCPY'
|
||||
if (psb_get_errstatus() /= 0) return
|
||||
info = 0
|
||||
call psb_erractionsave(err_act)
|
||||
name = 'psb_cd_set_bld'
|
||||
|
||||
ictxt = psb_cd_get_context(desc)
|
||||
|
||||
if (debug) write(0,*)'Entered CDSETBLD',ictxt
|
||||
! check on blacs grid
|
||||
call psb_info(ictxt, me, np)
|
||||
if (debug) write(0,*) me,'Entered CDSETBLD'
|
||||
if (psb_is_asb_desc(desc)) then
|
||||
end if
|
||||
|
||||
desc%matrix_data(psb_dec_type_) = psb_desc_bld_
|
||||
|
||||
if (psb_is_large_desc(desc)) then
|
||||
!
|
||||
! The idea: first build glb_lc with the info on
|
||||
! rows we already have, then leave space in
|
||||
! hash for newcomers (halo indices).
|
||||
! The policy is to allocate for as many entries
|
||||
! as there are rows; if we ever fill them up, we can
|
||||
! try and enlarge again, but by the time the hash
|
||||
! fills up it means we have as many halo as internals,
|
||||
! therefore there are much worse problems ahead than
|
||||
! the hash occupancy.
|
||||
!
|
||||
nc = psb_cd_get_local_cols(desc)
|
||||
if (.not.associated(desc%hash)) allocate(desc%hash,stat=info)
|
||||
if (info == 0)&
|
||||
& call psb_hash_init(nc,desc%hash,info)
|
||||
if (info == 0) call psi_bld_hash(desc,info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='hashInit')
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
end if
|
||||
|
||||
if (debug) write(0,*) me,'SET_BLD: done'
|
||||
call psb_erractionrestore(err_act)
|
||||
return
|
||||
|
||||
9999 continue
|
||||
call psb_erractionrestore(err_act)
|
||||
|
||||
if (err_act == psb_act_ret_) then
|
||||
return
|
||||
else
|
||||
call psb_error(ictxt)
|
||||
end if
|
||||
return
|
||||
end subroutine psb_cd_set_bld
|
||||
@@ -51,7 +51,6 @@ subroutine psb_cdals(m, n, parts, ictxt, desc, info)
|
||||
use psb_const_mod
|
||||
use psi_mod
|
||||
use psb_penv_mod
|
||||
use psb_avl_mod
|
||||
implicit None
|
||||
include 'parts.fh'
|
||||
!....Parameters...
|
||||
@@ -74,7 +73,7 @@ subroutine psb_cdals(m, n, parts, ictxt, desc, info)
|
||||
call psb_erractionsave(err_act)
|
||||
debug_unit = psb_get_debug_unit()
|
||||
debug_level = psb_get_debug_level()
|
||||
|
||||
|
||||
|
||||
call psb_info(ictxt, me, np)
|
||||
if (debug_level >= psb_debug_ext_) &
|
||||
@@ -125,18 +124,23 @@ subroutine psb_cdals(m, n, parts, ictxt, desc, info)
|
||||
|
||||
call psb_nullify_desc(desc)
|
||||
|
||||
!count local rows number
|
||||
! count local rows number
|
||||
loc_row = max(1,(m+np-1)/np)
|
||||
! allocate work vector
|
||||
if (psb_cd_choose_large_state(ictxt,m)) then
|
||||
allocate(desc%matrix_data(psb_mdata_size_),&
|
||||
& temp_ovrlap(m),prc_v(np),stat=info)
|
||||
desc%matrix_data(:) = 0
|
||||
desc%matrix_data(psb_desc_size_) = psb_desc_large_
|
||||
& temp_ovrlap(2*loc_row),prc_v(np),stat=info)
|
||||
if (info == 0) then
|
||||
desc%matrix_data(:) = 0
|
||||
desc%matrix_data(psb_desc_size_) = psb_desc_large_
|
||||
end if
|
||||
else
|
||||
allocate(desc%glob_to_loc(m),desc%matrix_data(psb_mdata_size_),&
|
||||
& temp_ovrlap(m),prc_v(np),stat=info)
|
||||
desc%matrix_data(:) = 0
|
||||
desc%matrix_data(psb_desc_size_) = psb_desc_normal_
|
||||
& temp_ovrlap(2*loc_row),prc_v(np),stat=info)
|
||||
if (info == 0) then
|
||||
desc%matrix_data(:) = 0
|
||||
desc%matrix_data(psb_desc_size_) = psb_desc_normal_
|
||||
end if
|
||||
end if
|
||||
if (info /= 0) then
|
||||
info=4025
|
||||
@@ -170,11 +174,10 @@ subroutine psb_cdals(m, n, parts, ictxt, desc, info)
|
||||
! is transferred to a series of ordered linear lists,
|
||||
! hashed by the low order bits of the entries.
|
||||
!
|
||||
loc_col = (m+np-1)/np
|
||||
loc_col = max(1,(m+np-1)/np)
|
||||
loc_col = min(2*loc_col,m)
|
||||
allocate(desc%loc_to_glob(loc_col), desc%lprm(1),&
|
||||
& stat=info)
|
||||
if (info == 0) call InitSearchTree(desc%avltree,info)
|
||||
if (info /= 0) then
|
||||
info=4025
|
||||
int_err(1)=loc_col
|
||||
@@ -225,7 +228,7 @@ subroutine psb_cdals(m, n, parts, ictxt, desc, info)
|
||||
if (prc_v(j) == me) exit
|
||||
j=j+1
|
||||
enddo
|
||||
|
||||
|
||||
if (j <= nprocs) then
|
||||
if (prc_v(j) == me) then
|
||||
! this point belongs to me
|
||||
@@ -237,7 +240,6 @@ subroutine psb_cdals(m, n, parts, ictxt, desc, info)
|
||||
goto 9999
|
||||
end if
|
||||
desc%loc_to_glob(k) = i
|
||||
call SearchInsKey(desc%avltree,i,glx,k,info)
|
||||
if (nprocs > 1) then
|
||||
call psb_ensure_size((itmpov+3+nprocs),temp_ovrlap,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
@@ -253,7 +255,7 @@ subroutine psb_cdals(m, n, parts, ictxt, desc, info)
|
||||
itmpov = itmpov + nprocs
|
||||
endif
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
enddo
|
||||
if (info /= 0) then
|
||||
@@ -371,7 +373,7 @@ subroutine psb_cdals(m, n, parts, ictxt, desc, info)
|
||||
|
||||
|
||||
call psi_bld_tmpovrl(temp_ovrlap,desc,info)
|
||||
|
||||
|
||||
if (info == 0) deallocate(prc_v,temp_ovrlap,stat=info)
|
||||
if (info /= psb_no_err_) then
|
||||
info=4000
|
||||
@@ -396,6 +398,11 @@ subroutine psb_cdals(m, n, parts, ictxt, desc, info)
|
||||
desc%ext_index(:) = -1
|
||||
|
||||
call psb_cd_set_bld(desc,info)
|
||||
if (info /= 0) then
|
||||
info=4010
|
||||
call psb_errpush(info,name,a_err='psb_cd_set_bld')
|
||||
Goto 9999
|
||||
end if
|
||||
|
||||
|
||||
if (debug_level >= psb_debug_ext_) &
|
||||
|
||||
@@ -50,7 +50,6 @@ subroutine psb_cdalv(v, ictxt, desc, info, flag)
|
||||
use psb_error_mod
|
||||
use psi_mod
|
||||
use psb_penv_mod
|
||||
use psb_avl_mod
|
||||
implicit None
|
||||
!....Parameters...
|
||||
Integer, intent(in) :: ictxt, v(:)
|
||||
@@ -136,18 +135,23 @@ subroutine psb_cdalv(v, ictxt, desc, info, flag)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
!count local rows number
|
||||
! count local rows number
|
||||
loc_row = max(1,(m+np-1)/np)
|
||||
! allocate work vector
|
||||
if (psb_cd_choose_large_state(ictxt,m)) then
|
||||
allocate(desc%matrix_data(psb_mdata_size_),&
|
||||
&temp_ovrlap(m),stat=info)
|
||||
desc%matrix_data(:) = 0
|
||||
desc%matrix_data(psb_desc_size_) = psb_desc_large_
|
||||
&temp_ovrlap(2*loc_row),stat=info)
|
||||
if (info == 0) then
|
||||
desc%matrix_data(:) = 0
|
||||
desc%matrix_data(psb_desc_size_) = psb_desc_large_
|
||||
end if
|
||||
else
|
||||
allocate(desc%glob_to_loc(m),desc%matrix_data(psb_mdata_size_),&
|
||||
&temp_ovrlap(m),stat=info)
|
||||
desc%matrix_data(:) = 0
|
||||
desc%matrix_data(psb_desc_size_) = psb_desc_normal_
|
||||
&temp_ovrlap(2*loc_row),stat=info)
|
||||
if (info == 0) then
|
||||
desc%matrix_data(:) = 0
|
||||
desc%matrix_data(psb_desc_size_) = psb_desc_normal_
|
||||
end if
|
||||
end if
|
||||
if (info /= 0) then
|
||||
info=4025
|
||||
@@ -215,7 +219,6 @@ subroutine psb_cdalv(v, ictxt, desc, info, flag)
|
||||
|
||||
allocate(desc%loc_to_glob(loc_col), desc%lprm(1),&
|
||||
& stat=info)
|
||||
if (info == 0) call InitSearchTree(desc%avltree,info)
|
||||
if (info /= 0) then
|
||||
info=4025
|
||||
int_err(1)=loc_col
|
||||
@@ -231,7 +234,6 @@ subroutine psb_cdalv(v, ictxt, desc, info, flag)
|
||||
if ((v(i)-flag_) == me) then
|
||||
k = k + 1
|
||||
desc%loc_to_glob(k) = i
|
||||
call SearchInsKey(desc%avltree,i,glx,k,info)
|
||||
endif
|
||||
enddo
|
||||
|
||||
@@ -328,6 +330,11 @@ subroutine psb_cdalv(v, ictxt, desc, info, flag)
|
||||
desc%ext_index(:) = -1
|
||||
|
||||
call psb_cd_set_bld(desc,info)
|
||||
if (info /= 0) then
|
||||
info=4010
|
||||
call psb_errpush(info,name,a_err='psb_cd_set_bld')
|
||||
Goto 9999
|
||||
end if
|
||||
|
||||
if (debug_level >= psb_debug_ext_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),': end'
|
||||
|
||||
@@ -84,14 +84,11 @@ subroutine psb_cdcpy(desc_in, desc_out, info)
|
||||
if (info == 0) call psb_safe_ab_cpy(desc_in%glob_to_loc,desc_out%glob_to_loc,info)
|
||||
if (info == 0) call psb_safe_ab_cpy(desc_in%lprm,desc_out%lprm,info)
|
||||
if (info == 0) call psb_safe_ab_cpy(desc_in%idx_space,desc_out%idx_space,info)
|
||||
desc_out%hashvsize = desc_in%hashvsize
|
||||
desc_out%hashvmask = desc_in%hashvmask
|
||||
if (info == 0) call psb_safe_ab_cpy(desc_in%hashv,desc_out%hashv,info)
|
||||
if (info == 0) call psb_safe_ab_cpy(desc_in%glb_lc,desc_out%glb_lc,info)
|
||||
|
||||
if (info == 0) then
|
||||
if (associated(desc_in%avltree)) then
|
||||
call CloneSearchTree(desc_in%avltree,desc_out%avltree)
|
||||
end if
|
||||
end if
|
||||
if (info == 0) call CloneHashTable(desc_in%hash,desc_out%hash,info)
|
||||
|
||||
if (info /= 0) then
|
||||
info = 4010
|
||||
|
||||
@@ -556,6 +556,9 @@ Subroutine psb_dcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
works(j) = workr(i)
|
||||
end if
|
||||
end do
|
||||
! Eliminate duplicates from request
|
||||
call psb_msort_unique(works(1:j),iszs)
|
||||
|
||||
!
|
||||
! fnd_owner on desc_a because we want the procs who
|
||||
! owned the rows from the beginning!
|
||||
|
||||
@@ -49,7 +49,6 @@ subroutine psb_icdasb(desc_a,info,ext_hv)
|
||||
use psi_mod
|
||||
use psb_error_mod
|
||||
use psb_penv_mod
|
||||
use psb_avl_mod
|
||||
#ifdef MPI_MOD
|
||||
use mpi
|
||||
#endif
|
||||
@@ -113,7 +112,11 @@ subroutine psb_icdasb(desc_a,info,ext_hv)
|
||||
|
||||
if (debug_level >= psb_debug_ext_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),': Checking rows insertion'
|
||||
!
|
||||
! check if all local row are inserted
|
||||
! Note: this may still be useful for the case of
|
||||
! cdall(..., vl=vl, globalcheck=.false.)
|
||||
!
|
||||
do i=1,psb_cd_get_local_cols(desc_a)
|
||||
if (desc_a%loc_to_glob(i) < 0) then
|
||||
info=3100
|
||||
@@ -134,6 +137,10 @@ subroutine psb_icdasb(desc_a,info,ext_hv)
|
||||
if (debug_level >= psb_debug_ext_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),': Large descriptor, calling ldsc_pre_halo'
|
||||
call psi_ldsc_pre_halo(desc_a,ext_hv_,info)
|
||||
if (info /= 0) then
|
||||
call psb_errpush(4010,name,a_err='ldsc_pre_halo')
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
|
||||
! Take out the lists for ovrlap, halo and ext...
|
||||
@@ -150,23 +157,13 @@ subroutine psb_icdasb(desc_a,info,ext_hv)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
|
||||
deallocate(ovrlap_index, halo_index, ext_index, stat=info)
|
||||
if (info /= 0) then
|
||||
info =4000
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
! Finally, cleanup the AVL tree of indices, if any, as it is
|
||||
! only needed while in the build state.
|
||||
if (associated(desc_a%avltree)) then
|
||||
call FreeSearchTree(desc_a%avltree,info)
|
||||
if (info /= 0) then
|
||||
info=2059
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
end if
|
||||
end if
|
||||
|
||||
! Ok, register into MATRIX_DATA
|
||||
desc_a%matrix_data(psb_dec_type_) = psb_desc_asb_
|
||||
else
|
||||
|
||||
@@ -122,7 +122,8 @@ Subroutine psb_scdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
Call psb_info(ictxt, me, np)
|
||||
|
||||
If (debug_level >= psb_debug_outer_) &
|
||||
& Write(debug_unit,*) me,' ',trim(name),': start',novr
|
||||
& Write(debug_unit,*) me,' ',trim(name),&
|
||||
& ': start',novr
|
||||
|
||||
if (present(extype)) then
|
||||
extype_ = extype
|
||||
@@ -144,7 +145,8 @@ Subroutine psb_scdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
endif
|
||||
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),':Calling desccpy'
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ':Calling desccpy'
|
||||
call psb_cdcpy(desc_a,desc_ov,info)
|
||||
if (info /= 0) then
|
||||
info=4010
|
||||
@@ -153,7 +155,9 @@ Subroutine psb_scdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),':From desccpy'
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ':From desccpy'
|
||||
|
||||
if (novr==0) then
|
||||
!
|
||||
! Just copy the input.
|
||||
@@ -164,7 +168,8 @@ Subroutine psb_scdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
|
||||
|
||||
If (debug_level >= psb_debug_outer_)then
|
||||
Write(debug_unit,*) me,' ',trim(name),':BEGIN ',nhalo
|
||||
Write(debug_unit,*) me,' ',trim(name),&
|
||||
& ':BEGIN ',nhalo
|
||||
call psb_barrier(ictxt)
|
||||
endif
|
||||
|
||||
@@ -179,7 +184,7 @@ Subroutine psb_scdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
lworks = ((nztot+m-1)/m)*nhalo
|
||||
lworkr = ((nztot+m-1)/m)*nhalo
|
||||
else
|
||||
info=-1
|
||||
info = -1
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
@@ -234,12 +239,12 @@ Subroutine psb_scdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
tmp_ovr_idx(:) = -1
|
||||
orig_ovr(:) = -1
|
||||
tmp_halo(:) = -1
|
||||
counter_e = 1
|
||||
tot_recv = 0
|
||||
counter_t = 1
|
||||
counter_h = 1
|
||||
counter_o = 1
|
||||
cntov_o = 1
|
||||
counter_e = 1
|
||||
tot_recv = 0
|
||||
counter_t = 1
|
||||
counter_h = 1
|
||||
counter_o = 1
|
||||
cntov_o = 1
|
||||
! Init overlap with desc_a%ovrlap (if any)
|
||||
counter = 1
|
||||
Do While (desc_a%ovrlap_index(counter) /= -1)
|
||||
@@ -300,7 +305,8 @@ Subroutine psb_scdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
Do i_ovr = 1, novr
|
||||
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),':Running on overlap level ',i_ovr,' of ',novr
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ':Running on overlap level ',i_ovr,' of ',novr
|
||||
|
||||
!
|
||||
! At this point, halo contains a valid halo corresponding to the
|
||||
@@ -332,7 +338,8 @@ Subroutine psb_scdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
end If
|
||||
tot_recv=tot_recv+n_elem_recv
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),': tot_recv:',proc,n_elem_recv,tot_recv
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ': tot_recv:',proc,n_elem_recv,tot_recv
|
||||
!
|
||||
!
|
||||
! The format of the halo vector exists in two forms: 1. Temporary
|
||||
@@ -367,10 +374,10 @@ Subroutine psb_scdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
tmp_ovr_idx(counter_o)=proc
|
||||
tmp_ovr_idx(counter_o+1)=1
|
||||
tmp_ovr_idx(counter_o+2)=gidx
|
||||
tmp_ovr_idx(counter_o+3)=-1
|
||||
tmp_ovr_idx(counter_o) = proc
|
||||
tmp_ovr_idx(counter_o+1) = 1
|
||||
tmp_ovr_idx(counter_o+2) = gidx
|
||||
tmp_ovr_idx(counter_o+3) = -1
|
||||
counter_o=counter_o+3
|
||||
call psb_ensure_size((counter_h+3),tmp_halo,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
@@ -379,10 +386,10 @@ Subroutine psb_scdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
tmp_halo(counter_h)=proc
|
||||
tmp_halo(counter_h+1)=1
|
||||
tmp_halo(counter_h+2)=idx
|
||||
tmp_halo(counter_h+3)=-1
|
||||
tmp_halo(counter_h) = proc
|
||||
tmp_halo(counter_h+1) = 1
|
||||
tmp_halo(counter_h+2) = idx
|
||||
tmp_halo(counter_h+3) = -1
|
||||
|
||||
counter_h=counter_h+3
|
||||
|
||||
@@ -410,10 +417,10 @@ Subroutine psb_scdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
tmp_ovr_idx(counter_o)=proc
|
||||
tmp_ovr_idx(counter_o+1)=1
|
||||
tmp_ovr_idx(counter_o+2)=gidx
|
||||
tmp_ovr_idx(counter_o+3)=-1
|
||||
tmp_ovr_idx(counter_o) = proc
|
||||
tmp_ovr_idx(counter_o+1) = 1
|
||||
tmp_ovr_idx(counter_o+2) = gidx
|
||||
tmp_ovr_idx(counter_o+3) = -1
|
||||
counter_o=counter_o+3
|
||||
|
||||
!
|
||||
@@ -465,6 +472,7 @@ Subroutine psb_scdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ':Checktmp_o_i Loop Mid2',tmp_ovr_idx(1:10)
|
||||
|
||||
sdsz(proc+1) = tot_elem
|
||||
idxs = idxs + tot_elem
|
||||
end if
|
||||
@@ -516,7 +524,7 @@ Subroutine psb_scdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
call psb_errpush(info,name,a_err=ch_err)
|
||||
goto 9999
|
||||
end if
|
||||
lworkr=max(iszr,1)
|
||||
lworkr = max(iszr,1)
|
||||
end if
|
||||
|
||||
call mpi_alltoallv(works,sdsz,bsdindx,mpi_integer,&
|
||||
@@ -548,6 +556,9 @@ Subroutine psb_scdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
works(j) = workr(i)
|
||||
end if
|
||||
end do
|
||||
! Eliminate duplicates from request
|
||||
call psb_msort_unique(works(1:j),iszs)
|
||||
|
||||
!
|
||||
! fnd_owner on desc_a because we want the procs who
|
||||
! owned the rows from the beginning!
|
||||
@@ -574,11 +585,11 @@ Subroutine psb_scdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
t_halo_in(counter_t)=proc_id
|
||||
t_halo_in(counter_t+1)=1
|
||||
t_halo_in(counter_t+2)=lidx
|
||||
t_halo_in(counter_t+3)=-1
|
||||
counter_t=counter_t+3
|
||||
t_halo_in(counter_t) = proc_id
|
||||
t_halo_in(counter_t+1) = 1
|
||||
t_halo_in(counter_t+2) = lidx
|
||||
t_halo_in(counter_t+3) = -1
|
||||
counter_t = counter_t+3
|
||||
endif
|
||||
end Do
|
||||
n_col = psb_cd_get_local_cols(desc_ov)
|
||||
@@ -595,8 +606,8 @@ Subroutine psb_scdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
! we receive them guarantees that all indices for HALO(I)
|
||||
! will be less than those for HALO(J) whenever I<J
|
||||
!
|
||||
n_col=n_col+1
|
||||
proc_id=-desc_ov%glob_to_loc(idx)-np-1
|
||||
n_col = n_col+1
|
||||
proc_id = -desc_ov%glob_to_loc(idx)-np-1
|
||||
call psb_ensure_size(n_col,desc_ov%loc_to_glob,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
info=4010
|
||||
@@ -604,8 +615,8 @@ Subroutine psb_scdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
desc_ov%glob_to_loc(idx)=n_col
|
||||
desc_ov%loc_to_glob(n_col)=idx
|
||||
desc_ov%glob_to_loc(idx) = n_col
|
||||
desc_ov%loc_to_glob(n_col) = idx
|
||||
|
||||
call psb_ensure_size((counter_t+3),t_halo_in,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
@@ -614,21 +625,23 @@ Subroutine psb_scdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
t_halo_in(counter_t)=proc_id
|
||||
t_halo_in(counter_t+1)=1
|
||||
t_halo_in(counter_t+2)=n_col
|
||||
t_halo_in(counter_t+3)=-1
|
||||
t_halo_in(counter_t) = proc_id
|
||||
t_halo_in(counter_t+1) = 1
|
||||
t_halo_in(counter_t+2) = n_col
|
||||
t_halo_in(counter_t+3) = -1
|
||||
counter_t=counter_t+3
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),': Added into t_halo_in from recv',&
|
||||
&proc_id,n_col,idx
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ': Added into t_halo_in from recv',&
|
||||
& proc_id,n_col,idx
|
||||
else if (desc_ov%glob_to_loc(idx) < 0) Then
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),':Wrong input to cdbldextbld?',&
|
||||
&idx,desc_ov%glob_to_loc(idx)
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ':Wrong input to cdbldextbld?',&
|
||||
& idx,desc_ov%glob_to_loc(idx)
|
||||
End If
|
||||
End Do
|
||||
desc_ov%matrix_data(psb_n_col_)=n_col
|
||||
desc_ov%matrix_data(psb_n_col_) = n_col
|
||||
|
||||
end if
|
||||
|
||||
|
||||
@@ -122,7 +122,8 @@ Subroutine psb_zcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
Call psb_info(ictxt, me, np)
|
||||
|
||||
If (debug_level >= psb_debug_outer_) &
|
||||
& Write(debug_unit,*) me,' ',trim(name),': start',novr
|
||||
& Write(debug_unit,*) me,' ',trim(name),&
|
||||
& ': start',novr
|
||||
|
||||
if (present(extype)) then
|
||||
extype_ = extype
|
||||
@@ -144,7 +145,8 @@ Subroutine psb_zcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
endif
|
||||
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),':Calling desccpy'
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ':Calling desccpy'
|
||||
call psb_cdcpy(desc_a,desc_ov,info)
|
||||
if (info /= 0) then
|
||||
info=4010
|
||||
@@ -153,7 +155,9 @@ Subroutine psb_zcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),':From desccpy'
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ':From desccpy'
|
||||
|
||||
if (novr==0) then
|
||||
!
|
||||
! Just copy the input.
|
||||
@@ -164,7 +168,8 @@ Subroutine psb_zcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
|
||||
|
||||
If (debug_level >= psb_debug_outer_)then
|
||||
Write(debug_unit,*) me,' ',trim(name),':BEGIN ',nhalo
|
||||
Write(debug_unit,*) me,' ',trim(name),&
|
||||
& ':BEGIN ',nhalo
|
||||
call psb_barrier(ictxt)
|
||||
endif
|
||||
|
||||
@@ -179,7 +184,7 @@ Subroutine psb_zcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
lworks = ((nztot+m-1)/m)*nhalo
|
||||
lworkr = ((nztot+m-1)/m)*nhalo
|
||||
else
|
||||
info=-1
|
||||
info = -1
|
||||
call psb_errpush(info,name)
|
||||
goto 9999
|
||||
endif
|
||||
@@ -234,12 +239,12 @@ Subroutine psb_zcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
tmp_ovr_idx(:) = -1
|
||||
orig_ovr(:) = -1
|
||||
tmp_halo(:) = -1
|
||||
counter_e = 1
|
||||
tot_recv = 0
|
||||
counter_t = 1
|
||||
counter_h = 1
|
||||
counter_o = 1
|
||||
cntov_o = 1
|
||||
counter_e = 1
|
||||
tot_recv = 0
|
||||
counter_t = 1
|
||||
counter_h = 1
|
||||
counter_o = 1
|
||||
cntov_o = 1
|
||||
! Init overlap with desc_a%ovrlap (if any)
|
||||
counter = 1
|
||||
Do While (desc_a%ovrlap_index(counter) /= -1)
|
||||
@@ -300,7 +305,8 @@ Subroutine psb_zcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
Do i_ovr = 1, novr
|
||||
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),':Running on overlap level ',i_ovr,' of ',novr
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ':Running on overlap level ',i_ovr,' of ',novr
|
||||
|
||||
!
|
||||
! At this point, halo contains a valid halo corresponding to the
|
||||
@@ -332,7 +338,8 @@ Subroutine psb_zcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
end If
|
||||
tot_recv=tot_recv+n_elem_recv
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),': tot_recv:',proc,n_elem_recv,tot_recv
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ': tot_recv:',proc,n_elem_recv,tot_recv
|
||||
!
|
||||
!
|
||||
! The format of the halo vector exists in two forms: 1. Temporary
|
||||
@@ -367,10 +374,10 @@ Subroutine psb_zcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
tmp_ovr_idx(counter_o)=proc
|
||||
tmp_ovr_idx(counter_o+1)=1
|
||||
tmp_ovr_idx(counter_o+2)=gidx
|
||||
tmp_ovr_idx(counter_o+3)=-1
|
||||
tmp_ovr_idx(counter_o) = proc
|
||||
tmp_ovr_idx(counter_o+1) = 1
|
||||
tmp_ovr_idx(counter_o+2) = gidx
|
||||
tmp_ovr_idx(counter_o+3) = -1
|
||||
counter_o=counter_o+3
|
||||
call psb_ensure_size((counter_h+3),tmp_halo,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
@@ -379,10 +386,10 @@ Subroutine psb_zcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
tmp_halo(counter_h)=proc
|
||||
tmp_halo(counter_h+1)=1
|
||||
tmp_halo(counter_h+2)=idx
|
||||
tmp_halo(counter_h+3)=-1
|
||||
tmp_halo(counter_h) = proc
|
||||
tmp_halo(counter_h+1) = 1
|
||||
tmp_halo(counter_h+2) = idx
|
||||
tmp_halo(counter_h+3) = -1
|
||||
|
||||
counter_h=counter_h+3
|
||||
|
||||
@@ -410,10 +417,10 @@ Subroutine psb_zcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
tmp_ovr_idx(counter_o)=proc
|
||||
tmp_ovr_idx(counter_o+1)=1
|
||||
tmp_ovr_idx(counter_o+2)=gidx
|
||||
tmp_ovr_idx(counter_o+3)=-1
|
||||
tmp_ovr_idx(counter_o) = proc
|
||||
tmp_ovr_idx(counter_o+1) = 1
|
||||
tmp_ovr_idx(counter_o+2) = gidx
|
||||
tmp_ovr_idx(counter_o+3) = -1
|
||||
counter_o=counter_o+3
|
||||
|
||||
!
|
||||
@@ -465,6 +472,7 @@ Subroutine psb_zcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ':Checktmp_o_i Loop Mid2',tmp_ovr_idx(1:10)
|
||||
|
||||
sdsz(proc+1) = tot_elem
|
||||
idxs = idxs + tot_elem
|
||||
end if
|
||||
@@ -516,7 +524,7 @@ Subroutine psb_zcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
call psb_errpush(info,name,a_err=ch_err)
|
||||
goto 9999
|
||||
end if
|
||||
lworkr=max(iszr,1)
|
||||
lworkr = max(iszr,1)
|
||||
end if
|
||||
|
||||
call mpi_alltoallv(works,sdsz,bsdindx,mpi_integer,&
|
||||
@@ -548,12 +556,15 @@ Subroutine psb_zcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
works(j) = workr(i)
|
||||
end if
|
||||
end do
|
||||
! Eliminate duplicates from request
|
||||
call psb_msort_unique(works(1:j),iszs)
|
||||
|
||||
!
|
||||
! fnd_owner on desc_a because we want the procs who
|
||||
! owned the rows from the beginning!
|
||||
!
|
||||
call psi_fnd_owner(iszs,works,temp,desc_a,info)
|
||||
n_col=psb_cd_get_local_cols(desc_ov)
|
||||
n_col = psb_cd_get_local_cols(desc_ov)
|
||||
|
||||
do i=1,iszs
|
||||
idx = works(i)
|
||||
@@ -574,11 +585,11 @@ Subroutine psb_zcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
t_halo_in(counter_t)=proc_id
|
||||
t_halo_in(counter_t+1)=1
|
||||
t_halo_in(counter_t+2)=lidx
|
||||
t_halo_in(counter_t+3)=-1
|
||||
counter_t=counter_t+3
|
||||
t_halo_in(counter_t) = proc_id
|
||||
t_halo_in(counter_t+1) = 1
|
||||
t_halo_in(counter_t+2) = lidx
|
||||
t_halo_in(counter_t+3) = -1
|
||||
counter_t = counter_t+3
|
||||
endif
|
||||
end Do
|
||||
n_col = psb_cd_get_local_cols(desc_ov)
|
||||
@@ -595,8 +606,8 @@ Subroutine psb_zcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
! we receive them guarantees that all indices for HALO(I)
|
||||
! will be less than those for HALO(J) whenever I<J
|
||||
!
|
||||
n_col=n_col+1
|
||||
proc_id=-desc_ov%glob_to_loc(idx)-np-1
|
||||
n_col = n_col+1
|
||||
proc_id = -desc_ov%glob_to_loc(idx)-np-1
|
||||
call psb_ensure_size(n_col,desc_ov%loc_to_glob,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
info=4010
|
||||
@@ -604,8 +615,8 @@ Subroutine psb_zcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
desc_ov%glob_to_loc(idx)=n_col
|
||||
desc_ov%loc_to_glob(n_col)=idx
|
||||
desc_ov%glob_to_loc(idx) = n_col
|
||||
desc_ov%loc_to_glob(n_col) = idx
|
||||
|
||||
call psb_ensure_size((counter_t+3),t_halo_in,info,pad=-1)
|
||||
if (info /= 0) then
|
||||
@@ -614,21 +625,23 @@ Subroutine psb_zcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
t_halo_in(counter_t)=proc_id
|
||||
t_halo_in(counter_t+1)=1
|
||||
t_halo_in(counter_t+2)=n_col
|
||||
t_halo_in(counter_t+3)=-1
|
||||
t_halo_in(counter_t) = proc_id
|
||||
t_halo_in(counter_t+1) = 1
|
||||
t_halo_in(counter_t+2) = n_col
|
||||
t_halo_in(counter_t+3) = -1
|
||||
counter_t=counter_t+3
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),': Added into t_halo_in from recv',&
|
||||
&proc_id,n_col,idx
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ': Added into t_halo_in from recv',&
|
||||
& proc_id,n_col,idx
|
||||
else if (desc_ov%glob_to_loc(idx) < 0) Then
|
||||
if (debug_level >= psb_debug_outer_) &
|
||||
& write(debug_unit,*) me,' ',trim(name),':Wrong input to cdbldextbld?',&
|
||||
&idx,desc_ov%glob_to_loc(idx)
|
||||
& write(debug_unit,*) me,' ',trim(name),&
|
||||
& ':Wrong input to cdbldextbld?',&
|
||||
& idx,desc_ov%glob_to_loc(idx)
|
||||
End If
|
||||
End Do
|
||||
desc_ov%matrix_data(psb_n_col_)=n_col
|
||||
desc_ov%matrix_data(psb_n_col_) = n_col
|
||||
|
||||
end if
|
||||
|
||||
@@ -691,7 +704,7 @@ Subroutine psb_zcdbldext(a,desc_a,novr,desc_ov,info, extype)
|
||||
call psb_errpush(4010,name,a_err='deallocate')
|
||||
goto 9999
|
||||
end if
|
||||
|
||||
|
||||
case(psb_ovt_asov_)
|
||||
!
|
||||
! Build an overlapped descriptor for Additive Schwarz
|
||||
|
||||
@@ -728,6 +728,7 @@ INSTALL
|
||||
INSTALL_DIR
|
||||
INSTALL_LIBDIR
|
||||
INSTALL_INCLUDEDIR
|
||||
INSTALL_DOCSDIR
|
||||
BLACS_LIBS
|
||||
METIS_LIBS
|
||||
CINCLUDES
|
||||
@@ -1988,8 +1989,12 @@ case $includedir in
|
||||
\/* ) eval "INSTALL_INCLUDEDIR=$includedir";;
|
||||
* ) eval "INSTALL_INCLUDEDIR=$INSTALL_DIR/include";;
|
||||
esac
|
||||
{ echo "$as_me:$LINENO: result: $INSTALL_DIR $INSTALL_INCLUDEDIR $INSTALL_LIBDIR" >&5
|
||||
echo "${ECHO_T}$INSTALL_DIR $INSTALL_INCLUDEDIR $INSTALL_LIBDIR" >&6; }
|
||||
case $docsdir in
|
||||
\/* ) eval "INSTALL_DOCSDIR=$docsdir";;
|
||||
* ) eval "INSTALL_DOCSDIR=$INSTALL_DIR/docs";;
|
||||
esac
|
||||
{ echo "$as_me:$LINENO: result: $INSTALL_DIR $INSTALL_INCLUDEDIR $INSTALL_LIBDIR $INSTALL_DOCSDIR" >&5
|
||||
echo "${ECHO_T}$INSTALL_DIR $INSTALL_INCLUDEDIR $INSTALL_LIBDIR $INSTALL_DOCSDIR" >&6; }
|
||||
|
||||
# Note that the following line won't save from troubles.
|
||||
# AC_PROG_FC([mpxlf95 mpxlf90 mpxlf pgf95 pgf90 mpif95 mpif90 gfortran f95 f90 ifc])
|
||||
@@ -10603,6 +10608,7 @@ UTILLIBNAME=libpsb_util.a
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if test "X$psblas_make_gnumake" == "Xyes" ; then
|
||||
@@ -11501,6 +11507,7 @@ INSTALL!$INSTALL$ac_delim
|
||||
INSTALL_DIR!$INSTALL_DIR$ac_delim
|
||||
INSTALL_LIBDIR!$INSTALL_LIBDIR$ac_delim
|
||||
INSTALL_INCLUDEDIR!$INSTALL_INCLUDEDIR$ac_delim
|
||||
INSTALL_DOCSDIR!$INSTALL_DOCSDIR$ac_delim
|
||||
BLACS_LIBS!$BLACS_LIBS$ac_delim
|
||||
METIS_LIBS!$METIS_LIBS$ac_delim
|
||||
CINCLUDES!$CINCLUDES$ac_delim
|
||||
@@ -11514,7 +11521,7 @@ LIBOBJS!$LIBOBJS$ac_delim
|
||||
LTLIBOBJS!$LTLIBOBJS$ac_delim
|
||||
_ACEOF
|
||||
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 27; then
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 28; then
|
||||
break
|
||||
elif $ac_last_try; then
|
||||
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
|
||||
|
||||
@@ -89,7 +89,11 @@ case $includedir in
|
||||
\/* ) eval "INSTALL_INCLUDEDIR=$includedir";;
|
||||
* ) eval "INSTALL_INCLUDEDIR=$INSTALL_DIR/include";;
|
||||
esac
|
||||
AC_MSG_RESULT([$INSTALL_DIR $INSTALL_INCLUDEDIR $INSTALL_LIBDIR])
|
||||
case $docsdir in
|
||||
\/* ) eval "INSTALL_DOCSDIR=$docsdir";;
|
||||
* ) eval "INSTALL_DOCSDIR=$INSTALL_DIR/docs";;
|
||||
esac
|
||||
AC_MSG_RESULT([$INSTALL_DIR $INSTALL_INCLUDEDIR $INSTALL_LIBDIR $INSTALL_DOCSDIR])
|
||||
|
||||
# Note that the following line won't save from troubles.
|
||||
# AC_PROG_FC([mpxlf95 mpxlf90 mpxlf pgf95 pgf90 mpif95 mpif90 gfortran f95 f90 ifc])
|
||||
@@ -643,6 +647,7 @@ AC_SUBST(INSTALL_DATA)
|
||||
AC_SUBST(INSTALL_DIR)
|
||||
AC_SUBST(INSTALL_LIBDIR)
|
||||
AC_SUBST(INSTALL_INCLUDEDIR)
|
||||
AC_SUBST(INSTALL_DOCSDIR)
|
||||
|
||||
AC_SUBST(BLAS_LIBS)
|
||||
AC_SUBST(BLACS_LIBS)
|
||||
|
||||
@@ -25,7 +25,7 @@ original version by: Nikos Drakos, CBLU, University of Leeds
|
||||
<BODY >
|
||||
|
||||
<DL>
|
||||
<DT><A NAME="foot164">...
|
||||
<DT><A NAME="foot165">...
|
||||
explicitly</A><A
|
||||
HREF="node3.html#tex2html2"><SUP>1</SUP></A></DT>
|
||||
<DD>In our prototype implementation we provide
|
||||
@@ -63,7 +63,7 @@ sample scatter/gather routines.
|
||||
.
|
||||
</PRE>
|
||||
</DD>
|
||||
<DT><A NAME="foot173">... domain</A><A
|
||||
<DT><A NAME="foot174">... domain</A><A
|
||||
HREF="node4.html#tex2html3"><SUP>2</SUP></A></DT>
|
||||
<DD>This is
|
||||
the normal situation when the pattern of the sparse matrix is
|
||||
@@ -104,7 +104,7 @@ sample scatter/gather routines.
|
||||
.
|
||||
</PRE>
|
||||
</DD>
|
||||
<DT><A NAME="foot6689">... follows</A><A
|
||||
<DT><A NAME="foot6717">... follows</A><A
|
||||
HREF="node99.html#tex2html28"><SUP>3</SUP></A></DT>
|
||||
<DD>The string is case-insensitive
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 544 B After Width: | Height: | Size: 393 B |
|
Before Width: | Height: | Size: 255 B After Width: | Height: | Size: 341 B |
|
Before Width: | Height: | Size: 387 B After Width: | Height: | Size: 258 B |
|
Before Width: | Height: | Size: 250 B After Width: | Height: | Size: 193 B |
|
Before Width: | Height: | Size: 244 B After Width: | Height: | Size: 134 B |
|
Before Width: | Height: | Size: 276 B After Width: | Height: | Size: 255 B |
|
Before Width: | Height: | Size: 374 B After Width: | Height: | Size: 387 B |
|
Before Width: | Height: | Size: 222 B After Width: | Height: | Size: 250 B |
|
Before Width: | Height: | Size: 259 B After Width: | Height: | Size: 244 B |
|
Before Width: | Height: | Size: 804 B After Width: | Height: | Size: 276 B |
|
Before Width: | Height: | Size: 408 B After Width: | Height: | Size: 374 B |
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 544 B |
|
Before Width: | Height: | Size: 419 B After Width: | Height: | Size: 222 B |
|
Before Width: | Height: | Size: 354 B After Width: | Height: | Size: 259 B |
|
Before Width: | Height: | Size: 310 B After Width: | Height: | Size: 804 B |
|
Before Width: | Height: | Size: 835 B After Width: | Height: | Size: 408 B |
|
Before Width: | Height: | Size: 335 B After Width: | Height: | Size: 419 B |
|
Before Width: | Height: | Size: 497 B After Width: | Height: | Size: 354 B |
|
Before Width: | Height: | Size: 403 B After Width: | Height: | Size: 310 B |
|
Before Width: | Height: | Size: 266 B After Width: | Height: | Size: 835 B |
|
Before Width: | Height: | Size: 533 B After Width: | Height: | Size: 335 B |
|
Before Width: | Height: | Size: 544 B After Width: | Height: | Size: 497 B |
|
Before Width: | Height: | Size: 240 B After Width: | Height: | Size: 129 B |
|
Before Width: | Height: | Size: 334 B After Width: | Height: | Size: 403 B |
|
Before Width: | Height: | Size: 231 B After Width: | Height: | Size: 266 B |
|
Before Width: | Height: | Size: 519 B After Width: | Height: | Size: 533 B |
|
Before Width: | Height: | Size: 604 B After Width: | Height: | Size: 544 B |
|
Before Width: | Height: | Size: 577 B After Width: | Height: | Size: 334 B |
|
Before Width: | Height: | Size: 210 B After Width: | Height: | Size: 231 B |
|
Before Width: | Height: | Size: 568 B After Width: | Height: | Size: 519 B |
|
Before Width: | Height: | Size: 743 B After Width: | Height: | Size: 604 B |
|
Before Width: | Height: | Size: 276 B After Width: | Height: | Size: 577 B |
|
Before Width: | Height: | Size: 521 B After Width: | Height: | Size: 210 B |
|
Before Width: | Height: | Size: 192 B After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 267 B After Width: | Height: | Size: 568 B |
|
Before Width: | Height: | Size: 568 B After Width: | Height: | Size: 743 B |
|
Before Width: | Height: | Size: 239 B After Width: | Height: | Size: 276 B |
|
Before Width: | Height: | Size: 0 B After Width: | Height: | Size: 521 B |
|
Before Width: | Height: | Size: 0 B After Width: | Height: | Size: 267 B |
|
Before Width: | Height: | Size: 371 B After Width: | Height: | Size: 568 B |
|
Before Width: | Height: | Size: 431 B After Width: | Height: | Size: 239 B |
|
Before Width: | Height: | Size: 916 B After Width: | Height: | Size: 0 B |
|
Before Width: | Height: | Size: 677 B After Width: | Height: | Size: 0 B |
|
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 371 B |