示例#1
0
def test_invalid_temporary_access(definition):
    builder = StencilBuilder(definition, backend=from_name("gtc:numpy"))
    with pytest.raises(
            TypeError,
            match="Invalid access with offset in k to temporary field tmp."):
        k_boundary = compute_k_boundary(
            builder.gtir_pipeline.full(skip=[prune_unused_parameters]))
示例#2
0
def test_k_bounds(definition, expected_k_bounds):
    builder = StencilBuilder(definition, backend=from_name("debug"))
    k_boundary = compute_k_boundary(builder.gtir_pipeline.full(skip=[prune_unused_parameters]))[
        "field_b"
    ]

    assert expected_k_bounds == k_boundary
示例#3
0
def make_args_data_from_gtir(pipeline: GtirPipeline) -> ModuleData:
    """
    Compute module data containing information about stencil arguments from gtir.

    This is no longer compatible with the legacy backends.
    """
    data = ModuleData()

    # NOTE: pipeline.gtir has not had prune_unused_parameters applied.
    all_params = pipeline.gtir.params

    node = pipeline.full()
    oir = gtir_to_oir.GTIRToOIR().visit(node)
    field_extents = compute_fields_extents(oir)
    accesses = compute_access_kinds(oir)

    for decl in (param for param in all_params
                 if isinstance(param, gtir.FieldDecl)):
        access = accesses[decl.name]
        dtype = numpy.dtype(decl.dtype.name.lower())

        if access != AccessKind.NONE:
            k_boundary = compute_k_boundary(node)[decl.name]
            boundary = Boundary(*field_extents[decl.name].to_boundary()[0:2],
                                k_boundary)
        else:
            boundary = Boundary.zeros(ndims=3)

        data.field_info[decl.name] = FieldInfo(
            access=access,
            boundary=boundary,
            axes=tuple(dimension_flags_to_names(decl.dimensions).upper()),
            data_dims=tuple(decl.data_dims),
            dtype=dtype,
        )

    for decl in (param for param in all_params
                 if isinstance(param, gtir.ScalarDecl)):
        access = accesses[decl.name]
        dtype = numpy.dtype(decl.dtype.name.lower())
        data.parameter_info[decl.name] = ParameterInfo(access=access,
                                                       dtype=dtype)

    data.unreferenced = [
        *sorted(name for name in accesses if accesses[name] == AccessKind.NONE)
    ]
    return data
示例#4
0
    def generate_dace_args(self, gtir, sdfg):
        oir = gtir_to_oir.GTIRToOIR().visit(gtir)
        field_extents = compute_fields_extents(oir, add_k=True)

        offset_dict: Dict[str, Tuple[int, int, int]] = {
            k: (-v[0][0], -v[1][0], -v[2][0])
            for k, v in field_extents.items()
        }
        k_origins = {
            field_name: boundary[0]
            for field_name, boundary in compute_k_boundary(gtir).items()
        }
        for name, origin in k_origins.items():
            offset_dict[name] = (offset_dict[name][0], offset_dict[name][1],
                                 origin)

        symbols = {f"__{var}": f"__{var}" for var in "IJK"}
        for name, array in sdfg.arrays.items():
            if array.transient:
                symbols[f"__{name}_K_stride"] = "1"
                symbols[f"__{name}_J_stride"] = str(array.shape[2])
                symbols[f"__{name}_I_stride"] = str(array.shape[1] *
                                                    array.shape[2])
            else:
                dims = [
                    dim for dim, select in zip("IJK", array_dimensions(array))
                    if select
                ]
                data_ndim = len(array.shape) - len(dims)

                # api field strides
                fmt = "gt::sid::get_stride<{dim}>(gt::sid::get_strides(__{name}_sid))"

                symbols.update({
                    f"__{name}_{dim}_stride":
                    fmt.format(dim=f"gt::stencil::dim::{dim.lower()}",
                               name=name)
                    for dim in dims
                })
                symbols.update({
                    f"__{name}_d{dim}_stride":
                    fmt.format(dim=f"gt::integral_constant<int, {3 + dim}>",
                               name=name)
                    for dim in range(data_ndim)
                })

                # api field pointers
                fmt = """gt::sid::multi_shifted(
                             gt::sid::get_origin(__{name}_sid)(),
                             gt::sid::get_strides(__{name}_sid),
                             std::array<gt::int_t, {ndim}>{{{origin}}}
                         )"""
                origin = tuple(-offset_dict[name][idx]
                               for idx, var in enumerate("IJK") if any(
                                   dace.symbolic.pystr_to_symbolic(f"__{var}")
                                   in s.free_symbols for s in array.shape
                                   if hasattr(s, "free_symbols")))
                symbols[name] = fmt.format(name=name,
                                           ndim=len(array.shape),
                                           origin=",".join(
                                               str(o) for o in origin))
        # the remaining arguments are variables and can be passed by name
        for sym in sdfg.signature_arglist(with_types=False, for_call=True):
            if sym not in symbols:
                symbols[sym] = sym

        # return strings in order of sdfg signature
        return [
            symbols[s]
            for s in sdfg.signature_arglist(with_types=False, for_call=True)
        ]
示例#5
0
def make_args_data_from_gtir(pipeline: GtirPipeline,
                             legacy=False) -> ModuleData:
    """
    Compute module data containing information about stencil arguments from gtir.

    Use `legacy` parameter to ensure equality with values from :func:`make_args_data_from_iir`.
    """
    data = ModuleData()
    node = pipeline.full()

    write_fields = (node.iter_tree().if_isinstance(
        gtir.ParAssignStmt).getattr("left").if_isinstance(
            gtir.FieldAccess).getattr("name").to_set())

    read_fields: Set[str] = set()
    for expr in node.iter_tree().if_isinstance(
            gtir.ParAssignStmt).getattr("right"):
        read_fields |= expr.iter_tree().if_isinstance(
            gtir.FieldAccess).getattr("name").to_set()

    referenced_field_params = [
        param.name for param in node.params
        if isinstance(param, gtir.FieldDecl)
    ]
    field_extents = compute_legacy_extents(node, mask_inwards=legacy)
    k_boundary = (compute_k_boundary(node) if not legacy else
                  {v: (0, 0)
                   for v in referenced_field_params})
    for name in sorted(referenced_field_params):
        access = AccessKind.NONE
        if name in read_fields:
            access |= AccessKind.READ
        if name in write_fields:
            access |= AccessKind.WRITE
        boundary = Boundary(*field_extents[name].to_boundary()[0:2],
                            k_boundary[name])
        data.field_info[name] = FieldInfo(
            access=access,
            boundary=boundary,
            axes=tuple(
                dimension_flags_to_names(
                    node.symtable_[name].dimensions).upper()),
            data_dims=tuple(node.symtable_[name].data_dims),
            dtype=numpy.dtype(node.symtable_[name].dtype.name.lower()),
        )

    referenced_scalar_params = [
        param.name for param in node.params
        if param.name not in referenced_field_params
    ]
    for name in sorted(referenced_scalar_params):
        data.parameter_info[name] = ParameterInfo(
            dtype=numpy.dtype(node.symtable_[name].dtype.name.lower()))

    unref_params = get_unused_params_from_gtir(pipeline)
    for param in sorted(unref_params, key=lambda decl: decl.name):
        if isinstance(param, gtir.FieldDecl):
            data.field_info[param.name] = None
        elif isinstance(param, gtir.ScalarDecl):
            data.parameter_info[param.name] = None

    data.unreferenced = [*sorted(param.name for param in unref_params)]
    return data