예제 #1
0
def get_userbuffer_group(func_name, parameters, i):
    """internal function used by process_func_parameters"""
    p = parameters[i]
    p2 = parameters[i + 1]
    p3 = parameters[i + 2]
    if RE.match(r'mpi_i?(alltoall|allgather|gather|scatter)', func_name,
                re.IGNORECASE):
        type = "inplace"
        if RE.search(r'send', p['name'], re.IGNORECASE) and RE.search(
                r'scatter', func_name, re.IGNORECASE):
            type = "noinplace"
        elif RE.search(r'recv', p['name'], re.IGNORECASE) and not RE.search(
                r'scatter', func_name, re.IGNORECASE):
            type = "noinplace"

        if RE.search(r'alltoallw', func_name, re.IGNORECASE):
            group_kind = "USERBUFFER-%s-w" % (type)
            group_count = 4
        elif p3['kind'] == "DATATYPE":
            group_kind = "USERBUFFER-%s" % (type)
            group_count = 3
        else:
            group_kind = "USERBUFFER-%s-v" % (type)
            group_count = 4
    elif RE.match(r'mpi_i?neighbor', func_name, re.IGNORECASE):
        if RE.search(r'alltoallw', func_name, re.IGNORECASE):
            group_kind = "USERBUFFER-neighbor-w"
            group_count = 4
        elif p3['kind'] == "DATATYPE":
            group_kind = "USERBUFFER-neighbor"
            group_count = 3
        else:
            group_kind = "USERBUFFER-neighbor-v"
            group_count = 4
    elif RE.match(r'mpi_i?(allreduce|reduce|scan|exscan)', func_name,
                  re.IGNORECASE):
        group_kind = "USERBUFFER-reduce"
        group_count = 5
    elif RE.match(r'mpi_p(send|recv)_init', func_name, re.IGNORECASE):
        group_kind = "USERBUFFER-partition"
        group_count = 4
    elif RE.search(r'XFER_NUM_ELEM', p2['kind']) and RE.search(
            r'DATATYPE', p3['kind']):
        group_kind = "USERBUFFER-simple"
        group_count = 3
    else:
        group_kind, group_count = None, 0
    return (group_kind, group_count)
예제 #2
0
def parse_param_attributes(p):
    """Parse the parameter attribute string and populate common fields"""
    # this filter function should result in identical results as the JSON
    if RE.search(r'direction\s*=\s*out', p['t'], re.IGNORECASE):
        p['param_direction'] = 'out'
    elif RE.search(r'direction\s*=\s*inout', p['t'], re.IGNORECASE):
        p['param_direction'] = 'inout'
    else:
        p['param_direction'] = 'in'

    if RE.search(r'length\s*=\s*\[(.*)\]', p['t']):
        # only the case of MPI_Group_range_{excl,incl} where length=[n, 3]
        p['length'] = RE.m.group(1).replace(' ', '').split(',')
    elif RE.search(r'length\s*=\s*([^,\s]*)', p['t']):
        p['length'] = RE.m.group(1)
    else:
        p['length'] = None

    if RE.search(r'large_only', p['t']):
        p['large_only'] = True
    else:
        p['large_only'] = False

    if RE.search(r'pointer\s*=\s*True', p['t']):
        p['pointer'] = True
    elif RE.search(r'pointer\s*=\s*False', p['t']):
        p['pointer'] = False
    else:
        p['pointer'] = None

    if RE.search(r'suppress=.*c_parameter', p['t']):
        p['suppress'] = "c_parameter"
    else:
        p['suppress'] = ''

    if RE.search(r'func_type\s*=\s*(\w+)', p['t']):
        p['func_type'] = RE.m.group(1)
    else:
        p['func_type'] = ''

    if RE.search(r'constant\s*=\s*True', p['t']):
        p['constant'] = True
    else:
        p['constant'] = False

    if RE.search(r'asynchronous\s*=\s*True', p['t']):
        p['asynchronous'] = True
    else:
        p['asynchronous'] = False
예제 #3
0
def load_mpi_api(api_txt, gen_in_dir=""):
    """Load mpi standard api into global (G) lists and dictionaries."""
    cur_func, cur_name = '', ''
    stage = ''
    with open(api_txt, "r") as In:
        for line in In:
            # -- stage header --
            if RE.match(r'(MPI\w+):\s*(.*)', line):
                name, attr = RE.m.group(1, 2)
                key = name.lower()
                stage = "FUNC"
                cur_name = name
                if key in G.FUNCS:
                    cur_func = G.FUNCS[key]
                    if RE.search(r'not_implemented', attr):
                        cur_func['not_implemented'] = True
                else:
                    cur_func = {
                        'name': name,
                        'parameters': [],
                        'attrs': attr,
                        'desc': ""
                    }
                    G.FUNCS[key] = cur_func
                if gen_in_dir:
                    cur_func['dir'] = gen_in_dir
            elif RE.match(r'(\w+)', line):
                print("Unexpected leading word [%s] in %s" %
                      (RE.m.group(1), api_txt),
                      file=sys.stderr)
                # anything with unexpected unindented word resets stage
                stage = ''
            # -- per-stage parsing --
            elif stage == "FUNC":
                if RE.match(r'\s+\.(\w+):\s*(.*)', line):
                    key, val = RE.m.group(1, 2)
                    cur_func[key] = val
                elif RE.match(r'\s+(\w+):\s*(\w+)(.*)', line):
                    name, kind, t = RE.m.group(1, 2, 3)
                    if name == 'index':
                        # avoid -Wshadow warning
                        name = 'indx'
                    p = {'name': name, 'kind': kind}
                    if RE.match(r'(.*),\s*\[(.*)\]\s*$', t):
                        t, p['desc'] = RE.m.group(1, 2)
                    p['t'] = t
                    # we include all extra attributes in a 't' string for flexibity
                    # we'll parse the common fields also to improve code readability
                    parse_param_attributes(p)
                    cur_func['parameters'].append(p)
                elif RE.match(r'{\s*-+\s*(\w+)\s*-+(.*)', line):
                    stage = "code-" + RE.m.group(1)
                    if stage not in cur_func:
                        cur_func[stage] = []
                    # "error_check" may include list of parameters checked
                    # "handle_ptr" may include list of parameters converted
                    cur_func[stage + "-tail"] = RE.m.group(2).replace(
                        ' ', '').split(',')
                elif RE.match(r'{', line):
                    stage = "FUNC-body"
                    if 'body' not in cur_func:
                        cur_func['body'] = []
                elif RE.match(r'\/\*', line):
                    # man page notes
                    stage = "FUNC-notes"
                    # 'notes' and 'notes2' goes before and after auto-generated notes
                    if RE.match(r'\/\*\s*-+\s*notes-2\s*-+', line):
                        cur_func['notes2'] = []
                    elif 'notes' not in cur_func:
                        cur_func['notes'] = []
                    else:
                        cur_func['notes2'] = []
            elif stage == "FUNC-body":
                if RE.match(r'}', line):
                    stage = "FUNC"
                else:
                    line = re.sub(r'^    ', '', line)
                    cur_func['body'].append(line)
            elif RE.match(r'(code-\w+)', stage):
                if RE.match(r'}', line):
                    stage = "FUNC"
                else:
                    line = re.sub(r'^    ', '', line)
                    cur_func[stage].append(line)
            elif stage == "FUNC-notes":
                if RE.match(r'\*\/', line):
                    stage = "FUNC"
                else:
                    line = re.sub(r'^    ', '', line)
                    if 'notes2' in cur_func:
                        cur_func['notes2'].append(line)
                    else:
                        cur_func['notes'].append(line)