예제 #1
0
def field_extraction_code(field,
                          is_temporary,
                          declaration_only=False,
                          no_declaration=False,
                          is_gpu=False):
    """Returns code string for getting a field pointer.

    This can happen in two ways: either the field is extracted from a walberla block, or a temporary field to swap is
    created.

    Args:
        field: the field for which the code should be created
        is_temporary: new_filtered field from block (False) or create a temporary copy of an existing field (True)
        declaration_only: only create declaration instead of the full code
        no_declaration: create the extraction code, and assume that declarations are elsewhere
        is_gpu: if the field is a GhostLayerField or a GpuField
    """

    # Determine size of f coordinate which is a template parameter
    f_size = get_field_fsize(field)
    field_name = field.name
    dtype = get_base_type(field.dtype)
    field_type = make_field_type(dtype, f_size, is_gpu)

    if not is_temporary:
        dtype = get_base_type(field.dtype)
        field_type = make_field_type(dtype, f_size, is_gpu)
        if declaration_only:
            return "%s * %s;" % (field_type, field_name)
        else:
            prefix = "" if no_declaration else "auto "
            return "%s%s = block->uncheckedFastGetData< %s >(%sID);" % (
                prefix, field_name, field_type, field_name)
    else:
        assert field_name.endswith('_tmp')
        original_field_name = field_name[:-len('_tmp')]
        if declaration_only:
            return "%s * %s;" % (field_type, field_name)
        else:
            declaration = "{type} * {tmp_field_name};".format(
                type=field_type, tmp_field_name=field_name)
            tmp_field_str = temporary_fieldTemplate.format(
                original_field_name=original_field_name,
                tmp_field_name=field_name,
                type=field_type)
            return tmp_field_str if no_declaration else declaration + tmp_field_str
예제 #2
0
 def __new_stage2__(cls, field_name, field_dtype, const):
     name = f"_data_{field_name}"
     dtype = PointerType(get_base_type(field_dtype),
                         const=const,
                         restrict=True)
     obj = super(FieldPointerSymbol, cls).__xnew__(cls, name, dtype)
     obj.field_name = field_name
     return obj
예제 #3
0
 def check_type(e):
     if only_type is None:
         return True
     try:
         base_type = get_base_type(get_type_of_expression(e))
     except ValueError:
         return False
     if only_type == 'int' and (base_type.is_int() or base_type.is_uint()):
         return True
     if only_type == 'real' and (base_type.is_float()):
         return True
     else:
         return base_type == only_type
예제 #4
0
def generate_benchmark(ast, likwid=False, openmp=False, timing=False):
    """Return C code of a benchmark program for the given kernel.

    Args:
        ast: the pystencils AST object as returned by create_kernel
        likwid: if True likwid markers are added to the code
        openmp: relevant only if likwid=True, to generated correct likwid initialization code
        timing: add timing output to the code, prints time per iteration to stdout

    Returns:
        C code as string
    """
    accessed_fields = {f.name: f for f in ast.fields_accessed}
    constants = []
    fields = []
    call_parameters = []
    for p in ast.get_parameters():
        if not p.is_field_parameter:
            constants.append((p.symbol.name, str(p.symbol.dtype)))
            call_parameters.append(p.symbol.name)
        else:
            assert p.is_field_pointer, "Benchmark implemented only for kernels with fixed loop size"
            field = accessed_fields[p.field_name]
            dtype = str(get_base_type(p.symbol.dtype))
            fields.append((p.field_name, dtype, prod(field.shape)))
            call_parameters.append(p.field_name)

    header_list = get_headers(ast)
    includes = "\n".join(["#include %s" % (include_file,) for include_file in header_list])

    # Strip "#pragma omp parallel" from within kernel, because main function takes care of that
    # when likwid and openmp are enabled
    if likwid and openmp:
        if len(ast.body.args) > 0 and isinstance(ast.body.args[0], PragmaBlock):
            ast.body.args[0].pragma_line = ''

    args = {
        'likwid': likwid,
        'openmp': openmp,
        'kernel_code': generate_c(ast, dialect='c'),
        'kernelName': ast.function_name,
        'fields': fields,
        'constants': constants,
        'call_argument_list': ",".join(call_parameters),
        'includes': includes,
        'timing': timing,
    }
    return benchmark_template.render(**args)
예제 #5
0
def get_field_stride(param):
    field = param.fields[0]
    type_str = get_base_type(param.symbol.dtype).base_name
    stride_names = ['xStride()', 'yStride()', 'zStride()', 'fStride()']
    stride_names = [
        "%s(%s->%s)" % (type_str, param.field_name, e) for e in stride_names
    ]
    strides = stride_names[:field.spatial_dimensions]
    if field.index_dimensions > 0:
        additional_strides = [1]
        for shape in reversed(field.index_shape[1:]):
            additional_strides.append(additional_strides[-1] * shape)
        assert len(additional_strides) == field.index_dimensions
        f_stride_name = stride_names[-1]
        strides.extend([
            "%s(%d * %s)" % (type_str, e, f_stride_name)
            for e in reversed(additional_strides)
        ])
    return strides[param.symbol.coordinate]
예제 #6
0
def generate_members(ctx,
                     kernel_info,
                     parameters_to_ignore=(),
                     only_fields=False):
    ast = kernel_info.ast
    fields = {f.name: f for f in ast.fields_accessed}

    params_to_skip = tuple(parameters_to_ignore) + tuple(
        kernel_info.temporary_fields)
    params_to_skip += tuple(e[1] for e in kernel_info.varying_parameters)
    is_gpu = ctx['target'] == 'gpu'

    result = []
    for param in kernel_info.parameters:
        if only_fields and not param.is_field_parameter:
            continue
        if param.is_field_pointer and param.field_name not in params_to_skip:
            result.append("BlockDataID %sID;" % (param.field_name, ))
        elif not param.is_field_parameter and param.symbol.name not in params_to_skip:
            result.append("%s %s;" % (
                param.symbol.dtype,
                param.symbol.name,
            ))

    for field_name in kernel_info.temporary_fields:
        f = fields[field_name]
        if field_name in parameters_to_ignore:
            continue
        assert field_name.endswith('_tmp')
        original_field_name = field_name[:-len('_tmp')]
        f_size = get_field_fsize(f)
        field_type = make_field_type(get_base_type(f.dtype), f_size, is_gpu)
        result.append(
            temporary_fieldMemberTemplate.format(
                type=field_type, original_field_name=original_field_name))

    if hasattr(kernel_info, 'varying_parameters'):
        result.extend(["%s %s;" % e for e in kernel_info.varying_parameters])

    return "\n".join(result)