Skip to content

Commit 7e92cd5

Browse files
committed
extend test_toy_cuda_sanity_check to also check whether shared libraries under lib/python*/site-packages are being checked in CUDA sanity check
1 parent ceacffa commit 7e92cd5

File tree

1 file changed

+69
-50
lines changed

1 file changed

+69
-50
lines changed

test/framework/toy_build.py

Lines changed: 69 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3121,9 +3121,22 @@ def test_toy_cuda_sanity_check(self):
31213121
topdir = os.path.dirname(os.path.abspath(__file__))
31223122
toy_ec = os.path.join(topdir, 'easyconfigs', 'test_ecs', 't', 'toy', 'toy-0.0.eb')
31233123

3124+
toy_bin = '%(installdir)s/bin/toy'
3125+
py_site_pkgs = '%(installdir)s/lib/python3.9/site-packages'
3126+
shlib_ext = get_shared_lib_ext()
3127+
31243128
toy_ec_cuda = os.path.join(self.test_prefix, 'toy-0.0-cuda.eb')
3125-
write_file(toy_ec_cuda, read_file(toy_ec) + "\ndependencies = [('CUDA', '5.5.22', '', SYSTEM)]")
3126-
toy_ec = toy_ec_cuda
3129+
toy_ec_txt = read_file(toy_ec)
3130+
toy_ec_txt += '\n' + '\n'.join([
3131+
"dependencies = [('CUDA', '5.5.22', '', SYSTEM)]",
3132+
"postinstallcmds += [",
3133+
" 'mkdir -p %(installdir)s/lib/python3.9/site-packages/plugins',",
3134+
# copy 'toy' binary, must be something that passes 'file' check in get_cuda_object_dump_raw
3135+
" 'cp %s %s/pytoy-cuda.cpython-39-x86_64-linux-gnu.%s'," % (toy_bin, py_site_pkgs, shlib_ext),
3136+
" 'cp %s %s/plugins/libpytoy_cuda.%s'," % (toy_bin, py_site_pkgs, shlib_ext),
3137+
"]",
3138+
])
3139+
write_file(toy_ec_cuda, toy_ec_txt)
31273140

31283141
# Create mock cuobjdump
31293142
# First, lets define sections of echo's for cuobjdump for various scenarios
@@ -3243,10 +3256,10 @@ def test_toy_cuda_sanity_check(self):
32433256
# If either of these fail their assert, print an informative, standardized message
32443257
def assert_regex(pattern, log, stdout=None):
32453258
regex = re.compile(pattern, re.M)
3246-
msg = "Pattern %s not found in full build log: %s" % (pattern, log)
3259+
msg = "Pattern '%s' not found in full build log: %s" % (pattern, log)
32473260
self.assertTrue(regex.search(log), msg)
32483261
if stdout is not None:
3249-
msg2 = "Pattern %s not found in standard output: %s" % (pattern, stdout)
3262+
msg2 = "Pattern '%s' not found in standard output: %s" % (pattern, stdout)
32503263
self.assertTrue(regex.search(stdout), msg2)
32513264

32523265
def assert_cuda_report(missing_cc, additional_cc, missing_ptx, log, stdout=None, missing_cc_but_ptx=None,
@@ -3278,9 +3291,9 @@ def assert_cuda_report(missing_cc, additional_cc, missing_ptx, log, stdout=None,
32783291
args = ['--cuda-compute-capabilities=8.0']
32793292
# We expect this to pass, so no need to check errors
32803293
with self.mocked_stdout_stderr():
3281-
outtxt = self._test_toy_build(ec_file=toy_ec, extra_args=args, raise_error=True)
3294+
outtxt = self._test_toy_build(ec_file=toy_ec_cuda, extra_args=args, raise_error=True)
32823295
stdout = self.get_stdout()
3283-
assert_cuda_report(missing_cc=0, additional_cc=0, missing_ptx=1, log=outtxt, stdout=stdout)
3296+
assert_cuda_report(missing_cc=0, additional_cc=0, missing_ptx=3, log=outtxt, stdout=stdout)
32843297

32853298
# Test case 1b: test with default options, --cuda-compute-capabilities=8.0 and a binary that contains
32863299
# 7.0 and 9.0 device code and 8.0 PTX code.
@@ -3297,29 +3310,29 @@ def assert_cuda_report(missing_cc, additional_cc, missing_ptx, log, stdout=None,
32973310
args = ['--cuda-compute-capabilities=8.0']
32983311
# We expect this to pass, so no need to check errors
32993312
with self.mocked_stdout_stderr():
3300-
outtxt = self._test_toy_build(ec_file=toy_ec, extra_args=args, raise_error=True)
3313+
outtxt = self._test_toy_build(ec_file=toy_ec_cuda, extra_args=args, raise_error=True)
33013314
stdout = self.get_stdout()
3302-
msg = "Pattern %s not found in full build log: %s" % (device_additional_70_90_code_regex.pattern, outtxt)
3315+
msg = "Pattern '%s' not found in full build log: %s" % (device_additional_70_90_code_regex.pattern, outtxt)
33033316
self.assertTrue(device_additional_70_90_code_regex.search(outtxt), msg)
3304-
msg = "Pattern %s not found in full build log: %s" % (device_missing_80_code_regex.pattern, outtxt)
3317+
msg = "Pattern '%s' not found in full build log: %s" % (device_missing_80_code_regex.pattern, outtxt)
33053318
self.assertTrue(device_missing_80_code_regex.search(outtxt), msg)
3306-
assert_cuda_report(missing_cc=1, additional_cc=1, missing_ptx=0, log=outtxt, stdout=stdout)
3319+
assert_cuda_report(missing_cc=3, additional_cc=3, missing_ptx=0, log=outtxt, stdout=stdout)
33073320

33083321
# Test case 2: same as Test case 1, but add --cuda-sanity-check-error-on-failed-checks
33093322
# This is expected to fail since there is missing device code for CC80
33103323
args = ['--cuda-compute-capabilities=8.0', '--cuda-sanity-check-error-on-failed-checks']
33113324
# We expect this to fail, so first check error, then run again to check output
3312-
error_pattern = r"Files missing CUDA device code: 1."
3325+
error_pattern = r"Files missing CUDA device code: 3."
33133326
with self.mocked_stdout_stderr():
3314-
self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec,
3327+
self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec_cuda,
33153328
extra_args=args, raise_error=True)
3316-
outtxt = self._test_toy_build(ec_file=toy_ec, extra_args=args, raise_error=False, verify=False)
3329+
outtxt = self._test_toy_build(ec_file=toy_ec_cuda, extra_args=args, raise_error=False, verify=False)
33173330
stdout = self.get_stdout()
3318-
msg = "Pattern %s not found in full build log: %s" % (device_additional_70_90_code_regex.pattern, outtxt)
3331+
msg = "Pattern '%s' not found in full build log: %s" % (device_additional_70_90_code_regex.pattern, outtxt)
33193332
self.assertTrue(device_additional_70_90_code_regex.search(outtxt), msg)
3320-
msg = "Pattern %s not found in full build log: %s" % (device_missing_80_code_regex.pattern, outtxt)
3333+
msg = "Pattern '%s' not found in full build log: %s" % (device_missing_80_code_regex.pattern, outtxt)
33213334
self.assertTrue(device_missing_80_code_regex.search(outtxt), msg)
3322-
assert_cuda_report(missing_cc=1, additional_cc=1, missing_ptx=0, log=outtxt, stdout=stdout)
3335+
assert_cuda_report(missing_cc=3, additional_cc=3, missing_ptx=0, log=outtxt, stdout=stdout)
33233336

33243337
# Test case 3: same as Test case 2, but add --cuda-sanity-check-accept-ptx-as-devcode
33253338
# This is expected to succeed, since now the PTX code for CC80 will be accepted as
@@ -3329,28 +3342,28 @@ def assert_cuda_report(missing_cc, additional_cc, missing_ptx, log, stdout=None,
33293342
'--cuda-sanity-check-accept-ptx-as-devcode']
33303343
# We expect this to pass, so no need to check errors
33313344
with self.mocked_stdout_stderr():
3332-
outtxt = self._test_toy_build(ec_file=toy_ec, extra_args=args, raise_error=True)
3345+
outtxt = self._test_toy_build(ec_file=toy_ec_cuda, extra_args=args, raise_error=True)
33333346
stdout = self.get_stdout()
3334-
msg = "Pattern %s not found in full build log: %s" % (device_additional_70_90_code_regex.pattern, outtxt)
3347+
msg = "Pattern '%s' not found in full build log: %s" % (device_additional_70_90_code_regex.pattern, outtxt)
33353348
self.assertTrue(device_additional_70_90_code_regex.search(outtxt), msg)
3336-
msg = "Pattern %s not found in full build log: %s" % (device_missing_80_code_regex.pattern, outtxt)
3349+
msg = "Pattern '%s' not found in full build log: %s" % (device_missing_80_code_regex.pattern, outtxt)
33373350
self.assertTrue(device_missing_80_code_regex.search(outtxt), msg)
3338-
assert_cuda_report(missing_cc=0, additional_cc=1, missing_ptx=0, log=outtxt, stdout=stdout,
3339-
missing_cc_but_ptx=1)
3351+
assert_cuda_report(missing_cc=0, additional_cc=3, missing_ptx=0, log=outtxt, stdout=stdout,
3352+
missing_cc_but_ptx=3)
33403353

33413354
# Test case 4: same as Test case 2, but run with --cuda-compute-capabilities=9.0
33423355
# This is expected to fail: device code is present, but PTX code for the highest CC (9.0) is missing
33433356
args = ['--cuda-compute-capabilities=9.0', '--cuda-sanity-check-error-on-failed-checks']
33443357
# We expect this to fail, so first check error, then run again to check output
3345-
error_pattern = r"Files missing CUDA PTX code: 1"
3358+
error_pattern = r"Files missing CUDA PTX code: 3"
33463359
with self.mocked_stdout_stderr():
3347-
self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec,
3360+
self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec_cuda,
33483361
extra_args=args, raise_error=True)
3349-
outtxt = self._test_toy_build(ec_file=toy_ec, extra_args=args, raise_error=False, verify=False)
3362+
outtxt = self._test_toy_build(ec_file=toy_ec_cuda, extra_args=args, raise_error=False, verify=False)
33503363
stdout = self.get_stdout()
3351-
msg = "Pattern %s not found in full build log: %s" % (device_additional_70_code_regex.pattern, outtxt)
3364+
msg = "Pattern '%s' not found in full build log: %s" % (device_additional_70_code_regex.pattern, outtxt)
33523365
self.assertTrue(device_additional_70_code_regex.search(outtxt), msg)
3353-
assert_cuda_report(missing_cc=0, additional_cc=1, missing_ptx=1, log=outtxt, stdout=stdout)
3366+
assert_cuda_report(missing_cc=0, additional_cc=3, missing_ptx=3, log=outtxt, stdout=stdout)
33543367

33553368
# Test case 5: same as Test case 4, but add --cuda-sanity-check-accept-missing-ptx
33563369
# This is expected to succeed: device code is present, PTX code is missing, but that's accepted
@@ -3362,43 +3375,49 @@ def assert_cuda_report(missing_cc, additional_cc, missing_ptx, log, stdout=None,
33623375
warning_pattern += r"\(PTX architectures supported in that file: \['8\.0'\]\)"
33633376
warning_pattern_regex = re.compile(warning_pattern, re.M)
33643377
with self.mocked_stdout_stderr():
3365-
outtxt = self._test_toy_build(ec_file=toy_ec, extra_args=args, raise_error=True)
3378+
outtxt = self._test_toy_build(ec_file=toy_ec_cuda, extra_args=args, raise_error=True)
33663379
stdout = self.get_stdout()
3367-
msg = "Pattern %s not found in full build log: %s" % (device_additional_70_code_regex.pattern, outtxt)
3380+
msg = "Pattern '%s' not found in full build log: %s" % (device_additional_70_code_regex.pattern, outtxt)
33683381
self.assertTrue(device_additional_70_code_regex.search(outtxt), msg)
3369-
msg = "Pattern %s not found in full build log: %s" % (warning_pattern, outtxt)
3382+
msg = "Pattern '%s' not found in full build log: %s" % (warning_pattern, outtxt)
33703383
self.assertTrue(warning_pattern_regex.search(outtxt), msg)
3371-
assert_cuda_report(missing_cc=0, additional_cc=1, missing_ptx=1, log=outtxt, stdout=stdout)
3384+
assert_cuda_report(missing_cc=0, additional_cc=3, missing_ptx=3, log=outtxt, stdout=stdout)
33723385

33733386
# Test case 6: same as Test case 5, but add --cuda-sanity-check-strict
33743387
# This is expected to fail: device code is present, PTX code is missing (but accepted due to option)
33753388
# but additional device code is present, which is not allowed by --cuda-sanity-check-strict
33763389
args = ['--cuda-compute-capabilities=9.0', '--cuda-sanity-check-error-on-failed-checks',
33773390
'--cuda-sanity-check-accept-missing-ptx', '--cuda-sanity-check-strict']
33783391
# We expect this to fail, so first check error, then run again to check output
3379-
error_pattern = r"Files with additional CUDA device code: 1"
3392+
error_pattern = r"Files with additional CUDA device code: 3"
33803393
with self.mocked_stdout_stderr():
3381-
self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec,
3394+
self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec_cuda,
33823395
extra_args=args, raise_error=True)
3383-
outtxt = self._test_toy_build(ec_file=toy_ec, extra_args=args, raise_error=False, verify=False)
3396+
outtxt = self._test_toy_build(ec_file=toy_ec_cuda, extra_args=args, raise_error=False, verify=False)
33843397
stdout = self.get_stdout()
3385-
msg = "Pattern %s not found in full build log: %s" % (device_additional_70_code_regex.pattern, outtxt)
3398+
msg = "Pattern '%s' not found in full build log: %s" % (device_additional_70_code_regex.pattern, outtxt)
33863399
self.assertTrue(device_additional_70_code_regex.search(outtxt), msg)
3387-
assert_cuda_report(missing_cc=0, additional_cc=1, missing_ptx=1, log=outtxt, stdout=stdout)
3400+
assert_cuda_report(missing_cc=0, additional_cc=3, missing_ptx=3, log=outtxt, stdout=stdout)
33883401

33893402
# Test case 7: same as Test case 6, but add the failing file to the cuda_sanity_ignore_files
33903403
# This is expected to succeed: the individual file which _would_ cause the sanity check to fail is
33913404
# now on the ignore list
33923405
toy_whitelist_ec = os.path.join(self.test_prefix, 'toy-0.0-cuda-whitelist.eb')
3393-
write_file(toy_whitelist_ec, read_file(toy_ec) + '\ncuda_sanity_ignore_files = ["bin/toy"]')
3406+
toy_ec_txt = read_file(toy_ec)
3407+
toy_ec_txt += '\n' + '\n'.join([
3408+
"dependencies = [('CUDA', '5.5.22', '', SYSTEM)]",
3409+
"cuda_sanity_ignore_files = ['bin/toy']",
3410+
])
3411+
write_file(toy_ec_cuda, toy_ec_txt)
3412+
write_file(toy_whitelist_ec, toy_ec_txt)
33943413

33953414
args = ['--cuda-compute-capabilities=9.0', '--cuda-sanity-check-error-on-failed-checks',
33963415
'--cuda-sanity-check-accept-missing-ptx', '--cuda-sanity-check-strict']
33973416
# We expect this to succeed, so check output for expected patterns
33983417
with self.mocked_stdout_stderr():
33993418
outtxt = self._test_toy_build(ec_file=toy_whitelist_ec, extra_args=args, raise_error=True, verify=False)
34003419
stdout = self.get_stdout()
3401-
msg = "Pattern %s not found in full build log: %s" % (device_additional_70_code_regex.pattern, outtxt)
3420+
msg = "Pattern '%s' not found in full build log: %s" % (device_additional_70_code_regex.pattern, outtxt)
34023421
self.assertTrue(device_additional_70_code_regex.search(outtxt), msg)
34033422
assert_cuda_report(missing_cc=0, additional_cc=1, missing_ptx=1, log=outtxt, stdout=stdout)
34043423

@@ -3417,15 +3436,15 @@ def assert_cuda_report(missing_cc, additional_cc, missing_ptx, log, stdout=None,
34173436
'--cuda-sanity-check-strict']
34183437
# We expect this to pass, so no need to check errors
34193438
with self.mocked_stdout_stderr():
3420-
outtxt = self._test_toy_build(ec_file=toy_ec, extra_args=args, raise_error=True)
3439+
outtxt = self._test_toy_build(ec_file=toy_ec_cuda, extra_args=args, raise_error=True)
34213440
stdout = self.get_stdout()
3422-
msg = "Pattern %s not found in full build log: %s" % (device_code_regex_success.pattern, outtxt)
3441+
msg = "Pattern '%s' not found in full build log: %s" % (device_code_regex_success.pattern, outtxt)
34233442
self.assertTrue(device_code_regex_success.search(outtxt), msg)
3424-
msg = "Pattern %s not found in full build log: %s" % (ptx_code_regex_success.pattern, outtxt)
3443+
msg = "Pattern '%s' not found in full build log: %s" % (ptx_code_regex_success.pattern, outtxt)
34253444
self.assertTrue(ptx_code_regex_success.search(outtxt), msg)
34263445
expected_result_pattern = "INFO Sanity check for toy successful"
34273446
expected_result = re.compile(expected_result_pattern, re.M)
3428-
msg = "Pattern %s not found in full build log: %s" % (expected_result, outtxt)
3447+
msg = "Pattern '%s' not found in full build log: %s" % (expected_result, outtxt)
34293448
self.assertTrue(expected_result.search(outtxt), msg)
34303449
assert_cuda_report(missing_cc=0, additional_cc=0, missing_ptx=0, log=outtxt, stdout=stdout)
34313450

@@ -3434,15 +3453,15 @@ def assert_cuda_report(missing_cc, additional_cc, missing_ptx, log, stdout=None,
34343453
args = ['--cuda-sanity-check-error-on-failed-checks', '--cuda-sanity-check-strict']
34353454
# We expect this to pass, so no need to check errors
34363455
with self.mocked_stdout_stderr():
3437-
outtxt = self._test_toy_build(ec_file=toy_ec, extra_args=args, raise_error=True)
3456+
outtxt = self._test_toy_build(ec_file=toy_ec_cuda, extra_args=args, raise_error=True)
34383457
stdout = self.get_stdout()
34393458
cuda_sanity_skipped = r"INFO Skipping CUDA sanity check, as no CUDA compute capabilities were configured"
34403459
cuda_sanity_skipped_regex = re.compile(cuda_sanity_skipped, re.M)
3441-
msg = "Pattern %s not found in full build log: %s" % (cuda_sanity_skipped, outtxt)
3460+
msg = "Pattern '%s' not found in full build log: %s" % (cuda_sanity_skipped, outtxt)
34423461
self.assertTrue(cuda_sanity_skipped_regex.search(outtxt), msg)
34433462
expected_result_pattern = "INFO Sanity check for toy successful"
34443463
expected_result = re.compile(expected_result_pattern, re.M)
3445-
msg = "Pattern %s not found in full build log: %s" % (expected_result, outtxt)
3464+
msg = "Pattern '%s' not found in full build log: %s" % (expected_result, outtxt)
34463465
self.assertTrue(expected_result.search(outtxt), msg)
34473466

34483467
# Test case 10: running with default options and a binary that does not contain ANY CUDA device code
@@ -3453,16 +3472,16 @@ def assert_cuda_report(missing_cc, additional_cc, missing_ptx, log, stdout=None,
34533472
args = ['--cuda-compute-capabilities=9.0']
34543473
# We expect this to pass, so no need to check errors
34553474
with self.mocked_stdout_stderr():
3456-
outtxt = self._test_toy_build(ec_file=toy_ec, extra_args=args, raise_error=True)
3475+
outtxt = self._test_toy_build(ec_file=toy_ec_cuda, extra_args=args, raise_error=True)
34573476
stdout = self.get_stdout()
34583477
no_cuda_pattern = r".*/bin/toy does not appear to be a CUDA executable \(no CUDA device code found\), "
34593478
no_cuda_pattern += r"so skipping CUDA sanity check"
34603479
no_cuda_regex = re.compile(no_cuda_pattern, re.M)
3461-
msg = "Pattern %s not found in full build log: %s" % (no_cuda_pattern, outtxt)
3480+
msg = "Pattern '%s' not found in full build log: %s" % (no_cuda_pattern, outtxt)
34623481
self.assertTrue(no_cuda_regex.search(outtxt), msg)
34633482
expected_result_pattern = "INFO Sanity check for toy successful"
34643483
expected_result = re.compile(expected_result_pattern, re.M)
3465-
msg = "Pattern %s not found in full build log: %s" % (expected_result, outtxt)
3484+
msg = "Pattern '%s' not found in full build log: %s" % (expected_result, outtxt)
34663485
self.assertTrue(expected_result.search(outtxt), msg)
34673486
assert_cuda_report(missing_cc=0, additional_cc=0, missing_ptx=0, log=outtxt, stdout=stdout, num_checked=0)
34683487

@@ -3471,16 +3490,16 @@ def assert_cuda_report(missing_cc, additional_cc, missing_ptx, log, stdout=None,
34713490
args = ['--cuda-compute-capabilities=9.0', '--cuda-sanity-check-error-on-failed-checks']
34723491
# We expect this to pass, so no need to check errors
34733492
with self.mocked_stdout_stderr():
3474-
outtxt = self._test_toy_build(ec_file=toy_ec, extra_args=args, raise_error=True)
3493+
outtxt = self._test_toy_build(ec_file=toy_ec_cuda, extra_args=args, raise_error=True)
34753494
stdout = self.get_stdout()
34763495
no_cuda_pattern = r".*/bin/toy does not appear to be a CUDA executable \(no CUDA device code found\), "
34773496
no_cuda_pattern += r"so skipping CUDA sanity check"
34783497
no_cuda_regex = re.compile(no_cuda_pattern, re.M)
3479-
msg = "Pattern %s not found in full build log: %s" % (no_cuda_pattern, outtxt)
3498+
msg = "Pattern '%s' not found in full build log: %s" % (no_cuda_pattern, outtxt)
34803499
self.assertTrue(no_cuda_regex.search(outtxt), msg)
34813500
expected_result_pattern = "INFO Sanity check for toy successful"
34823501
expected_result = re.compile(expected_result_pattern, re.M)
3483-
msg = "Pattern %s not found in full build log: %s" % (expected_result, outtxt)
3502+
msg = "Pattern '%s' not found in full build log: %s" % (expected_result, outtxt)
34843503
self.assertTrue(expected_result.search(outtxt), msg)
34853504
assert_cuda_report(missing_cc=0, additional_cc=0, missing_ptx=0, log=outtxt, stdout=stdout, num_checked=0)
34863505

0 commit comments

Comments
 (0)