def test_test2(self): """ Apply the laplacian finite difference operator to clt """ f = cdms2.open(cdat_info.get_prefix() + '/sample_data/clt.nc', 'r') cltVar = f['clt'] # global sizes nLat, nLon = cltVar.shape[1:] # local rank and number of procs rk = MPI.COMM_WORLD.Get_rank() sz = MPI.COMM_WORLD.Get_size() # compute domain decomposition decomp = CubeDecomp(sz, (nLat, nLon)) # number of processors along each axis npLat, npLon = None, None # list of slices slab = decomp.getSlab(rk) dc = decomp.getDecomp() if dc is not None: npLat, npLon = dc if rk == 0: print '' print 'lat x lon sizes : %d x %d ' % (nLat, nLon) print 'lat x lon domain decomp: %d x %d ' % (npLat, npLon) else: if rk == 0: print 'No uniform decomp could be found for %d procs' % sz sys.exit(1) # starting/ending indices for local domain iLatBeg, iLatEnd = slab[0].start, slab[0].stop iLonBeg, iLonEnd = slab[1].start, slab[1].stop # now read local domain data for time 0 clt = cltVar[0, iLatBeg:iLatEnd, iLonBeg:iLonEnd] # make halo available to other procs numGhosts = 1 clt.exposeHalo(ghostWidth=numGhosts) # compute the star Laplacian in the interior, this does not require # any communication # laplacian = 4*clt[j, i] - clt[j+1, i] - clt[j-1, i] - clt[j, i+1] - clt[j, i-1] # data domain laplaceClt = 4 * clt[:] # local neighbor contributions, no communication laplaceClt[1:, :] -= clt[0:-1, :] laplaceClt[0:-1, :] -= clt[1:, :] laplaceClt[:, 1:] -= clt[:, 0:-1] laplaceClt[:, 0:-1] -= clt[:, 1:] # now compute and fill in the halo # find the procs to the north, east, south, and west. This call will # return None if there is no neighbor. noProc = decomp.getNeighborProc(rk, (1, 0), periodic=(False, True)) soProc = decomp.getNeighborProc(rk, (-1, 0), periodic=(False, True)) eaProc = decomp.getNeighborProc(rk, (0, 1), periodic=(False, True)) weProc = decomp.getNeighborProc(rk, (0, -1), periodic=(False, True)) # correct at north/south poles where zero flux condition applies if noProc is None: laplaceClt[-1, :] -= clt[-1, :] if soProc is None: laplaceClt[0, :] -= clt[0, :] # fetch the remote data in the halo of the neighboring processor. When # the first argument is None, this amounts to a no-op (zero data are # returned. Note that side refers to the neighbour domain. For instance, # the data to the west of the local domain correspond to the east halo # on the neighbouring processor. weCltData = clt.fetchHaloData(weProc, side=(0, +1)) eaCltData = clt.fetchHaloData(eaProc, side=(0, -1)) soCltData = clt.fetchHaloData(soProc, side=(+1, 0)) noCltData = clt.fetchHaloData(noProc, side=(-1, 0)) # finish the operator weSlc = clt.getHaloEllipsis(side=(0, -1)) eaSlc = clt.getHaloEllipsis(side=(0, +1)) soSlc = clt.getHaloEllipsis(side=(-1, 0)) noSlc = clt.getHaloEllipsis(side=(+1, 0)) laplaceClt[weSlc] -= weCltData laplaceClt[eaSlc] -= eaCltData if soProc is not None: laplaceClt[soSlc] -= soCltData if noProc is not None: laplaceClt[noSlc] -= noCltData if True: laplaceClt0 = numpy.zeros(cltVar.shape[1:], cltVar.dtype) # gather the data on proc 0 laplaceClt0List = MPI.COMM_WORLD.gather(laplaceClt, root=0) checksum = 0 if rk == 0: for proc in range(sz): slab = decomp.getSlab(proc) iLatBeg, iLatEnd = slab[0].start, slab[0].stop iLonBeg, iLonEnd = slab[1].start, slab[1].stop laplaceClt0[iLatBeg:iLatEnd, iLonBeg:iLonEnd] = \ laplaceClt0List[proc] checksum = laplaceClt0.sum() print 'checksum = %20.15g' % checksum if False: # plot lat = cltVar.getLatitude() lon = cltVar.getLongitude() latmin, latmax = lat[:].min(), lat[:].max() lonmin, lonmax = lon[:].min(), lon[:].max() mp = Basemap(llcrnrlat=latmin, urcrnrlat=latmax, llcrnrlon=lonmin, urcrnrlon=lonmax, projection='cyl', resolution='l') mp.pcolor(lon[:], lat[:], laplaceClt0) mp.colorbar() mp.drawcoastlines() pylab.title('Laplacian of clt') # checks self.assertLess(abs(checksum), 1.e-3) # clean up clt.freeHalo()
def test_test2(self): """ Apply the laplacian finite difference operator to clt """ f = cdms2.open(cdat_info.get_prefix() + '/sample_data/clt.nc', 'r') cltVar = f['clt'] # global sizes nLat, nLon = cltVar.shape[1:] # local rank and number of procs rk = MPI.COMM_WORLD.Get_rank() sz = MPI.COMM_WORLD.Get_size() # compute domain decomposition decomp = CubeDecomp(sz, (nLat, nLon)) # number of processors along each axis npLat, npLon = None, None # list of slices slab = decomp.getSlab(rk) dc = decomp.getDecomp() if dc is not None: npLat, npLon = dc if rk == 0: print '' print 'lat x lon sizes : %d x %d ' % (nLat, nLon) print 'lat x lon domain decomp: %d x %d ' % (npLat, npLon) else: if rk == 0: print 'No uniform decomp could be found for %d procs' % sz sys.exit(1) # starting/ending indices for local domain iLatBeg, iLatEnd = slab[0].start, slab[0].stop iLonBeg, iLonEnd = slab[1].start, slab[1].stop # now read local domain data for time 0 clt = cltVar[0, iLatBeg:iLatEnd, iLonBeg:iLonEnd] # make halo available to other procs numGhosts = 1 clt.exposeHalo(ghostWidth = numGhosts) # compute the star Laplacian in the interior, this does not require # any communication # laplacian = 4*clt[j, i] - clt[j+1, i] - clt[j-1, i] - clt[j, i+1] - clt[j, i-1] # data domain laplaceClt = 4 * clt[:] # local neighbor contributions, no communication laplaceClt[1: , :] -= clt[0:-1,:] laplaceClt[0:-1, :] -= clt[1: ,:] laplaceClt[:, 1: ] -= clt[:,0:-1] laplaceClt[:, 0:-1] -= clt[:,1: ] # now compute and fill in the halo # find the procs to the north, east, south, and west. This call will # return None if there is no neighbor. noProc = decomp.getNeighborProc(rk, ( 1, 0), periodic = (False, True)) soProc = decomp.getNeighborProc(rk, (-1, 0), periodic = (False, True)) eaProc = decomp.getNeighborProc(rk, ( 0, 1), periodic = (False, True)) weProc = decomp.getNeighborProc(rk, ( 0, -1), periodic = (False, True)) # correct at north/south poles where zero flux condition applies if noProc is None: laplaceClt[-1,:] -= clt[-1,:] if soProc is None: laplaceClt[0,:] -= clt[0,:] # fetch the remote data in the halo of the neighboring processor. When # the first argument is None, this amounts to a no-op (zero data are # returned. Note that side refers to the neighbour domain. For instance, # the data to the west of the local domain correspond to the east halo # on the neighbouring processor. weCltData = clt.fetchHaloData(weProc, side=(0, +1)) eaCltData = clt.fetchHaloData(eaProc, side=(0, -1)) soCltData = clt.fetchHaloData(soProc, side=(+1, 0)) noCltData = clt.fetchHaloData(noProc, side=(-1, 0)) # finish the operator weSlc = clt.getHaloEllipsis(side=(0, -1)) eaSlc = clt.getHaloEllipsis(side=(0, +1)) soSlc = clt.getHaloEllipsis(side=(-1, 0)) noSlc = clt.getHaloEllipsis(side=(+1, 0)) laplaceClt[weSlc] -= weCltData laplaceClt[eaSlc] -= eaCltData if soProc is not None: laplaceClt[soSlc] -= soCltData if noProc is not None: laplaceClt[noSlc] -= noCltData if True: laplaceClt0 = numpy.zeros(cltVar.shape[1:], cltVar.dtype) # gather the data on proc 0 laplaceClt0List = MPI.COMM_WORLD.gather(laplaceClt, root = 0) checksum = 0 if rk == 0: for proc in range(sz): slab = decomp.getSlab(proc) iLatBeg, iLatEnd = slab[0].start, slab[0].stop iLonBeg, iLonEnd = slab[1].start, slab[1].stop laplaceClt0[iLatBeg:iLatEnd, iLonBeg:iLonEnd] = \ laplaceClt0List[proc] checksum = laplaceClt0.sum() print 'checksum = %20.15g' % checksum if False: # plot lat = cltVar.getLatitude() lon = cltVar.getLongitude() latmin, latmax = lat[:].min(), lat[:].max() lonmin, lonmax = lon[:].min(), lon[:].max() mp = Basemap(llcrnrlat = latmin, urcrnrlat = latmax, llcrnrlon = lonmin, urcrnrlon = lonmax, projection = 'cyl', resolution = 'l') mp.pcolor(lon[:], lat[:], laplaceClt0) mp.colorbar() mp.drawcoastlines() pylab.title('Laplacian of clt') # checks self.assertLess(abs(checksum), 1.e-3) # clean up clt.freeHalo()
def getDomainDecomp(nprocs,sizes): latPrimeNumbers = getPrimeFactors(sizes[0]) lonPrimeNumbers = getPrimeFactors(sizes[1]) lonPrimeNumbers.reverse() for plat in latPrimeNumbers: for plon in lonPrimeNumbers: if plat * plon == nprocs: return [plat, plon] return None, None nLat,nLon = clt.shape[1:] rk = MPI.COMM_WORLD.Get_rank() sz = MPI.COMM_WORLD.Get_size() decomp = CubeDecomp(sz, (nLat,nLon)) npLat,npLon = decomp.getDecomp() slab = decomp.getSlab(rk) print 'SLAB:',slab,type(slab) if npLat is None or npLon is None: print 'could not find a domain decomp for this number of procs' sys.exit(1) if rk == 0: print 'domain decomp: ', npLat, ' x ', npLon iLatBeg , iLatEnd = slab[0].start, slab[0].stop iLonBeg , iLonEnd = slab[1].start, slab[1].stop print '[%d] sub-domain slab: %d:%d, %d:%d dims %d x %d size: %d' % (rk, iLatBeg, iLatEnd, iLonBeg, iLatEnd, iLatEnd - iLatBeg, iLonEnd - iLonBeg, (iLatEnd - iLatBeg)*(iLonEnd - iLonBeg))