Page MenuHomec4science

gather_pivoted_approximant.py
No OneTemporary

File Metadata

Created
Tue, Nov 5, 20:32

gather_pivoted_approximant.py

# Copyright (C) 2018-2020 by the RROMPy authors
#
# This file is part of RROMPy.
#
# RROMPy is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# RROMPy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with RROMPy. If not, see <http://www.gnu.org/licenses/>.
#
import numpy as np
from rrompy.utilities.base.types import Np2D, Tuple, List, interpEng
from rrompy.utilities.poly_fitting.polynomial import (PolynomialInterpolator,
PolynomialInterpolatorNodal)
from rrompy.utilities.parallel.base import (COMM, allowParallelExecution,
forcedSerial)
def gatherPivotedApproximant(pMat:Np2D, Ps:List[interpEng], Qs:List[interpEng],
mus:Np2D, sizes:List[int], polybasis:str,
send_mus : bool = True) \
-> Tuple[Np2D, List[interpEng],
List[interpEng], Np2D, List[int]]:
allowParallelExecution(True)
Qnodal = isinstance(Qs[0], PolynomialInterpolatorNodal)
sizes, sumsizes = np.array(sizes, dtype = int), np.sum(sizes)
npar, samplesize = mus.shape[1], pMat.shape[0]
shapePQ = np.array([[P.deg[0] + 1, P.shape[0], Q.deg[0] + 1 - Qnodal]
for P, Q in zip(Ps, Qs)], dtype = int).flatten()
if forcedSerial() or len(sizes) == 1:
return pMat, Ps, Qs, mus, list(shapePQ[1::3])
# share shapes of local Ps and Qs
shapePQs = np.empty(3 * sumsizes, dtype = int)
COMM.Allgatherv(shapePQ, [shapePQs, 3 * sizes])
sP = np.hstack((shapePQs[::3].reshape(-1, 1),
shapePQs[1::3].reshape(-1, 1)))
sQ = shapePQs[2::3]
# compute cumulative shapes of all Ps and Qs
sizesP, sizesQ, sizespMat = [], [], []
if send_mus: sizesmu = []
sizeOld = 0
for size in sizes:
sizesP += [np.sum(np.product(sP[sizeOld : sizeOld + size], axis = 1))]
sizesQ += [np.sum(sQ[sizeOld : sizeOld + size])]
sizespMat += [samplesize * np.sum(sP[sizeOld : sizeOld + size, 1])]
if send_mus:
sizesmu += [npar * np.sum(sP[sizeOld : sizeOld + size, 1])]
sizeOld += size
# initiate nonblocking gathers
pMatflat = pMat.T.flatten()
if len(shapePQ) > 0:
Pflat = np.concatenate([P.coeffs.flatten() for P in Ps])
if Qnodal:
Qflat = np.concatenate([Q.poles for Q in Qs])
else:
Qflat = np.concatenate([np.squeeze(Q.coeffs) for Q in Qs])
else:
Pflat = np.zeros(0, dtype = pMat.dtype)
Qflat = np.zeros(0, dtype = np.complex)
pMatsflat = np.empty(np.sum(sizespMat), dtype = pMat.dtype)
Psflat = np.empty(np.sum(sizesP), dtype = Pflat.dtype)
Qsflat = np.empty(np.sum(sizesQ), dtype = Qflat.dtype)
pMatreq = COMM.Iallgatherv(pMatflat, [pMatsflat, sizespMat])
Preq = COMM.Iallgatherv(Pflat, [Psflat, sizesP])
Qreq = COMM.Iallgatherv(Qflat, [Qsflat, sizesQ])
if send_mus:
musflat = np.empty(np.sum(sizesmu), dtype = mus.dtype)
mureq = COMM.Iallgatherv(mus.flatten(), [musflat, sizesmu])
# post-process data
pMatreq.wait()
pMat = pMatsflat.reshape(-1, samplesize).T
Preq.wait()
Ps, shift = [], 0
for sPj in sP:
currSize = np.product(sPj)
P = PolynomialInterpolator()
P.coeffs = Psflat[shift : shift + currSize].reshape(sPj)
P.npar = 1
P.polybasis = polybasis
Ps += [P]
shift += currSize
Qreq.wait()
Qs, shift = [], 0
for currSize in sQ:
if Qnodal:
Q = PolynomialInterpolatorNodal()
Q.poles = Qsflat[shift : shift + currSize]
else:
Q = PolynomialInterpolator()
Q.coeffs = Qsflat[shift : shift + currSize]
Q.npar = 1
Q.polybasis = polybasis
Qs += [Q]
shift += currSize
if send_mus:
mureq.wait()
mus = musflat.reshape(-1, npar)
return pMat, Ps, Qs, mus, list(sP[:, 1])

Event Timeline