pyomp 0.5.0__cp314-cp314t-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- numba/openmp/__init__.py +106 -0
- numba/openmp/_version.py +34 -0
- numba/openmp/analysis.py +251 -0
- numba/openmp/compiler.py +402 -0
- numba/openmp/config.py +27 -0
- numba/openmp/decorators.py +27 -0
- numba/openmp/exceptions.py +26 -0
- numba/openmp/ir_utils.py +4 -0
- numba/openmp/libs/openmp/lib/libgomp.1.dylib +0 -0
- numba/openmp/libs/openmp/lib/libgomp.dylib +0 -0
- numba/openmp/libs/openmp/lib/libiomp5.dylib +0 -0
- numba/openmp/libs/openmp/lib/libomp.dylib +0 -0
- numba/openmp/libs/openmp/patches/14.0.6/0001-BACKPORT-Fix-for-CUDA-OpenMP-RTL.patch +39 -0
- numba/openmp/libs/openmp/patches/14.0.6/0002-Fix-missing-includes.patch +12 -0
- numba/openmp/libs/openmp/patches/14.0.6/0003-Link-static-LLVM-libs.patch +13 -0
- numba/openmp/libs/openmp/patches/15.0.7/0001-Fix-missing-includes.patch +14 -0
- numba/openmp/libs/openmp/patches/15.0.7/0002-Link-LLVM-statically.patch +101 -0
- numba/openmp/libs/openmp/patches/15.0.7/0003-Disable-opaque-pointers-DeviceRTL-bitcode.patch +12 -0
- numba/openmp/libs/openmp/patches/16.0.6/0001-Load-plugins-from-install-directory.patch +53 -0
- numba/openmp/libs/openmp/patches/16.0.6/0002-Link-LLVM-statically.patch +218 -0
- numba/openmp/libs/openmp/patches/20.1.8/0001-Enable-standalone-build.patch +13 -0
- numba/openmp/libs/openmp/patches/20.1.8/0002-Link-statically-LLVM.patch +24 -0
- numba/openmp/libs/openmp/patches/20.1.8/0003-Do-not-build-liboffload.patch +12 -0
- numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp +2939 -0
- numba/openmp/libs/pass/CGIntrinsicsOpenMP.h +606 -0
- numba/openmp/libs/pass/CMakeLists.txt +57 -0
- numba/openmp/libs/pass/DebugOpenMP.cpp +17 -0
- numba/openmp/libs/pass/DebugOpenMP.h +28 -0
- numba/openmp/libs/pass/IntrinsicsOpenMP.cpp +837 -0
- numba/openmp/libs/pass/IntrinsicsOpenMP.h +13 -0
- numba/openmp/libs/pass/IntrinsicsOpenMP_CAPI.h +23 -0
- numba/openmp/libs/pass/libIntrinsicsOpenMP.dylib +0 -0
- numba/openmp/link_utils.py +126 -0
- numba/openmp/llvm_pass.py +48 -0
- numba/openmp/llvmlite_extensions.py +75 -0
- numba/openmp/omp_context.py +242 -0
- numba/openmp/omp_grammar.py +696 -0
- numba/openmp/omp_ir.py +2105 -0
- numba/openmp/omp_lower.py +3125 -0
- numba/openmp/omp_runtime.py +107 -0
- numba/openmp/overloads.py +53 -0
- numba/openmp/parser.py +6 -0
- numba/openmp/tags.py +532 -0
- numba/openmp/tests/test_openmp.py +5056 -0
- pyomp-0.5.0.dist-info/METADATA +193 -0
- pyomp-0.5.0.dist-info/RECORD +52 -0
- pyomp-0.5.0.dist-info/WHEEL +6 -0
- pyomp-0.5.0.dist-info/licenses/LICENSE +25 -0
- pyomp-0.5.0.dist-info/licenses/LICENSE-OPENMP.txt +361 -0
- pyomp-0.5.0.dist-info/top_level.txt +3 -0
- pyomp.dylibs/libc++.1.0.dylib +0 -0
- pyomp.dylibs/libzstd.1.5.7.dylib +0 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
from numba.core import types
|
|
2
|
+
from numba.core.types.functions import ExternalFunction
|
|
3
|
+
from numba.core.datamodel.registry import register_default as model_register
|
|
4
|
+
from numba.core.datamodel.models import OpaqueModel
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class _OpenmpExternalFunction(types.ExternalFunction):
|
|
8
|
+
def __call__(self, *args):
|
|
9
|
+
import inspect
|
|
10
|
+
|
|
11
|
+
frm = inspect.stack()[1]
|
|
12
|
+
mod = inspect.getmodule(frm[0])
|
|
13
|
+
if mod.__name__.startswith("numba") and not mod.__name__.startswith(
|
|
14
|
+
"numba.openmp.tests"
|
|
15
|
+
):
|
|
16
|
+
return super(ExternalFunction, self).__call__(*args)
|
|
17
|
+
|
|
18
|
+
# Resolve the function address via llvmlite's symbol table so we
|
|
19
|
+
# call the same LLVM-registered symbol the JIT uses. Then wrap
|
|
20
|
+
# it with ctypes CFUNCTYPE to call from Python. This avoids
|
|
21
|
+
# dlopen/dlsym namespace mismatches.
|
|
22
|
+
import llvmlite.binding as ll
|
|
23
|
+
import ctypes
|
|
24
|
+
|
|
25
|
+
fname = self.symbol
|
|
26
|
+
|
|
27
|
+
addr = ll.address_of_symbol(fname)
|
|
28
|
+
if not addr:
|
|
29
|
+
raise RuntimeError(
|
|
30
|
+
f"symbol {fname} not found via llvmlite.address_of_symbol"
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
def numba_to_ctype(tstr):
|
|
34
|
+
if tstr == "int32":
|
|
35
|
+
return ctypes.c_int
|
|
36
|
+
elif tstr == "none":
|
|
37
|
+
return None
|
|
38
|
+
elif tstr == "float64":
|
|
39
|
+
return ctypes.c_double
|
|
40
|
+
else:
|
|
41
|
+
raise RuntimeError(f"unsupported type: {tstr}")
|
|
42
|
+
|
|
43
|
+
restype = numba_to_ctype(str(self.sig.return_type))
|
|
44
|
+
argtypes = [numba_to_ctype(str(a)) for a in self.sig.args]
|
|
45
|
+
|
|
46
|
+
# CFUNCTYPE requires a valid ctypes restype; None maps to None (void)
|
|
47
|
+
cfunctype = (
|
|
48
|
+
ctypes.CFUNCTYPE(restype, *argtypes)
|
|
49
|
+
if argtypes
|
|
50
|
+
else ctypes.CFUNCTYPE(restype)
|
|
51
|
+
)
|
|
52
|
+
cfunc = cfunctype(addr)
|
|
53
|
+
return cfunc(*args)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
model_register(_OpenmpExternalFunction)(OpaqueModel)
|
|
57
|
+
|
|
58
|
+
omp_set_num_threads = _OpenmpExternalFunction(
|
|
59
|
+
"omp_set_num_threads", types.void(types.int32)
|
|
60
|
+
)
|
|
61
|
+
omp_get_thread_num = _OpenmpExternalFunction("omp_get_thread_num", types.int32())
|
|
62
|
+
omp_get_num_threads = _OpenmpExternalFunction("omp_get_num_threads", types.int32())
|
|
63
|
+
omp_get_wtime = _OpenmpExternalFunction("omp_get_wtime", types.float64())
|
|
64
|
+
omp_set_dynamic = _OpenmpExternalFunction("omp_set_dynamic", types.void(types.int32))
|
|
65
|
+
omp_set_nested = _OpenmpExternalFunction("omp_set_nested", types.void(types.int32))
|
|
66
|
+
omp_set_max_active_levels = _OpenmpExternalFunction(
|
|
67
|
+
"omp_set_max_active_levels", types.void(types.int32)
|
|
68
|
+
)
|
|
69
|
+
omp_get_max_active_levels = _OpenmpExternalFunction(
|
|
70
|
+
"omp_get_max_active_levels", types.int32()
|
|
71
|
+
)
|
|
72
|
+
omp_get_max_threads = _OpenmpExternalFunction("omp_get_max_threads", types.int32())
|
|
73
|
+
omp_get_num_procs = _OpenmpExternalFunction("omp_get_num_procs", types.int32())
|
|
74
|
+
omp_in_parallel = _OpenmpExternalFunction("omp_in_parallel", types.int32())
|
|
75
|
+
omp_get_thread_limit = _OpenmpExternalFunction("omp_get_thread_limit", types.int32())
|
|
76
|
+
omp_get_supported_active_levels = _OpenmpExternalFunction(
|
|
77
|
+
"omp_get_supported_active_levels", types.int32()
|
|
78
|
+
)
|
|
79
|
+
omp_get_level = _OpenmpExternalFunction("omp_get_level", types.int32())
|
|
80
|
+
omp_get_active_level = _OpenmpExternalFunction("omp_get_active_level", types.int32())
|
|
81
|
+
omp_get_ancestor_thread_num = _OpenmpExternalFunction(
|
|
82
|
+
"omp_get_ancestor_thread_num", types.int32(types.int32)
|
|
83
|
+
)
|
|
84
|
+
omp_get_team_size = _OpenmpExternalFunction(
|
|
85
|
+
"omp_get_team_size", types.int32(types.int32)
|
|
86
|
+
)
|
|
87
|
+
omp_in_final = _OpenmpExternalFunction("omp_in_finale", types.int32())
|
|
88
|
+
omp_get_proc_bind = _OpenmpExternalFunction("omp_get_proc_bind", types.int32())
|
|
89
|
+
omp_get_num_places = _OpenmpExternalFunction("omp_get_num_places", types.int32())
|
|
90
|
+
omp_get_place_num_procs = _OpenmpExternalFunction(
|
|
91
|
+
"omp_get_place_num_procs", types.int32(types.int32)
|
|
92
|
+
)
|
|
93
|
+
omp_get_place_num = _OpenmpExternalFunction("omp_get_place_num", types.int32())
|
|
94
|
+
omp_set_default_device = _OpenmpExternalFunction(
|
|
95
|
+
"omp_set_default_device", types.int32(types.int32)
|
|
96
|
+
)
|
|
97
|
+
omp_get_default_device = _OpenmpExternalFunction(
|
|
98
|
+
"omp_get_default_device", types.int32()
|
|
99
|
+
)
|
|
100
|
+
omp_get_num_devices = _OpenmpExternalFunction("omp_get_num_devices", types.int32())
|
|
101
|
+
omp_get_device_num = _OpenmpExternalFunction("omp_get_device_num", types.int32())
|
|
102
|
+
omp_get_team_num = _OpenmpExternalFunction("omp_get_team_num", types.int32())
|
|
103
|
+
omp_get_num_teams = _OpenmpExternalFunction("omp_get_num_teams", types.int32())
|
|
104
|
+
omp_is_initial_device = _OpenmpExternalFunction("omp_is_initial_device", types.int32())
|
|
105
|
+
omp_get_initial_device = _OpenmpExternalFunction(
|
|
106
|
+
"omp_get_initial_device", types.int32()
|
|
107
|
+
)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from numba.extending import overload
|
|
2
|
+
from numba.core import types
|
|
3
|
+
from numba import cuda as numba_cuda
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
from .config import DEBUG_OPENMP
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def openmp_copy(a):
|
|
11
|
+
pass # should always be called through overload
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@overload(openmp_copy)
|
|
15
|
+
def openmp_copy_overload(a):
|
|
16
|
+
if DEBUG_OPENMP >= 1:
|
|
17
|
+
print("openmp_copy:", a, type(a))
|
|
18
|
+
if isinstance(a, types.npytypes.Array):
|
|
19
|
+
|
|
20
|
+
def cimpl(a):
|
|
21
|
+
return np.copy(a)
|
|
22
|
+
|
|
23
|
+
return cimpl
|
|
24
|
+
else:
|
|
25
|
+
|
|
26
|
+
def cimpl(a):
|
|
27
|
+
return a
|
|
28
|
+
|
|
29
|
+
return cimpl
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def omp_shared_array(size, dtype):
|
|
33
|
+
return np.empty(size, dtype=dtype)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@overload(omp_shared_array, target="cpu", inline="always", prefer_literal=True)
|
|
37
|
+
def omp_shared_array_overload_cpu(size, dtype):
|
|
38
|
+
assert isinstance(size, types.IntegerLiteral)
|
|
39
|
+
|
|
40
|
+
def impl(size, dtype):
|
|
41
|
+
return np.empty(size, dtype=dtype)
|
|
42
|
+
|
|
43
|
+
return impl
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@overload(omp_shared_array, target="cuda", inline="always", prefer_literal=True)
|
|
47
|
+
def omp_shared_array_overload_cuda(size, dtype):
|
|
48
|
+
assert isinstance(size, types.IntegerLiteral)
|
|
49
|
+
|
|
50
|
+
def impl(size, dtype):
|
|
51
|
+
return numba_cuda.shared.array(size, dtype)
|
|
52
|
+
|
|
53
|
+
return impl
|
numba/openmp/parser.py
ADDED
numba/openmp/tags.py
ADDED
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
from numba.core import ir, types, cgutils
|
|
2
|
+
from numba import njit
|
|
3
|
+
from numba.core.ir_utils import replace_vars_inner
|
|
4
|
+
import llvmlite.ir as lir
|
|
5
|
+
import numpy as np
|
|
6
|
+
|
|
7
|
+
from .config import DEBUG_OPENMP
|
|
8
|
+
from .llvmlite_extensions import get_decl
|
|
9
|
+
from .analysis import typemap_lookup, is_dsa
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def copy_np_array(x):
|
|
13
|
+
return np.copy(x)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class StringLiteral:
|
|
17
|
+
def __init__(self, x):
|
|
18
|
+
self.x = x
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class NameSlice:
|
|
22
|
+
def __init__(self, name, the_slice):
|
|
23
|
+
self.name = name
|
|
24
|
+
self.the_slice = the_slice
|
|
25
|
+
|
|
26
|
+
def __str__(self):
|
|
27
|
+
return "NameSlice(" + str(self.name) + "," + str(self.the_slice) + ")"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def create_native_np_copy(arg_typ):
|
|
31
|
+
# Use the high-level dispatcher API (`njit`) instead of the
|
|
32
|
+
# removed/legacy `compile_isolated` helper.
|
|
33
|
+
dispatcher = njit(copy_np_array)
|
|
34
|
+
dispatcher.get_function_type()
|
|
35
|
+
atypes = (arg_typ,)
|
|
36
|
+
# copy_cres = dispatcher.get_compile_result(sig)
|
|
37
|
+
dispatcher.compile(atypes)
|
|
38
|
+
copy_cres = dispatcher.overloads[atypes]
|
|
39
|
+
assert copy_cres is not None
|
|
40
|
+
fndesc = getattr(copy_cres, "fndesc", None)
|
|
41
|
+
assert fndesc is not None
|
|
42
|
+
copy_name = getattr(fndesc, "llvm_cfunc_wrapper_name", None)
|
|
43
|
+
assert copy_name is not None
|
|
44
|
+
|
|
45
|
+
return (copy_name, copy_cres)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class openmp_tag(object):
|
|
49
|
+
def __init__(self, name, arg=None, load=False, non_arg=False, omp_slice=None):
|
|
50
|
+
self.name = name
|
|
51
|
+
self.arg = arg
|
|
52
|
+
self.load = load
|
|
53
|
+
self.loaded_arg = None
|
|
54
|
+
self.xarginfo = []
|
|
55
|
+
self.non_arg = non_arg
|
|
56
|
+
self.omp_slice = omp_slice
|
|
57
|
+
|
|
58
|
+
def __getstate__(self):
|
|
59
|
+
state = self.__dict__.copy()
|
|
60
|
+
if isinstance(self.arg, lir.instructions.AllocaInstr):
|
|
61
|
+
del state["arg"]
|
|
62
|
+
return state
|
|
63
|
+
|
|
64
|
+
def __setstate__(self, state):
|
|
65
|
+
self.__dict__.update(state)
|
|
66
|
+
if not hasattr(self, "arg"):
|
|
67
|
+
self.arg = None
|
|
68
|
+
|
|
69
|
+
def var_in(self, var):
|
|
70
|
+
assert isinstance(var, str)
|
|
71
|
+
|
|
72
|
+
if isinstance(self.arg, ir.Var):
|
|
73
|
+
return self.arg.name == var
|
|
74
|
+
|
|
75
|
+
if isinstance(self.arg, str):
|
|
76
|
+
return self.arg == var
|
|
77
|
+
|
|
78
|
+
return False
|
|
79
|
+
|
|
80
|
+
def arg_size(self, x, lowerer):
|
|
81
|
+
if DEBUG_OPENMP >= 2:
|
|
82
|
+
print("arg_size:", x, type(x))
|
|
83
|
+
if isinstance(x, NameSlice):
|
|
84
|
+
x = x.name
|
|
85
|
+
if isinstance(x, ir.Var):
|
|
86
|
+
# Make sure the var referred to has been alloc'ed already.
|
|
87
|
+
lowerer._alloca_var(x.name, lowerer.fndesc.typemap[x.name])
|
|
88
|
+
if self.load:
|
|
89
|
+
assert False
|
|
90
|
+
else:
|
|
91
|
+
arg_str = lowerer.getvar(x.name)
|
|
92
|
+
return lowerer.context.get_abi_sizeof(arg_str.type.pointee)
|
|
93
|
+
elif isinstance(x, lir.instructions.AllocaInstr):
|
|
94
|
+
return lowerer.context.get_abi_sizeof(x.type.pointee)
|
|
95
|
+
elif isinstance(x, str):
|
|
96
|
+
xtyp = lowerer.fndesc.typemap[x]
|
|
97
|
+
if DEBUG_OPENMP >= 1:
|
|
98
|
+
print("xtyp:", xtyp, type(xtyp))
|
|
99
|
+
lowerer._alloca_var(x, xtyp)
|
|
100
|
+
if self.load:
|
|
101
|
+
assert False
|
|
102
|
+
else:
|
|
103
|
+
arg_str = lowerer.getvar(x)
|
|
104
|
+
return lowerer.context.get_abi_sizeof(arg_str.type.pointee)
|
|
105
|
+
elif isinstance(x, int):
|
|
106
|
+
assert False
|
|
107
|
+
else:
|
|
108
|
+
print("unknown arg type:", x, type(x))
|
|
109
|
+
assert False
|
|
110
|
+
|
|
111
|
+
def arg_to_str(self, x, lowerer, gen_copy=False):
|
|
112
|
+
if DEBUG_OPENMP >= 1:
|
|
113
|
+
print("arg_to_str:", x, type(x), self.load, type(self.load))
|
|
114
|
+
|
|
115
|
+
typemap = lowerer.fndesc.typemap
|
|
116
|
+
xtyp = None
|
|
117
|
+
|
|
118
|
+
if isinstance(x, NameSlice):
|
|
119
|
+
if DEBUG_OPENMP >= 2:
|
|
120
|
+
print("nameslice found:", x)
|
|
121
|
+
x = x.name
|
|
122
|
+
if isinstance(x, ir.Var):
|
|
123
|
+
# Make sure the var referred to has been alloc'ed already.
|
|
124
|
+
lowerer._alloca_var(x.name, typemap_lookup(typemap, x))
|
|
125
|
+
if self.load:
|
|
126
|
+
if not self.loaded_arg:
|
|
127
|
+
self.loaded_arg = lowerer.loadvar(x.name)
|
|
128
|
+
lop = self.loaded_arg.operands[0]
|
|
129
|
+
loptype = lop.type
|
|
130
|
+
pointee = loptype.pointee
|
|
131
|
+
ref = self.loaded_arg._get_reference()
|
|
132
|
+
decl = str(pointee) + " " + ref
|
|
133
|
+
else:
|
|
134
|
+
arg_str = lowerer.getvar(x.name)
|
|
135
|
+
if isinstance(arg_str, lir.values.Argument):
|
|
136
|
+
decl = str(arg_str)
|
|
137
|
+
else:
|
|
138
|
+
decl = get_decl(arg_str)
|
|
139
|
+
elif isinstance(x, lir.instructions.AllocaInstr):
|
|
140
|
+
decl = get_decl(x)
|
|
141
|
+
elif isinstance(x, str):
|
|
142
|
+
if "*" in x:
|
|
143
|
+
xsplit = x.split("*")
|
|
144
|
+
assert len(xsplit) == 2
|
|
145
|
+
# xtyp = get_dotted_type(x, typemap, lowerer)
|
|
146
|
+
xtyp = typemap_lookup(typemap, xsplit[0])
|
|
147
|
+
if DEBUG_OPENMP >= 1:
|
|
148
|
+
print("xtyp:", xtyp, type(xtyp))
|
|
149
|
+
lowerer._alloca_var(x, xtyp)
|
|
150
|
+
if self.load:
|
|
151
|
+
if not self.loaded_arg:
|
|
152
|
+
self.loaded_arg = lowerer.loadvar(x)
|
|
153
|
+
lop = self.loaded_arg.operands[0]
|
|
154
|
+
loptype = lop.type
|
|
155
|
+
pointee = loptype.pointee
|
|
156
|
+
ref = self.loaded_arg._get_reference()
|
|
157
|
+
decl = str(pointee) + " " + ref
|
|
158
|
+
assert len(xsplit) == 1
|
|
159
|
+
else:
|
|
160
|
+
arg_str = lowerer.getvar(xsplit[0])
|
|
161
|
+
# arg_str = lowerer.getvar(x)
|
|
162
|
+
if isinstance(arg_str, lir.Argument):
|
|
163
|
+
decl = str(arg_str)
|
|
164
|
+
else:
|
|
165
|
+
decl = get_decl(arg_str)
|
|
166
|
+
if len(xsplit) > 1:
|
|
167
|
+
cur_typ = xtyp
|
|
168
|
+
field_info = []
|
|
169
|
+
for field in xsplit[1:]:
|
|
170
|
+
dm = lowerer.context.data_model_manager.lookup(cur_typ)
|
|
171
|
+
findex = dm._fields.index(field)
|
|
172
|
+
cur_typ = dm._members[findex]
|
|
173
|
+
llvm_type = lowerer.context.get_value_type(cur_typ)
|
|
174
|
+
if isinstance(cur_typ, types.CPointer):
|
|
175
|
+
llvm_type = llvm_type.pointee
|
|
176
|
+
field_info.append(f"{llvm_type} poison")
|
|
177
|
+
field_info.append("i32 " + str(findex))
|
|
178
|
+
fi_str = ", ".join(field_info)
|
|
179
|
+
decl += f", {fi_str}"
|
|
180
|
+
# decl = f"SCOPE({decl}, {fi_str})"
|
|
181
|
+
else:
|
|
182
|
+
xtyp = typemap_lookup(typemap, x)
|
|
183
|
+
if DEBUG_OPENMP >= 1:
|
|
184
|
+
print("xtyp:", xtyp, type(xtyp))
|
|
185
|
+
lowerer._alloca_var(x, xtyp)
|
|
186
|
+
if self.load:
|
|
187
|
+
if not self.loaded_arg:
|
|
188
|
+
self.loaded_arg = lowerer.loadvar(x)
|
|
189
|
+
lop = self.loaded_arg.operands[0]
|
|
190
|
+
loptype = lop.type
|
|
191
|
+
pointee = loptype.pointee
|
|
192
|
+
ref = self.loaded_arg._get_reference()
|
|
193
|
+
decl = str(pointee) + " " + ref
|
|
194
|
+
else:
|
|
195
|
+
arg_str = lowerer.getvar(x)
|
|
196
|
+
if isinstance(arg_str, lir.values.Argument):
|
|
197
|
+
decl = str(arg_str)
|
|
198
|
+
elif isinstance(arg_str, lir.instructions.AllocaInstr):
|
|
199
|
+
decl = get_decl(arg_str)
|
|
200
|
+
else:
|
|
201
|
+
assert False, (
|
|
202
|
+
f"Don't know how to get decl string for variable {arg_str} of type {type(arg_str)}"
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
if gen_copy and isinstance(xtyp, types.npytypes.Array):
|
|
206
|
+
native_np_copy, copy_cres = create_native_np_copy(xtyp)
|
|
207
|
+
lowerer.library.add_llvm_module(copy_cres.library._final_module)
|
|
208
|
+
nnclen = len(native_np_copy)
|
|
209
|
+
decl += f', [{nnclen} x i8] c"{native_np_copy}"'
|
|
210
|
+
|
|
211
|
+
# Add type information using a poison value operand for non-alloca pointers.
|
|
212
|
+
if not isinstance(lowerer.getvar(x), lir.instructions.AllocaInstr):
|
|
213
|
+
llvm_type = lowerer.context.get_value_type(xtyp)
|
|
214
|
+
decl += f", {llvm_type} poison"
|
|
215
|
+
elif isinstance(x, StringLiteral):
|
|
216
|
+
decl = str(cgutils.make_bytearray(x.x))
|
|
217
|
+
elif isinstance(x, int):
|
|
218
|
+
decl = "i32 " + str(x)
|
|
219
|
+
else:
|
|
220
|
+
print("unknown arg type:", x, type(x))
|
|
221
|
+
|
|
222
|
+
if self.omp_slice is not None:
|
|
223
|
+
|
|
224
|
+
def handle_var(x):
|
|
225
|
+
if isinstance(x, ir.Var):
|
|
226
|
+
loaded_size = lowerer.loadvar(x.name)
|
|
227
|
+
loaded_op = loaded_size.operands[0]
|
|
228
|
+
loaded_pointee = loaded_op.type.pointee
|
|
229
|
+
ret = str(loaded_pointee) + " " + loaded_size._get_reference()
|
|
230
|
+
else:
|
|
231
|
+
ret = "i64 " + str(x)
|
|
232
|
+
return ret
|
|
233
|
+
|
|
234
|
+
start_slice = handle_var(self.omp_slice[0])
|
|
235
|
+
end_slice = handle_var(self.omp_slice[1])
|
|
236
|
+
decl += f", {start_slice}, {end_slice}"
|
|
237
|
+
# decl = f"SLICE({decl}, {self.omp_slice[0]}, {self.omp_slice[1]})"
|
|
238
|
+
|
|
239
|
+
return decl
|
|
240
|
+
|
|
241
|
+
def post_entry(self, lowerer):
|
|
242
|
+
for xarginfo, xarginfo_args, x, alloca_tuple_list in self.xarginfo:
|
|
243
|
+
loaded_args = [
|
|
244
|
+
lowerer.builder.load(alloca_tuple[2])
|
|
245
|
+
for alloca_tuple in alloca_tuple_list
|
|
246
|
+
]
|
|
247
|
+
fa_res = xarginfo.from_arguments(lowerer.builder, tuple(loaded_args))
|
|
248
|
+
# fa_res = xarginfo.from_arguments(lowerer.builder,tuple([xarg for xarg in xarginfo_args]))
|
|
249
|
+
assert len(fa_res) == 1
|
|
250
|
+
lowerer.storevar(fa_res[0], x)
|
|
251
|
+
|
|
252
|
+
def add_length_firstprivate(self, x, lowerer):
|
|
253
|
+
if self.name == "QUAL.OMP.FIRSTPRIVATE":
|
|
254
|
+
return [x]
|
|
255
|
+
# return [x, self.arg_size(x, lowerer)]
|
|
256
|
+
# return [x, lowerer.context.get_constant(types.uintp, self.arg_size(x, lowerer))]
|
|
257
|
+
else:
|
|
258
|
+
return [x]
|
|
259
|
+
|
|
260
|
+
def unpack_arg(self, x, lowerer, xarginfo_list):
|
|
261
|
+
if isinstance(x, ir.Var):
|
|
262
|
+
return self.add_length_firstprivate(x, lowerer), None
|
|
263
|
+
elif isinstance(x, lir.instructions.AllocaInstr):
|
|
264
|
+
return self.add_length_firstprivate(x, lowerer), None
|
|
265
|
+
elif isinstance(x, str):
|
|
266
|
+
xtyp = lowerer.fndesc.typemap[x]
|
|
267
|
+
if DEBUG_OPENMP >= 2:
|
|
268
|
+
print("xtyp:", xtyp, type(xtyp))
|
|
269
|
+
if self.load:
|
|
270
|
+
return self.add_length_firstprivate(x, lowerer), None
|
|
271
|
+
else:
|
|
272
|
+
names_to_unpack = []
|
|
273
|
+
# names_to_unpack = ["QUAL.OMP.FIRSTPRIVATE"]
|
|
274
|
+
# names_to_unpack = ["QUAL.OMP.PRIVATE", "QUAL.OMP.FIRSTPRIVATE"]
|
|
275
|
+
if (
|
|
276
|
+
isinstance(xtyp, types.npytypes.Array)
|
|
277
|
+
and self.name in names_to_unpack
|
|
278
|
+
):
|
|
279
|
+
# from core/datamodel/packer.py
|
|
280
|
+
xarginfo = lowerer.context.get_arg_packer((xtyp,))
|
|
281
|
+
xloaded = lowerer.loadvar(x)
|
|
282
|
+
xarginfo_args = list(
|
|
283
|
+
xarginfo.as_arguments(lowerer.builder, [xloaded])
|
|
284
|
+
)
|
|
285
|
+
xarg_alloca_vars = []
|
|
286
|
+
for xarg in xarginfo_args:
|
|
287
|
+
if DEBUG_OPENMP >= 2:
|
|
288
|
+
print(
|
|
289
|
+
"xarg:",
|
|
290
|
+
type(xarg),
|
|
291
|
+
xarg,
|
|
292
|
+
"agg:",
|
|
293
|
+
xarg.aggregate,
|
|
294
|
+
type(xarg.aggregate),
|
|
295
|
+
"ind:",
|
|
296
|
+
xarg.indices,
|
|
297
|
+
)
|
|
298
|
+
print(xarg.aggregate.type.elements[xarg.indices[0]])
|
|
299
|
+
alloca_name = "$alloca_" + xarg.name
|
|
300
|
+
alloca_typ = xarg.aggregate.type.elements[xarg.indices[0]]
|
|
301
|
+
alloca_res = lowerer.alloca_lltype(alloca_name, alloca_typ)
|
|
302
|
+
if DEBUG_OPENMP >= 2:
|
|
303
|
+
print(
|
|
304
|
+
"alloca:",
|
|
305
|
+
alloca_name,
|
|
306
|
+
alloca_typ,
|
|
307
|
+
alloca_res,
|
|
308
|
+
alloca_res.get_reference(),
|
|
309
|
+
)
|
|
310
|
+
xarg_alloca_vars.append((alloca_name, alloca_typ, alloca_res))
|
|
311
|
+
lowerer.builder.store(xarg, alloca_res)
|
|
312
|
+
xarginfo_list.append((xarginfo, xarginfo_args, x, xarg_alloca_vars))
|
|
313
|
+
rets = []
|
|
314
|
+
for i, xarg in enumerate(xarg_alloca_vars):
|
|
315
|
+
rets.append(xarg[2])
|
|
316
|
+
if i == 4:
|
|
317
|
+
alloca_name = "$alloca_total_size_" + str(x)
|
|
318
|
+
if DEBUG_OPENMP >= 2:
|
|
319
|
+
print("alloca_name:", alloca_name)
|
|
320
|
+
alloca_typ = lowerer.context.get_value_type(
|
|
321
|
+
types.intp
|
|
322
|
+
) # lir.Type.int(64)
|
|
323
|
+
alloca_res = lowerer.alloca_lltype(alloca_name, alloca_typ)
|
|
324
|
+
if DEBUG_OPENMP >= 2:
|
|
325
|
+
print(
|
|
326
|
+
"alloca:",
|
|
327
|
+
alloca_name,
|
|
328
|
+
alloca_typ,
|
|
329
|
+
alloca_res,
|
|
330
|
+
alloca_res.get_reference(),
|
|
331
|
+
)
|
|
332
|
+
mul_res = lowerer.builder.mul(
|
|
333
|
+
lowerer.builder.load(xarg_alloca_vars[2][2]),
|
|
334
|
+
lowerer.builder.load(xarg_alloca_vars[3][2]),
|
|
335
|
+
)
|
|
336
|
+
lowerer.builder.store(mul_res, alloca_res)
|
|
337
|
+
rets.append(alloca_res)
|
|
338
|
+
else:
|
|
339
|
+
rets.append(self.arg_size(xarg[2], lowerer))
|
|
340
|
+
return rets, [x]
|
|
341
|
+
else:
|
|
342
|
+
return self.add_length_firstprivate(x, lowerer), None
|
|
343
|
+
elif isinstance(x, int):
|
|
344
|
+
return self.add_length_firstprivate(x, lowerer), None
|
|
345
|
+
else:
|
|
346
|
+
print("unknown arg type:", x, type(x))
|
|
347
|
+
|
|
348
|
+
return self.add_length_firstprivate(x, lowerer), None
|
|
349
|
+
|
|
350
|
+
def unpack_arrays(self, lowerer):
|
|
351
|
+
if isinstance(self.arg, list):
|
|
352
|
+
arg_list = self.arg
|
|
353
|
+
elif self.arg is not None:
|
|
354
|
+
arg_list = [self.arg]
|
|
355
|
+
else:
|
|
356
|
+
return [self]
|
|
357
|
+
new_xarginfo = []
|
|
358
|
+
unpack_res = [self.unpack_arg(arg, lowerer, new_xarginfo) for arg in arg_list]
|
|
359
|
+
new_args = [x[0] for x in unpack_res]
|
|
360
|
+
arrays_to_private = []
|
|
361
|
+
for x in unpack_res:
|
|
362
|
+
if x[1]:
|
|
363
|
+
arrays_to_private.append(x[1])
|
|
364
|
+
ot_res = openmp_tag(self.name, sum(new_args, []), self.load)
|
|
365
|
+
ot_res.xarginfo = new_xarginfo
|
|
366
|
+
return [ot_res] + (
|
|
367
|
+
[]
|
|
368
|
+
if len(arrays_to_private) == 0
|
|
369
|
+
else [openmp_tag("QUAL.OMP.PRIVATE", sum(arrays_to_private, []), self.load)]
|
|
370
|
+
)
|
|
371
|
+
|
|
372
|
+
def lower(self, lowerer, debug):
|
|
373
|
+
decl = ""
|
|
374
|
+
if debug and DEBUG_OPENMP >= 1:
|
|
375
|
+
print("openmp_tag::lower", self.name, self.arg, type(self.arg))
|
|
376
|
+
|
|
377
|
+
if isinstance(self.arg, list):
|
|
378
|
+
arg_list = self.arg
|
|
379
|
+
elif self.arg is not None:
|
|
380
|
+
arg_list = [self.arg]
|
|
381
|
+
else:
|
|
382
|
+
arg_list = []
|
|
383
|
+
typemap = lowerer.fndesc.typemap
|
|
384
|
+
assert len(arg_list) <= 1
|
|
385
|
+
|
|
386
|
+
if self.name == "QUAL.OMP.TARGET.IMPLICIT":
|
|
387
|
+
assert False # shouldn't get here anymore
|
|
388
|
+
|
|
389
|
+
name_to_use = self.name
|
|
390
|
+
|
|
391
|
+
is_array = self.arg in typemap and isinstance(
|
|
392
|
+
typemap[self.arg], types.npytypes.Array
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
gen_copy = name_to_use in ["QUAL.OMP.FIRSTPRIVATE", "QUAL.OMP.LASTPRIVATE"]
|
|
396
|
+
|
|
397
|
+
if (
|
|
398
|
+
name_to_use
|
|
399
|
+
in [
|
|
400
|
+
"QUAL.OMP.MAP.TOFROM",
|
|
401
|
+
"QUAL.OMP.MAP.TO",
|
|
402
|
+
"QUAL.OMP.MAP.FROM",
|
|
403
|
+
"QUAL.OMP.MAP.ALLOC",
|
|
404
|
+
]
|
|
405
|
+
and is_array
|
|
406
|
+
):
|
|
407
|
+
decl = ",".join(
|
|
408
|
+
[self.arg_to_str(x, lowerer, gen_copy=gen_copy) for x in arg_list]
|
|
409
|
+
)
|
|
410
|
+
else:
|
|
411
|
+
decl = ",".join(
|
|
412
|
+
[self.arg_to_str(x, lowerer, gen_copy=gen_copy) for x in arg_list]
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
return '"' + name_to_use + '"(' + decl + ")"
|
|
416
|
+
|
|
417
|
+
def replace_vars_inner(self, var_dict):
|
|
418
|
+
if isinstance(self.arg, ir.Var):
|
|
419
|
+
self.arg = replace_vars_inner(self.arg, var_dict)
|
|
420
|
+
|
|
421
|
+
def add_to_usedef_set(self, use_set, def_set, start):
|
|
422
|
+
assert start in (True, False)
|
|
423
|
+
if DEBUG_OPENMP >= 3:
|
|
424
|
+
print("add_to_usedef_set", start, self.name, "is_dsa=", is_dsa(self.name))
|
|
425
|
+
|
|
426
|
+
def add_arg(arg, the_set):
|
|
427
|
+
if isinstance(self.arg, ir.Var):
|
|
428
|
+
the_set.add(self.arg.name)
|
|
429
|
+
elif isinstance(self.arg, str):
|
|
430
|
+
the_set.add(self.arg)
|
|
431
|
+
elif isinstance(self.arg, NameSlice):
|
|
432
|
+
assert isinstance(self.arg.name, str), "Expected str in NameSlice arg"
|
|
433
|
+
the_set.add(self.arg.name)
|
|
434
|
+
# TODO: Create a good error check mechanism.
|
|
435
|
+
# else: ?
|
|
436
|
+
|
|
437
|
+
if self.name.startswith("DIR.OMP"):
|
|
438
|
+
assert not isinstance(self.arg, (ir.Var, str))
|
|
439
|
+
return
|
|
440
|
+
|
|
441
|
+
if self.name in [
|
|
442
|
+
"QUAL.OMP.MAP.TO",
|
|
443
|
+
"QUAL.OMP.IF",
|
|
444
|
+
"QUAL.OMP.NUM_THREADS",
|
|
445
|
+
"QUAL.OMP.NUM_TEAMS",
|
|
446
|
+
"QUAL.OMP.THREAD_LIMIT",
|
|
447
|
+
"QUAL.OMP.SCHEDULE.STATIC",
|
|
448
|
+
"QUAL.OMP.SCHEDULE.RUNTIME",
|
|
449
|
+
"QUAL.OMP.SCHEDULE.GUIDED",
|
|
450
|
+
"QUAL.OMP.SCHEDULE_DYNAMIC",
|
|
451
|
+
"QUAL.OMP.FIRSTPRIVATE",
|
|
452
|
+
"QUAL.OMP.COPYIN",
|
|
453
|
+
"QUAL.OMP.COPYPRIVATE",
|
|
454
|
+
"QUAL.OMP.NORMALIZED.LB",
|
|
455
|
+
"QUAL.OMP.NORMALIZED.START",
|
|
456
|
+
"QUAL.OMP.NORMALIZED.UB",
|
|
457
|
+
"QUAL.OMP.MAP.TO.STRUCT",
|
|
458
|
+
]:
|
|
459
|
+
if start:
|
|
460
|
+
add_arg(self.arg, use_set)
|
|
461
|
+
elif self.name in [
|
|
462
|
+
"QUAL.OMP.PRIVATE",
|
|
463
|
+
"QUAL.OMP.LINEAR",
|
|
464
|
+
"QUAL.OMP.NORMALIZED.IV",
|
|
465
|
+
"QUAL.OMP.MAP.ALLOC",
|
|
466
|
+
"QUAL.OMP.MAP.ALLOC.STRUCT",
|
|
467
|
+
]:
|
|
468
|
+
# Intentionally do nothing.
|
|
469
|
+
pass
|
|
470
|
+
elif self.name in ["QUAL.OMP.SHARED"]:
|
|
471
|
+
add_arg(self.arg, use_set)
|
|
472
|
+
elif self.name in [
|
|
473
|
+
"QUAL.OMP.MAP.TOFROM",
|
|
474
|
+
"QUAL.OMP.TARGET.IMPLICIT",
|
|
475
|
+
"QUAL.OMP.MAP.TOFROM.STRUCT",
|
|
476
|
+
]:
|
|
477
|
+
if start:
|
|
478
|
+
add_arg(self.arg, use_set)
|
|
479
|
+
else:
|
|
480
|
+
add_arg(self.arg, use_set)
|
|
481
|
+
add_arg(self.arg, def_set)
|
|
482
|
+
elif self.name in [
|
|
483
|
+
"QUAL.OMP.MAP.FROM",
|
|
484
|
+
"QUAL.OMP.LASTPRIVATE",
|
|
485
|
+
"QUAL.OMP.MAP.FROM.STRUCT",
|
|
486
|
+
] or self.name.startswith("QUAL.OMP.REDUCTION"):
|
|
487
|
+
if not start:
|
|
488
|
+
add_arg(self.arg, use_set)
|
|
489
|
+
add_arg(self.arg, def_set)
|
|
490
|
+
else:
|
|
491
|
+
# All other clauses should not have a variable argument.
|
|
492
|
+
if isinstance(self.arg, (ir.Var, str)):
|
|
493
|
+
print("Bad usedef tag:", self.name, self.arg)
|
|
494
|
+
assert not isinstance(self.arg, (ir.Var, str))
|
|
495
|
+
|
|
496
|
+
def __str__(self):
|
|
497
|
+
return (
|
|
498
|
+
"openmp_tag("
|
|
499
|
+
+ str(self.name)
|
|
500
|
+
+ ","
|
|
501
|
+
+ str(self.arg)
|
|
502
|
+
+ (
|
|
503
|
+
""
|
|
504
|
+
if self.omp_slice is None
|
|
505
|
+
else f", omp_slice({self.omp_slice[0]},{self.omp_slice[1]})"
|
|
506
|
+
)
|
|
507
|
+
+ ")"
|
|
508
|
+
)
|
|
509
|
+
|
|
510
|
+
def __repr__(self):
|
|
511
|
+
return self.__str__()
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
def openmp_tag_list_to_str(tag_list, lowerer, debug):
|
|
515
|
+
tag_strs = [x.lower(lowerer, debug) for x in tag_list]
|
|
516
|
+
return "[ " + ", ".join(tag_strs) + " ]"
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
def list_vars_from_tags(tags):
|
|
520
|
+
used_vars = []
|
|
521
|
+
for t in tags:
|
|
522
|
+
if isinstance(t.arg, ir.Var):
|
|
523
|
+
used_vars.append(t.arg)
|
|
524
|
+
return used_vars
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
def get_tags_of_type(clauses, ctype):
|
|
528
|
+
ret = []
|
|
529
|
+
for c in clauses:
|
|
530
|
+
if c.name == ctype:
|
|
531
|
+
ret.append(c)
|
|
532
|
+
return ret
|