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.
Files changed (52) hide show
  1. numba/openmp/__init__.py +106 -0
  2. numba/openmp/_version.py +34 -0
  3. numba/openmp/analysis.py +251 -0
  4. numba/openmp/compiler.py +402 -0
  5. numba/openmp/config.py +27 -0
  6. numba/openmp/decorators.py +27 -0
  7. numba/openmp/exceptions.py +26 -0
  8. numba/openmp/ir_utils.py +4 -0
  9. numba/openmp/libs/openmp/lib/libgomp.1.dylib +0 -0
  10. numba/openmp/libs/openmp/lib/libgomp.dylib +0 -0
  11. numba/openmp/libs/openmp/lib/libiomp5.dylib +0 -0
  12. numba/openmp/libs/openmp/lib/libomp.dylib +0 -0
  13. numba/openmp/libs/openmp/patches/14.0.6/0001-BACKPORT-Fix-for-CUDA-OpenMP-RTL.patch +39 -0
  14. numba/openmp/libs/openmp/patches/14.0.6/0002-Fix-missing-includes.patch +12 -0
  15. numba/openmp/libs/openmp/patches/14.0.6/0003-Link-static-LLVM-libs.patch +13 -0
  16. numba/openmp/libs/openmp/patches/15.0.7/0001-Fix-missing-includes.patch +14 -0
  17. numba/openmp/libs/openmp/patches/15.0.7/0002-Link-LLVM-statically.patch +101 -0
  18. numba/openmp/libs/openmp/patches/15.0.7/0003-Disable-opaque-pointers-DeviceRTL-bitcode.patch +12 -0
  19. numba/openmp/libs/openmp/patches/16.0.6/0001-Load-plugins-from-install-directory.patch +53 -0
  20. numba/openmp/libs/openmp/patches/16.0.6/0002-Link-LLVM-statically.patch +218 -0
  21. numba/openmp/libs/openmp/patches/20.1.8/0001-Enable-standalone-build.patch +13 -0
  22. numba/openmp/libs/openmp/patches/20.1.8/0002-Link-statically-LLVM.patch +24 -0
  23. numba/openmp/libs/openmp/patches/20.1.8/0003-Do-not-build-liboffload.patch +12 -0
  24. numba/openmp/libs/pass/CGIntrinsicsOpenMP.cpp +2939 -0
  25. numba/openmp/libs/pass/CGIntrinsicsOpenMP.h +606 -0
  26. numba/openmp/libs/pass/CMakeLists.txt +57 -0
  27. numba/openmp/libs/pass/DebugOpenMP.cpp +17 -0
  28. numba/openmp/libs/pass/DebugOpenMP.h +28 -0
  29. numba/openmp/libs/pass/IntrinsicsOpenMP.cpp +837 -0
  30. numba/openmp/libs/pass/IntrinsicsOpenMP.h +13 -0
  31. numba/openmp/libs/pass/IntrinsicsOpenMP_CAPI.h +23 -0
  32. numba/openmp/libs/pass/libIntrinsicsOpenMP.dylib +0 -0
  33. numba/openmp/link_utils.py +126 -0
  34. numba/openmp/llvm_pass.py +48 -0
  35. numba/openmp/llvmlite_extensions.py +75 -0
  36. numba/openmp/omp_context.py +242 -0
  37. numba/openmp/omp_grammar.py +696 -0
  38. numba/openmp/omp_ir.py +2105 -0
  39. numba/openmp/omp_lower.py +3125 -0
  40. numba/openmp/omp_runtime.py +107 -0
  41. numba/openmp/overloads.py +53 -0
  42. numba/openmp/parser.py +6 -0
  43. numba/openmp/tags.py +532 -0
  44. numba/openmp/tests/test_openmp.py +5056 -0
  45. pyomp-0.5.0.dist-info/METADATA +193 -0
  46. pyomp-0.5.0.dist-info/RECORD +52 -0
  47. pyomp-0.5.0.dist-info/WHEEL +6 -0
  48. pyomp-0.5.0.dist-info/licenses/LICENSE +25 -0
  49. pyomp-0.5.0.dist-info/licenses/LICENSE-OPENMP.txt +361 -0
  50. pyomp-0.5.0.dist-info/top_level.txt +3 -0
  51. pyomp.dylibs/libc++.1.0.dylib +0 -0
  52. 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
@@ -0,0 +1,6 @@
1
+ from lark import Lark
2
+
3
+ from .omp_grammar import openmp_grammar
4
+
5
+ openmp_parser = Lark(openmp_grammar, start="openmp_statement")
6
+ var_collector_parser = Lark(openmp_grammar, start="openmp_statement")
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