Esempio n. 1
0
    def test_iteration_parallelism_2d(self, exprs, atomic, parallel):
        """Tests detection of PARALLEL_* properties."""
        grid = Grid(shape=(10, 10))
        time = grid.time_dim  # noqa
        t = grid.stepping_dim  # noqa
        x, y = grid.dimensions  # noqa

        p = Dimension(name='p')
        d = Dimension(name='d')
        rx = Dimension(name='rx')
        ry = Dimension(name='ry')

        u = Function(name='u', grid=grid)  # noqa
        v = TimeFunction(name='v', grid=grid, save=None)  # noqa

        cx = Function(name='coeff_x', dimensions=(p, rx), shape=(1, 2))  # noqa
        cy = Function(name='coeff_y', dimensions=(p, ry), shape=(1, 2))  # noqa

        gp = Function(name='gridpoints', dimensions=(p, d), shape=(1, 2))  # noqa
        src = Function(name='src', dimensions=(p,), shape=(1,))  # noqa
        rcv = Function(name='rcv', dimensions=(time, p), shape=(100, 1), space_order=0)  # noqa

        # List comprehension would need explicit locals/globals mappings to eval
        for i, e in enumerate(list(exprs)):
            exprs[i] = eval(e)

        op = Operator(exprs, opt='openmp')

        iters = FindNodes(Iteration).visit(op)
        assert all(i.is_ParallelAtomic for i in iters if i.dim.name in atomic)
        assert all(not i.is_ParallelAtomic for i in iters if i.dim.name not in atomic)
        assert all(i.is_Parallel for i in iters if i.dim.name in parallel)
        assert all(not i.is_Parallel for i in iters if i.dim.name not in parallel)
Esempio n. 2
0
    def test_collapsing_v2(self):
        """
        MFE from issue #1478.
        """
        n = 8
        m = 8
        nx, ny, nchi, ncho = 12, 12, 1, 1
        x, y = SpaceDimension("x"), SpaceDimension("y")
        ci, co = Dimension("ci"), Dimension("co")
        i, j = Dimension("i"), Dimension("j")
        grid = Grid((nx, ny), dtype=np.float32, dimensions=(x, y))

        X = Function(name="xin", dimensions=(ci, x, y),
                     shape=(nchi, nx, ny), grid=grid, space_order=n//2)
        dy = Function(name="dy", dimensions=(co, x, y),
                      shape=(ncho, nx, ny), grid=grid, space_order=n//2)
        dW = Function(name="dW", dimensions=(co, ci, i, j), shape=(ncho, nchi, n, m),
                      grid=grid)

        eq = [Eq(dW[co, ci, i, j],
                 dW[co, ci, i, j] + dy[co, x, y]*X[ci, x+i-n//2, y+j-m//2])
              for i in range(n) for j in range(m)]

        op = Operator(eq, opt=('advanced', {'openmp': True}))

        iterations = FindNodes(Iteration).visit(op)
        assert len(iterations) == 4
        assert iterations[0].ncollapsed == 1
        assert iterations[1].is_Vectorized
        assert iterations[2].is_Sequential
        assert iterations[3].is_Sequential
Esempio n. 3
0
def grad(nx, ny, nchi, ncho, n, m, xdat, dydat):

    # Image size
    dt = np.float32
    x, y, ci, co = (SpaceDimension("x"), SpaceDimension("y"), Dimension("ci"),
                    Dimension("co"))
    grid = Grid((nx, ny), dtype=dt, dimensions=(x, y))

    # Image
    X = Function(name="xin", dimensions=(ci, x, y),
                 shape=(nchi, nx, ny), grid=grid, space_order=n//2)

    # Output
    dy = Function(name="dy", dimensions=(co, x, y),
                  shape=(ncho, nx, ny), grid=grid, space_order=n//2)

    # Weights
    i, j = Dimension("i"), Dimension("j")
    dW = Function(name="dW", dimensions=(co, ci, i, j),
                  shape=(ncho, nchi, n, m), grid=grid)

    # Gradient
    grad_eq = Inc(dW[co, ci, i, j], dy[co, x, y]*X[ci, x+i-n//2, y+j-m//2])
    op = Operator(grad_eq)
    op.cfunction

    X.data[:] = xdat[:]
    dy.data[:] = dydat[:]

    return op
Esempio n. 4
0
    def test_indexed_w_indirections(self):
        """Test point-wise arithmetic with indirectly indexed :class:`Function`s."""
        grid = Grid(shape=(10, 10))
        x, y = grid.dimensions

        p_poke = Dimension('p_src')
        d = Dimension('d')

        npoke = 1

        u = Function(name='u', grid=grid, space_order=0)
        coordinates = Function(name='coordinates', dimensions=(p_poke, d),
                               shape=(npoke, grid.dim), space_order=0, dtype=np.int32)
        coordinates.data[0, 0] = 4
        coordinates.data[0, 1] = 3

        poke_eq = Eq(u.indexed[coordinates.indexed[p_poke, 0],
                               coordinates.indexed[p_poke, 1]], 1.0)
        op = Operator(poke_eq)
        op.apply()

        ix, iy = np.where(u.data == 1.)
        assert len(ix) == len(iy) == 1
        assert ix[0] == 4 and iy[0] == 3
        assert np.all(u.data[0:3] == 0.) and np.all(u.data[5:] == 0.)
        assert np.all(u.data[:, 0:3] == 0.) and np.all(u.data[:, 5:] == 0.)
Esempio n. 5
0
    def test_multi_sets_eq(self):
        """
        Check functionality for when multiple subdomain sets are present, each
        with multiple equations.
        """

        Nx = 10
        Ny = Nx
        n_domains = 2

        n = Dimension(name='n')
        m = Dimension(name='m')

        class MySubdomains1(SubDomainSet):
            name = 'mydomains1'
            implicit_dimension = n

        class MySubdomains2(SubDomainSet):
            name = 'mydomains2'
            implicit_dimension = m

        bounds_xm = np.array([1, Nx / 2 + 1], dtype=np.int32)
        bounds_xM = np.array([Nx / 2 + 1, 1], dtype=np.int32)
        bounds_ym = int(1)
        bounds_yM = int(Ny / 2 + 1)
        bounds1 = (bounds_xm, bounds_xM, bounds_ym, bounds_yM)

        bounds_xm = np.array([1, Nx / 2 + 1], dtype=np.int32)
        bounds_xM = np.array([Nx / 2 + 1, 1], dtype=np.int32)
        bounds_ym = int(Ny / 2 + 1)
        bounds_yM = int(1)
        bounds2 = (bounds_xm, bounds_xM, bounds_ym, bounds_yM)

        my_sd1 = MySubdomains1(N=n_domains, bounds=bounds1)
        my_sd2 = MySubdomains2(N=n_domains, bounds=bounds2)

        grid = Grid(extent=(Nx, Ny),
                    shape=(Nx, Ny),
                    subdomains=(my_sd1, my_sd2))

        f = Function(name='f', grid=grid, dtype=np.int32)
        g = Function(name='g', grid=grid, dtype=np.int32)

        eq1 = Eq(f, f + 2, subdomain=grid.subdomains['mydomains1'])
        eq2 = Eq(g, g + 2, subdomain=grid.subdomains['mydomains2'])
        eq3 = Eq(f, f - 1, subdomain=grid.subdomains['mydomains1'])
        eq4 = Eq(g, g + 1, subdomain=grid.subdomains['mydomains2'])

        op = Operator([eq1, eq2, eq3, eq4])
        op.apply()

        expected = np.array(
            [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 1, 0, 0, 3, 3, 3, 0],
             [0, 1, 1, 1, 0, 0, 3, 3, 3, 0], [0, 1, 1, 1, 0, 0, 3, 3, 3, 0],
             [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             [0, 1, 1, 1, 0, 0, 3, 3, 3, 0], [0, 1, 1, 1, 0, 0, 3, 3, 3, 0],
             [0, 1, 1, 1, 0, 0, 3, 3, 3, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
            dtype=np.int32)

        assert ((np.array(f.data[:] + g.data[:]) == expected).all())
Esempio n. 6
0
    def test_conditional_dimension(self):
        """Test that different ConditionalDimensions have different hash value."""
        d0 = Dimension(name='d')
        s0 = Scalar(name='s')
        d1 = Dimension(name='d', spacing=s0)

        cd0 = ConditionalDimension(name='cd', parent=d0, factor=4)
        cd1 = ConditionalDimension(name='cd', parent=d0, factor=5)
        assert cd0 is not cd1
        assert hash(cd0) != hash(cd1)

        cd2 = ConditionalDimension(name='cd',
                                   parent=d0,
                                   factor=4,
                                   indirect=True)
        assert hash(cd0) != hash(cd2)

        cd3 = ConditionalDimension(name='cd', parent=d1, factor=4)
        assert hash(cd0) != hash(cd3)

        s1 = Scalar(name='s', dtype=np.int32)
        cd4 = ConditionalDimension(name='cd',
                                   parent=d0,
                                   factor=4,
                                   condition=s0 > 3)
        assert hash(cd0) != hash(cd4)

        cd5 = ConditionalDimension(name='cd',
                                   parent=d0,
                                   factor=4,
                                   condition=s1 > 3)
        assert hash(cd0) != hash(cd5)
        assert hash(cd4) != hash(cd5)
Esempio n. 7
0
    def test_partial_offloading(self):
        """
        Check that :class:`Function` objects not using any :class:`SpaceDimension`
        are computed in Devito-land, rather than via YASK.
        """
        shape = (4, 4, 4)
        grid = Grid(shape=shape)
        dx = Dimension(name='dx')
        dy = Dimension(name='dy')
        dz = Dimension(name='dz')
        x, y, z = grid.dimensions

        u = TimeFunction(name='yu4D', grid=grid, space_order=0)
        f = Function(name='f', dimensions=(dx, dy, dz), shape=shape)

        u.data_with_halo[:] = 0.
        f.data[:] = 0.

        eqns = [Eq(u.forward, u + 1.),
                Eq(f, u[1, dx, dy, dz] + 1.)]
        op = Operator(eqns)

        op(time=0)
        assert np.all(u.data[0] == 0.)
        assert np.all(u.data[1] == 1.)
        assert np.all(f.data == 2.)
def custom_points(grid, ranges, npoints, name='points'):
    """Create a set of sparse points from a set of coordinate
    ranges for each spatial dimension.
    """
    scale = Dimension(name="scale")
    dim = Dimension(name="dim")
    points = SparseFunction(name=name, grid=grid, dimensions=(scale, dim),
                            shape=(3, npoints), npoint=npoints)
    for i, r in enumerate(ranges):
        points.coordinates.data[:, i] = np.linspace(r[0], r[1], npoints)
    return points
def conv(nx, ny, nchi, ncho, n, m):

    # Image size
    dt = np.float32
    x, y, ci, co = (SpaceDimension("x"), SpaceDimension("y"), Dimension("ci"),
                    Dimension("co"))
    grid = Grid((nchi, ncho, nx, ny), dtype=dt, dimensions=(ci, co, x, y))

    # Image
    im_in = Function(name="imi",
                     dimensions=(ci, x, y),
                     shape=(nchi, nx, ny),
                     grid=grid,
                     space_order=n // 2)

    # Output
    im_out = Function(name="imo",
                      dimensions=(co, x, y),
                      shape=(ncho, nx, ny),
                      grid=grid,
                      space_order=n // 2)

    # Weights
    i, j = Dimension("i"), Dimension("j")
    W = Function(name="W",
                 dimensions=(co, ci, i, j),
                 shape=(ncho, nchi, n, m),
                 grid=grid)

    # Popuate weights with deterministic values
    for i in range(ncho):
        for j in range(nchi):
            W.data[i, j, :, :] = np.linspace(i + j, i + j + (n * m),
                                             n * m).reshape(n, m)

    # Convlution
    conv = [
        Eq(
            im_out, im_out + sum([
                W[co, ci, i2, i1] * im_in[ci, x + i1 - n // 2, y + i2 - m // 2]
                for i1 in range(n) for i2 in range(m)
            ]))
    ]

    op = Operator(conv)
    op.cfunction

    # Initialize the input/output
    input_data = np.linspace(-1, 1, nx * ny * nchi).reshape(nchi, nx, ny)
    im_in.data[:] = input_data.astype(np.float32)
    im_out.data

    return op
Esempio n. 10
0
    def test_sub_dimension(self):
        """Test that different SubDimensions have different hash value."""
        d0 = Dimension(name='d')
        d1 = Dimension(name='d', spacing=Scalar(name='s'))

        di0 = SubDimension.middle('di', d0, 1, 1)
        di1 = SubDimension.middle('di', d1, 1, 1)
        assert hash(di0) != hash(d0)
        assert hash(di0) != hash(di1)

        dl0 = SubDimension.left('dl', d0, 2)
        assert hash(dl0) != hash(di0)
Esempio n. 11
0
    def test_symbols_args_vs_kwargs(self):
        """
        Unlike Functions, Symbols don't require the use of a kwarg to specify the name.
        This test basically checks that `Symbol('s') is Symbol(name='s')`, i.e. that we
        don't make any silly mistakes when it gets to compute the cache key.
        """
        v_arg = Symbol('v')
        v_kwarg = Symbol(name='v')
        assert v_arg is v_kwarg

        d_arg = Dimension('d100')
        d_kwarg = Dimension(name='d100')
        assert d_arg is d_kwarg
Esempio n. 12
0
    def test_dimension(self):
        """Test that different Dimensions have different hash value."""
        d0 = Dimension(name='d')
        s0 = Scalar(name='s')
        d1 = Dimension(name='d', spacing=s0)
        assert hash(d0) != hash(d1)

        s1 = Scalar(name='s', dtype=np.int32)
        d2 = Dimension(name='d', spacing=s1)
        assert hash(d1) != hash(d2)

        d3 = Dimension(name='d', spacing=Constant(name='s1'))
        assert hash(d3) != hash(d0)
        assert hash(d3) != hash(d1)
Esempio n. 13
0
    def __new__(cls,
                name,
                grid,
                ntime=None,
                npoint=None,
                data=None,
                coordinates=None,
                **kwargs):
        p_dim = kwargs.get('dimension', Dimension(name='p_%s' % name))
        npoint = npoint or coordinates.shape[0]
        if data is None:
            if ntime is None:
                error('Either data or ntime are required to'
                      'initialise source/receiver objects')
        else:
            ntime = ntime or data.shape[0]

        # Create the underlying SparseTimeFunction object
        obj = SparseTimeFunction.__new__(cls,
                                         name=name,
                                         grid=grid,
                                         dimensions=[grid.time_dim, p_dim],
                                         npoint=npoint,
                                         nt=ntime,
                                         coordinates=coordinates,
                                         **kwargs)

        # If provided, copy initial data into the allocated buffer
        if data is not None:
            obj.data[:] = data
        return obj
Esempio n. 14
0
    def test_override_composite_data(self):
        i, j = dimify('i j')
        grid = Grid(shape=(10, 10), dimensions=(i, j))
        original_coords = (1., 1.)
        new_coords = (2., 2.)
        p_dim = Dimension('p_src')
        u = TimeFunction(name='u', grid=grid, time_order=2, space_order=2)
        src1 = SparseFunction(name='src1',
                              grid=grid,
                              dimensions=[time, p_dim],
                              npoint=1,
                              nt=10,
                              coordinates=original_coords)
        src2 = SparseFunction(name='src1',
                              grid=grid,
                              dimensions=[time, p_dim],
                              npoint=1,
                              nt=10,
                              coordinates=new_coords)
        op = Operator(src1.inject(u, src1))

        # Move the source from the location where the setup put it so we can test
        # whether the override picks up the original coordinates or the changed ones

        # Operator.arguments() returns a tuple of (data, dimension_sizes)
        args = op.arguments(src1=src2)[0]
        arg_name = src1.name + "_coords"
        assert (np.array_equal(args[arg_name], np.asarray((new_coords, ))))
Esempio n. 15
0
    def test_reinsertion_after_deletion(self, operate_on_empty_cache):
        """
        Test that dead weakrefs in the symbol cache do not cause any issues when
        objects with the same key/hash are reinserted.
        """
        d = Dimension(name='d')
        del d

        # `d` has just been deleted, but a weakref pointing to a dead object is still
        # in the symbol cache at this point; `h_d` is still in the cache too, dead too
        assert len(_SymbolCache) == 2
        assert all(i() is None for i in _SymbolCache.values())

        d = Dimension(name='d')  # noqa
        assert len(_SymbolCache) == 2
        assert all(i() is not None for i in _SymbolCache.values())
Esempio n. 16
0
    def test_default_dimension(self):
        d = Dimension(name='d')
        dd0 = DefaultDimension(name='d')
        assert d is not dd0

        dd1 = DefaultDimension(name='d')
        assert dd0 is not dd1
Esempio n. 17
0
    def test_equations_mixed_densedata_timedata(self, shape, dimensions):
        """
        Test that equations using a mixture of DenseData and TimeData objects
        are embedded within the same time loop.
        """
        a = TimeData(name='a', shape=shape, time_order=2, dimensions=dimensions,
                     space_order=2, time_dim=6, save=False)
        p_aux = Dimension(name='p_aux', size=10)
        b = DenseData(name='b', shape=shape + (10,), dimensions=dimensions + (p_aux,),
                      space_order=2)
        b.data[:] = 1.0
        b2 = DenseData(name='b2', shape=(10,) + shape, dimensions=(p_aux,) + dimensions,
                       space_order=2)
        b2.data[:] = 1.0
        eqns = [Eq(a.forward, a.laplace + 1.),
                Eq(b, time*b*a + b)]
        eqns2 = [Eq(a.forward, a.laplace + 1.),
                 Eq(b2, time*b2*a + b2)]
        subs = {x.spacing: 2.5, y.spacing: 1.5, z.spacing: 2.0}
        op = Operator(eqns, subs=subs, dle='noop')
        trees = retrieve_iteration_tree(op)
        assert len(trees) == 2
        assert all(trees[0][i] is trees[1][i] for i in range(3))

        op2 = Operator(eqns2, subs=subs, dle='noop')
        trees = retrieve_iteration_tree(op2)
        assert len(trees) == 2
        assert all(trees[0][i] is trees[1][i] for i in range(3))

        # Verify both operators produce the same result
        op()
        op2()

        assert(np.allclose(b2.data[2, ...].reshape(-1) -
                           b.data[..., 2].reshape(-1), 0.))
Esempio n. 18
0
    def adjoint_y_run(self,
                      y,
                      src_coords,
                      rcv_coords,
                      weight_fun_pars=None,
                      save=False):
        v = wavefield(self.model,
                      self.space_order,
                      save=save,
                      nt=y.shape[0],
                      fw=False)
        kwargs = wf_kwargs(v)
        rcv = Receiver(name="rcv",
                       grid=self.model.grid,
                       ntime=y.shape[0],
                       coordinates=src_coords)
        src = PointSource(name="src",
                          grid=self.model.grid,
                          ntime=y.shape[0],
                          coordinates=rcv_coords)
        src.data[:, :] = y[:, :]

        adj = self.op_adj_y(weight_fun_pars=weight_fun_pars, save=save)

        i = Dimension(name="i", )
        norm_v = Function(name="nvy2",
                          shape=(1, ),
                          dimensions=(i, ),
                          grid=self.model.grid)

        adj(src=src, rcv=rcv, nvy2=norm_v, **kwargs)

        return norm_v.data[0], rcv.data, v
def forward_freq_modeling(model, src_coords, wavelet, rec_coords, freq, space_order=8, dt=None, factor=None, free_surface=False):
    # Forward modeling with on-the-fly DFT of forward wavefields
    clear_cache()

    # Parameters
    nt = wavelet.shape[0]
    if dt is None:
        dt = model.critical_dt
    m, rho, damp = model.m, model.rho, model.damp

    freq_dim = Dimension(name='freq_dim')
    time = model.grid.time_dim
    if factor is None:
        factor = int(1 / (dt*4*np.max(freq)))
        tsave = ConditionalDimension(name='tsave', parent=model.grid.time_dim, factor=factor)
    if factor==1:
        tsave = time
    else:
        tsave = ConditionalDimension(name='tsave', parent=model.grid.time_dim, factor=factor)
    print("DFT subsampling factor: ", factor)

    # Create wavefields
    nfreq = freq.shape[0]
    u = TimeFunction(name='u', grid=model.grid, time_order=2, space_order=space_order)
    f = Function(name='f', dimensions=(freq_dim,), shape=(nfreq,))
    f.data[:] = freq[:]
    ufr = Function(name='ufr', dimensions=(freq_dim,) + u.indices[1:], shape=(nfreq,) + model.shape_domain)
    ufi = Function(name='ufi', dimensions=(freq_dim,) + u.indices[1:], shape=(nfreq,) + model.shape_domain)

    ulaplace, rho = acoustic_laplacian(u, rho)

    # Set up PDE and rearrange
    stencil = damp * (2.0 * u - damp * u.backward + dt**2 * rho / m * ulaplace)
    expression = [Eq(u.forward, stencil)]
    expression += [Eq(ufr, ufr + factor*u*cos(2*np.pi*f*tsave*factor*dt))]
    expression += [Eq(ufi, ufi - factor*u*sin(2*np.pi*f*tsave*factor*dt))]

    # Source symbol with input wavelet
    src = PointSource(name='src', grid=model.grid, ntime=nt, coordinates=src_coords)
    src.data[:] = wavelet[:]
    src_term = src.inject(field=u.forward, expr=src * dt**2 / m)

    # Data is sampled at receiver locations
    rec = Receiver(name='rec', grid=model.grid, ntime=nt, coordinates=rec_coords)
    rec_term = rec.interpolate(expr=u)

    # Create operator and run

    expression += src_term + rec_term
    # Free surface
    if free_surface is True:
        expression += freesurface(u, space_order//2, model.nbpml)

    subs = model.spacing_map
    subs[u.grid.time_dim.spacing] = dt
    op = Operator(expression, subs=subs, dse='advanced', dle='advanced')
    cf = op.cfunction
    op()

    return rec.data, ufr, ufi
Esempio n. 20
0
def solver(I, w, dt, T):
    """
    Solve u'=v, v' = - w**2*u for t in (0,T], u(0)=I and v(0)=0,
    by an Euler-Cromer method.
    """
    dt = float(dt)
    Nt = int(round(T/dt))
    
    t = Dimension('t', spacing=Constant('h_t'))
    v = TimeFunction(name='v', dimensions=(t,), shape=(Nt+1,), space_order=2)
    u = TimeFunction(name='u', dimensions=(t,), shape=(Nt+1,), space_order=2)

    v.data[:] = 0    
    u.data[:] = I

    eq_v = Eq(v.dt, -(w**2)*u)
    eq_u = Eq(u.dt, v.forward)
    
    stencil_v = solve(eq_v, v.forward)
    stencil_u = solve(eq_u, u.forward)
    
    update_v = Eq(v.forward, stencil_v)
    update_u = Eq(u.forward, stencil_u)
    

    op = Operator([update_v, update_u])
    op.apply(h_t=dt, t_M=Nt-1)

    return u.data, v.data, np.linspace(0, Nt*dt, Nt+1)
Esempio n. 21
0
    def test_implicit_dims(self):
        """
        Test ConditionalDimension as an implicit dimension for an equation.
        """

        # This test makes an Operator that should create a vector of increasing
        # integers, but stop incrementing when a certain stop value is reached

        shape = (50, )
        stop_value = 20

        time = Dimension(name='time')
        f = TimeFunction(name='f', shape=shape, dimensions=[time])

        # The condition to stop incrementing
        cond = ConditionalDimension(name='cond',
                                    parent=time,
                                    condition=f[time] < stop_value)

        eqs = [
            Eq(f.forward, f),
            Eq(f.forward, f.forward + 1, implicit_dims=[cond])
        ]
        op = Operator(eqs)
        op.apply(time_M=shape[0] - 2)

        # Make the same calculation in python to assert the result
        F = np.zeros(shape[0])
        for i in range(shape[0]):
            F[i] = i if i < stop_value else stop_value

        assert np.all(f.data == F)
    def test_staggered_function(self, order):
        """Test custom function coefficients on a staggered grid"""
        grid = Grid(shape=(11, ), extent=(10., ))
        x = grid.dimensions[0]

        f = Function(name='f',
                     grid=grid,
                     space_order=order,
                     coefficients='symbolic')
        g = Function(name='g',
                     grid=grid,
                     space_order=order,
                     coefficients='symbolic',
                     staggered=x)
        f.data[::2] = 1
        g.data[::2] = 1

        s = Dimension(name='s')
        ncoeffs = order + 1

        wshape = grid.shape + (ncoeffs, )
        wdims = grid.dimensions + (s, )

        w = Function(name='w', dimensions=wdims, shape=wshape)
        w.data[:] = 1.0 / grid.spacing[0]**2

        coeffs_f = Coefficient(2, f, x, w)
        coeffs_g = Coefficient(2, g, x, w)

        eq_f = Eq(f, f.dx2, coefficients=Substitutions(coeffs_f))
        eq_g = Eq(g, g.dx2, coefficients=Substitutions(coeffs_g))

        Operator([eq_f, eq_g])()

        assert np.allclose(f.data, g.data, atol=1e-7)
Esempio n. 23
0
    def test_argument_from_index_constant(self):
        nx, ny = 30, 30
        grid = Grid(shape=(nx, ny))
        x, y = grid.dimensions

        arbdim = Dimension('arb')
        u = TimeFunction(name='u',
                         grid=grid,
                         save=None,
                         time_order=2,
                         space_order=0)
        snap = Function(name='snap',
                        dimensions=(arbdim, x, y),
                        shape=(5, nx, ny),
                        space_order=0)

        save_t = Constant(name='save_t', dtype=np.int32)
        save_slot = Constant(name='save_slot', dtype=np.int32)

        expr = Eq(snap.subs(arbdim, save_slot),
                  u.subs(grid.stepping_dim, save_t))
        op = Operator(expr)
        u.data[:] = 0.0
        snap.data[:] = 0.0
        u.data[0, 10, 10] = 1.0
        op.apply(save_t=0, save_slot=1)
        assert snap.data[1, 10, 10] == 1.0
Esempio n. 24
0
    def test_conditional_dimension(self):
        """
        Test that ConditionalDimensions with same name but different attributes do not
        alias to the same ConditionalDimension. Conversely, if the name and the attributes
        are the same, they must alias to the same ConditionalDimension.
        """
        i = Dimension(name='i')
        ci0 = ConditionalDimension(name='ci', parent=i, factor=4)
        ci1 = ConditionalDimension(name='ci', parent=i, factor=4)
        assert ci0 is ci1

        ci2 = ConditionalDimension(name='ci', parent=i, factor=8)
        assert ci2 is not ci1

        ci3 = ConditionalDimension(name='ci',
                                   parent=i,
                                   factor=4,
                                   indirect=True)
        assert ci3 is not ci1

        s = Scalar(name='s')
        ci4 = ConditionalDimension(name='ci',
                                   parent=i,
                                   factor=4,
                                   condition=s > 3)
        assert ci4 is not ci1
        ci5 = ConditionalDimension(name='ci',
                                   parent=i,
                                   factor=4,
                                   condition=s > 3)
        assert ci5 is ci4
    def __new__(cls,
                name,
                grid,
                time_range,
                npoint=None,
                data=None,
                coordinates=None,
                **kwargs):
        p_dim = kwargs.get('dimension', Dimension(name='p_%s' % name))
        time_order = kwargs.get('time_order', 2)
        npoint = npoint or coordinates.shape[0]

        # Create the underlying SparseTimeFunction object
        obj = SparseTimeFunction.__new__(cls,
                                         name=name,
                                         grid=grid,
                                         dimensions=[grid.time_dim, p_dim],
                                         npoint=npoint,
                                         nt=time_range.num,
                                         time_order=time_order,
                                         coordinates=coordinates,
                                         **kwargs)

        obj._time_range = time_range._rebuild()

        # If provided, copy initial data into the allocated buffer
        if data is not None:
            obj.data[:] = data

        return obj
Esempio n. 26
0
    def __new__(cls, **kwargs):
        name = kwargs.pop('name')
        grid = kwargs.pop('grid')
        time_range = kwargs.pop('time_range')
        time_order = kwargs.pop('time_order', 2)
        p_dim = kwargs.pop('dimension', Dimension(name='p_%s' % name))

        # Either `npoint` or `coordinates` must be provided
        coordinates = kwargs.pop('coordinates', None)
        npoint = kwargs.pop('npoint', None) or coordinates.shape[0]

        # Create the underlying SparseTimeFunction object
        obj = SparseTimeFunction.__new__(cls,
                                         name=name,
                                         grid=grid,
                                         dimensions=(grid.time_dim, p_dim),
                                         npoint=npoint,
                                         nt=time_range.num,
                                         time_order=time_order,
                                         coordinates=coordinates,
                                         **kwargs)

        obj._time_range = time_range._rebuild()

        # If provided, copy initial data into the allocated buffer
        data = kwargs.get('data')
        if data is not None:
            obj.data[:] = data

        return obj
Esempio n. 27
0
    def test_function_wo(self):
        grid = Grid(shape=(3, 3, 3))
        i = Dimension(name='i')

        f = Function(name='f', shape=(1,), dimensions=(i,), grid=grid)
        u = TimeFunction(name='u', grid=grid)

        eqns = [Eq(u.forward, u + 1),
                Eq(f[0], u[0, 0, 0, 0])]

        op = Operator(eqns, opt='noop')

        assert len(op.body[1].header) == 2
        assert len(op.body[1].footer) == 2
        assert op.body[1].header[0].value ==\
            ('omp target enter data map(to: u[0:u_vec->size[0]]'
             '[0:u_vec->size[1]][0:u_vec->size[2]][0:u_vec->size[3]])')
        assert str(op.body[1].header[1]) == ''
        assert str(op.body[1].footer[0]) == ''
        assert op.body[1].footer[1].contents[0].value ==\
            ('omp target update from(u[0:u_vec->size[0]]'
             '[0:u_vec->size[1]][0:u_vec->size[2]][0:u_vec->size[3]])')
        assert op.body[1].footer[1].contents[1].value ==\
            ('omp target exit data map(release: u[0:u_vec->size[0]]'
             '[0:u_vec->size[1]][0:u_vec->size[2]][0:u_vec->size[3]])')
Esempio n. 28
0
def test_array():
    grid = Grid(shape=(3, 3))
    d = Dimension(name='d')

    a = Array(name='a',
              dimensions=grid.dimensions,
              dtype=np.int32,
              halo=((1, 1), (2, 2)),
              padding=((2, 2), (2, 2)),
              space='remote',
              scope='stack')

    pkl_a = pickle.dumps(a)
    new_a = pickle.loads(pkl_a)
    assert new_a.name == a.name
    assert new_a.dtype is np.int32
    assert new_a.dimensions[0].name == 'x'
    assert new_a.dimensions[1].name == 'y'
    assert new_a.halo == ((1, 1), (2, 2))
    assert new_a.padding == ((2, 2), (2, 2))
    assert new_a.space == 'remote'
    assert new_a.scope == 'stack'

    # Now with a pointer array
    pa = PointerArray(name='pa', dimensions=d, array=a)

    pkl_pa = pickle.dumps(pa)
    new_pa = pickle.loads(pkl_pa)
    assert new_pa.name == pa.name
    assert new_pa.dim.name == 'd'
    assert new_pa.array.name == 'a'
Esempio n. 29
0
    def test_override_sparse_data_fix_dim(self):
        """
        Ensure the arguments are derived correctly for an input SparseFunction.
        The dimensions are forced to be the same in this case to verify
        the aliasing on the SparseFunction name.
        """
        grid = Grid(shape=(10, 10))
        time = grid.time_dim

        u = TimeFunction(name='u', grid=grid, time_order=2, space_order=2)

        original_coords = (1., 1.)
        new_coords = (2., 2.)
        p_dim = Dimension(name='p_src')
        src1 = SparseTimeFunction(name='src1', grid=grid, dimensions=[time, p_dim], nt=10,
                                  npoint=1, coordinates=original_coords, time_order=2)
        src2 = SparseTimeFunction(name='src2', grid=grid, dimensions=[time, p_dim],
                                  npoint=1, nt=10, coordinates=new_coords, time_order=2)
        op = Operator(src1.inject(u, src1))

        # Move the source from the location where the setup put it so we can test
        # whether the override picks up the original coordinates or the changed ones

        args = op.arguments(src1=src2, time=0)
        arg_name = src1.name + "_coords"
        assert(np.array_equal(args[arg_name], np.asarray((new_coords,))))
Esempio n. 30
0
def test_temp_function():
    grid = Grid(shape=(3, 3))
    d = Dimension(name='d')

    cf = TempFunction(name='f',
                      dtype=np.float64,
                      dimensions=grid.dimensions,
                      halo=((1, 1), (1, 1)))

    pkl_cf = pickle.dumps(cf)
    new_cf = pickle.loads(pkl_cf)
    assert new_cf.name == cf.name
    assert new_cf.dtype is np.float64
    assert new_cf.halo == ((1, 1), (1, 1))
    assert new_cf.ndim == cf.ndim
    assert new_cf.dim is None

    pcf = cf._make_pointer(d)

    pkl_pcf = pickle.dumps(pcf)
    new_pcf = pickle.loads(pkl_pcf)
    assert new_pcf.name == pcf.name
    assert new_pcf.dim.name == 'd'
    assert new_pcf.ndim == cf.ndim + 1
    assert new_pcf.halo == ((0, 0), (1, 1), (1, 1))