Skip to content
This repository was archived by the owner on Apr 23, 2025. It is now read-only.

Commit 2dca098

Browse files
Update building and testing with llvm-openmp-dev (#34)
- Remove binaries from instalation - Update CI testing
1 parent 8c86b25 commit 2dca098

File tree

6 files changed

+75
-124
lines changed

6 files changed

+75
-124
lines changed

.github/workflows/pyomp-ci.yml

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
name: Test Numba PyOMP
22

33
on:
4-
push:
54
pull_request:
65
workflow_dispatch:
76

87
jobs:
98
build-and-test:
109
strategy:
1110
matrix:
12-
os: [ubuntu-latest]
13-
#os: [ubuntu-latest, macOS-latest]
14-
name: Build Numba PyOMP for platform ${{ matrix.os }}
11+
os: [ubuntu-latest, macOS-latest]
12+
name: Build and test Numba PyOMP ${{ matrix.os }}
1513
runs-on: ${{ matrix.os }}
1614
defaults:
1715
run:
@@ -27,18 +25,13 @@ jobs:
2725
- name: Build Numba PyOMP
2826
run: |
2927
conda create -c python-for-hpc -c conda-forge --override-channels -n test-numba-pyomp \
30-
llvmdev llvmlite numpy=1.24 lark-parser cffi python=3.10
28+
compilers llvmdev=14.0.6 numpy=1.24 lark-parser cffi python=3.10 \
29+
llvmlite=pyomp_0.40 \
30+
llvm-openmp-dev=14.0.6
3131
conda init
3232
conda activate test-numba-pyomp
3333
pushd ${GITHUB_WORKSPACE}
3434
MACOSX_DEPLOYMENT_TARGET=10.10 python setup.py build_static build_ext build install --single-version-externally-managed --record=record.txt
35-
mkdir -p ${GITHUB_WORKSPACE}/bin
36-
mkdir -p ${GITHUB_WORKSPACE}/lib
37-
cp ${CONDA_PREFIX}/bin/clang ${GITHUB_WORKSPACE}/bin
38-
cp ${CONDA_PREFIX}/bin/opt ${GITHUB_WORKSPACE}/bin
39-
cp ${CONDA_PREFIX}/bin/llc ${GITHUB_WORKSPACE}/bin
40-
cp ${CONDA_PREFIX}/bin/llvm-link ${GITHUB_WORKSPACE}/bin
41-
cp ${CONDA_PREFIX}/lib/lib*omp* ${GITHUB_WORKSPACE}/lib
4235
popd
4336
- name: Test Numba PyOMP Host
4437
env:
@@ -53,16 +46,17 @@ jobs:
5346
numba -s
5447
python -m numba.runtests -v -- numba.tests.test_openmp
5548
popd
56-
- name: Test Numba PyOMP Device target host device(1)
57-
env:
58-
TEST_DEVICES: 1
59-
RUN_TARGET: 1
60-
run: |
61-
# Must be in a different directory to run tests.
62-
pushd ${RUNNER_WORKSPACE}
63-
conda init
64-
conda activate test-numba-pyomp
65-
numba -h
66-
numba -s
67-
python -m numba.runtests -v -- numba.tests.test_openmp.TestOpenmpTarget
68-
popd
49+
# TODO: Re-enable when fixed.
50+
#- name: Test Numba PyOMP Device target host device(1)
51+
# env:
52+
# TEST_DEVICES: 1
53+
# RUN_TARGET: 1
54+
# run: |
55+
# # Must be in a different directory to run tests.
56+
# pushd ${RUNNER_WORKSPACE}
57+
# conda init
58+
# conda activate test-numba-pyomp
59+
# numba -h
60+
# numba -s
61+
# python -m numba.runtests -v -- numba.tests.test_openmp.TestOpenmpTarget
62+
# popd

MANIFEST.in

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ include README.rst setup.py runtests.py versioneer.py CHANGE_LOG LICENSE
44
recursive-include numba *.c *.cpp *.h *.hpp *.inc
55
recursive-include docs *.ipynb *.txt *.py Makefile *.rst
66
recursive-include examples *.py
7-
recursive-include numba/lib *.bc lib*omp*so
8-
recursive-include numba/bin opt llc llvm-link clang
97

108
prune docs/_build
119
prune docs/gh-pages

buildscripts/gitlab/ci-build-test.sh

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,11 @@ machine=${hostname//[0-9]/}
66

77
source /usr/workspace/ggeorgak/${machine}/miniconda3-env.sh
88
conda create -y -p ${CI_BUILDS_DIR}/test-numba-pyomp -c python-for-hpc -c conda-forge --override-channels \
9-
llvmdev llvmlite numpy=1.24 lark-parser cffi python=3.10
9+
llvmdev=14.0.6 numpy=1.24 lark-parser cffi python=3.10 \
10+
llvm-openmp-dev=14.0.6 \
11+
llvmlite=pyomp_0.40
1012
conda activate ${CI_BUILDS_DIR}/test-numba-pyomp
1113
pushd ${CI_PROJECT_DIR}
12-
mkdir -p ${CI_PROJECT_DIR}/numba/bin
13-
mkdir -p ${CI_PROJECT_DIR}/numba/lib
14-
cp ${CONDA_PREFIX}/bin/clang ${CI_PROJECT_DIR}/numba/bin
15-
cp ${CONDA_PREFIX}/bin/opt ${CI_PROJECT_DIR}/numba/bin
16-
cp ${CONDA_PREFIX}/bin/llc ${CI_PROJECT_DIR}/numba/bin
17-
cp ${CONDA_PREFIX}/bin/llvm-link ${CI_PROJECT_DIR}/numba/bin
18-
cp ${CONDA_PREFIX}/lib/lib*omp* ${CI_PROJECT_DIR}/numba/lib
1914
MACOSX_DEPLOYMENT_TARGET=10.10 python setup.py \
2015
build_static build_ext build install --single-version-externally-managed --record=record.txt || { echo "Build failed"; exit 1; }
2116
popd
@@ -25,17 +20,17 @@ echo "=> Test Numba PyOMP Host"
2520
TEST_DEVICES=0 RUN_TARGET=0 python -m numba.runtests -- numba.tests.test_openmp \
2621
|| { echo "Test Numba PyOMP Host failed"; exit 1; }
2722

28-
2923
if [[ "${machine}" == "lassen" ]]; then
3024
echo "=> Test Numba PyOMP Target GPU device(0)"
3125
TEST_DEVICES=0 RUN_TARGET=1 python -m numba.runtests -- numba.tests.test_openmp.TestOpenmpTarget \
3226
|| { echo "Test Numba PyOMP Target GPU failed"; exit 1; }
3327
fi
3428

35-
if [[ "${machine}" == "ruby" ]]; then
36-
echo "=> Test Numba PyOMP Target Host device(1)"
37-
TEST_DEVICES=1 RUN_TARGET=1 python -m numba.runtests -- numba.tests.test_openmp.TestOpenmpTarget \
38-
|| { echo "Test Numba PyOMP Target Host failed"; exit 1; }
39-
fi
29+
# TODO: Enable once we fix codegen in the backend.
30+
#if [[ "${machine}" == "ruby" ]]; then
31+
# echo "=> Test Numba PyOMP Target Host device(1)"
32+
# TEST_DEVICES=1 RUN_TARGET=1 python -m numba.runtests -- numba.tests.test_openmp.TestOpenmpTarget \
33+
# || { echo "Test Numba PyOMP Target Host failed"; exit 1; }
34+
#fi
4035

4136
popd

numba/openmp.py

Lines changed: 34 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -50,53 +50,36 @@
5050
import types as python_types
5151
import numba
5252

53+
llvm_binpath=None
54+
llvm_libpath=None
55+
def _init():
56+
global llvm_binpath
57+
global llvm_libpath
5358

54-
if config.DEBUG_OPENMP_LLVM_PASS >= 1:
55-
ll.set_option('openmp', '-debug')
56-
ll.set_option('openmp', '-debug-only=intrinsics-openmp')
57-
58-
library_missing = False
59-
60-
numba_openmp_path = os.path.dirname(os.path.realpath(__file__))
61-
numba_openmp_lib_path = numba_openmp_path + "/lib"
62-
numba_openmp_bin_path = numba_openmp_path + "/bin"
63-
64-
iomplib = os.getenv('NUMBA_OMP_LIB',None)
65-
if iomplib is None:
66-
lib_name = numba_openmp_lib_path + "/libomp.so"
67-
if os.path.isfile(lib_name):
68-
iomplib = lib_name
69-
if iomplib is None:
70-
iomplib = ctypes.util.find_library("libomp.so")
71-
if iomplib is None:
72-
iomplib = ctypes.util.find_library("libiomp5.so")
73-
if iomplib is None:
74-
iomplib = ctypes.util.find_library("omp")
75-
if iomplib is None:
76-
iomplib = ctypes.util.find_library("libomp")
77-
if iomplib is None:
78-
library_missing = True
79-
else:
59+
sys_platform = sys.platform
60+
61+
llvm_version = subprocess.check_output(['llvm-config', '--version']).decode().strip()
62+
if llvm_version != "14.0.6":
63+
raise RuntimeError(f"Incompatible LLVM version {llvm_version}, PyOMP expects LLVM 14.0.6")
64+
65+
llvm_binpath = subprocess.check_output(['llvm-config', '--bindir']).decode().strip()
66+
llvm_libpath = subprocess.check_output(['llvm-config', '--libdir']).decode().strip()
67+
iomplib = llvm_libpath + "/libomp" + (".dylib" if sys_platform == "darwin" else ".so")
8068
if config.DEBUG_OPENMP >= 1:
8169
print("Found OpenMP runtime library at", iomplib)
8270
ll.load_library_permanently(iomplib)
8371

84-
omptargetlib = os.getenv('NUMBA_OMPTARGET_LIB', None)
85-
if omptargetlib is None:
86-
lib_name = numba_openmp_lib_path + "/libomptarget.so"
87-
if os.path.isfile(lib_name):
88-
omptargetlib = lib_name
89-
if omptargetlib is None:
90-
omptargetlib = ctypes.util.find_library("libomptarget.so")
91-
if omptargetlib is None:
92-
omptargetlib = ctypes.util.find_library("omptarget")
93-
if omptargetlib is None:
94-
library_missing = True
95-
else:
72+
# libomptarget is unavailable on apple, windows, so return.
73+
if sys_platform.startswith("darwin") or sys_platform.startswith("win32"):
74+
return
75+
76+
omptargetlib = llvm_libpath + "/libomptarget.so"
9677
if config.DEBUG_OPENMP >= 1:
9778
print("Found OpenMP target runtime library at", omptargetlib)
9879
ll.load_library_permanently(omptargetlib)
9980

81+
_init()
82+
10083
#----------------------------------------------------------------------------------------------
10184

10285
class NameSlice:
@@ -2083,7 +2066,7 @@ def __init__(self):
20832066
self.libdevice_path = cudalibs.get_libdevice()
20842067
with open(self.libdevice_path, "rb") as f:
20852068
self.libs_mod = ll.parse_bitcode(f.read())
2086-
self.libomptarget_arch = numba_openmp_lib_path + \
2069+
self.libomptarget_arch = llvm_libpath + \
20872070
'/libomptarget-new-nvptx-' + self.sm + '.bc'
20882071
with open(self.libomptarget_arch, "rb") as f:
20892072
libomptarget_mod = ll.parse_bitcode(f.read())
@@ -2181,25 +2164,27 @@ def _get_target_image_toolchain(self, mod, filename_prefix):
21812164
with open(filename_prefix + '.ll', 'w') as f:
21822165
f.write(str(mod))
21832166

2184-
if config.DEBUG_OPENMP_LLVM_PASS >= 1:
2185-
cmd_list = [numba_openmp_bin_path + '/opt', '-S', '--intrinsics-openmp', '-debug-only=intrinsics-openmp',
2186-
filename_prefix + '.ll', '-o', filename_prefix + '-intrinsics_omp.ll']
2187-
else:
2188-
cmd_list = [numba_openmp_bin_path + '/opt', '-S', '--intrinsics-openmp',
2189-
filename_prefix + '.ll', '-o', filename_prefix + '-intrinsics_omp.ll']
2190-
subprocess.run(cmd_list, check=True)
2167+
# Lower openmp intrinsics.
2168+
with ll.create_module_pass_manager() as pm:
2169+
pm.add_intrinsics_openmp_pass()
2170+
pm.add_cfg_simplification_pass()
2171+
pm.run(mod)
2172+
2173+
with open(filename_prefix + '-intrinsics_omp.ll', 'w') as f:
2174+
f.write(str(mod))
2175+
21912176
if config.DEBUG_OPENMP >= 1:
21922177
print('libomptarget_arch', self.libomptarget_arch)
2193-
subprocess.run([numba_openmp_bin_path + '/llvm-link',
2178+
subprocess.run([llvm_binpath + '/llvm-link',
21942179
'--suppress-warnings',
21952180
'--internalize', '-S', filename_prefix +
21962181
'-intrinsics_omp.ll', self.libomptarget_arch, self.libdevice_path,
21972182
'-o', filename_prefix + '-intrinsics_omp-linked.ll'],
21982183
check=True)
2199-
subprocess.run([numba_openmp_bin_path + '/opt', '-S', '-O3', filename_prefix + '-intrinsics_omp-linked.ll',
2184+
subprocess.run([llvm_binpath + '/opt', '-S', '-O3', filename_prefix + '-intrinsics_omp-linked.ll',
22002185
'-o', filename_prefix + '-intrinsics_omp-linked-opt.ll'], check=True)
22012186

2202-
subprocess.run([numba_openmp_bin_path + '/llc', '-O3', '-march=nvptx64', f'-mcpu={self.sm}', f'-mattr=+ptx64,+{self.sm}',
2187+
subprocess.run([llvm_binpath + '/llc', '-O3', '-march=nvptx64', f'-mcpu={self.sm}', f'-mattr=+ptx64,+{self.sm}',
22032188
filename_prefix + '-intrinsics_omp-linked-opt.ll',
22042189
'-o', filename_prefix + '-intrinsics_omp-linked-opt.s'], check=True)
22052190

@@ -6216,26 +6201,6 @@ def _add_openmp_ir_nodes(func_ir, blocks, blk_start, blk_end, body_blocks, extra
62166201
openmp ir nodes in it and adds the ending openmp ir nodes to
62176202
the end block.
62186203
"""
6219-
# First check for presence of required libraries.
6220-
if library_missing:
6221-
if iomplib is None:
6222-
print("OpenMP runtime library could not be found.")
6223-
print("Make sure that libomp.so or libiomp5.so is in your library path or")
6224-
print("specify the location of the OpenMP runtime library with the")
6225-
print("NUMBA_OMP_LIB environment variables.")
6226-
sys.exit(-1)
6227-
6228-
if omptargetlib is None:
6229-
if sys.platform.startswith("darwin"):
6230-
# OpenMP GPU offloading is unavailable on Darwin
6231-
pass
6232-
else:
6233-
print("OpenMP target runtime library could not be found.")
6234-
print("Make sure that libomptarget.so or")
6235-
print("specify the location of the OpenMP runtime library with the")
6236-
print("NUMBA_OMPTARGET_LIB environment variables.")
6237-
sys.exit(-1)
6238-
62396204
sblk = blocks[blk_start]
62406205
scope = sblk.scope
62416206
loc = sblk.loc

numba/tests/test_openmp.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
# process starts which enables the tests within the process. The decorator
6060
# @needs_subprocess is used to ensure the appropriate test skips are made.
6161

62-
#@linux_only
62+
#
6363
#class TestOpenmpRunner(TestCase):
6464
# _numba_parallel_test_ = False
6565
#
@@ -323,7 +323,7 @@ def __init__(self, typingctx, targetctx, args, test_ir):
323323
self.state.metadata = {}
324324

325325

326-
#@linux_only
326+
#
327327
#class TestOpenmpBasic(TestOpenmpBase):
328328
# """OpenMP smoke tests. These tests check the most basic
329329
# functionality"""
@@ -332,7 +332,7 @@ def __init__(self, typingctx, targetctx, args, test_ir):
332332
# TestOpenmpBase.__init__(self, *args)
333333

334334

335-
@linux_only
335+
336336
class TestOpenmpRoutinesEnvVariables(TestOpenmpBase):
337337
MAX_THREADS = 5
338338

@@ -551,7 +551,7 @@ def test_impl(N, c):
551551
np.testing.assert_array_equal(r[0], r[1])
552552

553553

554-
@linux_only
554+
555555
class TestOpenmpParallelForResults(TestOpenmpBase):
556556

557557
def __init__(self, *args):
@@ -702,7 +702,7 @@ def test_impl(n1, n2, n3):
702702
np.testing.assert_equal(ja[a1i][a2i], ka[a1i][a2i])
703703

704704

705-
@linux_only
705+
706706
class TestOpenmpWorksharingSchedule(TestOpenmpBase):
707707

708708
def __init__(self, *args):
@@ -861,7 +861,7 @@ def test_impl(nt, c, cs):
861861
assert(ca[-2] >= cs)
862862

863863

864-
@linux_only
864+
865865
class TestOpenmpParallelClauses(TestOpenmpBase):
866866

867867
def __init__(self, *args):
@@ -997,7 +997,7 @@ def test_impl():
997997
self.check(test_impl)
998998

999999

1000-
@linux_only
1000+
10011001
class TestOpenmpDataClauses(TestOpenmpBase):
10021002

10031003
def __init__(self, *args):
@@ -1446,7 +1446,7 @@ def test_impl(N):
14461446
assert(r[1] == N//2-1)
14471447

14481448

1449-
@linux_only
1449+
14501450
class TestOpenmpConstraints(TestOpenmpBase):
14511451
"""Tests designed to confirm that errors occur when expected, or
14521452
to see how OpenMP behaves in various circumstances"""
@@ -1655,7 +1655,7 @@ def test_impl():
16551655
test_impl()
16561656

16571657

1658-
@linux_only
1658+
16591659
class TestOpenmpConcurrency(TestOpenmpBase):
16601660

16611661
def __init__(self, *args):
@@ -2082,7 +2082,7 @@ def test_impl(N):
20822082
for i in range(N):
20832083
np.testing.assert_array_equal(r[i], np.array([1, 2]))
20842084

2085-
@linux_only
2085+
20862086
class TestOpenmpTask(TestOpenmpBase):
20872087

20882088
def __init__(self, *args):
@@ -2507,7 +2507,7 @@ def test_impl(mode):
25072507
self.check(test_impl, 2)
25082508

25092509

2510-
@linux_only
2510+
25112511
@unittest.skipUnless(TestOpenmpBase.skip_disabled, "Unimplemented")
25122512
class TestOpenmpTaskloop(TestOpenmpBase):
25132513

@@ -2596,6 +2596,7 @@ def test_impl(ntsks, nt):
25962596
np.testing.assert_array_equal(r[1], r[2])
25972597

25982598

2599+
25992600
@linux_only
26002601
@unittest.skipUnless(TestOpenmpBase.skip_disabled or
26012602
TestOpenmpBase.run_target, "Unimplemented")
@@ -3893,7 +3894,7 @@ def func_with_subtest(self):
38933894
return func_with_subtest
38943895
setattr(TestOpenmpTarget, "test_" + test_func.__name__, make_func_with_subtest(test_func))
38953896

3896-
@linux_only
3897+
38973898
class TestOpenmpPi(TestOpenmpBase):
38983899

38993900
def __init__(self, *args):

setup.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,8 +442,6 @@ def check_file_at_path(path2file):
442442
"numba.misc": ["cmdlang.gdb"],
443443
"numba.typed": ["py.typed"],
444444
"numba.cuda" : ["cpp_function_wrappers.cu"],
445-
"numba.lib" : ["numba/lib/*.bc", "numba/lib/lib*omp*so"],
446-
"numba.bin" : ["numba/bin/opt", "numba/bin/llc", "numba/bin/llvm-link", "numba/bin/clang"]
447445
},
448446
scripts=["bin/numba"],
449447
url="https://numba.pydata.org",

0 commit comments

Comments
 (0)