From 11b6e0603a3f7647c2310e51be3a3a6074033ab3 Mon Sep 17 00:00:00 2001 From: Tim Davis Date: Sat, 2 Dec 2023 20:12:15 -0600 Subject: [PATCH] Example: add version checks to C++ library --- Example/Source/my.c | 26 ++--- Example/Source/my_cxx.cc | 244 +++++++++++++++++++++------------------ 2 files changed, 147 insertions(+), 123 deletions(-) diff --git a/Example/Source/my.c b/Example/Source/my.c index 6da684e0e..54989e6bb 100644 --- a/Example/Source/my.c +++ b/Example/Source/my.c @@ -7,7 +7,7 @@ //------------------------------------------------------------------------------ -// Example library that relies on SuiteSparse packages +// Example C library that relies on SuiteSparse packages // ANSI C include files: #include @@ -128,7 +128,7 @@ int my_function (void) // returns 0 on success, -1 on failure //-------------------------------------------------------------------------- amd_version (version) ; - OK (my_check_version ("AMD", + OK (my_check_version ("AMD", AMD_MAIN_VERSION, AMD_SUB_VERSION, AMD_SUBSUB_VERSION, AMD_DATE, version)) ; @@ -141,7 +141,7 @@ int my_function (void) // returns 0 on success, -1 on failure //-------------------------------------------------------------------------- btf_version (version) ; - OK (my_check_version ("BTF", + OK (my_check_version ("BTF", BTF_MAIN_VERSION, BTF_SUB_VERSION, BTF_SUBSUB_VERSION, BTF_DATE, version)) ; @@ -160,7 +160,7 @@ int my_function (void) // returns 0 on success, -1 on failure //-------------------------------------------------------------------------- camd_version (version) ; - OK (my_check_version ("CAMD", + OK (my_check_version ("CAMD", CAMD_MAIN_VERSION, CAMD_SUB_VERSION, CAMD_SUBSUB_VERSION, CAMD_DATE, version)) ; @@ -174,7 +174,7 @@ int my_function (void) // returns 0 on success, -1 on failure //-------------------------------------------------------------------------- ccolamd_version (version) ; - OK (my_check_version ("CCOLAMD", + OK (my_check_version ("CCOLAMD", CCOLAMD_MAIN_VERSION, CCOLAMD_SUB_VERSION, CCOLAMD_SUBSUB_VERSION, CCOLAMD_DATE, version)) ; @@ -191,7 +191,7 @@ int my_function (void) // returns 0 on success, -1 on failure //-------------------------------------------------------------------------- colamd_version (version) ; - OK (my_check_version ("COLAMD", + OK (my_check_version ("COLAMD", COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION, COLAMD_SUBSUB_VERSION, COLAMD_DATE, version)) ; @@ -208,7 +208,7 @@ int my_function (void) // returns 0 on success, -1 on failure //-------------------------------------------------------------------------- v = cholmod_l_version (version) ; - OK (my_check_version ("CHOLMOD", + OK (my_check_version ("CHOLMOD", CHOLMOD_MAIN_VERSION, CHOLMOD_SUB_VERSION, CHOLMOD_SUBSUB_VERSION, CHOLMOD_DATE, version)) ; @@ -247,7 +247,7 @@ int my_function (void) // returns 0 on success, -1 on failure //-------------------------------------------------------------------------- klu_version (version) ; - OK (my_check_version ("KLU", + OK (my_check_version ("KLU", KLU_MAIN_VERSION, KLU_SUB_VERSION, KLU_SUBSUB_VERSION, KLU_DATE, version)) ; @@ -281,7 +281,7 @@ int my_function (void) // returns 0 on success, -1 on failure //-------------------------------------------------------------------------- ldl_version (version) ; - OK (my_check_version ("LDL", + OK (my_check_version ("LDL", LDL_MAIN_VERSION, LDL_SUB_VERSION, LDL_SUBSUB_VERSION, LDL_DATE, version)) ; @@ -303,7 +303,7 @@ int my_function (void) // returns 0 on success, -1 on failure //-------------------------------------------------------------------------- RBio_version (version) ; - OK (my_check_version ("RBio", + OK (my_check_version ("RBio", RBIO_MAIN_VERSION, RBIO_SUB_VERSION, RBIO_SUBSUB_VERSION, RBIO_DATE, version)) ; @@ -339,7 +339,7 @@ int my_function (void) // returns 0 on success, -1 on failure OK (SPEX_initialize ( ) == SPEX_OK) ; SPEX_version (version) ; - OK (my_check_version ("SPEX", + OK (my_check_version ("SPEX", SPEX_VERSION_MAJOR, SPEX_VERSION_MINOR, SPEX_VERSION_SUB, SPEX_DATE, version)) ; OK (SPEX_finalize ( ) == SPEX_OK) ; @@ -349,7 +349,7 @@ int my_function (void) // returns 0 on success, -1 on failure //-------------------------------------------------------------------------- SuiteSparseQR_C_version (version) ; - OK (my_check_version ("SuiteSparseQR", + OK (my_check_version ("SuiteSparseQR", SPQR_MAIN_VERSION, SPQR_SUB_VERSION, SPQR_SUBSUB_VERSION, SPQR_DATE, version)) ; @@ -396,7 +396,7 @@ int my_function (void) // returns 0 on success, -1 on failure //-------------------------------------------------------------------------- umfpack_version (version) ; - OK (my_check_version ("UMFPACK", + OK (my_check_version ("UMFPACK", UMFPACK_MAIN_VERSION, UMFPACK_SUB_VERSION, UMFPACK_SUBSUB_VERSION, UMFPACK_DATE, version)) ; diff --git a/Example/Source/my_cxx.cc b/Example/Source/my_cxx.cc index 9e9840599..2a2d8a469 100644 --- a/Example/Source/my_cxx.cc +++ b/Example/Source/my_cxx.cc @@ -13,18 +13,24 @@ #include #include -// FIXME: use another filename #include "my_internal.h" -// FIXME: return -1 -#define OK(result) \ - if (!(result)) \ - { \ - std::cout << "abort line " << __LINE__ << std::endl ; \ - abort ( ) ; \ +//------------------------------------------------------------------------------ +// OK: check a result and return an error if it fails +//------------------------------------------------------------------------------ + +#define OK(result) \ + if (!(result)) \ + { \ + std::cout << "FAIL file: " << __FILE__ \ + " line: " << __LINE__ << std::endl ;\ + return (-1) ; \ } -// FIXME: use the C code? or rename? +//------------------------------------------------------------------------------ +// my_version: version of MY library +//------------------------------------------------------------------------------ + void my_version (int version [3], char date [128]) { // get the version of this library @@ -34,36 +40,76 @@ void my_version (int version [3], char date [128]) version [2] = MY_PATCH_VERSION ; } -// FIXME: rename? +//------------------------------------------------------------------------------ +// my_check_version: check library version +//------------------------------------------------------------------------------ + +int my_check_version (const char *package, int major, int minor, int patch, + const char *date, int version [3]) +{ + // version and date in package header file: + std::cout << + "\n------------------------------------------------------------\n" + << package << ": v" + << major << "." + << minor << "." + << patch << " " + << "(" << date << ")" << std::endl ; + + // version in library itself: + std::cout + << package << ": v" + << version [0] << "." + << version [1] << "." + << version [2] << " " + << "(in library)" << std::endl ; + + // make sure the versions match + int ok = (major == version [0]) && + (minor == version [1]) && + (patch == version [2]) ; + + if (!ok) std::cout << "Versions do not match" << std::endl ; + return (ok) ; +} + +//------------------------------------------------------------------------------ +// my_function: try each library in SuiteSparse +//------------------------------------------------------------------------------ + int my_function (void) { + int version [3] ; + + //-------------------------------------------------------------------------- + // My package + //-------------------------------------------------------------------------- + + char my_date [128] ; + my_version (version, my_date) ; + OK (my_check_version ("MY", MY_MAJOR_VERSION, MY_MINOR_VERSION, + MY_PATCH_VERSION, MY_DATE, version)) ; + std::cout << "MY date: " << my_date << std::endl ; + OK (strcmp (my_date, MY_DATE) == 0) ; + //-------------------------------------------------------------------------- // SuiteSparse_config //-------------------------------------------------------------------------- - std::cout << "SuiteSparse: v" - << SUITESPARSE_MAIN_VERSION << "." - << SUITESPARSE_SUB_VERSION << "." - << SUITESPARSE_SUBSUB_VERSION << " " - << "(" << SUITESPARSE_DATE << ")" << std::endl; - int version[3]; int v = SuiteSparse_version (version) ; - std::cout << "SuiteSparse: v" - << version[0] << "." - << version[1] << "." - << version[2] << " " - << "(in library)" << std::endl; + OK (my_check_version ("SuiteSparse_config", + SUITESPARSE_MAIN_VERSION, SUITESPARSE_SUB_VERSION, + SUITESPARSE_SUBSUB_VERSION, SUITESPARSE_DATE, version)) ; //-------------------------------------------------------------------------- // CXSparse //-------------------------------------------------------------------------- - std::cout << "CXSparse: v" - << CS_VER << "." - << CS_SUBVER << "." - << CS_SUBSUB << " " - << "(" << CS_DATE << ")" << std::endl; + cxsparse_version (version) ; + OK (my_check_version ("CXSparse", CS_VER, CS_SUBVER, CS_SUBSUB, CS_DATE, + version)) ; + cs_dl *A = nullptr ; // create a dense 2-by-2 matrix @@ -88,11 +134,11 @@ int my_function (void) // AMD //-------------------------------------------------------------------------- - std::cout << "AMD: v" - << AMD_MAIN_VERSION << "." - << AMD_SUB_VERSION << "." - << AMD_SUBSUB_VERSION << " " - << "(" << AMD_DATE << ")" << std::endl; + amd_version (version) ; + OK (my_check_version ("AMD", + AMD_MAIN_VERSION, AMD_SUB_VERSION, AMD_SUBSUB_VERSION, AMD_DATE, + version)) ; + int64_t P [N] ; OK (amd_l_order (n, Ap, Ai, P, nullptr, nullptr) == AMD_OK) ; for (int k = 0 ; k < n ; k++) @@ -102,11 +148,11 @@ int my_function (void) // BTF //-------------------------------------------------------------------------- - std::cout << "BTF: v" - << BTF_MAIN_VERSION << "." - << BTF_SUB_VERSION << "." - << BTF_SUBSUB_VERSION << " " - << "(" << BTF_DATE << ")" << std::endl; + btf_version (version) ; + OK (my_check_version ("BTF", + BTF_MAIN_VERSION, BTF_SUB_VERSION, BTF_SUBSUB_VERSION, BTF_DATE, + version)) ; + double work ; int64_t nmatch ; int64_t Q [N], R [N+1], Work [5*N] ; @@ -123,11 +169,11 @@ int my_function (void) // CAMD //-------------------------------------------------------------------------- - std::cout << "CAMD: v" - << CAMD_MAIN_VERSION << "." - << CAMD_SUB_VERSION << "." - << CAMD_SUBSUB_VERSION << " " - << "(" << CAMD_DATE << ")" << std::endl; + camd_version (version) ; + OK (my_check_version ("CAMD", + CAMD_MAIN_VERSION, CAMD_SUB_VERSION, CAMD_SUBSUB_VERSION, CAMD_DATE, + version)) ; + int64_t Cmem [N] ; for (int k = 0 ; k < n ; k++) Cmem [k] = 0 ; @@ -139,11 +185,11 @@ int my_function (void) // CCOLAMD //-------------------------------------------------------------------------- - std::cout << "CCOLAMD: v" - << CCOLAMD_MAIN_VERSION << "." - << CCOLAMD_SUB_VERSION << "." - << CCOLAMD_SUBSUB_VERSION << " " - << "(" << CCOLAMD_DATE << ")" << std::endl; + ccolamd_version (version) ; + OK (my_check_version ("CCOLAMD", + CCOLAMD_MAIN_VERSION, CCOLAMD_SUB_VERSION, CCOLAMD_SUBSUB_VERSION, + CCOLAMD_DATE, version)) ; + int64_t Alen = ccolamd_l_recommended (NNZ, n, n) ; int64_t *Awork = (int64_t *) malloc (Alen * sizeof (int64_t)) ; OK (Awork != nullptr) ; @@ -157,11 +203,11 @@ int my_function (void) // COLAMD //-------------------------------------------------------------------------- - std::cout << "COLAMD: v" - << COLAMD_MAIN_VERSION << "." - << COLAMD_SUB_VERSION << "." - << COLAMD_SUBSUB_VERSION << " " - << "(" << COLAMD_DATE << ")" << std::endl; + colamd_version (version) ; + OK (my_check_version ("COLAMD", + COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION, COLAMD_SUBSUB_VERSION, + COLAMD_DATE, version)) ; + Alen = ccolamd_l_recommended (NNZ, n, n) ; Awork = (int64_t *) malloc (Alen * sizeof (int64_t)) ; OK (Awork != nullptr) ; @@ -175,17 +221,11 @@ int my_function (void) // CHOLMOD //-------------------------------------------------------------------------- - std::cout << "CHOLMOD: v" - << CHOLMOD_MAIN_VERSION << "." - << CHOLMOD_SUB_VERSION << "." - << CHOLMOD_SUBSUB_VERSION << " " - << "(" << CHOLMOD_DATE << ")" << std::endl; v = cholmod_l_version (version) ; - std::cout << "CHOLMOD: v" - << version[0] << "." - << version[1] << "." - << version[2] << " " - << "(in library)" << std::endl; + OK (my_check_version ("CHOLMOD", + CHOLMOD_MAIN_VERSION, CHOLMOD_SUB_VERSION, CHOLMOD_SUBSUB_VERSION, + CHOLMOD_DATE, version)) ; + cholmod_common cc ; OK (cholmod_l_start (&cc)) ; @@ -194,18 +234,11 @@ int my_function (void) //-------------------------------------------------------------------------- #if ! defined (NO_GRAPHBLAS) - std::cout << "GraphBLAS: v" - << GxB_IMPLEMENTATION_MAJOR << "." - << GxB_IMPLEMENTATION_MINOR << "." - << GxB_IMPLEMENTATION_SUB << " " - << "(" << GxB_IMPLEMENTATION_DATE << ")" << std::endl; OK (GrB_init (GrB_NONBLOCKING) == GrB_SUCCESS) ; OK (GxB_Global_Option_get (GxB_LIBRARY_VERSION, version) == GrB_SUCCESS) ; - std::cout << "GraphBLAS: v" - << version[0] << "." - << version[1] << "." - << version[2] << " " - << "(in library)" << std::endl; + OK (my_check_version ("GraphBLAS", + GxB_IMPLEMENTATION_MAJOR, GxB_IMPLEMENTATION_MINOR, + GxB_IMPLEMENTATION_SUB, GxB_IMPLEMENTATION_DATE, version)) ; OK (GrB_finalize ( ) == GrB_SUCCESS) ; #endif @@ -215,18 +248,11 @@ int my_function (void) #if ! defined (NO_LAGRAPH) char msg [LAGRAPH_MSG_LEN], verstring [LAGRAPH_MSG_LEN] ; - std::cout << "LAGraph: v" - << LAGRAPH_VERSION_MAJOR << "." - << LAGRAPH_VERSION_MINOR << "." - << LAGRAPH_VERSION_UPDATE << " " - << "(" << LAGRAPH_DATE << ")" << std::endl; OK (LAGraph_Init (msg) == GrB_SUCCESS) ; OK (LAGraph_Version (version, verstring, msg) == GrB_SUCCESS) ; - std::cout << "LAGraph: v" - << version[0] << "." - << version[1] << "." - << version[2] << " " - << "(in library)" << std::endl; + OK (my_check_version ("LAGraph", + LAGRAPH_VERSION_MAJOR, LAGRAPH_VERSION_MINOR, LAGRAPH_VERSION_UPDATE, + LAGRAPH_DATE, version)) ; OK (LAGraph_Finalize (msg) == GrB_SUCCESS) ; #endif @@ -234,11 +260,11 @@ int my_function (void) // KLU //-------------------------------------------------------------------------- - std::cout << "KLU: v" - << KLU_MAIN_VERSION << "." - << KLU_SUB_VERSION << "." - << KLU_SUBSUB_VERSION << " " - << "(" << KLU_DATE << ")" << std::endl; + klu_version (version) ; + OK (my_check_version ("KLU", + KLU_MAIN_VERSION, KLU_SUB_VERSION, KLU_SUBSUB_VERSION, + KLU_DATE, version)) ; + double b [N] = {8., 45.} ; double xgood [N] = {36.4, -32.7} ; double x [N] ; @@ -268,11 +294,11 @@ int my_function (void) // LDL //-------------------------------------------------------------------------- - std::cout << "LDL: v" - << LDL_MAIN_VERSION << "." - << LDL_SUB_VERSION << "." - << LDL_SUBSUB_VERSION << " " - << "(" << LDL_DATE << ")" << std::endl; + ldl_version (version) ; + OK (my_check_version ("LDL", + LDL_MAIN_VERSION, LDL_SUB_VERSION, LDL_SUBSUB_VERSION, + LDL_DATE, version)) ; + double x2 [N] ; P [0] = 0 ; P [1] = 1 ; @@ -290,11 +316,11 @@ int my_function (void) // RBio //-------------------------------------------------------------------------- - std::cout << "RBio: v" - << RBIO_MAIN_VERSION << "." - << RBIO_SUB_VERSION << "." - << RBIO_SUBSUB_VERSION << " " - << "(" << RBIO_DATE << ")" << std::endl; + RBio_version (version) ; + OK (my_check_version ("RBio", + RBIO_MAIN_VERSION, RBIO_SUB_VERSION, RBIO_SUBSUB_VERSION, + RBIO_DATE, version)) ; + char mtype [4]; std::string key {"simple"}; std::string title {"2-by-2 matrix"}; @@ -326,23 +352,22 @@ int my_function (void) // SPEX //-------------------------------------------------------------------------- - std::cout << "SPEX: v" - << SPEX_VERSION_MAJOR << "." - << SPEX_VERSION_MINOR << "." - << SPEX_VERSION_SUB << " " - << "(" << SPEX_DATE << ")" << std::endl; OK (SPEX_initialize ( ) == SPEX_OK) ; + SPEX_version (version) ; + OK (my_check_version ("SPEX", + SPEX_VERSION_MAJOR, SPEX_VERSION_MINOR, SPEX_VERSION_SUB, SPEX_DATE, + version)) ; OK (SPEX_finalize ( ) == SPEX_OK) ; //-------------------------------------------------------------------------- // SPQR //-------------------------------------------------------------------------- - std::cout << "SPQR: v" - << SPQR_MAIN_VERSION << "." - << SPQR_SUB_VERSION << "." - << SPQR_SUBSUB_VERSION << " " - << "(" << SPQR_DATE << ")" << std::endl; + SuiteSparseQR_version (version) ; + OK (my_check_version ("SuiteSparseQR", + SPQR_MAIN_VERSION, SPQR_SUB_VERSION, SPQR_SUBSUB_VERSION, SPQR_DATE, + version)) ; + cholmod_sparse *A2, A2_struct ; cholmod_dense *B2, B2_struct ; cholmod_dense *X2 ; @@ -385,11 +410,10 @@ int my_function (void) // UMFPACK //-------------------------------------------------------------------------- - std::cout << "UMFPACK: v" - << UMFPACK_MAIN_VERSION << "." - << UMFPACK_SUB_VERSION << "." - << UMFPACK_SUBSUB_VERSION << " " - << "(" << UMFPACK_DATE << ")" << std::endl; + umfpack_version (version) ; + OK (my_check_version ("UMFPACK", + UMFPACK_MAIN_VERSION, UMFPACK_SUB_VERSION, UMFPACK_SUBSUB_VERSION, + UMFPACK_DATE, version)) ; std::cout << UMFPACK_VERSION << std::endl; std::cout << UMFPACK_COPYRIGHT;