Esempio n. 1
0
    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()
Esempio n. 2
0
    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()
Esempio n. 3
0
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))