[petsc-users] petsc4py sparse matrix construction time

Cetinbas, Cankur Firat ccetinbas at anl.gov
Mon Oct 30 19:06:05 CDT 2017


Hello,

I am a beginner both in PETSc and mpi4py. I have been working on parallelizing our water transport code (where we solve linear system of equations) and I started with the toy code below.

The toy code reads right hand size (rh), row, column, value vectors to construct sparse coefficient matrix and then scatters them to construct parallel PETSc coefficient matrix and right hand side vector.

The sparse matrix generation time is extremely high in comparison to sps.csr_matrix((val, (row, col)), shape=(n,n)) in python. For instance python generates 181197x181197 sparse matrix in 0.06 seconds and this code with 32 cores:1.19s, 16 cores:6.98s and 8 cores:29.5 s.  I was wondering if I am making a mistake in generating sparse matrix? Is there a more efficient way?

Thanks for your help in advance.

Regards,

Firat

from petsc4py import PETSc
from mpi4py import MPI
import numpy as np
import time

comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()

if rank==0:
    # proc 0 loads tomo image and does fast calculations to append row, col, val, rh lists
    # in the real code this vectors will be available on proc 0 no txt files are read
    row = np.loadtxt('row.out')  # indices of non-zero rows
    col = np.loadtxt('col.out') # indices of non-zero columns
    val = np.loadtxt('vs.out')  # values in the sparse matrix
    rh = np.loadtxt('RHS.out') # right hand side vector
    n = row.shape[0]  #1045699
    m = rh.shape[0] #181197 square sparse matrix size
else:
    n = None
    m = None
    row = None
    col = None
    val = None
    rh = None
    rh_ind = None

m_lcl = comm.bcast(m,root=0)
n_lcl = comm.bcast(n,root=0)
neq = n_lcl//size
meq = m_lcl//size
nx = np.mod(n_lcl,size)
mx = np.mod(m_lcl,size)
row_lcl = np.zeros(neq)
col_lcl = np.zeros(neq)
val_lcl = np.zeros(neq)
rh_lcl = np.zeros(meq)
a = [neq]*size #send counts for Scatterv
am = [meq]*size #send counts for Scatterv

if nx>0:
    for i in range(0,nx):
        if rank==i:
            row_lcl = np.zeros(neq+1)
            col_lcl = np.zeros(neq+1)
            val_lcl = np.zeros(neq+1)
        a[i] = a[i]+1
if mx>0:
    for ii in range(0,mx):
        if rank==ii:
            rh_lcl = np.zeros(meq+1)
        am[ii] = am[ii]+1

comm.Scatterv([row,a],row_lcl)
comm.Scatterv([col,a],col_lcl)
comm.Scatterv([val,a],val_lcl)
comm.Scatterv([rh,am],rh_lcl)
comm.Barrier()

A = PETSc.Mat()
A.create()
A.setSizes([m_lcl,m_lcl])
A.setType('aij')
A.setUp()
lr = row_lcl.shape[0]
for i in range(0,lr):
    A[row_lcl[i],col_lcl[i]] = val_lcl[i]
A.assemblyBegin()
A.assemblyEnd()

if size>1: # to get the range for scattered vectors
    ami = [0]
    ami = np.array([0]+am).cumsum()
    for kk in range(0,size):
        if rank==kk:
            Is = ami[kk]
            Ie = ami[kk+1]
else:
    Is=0; Ie=m_lcl

b= PETSc.Vec()
b.create()
b.setSizes(m_lcl)
b.setFromOptions()
b.setUp()
b.setValues(list(range(Is,Ie)),rh_lcl)
b.assemblyBegin()
b.assemblyEnd()

# solution vector
x = b.duplicate()
x.assemblyBegin()
x.assemblyEnd()

# create linear solver
ksp = PETSc.KSP()
ksp.create()
ksp.setOperators(A)
ksp.setType('cg')
#ksp.getPC().setType('icc') # only sequential
ksp.getPC().setType('jacobi')
print('solving with:', ksp.getType())

#solve
st=time.time()
ksp.solve(b,x)
et=time.time()
print(et-st)

if size>1:
    #gather
    if rank==0:
        xGthr = np.zeros(m)
    else:
        xGthr = None
    comm.Gatherv(x,[xGthr,am])
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20171031/5b5bb841/attachment.html>


More information about the petsc-users mailing list