diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 2abb9eb..fd0d508 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -80,26 +80,47 @@ jobs: - - name: FindBLAS Default + - name: FindBLAS Default (C) # Disable for MKL-ILP64 b/c the default is LP64 unless otherwise specified if: ${{ matrix.linalg_lib != 'intel-mkl' || matrix.int_interface != 'ilp64' }} run: | - cmake -H${GITHUB_WORKSPACE}/examples/blas/default \ - -B${{runner.workspace}}/build-findblas-default \ + cmake -H${GITHUB_WORKSPACE}/examples/blas/default_c \ + -B${{runner.workspace}}/build-findblas-default_c \ -DCMAKE_MODULE_PATH=${GITHUB_WORKSPACE} \ -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} \ -DBLAS_THREAD_LAYER=${{matrix.thread}} .github/workflows/scripts/check_blas_cmake_cache.sh \ - ${{runner.workspace}}/build-findblas-default \ + ${{runner.workspace}}/build-findblas-default_c \ ${{matrix.linalg_lib}} ${{matrix.thread}} ${{matrix.int_interface}} - - name: FindBLAS Default (Error Output) + - name: FindBLAS Default (C) (Error Output) if: ${{ failure() }} run: | - ls ${{runner.workspace}}/build-findblas-default - ls ${{runner.workspace}}/build-findblas-default/CMakeFiles - #echo "CMAKE OUTPUT" && cat ${{runner.workspace}}/build-findblas-default/CMakeFiles/CMakeOutput.log - echo "CMAKE ERROR" && cat ${{runner.workspace}}/build-findblas-default/CMakeFiles/CMakeError.log + ls ${{runner.workspace}}/build-findblas-default_c + ls ${{runner.workspace}}/build-findblas-default_c/CMakeFiles + #echo "CMAKE OUTPUT" && cat ${{runner.workspace}}/build-findblas-default_c/CMakeFiles/CMakeOutput.log + echo "CMAKE ERROR" && cat ${{runner.workspace}}/build-findblas-default_c/CMakeFiles/CMakeError.log + + - name: FindBLAS Default (CXX) + # Disable for MKL-ILP64 b/c the default is LP64 unless otherwise specified + if: ${{ matrix.linalg_lib != 'intel-mkl' || matrix.int_interface != 'ilp64' }} + run: | + cmake -H${GITHUB_WORKSPACE}/examples/blas/default_cxx \ + -B${{runner.workspace}}/build-findblas-default_cxx \ + -DCMAKE_MODULE_PATH=${GITHUB_WORKSPACE} \ + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} \ + -DBLAS_THREAD_LAYER=${{matrix.thread}} + .github/workflows/scripts/check_blas_cmake_cache.sh \ + ${{runner.workspace}}/build-findblas-default_cxx \ + ${{matrix.linalg_lib}} ${{matrix.thread}} ${{matrix.int_interface}} + + - name: FindBLAS Default (CXX) (Error Output) + if: ${{ failure() }} + run: | + ls ${{runner.workspace}}/build-findblas-default_cxx + ls ${{runner.workspace}}/build-findblas-default_cxx/CMakeFiles + #echo "CMAKE OUTPUT" && cat ${{runner.workspace}}/build-findblas-default_cxx/CMakeFiles/CMakeOutput.log + echo "CMAKE ERROR" && cat ${{runner.workspace}}/build-findblas-default_cxx/CMakeFiles/CMakeError.log - name: FindBLAS Integer Specific run: | diff --git a/FindBLIS.cmake b/FindBLIS.cmake index 663485c..361cc59 100644 --- a/FindBLIS.cmake +++ b/FindBLIS.cmake @@ -34,15 +34,29 @@ endif() # check ILP64 if( BLIS_INCLUDE_DIR ) - try_run( BLIS_USES_LP64 - BLIS_TEST_COMPILES - ${CMAKE_CURRENT_BINARY_DIR} - SOURCES ${CMAKE_CURRENT_LIST_DIR}/util/blis_int_size.c - CMAKE_FLAGS -DINCLUDE_DIRECTORIES:STRING=${BLIS_INCLUDE_DIR} - LINK_LIBRARIES ${BLIS_LIBRARIES} - COMPILE_OUTPUT_VARIABLE _blis_idx_compile_output - RUN_OUTPUT_VARIABLE _blis_idx_run_output - ) + + check_lang_enabled( "C" _c_enabled ) + check_lang_enabled( "CXX" _cxx_enabled ) + set(_blis_int_size_src FALSE) + if( _c_enabled ) + set(_blis_int_size_src ${CMAKE_CURRENT_LIST_DIR}/util/blis_int_size.c ) + elseif(_cxx_enabled) + set(_blis_int_size_src ${CMAKE_CURRENT_LIST_DIR}/util/blis_int_size.cxx ) + endif() + + if( _blis_int_size_src ) + try_run( BLIS_USES_LP64 + BLIS_TEST_COMPILES + ${CMAKE_CURRENT_BINARY_DIR} + SOURCES ${_blis_int_size_src} + CMAKE_FLAGS -DINCLUDE_DIRECTORIES:STRING=${BLIS_INCLUDE_DIR} + LINK_LIBRARIES ${BLIS_LIBRARIES} + COMPILE_OUTPUT_VARIABLE _blis_idx_compile_output + RUN_OUTPUT_VARIABLE _blis_idx_run_output + ) + else() + set(BLIS_TEST_COMPILES FALSE) + endif() if( NOT BLIS_TEST_COMPILES ) if( ${_blis_idx_compile_output} MATCHES "pthread_" ) @@ -60,31 +74,38 @@ if( BLIS_INCLUDE_DIR ) endif() endif() - try_run( BLIS_USES_LP64 - BLIS_TEST_COMPILES - ${CMAKE_CURRENT_BINARY_DIR} - SOURCES ${CMAKE_CURRENT_LIST_DIR}/util/blis_int_size.c - CMAKE_FLAGS -DINCLUDE_DIRECTORIES:STRING=${BLIS_INCLUDE_DIR} - LINK_LIBRARIES ${BLIS_LIBRARIES} - COMPILE_OUTPUT_VARIABLE _blis_idx_compile_output - RUN_OUTPUT_VARIABLE _blis_idx_run_output - ) + if( _blis_int_size_src ) + try_run( BLIS_USES_LP64 + BLIS_TEST_COMPILES + ${CMAKE_CURRENT_BINARY_DIR} + SOURCES ${_blis_int_size_src} + CMAKE_FLAGS -DINCLUDE_DIRECTORIES:STRING=${BLIS_INCLUDE_DIR} + LINK_LIBRARIES ${BLIS_LIBRARIES} + COMPILE_OUTPUT_VARIABLE _blis_idx_compile_output + RUN_OUTPUT_VARIABLE _blis_idx_run_output + ) + if( ${BLIS_USES_LP64} EQUAL 0 ) + set( BLIS_USES_LP64 TRUE ) + else() + set( BLIS_USES_LP64 FALSE ) + endif() - if( ${BLIS_USES_LP64} EQUAL 0 ) - set( BLIS_USES_LP64 TRUE ) + ## Handle components + if( BLIS_USES_LP64 ) + set( BLIS_ilp64_FOUND FALSE ) + set( BLIS_lp64_FOUND TRUE ) + else() + set( BLIS_ilp64_FOUND TRUE ) + set( BLIS_lp64_FOUND FALSE ) + endif() else() - set( BLIS_USES_LP64 FALSE ) + set(BLIS_USES_LP64 FALSE) + set(BLIS_lp64_FOUND FALSE) + set(BLIS_ilp64_FOUND FALSE) endif() - ## Handle components - if( BLIS_USES_LP64 ) - set( BLIS_ilp64_FOUND FALSE ) - set( BLIS_lp64_FOUND TRUE ) - else() - set( BLIS_ilp64_FOUND TRUE ) - set( BLIS_lp64_FOUND FALSE ) - endif() + endif() diff --git a/examples/blas/default/CMakeLists.txt b/examples/blas/default_c/CMakeLists.txt similarity index 100% rename from examples/blas/default/CMakeLists.txt rename to examples/blas/default_c/CMakeLists.txt diff --git a/examples/blas/default_cxx/CMakeLists.txt b/examples/blas/default_cxx/CMakeLists.txt new file mode 100644 index 0000000..1d5546c --- /dev/null +++ b/examples/blas/default_cxx/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required( VERSION 3.10 ) +project(blas_test LANGUAGES CXX) + +find_package( BLAS REQUIRED ) +include( ../../blas/common.cmake ) diff --git a/util/BLASUtilities.cmake b/util/BLASUtilities.cmake index 1d782f3..0f1885c 100644 --- a/util/BLASUtilities.cmake +++ b/util/BLASUtilities.cmake @@ -2,13 +2,31 @@ set( BLAS_UTILITY_CMAKE_FILE_DIR ${CMAKE_CURRENT_LIST_DIR} ) function( check_blas_int _libs _dgemm_name _libs_are_lp64 ) -try_run( _run_result _compile_result ${CMAKE_CURRENT_BINARY_DIR} - SOURCES ${BLAS_UTILITY_CMAKE_FILE_DIR}/ilp64_checker.c - LINK_LIBRARIES ${${_libs}} - COMPILE_DEFINITIONS "-DDGEMM_NAME=${_dgemm_name}" - COMPILE_OUTPUT_VARIABLE _compile_output - RUN_OUTPUT_VARIABLE _run_output -) + check_lang_enabled( "C" _c_enabled ) + check_lang_enabled( "CXX" _cxx_enabled ) + check_lang_enabled( "Fortran" _fortran_enabled ) + + set(_func_src_file) + if( _c_enabled ) + set( _func_src_file ${BLAS_UTILITY_CMAKE_FILE_DIR}/ilp64_checker.c ) + elseif( _cxx_enabled ) + set( _func_src_file ${BLAS_UTILITY_CMAKE_FILE_DIR}/ilp64_checker.cxx ) + elseif( _fortran_enabled ) + set( _func_src_file ${BLAS_UTILITY_CMAKE_FILE_DIR}/ilp64_checker.f ) + endif() + + +if(_func_src_file) + try_run( _run_result _compile_result ${CMAKE_CURRENT_BINARY_DIR} + SOURCES ${_func_src_file} + LINK_LIBRARIES ${${_libs}} + COMPILE_DEFINITIONS "-DDGEMM_NAME=${_dgemm_name}" + COMPILE_OUTPUT_VARIABLE _compile_output + RUN_OUTPUT_VARIABLE _run_output + ) +else() + set(_compile_result FALSE) +endif() if (NOT _compile_result) message(FATAL_ERROR "check_blas_int: try_run failed: _compile_output=${_compile_output}") diff --git a/util/CommonFunctions.cmake b/util/CommonFunctions.cmake index 953cd1f..05cf59c 100644 --- a/util/CommonFunctions.cmake +++ b/util/CommonFunctions.cmake @@ -109,6 +109,14 @@ function( copy_meta_data _src _dest ) endfunction() +function( check_lang_enabled _lang _out ) + if( CMAKE_${_lang}_COMPILER ) + set( ${_out} TRUE PARENT_SCOPE ) + else() + set( ${_out} FALSE PARENT_SCOPE ) + endif() +endfunction() + function( get_true_target_property _out _target _property ) @@ -153,11 +161,28 @@ endfunction() function( check_function_exists_w_results _libs _func _output _result ) + check_lang_enabled( "C" _c_enabled ) + check_lang_enabled( "CXX" _cxx_enabled ) + check_lang_enabled( "Fortran" _fortran_enabled ) + + set(_func_src_file) + if( _c_enabled ) + set( _func_src_file ${COMMON_UTILITY_CMAKE_FILE_DIR}/func_check.c ) + elseif( _cxx_enabled ) + set( _func_src_file ${COMMON_UTILITY_CMAKE_FILE_DIR}/func_check.cxx ) + elseif( _fortran_enabled ) + set( _func_src_file ${COMMON_UTILITY_CMAKE_FILE_DIR}/func_check.f ) + endif() + + if( _func_src_file ) try_compile( ${_result} ${CMAKE_CURRENT_BINARY_DIR} - SOURCES ${COMMON_UTILITY_CMAKE_FILE_DIR}/func_check.c + SOURCES ${_func_src_file} COMPILE_DEFINITIONS "-DFUNC_NAME=${_func}" LINK_LIBRARIES ${_libs} OUTPUT_VARIABLE ${_output} ) + else() + set( ${_result} FALSE ) + endif() set( ${_output} "${${_output}}" PARENT_SCOPE ) set( ${_result} "${${_result}}" PARENT_SCOPE ) diff --git a/util/blis_int_size.cxx b/util/blis_int_size.cxx new file mode 100644 index 0000000..8b5d457 --- /dev/null +++ b/util/blis_int_size.cxx @@ -0,0 +1,90 @@ +#if 0 +//#define BLIS_PARAM_MACRO_DEFS_H +//#define BLIS_OBJ_MACRO_DEFS_H +//#define BLIS_MISC_MACRO_DEFS_H +//#define BLIS_SCAL2RIS_MXN_H +//#define BLIS_SCALRIS_MXN_UPLO_H +//#define BLIS_ABSQR2_H +//#define BLIS_ABVAL2S_H +//#define BLIS_ADDS_H +//#define BLIS_ADDJS_H +//#define BLIS_ADD3S_H +//#define BLIS_AXPBYS_H +//#define BLIS_AXPBYJS_H +//#define BLIS_AXPYS_H +//#define BLIS_AXPYJS_H +//#define BLIS_AXMYS_H +//#define BLIS_CONJS_H +//#define BLIS_COPYS_H +//#define BLIS_COPYJS_H +//#define BLIS_COPYCJS_H +//#define BLIS_COPYNZS_H +//#define BLIS_COPYJNZS_H +//#define BLIS_ADDS_MXN_H +#include + +//blis_version.c:(.text+0x304): undefined reference to `round' +void* bli_thrcomm_bcast( dim_t inside_id, void* to_send, thrcomm_t* comm ) { } +void bli_thrcomm_barrier( dim_t thread_id, thrcomm_t* comm ){ } +void bli_thread_range_sub + ( + thrinfo_t* thread, + dim_t n, + dim_t bf, + bool_t handle_edge_low, + dim_t* start, + dim_t* end + ){ } + +BLIS_EXPORT_BLIS int bli_pthread_mutex_init + ( + bli_pthread_mutex_t* mutex, + const bli_pthread_mutexattr_t* attr + ){ } + +BLIS_EXPORT_BLIS int bli_pthread_mutex_destroy + ( + bli_pthread_mutex_t* mutex + ){ } + +BLIS_EXPORT_BLIS int bli_pthread_mutex_lock + ( + bli_pthread_mutex_t* mutex + ){ } + +BLIS_EXPORT_BLIS int bli_pthread_mutex_trylock + ( + bli_pthread_mutex_t* mutex + ){ } + +BLIS_EXPORT_BLIS int bli_pthread_mutex_unlock + ( + bli_pthread_mutex_t* mutex + ) { } + +void bli_abort(){ } +void bli_obj_scalar_detach + ( + obj_t* a, + obj_t* alpha + ){ } +bool_t bli_obj_imag_is_zero( obj_t* a ){ } +double round( double x) {} + +int main() { + int blis_int_size = BLIS_BLAS_INT_TYPE_SIZE; + if( blis_int_size == 32 ) return 0; + else return 1; +} +#else +#if __has_include() +#include +#else +#include +#endif +int main() { + int blis_int_size = BLIS_BLAS_INT_TYPE_SIZE; + if( blis_int_size == 32 ) return 0; + else return 1; +} +#endif diff --git a/util/func_check.cxx b/util/func_check.cxx new file mode 100644 index 0000000..015f710 --- /dev/null +++ b/util/func_check.cxx @@ -0,0 +1,5 @@ +extern "C" { void FUNC_NAME(); } +int main() { + FUNC_NAME(); + return 0; +} diff --git a/util/ilp64_checker.cxx b/util/ilp64_checker.cxx new file mode 100644 index 0000000..58c5925 --- /dev/null +++ b/util/ilp64_checker.cxx @@ -0,0 +1,50 @@ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + void DGEMM_NAME(const char*, const char*, int32_t*,int32_t*,int32_t*, double*, double*, int32_t*, double*, int32_t*, double*, double*, int32_t*); +#ifdef __cplusplus +} +#endif + +int main() { + + int32_t fake_two[2] = {2,1}; // Will be interpreted as 2 in LP64 and 2^32+2 in ILP64 + int32_t true_two[2] = {2,0}; // Will be interpreted as 2 in both LP64 and ILP64 + + double A[4] = {1.,1.,1.,1.}; + double B[4] = {1.,1.,1.,1.}; + double C[4] = {0.,0.,0.,0.}; + + double zero = 0., one_d = 1.; + int32_t* fake_two_ptr = fake_two; + int32_t* true_two_ptr = true_two; + + // In an LP64 BLAS Library, the GEMM will be interpreted as N=M=K=LDA=LDB=LDA=2 + // In an ILP64 BLAS Library, the GEMM will be interpreted as LDA=LDB=LDC=2 and M=N=K=LARGE + // Because LDA < M, etc in ILP64, the GEMM fails by the standard + // Valid for MKL, BLIS, OpenBLAS, NETLIB (Reference) BLAS, and ESSL + DGEMM_NAME( "N","N", + fake_two_ptr, fake_two_ptr, fake_two_ptr, + &one_d, A, true_two_ptr, B, true_two_ptr, + &zero, C, true_two_ptr ); + + // Print out result, will either be zero or it work print due to GEMM abort + double sum = 0.; + int i; + for( i = 0; i < 4; ++i ) sum += C[i]; + + +#if 0 + if( ((int)sum) == 8 ) return 0; + else return 1; +#else + if( ((int)sum) == 8 ) printf("XXXX BLAS IS LP64 XXXX\n" ); + else printf("XXXX BLAS IS ILP64 XXXX\n"); +#endif + + return 0; +}; +