mpcdf_common.py 3.59 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
from __future__ import print_function

__all__ = ["valid_mpi", "valid_cuda", "get_attribute", "mpcdf_enable_repositories"]

import osc
import osc.conf
import osc.core

from xml.etree import ElementTree


def valid_mpi(compiler, mpi):
    """
    It might be possible to use Intel MPI libararies and compilers from
    different Parallel Studio packages, but I currently do not want to support
    it
    """
    if compiler == "intel_17_0":
        if mpi.startswith("impi"):
            return mpi == "impi_2017_3"
    if compiler == "intel_16_0":
        if mpi.startswith("impi"):
            return mpi == "impi_5_1_3"
    return True


def valid_cuda(cuda, compiler):
    """
    The CUDA distribution only works with certain gcc versions,
    this little function takes care that only supported combinations
    are allowed
    """
    if cuda == "cuda_8":
        return compiler == "gcc_5"
    return False


def get_attribute(api_url, project, package, attribute, with_project=False):

    attribute_meta = osc.core.show_attribute_meta(api_url, project, package, None, attribute, False, with_project)
    if attribute_meta is None:
        raise oscerr.APIError("Cannot fetch value for attribute '{0}' from {1}".format(attribute, (project, package)))

    root = ElementTree.fromstringlist(attribute_meta)
    attribute = root.find("./attribute")
    if attribute is not None:
        return list(value.text for value in attribute.findall("./value"))
    else:
        raise Exception("Attribute not set")


def mpcdf_enable_repositories(api_url, project, package, verbose=False):

    root = ElementTree.fromstringlist(osc.core.show_package_meta(api_url, project, package))
    build = root.find("./build")
    for enable in build.findall("./enable"):
        build.remove(enable)

    compilers = get_attribute(api_url, project, package, "MPCDF:compiler_modules", with_project=True)
    mpis = get_attribute(api_url, project, package, "MPCDF:mpi_modules", with_project=True)
    cudas = get_attribute(api_url, project, package, "MPCDF:cuda_modules", with_project=True)

    def enable(name):
        node = ElementTree.Element("enable")
        node.set("repository", name)
        node.tail = "\n    "
        build.insert(0, node)
        if verbose:
            print("Enabling", name)

    try:
        enable_repos = get_attribute(api_url, project, package, "MPCDF:enable_repositories")
    except:
        if verbose:
            print("Warning: Could not get attribute MPCDF:enable_repositories for package {0}".format(package))
        return False

    for flag in enable_repos:

        if flag == "system":
            enable("System")

        if flag == "compilers":
            for compiler in compilers:
                enable(compiler)

        if flag == "mpi":
            for compiler in compilers:
                for mpi in mpis:
                    if valid_mpi(compiler, mpi):
                       enable(mpi + "_" + compiler)

        if flag == "cuda":
            for cuda in cudas:
                for compiler in compilers:
                    if valid_cuda(cuda, compiler):
                        enable(cuda + "_" + compiler)

        if flag == "cuda_mpi":
            for cuda in cudas:
                for compiler in compilers:
                    if valid_cuda(cuda, compiler):
                        for mpi in mpis:
                            if valid_mpi(compiler, mpi):
                                enable(cuda + "_" + compiler)

    build.getchildren()[-1].tail = "\n  "

    pkg_meta = ET.tostring(root, encoding=osc.core.ET_ENCODING)

    osc.core.edit_meta("pkg", (project, package), data=pkg_meta)
    return True