示例#1
0
    def make_grid(self, obj):
        """
        Create and return a new :class:`Data`, a YASK grid wrapper. Memory
        is allocated.

        :param obj: The :class:`Function` for which a YASK grid is allocated.
        """
        # 'hook' compiler solution: describes the grid
        # 'hook' kernel solution: allocates memory

        # A unique name for the 'hook' compiler and kernel solutions
        suffix = Signer._digest(self, obj, configuration,
                                YaskContext._hookcounter)
        YaskContext._hookcounter += 1
        name = namespace['jit-hook'](suffix)

        # Create 'hook' compiler solution
        yc_hook = self.make_yc_solution(name)
        if obj.indices != self.dimensions:
            # Note: YASK wants *at least* a grid with *all* space (domain) dimensions
            # *and* the stepping dimension. `obj`, however, may actually employ a
            # different set of dimensions (e.g., a strict subset and/or some misc
            # dimensions). In such a case, an extra dummy grid is attached
            # `obj` examples: u(x, d), u(x, y, z)
            dimensions = [
                make_yask_ast(i, yc_hook, {}) for i in self.dimensions
            ]
            yc_hook.new_grid('dummy_grid_full', dimensions)
        dimensions = [make_yask_ast(i, yc_hook, {}) for i in obj.indices]
        yc_hook.new_grid('dummy_grid_true', dimensions)

        # Create 'hook' kernel solution
        yk_hook = YaskKernel(name, yc_hook)
        grid = yk_hook.new_grid(obj)

        # Where should memory be allocated ?
        alloc = obj._allocator
        if alloc.is_Numa:
            if alloc.put_onnode:
                grid.set_numa_preferred(alloc.node)
            elif alloc.put_local:
                grid.set_numa_preferred(namespace['numa-put-local'])

        for i, s, h in zip(obj.indices, obj.shape_allocated, obj._extent_halo):
            if i.is_Space:
                # Note:
                # From the YASK docs: "If the halo is set to a value larger than
                # the padding size, the padding size will be automatically increased
                # to accomodate it."
                grid.set_left_halo_size(i.name, h.left)
                grid.set_right_halo_size(i.name, h.right)
            else:
                # time and misc dimensions
                assert grid.is_dim_used(i.name)
                assert grid.get_alloc_size(i.name) == s
        grid.alloc_storage()

        self.grids[grid.get_name()] = grid

        return grid
示例#2
0
文件: wrappers.py 项目: opesci/devito
    def make_grid(self, obj):
        """
        Create a Data wrapping a YASK grid. Memory is allocated.

        Parameters
        ----------
        obj : Function
            The symbolic object for which a new YASK grid is created.
        """
        # 'hook' compiler solution: describes the grid
        # 'hook' kernel solution: allocates memory

        # A unique name for the 'hook' compiler and kernel solutions
        suffix = Signer._digest(self, obj, configuration, YaskContext._hookcounter)
        YaskContext._hookcounter += 1
        name = namespace['jit-hook'](suffix)

        # Create 'hook' compiler solution
        yc_hook = self.make_yc_solution(name)
        if obj.indices != self.dimensions:
            # Note: YASK wants *at least* a grid with *all* space (domain) dimensions
            # *and* the stepping dimension. `obj`, however, may actually employ a
            # different set of dimensions (e.g., a strict subset and/or some misc
            # dimensions). In such a case, an extra dummy grid is attached
            # `obj` examples: u(x, d), u(x, y, z)
            dimensions = [make_yask_ast(i, yc_hook) for i in self.dimensions]
            yc_hook.new_grid('dummy_grid_full', dimensions)
        dimensions = [make_yask_ast(i.root, yc_hook) for i in obj.indices]
        yc_hook.new_grid('dummy_grid_true', dimensions)

        # Create 'hook' kernel solution
        yk_hook = YaskKernel(name, yc_hook)
        grid = yk_hook.new_grid(obj)

        # Where should memory be allocated ?
        alloc = obj._allocator
        if alloc.is_Numa:
            if alloc.put_onnode:
                grid.set_numa_preferred(alloc.node)
            elif alloc.put_local:
                grid.set_numa_preferred(namespace['numa-put-local'])

        for i, s, h in zip(obj.indices, obj.shape_allocated, obj._size_halo):
            if i.is_Space:
                # Note:
                # From the YASK docs: "If the halo is set to a value larger than
                # the padding size, the padding size will be automatically increased
                # to accomodate it."
                grid.set_left_halo_size(i.name, h.left)
                grid.set_right_halo_size(i.name, h.right)
            else:
                # time and misc dimensions
                assert grid.is_dim_used(i.root.name)
                assert grid.get_alloc_size(i.root.name) == s
        grid.alloc_storage()

        self.grids[grid.get_name()] = grid

        return grid
示例#3
0
    def make_yc_solution(self, name):
        """
        Create and return a YASK compiler solution object.
        """
        yc_soln = cfac.new_solution(name)

        # Redirect stdout/strerr to a string or file
        if configuration.yask['dump']:
            filename = 'yc_dump.%s.%s.%s.txt' % (
                name, configuration['platform'], configuration['isa'])
            filename = os.path.join(configuration.yask['dump'], filename)
            yc_soln.set_debug_output(ofac.new_file_output(filename))
        else:
            yc_soln.set_debug_output(ofac.new_null_output())

        # Set data type size
        yc_soln.set_element_bytes(self.dtype().itemsize)

        # Apply compile-time optimizations
        if configuration['isa'] != 'cpp':
            dimensions = [
                make_yask_ast(i, yc_soln, {}) for i in self.space_dimensions
            ]
            # Vector folding
            for i, j in zip(dimensions, configuration.yask['folding']):
                yc_soln.set_fold_len(i, j)
            # Unrolling
            for i, j in zip(dimensions, configuration.yask['clustering']):
                yc_soln.set_cluster_mult(i, j)

        return yc_soln
示例#4
0
文件: wrappers.py 项目: opesci/devito
    def make_yc_solution(self, name):
        """Create a YASK compiler solution."""
        yc_soln = cfac.new_solution(name)

        # Redirect stdout/strerr to a string or file
        if configuration.yask['dump']:
            filename = 'yc_dump.%s.%s.%s.txt' % (name, configuration['platform'],
                                                 configuration['platform'].isa)
            filename = os.path.join(configuration.yask['dump'], filename)
            yc_soln.set_debug_output(ofac.new_file_output(filename))
        else:
            yc_soln.set_debug_output(ofac.new_null_output())

        # Set data type size
        yc_soln.set_element_bytes(self.dtype().itemsize)

        # Apply compile-time optimizations
        if configuration['platform'].isa != 'cpp':
            dimensions = [make_yask_ast(i, yc_soln) for i in self.space_dimensions]
            # Vector folding
            for i, j in zip(dimensions, configuration.yask['folding']):
                yc_soln.set_fold_len(i, j)
            # Unrolling
            for i, j in zip(dimensions, configuration.yask['clustering']):
                yc_soln.set_cluster_mult(i, j)

        return yc_soln
示例#5
0
    def make_var(self, obj):
        """
        Create a Data wrapping a YASK var. Memory is allocated.

        Parameters
        ----------
        obj : Function
            The symbolic object for which a new YASK var is created.
        """
        # 'hook' compiler solution: describes the var
        # 'hook' kernel solution: allocates memory

        # A unique name for the 'hook' compiler and kernel solutions
        suffix = Signer._digest(self, obj, configuration,
                                YaskContext._hookcounter)
        YaskContext._hookcounter += 1
        name = namespace['jit-hook'](suffix)

        # Create 'hook' compiler solution
        yc_hook = self.make_yc_solution(name)

        # Tell YASK compiler about *all* space (domain) dimensions *and* the
        # stepping dimension. This is done to ensure that all hook solutions
        # have the same list of problem dimensions.  Note: `obj` may
        # actually employ a different set of dimensions (e.g., a strict
        # subset and/or some misc dimensions).
        space_dims = [make_yask_ast(i, yc_hook) for i in self.space_dimensions]
        yc_hook.set_domain_dims(space_dims)
        step_dim = make_yask_ast(self.step_dimension, yc_hook)
        yc_hook.set_step_dim(step_dim)

        # Create YASK compiler variable based on dimensions of `obj`.
        # This is done to force YASK to generate code to create vars
        # of this type, which will be needed when creating the YASK
        # kernel variable below.
        dimensions = [make_yask_ast(i.root, yc_hook) for i in obj.indices]
        yc_hook.new_var('template_var', dimensions)

        # Create 'hook' kernel solution from `yc_hook`
        yk_hook = YaskKernel(name, yc_hook)

        # Create YASK kernel variable for `obj`. YASK knows how to
        # create a variable of these dimesions because of the
        # 'dummy_var' declared above.
        var = yk_hook.new_var(obj)

        # Where should memory be allocated ?
        alloc = obj._allocator
        if alloc.is_Numa:
            if alloc.put_onnode:
                var.set_numa_preferred(alloc.node)
            elif alloc.put_local:
                var.set_numa_preferred(namespace['numa-put-local'])

        for i, s, h in zip(obj.indices, obj.shape_allocated, obj._size_halo):
            if i.is_Space:
                # Note:
                # From the YASK docs: "If the halo is set to a value larger than
                # the padding size, the padding size will be automatically increased
                # to accommodate it."
                var.set_left_halo_size(i.name, h.left)
                var.set_right_halo_size(i.name, h.right)
            else:
                # time and misc dimensions
                assert var.is_dim_used(i.root.name)
                assert var.get_alloc_size(i.root.name) == s
        var.alloc_storage()

        self.vars[var.get_name()] = var

        return var