From e228fbdc5b2d1a3b0c20c97c3b7f6ae6a8898d23 Mon Sep 17 00:00:00 2001 From: Michele Simionato Date: Sat, 14 Oct 2023 08:41:39 +0200 Subject: [PATCH] Skipping useless calculations --- openquake/hazardlib/calc/gmf.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/openquake/hazardlib/calc/gmf.py b/openquake/hazardlib/calc/gmf.py index 2ced07e103e8..6116eee8376e 100644 --- a/openquake/hazardlib/calc/gmf.py +++ b/openquake/hazardlib/calc/gmf.py @@ -267,35 +267,38 @@ def compute_all(self, max_iml=None, rng = numpy.random.default_rng(self.seed) data = AccumDict(accum=[]) for g, (gs, rlzs) in enumerate(self.cmaker.gsims.items()): + idxs, = numpy.where(numpy.isin(self.rlz, rlzs)) + E = len(idxs) + if E == 0: # crucial for performance + continue with cmon: - array = self.compute(gs, rlzs, mean_stds[:, g], rng) # NME + array = self.compute(gs, idxs, mean_stds[:, g], rng) # NME with umon: self.update(data, array, rlzs, mean_stds[:, g], max_iml) with umon: return self.strip_zeros(data) - def compute(self, gsim, rlzs, mean_stds, rng): + def compute(self, gsim, idxs, mean_stds, rng): """ :param gsim: GSIM used to compute mean_stds - :param rlzs: realizations associated to the gsim + :param idxs: affected indices :param mean_stds: array of shape (4, M, N) :param rng: random number generator for the rupture :returns: a 32 bit array of shape (N, M, E) """ # sets self.eps M = len(self.imts) - mask = numpy.isin(self.rlz, rlzs) - E = mask.sum() + E = len(idxs) result = numpy.zeros( (len(self.imts), len(self.ctx.sids), E), F32) ccdist = self.cross_correl.distribution # build arrays of random numbers of shape (M, N, E) and (M, E) intra_eps = [ccdist.rvs((self.N, E), rng) for _ in range(M)] - self.eps[mask] = self.cross_correl.get_inter_eps(self.imts, E, rng).T + self.eps[idxs] = self.cross_correl.get_inter_eps(self.imts, E, rng).T for m, imt in enumerate(self.imts): try: result[m] = self._compute( - mean_stds[:, m], m, imt, gsim, intra_eps[m], mask) + mean_stds[:, m], m, imt, gsim, intra_eps[m], idxs) except Exception as exc: raise RuntimeError( '(%s, %s, source_id=%r) %s: %s' % @@ -307,7 +310,7 @@ def compute(self, gsim, rlzs, mean_stds, rng): self.ctx.ampcode, result, self.imts, self.seed) return result.transpose(1, 0, 2) - def _compute(self, mean_stds, m, imt, gsim, intra_eps, mask): + def _compute(self, mean_stds, m, imt, gsim, intra_eps, idxs): # sets self.sig im = imt.string if self.cmaker.truncation_level <= 1E-9: @@ -329,7 +332,7 @@ def _compute(self, mean_stds, m, imt, gsim, intra_eps, mask): mean, sig, _, _ = mean_stds gmf = exp(mean[:, None] + sig[:, None] * intra_eps, im!='MMI') - self.sig[mask, m] = numpy.nan + self.sig[idxs, m] = numpy.nan else: mean, sig, tau, phi = mean_stds # the [:, None] is used to implement multiplication by row; @@ -344,10 +347,10 @@ def _compute(self, mean_stds, m, imt, gsim, intra_eps, mask): if len(intra_res.shape) == 1: # a vector intra_res = intra_res[:, None] - inter_res = tau[:, None] * self.eps[mask, m] + inter_res = tau[:, None] * self.eps[idxs, m] # shape (N, 1) * E => (N, E) gmf = exp(mean[:, None] + intra_res + inter_res, im!='MMI') - self.sig[mask, m] = tau.max() # from shape (N, 1) => scalar + self.sig[idxs, m] = tau.max() # from shape (N, 1) => scalar return gmf # shapes (N, E)