33
44@author: Andrew Edmondson (University of Birmingham)
55@author: Alex Domingo (Vrije Universiteit Brussel)
6+ @author: Kenneth Hoste (Ghent University)
67"""
78import os
9+ import re
810from distutils .version import LooseVersion
911from easybuild .easyblocks .generic .configuremake import ConfigureMake
12+ from easybuild .framework .easyconfig import CUSTOM
1013from easybuild .tools .systemtools import POWER , get_cpu_architecture , get_shared_lib_ext
11- from easybuild .tools .build_log import print_warning
14+ from easybuild .tools .build_log import EasyBuildError , print_warning
1215from easybuild .tools .config import ERROR
1316from easybuild .tools .run import run_cmd , check_log_for_errors
1417
18+ LAPACK_TEST_TARGET = 'lapack-test'
1519TARGET = 'TARGET'
1620
1721
1822class EB_OpenBLAS (ConfigureMake ):
1923 """Support for building/installing OpenBLAS."""
2024
25+ @staticmethod
26+ def extra_options ():
27+ """Custom easyconfig parameters for OpenBLAS easyblock."""
28+ extra_vars = {
29+ 'max_failing_lapack_tests_num_errors' : [0 , "Maximum number of LAPACK tests failing "
30+ "due to numerical errors" , CUSTOM ],
31+ 'max_failing_lapack_tests_other_errors' : [0 , "Maximum number of LAPACK tests failing "
32+ "due to non-numerical errors" , CUSTOM ],
33+ 'run_lapack_tests' : [False , "Run LAPACK tests during test step, "
34+ "and check whether failing tests exceeds threshold" , CUSTOM ],
35+ }
36+
37+ return ConfigureMake .extra_options (extra_vars )
38+
2139 def configure_step (self ):
2240 """ set up some options - but no configure command to run"""
2341
@@ -72,10 +90,47 @@ def build_step(self):
7290 cmd = ' ' .join ([self .cfg ['prebuildopts' ], makecmd , ' ' .join (build_parts ), self .cfg ['buildopts' ]])
7391 run_cmd (cmd , log_all = True , simple = True )
7492
93+ def check_lapack_test_results (self , test_output ):
94+ """Check output of OpenBLAS' LAPACK test suite ('make lapack-test')."""
95+
96+ # example:
97+ # --> LAPACK TESTING SUMMARY <--
98+ # SUMMARY nb test run numerical error other error
99+ # ================ =========== ================= ================
100+ # ...
101+ # --> ALL PRECISIONS 4116982 4172 (0.101%) 0 (0.000%)
102+ test_summary_pattern = r'\s+' .join ([
103+ r"^--> ALL PRECISIONS" ,
104+ r"(?P<test_cnt>[0-9]+)" ,
105+ r"(?P<test_fail_num_error>[0-9]+)\s+\([0-9.]+\%\)" ,
106+ r"(?P<test_fail_other_error>[0-9]+)\s+\([0-9.]+\%\)" ,
107+ ])
108+ regex = re .compile (test_summary_pattern , re .M )
109+ res = regex .search (test_output )
110+ if res :
111+ (tot_cnt , fail_cnt_num_errors , fail_cnt_other_errors ) = [int (x ) for x in res .groups ()]
112+ msg = "%d LAPACK tests run - %d failed due to numerical errors - %d failed due to other errors"
113+ self .log .info (msg , tot_cnt , fail_cnt_num_errors , fail_cnt_other_errors )
114+
115+ if fail_cnt_other_errors > self .cfg ['max_failing_lapack_tests_other_errors' ]:
116+ raise EasyBuildError ("Too many LAPACK tests failed due to non-numerical errors: %d (> %d)" ,
117+ fail_cnt_other_errors , self .cfg ['max_failing_lapack_tests_other_errors' ])
118+
119+ if fail_cnt_num_errors > self .cfg ['max_failing_lapack_tests_num_errors' ]:
120+ raise EasyBuildError ("Too many LAPACK tests failed due to numerical errors: %d (> %d)" ,
121+ fail_cnt_num_errors , self .cfg ['max_failing_lapack_tests_num_errors' ])
122+ else :
123+ raise EasyBuildError ("Failed to find test summary using pattern '%s' in test output: %s" ,
124+ test_summary_pattern , test_output )
125+
75126 def test_step (self ):
76127 """ Mandatory test step plus optional runtest"""
77128
78129 run_tests = ['tests' ]
130+
131+ if self .cfg ['run_lapack_tests' ]:
132+ run_tests += [LAPACK_TEST_TARGET ]
133+
79134 if self .cfg ['runtest' ]:
80135 run_tests += [self .cfg ['runtest' ]]
81136
@@ -86,6 +141,10 @@ def test_step(self):
86141 # Raise an error if any test failed
87142 check_log_for_errors (out , [('FATAL ERROR' , ERROR )])
88143
144+ # check number of failing LAPACK tests more closely
145+ if runtest == LAPACK_TEST_TARGET :
146+ self .check_lapack_test_results (out )
147+
89148 def sanity_check_step (self ):
90149 """ Custom sanity check for OpenBLAS """
91150 custom_paths = {
0 commit comments