diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2626072335..26fa99157e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,11 @@ name: LAGraph CI -on: [push, pull_request] +on: + workflow_dispatch: + push: + branches-ignore: + - '**/*dev2' + pull_request: jobs: linux: diff --git a/Acknowledgments.txt b/Acknowledgments.txt index ecb4359f84..815f4e01f9 100644 --- a/Acknowledgments.txt +++ b/Acknowledgments.txt @@ -16,7 +16,7 @@ THIS WORK IS FUNDED IN PART BY: THIS WORK BUILDS UPON THE FOLLOWING PRIOR WORKS: 1. SuiteSparse:GraphBLAS, (http://faculty.cse.tamu.edu/davis/GraphBLAS.html) - Copyright 2017-2022 Timothy A. Davis (Author), AldenMath.com. + Copyright 2017-2023 Timothy A. Davis (Author), AldenMath.com. By Tim Davis, Texas A&M University. Note that while SuiteSparse:GraphBLAS is itself under the Apache 2 license, any contributions derived from SuiteSparse:GraphBLAS and incorporated by the Author into LAGraph are diff --git a/CMakeLists.txt b/CMakeLists.txt index bfe16c3da5..975582e662 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,31 +36,45 @@ # get the version #------------------------------------------------------------------------------- -cmake_minimum_required ( VERSION 3.13 ) +cmake_minimum_required ( VERSION 3.20 ) # LAGraph can be built stand-alone -set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} - ${CMAKE_SOURCE_DIR}/cmake_modules - ${CMAKE_SOURCE_DIR}/../cmake_modules - ${CMAKE_SOURCE_DIR}/../SuiteSparse/cmake_modules - ) +# version of LAGraph +set ( LAGraph_DATE "Dec 30, 2023" ) +set ( LAGraph_VERSION_MAJOR 1 CACHE STRING "" FORCE ) +set ( LAGraph_VERSION_MINOR 1 CACHE STRING "" FORCE ) +set ( LAGraph_VERSION_SUB 0 CACHE STRING "" FORCE ) -cmake_policy ( SET CMP0042 NEW ) -cmake_policy ( SET CMP0048 NEW ) -set ( CMAKE_MACOSX_RPATH TRUE ) +message ( STATUS "Building LAGraph version: v" + ${LAGraph_VERSION_MAJOR}. + ${LAGraph_VERSION_MINOR}. + ${LAGraph_VERSION_SUB} " (" ${LAGraph_DATE} ")" ) -# version of LAGraph -set ( LAGraph_DATE "Aug 2, 2023" ) -set ( LAGraph_VERSION_MAJOR 1 ) -set ( LAGraph_VERSION_MINOR 0 ) -set ( LAGraph_VERSION_SUB 2 ) +#------------------------------------------------------------------------------- +# define the project +#------------------------------------------------------------------------------- -project ( lagraph +project ( LAGraph VERSION "${LAGraph_VERSION_MAJOR}.${LAGraph_VERSION_MINOR}.${LAGraph_VERSION_SUB}" ) +#------------------------------------------------------------------------------- +# SuiteSparse policies +#------------------------------------------------------------------------------- + +set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} + ${PROJECT_SOURCE_DIR}/cmake_modules + ${PROJECT_SOURCE_DIR}/../cmake_modules + ${PROJECT_SOURCE_DIR}/../SuiteSparse_config/cmake_modules + ) + +include ( SuiteSparsePolicy ) + +enable_language ( C ) + # configure LAGraph.h with the LAGraph date and version configure_file ( "config/LAGraph.h.in" - "${PROJECT_SOURCE_DIR}/include/LAGraph.h" ) + "${PROJECT_SOURCE_DIR}/include/LAGraph.h" + NEWLINE_STYLE LF ) #------------------------------------------------------------------------------- # code coverage and build type @@ -73,30 +87,28 @@ configure_file ( # make test_coverage if ( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") - if ( COVERAGE ) - message ( STATUS "============== Code coverage enabled ===============" ) - set ( CMAKE_BUILD_TYPE Debug ) - # On the Mac, you need gcov-11 from homebrew (part of gcc-11): - # and uncomment this line: - # set ( GCOV_PATH /usr/local/bin/gcov-11) - include ( CodeCoverage ) - - append_coverage_compiler_flags ( ) - - # turn off optimization for non-skewed coverage reports - set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -DCOVERAGE" ) - set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0" ) - - setup_target_for_coverage_lcov ( - NAME test_coverage - EXECUTABLE ctest - DEPENDENCIES ${PROJECT_NAME} - BASE_DIRECTORY "." - NO_DEMANGLE TRUE - EXCLUDE "*/benchmark/*" "deps/json*/*" - "src/test/include/acutest.h" - ) - endif ( ) + if ( COVERAGE ) + message ( STATUS "============== Code coverage enabled ===============" ) + set ( CMAKE_BUILD_TYPE Debug ) + # On the Mac, you need gcov-11 from homebrew (part of gcc-11): + # and uncomment this line: + # set ( GCOV_PATH /usr/local/bin/gcov-11) + include ( CodeCoverage ) + + append_coverage_compiler_flags ( ) + + # turn off optimization for non-skewed coverage reports + set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -DCOVERAGE" ) + + setup_target_for_coverage_lcov ( + NAME test_coverage + EXECUTABLE ctest + DEPENDENCIES ${PROJECT_NAME} + BASE_DIRECTORY "." + NO_DEMANGLE TRUE + EXCLUDE "*/benchmark/*" "deps/json*/*" "src/test/include/acutest.h" + ) + endif ( ) endif ( ) # For development only, not for end-users: @@ -110,37 +122,80 @@ endif ( ) # Find the GraphBLAS installation #------------------------------------------------------------------------------- -# If GraphBLAS is not in a standard installation location, either -# export GRAPHBLAS_ROOT -# or -# GRAPHBLAS_ROOT= cmake .. -# or uncomment the next line: -# set ( ENV{GRAPHBLAS_ROOT} ${CMAKE_SOURCE_DIR}/../GraphBLAS ) -message ( STATUS "GraphBLAS_ROOT: ${GraphBLAS_ROOT} $ENV{GraphBLAS_ROOT}" ) -message ( STATUS "GRAPHBLAS_ROOT: ${GRAPHBLAS_ROOT} $ENV{GRAPHBLAS_ROOT}" ) -find_package (GraphBLAS 7.0.1 REQUIRED MODULE) +if ( SUITESPARSE_ROOT_CMAKELISTS ) + + if ( TARGET GraphBLAS ) + add_library ( GraphBLAS::GraphBLAS ALIAS GraphBLAS ) + else ( ) + add_library ( GraphBLAS::GraphBLAS ALIAS GraphBLAS_static ) + endif ( ) + if ( TARGET GraphBLAS_static ) + add_library ( GraphBLAS::GraphBLAS_static ALIAS GraphBLAS_static ) + endif ( ) + +else ( ) + + # If GraphBLAS is not in a standard installation location, either + # export GRAPHBLAS_ROOT + # or + # GRAPHBLAS_ROOT= cmake .. + # or uncomment the next line: + # set ( ENV{GRAPHBLAS_ROOT} ${PROJECT_SOURCE_DIR}/../GraphBLAS ) + + # The ../GraphBLAS folder is considered by default, if it exists. + +# message ( STATUS "GraphBLAS_ROOT: ${GraphBLAS_ROOT} $ENV{GraphBLAS_ROOT}" ) +# message ( STATUS "GRAPHBLAS_ROOT: ${GRAPHBLAS_ROOT} $ENV{GRAPHBLAS_ROOT}" ) + + # No package version is explicitly stated here; an arbitrary GraphBLAS + # library can have any version number. For SuiteSparse:GraphBLAS, LAGraph + # requires v7.1.0 or later, which is checked in LAGraph.h. + find_package ( GraphBLAS MODULE REQUIRED ) + +endif ( ) #------------------------------------------------------------------------------- # determine what user threading model to use #------------------------------------------------------------------------------- +option ( LAGRAPH_USE_OPENMP "ON: Use OpenMP in LAGraph if available. OFF: Do not use OpenMP. (Default: SUITESPARSE_USE_OPENMP)" ${SUITESPARSE_USE_OPENMP} ) +if ( NOT SUITESPARSE_USE_OPENMP ) + set ( LAGRAPH_USE_OPENMP "OFF" CACHE STRING "" FORCE ) +endif ( ) if ( COVERAGE ) + set ( LAGRAPH_USE_OPENMP "OFF" CACHE STRING "" FORCE ) # OK: test coverage is enabled message ( STATUS "OpenMP disabled for test coverage" ) else ( ) - include ( FindOpenMP ) - include ( FindThreads ) - if ( OPENMP_FOUND ) - set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS} " ) + if ( LAGRAPH_USE_OPENMP ) + find_package ( OpenMP GLOBAL ) + if ( OpenMP_C_FOUND AND BUILD_STATIC_LIBS ) + list ( APPEND LAGRAPH_STATIC_LIBS ${OpenMP_C_LIBRARIES} ) + endif ( ) + find_package ( Threads ) + else ( ) + set ( OpenMP_C_FOUND OFF ) endif ( ) endif ( ) +if ( OpenMP_C_FOUND ) + set ( LAGRAPH_HAS_OPENMP ON ) +else ( ) + set ( LAGRAPH_HAS_OPENMP OFF ) +endif ( ) +message ( STATUS "LAGraph has OpenMP: ${LAGRAPH_HAS_OPENMP}" ) + +# check for strict usage +if ( SUITESPARSE_USE_STRICT AND LAGRAPH_USE_OPENMP AND NOT LAGRAPH_HAS_OPENMP ) + message ( FATAL_ERROR "OpenMP required for LAGraph but not found" ) +endif ( ) + #------------------------------------------------------------------------------- # report status #------------------------------------------------------------------------------- message ( STATUS "CMAKE build type: " ${CMAKE_BUILD_TYPE} ) -message ( STATUS "CMAKE source directory: " ${CMAKE_SOURCE_DIR} ) -message ( STATUS "CMAKE build directory: " ${CMAKE_BINARY_DIR} ) +message ( STATUS "CMAKE source directory: " ${PROJECT_SOURCE_DIR} ) +message ( STATUS "CMAKE build directory: " ${PROJECT_BINARY_DIR} ) if ( ${CMAKE_BUILD_TYPE} STREQUAL "Debug") message ( STATUS "CMAKE C Flags debug: " ${CMAKE_C_FLAGS_DEBUG} ) @@ -152,34 +207,27 @@ message ( STATUS "CMAKE compiler ID: " ${CMAKE_C_COMPILER_ID} ) message ( STATUS "CMAKE thread library: " ${CMAKE_THREAD_LIBS_INIT} ) message ( STATUS "CMAKE have pthreads: " ${CMAKE_USE_PTHREADS_INIT} ) message ( STATUS "CMAKE have Win32 pthreads: " ${CMAKE_USE_WIN32_THREADS_INIT} ) -message ( STATUS "CMAKE have OpenMP: " ${OPENMP_FOUND} ) +message ( STATUS "CMAKE have OpenMP: " ${OPENMP_C_FOUND} ) #------------------------------------------------------------------------------- # include directories for LAGraph library #------------------------------------------------------------------------------- -include_directories ( ${CMAKE_SOURCE_DIR}/include - ${CMAKE_SOURCE_DIR}/src/utility - ${CMAKE_SOURCE_DIR}/test/include - ${GRAPHBLAS_INCLUDE_DIR} ) -include_directories ( "/usr/local/include" ) +include_directories ( ${PROJECT_SOURCE_DIR}/include + ${PROJECT_SOURCE_DIR}/src/utility + ${PROJECT_SOURCE_DIR}/test/include ) # tell LAGraph where to find its own source (for LAGraph/data files) -set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DLGDIR=${CMAKE_SOURCE_DIR}" ) +set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DLGDIR=${PROJECT_SOURCE_DIR}" ) +# set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O" ) #------------------------------------------------------------------------------- # compiler options #------------------------------------------------------------------------------- -set(CMAKE_C_STANDARD 11) -set(CMAKE_C_STANDARD_REQUIRED True) - # check which compiler is being used. If you need to make # compiler-specific modifications, here is the place to do it. if ( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") - # cmake 2.8 workaround: gcc needs to be told to do ANSI C11. - # cmake 3.0 doesn't have this problem. - set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -lm -Wno-pragmas " ) # check all warnings: # set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wpedantic -Werror " ) # set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g " ) @@ -187,11 +235,9 @@ if ( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") # message ( FATAL_ERROR "gcc version must be at least 4.9" ) #endif ( ) elseif ( "${CMAKE_C_COMPILER_ID}" STREQUAL "Intel" ) - # options for icc: also needs -std=c11 # note that -g can be used, for VTune. Comment out the following line # to compile without -g. # set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g " ) - set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 " ) # check all warnings: # set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w3 " ) #if ( CMAKE_C_COMPILER_VERSION VERSION_LESS 18.0 ) @@ -199,7 +245,7 @@ elseif ( "${CMAKE_C_COMPILER_ID}" STREQUAL "Intel" ) #endif ( ) elseif ( "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" ) # options for clang - set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -std=c11 " ) + set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 " ) #if ( CMAKE_C_COMPILER_VERSION VERSION_LESS 3.3 ) # message ( FATAL_ERROR "clang version must be at least 3.3" ) #endif ( ) @@ -207,8 +253,7 @@ elseif ( "${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC" ) # options for MicroSoft Visual Studio elseif ( "${CMAKE_C_COMPILER_ID}" STREQUAL "PGI" ) # options for PGI pgcc compiler - set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -acc -Minfo=accel -Mcuda -Mnoopenmp -noswitcherror -c11 -lm -fPIC " ) - set ( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -acc -Minfo=accel -Mcuda -Mnoopenmp -D__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1 -noswitcherror --c++11 -lm -fPIC " ) + set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -acc -Minfo=accel -Mcuda -Mnoopenmp -noswitcherror -fPIC " ) endif ( ) if ( ${CMAKE_BUILD_TYPE} STREQUAL "Debug") @@ -238,11 +283,7 @@ message ( STATUS "CMAKE C flags: " ${CMAKE_C_FLAGS} ) # enable testing and add subdirectories #------------------------------------------------------------------------------- -# allow ctest to find the binaries: -set ( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} ) -set ( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} ) - -enable_testing ( ) +include ( CTest ) add_subdirectory ( src ) add_subdirectory ( experimental ) @@ -254,17 +295,128 @@ endif ( ) # LAGraph installation location #------------------------------------------------------------------------------- -# install in ${CMAKE_INSTALL_PREFIX}/lib and ${CMAKE_INSTALL_PREFIX}/include. -# Requires "sudo make install" if this is /usr/local (default). +include ( CMakePackageConfigHelpers ) -message ( STATUS "Installation in: ${CMAKE_INSTALL_PREFIX}" ) -include ( GNUInstallDirs ) +if ( BUILD_SHARED_LIBS ) + install ( TARGETS LAGraph LAGraphX + EXPORT LAGraphTargets + LIBRARY DESTINATION ${SUITESPARSE_LIBDIR} + ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} + RUNTIME DESTINATION ${SUITESPARSE_BINDIR} + PUBLIC_HEADER DESTINATION ${SUITESPARSE_INCLUDEDIR} ) +endif ( ) -install ( TARGETS lagraph lagraphx - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) +if ( BUILD_STATIC_LIBS ) + install ( TARGETS LAGraph_static LAGraphX_static + EXPORT LAGraphTargets + ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} + PUBLIC_HEADER DESTINATION ${SUITESPARSE_INCLUDEDIR} ) +endif ( ) -install ( TARGETS lagraph_static lagraphx_static - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) +# create (temporary) export target file during build +export ( EXPORT LAGraphTargets + NAMESPACE SuiteSparse:: + FILE ${CMAKE_CURRENT_BINARY_DIR}/LAGraphTargets.cmake ) + +# install export target, config and version files for find_package +install ( EXPORT LAGraphTargets + NAMESPACE SuiteSparse:: + DESTINATION ${SUITESPARSE_PKGFILEDIR}/cmake/LAGraph ) + +# generate config file to be used in common build tree +set ( SUITESPARSE_IN_BUILD_TREE ON ) +configure_package_config_file ( + config/LAGraphConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/LAGraphConfig.cmake + INSTALL_DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/LAGraphConfig.cmake ) + +# generate config file to be installed +set ( SUITESPARSE_IN_BUILD_TREE OFF ) +configure_package_config_file ( + config/LAGraphConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/target/LAGraphConfig.cmake + INSTALL_DESTINATION ${SUITESPARSE_PKGFILEDIR}/cmake/LAGraph ) + +write_basic_package_version_file ( + ${CMAKE_CURRENT_BINARY_DIR}/LAGraphConfigVersion.cmake + COMPATIBILITY SameMajorVersion ) + +install ( FILES + ${CMAKE_CURRENT_BINARY_DIR}/target/LAGraphConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/LAGraphConfigVersion.cmake + ${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules/FindGraphBLAS.cmake + DESTINATION ${SUITESPARSE_PKGFILEDIR}/cmake/LAGraph ) + +#------------------------------------------------------------------------------- +# create pkg-config file +#------------------------------------------------------------------------------- + +if ( NOT MSVC ) + if ( BUILD_STATIC_LIBS ) + if ( NOT WIN32 ) + list ( APPEND LAGRAPH_STATIC_LIBS "m" ) + endif ( ) + endif ( ) + # This might be something like: + # /usr/lib/libgomp.so;/usr/lib/libpthread.a;m + # convert to -l flags for pkg-config, i.e.: "-lgomp -lpthread -lm" + set ( LAGRAPH_STATIC_LIBS_LIST ${LAGRAPH_STATIC_LIBS} ) + set ( LAGRAPH_STATIC_LIBS "" ) + foreach ( _lib ${LAGRAPH_STATIC_LIBS_LIST} ) + string ( FIND ${_lib} "." _pos REVERSE ) + if ( ${_pos} EQUAL "-1" ) + set ( LAGRAPH_STATIC_LIBS "${LAGRAPH_STATIC_LIBS} -l${_lib}" ) + continue () + endif ( ) + set ( _kinds "SHARED" "STATIC" ) + if ( WIN32 ) + list ( PREPEND _kinds "IMPORT" ) + endif ( ) + foreach ( _kind IN LISTS _kinds ) + set ( _regex ".*\\/(lib)?([^\\.]*)(${CMAKE_${_kind}_LIBRARY_SUFFIX})" ) + if ( ${_lib} MATCHES ${_regex} ) + string ( REGEX REPLACE ${_regex} "\\2" _libname ${_lib} ) + if ( NOT "${_libname}" STREQUAL "" ) + set ( LAGRAPH_STATIC_LIBS "${LAGRAPH_STATIC_LIBS} -l${_libname}" ) + break () + endif ( ) + endif ( ) + endforeach ( ) + endforeach ( ) + if ( BUILD_STATIC_LIBS ) + set ( LAGRAPH_STATIC_LIBS "-l$ ${LAGRAPH_STATIC_LIBS}" ) + endif ( ) + + set ( prefix "${CMAKE_INSTALL_PREFIX}" ) + set ( exec_prefix "\${prefix}" ) + cmake_path ( IS_ABSOLUTE SUITESPARSE_LIBDIR SUITESPARSE_LIBDIR_IS_ABSOLUTE ) + if (SUITESPARSE_LIBDIR_IS_ABSOLUTE) + set ( libdir "${SUITESPARSE_LIBDIR}") + else ( ) + set ( libdir "\${exec_prefix}/${SUITESPARSE_LIBDIR}") + endif ( ) + cmake_path ( IS_ABSOLUTE SUITESPARSE_INCLUDEDIR SUITESPARSE_INCLUDEDIR_IS_ABSOLUTE ) + if (SUITESPARSE_INCLUDEDIR_IS_ABSOLUTE) + set ( includedir "${SUITESPARSE_INCLUDEDIR}") + else ( ) + set ( includedir "\${prefix}/${SUITESPARSE_INCLUDEDIR}") + endif ( ) + if ( BUILD_SHARED_LIBS ) + set ( SUITESPARSE_LIB_BASE_NAME $ ) + else ( ) + set ( SUITESPARSE_LIB_BASE_NAME $ ) + endif ( ) + configure_file ( + config/LAGraph.pc.in + LAGraph.pc.out + @ONLY + NEWLINE_STYLE LF ) + file ( GENERATE + OUTPUT LAGraph.pc + INPUT ${CMAKE_CURRENT_BINARY_DIR}/LAGraph.pc.out + NEWLINE_STYLE LF ) + install ( FILES + ${CMAKE_CURRENT_BINARY_DIR}/LAGraph.pc + DESTINATION ${SUITESPARSE_PKGFILEDIR}/pkgconfig ) +endif ( ) diff --git a/ChangeLog b/ChangeLog index fb7e628499..c88d5f479d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Dec 30, 2023: version 1.1.0 + + * major change to build system: by Markus Mützel + * port: to 32-bit systems + Version 1.0.2: Aug 2, 2023 * port: removed GxB_SelectOp so LAGraph v1.0.2 can be compiled with diff --git a/Contributors.txt b/Contributors.txt index 4e2f47c319..367ebe60fd 100644 --- a/Contributors.txt +++ b/Contributors.txt @@ -22,9 +22,10 @@ Contributors (in alphabetical order): Tze Meng Low, Carnegie Mellon University Tim Mattson, Intel Scott McMillan, Carnegie Mellon University + Markus Muetzel, Michel Pelletier, Graphegon Gabor Szarnyas, CWI Amsterdam, The Netherlands Erik Welch, Anaconda, NVIDIA - Carl Yang, University of Californie at Davis, Waymo + Carl Yang, University of California at Davis, Waymo Yongzhe Zhang, SOKENDAI, Japan diff --git a/Makefile b/Makefile index 7d22a3dcbc..2f91ff5fc4 100644 --- a/Makefile +++ b/Makefile @@ -51,30 +51,44 @@ JOBS ?= 8 default: library library: - ( cd build && cmake $(CMAKE_OPTIONS) .. && $(MAKE) --jobs=${JOBS} ) + ( cd build && cmake $(CMAKE_OPTIONS) .. && cmake --build . --config Release -j${JOBS} ) + +# install only in SuiteSparse/lib and SuiteSparse/include +local: + ( cd build && cmake $(CMAKE_OPTIONS) -USUITESPARSE_PKGFILEDIR -DSUITESPARSE_LOCAL_INSTALL=1 .. && cmake --build . --config Release -j${JOBS} ) + +# install CMAKE_INSTALL_PREFIX +global: + ( cd build && cmake $(CMAKE_OPTIONS) -USUITESPARSE_PKGFILEDIR -DSUITESPARSE_LOCAL_INSTALL=0 .. && cmake --build . --config Release -j${JOBS} ) vanilla: - ( cd build && cmake $(CMAKE_OPTIONS) -DLAGRAPH_VANILLA=1 .. && $(MAKE) --jobs=${JOBS} ) + ( cd build && cmake $(CMAKE_OPTIONS) -USUITESPARSE_PKGFILEDIR -DLAGRAPH_VANILLA=1 .. && cmake --build . --config Release -j${JOBS} ) # compile with -g for debugging debug: - ( cd build && cmake $(CMAKE_OPTIONS) -DCMAKE_BUILD_TYPE=Debug .. && $(MAKE) --jobs=${JOBS} ) + ( cd build && cmake $(CMAKE_OPTIONS) -DCMAKE_BUILD_TYPE=Debug .. && cmake --build . --config Release -j${JOBS} ) all: library test: library - ( cd build && make test ) + ( cd build && ctest . || ctest . --rerun-failed --output-on-failure ) + +verbose_test: library + ( cd build && ctest . --verbose || ctest . --rerun-failed --output-on-failure ) + +# target used in CI +demos: test # just compile after running cmake; do not run cmake again remake: - ( cd build && $(MAKE) --jobs=${JOBS} ) + ( cd build && cmake --build . --config Release -j${JOBS} ) # just run cmake to set things up setup: ( cd build ; cmake $(CMAKE_OPTIONS) .. ) install: - ( cd build ; $(MAKE) install ) + ( cd build ; cmake --install . ) # remove any installed libraries and #include files uninstall: @@ -82,7 +96,7 @@ uninstall: # clean, compile, and run test coverage cov: distclean - ( cd build && cmake -DCOVERAGE=1 .. && $(MAKE) --jobs=${JOBS} && make test_coverage ) + ( cd build && cmake -DCOVERAGE=1 .. && cmake --build . --config Release -j${JOBS} && cmake --build . --target test_coverage ) # remove all files not in the distribution clean: distclean diff --git a/cmake_modules/CodeCoverage.cmake b/cmake_modules/CodeCoverage.cmake index a0ebde1173..2d5fcfb448 100644 --- a/cmake_modules/CodeCoverage.cmake +++ b/cmake_modules/CodeCoverage.cmake @@ -134,7 +134,7 @@ find_program( GCOV_PATH gcov ) find_program( LCOV_PATH NAMES lcov lcov.bat lcov.exe lcov.perl) find_program( FASTCOV_PATH NAMES fastcov fastcov.py ) find_program( GENHTML_PATH NAMES genhtml genhtml.perl genhtml.bat ) -find_program( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test) +find_program( GCOVR_PATH gcovr PATHS ${PROJECT_SOURCE_DIR}/scripts/test) find_program( CPPFILT_PATH NAMES c++filt ) execute_process( diff --git a/cmake_modules/FindGraphBLAS.cmake b/cmake_modules/FindGraphBLAS.cmake index b6e7d19894..086eaf4351 100644 --- a/cmake_modules/FindGraphBLAS.cmake +++ b/cmake_modules/FindGraphBLAS.cmake @@ -9,13 +9,13 @@ SPDX-License-Identifier: BSD-2-Clause See additional acknowledgments in the LICENSE file, or contact permission@sei.cmu.edu for the full terms. -Find the native GRAPHBLAS includes and library. +Find the native GraphBLAS includes and library. IMPORTED Targets ^^^^^^^^^^^^^^^^ -This module defines :prop_tgt:`IMPORTED` target ``GRAPHBLAS::GRAPHBLAS``, if -GRAPHBLAS has been found. +This module defines :prop_tgt:`IMPORTED` target ``GraphBLAS::GraphBLAS``, if +GraphBLAS has been found. Result Variables ^^^^^^^^^^^^^^^^ @@ -35,75 +35,230 @@ This module defines the following variables: Hints ^^^^^ -A user may set ``GRAPHBLAS_ROOT`` or ``GraphBLAS_ROOT`` to a GraphBLAS -installation root to tell this module where to look. +A user may set ``GraphBLAS_ROOT`` to a GraphBLAS installation root to tell this +module where to look (for cmake 3.27, you may also use ``GRAPHBLAS_ROOT``). -Otherwise, the first place searched is in ../GraphBLAS, relative to the LAGraph -source directory. That is, if GraphBLAS and LAGraph reside in the same parent -folder, side-by-side, and if it contains GraphBLAS/Include/GraphBLAS.h file and -GraphBLAS/build/libgraphblas.so (or dylib, etc), then that version is used. -This takes precedence over the system-wide installation of GraphBLAS, which -might be an older version. This method gives the user the ability to compile -LAGraph with their own copy of GraphBLAS, ignoring the system-wide version. +First, a GraphBLASConfig.cmake file is searched in the LAGraph/build or +../GraphBLAS/build folder. If that is not found, a search is made for +GraphBLASConfig.cmake in the standard places that CMake looks. +SuiteSparse::GraphBLAS v8.2.0 and following create a GraphBLASConfig.cmake +file, and other GraphBLAS libraries may do the same. -If SuiteSparse:GraphBLAS is the GraphBLAS library being utilized, -all the Find*.cmake files in SuiteSparse are installed by 'make install' into -/usr/local/lib/cmake/SuiteSparse (where '/usr/local' is the -${CMAKE_INSTALL_PREFIX}). To access this file, place the following commands -in your CMakeLists.txt file. See also SuiteSparse/Example/CMakeLists.txt: +If the GraphBLASConfig.cmake file is not found, the GraphBLAS.h include file +and compiled GraphBLAS library are searched for in the places given by +GraphBLAS_ROOT, GRAPHBLAS_ROOT, LAGraph/.., LAGraph/../GraphBLAS, or +LAGraph/../SuiteSparse/GraphBLAS. This will find SuiteSparse:GraphBLAS +versions 8.0.x and later, or it may find another GraphBLAS library that does +not provide a GraphBLASConfig.cmake file. - set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} - ${CMAKE_INSTALL_PREFIX}/lib/cmake/SuiteSparse ) +If SuiteSparse:GraphBLAS is used, all the *Config.cmake files in SuiteSparse +are installed by 'make install' into the default location when compiling +SuiteSparse. CMake should know where to find them. + +SuiteSparse:GraphBLAS also comes in many Linux distros, spack, brew, conda, +etc. Try: + + apt search libsuitesparse-dev + spack info suite-sparse + brew info suite-sparse + conda search -c conda-forge graphblas + +If GraphBLAS is not found, or if a different version is found than what was +expected, you can enable the LAGRAPH_DUMP option to display the places where +CMake looks. #]=======================================================================] +option ( LAGRAPH_DUMP "ON: display list of places to search. OFF (default): no debug output" OFF ) + # NB: this is built around assumptions about one particular GraphBLAS # installation (SuiteSparse:GraphBLAS). As other installations become available # changes to this will likely be required. +#------------------------------------------------------------------------------- +# find GraphBLASConfig.make in ../GraphBLAS (typically inside SuiteSparse): +#------------------------------------------------------------------------------- + +if ( LAGRAPH_DUMP AND NOT GraphBLAS_DIR ) + message ( STATUS "(1) Looking for GraphBLASConfig.cmake in... : + CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR} + PROJECT_SOURCE_DIR/../GraphBLAS/build: ${PROJECT_SOURCE_DIR}/../GraphBLAS/build" ) +endif ( ) + +find_package ( GraphBLAS ${GraphBLAS_FIND_VERSION} CONFIG + PATHS ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/../GraphBLAS/build + NO_DEFAULT_PATH ) + +set ( _lagraph_gb_common_tree ON ) + +#------------------------------------------------------------------------------- +# if not yet found, look for GraphBLASConfig.cmake in the standard places +#------------------------------------------------------------------------------- + +if ( LAGRAPH_DUMP AND NOT TARGET SuiteSparse::GraphBLAS ) +message ( STATUS "(2) Looking for GraphBLASConfig.cmake in these places (in order): + GraphBLAS_ROOT: ${GraphBLAS_ROOT}" ) +if ( CMAKE_VERSION VERSION_GREATER_EQUAL "3.27" ) + message ( STATUS " + GRAPHBLAS_ROOT: ${GRAPHBLAS_ROOT}" ) +endif ( ) + message ( STATUS " + ENV GraphBLAS_ROOT: $ENV{GraphBLAS_ROOT}" ) +if ( CMAKE_VERSION VERSION_GREATER_EQUAL "3.27" ) + message ( STATUS " + ENV GRAPHBLAS_ROOT: $ENV{GRAPHBLAS_ROOT}" ) +endif ( ) +message ( STATUS " + CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH} + CMAKE_FRAMEWORK_PATH: ${CMAKE_FRAMEWORK_PATH} + CMAKE_APPBUNDLE_PATH: ${CMAKE_APPBUNDLE_PATH} + ENV GraphBLAS_DIR: $ENV{GraphBLAS_DIR} + ENV CMAKE_PREFIX_PATH: $ENV{CMAKE_PREFIX_PATH} + ENV CMAKE_FRAMEWORK_PATH: $ENV{CMAKE_FRAMEWORK_PATH} + ENV CMAKE_APPBUNDLE_PATH: $ENV{CMAKE_APPBUNDLE_PATH} + ENV PATH: $ENV{PATH} + CMake user package registry: (see cmake documentation) + CMAKE_SYSTEM_PREFIX_PATH: ${CMAKE_SYSTEM_PREFIX_PATH} + CMAKE_SYSTEM_FRAMEWORK_PATH: ${CMAKE_SYSTEM_FRAMEWORK_PATH} + CMAKE_SYSTEM_APPBUNDLE_PATH: ${CMAKE_SYSTEM_APPBUNDLE_PATH} + CMake system package registry: (see cmake documentation)" + ) +endif ( ) + +if ( NOT TARGET SuiteSparse::GraphBLAS ) + find_package ( GraphBLAS ${GraphBLAS_FIND_VERSION} CONFIG ) + set ( _lagraph_gb_common_tree OFF ) +endif ( ) + +if ( GraphBLAS_FOUND ) + if ( TARGET SuiteSparse::GraphBLAS ) + # It's not possible to create an alias of an alias. + get_property ( _graphblas_aliased TARGET SuiteSparse::GraphBLAS + PROPERTY ALIASED_TARGET ) + if ( GRAPHBLAS_VERSION LESS "8.3.0" AND _lagraph_gb_common_tree ) + # workaround for incorrect INTERFACE_INCLUDE_DIRECTORIES of + # SuiteSparse:GraphBLAS 8.2.x before installation + # (did not have "/Include") + get_property ( _inc TARGET SuiteSparse::GraphBLAS PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ) + if ( IS_DIRECTORY ${_inc}/Include ) + if ( "${_graphblas_aliased}" STREQUAL "" ) + target_include_directories ( SuiteSparse::GraphBLAS INTERFACE + ${_inc}/Include ) + else ( ) + target_include_directories ( ${_graphblas_aliased} INTERFACE + ${_inc}/Include ) + endif ( ) + message ( STATUS "additional include: ${_inc}/Include" ) + endif ( ) + endif ( ) + if ( "${_graphblas_aliased}" STREQUAL "" ) + add_library ( GraphBLAS::GraphBLAS ALIAS SuiteSparse::GraphBLAS ) + else ( ) + add_library ( GraphBLAS::GraphBLAS ALIAS ${_graphblas_aliased} ) + endif ( ) + endif ( ) + if ( TARGET SuiteSparse::GraphBLAS_static ) + # It's not possible to create an alias of an alias. + get_property ( _graphblas_aliased TARGET SuiteSparse::GraphBLAS_static + PROPERTY ALIASED_TARGET ) + if ( GRAPHBLAS_VERSION LESS "8.3.0" AND _lagraph_gb_common_tree ) + # workaround for incorrect INTERFACE_INCLUDE_DIRECTORIES of + # SuiteSparse:GraphBLAS 8.2.x before installation + # (did not have "/Include") + get_property ( _inc TARGET SuiteSparse::GraphBLAS_static PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ) + if ( IS_DIRECTORY ${_inc}/Include ) + if ( "${_graphblas_aliased}" STREQUAL "" ) + target_include_directories ( SuiteSparse::GraphBLAS_static INTERFACE + ${_inc}/Include ) + else ( ) + target_include_directories ( ${_graphblas_aliased} INTERFACE + ${_inc}/Include ) + endif ( ) + message ( STATUS "additional include: ${_inc}/Include" ) + endif ( ) + endif ( ) + if ( "${_graphblas_aliased}" STREQUAL "" ) + add_library ( GraphBLAS::GraphBLAS_static ALIAS SuiteSparse::GraphBLAS_static ) + else ( ) + add_library ( GraphBLAS::GraphBLAS_static ALIAS ${_graphblas_aliased} ) + endif ( ) + endif ( ) + return ( ) +endif ( ) + +#------------------------------------------------------------------------------- +# if still not found, look for GraphBLAS.h and compiled libraries directly +#------------------------------------------------------------------------------- + +# Older versions of SuiteSparse GraphBLAS (8.0 or older) or GraphBLAS libraries +# not from SuiteSparse. + +if ( LAGRAPH_DUMP ) + message ( STATUS "Looking for vanilla GraphBLAS (or older SuiteSparse), + GraphBLAS.h and the compiled GraphBLAS library in: + GraphBLAS_ROOT: ${GraphBLAS_ROOT} + ENV GraphBLAS_ROOT $ENV{GraphBLAS_ROOT} + GRAPHBLAS_ROOT: ${GRAPHBLAS_ROOT} + ENV GRAPHBLAS_ROOT ENV${GRAPHBLAS_ROOT} + PROJECT_SOURCE_DIR/..: ${PROJECT_SOURCE_DIR}/.. + PROJECT_SOURCE_DIR/../GraphBLAS: ${PROJECT_SOURCE_DIR}/../GraphBLAS + PROJECT_SOURCE_DIR/../SuiteSparse/GraphBLAS: ${PROJECT_SOURCE_DIR}/../SuiteSparse/GraphBLAS" + ) +endif ( ) + # "Include" for SuiteSparse:GraphBLAS find_path ( GRAPHBLAS_INCLUDE_DIR NAMES GraphBLAS.h + HINTS ${GraphBLAS_ROOT} + HINTS ENV GraphBLAS_ROOT HINTS ${GRAPHBLAS_ROOT} HINTS ENV GRAPHBLAS_ROOT - HINTS ${CMAKE_SOURCE_DIR}/.. - HINTS ${CMAKE_SOURCE_DIR}/../GraphBLAS - HINTS ${CMAKE_SOURCE_DIR}/../SuiteSparse/GraphBLAS + HINTS ${PROJECT_SOURCE_DIR}/.. + HINTS ${PROJECT_SOURCE_DIR}/../GraphBLAS + HINTS ${PROJECT_SOURCE_DIR}/../SuiteSparse/GraphBLAS PATH_SUFFIXES include Include - ) + NO_DEFAULT_PATH ) # dynamic SuiteSparse:GraphBLAS library find_library ( GRAPHBLAS_LIBRARY NAMES graphblas + HINTS ${GraphBLAS_ROOT} + HINTS ENV GraphBLAS_ROOT HINTS ${GRAPHBLAS_ROOT} HINTS ENV GRAPHBLAS_ROOT - HINTS ${CMAKE_SOURCE_DIR}/.. - HINTS ${CMAKE_SOURCE_DIR}/../GraphBLAS - HINTS ${CMAKE_SOURCE_DIR}/../SuiteSparse/GraphBLAS + HINTS ${PROJECT_SOURCE_DIR}/.. + HINTS ${PROJECT_SOURCE_DIR}/../GraphBLAS + HINTS ${PROJECT_SOURCE_DIR}/../SuiteSparse/GraphBLAS PATH_SUFFIXES lib build alternative - ) + NO_DEFAULT_PATH ) if ( MSVC ) - set ( STATIC_SUFFIX .lib ) set ( STATIC_NAME graphblas_static ) else ( ) - set ( STATIC_SUFFIX .a ) set ( STATIC_NAME graphblas ) endif ( ) # static SuiteSparse:GraphBLAS library set ( save ${CMAKE_FIND_LIBRARY_SUFFIXES} ) -set ( CMAKE_FIND_LIBRARY_SUFFIXES ${STATIC_SUFFIX} ${CMAKE_FIND_LIBRARY_SUFFIXES} ) +set ( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX} ) find_library ( GRAPHBLAS_STATIC NAMES ${STATIC_NAME} + HINTS ${GraphBLAS_ROOT} + HINTS ENV GraphBLAS_ROOT HINTS ${GRAPHBLAS_ROOT} HINTS ENV GRAPHBLAS_ROOT - HINTS ${CMAKE_SOURCE_DIR}/.. - HINTS ${CMAKE_SOURCE_DIR}/../GraphBLAS - HINTS ${CMAKE_SOURCE_DIR}/../SuiteSparse/GraphBLAS + HINTS ${PROJECT_SOURCE_DIR}/.. + HINTS ${PROJECT_SOURCE_DIR}/../GraphBLAS + HINTS ${PROJECT_SOURCE_DIR}/../SuiteSparse/GraphBLAS PATH_SUFFIXES lib build alternative - ) + NO_DEFAULT_PATH ) + set ( CMAKE_FIND_LIBRARY_SUFFIXES ${save} ) +if ( MINGW AND GRAPHBLAS_STATIC MATCHES ".*\.dll\.a" ) + set ( GRAPHBLAS_STATIC "" ) +endif ( ) # get version of the library from the dynamic library name get_filename_component ( GRAPHBLAS_LIBRARY ${GRAPHBLAS_LIBRARY} REALPATH ) @@ -114,6 +269,23 @@ string ( ${GRAPHBLAS_FILENAME} ) +if ( GRAPHBLAS_VERSION ) + if ( ${GRAPHBLAS_VERSION} MATCHES "([0-9]+).[0-9]+.[0-9]+" ) + set ( GraphBLAS_VERSION_MAJOR ${CMAKE_MATCH_1} ) + endif ( ) + if ( ${GRAPHBLAS_VERSION} MATCHES "[0-9]+.([0-9]+).[0-9]+" ) + set ( GraphBLAS_VERSION_MINOR ${CMAKE_MATCH_1} ) + endif ( ) + if ( ${GRAPHBLAS_VERSION} MATCHES "[0-9]+.[0-9]+.([0-9]+)" ) + set ( GraphBLAS_VERSION_PATCH ${CMAKE_MATCH_1} ) + endif ( ) + if ( LAGRAPH_DUMP ) + message ( STATUS "major: ${GraphBLAS_VERSION_MAJOR}" ) + message ( STATUS "minor: ${GraphBLAS_VERSION_MINOR}" ) + message ( STATUS "patch: ${GraphBLAS_VERSION_PATCH}" ) + endif ( ) +endif ( ) + # set ( GRAPHBLAS_VERSION "" ) if ( EXISTS "${GRAPHBLAS_INCLUDE_DIR}" AND NOT GRAPHBLAS_VERSION ) # if the version does not appear in the filename, read the include file @@ -123,13 +295,15 @@ if ( EXISTS "${GRAPHBLAS_INCLUDE_DIR}" AND NOT GRAPHBLAS_VERSION ) REGEX "define GxB_IMPLEMENTATION_MINOR" ) file ( STRINGS ${GRAPHBLAS_INCLUDE_DIR}/GraphBLAS.h GRAPHBLAS_PATCH_STR REGEX "define GxB_IMPLEMENTATION_SUB" ) - message ( STATUS "major: ${GRAPHBLAS_MAJOR_STR}" ) - message ( STATUS "minor: ${GRAPHBLAS_MINOR_STR}" ) - message ( STATUS "patch: ${GRAPHBLAS_PATCH_STR}" ) - string ( REGEX MATCH "[0-9]+" GRAPHBLAS_MAJOR ${GRAPHBLAS_MAJOR_STR} ) - string ( REGEX MATCH "[0-9]+" GRAPHBLAS_MINOR ${GRAPHBLAS_MINOR_STR} ) - string ( REGEX MATCH "[0-9]+" GRAPHBLAS_PATCH ${GRAPHBLAS_PATCH_STR} ) - set (GRAPHBLAS_VERSION "${GRAPHBLAS_MAJOR}.${GRAPHBLAS_MINOR}.${GRAPHBLAS_PATCH}") + if ( LAGRAPH_DUMP ) + message ( STATUS "major: ${GRAPHBLAS_MAJOR_STR}" ) + message ( STATUS "minor: ${GRAPHBLAS_MINOR_STR}" ) + message ( STATUS "patch: ${GRAPHBLAS_PATCH_STR}" ) + endif ( ) + string ( REGEX MATCH "[0-9]+" GraphBLAS_VERSION_MAJOR ${GRAPHBLAS_MAJOR_STR} ) + string ( REGEX MATCH "[0-9]+" GraphBLAS_VERSION_MINOR ${GRAPHBLAS_MINOR_STR} ) + string ( REGEX MATCH "[0-9]+" GraphBLAS_VERSION_PATCH ${GRAPHBLAS_PATCH_STR} ) + set (GRAPHBLAS_VERSION "${GraphBLAS_VERSION_MAJOR}.${GraphBLAS_VERSION_MINOR}.${GraphBLAS_VERSION_PATCH}") endif ( ) set ( GRAPHBLAS_LIBRARIES ${GRAPHBLAS_LIBRARY} ) @@ -162,3 +336,72 @@ else ( ) set ( GRAPHBLAS_STATIC "" ) endif ( ) +# Create target from information found + +if ( GRAPHBLAS_LIBRARY ) + message ( STATUS "Create target GraphBLAS::GraphBLAS" ) + # Get library name from filename of library + # This might be something like: + # /usr/lib/libgraphblas.so or /usr/lib/libgraphblas.a or graphblas64 + # convert to library name that can be used with -l flags for pkg-config + set ( GRAPHBLAS_LIBRARY_TMP ${GRAPHBLAS_LIBRARY} ) + string ( FIND ${GRAPHBLAS_LIBRARY} "." _pos REVERSE ) + if ( ${_pos} EQUAL "-1" ) + set ( _graphblas_library_name ${GRAPHBLAS_LIBRARY} ) + else ( ) + set ( _kinds "SHARED" "STATIC" ) + if ( WIN32 ) + list ( PREPEND _kinds "IMPORT" ) + endif ( ) + foreach ( _kind IN LISTS _kinds ) + set ( _regex ".*\\/(lib)?([^\\.]*)(${CMAKE_${_kind}_LIBRARY_SUFFIX})" ) + if ( ${GRAPHBLAS_LIBRARY} MATCHES ${_regex} ) + string ( REGEX REPLACE ${_regex} "\\2" _libname ${GRAPHBLAS_LIBRARY} ) + if ( NOT "${_libname}" STREQUAL "" ) + set ( _graphblas_library_name ${_libname} ) + break () + endif ( ) + endif ( ) + endforeach ( ) + endif ( ) + + add_library ( GraphBLAS::GraphBLAS UNKNOWN IMPORTED ) + set_target_properties ( GraphBLAS::GraphBLAS PROPERTIES + IMPORTED_LOCATION "${GRAPHBLAS_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${GRAPHBLAS_INCLUDE_DIR}" + OUTPUT_NAME ${_graphblas_library_name} ) +endif ( ) + +if ( GRAPHBLAS_STATIC ) + message ( STATUS "Create target GraphBLAS::GraphBLAS_static" ) + # Get library name from filename of library + # This might be something like: + # /usr/lib/libgraphblas.so or /usr/lib/libgraphblas.a or graphblas64 + # convert to library name that can be used with -l flags for pkg-config + set ( GRAPHBLAS_LIBRARY_TMP ${GRAPHBLAS_STATIC} ) + string ( FIND ${GRAPHBLAS_STATIC} "." _pos REVERSE ) + if ( ${_pos} EQUAL "-1" ) + set ( _graphblas_library_name ${GRAPHBLAS_STATIC} ) + else ( ) + set ( _kinds "SHARED" "STATIC" ) + if ( WIN32 ) + list ( PREPEND _kinds "IMPORT" ) + endif ( ) + foreach ( _kind IN LISTS _kinds ) + set ( _regex ".*\\/(lib)?([^\\.]*)(${CMAKE_${_kind}_LIBRARY_SUFFIX})" ) + if ( ${GRAPHBLAS_STATIC} MATCHES ${_regex} ) + string ( REGEX REPLACE ${_regex} "\\2" _libname ${GRAPHBLAS_STATIC} ) + if ( NOT "${_libname}" STREQUAL "" ) + set ( _graphblas_library_name ${_libname} ) + break () + endif ( ) + endif ( ) + endforeach ( ) + endif ( ) + + add_library ( GraphBLAS::GraphBLAS_static UNKNOWN IMPORTED ) + set_target_properties ( GraphBLAS::GraphBLAS_static PROPERTIES + IMPORTED_LOCATION "${GRAPHBLAS_STATIC}" + INTERFACE_INCLUDE_DIRECTORIES "${GRAPHBLAS_INCLUDE_DIR}" + OUTPUT_NAME ${_graphblas_library_name} ) +endif ( ) diff --git a/cmake_modules/FindLAGraph.cmake b/cmake_modules/FindLAGraph.cmake deleted file mode 100644 index b0ea8deada..0000000000 --- a/cmake_modules/FindLAGraph.cmake +++ /dev/null @@ -1,142 +0,0 @@ -#[=======================================================================[.rst: -FindLAGraph --------- - -LAGraph, (c) 2019-2022 by The LAGraph Contributors, All Rights Reserved. -SPDX-License-Identifier: BSD-2-Clause -See additional acknowledgments in the LICENSE file, -or contact permission@sei.cmu.edu for the full terms. - -Find the native LAGRAPH includes and library. - -IMPORTED Targets -^^^^^^^^^^^^^^^^ - -This module defines :prop_tgt:`IMPORTED` target ``LAGRAPH::LAGRAPH``, if -LAGRAPH has been found. - -Result Variables -^^^^^^^^^^^^^^^^ - -This module defines the following variables: - -:: - - LAGRAPH_INCLUDE_DIR - where to find LAGraph.h, etc. - LAGRAPH_LIBRARY - dynamic LAGraph library - LAGRAPH_STATIC - static LAGraph library - LAGRAPH_LIBRARIES - List of libraries when using LAGraph. - LAGRAPH_FOUND - True if LAGraph found. - -:: - -Hints -^^^^^ - -A user may set ``LAGRAPH_ROOT`` to a LAGraph installation root to tell this -module where to look. - -Otherwise, the first place searched is in ../LAGraph, relative to the current -source directory. That is, if the user application and LAGraph reside in the -same parent folder, side-by-side, and if it contains LAGraph/include/LAGraph.h -file and LAGraph/build/lib/liblagraph.so (or dylib, etc), then that version is -used. This takes precedence over the system-wide installation of LAGraph, -which might be an older version. This method gives the user the ability to -compile LAGraph with their own copy of LAGraph, ignoring the system-wide -version. - -#]=======================================================================] - -# "include" for LAGraph -find_path( - LAGRAPH_INCLUDE_DIR - NAMES LAGraph.h - HINTS ${LAGRAPH_ROOT} - HINTS ENV LAGRAPH_ROOT - HINTS ${CMAKE_SOURCE_DIR}/../LAGraph - PATH_SUFFIXES include Include - ) - -# dynamic LAGraph library -find_library( - LAGRAPH_LIBRARY - NAMES lagraph - HINTS ${LAGRAPH_ROOT} - HINTS ENV LAGRAPH_ROOT - HINTS ${CMAKE_SOURCE_DIR}/../LAGraph - PATH_SUFFIXES lib build - ) - -if ( MSVC ) - set ( STATIC_SUFFIX .lib ) -else ( ) - set ( STATIC_SUFFIX .a ) -endif ( ) - -# static LAGraph library -set ( save ${CMAKE_FIND_LIBRARY_SUFFIXES} ) -set ( CMAKE_FIND_LIBRARY_SUFFIXES ${STATIC_SUFFIX} ${CMAKE_FIND_LIBRARY_SUFFIXES} ) -find_library ( LAGRAPH_STATIC - NAMES lagraph - HINTS ${LAGRAPH_ROOT} - HINTS ENV LAGRAPH_ROOT - HINTS ${CMAKE_SOURCE_DIR}/../LAGraph - PATH_SUFFIXES lib build - ) -set ( CMAKE_FIND_LIBRARY_SUFFIXES ${save} ) - -# get version of the library from the dynamic library name -get_filename_component(LAGRAPH_LIBRARY ${LAGRAPH_LIBRARY} REALPATH) -string( - REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" - LAGRAPH_VERSION - ${LAGRAPH_LIBRARY} - ) - -# set ( LAGRAPH_VERSION "" ) -if ( EXISTS "${LAGRAPH_INCLUDE_DIR}" AND NOT LAGRAPH_VERSION ) - # if the version does not appear in the filename, read the include file - file ( STRINGS ${LAGRAPH_INCLUDE_DIR}/LAGraph.h LAGRAPH_MAJOR_STR - REGEX "define LAGRAPH_VERSION_MAJOR " ) - file ( STRINGS ${LAGRAPH_INCLUDE_DIR}/LAGraph.h LAGRAPH_MINOR_STR - REGEX "define LAGRAPH_VERSION_MINOR " ) - file ( STRINGS ${LAGRAPH_INCLUDE_DIR}/LAGraph.h LAGRAPH_PATCH_STR - REGEX "define LAGRAPH_VERSION_UPDATE " ) - message ( STATUS "major: ${LAGRAPH_MAJOR_STR}" ) - message ( STATUS "minor: ${LAGRAPH_MINOR_STR}" ) - message ( STATUS "patch: ${LAGRAPH_PATCH_STR}" ) - string ( REGEX MATCH "[0-9]+" LAGRAPH_MAJOR ${LAGRAPH_MAJOR_STR} ) - string ( REGEX MATCH "[0-9]+" LAGRAPH_MINOR ${LAGRAPH_MINOR_STR} ) - string ( REGEX MATCH "[0-9]+" LAGRAPH_PATCH ${LAGRAPH_PATCH_STR} ) - set (LAGRAPH_VERSION "${LAGRAPH_MAJOR}.${LAGRAPH_MINOR}.${LAGRAPH_PATCH}") -endif ( ) - -set ( LAGRAPH_LIBRARIES ${LAGRAPH_LIBRARY} ) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args( - LAGraph - REQUIRED_VARS LAGRAPH_LIBRARIES LAGRAPH_INCLUDE_DIR - VERSION_VAR LAGRAPH_VERSION - ) - -mark_as_advanced( - LAGRAPH_INCLUDE_DIR - LAGRAPH_LIBRARY - LAGRAPH_STATIC - LAGRAPH_LIBRARIES - ) - -if ( LAGRAPH_FOUND ) - message ( STATUS "LAGraph version: " ${LAGRAPH_VERSION} ) - message ( STATUS "LAGraph include: " ${LAGRAPH_INCLUDE_DIR} ) - message ( STATUS "LAGraph library: " ${LAGRAPH_LIBRARY} ) - message ( STATUS "LAGraph static:: " ${LAGRAPH_STATIC} ) -else ( ) - message ( STATUS "LAGraph not found" ) - set ( LAGRAPH_INCLUDE_DIR "" ) - set ( LAGRAPH_LIBRARIES "" ) - set ( LAGRAPH_LIBRARY "" ) - set ( LAGRAPH_STATIC "" ) -endif ( ) - diff --git a/cmake_modules/SuiteSparsePolicy.cmake b/cmake_modules/SuiteSparsePolicy.cmake new file mode 100644 index 0000000000..f2d132aa74 --- /dev/null +++ b/cmake_modules/SuiteSparsePolicy.cmake @@ -0,0 +1,342 @@ +#------------------------------------------------------------------------------- +# SuiteSparse/SuiteSparse_config/cmake_modules/SuiteSparsePolicy.cmake +#------------------------------------------------------------------------------- + +# Copyright (c) 2022-2023, Timothy A. Davis. All Rights Reserved. +# SPDX-License-Identifier: BSD-3-clause + +#------------------------------------------------------------------------------- + +# SuiteSparse CMake policies. The following parameters can be defined prior +# to including this file: +# +# CMAKE_BUILD_TYPE: if not set, it is set below to "Release". +# To use the "Debug" policy, precede this with +# set ( CMAKE_BUILD_TYPE Debug ) +# +# SUITESPARSE_USE_CUDA: if OFF, CUDA is disabled. if ON, CUDA is enabled, +# if available. Default: ON. +# +# SUITESPARSE_LOCAL_INSTALL: if true, "cmake --install" will install +# into SuiteSparse/lib and SuiteSparse/include. +# if false, "cmake --install" will install into the +# default prefix (or the one configured with +# CMAKE_INSTALL_PREFIX). Requires cmake 3.19. +# This is ignored when using the root CMakeLists.txt. +# Set CMAKE_INSTALL_PREFIX instead. +# Default: OFF +# +# BUILD_SHARED_LIBS: if true, shared libraries are built. +# Default: ON. +# +# BUILD_STATIC_LIBS: if true, static libraries are built. +# Default: ON, except for GraphBLAS, which +# takes a long time to compile so the default for +# GraphBLAS is false. +# +# SUITESPARSE_CUDA_ARCHITECTURES: a string, such as "all" or +# "35;50;75;80" that lists the CUDA architectures to use +# when compiling CUDA kernels with nvcc. The "all" +# option requires cmake 3.23 or later. +# Default: "52;75;80". +# +# BLA_VENDOR and BLA_SIZEOF_INTEGER: By default, SuiteSparse searches for +# the BLAS library in a specific order. If you wish to +# use a specific BLAS library, set both of these with +# (for example): +# -DBLA_VENDOR=Intel10_64lp -DBLA_SIZEOF_INTEGER=4 +# Both settings must appear, or neither. +# Default: neither are defined. +# +# BLA_STATIC: if ON, use static linkage for BLAS and LAPACK. +# Default: not set (that is, the same as OFF) +# +# SUITESPARSE_USE_64BIT_BLAS if true, SuiteSparse will search for both +# 32-bit and 64-bit BLAS. If false, only 32-bit BLAS +# will be searched for. Ignored if BLA_VENDOR and +# BLA_SIZEOF_INTEGER are defined. +# +# SUITESPARSE_C_TO_FORTRAN: a string that defines how C calls Fortran. +# Defaults to "(name,NAME) name" for Windows (lower case, +# no underscore appended to the name), which is the +# system that is most likely not to have a Fortran +# compiler. Defaults to "(name,NAME) name##_" otherwise. +# This setting is only used if no Fortran compiler is +# found. +# +# SUITESPARSE_USE_FORTRAN: if OFF, no Fortan files are compiled, and the +# Fortran language is not enabled in any cmake scripts. +# The built-in cmake script FortranCInterface is skipped. +# This will require SUITESPARSE_C_TO_FORTRAN to be +# defined explicitly, if the defaults are not appropriate +# for your system. +# Default: ON +# +# SUITESPARSE_PKGFILEDIR: Directory where CMake Config and pkg-config files +# will be installed. By default, CMake Config files will +# be installed in the subfolder `cmake` of the directory +# where the (static) libraries will be installed (e.g., +# `lib`). The `.pc` files for pkg-config will be +# installed in the subfolder `pkgconfig` of the directory +# where the (static) libraries will be installed. +# Default: CMAKE_INSTALL_PREFIX, or SuiteSparse/lib if +# SUITESPARSE_LOCAL_INSTALL is enabled. +# +# SUITESPARSE_INCLUDEDIR_POSTFIX : Postfix for installation target of +# header from SuiteSparse. Default: suitesparse, so the +# default include directory is: +# CMAKE_INSTALL_PREFIX/include/suitesparse +# +# SUITESPARSE_USE_STRICT: SuiteSparse has many user-definable settings of the +# form SUITESPARSE_USE_* or (package)_USE_* for some +# particular package. In general, these settings are not +# strict. For example, if SUITESPARSE_USE_OPENMP is +# ON then OpenMP is preferred, but SuiteSparse can be +# used without OpenMP so no error is generated if OpenMP +# is not found. However, if SUITESPARSE_USE_STRICT is +# ON then all *_USE_* settings are treated strictly +# and an error occurs if any are set to ON but the +# corresponding package or setting is not available. The +# *_USE_SYSTEM_* settings are always treated as strict. +# Default: OFF. + +message ( STATUS "Source: ${CMAKE_SOURCE_DIR} ") +message ( STATUS "Build: ${CMAKE_BINARY_DIR} ") + +if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.18.0" ) + cmake_policy ( SET CMP0104 NEW ) # initialize CUDA architectures +endif ( ) + +if ( WIN32 ) + set ( CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS true ) + add_compile_definitions ( _CRT_SECURE_NO_WARNINGS ) +endif ( ) + +enable_language ( C ) +include ( GNUInstallDirs ) + +# add the cmake_modules folder for this package to the module path +set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} + ${CMAKE_SOURCE_DIR}/cmake_modules ) + +# Use OpenMP +option ( SUITESPARSE_USE_OPENMP "ON (default): Use OpenMP if available. OFF: Do not use OpenMP" ON ) + +# strict usage +option ( SUITESPARSE_USE_STRICT "ON: treat all _USE__ settings as strict if they are ON. OFF (default): consider *_USE_* as preferences, not strict" OFF ) + +# build the demos +option ( SUITESPARSE_DEMOS "ON: Build the demo programs. OFF (default): do not build the demo programs." OFF ) + +# BUILD_SHARED_LIBS and BUILD_STATIC_LIBS options +option ( BUILD_SHARED_LIBS "OFF: do not build shared libraries. ON (default): build shared libraries" ON ) + +if ( BUILD_STATIC_LIBS_DEFAULT_OFF ) + option ( BUILD_STATIC_LIBS "OFF (default): do not build static libraries. ON: build static libraries" OFF ) +else ( ) + # For backwards compatibility, use NSTATIC if it is set. + if ( NSTATIC ) + option ( BUILD_STATIC_LIBS "OFF: do not build static libraries. ON (default): build static libraries" OFF ) + else ( ) + option ( BUILD_STATIC_LIBS "OFF: do not build static libraries. ON (default): build static libraries" ON ) + endif ( ) +endif ( ) + +if ( NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS ) + message ( FATAL_ERROR "At least one of BUILD_SHARED_LIBS or BUILD_STATIC_LIBS must be set to ON." ) +endif ( ) + +# installation options +if ( NOT SUITESPARSE_ROOT_CMAKELISTS AND ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.19.0" ) + # the SUITESPARSE_LOCAL_INSTALL option requires cmake 3.19.0 or later + option ( SUITESPARSE_LOCAL_INSTALL "Install in SuiteSparse/lib" OFF ) +else ( ) + set ( SUITESPARSE_LOCAL_INSTALL OFF ) +endif ( ) + +if ( SUITESPARSE_SECOND_LEVEL ) + # some packages in SuiteSparse are in SuiteSparse/Package/Package + set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} + ${CMAKE_SOURCE_DIR}/../../lib/cmake ) +else ( ) + # most packages in SuiteSparse are located in SuiteSparse/Package + set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} + ${CMAKE_SOURCE_DIR}/../lib/cmake ) +endif ( ) + +# allow libraries to "see" each other if they are installed in a non-default LIBRARY_PATH +list ( FIND CMAKE_INSTALL_RPATH "$ORIGIN" _idx ) +if ( _idx LESS 0 ) + # "$ORIGIN" not yet included in CMAKE_INSTALL_RPATH + list ( PREPEND CMAKE_INSTALL_RPATH "$ORIGIN" ) +endif ( ) + +set ( INSIDE_SUITESPARSE OFF ) +if ( NOT SUITESPARSE_ROOT_CMAKELISTS ) + # determine if this Package is inside the SuiteSparse folder + if ( SUITESPARSE_LOCAL_INSTALL ) + # if you do not want to install local copies of SuiteSparse + # packages in SuiteSparse/lib and SuiteSparse/, set + # SUITESPARSE_LOCAL_INSTALL to false in your CMake options. + if ( SUITESPARSE_SECOND_LEVEL ) + # the package is normally located at the 2nd level inside SuiteSparse + # (SuiteSparse/GraphBLAS/GraphBLAS/ for example) + if ( EXISTS ${CMAKE_SOURCE_DIR}/../../SuiteSparse_config ) + set ( INSIDE_SUITESPARSE true ) + endif ( ) + else ( ) + # typical case, the package is at the 1st level inside SuiteSparse + # (SuiteSparse/AMD for example) + if ( EXISTS ${CMAKE_SOURCE_DIR}/../SuiteSparse_config ) + set ( INSIDE_SUITESPARSE true ) + endif ( ) + endif ( ) + + if ( NOT INSIDE_SUITESPARSE ) + message ( FATAL_ERROR "Unsupported layout for local installation. Correct the directory layout or unset SUITESPARSE_LOCAL_INSTALL." ) + endif ( ) + + endif ( ) +endif ( ) + +set ( SUITESPARSE_INCLUDEDIR_POSTFIX "suitesparse" CACHE STRING + "Postfix for installation target of header from SuiteSparse (default: \"suitesparse\")" ) + +if ( SUITESPARSE_LOCAL_INSTALL ) + if ( INSIDE_SUITESPARSE ) + # ../lib and ../include exist: the package is inside SuiteSparse. + # find ( REAL_PATH ...) requires cmake 3.19. + if ( SUITESPARSE_SECOND_LEVEL ) + file ( REAL_PATH ${CMAKE_SOURCE_DIR}/../.. + SUITESPARSE_LOCAL_PREFIX ) + else ( ) + file ( REAL_PATH ${CMAKE_SOURCE_DIR}/.. + SUITESPARSE_LOCAL_PREFIX ) + endif ( ) + endif ( ) + set ( SUITESPARSE_LIBDIR ${SUITESPARSE_LOCAL_PREFIX}/lib ) + set ( SUITESPARSE_INCLUDEDIR ${SUITESPARSE_LOCAL_PREFIX}/include/${SUITESPARSE_INCLUDEDIR_POSTFIX} ) + set ( SUITESPARSE_BINDIR ${SUITESPARSE_LOCAL_PREFIX}/bin ) +else ( ) + set ( SUITESPARSE_LIBDIR ${CMAKE_INSTALL_LIBDIR} ) + set ( SUITESPARSE_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR}/${SUITESPARSE_INCLUDEDIR_POSTFIX} ) + set ( SUITESPARSE_BINDIR ${CMAKE_INSTALL_BINDIR} ) +endif ( ) + +if ( INSIDE_SUITESPARSE ) + # append ../lib to the install and build runpaths + list ( APPEND CMAKE_INSTALL_RPATH ${SUITESPARSE_LIBDIR} ) + list ( APPEND CMAKE_BUILD_RPATH ${SUITESPARSE_LIBDIR} ) +endif ( ) + +set ( SUITESPARSE_PKGFILEDIR ${SUITESPARSE_LIBDIR} CACHE STRING + "Directory where CMake Config and pkg-config files will be installed" ) + +message ( STATUS "Install lib: ${SUITESPARSE_LIBDIR}" ) +message ( STATUS "Install include: ${SUITESPARSE_INCLUDEDIR}" ) +message ( STATUS "Install bin: ${SUITESPARSE_BINDIR}" ) +message ( STATUS "Install pkg-file: ${SUITESPARSE_PKGFILEDIR}" ) +message ( STATUS "Install rpath: ${CMAKE_INSTALL_RPATH}" ) +message ( STATUS "Build rpath: ${CMAKE_BUILD_RPATH}" ) + +if ( NOT CMAKE_BUILD_TYPE ) + set ( CMAKE_BUILD_TYPE Release ) +endif ( ) + +message ( STATUS "Build type: ${CMAKE_BUILD_TYPE} ") + +set ( CMAKE_INCLUDE_CURRENT_DIR ON ) + +#------------------------------------------------------------------------------- +# check if Fortran is available and enabled +#------------------------------------------------------------------------------- + +include ( CheckLanguage ) +option ( SUITESPARSE_USE_FORTRAN "ON (default): use Fortran. OFF: do not use Fortran" ON ) +if ( SUITESPARSE_USE_FORTRAN ) + check_language ( Fortran ) + if ( CMAKE_Fortran_COMPILER ) + enable_language ( Fortran ) + message ( STATUS "Fortran: ${CMAKE_Fortran_COMPILER}" ) + set ( SUITESPARSE_HAS_FORTRAN ON ) + else ( ) + # Fortran not available: + set ( SUITESPARSE_HAS_FORTRAN OFF ) + message ( STATUS "Fortran: not available" ) + endif ( ) +else ( ) + message ( STATUS "Fortran: not enabled" ) + set ( SUITESPARSE_HAS_FORTRAN OFF ) +endif ( ) + +# check for strict usage +if ( SUITESPARSE_USE_STRICT AND SUITESPARSE_USE_FORTRAN AND NOT SUITESPARSE_HAS_FORTRAN ) + message ( FATAL_ERROR "Fortran required for SuiteSparse but not found" ) +endif ( ) + +# default C-to-Fortran name mangling if Fortran compiler not found +if ( MSVC ) + # MS Visual Studio Fortran compiler does not mangle the Fortran name + set ( SUITESPARSE_C_TO_FORTRAN "(name,NAME) name" + CACHE STRING "C to Fortan name mangling" ) +else ( ) + # Other systems (Linux, Mac) typically append an underscore + set ( SUITESPARSE_C_TO_FORTRAN "(name,NAME) name##_" + CACHE STRING "C to Fortan name mangling" ) +endif ( ) + +#------------------------------------------------------------------------------- +# find CUDA +#------------------------------------------------------------------------------- + +option ( SUITESPARSE_USE_CUDA "ON (default): enable CUDA acceleration for SuiteSparse, OFF: do not use CUDA" ON ) + +if ( SUITESPARSE_USE_CUDA ) + + # try finding CUDA + check_language ( CUDA ) + # message ( STATUS "Looking for CUDA" ) + if ( CMAKE_CUDA_COMPILER ) + # with CUDA: + # message ( STATUS "Find CUDA tool kit:" ) + # FindCUDAToolKit needs to have C or CXX enabled first (see above) + find_package ( CUDAToolkit ) + message ( STATUS "CUDA toolkit : " ${CUDAToolkit_FOUND} ) + message ( STATUS "CUDA toolkit ver: " ${CUDAToolkit_VERSION} ) + message ( STATUS "CUDA toolkit inc: " ${CUDAToolkit_INCLUDE_DIRS} ) + message ( STATUS "CUDA toolkit lib: " ${CUDAToolkit_LIBRARY_DIR} ) + if ( CUDAToolkit_VERSION VERSION_LESS "11.2" ) + # CUDA is present but too old + message ( STATUS "CUDA: not enabled (CUDA 11.2 or later required)" ) + set ( SUITESPARSE_HAS_CUDA OFF ) + else ( ) + # CUDA 11.2 or later present + enable_language ( CUDA ) + set ( SUITESPARSE_HAS_CUDA ON ) + endif ( ) + else ( ) + # without CUDA: + message ( STATUS "CUDA: not found" ) + set ( SUITESPARSE_HAS_CUDA OFF ) + endif ( ) + +else ( ) + + # CUDA is disabled + set ( SUITESPARSE_HAS_CUDA OFF ) + +endif ( ) + +if ( SUITESPARSE_HAS_CUDA ) + message ( STATUS "CUDA: enabled" ) + set ( SUITESPARSE_CUDA_ARCHITECTURES "52;75;80" CACHE STRING "CUDA architectures" ) + set ( CMAKE_CUDA_ARCHITECTURES ${SUITESPARSE_CUDA_ARCHITECTURES} ) +else ( ) + message ( STATUS "CUDA: not enabled" ) +endif ( ) + +# check for strict usage +if ( SUITESPARSE_USE_STRICT AND SUITESPARSE_USE_CUDA AND NOT SUITESPARSE_HAS_CUDA ) + message ( FATAL_ERROR "CUDA required for SuiteSparse but not found" ) +endif ( ) + diff --git a/config/LAGraph.h.in b/config/LAGraph.h.in index d49f1115eb..2fb2eef1df 100644 --- a/config/LAGraph.h.in +++ b/config/LAGraph.h.in @@ -2,7 +2,7 @@ // LAGraph.h: user-visible include file for LAGraph //------------------------------------------------------------------------------ -// LAGraph, (c) 2019-2022 by The LAGraph Contributors, All Rights Reserved. +// LAGraph, (c) 2019-2023 by The LAGraph Contributors, All Rights Reserved. // SPDX-License-Identifier: BSD-2-Clause // // For additional details (including references to third party source code and @@ -66,17 +66,17 @@ #error "The GraphBLAS library must support the v2.0 C API Specification" #endif -#if ( _MSC_VER && !__INTEL_COMPILER ) +#if ( _MSC_VER && !__INTEL_COMPILER && LG_DLL ) #ifdef LG_LIBRARY // compiling LAGraph itself, exporting symbols to user apps - #define LAGRAPH_PUBLIC extern __declspec ( dllexport ) + #define LAGRAPH_PUBLIC __declspec ( dllexport ) #else // compiling the user application, importing symbols from LAGraph - #define LAGRAPH_PUBLIC extern __declspec ( dllimport ) + #define LAGRAPH_PUBLIC __declspec ( dllimport ) #endif #else // for other compilers - #define LAGRAPH_PUBLIC extern + #define LAGRAPH_PUBLIC #endif #if defined ( __cplusplus ) @@ -98,6 +98,9 @@ #if ( !LAGRAPH_VANILLA ) && defined ( GxB_SUITESPARSE_GRAPHBLAS ) // use SuiteSparse, and its GxB* extensions + #if GxB_IMPLEMENTATION < GxB_VERSION (7,1,0) + #error "If using SuiteSparse::GraphBLAS, version 7.1.0 or later is required" + #endif #define LAGRAPH_SUITESPARSE 1 #else // use any GraphBLAS library (possibly SuiteSparse) but with no GxB* @@ -367,6 +370,15 @@ } \ } +//============================================================================== +// for C++ applications: +//============================================================================== + +#if defined ( __cplusplus ) +extern "C" +{ +#endif + //============================================================================== // LAGraph memory management //============================================================================== @@ -376,10 +388,10 @@ // the following are pointers to the ANSI C11 malloc/calloc/realloc/free // functions. -LAGRAPH_PUBLIC void * (* LAGraph_Malloc_function ) (size_t) ; -LAGRAPH_PUBLIC void * (* LAGraph_Calloc_function ) (size_t, size_t) ; -LAGRAPH_PUBLIC void * (* LAGraph_Realloc_function ) (void *, size_t) ; -LAGRAPH_PUBLIC void (* LAGraph_Free_function ) (void *) ; +LAGRAPH_PUBLIC extern void * (* LAGraph_Malloc_function ) (size_t) ; +LAGRAPH_PUBLIC extern void * (* LAGraph_Calloc_function ) (size_t, size_t) ; +LAGRAPH_PUBLIC extern void * (* LAGraph_Realloc_function ) (void *, size_t) ; +LAGRAPH_PUBLIC extern void (* LAGraph_Free_function ) (void *) ; //------------------------------------------------------------------------------ // LAGraph_Malloc: allocate a block of memory (wrapper for malloc) @@ -763,7 +775,7 @@ int LAGraph_Init // FUTURE: include these as built-in semirings in v2.1 C API, Table 3.9: // LAGraph semirings, created by LAGraph_Init or LAGr_Init: -LAGRAPH_PUBLIC GrB_Semiring +LAGRAPH_PUBLIC extern GrB_Semiring // LAGraph_plus_first_T: using the GrB_PLUS_MONOID_T monoid and the // corresponding GrB_FIRST_T multiplicative operator. @@ -2503,4 +2515,8 @@ int LAGr_TriangleCount char *msg ) ; +#if defined ( __cplusplus ) +} +#endif + #endif diff --git a/config/LAGraph.pc.in b/config/LAGraph.pc.in new file mode 100644 index 0000000000..4ca18e2544 --- /dev/null +++ b/config/LAGraph.pc.in @@ -0,0 +1,17 @@ +# LAGraph, Copyright (c) 2019-2023, LAGraph Contributors. All Rights Reserved. +# SPDX-License-Identifier: BSD-2-Clause + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: LAGraph +URL: https://github.com/GraphBLAS/LAGraph +Description: Library plus test harness for collecting algorithms that use GraphBLAS +Version: @LAGraph_VERSION_MAJOR@.@LAGraph_VERSION_MINOR@.@LAGraph_VERSION_SUB@ +Requires.private: GraphBLAS +Libs: -L${libdir} -l@SUITESPARSE_LIB_BASE_NAME@ +Libs.private: @LAGRAPH_STATIC_LIBS@ +Cflags: -I${includedir} -DLG_DLL +Cflags.private: -ULG_DLL diff --git a/config/LAGraphConfig.cmake.in b/config/LAGraphConfig.cmake.in new file mode 100644 index 0000000000..96ae114d08 --- /dev/null +++ b/config/LAGraphConfig.cmake.in @@ -0,0 +1,185 @@ +#------------------------------------------------------------------------------- +# SuiteSparse/LAGraph/cmake_modules/LAGraphConfig.cmake +#------------------------------------------------------------------------------- + +# The following copyright and license applies to just this file only, not to +# the library itself: +# LAGraphConfig.cmake, Copyright (c) 2019-2023, LAGraph Contributors. All +# Rights Reserved. +# SPDX-License-Identifier: BSD-3-clause + +#------------------------------------------------------------------------------- + +# Finds the LAGraph include file and compiled library. +# The following targets are defined: +# SuiteSparse::LAGraph - for the shared library (if available) +# SuiteSparse::LAGraph_static - for the static library (if available) + +# For backward compatibility the following variables are set: + +# LAGRAPH_INCLUDE_DIR - where to find LAGraph.h, etc. +# LAGRAPH_LIBRARY - dynamic LAGraph library +# LAGRAPH_STATIC - static LAGraph library +# LAGRAPH_LIBRARIES - libraries when using LAGraph +# LAGRAPH_FOUND - true if LAGraph found + +# Set ``CMAKE_MODULE_PATH`` to the parent folder where this module file is +# installed. + +#------------------------------------------------------------------------------- + +@PACKAGE_INIT@ + +set ( LAGRAPH_DATE "@LAGraph_DATE@" ) +set ( LAGRAPH_VERSION_MAJOR @LAGraph_VERSION_MAJOR@ ) +set ( LAGRAPH_VERSION_MINOR @LAGraph_VERSION_MINOR@ ) +set ( LAGRAPH_VERSION_PATCH @LAGraph_VERSION_SUB@ ) +set ( LAGRAPH_VERSION "@LAGraph_VERSION_MAJOR@.@LAGraph_VERSION_MINOR@.@LAGraph_VERSION_SUB@" ) + +# Check for dependent targets +include ( CMakeFindDependencyMacro ) +set ( _dependencies_found ON ) + +if ( NOT TARGET GraphBLAS::GraphBLAS ) + # Look GraphBLAS + list ( PREPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR} ) + find_dependency ( GraphBLAS @GraphBLAS_VERSION_MAJOR@.@GraphBLAS_VERSION_MINOR@ ) +endif ( ) + +if ( NOT GraphBLAS_FOUND ) + set ( LAGraph_FOUND OFF ) + return ( ) +endif ( ) + +# Look for OpenMP +if ( @LAGRAPH_HAS_OPENMP@ AND NOT OpenMP_C_FOUND ) + find_dependency ( OpenMP ) + if ( NOT OpenMP_C_FOUND ) + set ( _dependencies_found OFF ) + endif ( ) +endif ( ) + +if ( NOT _dependencies_found ) + set ( LAGraph_FOUND OFF ) + return ( ) +endif ( ) + +# Import target +include ( ${CMAKE_CURRENT_LIST_DIR}/LAGraphTargets.cmake ) + +if ( @LAGRAPH_HAS_OPENMP@ ) + if ( TARGET SuiteSparse::LAGraph ) + get_property ( _lagraph_aliased TARGET SuiteSparse::LAGraph + PROPERTY ALIASED_TARGET ) + if ( "${_lagraph_aliased}" STREQUAL "" ) + target_include_directories ( SuiteSparse::LAGraph SYSTEM AFTER INTERFACE + "$" ) + else ( ) + target_include_directories ( ${_lagraph_aliased} SYSTEM AFTER INTERFACE + "$" ) + endif ( ) + endif ( ) + if ( TARGET SuiteSparse::LAGraph_static ) + get_property ( _lagraph_aliased TARGET SuiteSparse::LAGraph_static + PROPERTY ALIASED_TARGET ) + if ( "${_lagraph_aliased}" STREQUAL "" ) + target_include_directories ( SuiteSparse::LAGraph_static SYSTEM AFTER INTERFACE + "$" ) + else ( ) + target_include_directories ( ${_lagraph_aliased} SYSTEM AFTER INTERFACE + "$" ) + endif ( ) + endif ( ) +endif ( ) + +# The following is only for backward compatibility with FindLAGraph. + +set ( _target_shared SuiteSparse::LAGraph ) +set ( _target_static SuiteSparse::LAGraph_static ) +set ( _var_prefix "LAGRAPH" ) + +if ( NOT @BUILD_SHARED_LIBS@ AND NOT TARGET ${_target_shared} ) + # make sure there is always an import target without suffix ) + add_library ( ${_target_shared} ALIAS ${_target_static} ) +endif ( ) +if ( NOT @BUILD_SHARED_LIBS@ AND NOT TARGET SuiteSparse::LAGraphX ) + # make sure there is always an import target without suffix ) + add_library ( SuiteSparse::LAGraphX ALIAS SuiteSparse::LAGraphX_static ) +endif ( ) + +get_target_property ( ${_var_prefix}_INCLUDE_DIR ${_target_shared} INTERFACE_INCLUDE_DIRECTORIES ) +if ( ${_var_prefix}_INCLUDE_DIR ) + # First item in SuiteSparse targets contains the "main" header directory. + list ( GET ${_var_prefix}_INCLUDE_DIR 0 ${_var_prefix}_INCLUDE_DIR ) +endif ( ) +get_target_property ( ${_var_prefix}_LIBRARY ${_target_shared} IMPORTED_IMPLIB ) +if ( NOT ${_var_prefix}_LIBRARY ) + get_target_property ( _library_chk ${_target_shared} IMPORTED_LOCATION ) + if ( EXISTS ${_library_chk} ) + set ( ${_var_prefix}_LIBRARY ${_library_chk} ) + endif ( ) +endif ( ) +if ( TARGET ${_target_static} ) + get_target_property ( ${_var_prefix}_STATIC ${_target_static} IMPORTED_LOCATION ) +endif ( ) + +# Check for most common build types +set ( _config_types "Debug" "Release" "RelWithDebInfo" "MinSizeRel" "None" ) + +get_property ( _isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG ) +if ( _isMultiConfig ) + # For multi-configuration generators (e.g., Visual Studio), prefer those + # configurations. + list ( PREPEND _config_types ${CMAKE_CONFIGURATION_TYPES} ) +else ( ) + # For single-configuration generators, prefer the current configuration. + list ( PREPEND _config_types ${CMAKE_BUILD_TYPE} ) +endif ( ) + +list ( REMOVE_DUPLICATES _config_types ) + +foreach ( _config ${_config_types} ) + string ( TOUPPER ${_config} _uc_config ) + if ( NOT ${_var_prefix}_LIBRARY ) + get_target_property ( _library_chk ${_target_shared} + IMPORTED_IMPLIB_${_uc_config} ) + if ( EXISTS ${_library_chk} ) + set ( ${_var_prefix}_LIBRARY ${_library_chk} ) + endif ( ) + endif ( ) + if ( NOT ${_var_prefix}_LIBRARY ) + get_target_property ( _library_chk ${_target_shared} + IMPORTED_LOCATION_${_uc_config} ) + if ( EXISTS ${_library_chk} ) + set ( ${_var_prefix}_LIBRARY ${_library_chk} ) + endif ( ) + endif ( ) + if ( TARGET ${_target_static} AND NOT ${_var_prefix}_STATIC ) + get_target_property ( _library_chk ${_target_static} + IMPORTED_LOCATION_${_uc_config} ) + if ( EXISTS ${_library_chk} ) + set ( ${_var_prefix}_STATIC ${_library_chk} ) + endif ( ) + endif ( ) +endforeach ( ) + +set ( LAGRAPH_LIBRARIES ${LAGRAPH_LIBRARY} ) + +macro ( suitesparse_check_exist _var _files ) + # ignore generator expressions + string ( GENEX_STRIP "${_files}" _files2 ) + + foreach ( _file ${_files2} ) + if ( NOT EXISTS "${_file}" ) + message ( FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist!" ) + endif ( ) + endforeach () +endmacro ( ) + +suitesparse_check_exist ( LAGRAPH_INCLUDE_DIR ${LAGRAPH_INCLUDE_DIR} ) +suitesparse_check_exist ( LAGRAPH_LIBRARY ${LAGRAPH_LIBRARY} ) + +message ( STATUS "LAGraph version: ${LAGRAPH_VERSION}" ) +message ( STATUS "LAGraph include: ${LAGRAPH_INCLUDE_DIR}" ) +message ( STATUS "LAGraph library: ${LAGRAPH_LIBRARY}" ) +message ( STATUS "LAGraph static: ${LAGRAPH_STATIC}" ) diff --git a/experimental/CMakeLists.txt b/experimental/CMakeLists.txt index a88386ffca..6038808bfc 100644 --- a/experimental/CMakeLists.txt +++ b/experimental/CMakeLists.txt @@ -2,7 +2,7 @@ # LAGraph/experimental/CMakeLists.txt: cmake script for LAGraph/experimental #------------------------------------------------------------------------------- -# LAGraph, (c) 2019-2022 by The LAGraph Contributors, All Rights Reserved. +# LAGraph, (c) 2019-2023 by The LAGraph Contributors, All Rights Reserved. # SPDX-License-Identifier: BSD-2-Clause # # For additional details (including references to third party source code and @@ -13,9 +13,9 @@ #------------------------------------------------------------------------------- -include_directories ( ${CMAKE_SOURCE_DIR}/include - ${CMAKE_SOURCE_DIR}/src/utility - ${CMAKE_SOURCE_DIR}/deps/json_h ) +include_directories ( + ${PROJECT_SOURCE_DIR}/src/utility + ${PROJECT_SOURCE_DIR}/deps/json_h ) file ( GLOB LAGRAPHX_LIB_SOURCES "utility/*.c" "algorithm/*.c" ) @@ -23,50 +23,82 @@ file ( GLOB LAGRAPHX_LIB_SOURCES "utility/*.c" "algorithm/*.c" ) # dynamic lagraphx library properties #------------------------------------------------------------------------------- -add_library ( lagraphx SHARED ${LAGRAPHX_LIB_SOURCES} ) -SET_TARGET_PROPERTIES ( lagraphx PROPERTIES - VERSION ${LAGraph_VERSION_MAJOR}.${LAGraph_VERSION_MINOR}.${LAGraph_VERSION_SUB} - SOVERSION ${LAGraph_VERSION_MAJOR} - C_STANDARD_REQUIRED 11 - PUBLIC_HEADER "include/LAGraphX.h" ) -set_property ( TARGET lagraphx PROPERTY C_STANDARD 11 ) -target_link_libraries ( lagraphx PUBLIC lagraph ${GRAPHBLAS_LIBRARIES} ) -target_link_directories ( lagraphx BEFORE PUBLIC ${CMAKE_SOURCE_DIR}/build ) +if ( BUILD_SHARED_LIBS ) + add_library ( LAGraphX SHARED ${LAGRAPHX_LIB_SOURCES} ) + set_target_properties ( LAGraphX PROPERTIES + VERSION ${LAGraph_VERSION_MAJOR}.${LAGraph_VERSION_MINOR}.${LAGraph_VERSION_SUB} + SOVERSION ${LAGraph_VERSION_MAJOR} + OUTPUT_NAME lagraphx + C_STANDARD_REQUIRED ON + C_STANDARD 11 + PUBLIC_HEADER "include/LAGraphX.h" + RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/dlls ) + + if ( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.25" ) + set_target_properties ( LAGraphX PROPERTIES EXPORT_NO_SYSTEM ON ) + endif ( ) + + target_link_libraries ( LAGraphX PRIVATE LAGraph GraphBLAS::GraphBLAS ) + + target_include_directories ( LAGraphX PUBLIC + $ + $ ) + + target_compile_definitions ( LAGraphX PRIVATE LGX_LIBRARY ) + target_compile_definitions ( LAGraphX PUBLIC LGX_DLL ) +endif ( ) #------------------------------------------------------------------------------- # static lagraphx library properties #------------------------------------------------------------------------------- -add_library ( lagraphx_static STATIC ${LAGRAPHX_LIB_SOURCES} ) -SET_TARGET_PROPERTIES ( lagraphx_static PROPERTIES - VERSION ${LAGraph_VERSION_MAJOR}.${LAGraph_VERSION_MINOR}.${LAGraph_VERSION_SUB} - OUTPUT_NAME lagraphx - POSITION_INDEPENDENT_CODE OFF - SOVERSION ${LAGraph_VERSION_MAJOR} - C_STANDARD_REQUIRED 11 ) - -if ( MSVC ) - set_target_properties ( lagraphx_static PROPERTIES - OUTPUT_NAME lagraphx_static ) -endif ( ) +if ( BUILD_STATIC_LIBS ) + add_library ( LAGraphX_static STATIC ${LAGRAPHX_LIB_SOURCES} ) + set_target_properties ( LAGraphX_static PROPERTIES + OUTPUT_NAME lagraphx + POSITION_INDEPENDENT_CODE OFF + C_STANDARD_REQUIRED ON + C_STANDARD 11 + PUBLIC_HEADER "include/LAGraphX.h" ) -set_property ( TARGET lagraphx_static PROPERTY C_STANDARD 11 ) -target_link_libraries ( lagraphx_static PUBLIC lagraph_static ${GRAPHBLAS_LIBRARIES} ) -target_link_directories ( lagraphx_static BEFORE PUBLIC ${CMAKE_SOURCE_DIR}/build ) + if ( MSVC ) + set_target_properties ( LAGraphX_static PROPERTIES + OUTPUT_NAME lagraphx_static ) + endif ( ) + + if ( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.25" ) + set_target_properties ( LAGraphX_static PROPERTIES EXPORT_NO_SYSTEM ON ) + endif ( ) + + if ( TARGET GraphBLAS::GraphBLAS_static ) + target_link_libraries ( LAGraphX_static PRIVATE GraphBLAS::GraphBLAS_static ) + else ( ) + target_link_libraries ( LAGraphX_static PRIVATE GraphBLAS::GraphBLAS ) + endif ( ) + + target_include_directories ( LAGraphX_static PUBLIC + $ + $ ) +endif ( ) #------------------------------------------------------------------------------- # add OpenMP #------------------------------------------------------------------------------- -if ( OPENMP_FOUND ) - target_link_libraries ( lagraphx PUBLIC lagraph ${OpenMP_C_LIBRARIES} ) - target_link_libraries ( lagraphx_static PUBLIC lagraph_static ${OpenMP_C_LIBRARIES} ) +if ( OpenMP_C_FOUND ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries ( LAGraphX PRIVATE OpenMP::OpenMP_C ) + endif ( ) + if ( BUILD_STATIC_LIBS ) + target_link_libraries ( LAGraphX_static PRIVATE OpenMP::OpenMP_C ) + endif ( ) endif ( ) #------------------------------------------------------------------------------- # applications #------------------------------------------------------------------------------- -add_subdirectory ( test ) -add_subdirectory ( benchmark ) - +if ( BUILD_TESTING ) + add_subdirectory ( test ) + add_subdirectory ( benchmark ) +endif ( ) diff --git a/experimental/algorithm/LAGraph_AllKCore.c b/experimental/algorithm/LAGraph_AllKCore.c index b1bad837d2..6500687168 100644 --- a/experimental/algorithm/LAGraph_AllKCore.c +++ b/experimental/algorithm/LAGraph_AllKCore.c @@ -94,6 +94,7 @@ int LAGraph_KCore_All //change deg vector to int32 if needed if(int_type == GrB_INT32){ + GrB_free (°) ; GRB_TRY (GrB_Vector_new(°, int_type, n)) ; GRB_TRY (GrB_assign (deg, G->out_degree, NULL, G->out_degree, GrB_ALL, n, NULL)) ; } diff --git a/experimental/algorithm/LAGraph_BF_full.c b/experimental/algorithm/LAGraph_BF_full.c index 3be0e48290..4d91d52a4b 100644 --- a/experimental/algorithm/LAGraph_BF_full.c +++ b/experimental/algorithm/LAGraph_BF_full.c @@ -218,8 +218,9 @@ GrB_Info LAGraph_BF_full LG_TRY (LAGraph_GetNumThreads (&nthreads_outer, &nthreads_inner, msg)) ; nthreads = nthreads_outer * nthreads_inner ; printf ("nthreads %d\n", nthreads) ; + int64_t k; #pragma omp parallel for num_threads(nthreads) schedule(static) - for (GrB_Index k = 0; k < nz; k++) + for (k = 0; k < nz; k++) { if (w[k] == 0) //diagonal entries { @@ -292,7 +293,7 @@ GrB_Info LAGraph_BF_full LAGRAPH_TRY (LAGraph_Malloc ((void **) &h , nz, sizeof(GrB_Index), msg)) ; LAGRAPH_TRY (LAGraph_Malloc ((void **) &pi, nz, sizeof(GrB_Index), msg)) ; - for (GrB_Index k = 0; k < nz; k++) + for (k = 0; k < nz; k++) { w [k] = W[k].w ; h [k] = W[k].h ; diff --git a/experimental/algorithm/LAGraph_BF_full1.c b/experimental/algorithm/LAGraph_BF_full1.c index f49b549ef7..5dab6d03cd 100644 --- a/experimental/algorithm/LAGraph_BF_full1.c +++ b/experimental/algorithm/LAGraph_BF_full1.c @@ -54,6 +54,7 @@ GrB_free(&BF_LT_Tuple3); \ GrB_free(&BF_lMIN_Tuple3_Monoid); \ GrB_free(&BF_lMIN_PLUSrhs_Tuple3); \ + GrB_free(&BF_Identity_Tuple3 ); \ LAGraph_Free ((void**)&I, NULL); \ LAGraph_Free ((void**)&J, NULL); \ LAGraph_Free ((void**)&w, NULL); \ @@ -173,15 +174,15 @@ GrB_Info LAGraph_BF_full1 // tmp vector to store distance vector after n (i.e., V) loops GrB_Vector d = NULL, dmasked = NULL, dless = NULL; GrB_Matrix Atmp = NULL; - GrB_Type BF_Tuple3; + GrB_Type BF_Tuple3 = NULL ; - GrB_BinaryOp BF_lMIN_Tuple3; - GrB_BinaryOp BF_PLUSrhs_Tuple3; - GrB_UnaryOp BF_Identity_Tuple3; - GrB_BinaryOp BF_LT_Tuple3; + GrB_BinaryOp BF_lMIN_Tuple3 = NULL ; + GrB_BinaryOp BF_PLUSrhs_Tuple3 = NULL ; + GrB_UnaryOp BF_Identity_Tuple3 = NULL ; + GrB_BinaryOp BF_LT_Tuple3 = NULL ; - GrB_Monoid BF_lMIN_Tuple3_Monoid; - GrB_Semiring BF_lMIN_PLUSrhs_Tuple3; + GrB_Monoid BF_lMIN_Tuple3_Monoid = NULL ; + GrB_Semiring BF_lMIN_PLUSrhs_Tuple3 = NULL ; GrB_Index nrows, ncols, n, nz; // n = # of row/col, nz = # of nnz in graph GrB_Index *I = NULL, *J = NULL; // for col/row indices of entries from A @@ -248,8 +249,9 @@ GrB_Info LAGraph_BF_full1 LG_TRY (LAGraph_GetNumThreads (&nthreads_outer, &nthreads_inner, msg)) ; nthreads = nthreads_outer * nthreads_inner ; printf ("nthreads %d\n", nthreads) ; + int64_t k; #pragma omp parallel for num_threads(nthreads) schedule(static) - for (GrB_Index k = 0; k < nz; k++) + for (k = 0; k < nz; k++) { W[k] = (BF1_Tuple3_struct) { .w = w[k], .h = 1, .pi = I[k] + 1 }; } @@ -350,7 +352,7 @@ GrB_Info LAGraph_BF_full1 GRB_TRY (GrB_Vector_extractTuples_UDT (I, (void *) W, &n, d)); - for (GrB_Index k = 0; k < n; k++) + for (k = 0; k < n; k++) { w [k] = W[k].w ; h [k] = W[k].h ; diff --git a/experimental/algorithm/LAGraph_BF_full1a.c b/experimental/algorithm/LAGraph_BF_full1a.c index e07c1ec0ce..28541da9e1 100644 --- a/experimental/algorithm/LAGraph_BF_full1a.c +++ b/experimental/algorithm/LAGraph_BF_full1a.c @@ -240,8 +240,9 @@ GrB_Info LAGraph_BF_full1a LG_TRY (LAGraph_GetNumThreads (&nthreads_outer, &nthreads_inner, msg)) ; nthreads = nthreads_outer * nthreads_inner ; printf ("nthreads %d\n", nthreads) ; + int64_t k; #pragma omp parallel for num_threads(nthreads) schedule(static) - for (GrB_Index k = 0; k < nz; k++) + for (k = 0; k < nz; k++) { W[k] = (BF_Tuple3_struct) { .w = w[k], .h = 1, .pi = I[k] + 1 }; } @@ -373,7 +374,7 @@ GrB_Info LAGraph_BF_full1a GRB_TRY (GrB_Vector_extractTuples_UDT (I, (void *) W, &n, d)); - for (GrB_Index k = 0; k < n; k++) + for (k = 0; k < n; k++) { w [k] = W[k].w ; h [k] = W[k].h ; diff --git a/experimental/algorithm/LAGraph_BF_full2.c b/experimental/algorithm/LAGraph_BF_full2.c index 9ae239d707..47eaeabb67 100644 --- a/experimental/algorithm/LAGraph_BF_full2.c +++ b/experimental/algorithm/LAGraph_BF_full2.c @@ -238,8 +238,9 @@ GrB_Info LAGraph_BF_full2 LG_TRY (LAGraph_GetNumThreads (&nthreads_outer, &nthreads_inner, msg)) ; nthreads = nthreads_outer * nthreads_inner ; printf ("nthreads %d\n", nthreads) ; + int64_t k; #pragma omp parallel for num_threads(nthreads) schedule(static) - for (GrB_Index k = 0; k < nz; k++) + for (k = 0; k < nz; k++) { if (w[k] == 0) //diagonal entries { @@ -331,7 +332,7 @@ GrB_Info LAGraph_BF_full2 nz = n ; GRB_TRY (GrB_Vector_extractTuples_UDT (I, (void *) W, &nz, d)); - for (GrB_Index k = 0; k < nz; k++) + for (k = 0; k < nz; k++) { w [k] = W[k].w ; h [k] = W[k].h ; diff --git a/experimental/algorithm/LAGraph_BF_pure_c_double.c b/experimental/algorithm/LAGraph_BF_pure_c_double.c index 1c99b5da06..bf514db5f8 100644 --- a/experimental/algorithm/LAGraph_BF_pure_c_double.c +++ b/experimental/algorithm/LAGraph_BF_pure_c_double.c @@ -44,6 +44,8 @@ LAGraph_Free ((void**) &pi, NULL) ; \ } +#include + #include "LG_internal.h" #include @@ -122,7 +124,7 @@ GrB_Info LAGraph_BF_pure_c_double { i = I[k]; j = J[k]; - if (d[j] > d[i] + W[k]) + if (d[j] > d[i] + W[k] + DBL_EPSILON*d[j]) { LG_FREE_ALL ; return (GrB_NO_VALUE) ; diff --git a/experimental/algorithm/LAGraph_FastGraphletTransform.c b/experimental/algorithm/LAGraph_FastGraphletTransform.c index cbcc2acc1c..568974a08c 100644 --- a/experimental/algorithm/LAGraph_FastGraphletTransform.c +++ b/experimental/algorithm/LAGraph_FastGraphletTransform.c @@ -58,6 +58,20 @@ GrB_free (&U_inv) ; \ GrB_free (&F_raw) ; \ GrB_free (&C_4) ; \ + GrB_free (&Sub_one_mult) ; \ + GrB_free (&T) ; \ + if (A_Tiles != NULL) \ + { \ + for (int i = 0; i < tile_cnt; ++i) GrB_free (&A_Tiles [i]) ; \ + } \ + if (D_Tiles != NULL) \ + { \ + for (int i = 0; i < tile_cnt; ++i) GrB_free (&D_Tiles [i]) ; \ + } \ + if (C_Tiles != NULL) \ + { \ + for (int i = 0; i < tile_cnt; ++i) GrB_free (&C_Tiles [i]) ; \ + } \ } #define LG_FREE_ALL \ @@ -90,6 +104,13 @@ int LAGraph_FastGraphletTransform GrB_Index const U_inv_J[] = {0, 1, 2, 4, 3, 4, 4, 5, 9, 10, 12, 13, 14, 15, 6, 10, 11, 12, 13, 14, 15, 7, 9, 10, 13, 14, 15, 8, 11, 14, 15, 9, 13, 15, 10, 13, 14, 15, 11, 14, 15, 12, 13, 14, 15, 13, 15, 14, 15, 15} ; int64_t const U_inv_X[] = {1, 1, 1, -2, 1, -1, 1, 1, -2, -1, -2, 4, 2, -6, 1, -1, -2, -2, 2, 4, -6, 1, -1, -1, 2, 1, -3, 1, -1, 1, -1, 1, -2, 3, 1, -2, -2, 6, 1, -2, 3, 1, -1, -1, 3, 1, -3, 1, -3, 1} ; GrB_Index const U_inv_nvals = 50; + GrB_UnaryOp Sub_one_mult = NULL ; + int tile_cnt = 0 ; + GrB_Matrix *A_Tiles = NULL ; + GrB_Matrix *D_Tiles = NULL ; + GrB_Matrix *C_Tiles = NULL ; + GrB_Index *Tile_nrows = NULL ; + GrB_Matrix T = NULL ; GrB_Matrix C_3 = NULL, A = NULL, @@ -149,10 +170,10 @@ int LAGraph_FastGraphletTransform // compute d_1 = Ae (in_degree) //-------------------------------------------------------------------------- - GRB_TRY (GrB_Vector_new (&d_1, GrB_INT64, n)) ; +// GRB_TRY (GrB_Vector_new (&d_1, GrB_INT64, n)) ; // d_1 = Ae (in_degree) - GRB_TRY (LAGraph_Cached_OutDegree (G, msg)) ; + LG_TRY (LAGraph_Cached_OutDegree (G, msg)) ; GRB_TRY (GrB_Vector_dup (&d_1, G->out_degree)) ; @@ -172,7 +193,6 @@ int LAGraph_FastGraphletTransform GRB_TRY (GrB_Vector_new (&d_3, GrB_INT64, n)) ; - GrB_UnaryOp Sub_one_mult = NULL ; GRB_TRY (GrB_UnaryOp_new (&Sub_one_mult, F_UNARY (sub_one_mult), GrB_INT64, GrB_INT64)) ; GRB_TRY (GrB_apply (d_3, NULL, NULL, Sub_one_mult, d_1, NULL)) ; @@ -295,15 +315,17 @@ int LAGraph_FastGraphletTransform const GrB_Index entries_per_tile = 1000; GrB_Index ntiles = (nvals + entries_per_tile - 1) / entries_per_tile ; - GrB_Matrix A_Tiles [ntiles], D_Tiles [ntiles], C_Tiles [ntiles] ; - GrB_Index Tile_nrows [ntiles] ; + // FIXME: use LAGraph_Calloc here, and check if out of memory: + A_Tiles = calloc (ntiles , sizeof (GrB_Matrix)) ; + D_Tiles = calloc (ntiles , sizeof (GrB_Matrix)) ; + C_Tiles = calloc (ntiles , sizeof (GrB_Matrix)) ; + Tile_nrows = calloc (ntiles , sizeof (GrB_Index)) ; GrB_Index Tile_ncols [1] = {n} ; int64_t tot_deg = 0 ; - int tile_cnt = 0 ; GrB_Index last_row = -1 ; for (GrB_Index i = 0; i < n; ++i) { - int64_t deg ; + int64_t deg = 0 ; GRB_TRY (GrB_Vector_extractElement (°, d_1, i)) ; if (i == n - 1 || (tot_deg / entries_per_tile != (tot_deg + deg) / entries_per_tile)) { @@ -317,18 +339,17 @@ int LAGraph_FastGraphletTransform GRB_TRY (GxB_Matrix_split (A_Tiles, tile_cnt, 1, Tile_nrows, Tile_ncols, A, NULL)) ; GRB_TRY (GxB_Matrix_split (D_Tiles, tile_cnt, 1, Tile_nrows, Tile_ncols, D_1, NULL)) ; - for (int i = 0; i < tile_cnt; ++i) C_Tiles [i] = NULL ; - -#define TRY(method) \ - { \ - GrB_Info info = method ; \ - if (info != GrB_SUCCESS) \ - { \ - GrB_free (&A_i) ; \ - GrB_free (&C_Tiles [i]) ; \ - GrB_free (&e) ; \ - continue ; \ - } \ +#define TRY(method) \ + { \ + GrB_Info info2 = method ; \ + if (info2 != GrB_SUCCESS) \ + { \ + GrB_free (&A_i) ; \ + GrB_free (&C_Tiles [i_tile]) ; \ + GrB_free (&e) ; \ + info1 = info2 ; \ + continue ; \ + } \ } // GxB_set (GxB_NTHREADS, 1) ; @@ -336,27 +357,31 @@ int LAGraph_FastGraphletTransform LG_TRY (LAGraph_GetNumThreads (&save_nthreads_outer, &save_nthreads_inner, msg)) ; LG_TRY (LAGraph_SetNumThreads (1, 1, msg)) ; + int i_tile; + GrB_Info info1 = GrB_SUCCESS ; #pragma omp parallel for num_threads(omp_get_max_threads()) schedule(dynamic,1) - for (int i = 0; i < tile_cnt; ++i) { + for (i_tile = 0; i_tile < tile_cnt; ++i_tile) { GrB_Matrix A_i = NULL, e = NULL ; TRY (GrB_Matrix_new (&e, GrB_INT64, n, 1)) ; TRY (GrB_assign (e, NULL, NULL, (int64_t) 1, GrB_ALL, n, GrB_ALL, 1, NULL)) ; - TRY (GrB_Matrix_new (&A_i, GrB_INT64, Tile_nrows [i], n)) ; - TRY (GrB_Matrix_new (&C_Tiles [i], GrB_INT64, Tile_nrows [i], 1)) ; + TRY (GrB_Matrix_new (&A_i, GrB_INT64, Tile_nrows [i_tile], n)) ; + TRY (GrB_Matrix_new (&C_Tiles [i_tile], GrB_INT64, Tile_nrows [i_tile], 1)) ; - TRY (GrB_mxm (A_i, NULL, NULL, GxB_PLUS_PAIR_INT64, A_Tiles [i], A, NULL)) ; - TRY (GrB_eWiseAdd (A_i, NULL, NULL, GrB_MINUS_INT64, A_i, D_Tiles [i], NULL)) ; + TRY (GrB_mxm (A_i, NULL, NULL, GxB_PLUS_PAIR_INT64, A_Tiles [i_tile], A, NULL)) ; + TRY (GrB_eWiseAdd (A_i, NULL, NULL, GrB_MINUS_INT64, A_i, D_Tiles [i_tile], NULL)) ; TRY (GrB_apply (A_i, NULL, NULL, Sub_one_mult, A_i, NULL)) ; // multiply A_i by it on the right - TRY (GrB_mxm (C_Tiles [i], NULL, NULL, GxB_PLUS_FIRST_INT64, A_i, e, NULL)) ; + TRY (GrB_mxm (C_Tiles [i_tile], NULL, NULL, GxB_PLUS_FIRST_INT64, A_i, e, NULL)) ; GrB_free (&A_i) ; GrB_free (&e) ; - } + + GRB_TRY (info1) ; + // GxB_set (GxB_NTHREADS, omp_get_max_threads()) ; LG_TRY (LAGraph_SetNumThreads (save_nthreads_outer, save_nthreads_inner, msg)) ; @@ -406,10 +431,9 @@ int LAGraph_FastGraphletTransform //-------------------------------------------------------------------------- if (compute_d_15) { - LAGRAPH_TRY (LAGraph_KTruss (&A, G, 4, msg)) ; + LG_TRY (LAGraph_KTruss (&T, G, 4, msg)) ; GRB_TRY (GrB_Vector_new (&d_15, GrB_INT64, n)) ; - //GrB_wait (A, GrB_MATERIALIZE) ; // this is essential int nthreads = 1 ; // todo: parallelize this... //#pragma omp parallel for num_threads(nthreads) @@ -426,32 +450,32 @@ int LAGraph_FastGraphletTransform } - // thread tid operates on A(row1:row2-1,:) + // thread tid operates on T(row1:row2-1,:) GrB_Index row1 = 0;//tid * (n / nthreads) ; GrB_Index row2 = n;//(tid == nthreads - 1) ? n : ((tid+1) * (n / nthreads)) ; GxB_Iterator riterator ; GxB_Iterator_new (&riterator) ; - GRB_TRY (GxB_rowIterator_attach (riterator, A, NULL)) ; + GRB_TRY (GxB_rowIterator_attach (riterator, T, NULL)) ; GxB_Iterator iterator ; GxB_Iterator_new (&iterator) ; - GRB_TRY (GxB_rowIterator_attach (iterator, A, NULL)) ; + GRB_TRY (GxB_rowIterator_attach (iterator, T, NULL)) ; - // seek to A(row1,:) + // seek to T(row1,:) GrB_Info info = GxB_rowIterator_seekRow (iterator, row1) ; while (info != GxB_EXHAUSTED) { - // iterate over entries in A(i,:) - GrB_Index i = GxB_rowIterator_getRowIndex (iterator) ; - if (i >= row2) break ; + // iterate over entries in T(i,:) + GrB_Index idx2 = GxB_rowIterator_getRowIndex (iterator) ; + if (idx2 >= row2) break ; int neighbor_cnt = 0 ; while (info == GrB_SUCCESS) { - // working with edge (i, j) + // working with edge (idx2, j) GrB_Index j = GxB_rowIterator_getColIndex (iterator) ; - if (j > i) { + if (j > idx2) { neighbors [neighbor_cnt++] = j ; isNeighbor [j] = 1 ; } @@ -480,7 +504,7 @@ int LAGraph_FastGraphletTransform while (info == GrB_SUCCESS) { // iterate over neighbors of k GrB_Index l = GxB_rowIterator_getColIndex (riterator) ; if (l > k && isNeighbor [l] == -1) { - f15[i]++ ; + f15[idx2]++ ; f15[j]++ ; f15[k]++ ; f15[l]++ ; @@ -498,11 +522,12 @@ int LAGraph_FastGraphletTransform isNeighbor [j] = 0 ; } - // move to the next row, A(i+1,:) + // move to the next row, T(i+1,:) info = GxB_rowIterator_nextRow (iterator) ; } GrB_free (&iterator) ; GrB_free (&riterator) ; + GrB_free (&T) ; GRB_TRY (GrB_Vector_build (d_15, I, f15, n, NULL)) ; free (neighbors) ; @@ -566,6 +591,10 @@ int LAGraph_FastGraphletTransform //-------------------------------------------------------------------------- LG_FREE_WORK ; + free ((void *) A_Tiles) ; A_Tiles = NULL ; + free ((void *) D_Tiles) ; D_Tiles = NULL ; + free ((void *) C_Tiles) ; C_Tiles = NULL ; + free ((void *) Tile_nrows) ; Tile_nrows = NULL ; return (0) ; #endif diff --git a/experimental/algorithm/LAGraph_MaximalIndependentSet.c b/experimental/algorithm/LAGraph_MaximalIndependentSet.c index 8e30a6abd7..80f70fe274 100644 --- a/experimental/algorithm/LAGraph_MaximalIndependentSet.c +++ b/experimental/algorithm/LAGraph_MaximalIndependentSet.c @@ -27,6 +27,7 @@ GrB_free (&empty) ; \ GrB_free (&Seed) ; \ GrB_free (&score) ; \ + GrB_free (°ree) ; \ } #define LG_FREE_ALL \ diff --git a/experimental/algorithm/LAGraph_SquareClustering.c b/experimental/algorithm/LAGraph_SquareClustering.c index 0e11b46625..cb4c6518e3 100644 --- a/experimental/algorithm/LAGraph_SquareClustering.c +++ b/experimental/algorithm/LAGraph_SquareClustering.c @@ -79,13 +79,14 @@ { \ GrB_free (&squares) ; \ GrB_free (&denom) ; \ + GrB_free (&neg_denom) ; \ + GrB_free (&P2) ; \ + GrB_free (&D) ; \ } #define LG_FREE_ALL \ { \ LG_FREE_WORK ; \ - GrB_free (&D) ; \ - GrB_free (&P2) ; \ GrB_free (&r) ; \ } diff --git a/experimental/algorithm/LAGraph_cc_lacc.c b/experimental/algorithm/LAGraph_cc_lacc.c index 7cc590c386..97c5e1eb37 100644 --- a/experimental/algorithm/LAGraph_cc_lacc.c +++ b/experimental/algorithm/LAGraph_cc_lacc.c @@ -25,6 +25,7 @@ { \ free(I); \ free(V); \ + GrB_free (&S2) ; \ GrB_free (&stars); \ GrB_free (&mask); \ GrB_free (&parents); \ @@ -91,6 +92,7 @@ int LAGraph_cc_lacc GrB_Vector tmp = NULL, pNonstars = NULL, nsgp = NULL; // temporary GrB_Index *I = NULL; GrB_Index *V = NULL; + GrB_Matrix S = NULL, S2 = NULL ; GrB_Index n ; GRB_TRY (GrB_Matrix_nrows (&n, A)) ; @@ -99,11 +101,11 @@ int LAGraph_cc_lacc //printf ("number of nodes: %g\n", (double) n) ; //printf ("number of edges: %g\n", (double) nnz) ; - GrB_Matrix S = NULL; if (sanitize) { - GRB_TRY (GrB_Matrix_new (&S, GrB_BOOL, n, n)) ; - GRB_TRY (GrB_eWiseAdd (S, NULL, NULL, GrB_LOR, A, A, GrB_DESC_T1)) ; + GRB_TRY (GrB_Matrix_new (&S2, GrB_BOOL, n, n)) ; + GRB_TRY (GrB_eWiseAdd (S2, NULL, NULL, GrB_LOR, A, A, GrB_DESC_T1)) ; + S = S2 ; } else { diff --git a/experimental/algorithm/LAGraph_cdlp.c b/experimental/algorithm/LAGraph_cdlp.c index c800119020..e1d83c7012 100644 --- a/experimental/algorithm/LAGraph_cdlp.c +++ b/experimental/algorithm/LAGraph_cdlp.c @@ -213,7 +213,7 @@ int LAGraph_cdlp LAGRAPH_TRY (LAGraph_Malloc ((void **) &AJ, nz, sizeof(GrB_Index),msg)); GRB_TRY (GrB_Matrix_extractTuples_UINT64(AI, AJ, GrB_NULL, &nz, A)) - LAGRAPH_TRY (LAGraph_Malloc ((void **) &AX, nz, sizeof(GrB_Index),msg)); + LAGRAPH_TRY (LAGraph_Calloc ((void **) &AX, nz, sizeof(GrB_Index),msg)); GRB_TRY (GrB_Matrix_new(&S, GrB_UINT64, n, n)); GRB_TRY (GrB_Matrix_build(S, AI, AJ, AX, nz, GrB_PLUS_UINT64)); @@ -234,6 +234,7 @@ int LAGraph_cdlp GRB_TRY (GxB_get(GxB_FORMAT, &global_format)) if (A_format != GxB_BY_ROW || global_format != GxB_BY_ROW) { + LG_FREE_ALL; return (GrB_INVALID_VALUE) ; } #endif diff --git a/experimental/algorithm/LAGraph_lcc.c b/experimental/algorithm/LAGraph_lcc.c index 3586ae49b9..84f4dccf5d 100644 --- a/experimental/algorithm/LAGraph_lcc.c +++ b/experimental/algorithm/LAGraph_lcc.c @@ -64,9 +64,9 @@ #define LG_FREE_ALL \ { \ - GrB_free (&C) ; \ + GrB_free (&A2) ; \ + GrB_free (&C2) ; \ GrB_free (&CL) ; \ - if (sanitize) GrB_free (&S) ; \ GrB_free (&U) ; \ GrB_free (&W) ; \ GrB_free (&LCC) ; \ @@ -133,7 +133,8 @@ int LAGraph_lcc // compute lcc for all nodes in A } GrB_Matrix C = NULL, CL = NULL, S = NULL, U = NULL ; - GrB_Vector W = NULL, LCC = NULL ; + GrB_Vector W = NULL, LCC = NULL ; + GrB_Matrix A2 = NULL, C2 = NULL ; GrB_UnaryOp LAGraph_COMB_DIR_FP64 = NULL ; GrB_UnaryOp LAGraph_COMB_UNDIR_FP64 = NULL ; GrB_Info info ; @@ -167,12 +168,13 @@ int LAGraph_lcc // compute lcc for all nodes in A t [0] = LAGraph_WallClockTime ( ) ; // S = binary structure of A - GrB_Matrix_new (&S, GrB_FP64, n, n) ; - GrB_apply (S, NULL, NULL, GrB_ONEB_FP64, A, 0, NULL) ; + GRB_TRY (GrB_Matrix_new (&A2, GrB_FP64, n, n)) ; + GRB_TRY (GrB_apply (A2, NULL, NULL, GrB_ONEB_FP64, A, 0, NULL)) ; // remove all self edges - GrB_select (S, NULL, NULL, GrB_OFFDIAG, S, 0, NULL) ; + GRB_TRY (GrB_select (A2, NULL, NULL, GrB_OFFDIAG, A2, 0, NULL)) ; t [0] = LAGraph_WallClockTime ( ) - t [0] ; + S = A2 ; } else { @@ -195,13 +197,11 @@ int LAGraph_lcc // compute lcc for all nodes in A F_UNARY (LAGraph_comb_undir_fp64), GrB_FP64, GrB_FP64)) ; - GRB_TRY (GrB_Matrix_new (&C, GrB_FP64, n, n)) ; GRB_TRY (GrB_Matrix_new (&U, GrB_UINT32, n, n)) ; if (symmetric) { C = S ; - S = NULL ; //---------------------------------------------------------------------- // U = triu(C) @@ -221,7 +221,8 @@ int LAGraph_lcc // compute lcc for all nodes in A // C = A \/ A' to create an undirected graph C //---------------------------------------------------------------------- - GRB_TRY (GrB_Matrix_new (&C, GrB_FP64, n, n)) ; + GRB_TRY (GrB_Matrix_new (&C2, GrB_FP64, n, n)) ; + C = C2 ; GRB_TRY (GrB_eWiseAdd (C, NULL, NULL, GrB_LOR, S, AT, NULL)) ; //---------------------------------------------------------------------- @@ -232,7 +233,6 @@ int LAGraph_lcc // compute lcc for all nodes in A GRB_TRY (GrB_eWiseAdd (D, NULL, NULL, GrB_PLUS_FP64, S, AT, NULL)) ; GrB_free (&AT) ; - if (sanitize) GrB_free (&S) ; //---------------------------------------------------------------------- // U = triu(D) diff --git a/experimental/algorithm/LG_CC_FastSV5.c b/experimental/algorithm/LG_CC_FastSV5.c index 87aecfdcc6..68ac423509 100644 --- a/experimental/algorithm/LG_CC_FastSV5.c +++ b/experimental/algorithm/LG_CC_FastSV5.c @@ -211,8 +211,9 @@ static inline int Reduce_assign32 ht_init (ht_key, ht_val) ; ht_sample (index, n, HASH_SAMPLES, ht_key, ht_val, seed) ; + int tid; #pragma omp parallel for num_threads(nthreads) schedule(static) - for (int tid = 0 ; tid < nthreads ; tid++) + for (tid = 0 ; tid < nthreads ; tid++) { // get the thread-specific buf array of size HASH_SIZE // todo: buf is a bad variable name; it's not a "buffer", @@ -260,7 +261,7 @@ static inline int Reduce_assign32 int32_t i = ht_key [h] ; if (i != -1) { - for (int32_t tid = 0 ; tid < nthreads ; tid++) + for (tid = 0 ; tid < nthreads ; tid++) { w_x [i] = LAGRAPH_MIN (w_x [i], mem [tid * HASH_SIZE + h]) ; } @@ -394,8 +395,9 @@ int LG_CC_FastSV5 // SuiteSparse:GraphBLAS method, with GxB extensions LAGRAPH_TRY (LAGraph_Malloc ((void **) &V32, n, sizeof (uint32_t), msg)) ; // prepare vectors + int64_t i; #pragma omp parallel for num_threads(nthreads2) schedule(static) - for (GrB_Index i = 0 ; i < n ; i++) + for (i = 0 ; i < n ; i++) { I [i] = i ; V32 [i] = (uint32_t) i ; @@ -487,8 +489,9 @@ int LG_CC_FastSV5 // SuiteSparse:GraphBLAS method, with GxB extensions // determine the number entries to be constructed in T for each thread //---------------------------------------------------------------------- + int tid; #pragma omp parallel for num_threads(nthreads) schedule(static) - for (int tid = 0 ; tid < nthreads ; tid++) + for (tid = 0 ; tid < nthreads ; tid++) { for (int32_t i = range [tid] ; i < range [tid+1] ; i++) { @@ -501,7 +504,7 @@ int LG_CC_FastSV5 // SuiteSparse:GraphBLAS method, with GxB extensions // count = cumsum (count) //---------------------------------------------------------------------- - for (int tid = 0 ; tid < nthreads ; tid++) + for (tid = 0 ; tid < nthreads ; tid++) { count [tid + 1] += count [tid] ; } @@ -518,7 +521,7 @@ int LG_CC_FastSV5 // SuiteSparse:GraphBLAS method, with GxB extensions // Note that Tx is not modified. Only Tp and Tj are constructed. #pragma omp parallel for num_threads(nthreads) schedule(static) - for (int tid = 0 ; tid < nthreads ; tid++) + for (tid = 0 ; tid < nthreads ; tid++) { GrB_Index p = count [tid] ; Tp [range [tid]] = p ; @@ -575,8 +578,9 @@ int LG_CC_FastSV5 // SuiteSparse:GraphBLAS method, with GxB extensions // calculate grandparent // fixme: NULL parameter is SS:GrB extension GRB_TRY (GrB_Vector_extractTuples (NULL, V32, &n, f)) ; // fixme + int32_t i; #pragma omp parallel for num_threads(nthreads2) schedule(static) - for (uint32_t i = 0 ; i < n ; i++) + for (i = 0 ; i < n ; i++) { I [i] = (GrB_Index) V32 [i] ; } @@ -630,7 +634,7 @@ int LG_CC_FastSV5 // SuiteSparse:GraphBLAS method, with GxB extensions // scheduled. #pragma omp parallel for num_threads(nthreads) schedule(static) - for (int tid = 0 ; tid < nthreads ; tid++) + for (tid = 0 ; tid < nthreads ; tid++) { GrB_Index ptr = Sp [range [tid]] ; // thread tid scans S (range [tid]:range [tid+1]-1,:), @@ -668,17 +672,32 @@ int LG_CC_FastSV5 // SuiteSparse:GraphBLAS method, with GxB extensions // Compact empty space out of Tj not filled in from the above phase. // This is a lot of work and should be done in parallel. GrB_Index offset = 0 ; - for (int tid = 0 ; tid < nthreads ; tid++) + for (tid = 0 ; tid < nthreads ; tid++) { - memcpy (Tj + offset, Tj + Tp [range [tid]], + +// this memcpy is not safe (src/dest can overlap) +// memcpy (Tj + offset, Tj + Tp [range [tid]], +// sizeof (GrB_Index) * count [tid]) ; + +// // using a for loop instead: +// GrB_Index *Tj_dest = Tj + offset ; +// GrB_Index *Tj_src = Tj + Tp [range [tid]] ; +// for (int64_t k = 0 ; k < count [tid] ; k++) +// { +// Tj_dest [k] = Tj_src [k] ; +// } + +// this is safe (memmove_s not necessary): + memmove (Tj + offset, Tj + Tp [range [tid]], sizeof (GrB_Index) * count [tid]) ; + offset += count [tid] ; count [tid] = offset - count [tid] ; } // Compact empty space out of Tp #pragma omp parallel for num_threads(nthreads) schedule(static) - for (int tid = 0 ; tid < nthreads ; tid++) + for (tid = 0 ; tid < nthreads ; tid++) { GrB_Index ptr = Tp [range [tid]] ; for (int32_t i = range [tid] ; i < range [tid+1] ; i++) @@ -736,8 +755,9 @@ int LG_CC_FastSV5 // SuiteSparse:GraphBLAS method, with GxB extensions // calculate grandparent // fixme: NULL parameter is SS:GrB extension GRB_TRY (GrB_Vector_extractTuples (NULL, V32, &n, f)) ; // fixme + int32_t k; #pragma omp parallel for num_threads(nthreads2) schedule(static) - for (uint32_t k = 0 ; k < n ; k++) + for (k = 0 ; k < n ; k++) { I [k] = (GrB_Index) V32 [k] ; } diff --git a/experimental/benchmark/CMakeLists.txt b/experimental/benchmark/CMakeLists.txt index e26887eeef..6cf1ca1c52 100644 --- a/experimental/benchmark/CMakeLists.txt +++ b/experimental/benchmark/CMakeLists.txt @@ -13,9 +13,9 @@ #------------------------------------------------------------------------------- -include_directories ( ${CMAKE_SOURCE_DIR}/src/test/include - ${CMAKE_SOURCE_DIR}/src/benchmark - ${CMAKE_SOURCE_DIR}/experimental/test/include ) +include_directories ( ${PROJECT_SOURCE_DIR}/src/test/include + ${PROJECT_SOURCE_DIR}/src/benchmark + ${PROJECT_SOURCE_DIR}/experimental/test/include ) file( GLOB DEMO_SOURCES LIST_DIRECTORIES false *_demo.c ) foreach( demosourcefile ${DEMO_SOURCES} ) @@ -23,6 +23,14 @@ foreach( demosourcefile ${DEMO_SOURCES} ) string( REPLACE ".c" "" demoname ${justname} ) # message("Adding: ${demoname}") add_executable( ${demoname} ${demosourcefile} ) - target_link_libraries( ${demoname} lagraphx lagraph lagraphtest lagraphxtest ${GRAPHBLAS_LIBRARIES} ) - target_link_directories( ${demoname} BEFORE PUBLIC ${CMAKE_SOURCE_DIR}/build ) + set_target_properties ( ${demoname} PROPERTIES + C_STANDARD_REQUIRED ON + C_STANDARD 11 ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries( ${demoname} + LAGraphX LAGraph lagraphtest lagraphxtest GraphBLAS::GraphBLAS ) + else ( ) + target_link_libraries( ${demoname} + LAGraphX_static LAGraph_static lagraphtest_static lagraphxtest_static GraphBLAS::GraphBLAS ) + endif ( ) endforeach( demosourcefile ${DEMO_SOURCES} ) diff --git a/experimental/benchmark/dnn_demo.c b/experimental/benchmark/dnn_demo.c index 1c6e7a0195..12dbce2d26 100644 --- a/experimental/benchmark/dnn_demo.c +++ b/experimental/benchmark/dnn_demo.c @@ -236,8 +236,8 @@ int main (int argc, char **argv) // LAGraph_dnn, but it is exploited here, simply to reduce the time to load // the problems. - int len = 1024 ; - char filename [len] ; + #define FILENAME_LEN 1024 + char filename [FILENAME_LEN] ; #define NMAXLAYERS 3 int maxLayers [NMAXLAYERS] = { 120, 480, 1920 } ; @@ -377,9 +377,10 @@ int main (int argc, char **argv) bool ok = true ; // assume the I/O system can handle 2-way parallelism + int layer; #pragma omp parallel for schedule(dynamic,1) reduction(&&:ok) \ num_threads (2) - for (int layer = first_layer ; layer < nlayers ; layer++) + for (layer = first_layer ; layer < nlayers ; layer++) { // read the neuron layer: W [layer] char my_filename [1024] ; @@ -428,7 +429,7 @@ int main (int argc, char **argv) printf ("read net time %g sec\n", t) ; double nedges = 0 ; - for (int layer = 0 ; layer < nlayers ; layer++) + for (layer = 0 ; layer < nlayers ; layer++) { GrB_Index nvals ; GRB_TRY (GrB_Matrix_nvals (&nvals, W [layer])) ; diff --git a/experimental/test/CMakeLists.txt b/experimental/test/CMakeLists.txt index 7b54598b4b..51f99f0987 100644 --- a/experimental/test/CMakeLists.txt +++ b/experimental/test/CMakeLists.txt @@ -17,9 +17,9 @@ # build the lagraphxtest library #------------------------------------------------------------------------------- -include_directories ( ${CMAKE_SOURCE_DIR}/src/test/include - ${CMAKE_SOURCE_DIR}/src/test/include - ${CMAKE_SOURCE_DIR}/experimental/test/include ) +include_directories ( ${PROJECT_SOURCE_DIR}/src/test/include + ${PROJECT_SOURCE_DIR}/src/test/include + ${PROJECT_SOURCE_DIR}/experimental/test/include ) file ( GLOB LAGRAPHXTEST_LIB_SOURCES "LG_*.c" ) @@ -35,43 +35,52 @@ endif ( ) # dynamic lagraphxtest library properties #------------------------------------------------------------------------------- -add_library ( lagraphxtest SHARED ${LAGRAPHXTEST_LIB_SOURCES} ) -SET_TARGET_PROPERTIES ( lagraphxtest PROPERTIES - VERSION ${LAGraph_VERSION_MAJOR}.${LAGraph_VERSION_MINOR}.${LAGraph_VERSION_SUB} - SOVERSION ${LAGraph_VERSION_MAJOR} - C_STANDARD_REQUIRED 11 ) -set_property ( TARGET lagraphxtest PROPERTY C_STANDARD 11 ) -target_link_libraries(lagraphxtest PUBLIC lagraph lagraphtest ${GRAPHBLAS_LIBRARIES}) -target_link_directories( lagraphxtest BEFORE PUBLIC ${CMAKE_SOURCE_DIR}/build ) +if ( BUILD_SHARED_LIBS ) + add_library ( lagraphxtest SHARED ${LAGRAPHXTEST_LIB_SOURCES} ) + set_target_properties ( lagraphxtest PROPERTIES + VERSION ${LAGraph_VERSION_MAJOR}.${LAGraph_VERSION_MINOR}.${LAGraph_VERSION_SUB} + SOVERSION ${LAGraph_VERSION_MAJOR} + C_STANDARD_REQUIRED ON + C_STANDARD 11 + RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/dlls ) + target_link_libraries ( lagraphxtest PRIVATE LAGraph lagraphtest GraphBLAS::GraphBLAS ) + target_compile_definitions ( lagraphxtest PRIVATE LGX_TEST_LIBRARY ) + target_compile_definitions ( lagraphxtest PUBLIC LGX_TEST_DLL ) +endif ( ) #------------------------------------------------------------------------------- # static lagraphxtest library properties #------------------------------------------------------------------------------- -add_library ( lagraphxtest_static STATIC ${LAGRAPHXTEST_LIB_SOURCES} ) -SET_TARGET_PROPERTIES ( lagraphxtest_static PROPERTIES - VERSION ${LAGraph_VERSION_MAJOR}.${LAGraph_VERSION_MINOR}.${LAGraph_VERSION_SUB} - OUTPUT_NAME lagraphxtest - POSITION_INDEPENDENT_CODE OFF - SOVERSION ${LAGraph_VERSION_MAJOR} - C_STANDARD_REQUIRED 11 ) - -if ( MSVC ) +if ( BUILD_STATIC_LIBS ) + add_library ( lagraphxtest_static STATIC ${LAGRAPHXTEST_LIB_SOURCES} ) set_target_properties ( lagraphxtest_static PROPERTIES - OUTPUT_NAME lagraphxtest_static ) + VERSION ${LAGraph_VERSION_MAJOR}.${LAGraph_VERSION_MINOR}.${LAGraph_VERSION_SUB} + OUTPUT_NAME lagraphxtest + POSITION_INDEPENDENT_CODE OFF + SOVERSION ${LAGraph_VERSION_MAJOR} + C_STANDARD_REQUIRED ON + C_STANDARD 11 ) + + if ( MSVC ) + set_target_properties ( lagraphxtest_static PROPERTIES + OUTPUT_NAME lagraphxtest_static ) + endif ( ) + + target_link_libraries ( lagraphxtest_static PRIVATE LAGraph_static lagraphtest_static GraphBLAS::GraphBLAS ) endif ( ) -set_property ( TARGET lagraphxtest_static PROPERTY C_STANDARD 11 ) -target_link_libraries(lagraphxtest_static PUBLIC lagraph lagraphtest ${GRAPHBLAS_LIBRARIES}) -target_link_directories( lagraphxtest_static BEFORE PUBLIC ${CMAKE_SOURCE_DIR}/build ) - #------------------------------------------------------------------------------- # add OpenMP #------------------------------------------------------------------------------- -if ( OPENMP_FOUND ) - target_link_libraries ( lagraphxtest PUBLIC ${OpenMP_C_LIBRARIES} ) - target_link_libraries ( lagraphxtest_static PUBLIC ${OpenMP_C_LIBRARIES} ) +if ( OpenMP_C_FOUND ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries ( lagraphxtest PRIVATE OpenMP::OpenMP_C ) + endif ( ) + if ( BUILD_STATIC_LIBS ) + target_link_libraries ( lagraphxtest_static PRIVATE OpenMP::OpenMP_C ) + endif ( ) endif ( ) @@ -85,9 +94,27 @@ foreach( testsourcefile ${TEST_SOURCES} ) string( REPLACE ".c" "" testname ${justname} ) # message("Adding: ${testname}") add_executable( ${testname} ${testsourcefile} ) - target_link_libraries( ${testname} lagraphx lagraph lagraphxtest lagraphtest ${GRAPHBLAS_LIBRARIES} ) - target_link_directories( ${testname} BEFORE PUBLIC ${CMAKE_SOURCE_DIR}/build ) - string( REPLACE "test_" "ctest_" ctestname ${testname}) - add_test( ${ctestname} ${testname}) + set_target_properties ( ${testname} PROPERTIES + C_STANDARD_REQUIRED ON + C_STANDARD 11 ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries( ${testname} + LAGraphX LAGraph lagraphxtest lagraphtest GraphBLAS::GraphBLAS ) + else ( ) + target_link_libraries( ${testname} + LAGraphX_static LAGraph_static lagraphxtest_static lagraphtest_static GraphBLAS::GraphBLAS ) + endif ( ) + string( REPLACE "test_" "LAGraphX_" ctestname ${testname}) + add_test( NAME ${ctestname} COMMAND $ ) +# add_test( NAME ${ctestname} COMMAND valgrind $ ) + if (WIN32) + if ( BUILD_SHARED_LIBS ) + set_tests_properties ( ${ctestname} PROPERTIES + ENVIRONMENT_MODIFICATION "PATH=path_list_prepend:$;PATH=path_list_prepend:$" ) + else ( ) + set_tests_properties ( ${ctestname} PROPERTIES + ENVIRONMENT_MODIFICATION "PATH=path_list_prepend:$" ) + endif ( ) + endif ( ) endforeach( testsourcefile ${TEST_SOURCES} ) diff --git a/experimental/test/LG_check_kcore.c b/experimental/test/LG_check_kcore.c index 00e507f41d..8ef56faa64 100644 --- a/experimental/test/LG_check_kcore.c +++ b/experimental/test/LG_check_kcore.c @@ -21,6 +21,10 @@ #define LG_FREE_ALL \ { \ + LAGraph_Free ((void **) &vert, msg) ; \ + LAGraph_Free ((void **) °, msg) ; \ + LAGraph_Free ((void **) &bin, msg) ; \ + LAGraph_Free ((void **) &pos, msg) ; \ LAGraph_Free ((void **) &Ap, msg) ; \ LAGraph_Free ((void **) &Aj, msg) ; \ LAGraph_Free ((void **) &Ax, msg) ; \ @@ -48,7 +52,8 @@ int LG_check_kcore //-------------------------------------------------------------------------- LG_CLEAR_MSG ; - + uint64_t *vert = NULL, *pos = NULL, *bin = NULL, *deg = NULL ; + uint64_t maxDeg = 0; GrB_Index *Ap = NULL, *Aj = NULL, *Ai = NULL ; void *Ax = NULL ; GrB_Index Ap_size, Aj_size, Ax_size, n, ncols, Ap_len, Aj_len, Ax_len ; @@ -78,8 +83,7 @@ int LG_check_kcore //printf("ap_len = %ld, aj_len = %ld, ax_len = %ld\n", Ap_len, Aj_len, Ax_len) ; //create the arrays - uint64_t *vert = NULL, *pos = NULL, *bin = NULL, *deg = NULL /*, *core = NULL */; - uint64_t maxDeg = 0; + LAGraph_Malloc((void **) °, n, sizeof(uint64_t), msg) ; LAGraph_Malloc((void **) &vert, n, sizeof(uint64_t), msg) ; LAGraph_Malloc((void **) &pos, n, sizeof(uint64_t), msg) ; diff --git a/experimental/test/LG_check_ktruss.c b/experimental/test/LG_check_ktruss.c index 31945c7a1b..e5dfb33e8e 100644 --- a/experimental/test/LG_check_ktruss.c +++ b/experimental/test/LG_check_ktruss.c @@ -105,10 +105,11 @@ int LG_check_ktruss //---------------------------------------------------------------------- // masked dot-product method: C{C}=C*C' using the PLUS_ONE semiring + int64_t i; #if !defined ( COVERAGE ) #pragma omp parallel for schedule(dynamic,1024) #endif - for (int64_t i = 0 ; i < n ; i++) + for (i = 0 ; i < n ; i++) { // for each entry in C(i,:) for (int64_t p = Cp [i] ; p < Cp [i+1] ; p++) diff --git a/experimental/test/test_AllKCore.c b/experimental/test/test_AllKCore.c index 58f75512a3..439787b94b 100644 --- a/experimental/test/test_AllKCore.c +++ b/experimental/test/test_AllKCore.c @@ -116,6 +116,8 @@ void test_AllKCore (void) TEST_CHECK(km1 == km2) ; OK (LAGraph_Vector_IsEqual (&ok, c1, c2, msg)) ; TEST_CHECK (ok) ; + GrB_free (&c1) ; + GrB_free (&c2) ; OK (LAGraph_Delete (&G, msg)) ; } diff --git a/experimental/test/test_BF.c b/experimental/test/test_BF.c index 3d942d4a72..e5e88ff4e6 100644 --- a/experimental/test/test_BF.c +++ b/experimental/test/test_BF.c @@ -312,6 +312,7 @@ void test_BF (void) LAGraph_Free ((void **) &pi10, NULL) ; result = LAGraph_BF_pure_c (&d10, &pi10, s, n, nvals, (const int64_t *) I, (const int64_t *) J, W_int32) ; + LAGraph_Free ((void **) &pi10, NULL) ; TEST_CHECK (result == valid) ; } @@ -498,6 +499,7 @@ void test_BF (void) GrB_free (&d9) ; GrB_free (&pi6) ; GrB_free (&h6) ; + LAGraph_Free ((void **) &d10, NULL) ; } teardown ( ) ; diff --git a/experimental/test/test_KTruss.c b/experimental/test/test_KTruss.c index bbb4652650..8bb75100fb 100644 --- a/experimental/test/test_KTruss.c +++ b/experimental/test/test_KTruss.c @@ -124,6 +124,8 @@ void test_ktruss (void) OK (LG_check_ktruss (&C2, G, 3, msg)) ; OK (LAGraph_Matrix_IsEqual (&ok, C1, C2, msg)) ; TEST_CHECK (ok) ; + OK (GrB_free (&C1)) ; + OK (GrB_free (&C2)) ; OK (LAGraph_Delete (&G, msg)) ; } diff --git a/experimental/test/test_MaximalIndependentSet.c b/experimental/test/test_MaximalIndependentSet.c index feeb4c33e2..95db12c42f 100644 --- a/experimental/test/test_MaximalIndependentSet.c +++ b/experimental/test/test_MaximalIndependentSet.c @@ -100,6 +100,7 @@ void test_MIS (void) // C = structure of A OK (LAGraph_Matrix_Structure (&C, A, msg)) ; + OK (GrB_free (&A)) ; // construct a directed graph G with adjacency matrix C OK (LAGraph_New (&G, &C, LAGraph_ADJACENCY_DIRECTED, msg)) ; diff --git a/experimental/test/test_SWrite.c b/experimental/test/test_SWrite.c index 53d883e1c8..58d00cc9e2 100644 --- a/experimental/test/test_SWrite.c +++ b/experimental/test/test_SWrite.c @@ -288,7 +288,7 @@ void test_SWrite_errors (void) TEST_CHECK (result == GrB_INVALID_VALUE) ; fclose (f) ; - f = fopen ("error.lagraph", "w") ; + f = fopen ("error.lagraph", "wb") ; TEST_CHECK (f != NULL) ; result = LAGraph_SWrite_HeaderStart (f, NULL, msg) ; diff --git a/experimental/test/test_TriangleCentrality.c b/experimental/test/test_TriangleCentrality.c index e1bcba3239..af7f1216b4 100644 --- a/experimental/test/test_TriangleCentrality.c +++ b/experimental/test/test_TriangleCentrality.c @@ -117,6 +117,7 @@ void test_TriangleCentrality (void) G->kind = LAGraph_ADJACENCY_DIRECTED ; OK (LAGraph_VertexCentrality_Triangle (&c, &ntri, 0, G, msg)) ; TEST_CHECK (ntri == ntriangles) ; + GrB_free (&c) ; OK (LAGraph_Delete (&G, msg)) ; } diff --git a/experimental/test/test_cdlp.c b/experimental/test/test_cdlp.c index 26a5170188..33e99d1d68 100644 --- a/experimental/test/test_cdlp.c +++ b/experimental/test/test_cdlp.c @@ -182,6 +182,7 @@ void test_cdlp (void) bool ok = false ; OK (LAGraph_Vector_IsEqual (&ok, c, cgood, msg)) ; TEST_CHECK (ok) ; + OK (GrB_free (&cgood)) ; } printf ("\ncdlp:\n") ; diff --git a/experimental/test/test_dnn.c b/experimental/test/test_dnn.c index f171ba1e7b..ea2edaa919 100644 --- a/experimental/test/test_dnn.c +++ b/experimental/test/test_dnn.c @@ -140,6 +140,7 @@ void test_dnn (void) OK (GrB_Col_extract (TrueCategories, NULL, NULL, T, GrB_ALL, nfeatures_subset, 0, NULL)) ; OK (LAGraph_Vector_Print (TrueCategories, LAGraph_COMPLETE, stdout, msg)) ; + GrB_free (&T) ; //-------------------------------------------------------------------------- // solve the problem diff --git a/experimental/test/test_lcc.c b/experimental/test/test_lcc.c index d96ee9b52f..55f66d0c32 100644 --- a/experimental/test/test_lcc.c +++ b/experimental/test/test_lcc.c @@ -182,6 +182,7 @@ void test_lcc (void) OK (GrB_reduce (&err, NULL, GrB_MAX_MONOID_FP64, cgood, NULL)) ; printf ("err: %g\n", err) ; TEST_CHECK (err < 1e-6) ; + OK (GrB_free (&cgood)) ; } printf ("\nlcc:\n") ; diff --git a/experimental/test/test_msf.c b/experimental/test/test_msf.c index f914793dfc..bf11e354c5 100644 --- a/experimental/test/test_msf.c +++ b/experimental/test/test_msf.c @@ -82,6 +82,7 @@ void test_msf (void) OK (GrB_assign (S, NULL, NULL, A, GrB_ALL, nrows, GrB_ALL, ncols, NULL)) ; GrB_Index n = nrows ; + OK (GrB_free (&A)) ; // construct a directed graph G with adjacency matrix S OK (LAGraph_New (&G, &S, LAGraph_ADJACENCY_DIRECTED, msg)) ; @@ -112,6 +113,7 @@ void test_msf (void) bool ok = false ; OK (LAGraph_Matrix_IsEqual (&ok, C, Cgood, msg)) ; TEST_CHECK (ok) ; + OK (GrB_free (&Cgood)) ; } printf ("\nmsf:\n") ; diff --git a/experimental/test/test_scc.c b/experimental/test/test_scc.c index cea92e42ff..5829077a85 100644 --- a/experimental/test/test_scc.c +++ b/experimental/test/test_scc.c @@ -141,6 +141,7 @@ void test_scc (void) bool ok = false ; OK (LAGraph_Vector_IsEqual (&ok, c, cgood, msg)) ; TEST_CHECK (ok) ; + OK (GrB_free (&cgood)) ; } printf ("\nscc:\n") ; diff --git a/experimental/utility/LAGraph_SLoadSet.c b/experimental/utility/LAGraph_SLoadSet.c index e5b7a71bf0..b0485f584a 100644 --- a/experimental/utility/LAGraph_SLoadSet.c +++ b/experimental/utility/LAGraph_SLoadSet.c @@ -91,7 +91,7 @@ int LAGraph_SLoadSet // load a set of matrices from a *.lagraph file if (filename != NULL) { - f = fopen (filename, "r") ; + f = fopen (filename, "rb") ; LG_ASSERT_MSG (f != NULL, LAGRAPH_IO_ERROR, "unable to open input file") ; } diff --git a/experimental/utility/LAGraph_SSaveSet.c b/experimental/utility/LAGraph_SSaveSet.c index 19d9fe8fd4..843109c993 100644 --- a/experimental/utility/LAGraph_SSaveSet.c +++ b/experimental/utility/LAGraph_SSaveSet.c @@ -77,7 +77,7 @@ int LAGraph_SSaveSet // save a set of matrices from a *.lagraph file GRB_TRY (GxB_set (desc, GxB_COMPRESSION, GxB_COMPRESSION_LZ4HC + 9)) ; #endif - f = fopen (filename, "w") ; + f = fopen (filename, "wb") ; LG_ASSERT_MSG (f != NULL, -1001, "unable to create output file") ; //-------------------------------------------------------------------------- diff --git a/include/LAGraph.h b/include/LAGraph.h index 5d5ddafc97..46a4f45a6d 100644 --- a/include/LAGraph.h +++ b/include/LAGraph.h @@ -2,7 +2,7 @@ // LAGraph.h: user-visible include file for LAGraph //------------------------------------------------------------------------------ -// LAGraph, (c) 2019-2022 by The LAGraph Contributors, All Rights Reserved. +// LAGraph, (c) 2019-2023 by The LAGraph Contributors, All Rights Reserved. // SPDX-License-Identifier: BSD-2-Clause // // For additional details (including references to third party source code and @@ -37,10 +37,10 @@ // See also the LAGraph_Version utility method, which returns these values. // These definitions are derived from LAGraph/CMakeLists.txt. -#define LAGRAPH_DATE "Aug 2, 2023" +#define LAGRAPH_DATE "Dec 30, 2023" #define LAGRAPH_VERSION_MAJOR 1 -#define LAGRAPH_VERSION_MINOR 0 -#define LAGRAPH_VERSION_UPDATE 2 +#define LAGRAPH_VERSION_MINOR 1 +#define LAGRAPH_VERSION_UPDATE 0 //============================================================================== // include files and helper macros @@ -66,17 +66,17 @@ #error "The GraphBLAS library must support the v2.0 C API Specification" #endif -#if ( _MSC_VER && !__INTEL_COMPILER ) +#if ( _MSC_VER && !__INTEL_COMPILER && LG_DLL ) #ifdef LG_LIBRARY // compiling LAGraph itself, exporting symbols to user apps - #define LAGRAPH_PUBLIC extern __declspec ( dllexport ) + #define LAGRAPH_PUBLIC __declspec ( dllexport ) #else // compiling the user application, importing symbols from LAGraph - #define LAGRAPH_PUBLIC extern __declspec ( dllimport ) + #define LAGRAPH_PUBLIC __declspec ( dllimport ) #endif #else // for other compilers - #define LAGRAPH_PUBLIC extern + #define LAGRAPH_PUBLIC #endif #if defined ( __cplusplus ) @@ -98,6 +98,9 @@ #if ( !LAGRAPH_VANILLA ) && defined ( GxB_SUITESPARSE_GRAPHBLAS ) // use SuiteSparse, and its GxB* extensions + #if GxB_IMPLEMENTATION < GxB_VERSION (7,1,0) + #error "If using SuiteSparse::GraphBLAS, version 7.1.0 or later is required" + #endif #define LAGRAPH_SUITESPARSE 1 #else // use any GraphBLAS library (possibly SuiteSparse) but with no GxB* @@ -367,6 +370,15 @@ } \ } +//============================================================================== +// for C++ applications: +//============================================================================== + +#if defined ( __cplusplus ) +extern "C" +{ +#endif + //============================================================================== // LAGraph memory management //============================================================================== @@ -376,10 +388,10 @@ // the following are pointers to the ANSI C11 malloc/calloc/realloc/free // functions. -LAGRAPH_PUBLIC void * (* LAGraph_Malloc_function ) (size_t) ; -LAGRAPH_PUBLIC void * (* LAGraph_Calloc_function ) (size_t, size_t) ; -LAGRAPH_PUBLIC void * (* LAGraph_Realloc_function ) (void *, size_t) ; -LAGRAPH_PUBLIC void (* LAGraph_Free_function ) (void *) ; +LAGRAPH_PUBLIC extern void * (* LAGraph_Malloc_function ) (size_t) ; +LAGRAPH_PUBLIC extern void * (* LAGraph_Calloc_function ) (size_t, size_t) ; +LAGRAPH_PUBLIC extern void * (* LAGraph_Realloc_function ) (void *, size_t) ; +LAGRAPH_PUBLIC extern void (* LAGraph_Free_function ) (void *) ; //------------------------------------------------------------------------------ // LAGraph_Malloc: allocate a block of memory (wrapper for malloc) @@ -763,7 +775,7 @@ int LAGraph_Init // FUTURE: include these as built-in semirings in v2.1 C API, Table 3.9: // LAGraph semirings, created by LAGraph_Init or LAGr_Init: -LAGRAPH_PUBLIC GrB_Semiring +LAGRAPH_PUBLIC extern GrB_Semiring // LAGraph_plus_first_T: using the GrB_PLUS_MONOID_T monoid and the // corresponding GrB_FIRST_T multiplicative operator. @@ -2503,4 +2515,8 @@ int LAGr_TriangleCount char *msg ) ; +#if defined ( __cplusplus ) +} +#endif + #endif diff --git a/include/LAGraphX.h b/include/LAGraphX.h index 67d65876f5..6f453690c7 100644 --- a/include/LAGraphX.h +++ b/include/LAGraphX.h @@ -2,7 +2,7 @@ // LAGraphX.h: include file for LAGraph experimental code //------------------------------------------------------------------------------ -// LAGraph, (c) 2019-2022 by The LAGraph Contributors, All Rights Reserved. +// LAGraph, (c) 2019-2023 by The LAGraph Contributors, All Rights Reserved. // SPDX-License-Identifier: BSD-2-Clause // // For additional details (including references to third party source code and @@ -19,24 +19,46 @@ #include #include +#if ( _MSC_VER && !__INTEL_COMPILER && LGX_DLL ) + #ifdef LGX_LIBRARY + // compiling LAGraph itself, exporting symbols to user apps + #define LAGRAPHX_PUBLIC __declspec ( dllexport ) + #else + // compiling the user application, importing symbols from LAGraph + #define LAGRAPHX_PUBLIC __declspec ( dllimport ) + #endif +#else + // for other compilers + #define LAGRAPHX_PUBLIC +#endif + +//============================================================================== +// for C++ applications: +//============================================================================== + +#if defined ( __cplusplus ) +extern "C" +{ +#endif + //============================================================================== // Experimental methods: in experimental/algorithm and experimental/utility //============================================================================== // Do not rely on these in production. These methods are still under -// development, and is intended only for illustration not benchmarking. Do not -// use for benchmarking, without asking the authors. +// development, and is intended only for illustration or testing, not +// benchmarking. Do not use for benchmarking without asking the authors. //------------------------------------------------------------------------------ // LAGraph_Random_*: Random number generator //------------------------------------------------------------------------------ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_Random_Init ( char *msg ) ; -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_Random_Finalize ( char *msg @@ -44,10 +66,10 @@ int LAGraph_Random_Finalize #if defined ( COVERAGE ) // for testing only -LAGRAPH_PUBLIC bool random_hack ; +LAGRAPHX_PUBLIC extern bool random_hack ; #endif -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_Random_Seed // construct a random seed vector ( // input/output @@ -57,7 +79,7 @@ int LAGraph_Random_Seed // construct a random seed vector char *msg ) ; -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_Random_Next // advance to next random vector ( // input/output @@ -65,7 +87,7 @@ int LAGraph_Random_Next // advance to next random vector char *msg ) ; -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC GrB_Info LAGraph_Random_Matrix // random matrix of any built-in type ( // output @@ -151,7 +173,7 @@ typedef struct } LAGraph_Contents ; -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_SWrite_HeaderStart // write the first part of the JSON header ( FILE *f, // file to write to @@ -159,7 +181,7 @@ int LAGraph_SWrite_HeaderStart // write the first part of the JSON header char *msg ) ; -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_SWrite_HeaderItem // write a single item to the JSON header ( // inputs: @@ -173,7 +195,7 @@ int LAGraph_SWrite_HeaderItem // write a single item to the JSON header char *msg ) ; -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_SWrite_HeaderItem // write a single item to the JSON header ( // inputs: @@ -188,14 +210,14 @@ int LAGraph_SWrite_HeaderItem // write a single item to the JSON header char *msg ) ; -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_SWrite_HeaderEnd // write the end of the JSON header ( FILE *f, // file to write to char *msg ) ; -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_SWrite_Item // write the serialized blob of a matrix/vector/text ( // input: @@ -205,7 +227,7 @@ int LAGraph_SWrite_Item // write the serialized blob of a matrix/vector/text char *msg ) ; -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_SRead // read a set of matrices from a *.lagraph file ( FILE *f, // file to read from @@ -216,7 +238,7 @@ int LAGraph_SRead // read a set of matrices from a *.lagraph file char *msg ) ; -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC void LAGraph_SFreeContents // free the Contents returned by LAGraph_SRead ( // input/output @@ -224,7 +246,7 @@ void LAGraph_SFreeContents // free the Contents returned by LAGraph_SRead GrB_Index ncontents ) ; -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_SSaveSet // save a set of matrices from a *.lagraph file ( // inputs: @@ -252,7 +274,7 @@ int LAGraph_SLoadSet // load a set of matrices from a *.lagraph file char *msg ) ; -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC void LAGraph_SFreeSet // free a set of matrices ( // input/output @@ -280,7 +302,7 @@ void LAGraph_SFreeSet // free a set of matrices * @retval GrB_SUCCESS if completed successfully (equal or not) * @retval GrB_NULL_POINTER if kmax, ntris, nedges, nsteps is NULL */ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_AllKTruss // compute all k-trusses of a graph ( // outputs @@ -308,7 +330,7 @@ int LAGraph_AllKTruss // compute all k-trusses of a graph * @retval GrB_NULL_POINTER if C or C_type is NULL * @return Any GraphBLAS errors that may have been encountered */ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_KTruss // compute the k-truss of a graph ( // outputs: @@ -335,7 +357,7 @@ int LAGraph_KTruss // compute the k-truss of a graph * @retval GrB_SUCCESS if completed successfully * @retval GrB_NULL_POINTER if result is NULL */ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_cc_lacc ( GrB_Vector *result, GrB_Matrix A, @@ -360,7 +382,7 @@ int LAGraph_cc_lacc ( * @retval GrB_INVALID_VALUE if A is not square, s is not a valid vertex index * @retval GrB_NO_VALUE if A has a negative weight cycle */ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC GrB_Info LAGraph_BF_basic ( GrB_Vector *pd_output, @@ -383,7 +405,7 @@ GrB_Info LAGraph_BF_basic * @retval GrB_NO_VALUE if A has a negative weight cycle * */ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC GrB_Info LAGraph_BF_basic_pushpull ( GrB_Vector *pd_output, @@ -406,7 +428,7 @@ GrB_Info LAGraph_BF_basic_pushpull * @retval GrB_NO_VALUE if A has a negative weight cycle * */ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC GrB_Info LAGraph_BF_basic_mxv ( GrB_Vector *pd_output, //the pointer to the vector of distance @@ -431,7 +453,7 @@ GrB_Info LAGraph_BF_basic_mxv * @retval GrB_NO_VALUE if A has a negative weight cycle * */ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC GrB_Info LAGraph_BF_full ( GrB_Vector *pd_output, @@ -458,7 +480,7 @@ GrB_Info LAGraph_BF_full * @retval GrB_NO_VALUE if A has a negative weight cycle * */ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC GrB_Info LAGraph_BF_full1 ( GrB_Vector *pd_output, @@ -485,7 +507,7 @@ GrB_Info LAGraph_BF_full1 * @retval GrB_NO_VALUE if A has a negative weight cycle * */ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC GrB_Info LAGraph_BF_full1a ( GrB_Vector *pd_output, @@ -512,7 +534,7 @@ GrB_Info LAGraph_BF_full1a * @retval GrB_NO_VALUE if A has a negative weight cycle * */ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC GrB_Info LAGraph_BF_full2 ( GrB_Vector *pd_output, //the pointer to the vector of distance @@ -539,7 +561,7 @@ GrB_Info LAGraph_BF_full2 * @retval GrB_NO_VALUE if A has a negative weight cycle * */ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC GrB_Info LAGraph_BF_full_mxv ( GrB_Vector *pd_output, @@ -560,18 +582,19 @@ GrB_Info LAGraph_BF_full_mxv * @param[in] s index of the source * @param[in] n number of nodes * @param[in] nz number of edges - * @param[in] I row index vector (size n) + * @param[in] Ilist row index vector (size n) * @param[in] J column index vector (size nz) - * @param[in] W weight vector (size nz), W(i) = weight of edge (I(i),J(i)) + * @param[in] W weight vector (size nz), W(i) = weight of edge + * (Ilist(i),J(i)) * * @retval GrB_SUCCESS if completed successfully - * @retval GrB_NULL_POINTER If pd, ppi, I, J, or W is NULL + * @retval GrB_NULL_POINTER If pd, ppi, Ilist, J, or W is NULL * @retval GrB_INVALID_VALUE if s is not a valid vertex index * @retval GrB_OUT_OF_MEMORY if allocation fails. * @retval GrB_NO_VALUE if A has a negative weight cycle * */ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC GrB_Info LAGraph_BF_pure_c ( int32_t **pd, @@ -581,7 +604,7 @@ GrB_Info LAGraph_BF_pure_c const int64_t s, const int64_t n, const int64_t nz, - const int64_t *I, + const int64_t *Ilist, const int64_t *J, const int32_t *W ) ; @@ -597,18 +620,19 @@ GrB_Info LAGraph_BF_pure_c * @param[in] s index of the source * @param[in] n number of nodes * @param[in] nz number of edges - * @param[in] I row index vector (size n) + * @param[in] Ilist row index vector (size n) * @param[in] J column index vector (size nz) - * @param[in] W weight vector (size nz), W(i) = weight of edge (I(i),J(i)) + * @param[in] W weight vector (size nz), W(i) = weight of edge + * (Ilist(i),J(i)) * * @retval GrB_SUCCESS if completed successfully - * @retval GrB_NULL_POINTER If pd, ppi, I, J, or W is NULL + * @retval GrB_NULL_POINTER If pd, ppi, Ilist, J, or W is NULL * @retval GrB_INVALID_VALUE if s is not a valid vertex index * @retval GrB_OUT_OF_MEMORY if allocation fails. * @retval GrB_NO_VALUE if A has a negative weight cycle * */ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC GrB_Info LAGraph_BF_pure_c_double ( double **pd, @@ -618,7 +642,7 @@ GrB_Info LAGraph_BF_pure_c_double const int64_t s, const int64_t n, const int64_t nz, - const int64_t *I, + const int64_t *Ilist, const int64_t *J, const double *W ) ; @@ -642,7 +666,7 @@ GrB_Info LAGraph_BF_pure_c_double * @retval GrB_OUT_OF_MEMORY if allocation fails. * @retval GrB_NO_VALUE if A has a negative weight cycle */ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_cdlp ( GrB_Vector *CDLP_handle, @@ -671,7 +695,7 @@ int LAGraph_cdlp * @retval GrB_DOMAIN_MISMATCH if type of Y0 is not FP32 or FP64, or the types of * W or Bias arent the same as Y0 */ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC GrB_Info LAGraph_dnn ( // output @@ -696,7 +720,7 @@ GrB_Info LAGraph_dnn * @retval GrB_NULL_POINTER If D or D_type is NULL * @retval GrB_INVALID_VALUE If G is not square */ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC GrB_Info LAGraph_FW ( const GrB_Matrix G, @@ -721,7 +745,7 @@ GrB_Info LAGraph_FW * @retval GrB_NULL_POINTER If LCC_handle or LCC_type is NULL * @retval GrB_INVALID_VALUE If A is not stored in CSR format */ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_lcc // compute lcc for all nodes in A ( GrB_Vector *LCC_handle, // output vector @@ -735,7 +759,7 @@ int LAGraph_lcc // compute lcc for all nodes in A //**************************************************************************** -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_msf ( GrB_Matrix *result, // output: an unsymmetrical matrix, the spanning forest @@ -746,7 +770,7 @@ int LAGraph_msf //**************************************************************************** -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_scc ( GrB_Vector *result, // output: array of component identifiers GrB_Matrix A, // input matrix @@ -754,7 +778,7 @@ int LAGraph_scc ( ) ; //**************************************************************************** -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_VertexCentrality_Triangle // vertex triangle-centrality ( // outputs: @@ -767,7 +791,7 @@ int LAGraph_VertexCentrality_Triangle // vertex triangle-centrality ) ; //**************************************************************************** -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_MaximalIndependentSet // maximal independent set ( // outputs: @@ -782,7 +806,7 @@ int LAGraph_MaximalIndependentSet // maximal independent set char *msg ) ; -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LG_CC_FastSV5 // SuiteSparse:GraphBLAS method, with GxB extensions ( // output @@ -796,7 +820,7 @@ int LG_CC_FastSV5 // SuiteSparse:GraphBLAS method, with GxB extensions // kcore algorithms //------------------------------------------------------------------------------ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_KCore_All ( // outputs: @@ -807,7 +831,7 @@ int LAGraph_KCore_All char *msg ) ; -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_KCore ( // outputs: @@ -818,7 +842,7 @@ int LAGraph_KCore char *msg ) ; -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_KCore_Decompose ( // outputs: @@ -834,7 +858,7 @@ int LAGraph_KCore_Decompose // counting graphlets //------------------------------------------------------------------------------ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_FastGraphletTransform ( // outputs: @@ -845,7 +869,7 @@ int LAGraph_FastGraphletTransform char *msg ) ; -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_SquareClustering ( // outputs: @@ -859,7 +883,7 @@ int LAGraph_SquareClustering // a simple example of an algorithm //------------------------------------------------------------------------------ -LAGRAPH_PUBLIC +LAGRAPHX_PUBLIC int LAGraph_HelloWorld // a simple algorithm, just for illustration ( // output @@ -869,4 +893,8 @@ int LAGraph_HelloWorld // a simple algorithm, just for illustration char *msg ) ; +#if defined ( __cplusplus ) +} +#endif + #endif diff --git a/rtdocs/CMakeLists.txt b/rtdocs/CMakeLists.txt index 10c0f9e30e..5b06879b7c 100644 --- a/rtdocs/CMakeLists.txt +++ b/rtdocs/CMakeLists.txt @@ -27,7 +27,9 @@ set(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in) set(DOXYFILE_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) # Set the Doxygen input and output directories in the Doxyfile -configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY) +configure_file ( ${DOXYFILE_IN} ${DOXYFILE_OUT} + @ONLY + NEWLINE_STYLE LF ) # Doxygen won't create this for us file(MAKE_DIRECTORY ${DOXYGEN_OUTPUT_DIR}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index daa435fbb4..515103d6b9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,7 +2,7 @@ # LAGraph/src/CMakeLists.txt: cmake script for LAGraph/src #------------------------------------------------------------------------------- -# LAGraph, (c) 2019-2022 by The LAGraph Contributors, All Rights Reserved. +# LAGraph, (c) 2019-2023 by The LAGraph Contributors, All Rights Reserved. # SPDX-License-Identifier: BSD-2-Clause # # For additional details (including references to third party source code and @@ -13,11 +13,11 @@ #------------------------------------------------------------------------------- -include_directories ( ${CMAKE_SOURCE_DIR}/include utility ) +include_directories ( utility ) file ( GLOB LAGRAPH_LIB_SOURCES "utility/*.c" "algorithm/*.c" ) -if ( "${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC" ) +if ( WIN32 ) set ( M_LIB "" ) else ( ) set ( M_LIB "m" ) @@ -27,52 +27,84 @@ endif ( ) # dynamic lagraph library properties #------------------------------------------------------------------------------- -add_library ( lagraph SHARED ${LAGRAPH_LIB_SOURCES} ) -SET_TARGET_PROPERTIES ( lagraph PROPERTIES - VERSION ${LAGraph_VERSION_MAJOR}.${LAGraph_VERSION_MINOR}.${LAGraph_VERSION_SUB} - SOVERSION ${LAGraph_VERSION_MAJOR} - C_STANDARD_REQUIRED 11 - PUBLIC_HEADER "include/LAGraph.h" ) -set_property ( TARGET lagraph PROPERTY C_STANDARD 11 ) -target_link_libraries ( lagraph PUBLIC ${GRAPHBLAS_LIBRARIES} ${M_LIB} ) -target_link_directories ( lagraph BEFORE PUBLIC ${CMAKE_SOURCE_DIR}/build ) -target_include_directories ( lagraph PUBLIC include/ ) -# install ( FILES ${LAGRAPH_INCLUDE} DESTINATION include) +if ( BUILD_SHARED_LIBS ) + add_library ( LAGraph SHARED ${LAGRAPH_LIB_SOURCES} ) + set_target_properties ( LAGraph PROPERTIES + VERSION ${LAGraph_VERSION_MAJOR}.${LAGraph_VERSION_MINOR}.${LAGraph_VERSION_SUB} + SOVERSION ${LAGraph_VERSION_MAJOR} + OUTPUT_NAME lagraph + C_STANDARD_REQUIRED ON + C_STANDARD 11 + PUBLIC_HEADER "include/LAGraph.h" + RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/dlls ) + + if ( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.25" ) + set_target_properties ( LAGraph PROPERTIES EXPORT_NO_SYSTEM ON ) + endif ( ) + + target_link_libraries ( LAGraph PRIVATE GraphBLAS::GraphBLAS ${M_LIB} ) + + target_include_directories ( LAGraph PUBLIC + $ + $ ) + + target_compile_definitions ( LAGraph PRIVATE LG_LIBRARY ) + target_compile_definitions ( LAGraph PUBLIC LG_DLL ) + # install ( FILES ${LAGRAPH_INCLUDE} DESTINATION include) +endif ( ) #------------------------------------------------------------------------------- # static lagraph library properties #------------------------------------------------------------------------------- -add_library ( lagraph_static STATIC ${LAGRAPH_LIB_SOURCES} ) -SET_TARGET_PROPERTIES ( lagraph_static PROPERTIES - VERSION ${LAGraph_VERSION_MAJOR}.${LAGraph_VERSION_MINOR}.${LAGraph_VERSION_SUB} - OUTPUT_NAME lagraph - POSITION_INDEPENDENT_CODE OFF - SOVERSION ${LAGraph_VERSION_MAJOR} - C_STANDARD_REQUIRED 11 ) - -if ( MSVC ) - set_target_properties ( lagraph_static PROPERTIES - OUTPUT_NAME lagraph_static ) +if ( BUILD_STATIC_LIBS ) + add_library ( LAGraph_static STATIC ${LAGRAPH_LIB_SOURCES} ) + SET_TARGET_PROPERTIES ( LAGraph_static PROPERTIES + OUTPUT_NAME lagraph + POSITION_INDEPENDENT_CODE OFF + C_STANDARD_REQUIRED ON + C_STANDARD 11 + PUBLIC_HEADER "include/LAGraph.h" ) + + if ( MSVC ) + set_target_properties ( LAGraph_static PROPERTIES + OUTPUT_NAME lagraph_static ) + endif ( ) + + if ( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.25" ) + set_target_properties ( LAGraph_static PROPERTIES EXPORT_NO_SYSTEM ON ) + endif ( ) + + if ( TARGET GraphBLAS::GraphBLAS_static ) + target_link_libraries ( LAGraph_static PUBLIC GraphBLAS::GraphBLAS_static ) + else ( ) + target_link_libraries ( LAGraph_static PUBLIC GraphBLAS::GraphBLAS ) + endif ( ) + target_link_libraries ( LAGraph_static PUBLIC ${M_LIB} ) + + target_include_directories ( LAGraph_static PUBLIC + $ + $ ) endif ( ) -set_property ( TARGET lagraph_static PROPERTY C_STANDARD 11 ) -target_link_libraries ( lagraph_static PUBLIC ${GRAPHBLAS_LIBRARIES} ${M_LIB} ) -target_link_directories( lagraph_static BEFORE PUBLIC ${CMAKE_SOURCE_DIR}/build ) - #------------------------------------------------------------------------------- # add OpenMP #------------------------------------------------------------------------------- -if ( OPENMP_FOUND ) - target_link_libraries ( lagraph PUBLIC ${OpenMP_C_LIBRARIES} ) - target_link_libraries ( lagraph_static PUBLIC ${OpenMP_C_LIBRARIES} ) +if ( OpenMP_C_FOUND ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries ( LAGraph PRIVATE OpenMP::OpenMP_C ) + endif ( ) + if ( BUILD_STATIC_LIBS ) + target_link_libraries ( LAGraph_static PRIVATE OpenMP::OpenMP_C ) + endif ( ) endif ( ) #------------------------------------------------------------------------------- # applications #------------------------------------------------------------------------------- -add_subdirectory ( test ) -add_subdirectory ( benchmark ) - +if ( BUILD_TESTING ) + add_subdirectory ( test ) + add_subdirectory ( benchmark ) +endif ( ) diff --git a/src/algorithm/LG_CC_Boruvka.c b/src/algorithm/LG_CC_Boruvka.c index 79cc5a3dd0..3c6998185a 100644 --- a/src/algorithm/LG_CC_Boruvka.c +++ b/src/algorithm/LG_CC_Boruvka.c @@ -25,6 +25,8 @@ // slower in general than LG_CC_FastSV6, which uses GxB pack/unpack methods // for faster access to the contents of the matrices and vectors. +#include + #include "LG_internal.h" //------------------------------------------------------------------------------ @@ -65,14 +67,20 @@ static GrB_Info Reduce_assign // select_func: IndexUnaryOp for pruning entries from S //------------------------------------------------------------------------------ -// Rather than using a global variable to access the Px array, it is passed to -// the select function as a uint64_t value that contains a pointer to Px. It -// might be better to create a user-defined type for y, but this works fine. +// The pointer to the Px array is passed to the select function as a component +// of a user-defined data type. + +typedef struct +{ + GrB_Index *pointer ; +} +Parent_struct ; void my_select_func (void *z, const void *x, const GrB_Index i, const GrB_Index j, const void *y) { - GrB_Index *Px = (*(GrB_Index **) y) ; + Parent_struct *Parent = (Parent_struct *) y ; + GrB_Index *Px = Parent->pointer ; (*((bool *) z)) = (Px [i] != Px [j]) ; } @@ -93,6 +101,8 @@ void my_select_func (void *z, const void *x, LAGraph_Free ((void **) &I, NULL) ; \ LAGraph_Free ((void **) &Px, NULL) ; \ LAGraph_Free ((void **) &mem, NULL) ; \ + GrB_free (&S) ; \ + GrB_free (&Parent_Type) ; \ GrB_free (&gp) ; \ GrB_free (&mnp) ; \ GrB_free (&ccmn) ; \ @@ -120,6 +130,8 @@ int LG_CC_Boruvka mask = NULL ; GrB_IndexUnaryOp select_op = NULL ; GrB_Matrix S = NULL ; + GrB_Type Parent_Type = NULL ; + Parent_struct Parent ; LG_CLEAR_MSG ; LG_TRY (LAGraph_CheckGraph (G, msg)) ; @@ -147,6 +159,9 @@ int LG_CC_Boruvka LG_TRY (LAGraph_Malloc ((void **) &mem, 3*n, sizeof (GrB_Index), msg)) ; LG_TRY (LAGraph_Malloc ((void **) &Px, n, sizeof (GrB_Index), msg)) ; + Parent.pointer = Px ; + + GRB_TRY (GrB_Type_new (&Parent_Type, sizeof (Parent_struct))) ; #if !LAGRAPH_SUITESPARSE // I is not needed for SuiteSparse and remains NULL @@ -163,7 +178,7 @@ int LG_CC_Boruvka GRB_TRY (GrB_Vector_extractTuples (I, Px, &n, parent)) ; GRB_TRY (GrB_IndexUnaryOp_new (&select_op, my_select_func, GrB_BOOL, - /* aij: ignored */ GrB_BOOL, /* y: pointer to Px */ GrB_UINT64)) ; + /* aij: ignored */ GrB_BOOL, /* y: pointer to Px */ Parent_Type)) ; GrB_Index nvals ; GRB_TRY (GrB_Matrix_nvals (&nvals, S)) ; @@ -249,7 +264,8 @@ int LG_CC_Boruvka // This step is the costliest part of this algorithm when dealing with // large matrices. - GRB_TRY (GrB_select (S, NULL, NULL, select_op, S, (uint64_t) Px, NULL)); + GRB_TRY (GrB_Matrix_select_UDT (S, NULL, NULL, select_op, S, + (void *) (&Parent), NULL)) ; GRB_TRY (GrB_Matrix_nvals (&nvals, S)) ; } @@ -261,3 +277,4 @@ int LG_CC_Boruvka LG_FREE_WORK ; return (GrB_SUCCESS) ; } + diff --git a/src/algorithm/LG_CC_FastSV6.c b/src/algorithm/LG_CC_FastSV6.c index 2a8043a851..24b9001416 100644 --- a/src/algorithm/LG_CC_FastSV6.c +++ b/src/algorithm/LG_CC_FastSV6.c @@ -47,6 +47,9 @@ // G->A will then become a truly read-only object (assuming GrB_wait (G->A) // has been done first). +#define __STDC_WANT_LIB_EXT1__ 1 +#include + #define LG_FREE_ALL ; #include "LG_internal.h" @@ -230,6 +233,7 @@ int LG_CC_FastSV6 // SuiteSparse:GraphBLAS method, with GxB extensions LG_TRY (LAGraph_CheckGraph (G, msg)) ; LG_ASSERT (component != NULL, GrB_NULL_POINTER) ; + (*component) = NULL ; LG_ASSERT_MSG ((G->kind == LAGraph_ADJACENCY_UNDIRECTED || (G->kind == LAGraph_ADJACENCY_DIRECTED && @@ -408,7 +412,8 @@ int LG_CC_FastSV6 // SuiteSparse:GraphBLAS method, with GxB extensions //---------------------------------------------------------------------- // thread tid works on rows range[tid]:range[tid+1]-1 of A and T - for (int tid = 0 ; tid <= nthreads ; tid++) + int tid; + for (tid = 0 ; tid <= nthreads ; tid++) { range [tid] = (n * tid + nthreads - 1) / nthreads ; } @@ -418,7 +423,7 @@ int LG_CC_FastSV6 // SuiteSparse:GraphBLAS method, with GxB extensions //---------------------------------------------------------------------- #pragma omp parallel for num_threads(nthreads) schedule(static) - for (int tid = 0 ; tid < nthreads ; tid++) + for (tid = 0 ; tid < nthreads ; tid++) { for (int64_t i = range [tid] ; i < range [tid+1] ; i++) { @@ -431,7 +436,7 @@ int LG_CC_FastSV6 // SuiteSparse:GraphBLAS method, with GxB extensions // count = cumsum (count) //---------------------------------------------------------------------- - for (int tid = 0 ; tid < nthreads ; tid++) + for (tid = 0 ; tid < nthreads ; tid++) { count [tid + 1] += count [tid] ; } @@ -443,7 +448,7 @@ int LG_CC_FastSV6 // SuiteSparse:GraphBLAS method, with GxB extensions // T (i,:) consists of the first FASTSV_SAMPLES of A (i,:). #pragma omp parallel for num_threads(nthreads) schedule(static) - for (int tid = 0 ; tid < nthreads ; tid++) + for (tid = 0 ; tid < nthreads ; tid++) { GrB_Index p = count [tid] ; Tp [range [tid]] = p ; @@ -473,7 +478,7 @@ int LG_CC_FastSV6 // SuiteSparse:GraphBLAS method, with GxB extensions // find the connected components of T //---------------------------------------------------------------------- - GRB_TRY (fastsv (T, parent, mngp, &gp, &gp_new, t, eq, min, min_2nd, + LG_TRY (fastsv (T, parent, mngp, &gp, &gp_new, t, eq, min, min_2nd, C, &Cp, &Px, &Cx, msg)) ; //---------------------------------------------------------------------- @@ -551,9 +556,8 @@ int LG_CC_FastSV6 // SuiteSparse:GraphBLAS method, with GxB extensions bool T_jumbled, T_iso ; GRB_TRY (GxB_Matrix_unpack_CSR (T, &Tp, &Tj, &Tx, &Tp_size, &Tj_size, &Tx_size, &T_iso, &T_jumbled, NULL)) ; - #pragma omp parallel for num_threads(nthreads) schedule(static) - for (int tid = 0 ; tid < nthreads ; tid++) + for (tid = 0 ; tid < nthreads ; tid++) { GrB_Index p = Ap [range [tid]] ; // thread tid scans A (range [tid]:range [tid+1]-1,:), @@ -598,17 +602,17 @@ int LG_CC_FastSV6 // SuiteSparse:GraphBLAS method, with GxB extensions // Compact empty space out of Tj not filled in from the above phase. nvals = 0 ; - for (int tid = 0 ; tid < nthreads ; tid++) + for (tid = 0 ; tid < nthreads ; tid++) { - memcpy (Tj + nvals, Tj + Tp [range [tid]], - sizeof (GrB_Index) * count [tid]) ; + memmove (Tj + nvals, + Tj + Tp [range [tid]], sizeof (GrB_Index) * count [tid]) ; nvals += count [tid] ; count [tid] = nvals - count [tid] ; } // Compact empty space out of Tp #pragma omp parallel for num_threads(nthreads) schedule(static) - for (int tid = 0 ; tid < nthreads ; tid++) + for (tid = 0 ; tid < nthreads ; tid++) { GrB_Index p = Tp [range [tid]] ; for (int64_t i = range [tid] ; i < range [tid+1] ; i++) @@ -653,7 +657,7 @@ int LG_CC_FastSV6 // SuiteSparse:GraphBLAS method, with GxB extensions // final phase //-------------------------------------------------------------------------- - GRB_TRY (fastsv (A, parent, mngp, &gp, &gp_new, t, eq, min, min_2nd, + LG_TRY (fastsv (A, parent, mngp, &gp, &gp_new, t, eq, min, min_2nd, C, &Cp, &Px, &Cx, msg)) ; //-------------------------------------------------------------------------- diff --git a/src/benchmark/CMakeLists.txt b/src/benchmark/CMakeLists.txt index ac1cebe34c..4025d37475 100644 --- a/src/benchmark/CMakeLists.txt +++ b/src/benchmark/CMakeLists.txt @@ -13,8 +13,8 @@ #------------------------------------------------------------------------------- -include_directories ( ${CMAKE_SOURCE_DIR}/src/test/include - ${CMAKE_SOURCE_DIR}/src/algorithm ) +include_directories ( ${PROJECT_SOURCE_DIR}/src/test/include + ${PROJECT_SOURCE_DIR}/src/algorithm ) file( GLOB DEMO_SOURCES LIST_DIRECTORIES false *_demo.c ) foreach( demosourcefile ${DEMO_SOURCES} ) @@ -22,6 +22,12 @@ foreach( demosourcefile ${DEMO_SOURCES} ) string( REPLACE ".c" "" demoname ${justname} ) # message("Adding: ${demoname}") add_executable( ${demoname} ${demosourcefile} ) - target_link_libraries( ${demoname} lagraph lagraphx lagraphtest ${GRAPHBLAS_LIBRARIES} ) - target_link_directories( ${demoname} BEFORE PUBLIC ${CMAKE_SOURCE_DIR}/build ) + set_target_properties ( ${demoname} PROPERTIES + C_STANDARD_REQUIRED ON + C_STANDARD 11 ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries( ${demoname} LAGraph LAGraphX lagraphtest GraphBLAS::GraphBLAS ) + else ( ) + target_link_libraries( ${demoname} LAGraph_static LAGraphX_static lagraphtest_static GraphBLAS::GraphBLAS ) + endif ( ) endforeach( demosourcefile ${DEMO_SOURCES} ) diff --git a/src/benchmark/README.md b/src/benchmark/README.md index 1bb6b89383..9789c69e3b 100644 --- a/src/benchmark/README.md +++ b/src/benchmark/README.md @@ -1,7 +1,7 @@ # LAGraph/src/benchmark: Demo programs that use LAGraph and GraphBLAS # to run all of the GAP Benchmark problems. -LAGraph, (c) 2021-2022 by The LAGraph Contributors, All Rights Reserved. +LAGraph, (c) 2021-2023 by The LAGraph Contributors, All Rights Reserved. SPDX-License-Identifier: BSD-2-Clause See additional acknowledgments in the LICENSE file, or contact permission@sei.cmu.edu for the full terms. @@ -14,19 +14,12 @@ impact on performance. Also, please contact the authors of the library if you have any questions about benchmarking. (Tim Davis: davis@tamu.edu, in particular). -LAGraph is a draft package (not yet v1.0), and its performance is not yet -stable. It includes many draft algorithms that are sometimes posted on github -in debug mode, or with known suboptimal performance. We ask that you not -benchmark LAGraph on your own without contacting the authors to make sure you -have the right version, and the right version of SuiteSparse:GraphBLAS to go -with it. - If you run in vanilla mode, by compiling LAGraph with cmake -DLAGRAPH_VANILLA=1 .. Then performance can be quite low since in this case LAGraph does not use -any SuiteSparse:GraphBLAS GxB extensions. We are still developing the +any SuiteSparse:GraphBLAS extensions. We are still developing the pure GrB implementations of these algorithms. However, assuming things are stable, follow the instructions in the diff --git a/src/benchmark/bc_demo.c b/src/benchmark/bc_demo.c index 76a1b1bdc8..1d606544dd 100644 --- a/src/benchmark/bc_demo.c +++ b/src/benchmark/bc_demo.c @@ -53,6 +53,8 @@ GrB_free (&SourceNodes) ; \ } +#define BATCH_SIZE 4 + int main (int argc, char **argv) { @@ -66,7 +68,7 @@ int main (int argc, char **argv) bool burble = false ; demo_init (burble) ; - int batch_size = 4 ; + int batch_size = BATCH_SIZE ; //-------------------------------------------------------------------------- // determine # of threads to use @@ -96,8 +98,7 @@ int main (int argc, char **argv) } printf ("\n") ; - double tt [nthreads_max+1] ; - double tt2 [nthreads_max+1] ; + double *tt = malloc ((nthreads_max+1) *sizeof (double)); //-------------------------------------------------------------------------- // read in the graph @@ -138,7 +139,7 @@ int main (int argc, char **argv) ntrials++ ; printf ("\nTrial %d : sources: [", ntrials) ; - GrB_Index vertex_list [batch_size] ; + GrB_Index vertex_list [BATCH_SIZE] ; for (int64_t k = 0 ; k < batch_size ; k++) { // get the kth source node @@ -147,8 +148,8 @@ int main (int argc, char **argv) k + kstart, 0)) ; // subtract one to convert from 1-based to 0-based source-- ; - vertex_list [k] = source ; - printf (" %"PRIu64, source) ; + vertex_list [k] = source ; + printf (" %"PRId64, source) ; } printf (" ]\n") ; @@ -197,6 +198,7 @@ int main (int argc, char **argv) Nthreads [t], t2, matrix_name) ; } + free ((void *) tt); LG_FREE_ALL; LAGRAPH_TRY (LAGraph_Finalize (msg)) ; return (GrB_SUCCESS) ; diff --git a/src/benchmark/bfs_demo.c b/src/benchmark/bfs_demo.c index 5b198fcbcd..6042418205 100644 --- a/src/benchmark/bfs_demo.c +++ b/src/benchmark/bfs_demo.c @@ -81,9 +81,9 @@ int main (int argc, char **argv) } printf ("\n") ; - double tpl [nthreads_max+1] ; - double tp [nthreads_max+1] ; - double tl [nthreads_max+1] ; + double *tpl = malloc ((nthreads_max+1) * sizeof (double)) ; + double *tp = malloc ((nthreads_max+1) * sizeof (double)) ; + double *tl = malloc ((nthreads_max+1) * sizeof (double)) ; //-------------------------------------------------------------------------- // read in the graph @@ -295,6 +295,9 @@ int main (int argc, char **argv) // free all workspace and finish //-------------------------------------------------------------------------- + free ((void *) tpl) ; + free ((void *) tp) ; + free ((void *) tl) ; LG_FREE_ALL ; LAGRAPH_TRY (LAGraph_Finalize (msg)) ; return (GrB_SUCCESS) ; diff --git a/src/benchmark/cc_demo.c b/src/benchmark/cc_demo.c index 7974615aac..42a0930db3 100644 --- a/src/benchmark/cc_demo.c +++ b/src/benchmark/cc_demo.c @@ -101,8 +101,6 @@ int main (int argc, char **argv) } printf ("\n") ; - double tt [nthreads_max+1] ; - //-------------------------------------------------------------------------- // read in the graph //-------------------------------------------------------------------------- diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index ac675e0328..025b1b35ab 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -20,8 +20,8 @@ # build the lagraphtest library #------------------------------------------------------------------------------- -include_directories ( ${CMAKE_SOURCE_DIR}/src/test/include - ${CMAKE_SOURCE_DIR}/src/algorithm ) +include_directories ( ${PROJECT_SOURCE_DIR}/src/test/include + ${PROJECT_SOURCE_DIR}/src/algorithm ) file ( GLOB LAGRAPHTEST_LIB_SOURCES "LG_*.c" ) @@ -37,43 +37,52 @@ endif ( ) # dynamic lagraphtest library properties #------------------------------------------------------------------------------- -add_library ( lagraphtest SHARED ${LAGRAPHTEST_LIB_SOURCES} ) -SET_TARGET_PROPERTIES ( lagraphtest PROPERTIES - VERSION ${LAGraph_VERSION_MAJOR}.${LAGraph_VERSION_MINOR}.${LAGraph_VERSION_SUB} - SOVERSION ${LAGraph_VERSION_MAJOR} - C_STANDARD_REQUIRED 11 ) -set_property ( TARGET lagraphtest PROPERTY C_STANDARD 11 ) -target_link_libraries( lagraphtest PUBLIC lagraph ${GRAPHBLAS_LIBRARIES}) -target_link_directories( lagraphtest BEFORE PUBLIC ${CMAKE_SOURCE_DIR}/build ) +if ( BUILD_SHARED_LIBS ) + add_library ( lagraphtest SHARED ${LAGRAPHTEST_LIB_SOURCES} ) + set_target_properties ( lagraphtest PROPERTIES + VERSION ${LAGraph_VERSION_MAJOR}.${LAGraph_VERSION_MINOR}.${LAGraph_VERSION_SUB} + SOVERSION ${LAGraph_VERSION_MAJOR} + C_STANDARD_REQUIRED ON + C_STANDARD 11 + RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/dlls ) + target_link_libraries ( lagraphtest PRIVATE LAGraph GraphBLAS::GraphBLAS ) + target_compile_definitions ( lagraphtest PRIVATE LG_TEST_LIBRARY ) + target_compile_definitions ( lagraphtest PUBLIC LG_TEST_DLL ) +endif ( ) #------------------------------------------------------------------------------- # static lagraphtest library properties #------------------------------------------------------------------------------- -add_library ( lagraphtest_static STATIC ${LAGRAPHTEST_LIB_SOURCES} ) -SET_TARGET_PROPERTIES ( lagraphtest_static PROPERTIES - VERSION ${LAGraph_VERSION_MAJOR}.${LAGraph_VERSION_MINOR}.${LAGraph_VERSION_SUB} - OUTPUT_NAME lagraphtest - POSITION_INDEPENDENT_CODE OFF - SOVERSION ${LAGraph_VERSION_MAJOR} - C_STANDARD_REQUIRED 11 ) - -if ( MSVC ) +if ( BUILD_STATIC_LIBS ) + add_library ( lagraphtest_static STATIC ${LAGRAPHTEST_LIB_SOURCES} ) set_target_properties ( lagraphtest_static PROPERTIES - OUTPUT_NAME lagraphtest_static ) + VERSION ${LAGraph_VERSION_MAJOR}.${LAGraph_VERSION_MINOR}.${LAGraph_VERSION_SUB} + OUTPUT_NAME lagraphtest + POSITION_INDEPENDENT_CODE OFF + SOVERSION ${LAGraph_VERSION_MAJOR} + C_STANDARD_REQUIRED ON + C_STANDARD 11 ) + + if ( MSVC ) + set_target_properties ( lagraphtest_static PROPERTIES + OUTPUT_NAME lagraphtest_static ) + endif ( ) + + target_link_libraries ( lagraphtest_static PRIVATE LAGraph_static GraphBLAS::GraphBLAS ) endif ( ) -set_property ( TARGET lagraphtest_static PROPERTY C_STANDARD 11 ) -target_link_libraries(lagraphtest_static PUBLIC lagraph ${GRAPHBLAS_LIBRARIES}) -target_link_directories( lagraphtest_static BEFORE PUBLIC ${CMAKE_SOURCE_DIR}/build ) - #------------------------------------------------------------------------------- # add OpenMP #------------------------------------------------------------------------------- -if ( OPENMP_FOUND ) - target_link_libraries ( lagraphtest PUBLIC ${OpenMP_C_LIBRARIES} ) - target_link_libraries ( lagraphtest_static PUBLIC ${OpenMP_C_LIBRARIES} ) +if ( OpenMP_C_FOUND ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries ( lagraphtest PRIVATE OpenMP::OpenMP_C ) + endif ( ) + if ( BUILD_STATIC_LIBS ) + target_link_libraries ( lagraphtest_static PRIVATE OpenMP::OpenMP_C ) + endif ( ) endif ( ) #------------------------------------------------------------------------------- @@ -86,9 +95,25 @@ foreach( testsourcefile ${TEST_SOURCES} ) string( REPLACE ".c" "" testname ${justname} ) # message("Adding: ${testname}") add_executable( ${testname} ${testsourcefile}) - target_link_libraries( ${testname} lagraph lagraphx lagraphtest ${GRAPHBLAS_LIBRARIES} ) - target_link_directories( ${testname} BEFORE PUBLIC ${CMAKE_SOURCE_DIR}/build ) - string( REPLACE "test_" "ctest_" ctestname ${testname}) - add_test( ${ctestname} ${testname}) + set_target_properties ( ${testname} PROPERTIES + C_STANDARD_REQUIRED ON + C_STANDARD 11 ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries( ${testname} LAGraph LAGraphX lagraphtest GraphBLAS::GraphBLAS ) + else ( ) + target_link_libraries( ${testname} LAGraph_static LAGraphX_static lagraphtest_static GraphBLAS::GraphBLAS ) + endif ( ) + string( REPLACE "test_" "LAGraph_" ctestname ${testname}) + add_test( NAME ${ctestname} COMMAND $ ) +# add_test( NAME ${ctestname} COMMAND valgrind $ ) + if (WIN32) + if ( BUILD_SHARED_LIBS ) + set_tests_properties ( ${ctestname} PROPERTIES + ENVIRONMENT_MODIFICATION "PATH=path_list_prepend:$;PATH=path_list_prepend:$" ) + else ( ) + set_tests_properties ( ${ctestname} PROPERTIES + ENVIRONMENT_MODIFICATION "PATH=path_list_prepend:$" ) + endif ( ) + endif ( ) endforeach( testsourcefile ${TEST_SOURCES} ) diff --git a/src/test/LG_brutal_malloc.c b/src/test/LG_brutal_malloc.c index 6db6373ef6..1af8e12cf4 100644 --- a/src/test/LG_brutal_malloc.c +++ b/src/test/LG_brutal_malloc.c @@ -19,6 +19,7 @@ // LAGr_Init. #include "LG_internal.h" +#include "LG_test.h" //------------------------------------------------------------------------------ // global variables: LG_brutal and LG_nmalloc @@ -38,14 +39,14 @@ // It is decremented by LG_brutal_free. After LAGraph_Finalize is called, // this value should be zero. If nonzero, a memory leak has occured. -int64_t LG_brutal = -1 ; -int64_t LG_nmalloc = 0 ; +LG_TEST_PUBLIC int64_t LG_brutal = -1 ; +LG_TEST_PUBLIC int64_t LG_nmalloc = 0 ; //------------------------------------------------------------------------------ // LG_brutal_malloc //------------------------------------------------------------------------------ -LAGRAPH_PUBLIC +LG_TEST_PUBLIC void *LG_brutal_malloc // return pointer to allocated block of memory ( size_t size // # of bytes to allocate @@ -83,7 +84,7 @@ void *LG_brutal_malloc // return pointer to allocated block of memory // LG_brutal_calloc //------------------------------------------------------------------------------ -LAGRAPH_PUBLIC +LG_TEST_PUBLIC void *LG_brutal_calloc // return pointer to allocated block of memory ( size_t nitems, // # of items to allocate @@ -103,7 +104,7 @@ void *LG_brutal_calloc // return pointer to allocated block of memory // LG_brutal_free //------------------------------------------------------------------------------ -LAGRAPH_PUBLIC +LG_TEST_PUBLIC void LG_brutal_free ( void *p // block to free @@ -125,7 +126,7 @@ void LG_brutal_free // LG_brutal_realloc //------------------------------------------------------------------------------ -LAGRAPH_PUBLIC +LG_TEST_PUBLIC void *LG_brutal_realloc // return pointer to reallocated memory ( void *p, // block to realloc diff --git a/src/test/LG_check_sssp.c b/src/test/LG_check_sssp.c index 4d0a20fc4a..204775c602 100644 --- a/src/test/LG_check_sssp.c +++ b/src/test/LG_check_sssp.c @@ -102,25 +102,25 @@ int LG_check_sssp { etypecode = 0 ; etypesize = sizeof (int32_t) ; - etypeinf = INT32_MAX ; + etypeinf = (double) INT32_MAX ; } else if (etype == GrB_INT64) { etypecode = 1 ; etypesize = sizeof (int64_t) ; - etypeinf = INT64_MAX ; + etypeinf = (double) INT64_MAX ; } else if (etype == GrB_UINT32) { etypecode = 2 ; etypesize = sizeof (uint32_t) ; - etypeinf = UINT32_MAX ; + etypeinf = (double) UINT32_MAX ; } else if (etype == GrB_UINT64) { etypecode = 3 ; etypesize = sizeof (uint64_t) ; - etypeinf = UINT64_MAX ; + etypeinf = (double) UINT64_MAX ; } else if (etype == GrB_FP32) { @@ -251,7 +251,7 @@ int LG_check_sssp // directly access the indices of entries in A(u,:) GrB_Index degree = Ap [u+1] - Ap [u] ; GrB_Index *node_u_adjacency_list = Aj + Ap [u] ; - void *weights = Ax + ((iso ? 0 : Ap [u]) * etypesize) ; + void *weights = ((char *) Ax) + ((iso ? 0 : Ap [u]) * etypesize) ; #else // extract the indices of entries in A(u,:) GrB_Index degree = n ; diff --git a/src/test/LG_check_tri.c b/src/test/LG_check_tri.c index 59fbff8983..9b8e426030 100644 --- a/src/test/LG_check_tri.c +++ b/src/test/LG_check_tri.c @@ -85,10 +85,11 @@ int LG_check_tri // -1 if out of memory, 0 if successful Ai = Aj ; // pretend A is symmetric and in CSC format instead // masked dot-product method + int64_t j; #if !defined ( COVERAGE ) #pragma omp parallel for reduction(+:ntriangles) schedule(dynamic,1024) #endif - for (int64_t j = 0 ; j < n ; j++) + for (j = 0 ; j < n ; j++) { // for each entry in the lower triangular part of A for (int64_t p = Ap [j] ; p < Ap [j+1] ; p++) diff --git a/src/test/include/LG_test.h b/src/test/include/LG_test.h index 337934596a..056896edf1 100644 --- a/src/test/include/LG_test.h +++ b/src/test/include/LG_test.h @@ -16,6 +16,20 @@ #include #include +#undef I + +#if ( _MSC_VER && !__INTEL_COMPILER && LG_TEST_DLL ) + #ifdef LG_TEST_LIBRARY + // compiling LAGraph itself, exporting symbols to user apps + #define LG_TEST_PUBLIC __declspec ( dllexport ) + #else + // compiling the user application, importing symbols from LAGraph + #define LG_TEST_PUBLIC __declspec ( dllimport ) + #endif +#else + // for other compilers + #define LG_TEST_PUBLIC +#endif int LG_check_bfs ( @@ -133,32 +147,32 @@ int LG_check_export // all entries cleared, if an out-of-memory failure occurs (GrB_assign // in particular). See src/test/test_vector for an example. -LAGRAPH_PUBLIC int LG_brutal_setup (char *msg) ; -LAGRAPH_PUBLIC int LG_brutal_teardown (char *msg) ; +LG_TEST_PUBLIC int LG_brutal_setup (char *msg) ; +LG_TEST_PUBLIC int LG_brutal_teardown (char *msg) ; -LAGRAPH_PUBLIC int64_t LG_brutal ; -LAGRAPH_PUBLIC int64_t LG_nmalloc ; +LG_TEST_PUBLIC extern int64_t LG_brutal ; +LG_TEST_PUBLIC extern int64_t LG_nmalloc ; -LAGRAPH_PUBLIC +LG_TEST_PUBLIC void *LG_brutal_malloc // return pointer to allocated block of memory ( size_t size // # of bytes to allocate ) ; -LAGRAPH_PUBLIC +LG_TEST_PUBLIC void *LG_brutal_calloc // return pointer to allocated block of memory ( size_t nitems, // # of items to allocate size_t itemsize // # of bytes per item ) ; -LAGRAPH_PUBLIC +LG_TEST_PUBLIC void LG_brutal_free ( void *p // block to free ) ; -LAGRAPH_PUBLIC +LG_TEST_PUBLIC void *LG_brutal_realloc // return pointer to reallocated memory ( void *p, // block to realloc diff --git a/src/test/include/acutest.h b/src/test/include/acutest.h index 1d13044f06..e853a95764 100644 --- a/src/test/include/acutest.h +++ b/src/test/include/acutest.h @@ -1541,7 +1541,7 @@ acutest_cmdline_callback_(int id, const char* arg) acutest_worker_index_ = atoi(arg); break; case 'x': - acutest_xml_output_ = fopen(arg, "w"); + acutest_xml_output_ = fopen(arg, "wb"); if (!acutest_xml_output_) { fprintf(stderr, "Unable to open '%s': %s\n", arg, strerror(errno)); acutest_exit_(2); diff --git a/src/test/test_ConnectedComponents.c b/src/test/test_ConnectedComponents.c index 9ae9fe9587..9140b2a9b4 100644 --- a/src/test/test_ConnectedComponents.c +++ b/src/test/test_ConnectedComponents.c @@ -23,6 +23,9 @@ #include "LAGraphX.h" #include "LG_alg_internal.h" +#undef NDEBUG +#include + char msg [LAGRAPH_MSG_LEN] ; LAGraph_Graph G = NULL ; #define LEN 512 @@ -82,6 +85,7 @@ void test_cc_matrices (void) { OK (LAGraph_Init (msg)) ; + // OK (GxB_set (GxB_BURBLE, true)) ; for (int k = 0 ; ; k++) { @@ -122,6 +126,7 @@ void test_cc_matrices (void) // check the result OK (LG_check_cc (C, G, msg)) ; + OK (GrB_free (&C)) ; // find the connected components with LG_CC_FastSV5 #if LAGRAPH_SUITESPARSE @@ -134,14 +139,16 @@ void test_cc_matrices (void) #endif // find the connected components with LG_CC_Boruvka + int result = GrB_SUCCESS ; printf ("\n------ CC_BORUVKA:\n") ; - OK (LG_CC_Boruvka (&C2, G, msg)) ; + result = LG_CC_Boruvka (&C2, G, msg) ; + OK (result) ; ncomponents = count_connected_components (C2) ; TEST_CHECK (ncomponents == ncomp) ; OK (LG_check_cc (C2, G, msg)) ; OK (GrB_free (&C2)) ; - int result = LG_CC_Boruvka (NULL, G, msg) ; + result = LG_CC_Boruvka (NULL, G, msg) ; TEST_CHECK (result == GrB_NULL_POINTER) ; if (trial == 0) @@ -167,7 +174,6 @@ void test_cc_matrices (void) } OK (LAGraph_Delete (&G, msg)) ; - OK (GrB_free (&C)) ; } OK (LAGraph_Finalize (msg)) ; @@ -183,8 +189,11 @@ void test_cc_errors (void) printf ("\n") ; // check for null pointers - int result = LG_CC_Boruvka (NULL, NULL, msg) ; + int result = GrB_SUCCESS ; + + result = LG_CC_Boruvka (NULL, NULL, msg) ; TEST_CHECK (result == GrB_NULL_POINTER) ; + #if LAGRAPH_SUITESPARSE result = LG_CC_FastSV6 (NULL, NULL, msg) ; TEST_CHECK (result == GrB_NULL_POINTER) ; @@ -203,6 +212,7 @@ void test_cc_errors (void) result = LG_CC_Boruvka (&C, G, msg) ; TEST_CHECK (result == -1001) ; printf ("result expected: %d msg:\n%s\n", result, msg) ; + #if LAGRAPH_SUITESPARSE result = LG_CC_FastSV6 (&C, G, msg) ; TEST_CHECK (result == -1001) ; diff --git a/src/test/test_MMRead.c b/src/test/test_MMRead.c index 51a8e449a7..48ecdafd7c 100644 --- a/src/test/test_MMRead.c +++ b/src/test/test_MMRead.c @@ -467,7 +467,7 @@ void test_MMWrite (void) // create a file for comments //---------------------------------------------------------------------- - FILE *fcomments = fopen (LG_DATA_DIR "comments.txt", "w") ; + FILE *fcomments = fopen (LG_DATA_DIR "comments.txt", "wb") ; TEST_CHECK (fcomments != NULL) ; fprintf (fcomments, " comments for %s\n", aname) ; fprintf (fcomments, " this file was created by test_MMRead.c\n") ; @@ -480,7 +480,7 @@ void test_MMWrite (void) snprintf (filename, LEN, LG_DATA_DIR "comments_%s", aname) ; fcomments = fopen (LG_DATA_DIR "comments.txt", "r") ; - FILE *foutput = fopen (filename, "w") ; + FILE *foutput = fopen (filename, "wb") ; TEST_CHECK (foutput != NULL) ; TEST_CHECK (fcomments != NULL) ; OK (LAGraph_MMWrite (A, foutput, fcomments, msg)) ; @@ -520,7 +520,7 @@ void test_MMWrite (void) double a ; OK (GrB_Matrix_extractElement (&a, A, 0, 0)) ; TEST_CHECK (isnan (a)) ; - foutput = fopen (filename, "w") ; + foutput = fopen (filename, "wb") ; fcomments = fopen (LG_DATA_DIR "comments.txt", "r") ; TEST_CHECK (foutput != NULL) ; OK (LAGraph_MMWrite (A, foutput, fcomments, msg)) ; @@ -724,7 +724,7 @@ void test_array_pattern ( ) // write it to a temporary file //-------------------------------------------------------------------------- - FILE *f = tmpfile ( ) ; // fopen ("/tmp/mine.mtx", "w") ; + FILE *f = tmpfile ( ) ; // fopen ("/tmp/mine.mtx", "wb") ; OK (LAGraph_MMWrite (A, f, NULL, msg)) ; TEST_MSG ("Failed to write matrix to a temp file\n") ; // OK (fclose (f)) ; diff --git a/src/test/test_Malloc.c b/src/test/test_Malloc.c index a28f73a3a4..9b1c531944 100644 --- a/src/test/test_Malloc.c +++ b/src/test/test_Malloc.c @@ -36,11 +36,15 @@ void test_malloc (void) OK (LAGraph_Free ((void **) &p, msg)) ; TEST_CHECK (p == NULL) ; - LAGraph_Malloc ((void **) &p, GrB_INDEX_MAX + 1, sizeof (char), msg) ; - TEST_CHECK (p == NULL) ; + size_t huge = 1 + SIZE_MAX/2 ; - LAGraph_Calloc ((void **) &p, GrB_INDEX_MAX + 1, sizeof (char), msg) ; - TEST_CHECK (p == NULL) ; + if (sizeof (size_t) >= sizeof (uint64_t)) + { + LAGraph_Malloc ((void **) &p, huge, sizeof (char), msg) ; + TEST_CHECK (p == NULL) ; // was FAIL + LAGraph_Calloc ((void **) &p, huge, sizeof (char), msg) ; + TEST_CHECK (p == NULL) ; // was FAIL + } OK (LAGraph_Calloc ((void **) &p, 42, sizeof (char), msg)) ; for (int k = 0 ; k < 42 ; k++) @@ -74,18 +78,22 @@ void test_malloc (void) TEST_CHECK (p == NULL) ; OK (LAGraph_Realloc ((void **) &p, 80, 0, sizeof (char), msg)) ; + + if (sizeof (size_t) >= sizeof (uint64_t)) + { + int s = (LAGraph_Realloc ((void **) &p, huge, 80, sizeof (char), msg)) ; + TEST_CHECK (s == GrB_OUT_OF_MEMORY) ; // was FAIL + } + for (int k = 0 ; k < 80 ; k++) { p [k] = (char) k ; } - int status = (LAGraph_Realloc ((void **) &p, GrB_INDEX_MAX+1, 80, sizeof (char), msg)) ; - TEST_CHECK (status == GrB_OUT_OF_MEMORY) ; - OK (LAGraph_Realloc ((void **) &p, 80, 80, sizeof (char), msg)) ; for (int k = 0 ; k < 80 ; k++) { - TEST_CHECK (p [k] == (char) k) ; + TEST_CHECK (p [k] == (char) k) ; // was FAIL } LAGraph_Realloc_function = NULL ; @@ -93,7 +101,7 @@ void test_malloc (void) OK (LAGraph_Realloc ((void **) &p, 100, 80, sizeof (char), msg)) ; for (int k = 0 ; k < 80 ; k++) { - TEST_CHECK (p [k] == (char) k) ; + TEST_CHECK (p [k] == (char) k) ; // was FAIL } OK (LAGraph_Free ((void **) &p, NULL)) ; diff --git a/src/test/test_Xinit.c b/src/test/test_Xinit.c index 064e8ab991..a968cdd8cb 100644 --- a/src/test/test_Xinit.c +++ b/src/test/test_Xinit.c @@ -2,7 +2,7 @@ // LAGraph/src/test/test_Xinit.c: test LAGr_Init and LAGraph_Global //------------------------------------------------------------------------------ -// LAGraph, (c) 2019-2022 by The LAGraph Contributors, All Rights Reserved. +// LAGraph, (c) 2019-2023 by The LAGraph Contributors, All Rights Reserved. // SPDX-License-Identifier: BSD-2-Clause // // For additional details (including references to third party source code and @@ -16,6 +16,11 @@ //------------------------------------------------------------------------------ #include "LAGraph_test.h" +#include "LAGraphX.h" + +// functions defined in LAGr_Init.c: +LAGRAPH_PUBLIC void LG_set_LAGr_Init_has_been_called (bool setting) ; +LAGRAPH_PUBLIC bool LG_get_LAGr_Init_has_been_called (void) ; //------------------------------------------------------------------------------ // global variables @@ -30,30 +35,43 @@ char msg [LAGRAPH_MSG_LEN] ; void test_Xinit (void) { - printf ("\nTesting LAGr_Init:\n") ; + printf ("\nTesting LAGr_Init: with expected errors\n") ; TEST_CHECK (LAGr_Init (GrB_NONBLOCKING, NULL, NULL, NULL, NULL, msg) == GrB_NULL_POINTER) ; - printf ("msg: %s\n", msg) ; + printf ("msg: [%s]\n", msg) ; TEST_CHECK (LAGr_Init (GrB_NONBLOCKING, malloc, NULL, NULL, NULL, msg) == GrB_NULL_POINTER) ; - printf ("msg: %s\n", msg) ; + printf ("msg: [%s]\n", msg) ; TEST_CHECK (LAGr_Init (GrB_NONBLOCKING, NULL, NULL, NULL, free, msg) == GrB_NULL_POINTER) ; - printf ("msg: %s\n", msg) ; + printf ("msg: [%s]\n", msg) ; OK (LAGr_Init (GrB_NONBLOCKING, malloc, calloc, realloc, free, msg)) ; printf ("msg: [%s]\n", msg) ; + TEST_CHECK (LG_get_LAGr_Init_has_been_called ( ) == true) ; // LAGr_Init cannot be called twice int status = LAGr_Init (GrB_NONBLOCKING, malloc, calloc, realloc, free, msg) ; TEST_CHECK (status != GrB_SUCCESS) ; - printf ("msg: %s\n", msg) ; + printf ("msg: [%s]\n", msg) ; OK (LAGraph_Finalize (msg)) ; + + // the flag is still set after LAGraph_Finalize has been called, + // per LAGraph policy + TEST_CHECK (LG_get_LAGr_Init_has_been_called ( ) == true) ; + + // reset and try again + LG_set_LAGr_Init_has_been_called (false) ; + TEST_CHECK (LG_get_LAGr_Init_has_been_called ( ) == false) ; + OK (LAGr_Init (GrB_NONBLOCKING, malloc, calloc, realloc, free, msg)) ; + TEST_CHECK (LG_get_LAGr_Init_has_been_called ( ) == true) ; + OK (LAGraph_Finalize (msg)) ; + TEST_CHECK (LG_get_LAGr_Init_has_been_called ( ) == true) ; } //------------------------------------------------------------------------------ @@ -61,7 +79,6 @@ void test_Xinit (void) //------------------------------------------------------------------------------ #if LAGRAPH_SUITESPARSE -LAGRAPH_PUBLIC bool LG_init_has_been_called ; void test_Xinit_brutal (void) { // no brutal memory failures, but test LG_brutal_malloc/calloc/realloc/free @@ -127,22 +144,29 @@ void test_Xinit_brutal (void) } } + TEST_CHECK (LG_get_LAGr_Init_has_been_called ( ) == true) ; + for (int nbrutal = 0 ; nbrutal < 1000 ; nbrutal++) { LG_brutal = nbrutal ; + // reset both GraphBLAS and LAGraph GB_Global_GrB_init_called_set (false) ; - LG_init_has_been_called = false ; + LG_set_LAGr_Init_has_been_called (false) ; + TEST_CHECK (LG_get_LAGr_Init_has_been_called ( ) == false) ; + // try to initialize GraphBLAS and LAGraph int result = LAGr_Init (GrB_NONBLOCKING, LG_brutal_malloc, LG_brutal_calloc, LG_brutal_realloc, LG_brutal_free, msg) ; if (result == 0) { + // success OK (LAGraph_Finalize (msg)) ; printf ("LAGr_Init: finally: %d %g\n", nbrutal, (double) LG_nmalloc) ; TEST_CHECK (LG_nmalloc == 0) ; break ; } + // failure: free anything partially allocated OK (LAGraph_Finalize (msg)) ; } } diff --git a/src/test/test_minmax.c b/src/test/test_minmax.c index 540d573b9e..799a9077c0 100644 --- a/src/test/test_minmax.c +++ b/src/test/test_minmax.c @@ -80,7 +80,7 @@ const matrix_info files [ ] = { 1, 1, "matrix_fp32_structure.mtx" } , { -INFINITY, INFINITY, "matrix_fp64.mtx" } , { -32768, 32767, "matrix_int16.mtx" } , - { -2147483648, 2147483647, "matrix_int32.mtx" } , + { -2147483648.0, 2147483647, "matrix_int32.mtx" } , { -128, 127, "matrix_int8.mtx" } , { 0, 65535, "matrix_uint16.mtx" } , { 0, 4294967295, "matrix_uint32.mtx" } , @@ -185,7 +185,7 @@ void test_minmax (void) TEST_CASE (aname) ; printf ("\n============= %2d: %s\n", k, aname) ; snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ; - FILE *f = fopen (filename, "r") ; + FILE *f = fopen (filename, "rb") ; TEST_CHECK (f != NULL) ; OK (LAGraph_MMRead (&A, f, msg)) ; OK (fclose (f)) ; @@ -212,6 +212,10 @@ void test_minmax (void) double emin2 = 0 ; double emax2 = 0 ; + printf ("min/max as GrB_Scalars:\n") ; + GxB_print (G->emin, 3) ; + GxB_print (G->emax, 3) ; + int result ; result = GrB_Scalar_extractElement_FP64 (&emin2, G->emin) ; printf ("min: %g %g err %g\n", emin1, emin2, emin1 - emin2) ; @@ -223,6 +227,29 @@ void test_minmax (void) { TEST_CHECK (result == GrB_SUCCESS) ; } + + #if 0 + if (emin1 != emin2) + { + // failure on MSVC, OpenMP + // https://github.com/DrTimothyAldenDavis/SuiteSparse/actions/runs/6763376325/job/18380420493?pr=503 + // now fixed. + printf ("Test failure, k: %d name: %s\n", k, aname) ; + printf ("emin1: %30.20g\n", emin1) ; + printf ("emin2: %30.20g\n", emin2) ; + OK (LAGraph_Matrix_Print (G->A, 5, stdout, msg)) ; + + // extract as int64: + int64_t emin2_int64 = 0 ; + int64_t emax2_int64 = 0 ; + GrB_Scalar_extractElement_INT64 (&emin2_int64, G->emin) ; + GrB_Scalar_extractElement_INT64 (&emax2_int64, G->emax) ; + printf ("emin2 int64: %" PRId64 "\n", emin2_int64) ; + printf ("emax2 int64: %" PRId64 "\n", emax2_int64) ; + + } + #endif + TEST_CHECK (emin1 == emin2) ; result = GrB_Scalar_extractElement_FP64 (&emax2, G->emax) ; @@ -273,7 +300,7 @@ void test_minmax_int64 (void) TEST_CASE (aname) ; printf ("\n============= %2d: %s\n", k, aname) ; snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ; - FILE *f = fopen (filename, "r") ; + FILE *f = fopen (filename, "rb") ; TEST_CHECK (f != NULL) ; OK (LAGraph_MMRead (&A, f, msg)) ; OK (fclose (f)) ; @@ -350,7 +377,7 @@ void test_minmax_uint64 (void) TEST_CASE (aname) ; printf ("\n============= %2d: %s\n", k, aname) ; snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ; - FILE *f = fopen (filename, "r") ; + FILE *f = fopen (filename, "rb") ; TEST_CHECK (f != NULL) ; OK (LAGraph_MMRead (&A, f, msg)) ; OK (fclose (f)) ; diff --git a/src/utility/LAGr_Init.c b/src/utility/LAGr_Init.c index 29146ac94b..31f3e449a6 100644 --- a/src/utility/LAGr_Init.c +++ b/src/utility/LAGr_Init.c @@ -2,7 +2,7 @@ // LAGr_Init: start GraphBLAS and LAGraph, and set malloc/etc functions //------------------------------------------------------------------------------ -// LAGraph, (c) 2019-2022 by The LAGraph Contributors, All Rights Reserved. +// LAGraph, (c) 2019-2023 by The LAGraph Contributors, All Rights Reserved. // SPDX-License-Identifier: BSD-2-Clause // // For additional details (including references to third party source code and @@ -20,66 +20,95 @@ #include "LG_internal.h" //------------------------------------------------------------------------------ -// LAGraph global objects +// LG_LAGr_Init_has_been_called: a static value only accessible within this file //------------------------------------------------------------------------------ -bool LG_init_has_been_called = false ; +// LG_LAGr_Init_has_been_called indicates if LAGr_Init has been called. +// LAGr_Init (or LAGraph_Init) can be called only once, even after +// LAGraph_Finalize has been called. For testing purposes, the flag can be +// cleared by src/test/test_Xinit, to allow LAGr_Init or LAGraph_Init to be +// called again. + +static bool LG_LAGr_Init_has_been_called = false ; + +// LG_LAGr_Init_has_been_called is only modified or accessed by the following +// two routines (even in this file). The two functions are made accessible via +// LAGRAPH_PUBLIC, only for testing purposes by src/test/test_Xinit.c. + +LAGRAPH_PUBLIC void LG_set_LAGr_Init_has_been_called (bool setting) ; +LAGRAPH_PUBLIC bool LG_get_LAGr_Init_has_been_called (void) ; + +LAGRAPH_PUBLIC +void LG_set_LAGr_Init_has_been_called (bool setting) +{ + LG_LAGr_Init_has_been_called = setting ; +} + +LAGRAPH_PUBLIC +bool LG_get_LAGr_Init_has_been_called (void) +{ + return (LG_LAGr_Init_has_been_called) ; +} + +//------------------------------------------------------------------------------ +// LAGraph global objects +//------------------------------------------------------------------------------ // LAGraph_plus_first_T: using the GrB_PLUS_MONOID_T monoid and the // corresponding GrB_FIRST_T multiplicative operator. -GrB_Semiring LAGraph_plus_first_int8 = NULL ; -GrB_Semiring LAGraph_plus_first_int16 = NULL ; -GrB_Semiring LAGraph_plus_first_int32 = NULL ; -GrB_Semiring LAGraph_plus_first_int64 = NULL ; -GrB_Semiring LAGraph_plus_first_uint8 = NULL ; -GrB_Semiring LAGraph_plus_first_uint16 = NULL ; -GrB_Semiring LAGraph_plus_first_uint32 = NULL ; -GrB_Semiring LAGraph_plus_first_uint64 = NULL ; -GrB_Semiring LAGraph_plus_first_fp32 = NULL ; -GrB_Semiring LAGraph_plus_first_fp64 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_int8 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_int16 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_int32 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_int64 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_uint8 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_uint16 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_uint32 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_uint64 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_fp32 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_first_fp64 = NULL ; // LAGraph_plus_second_T: using the GrB_PLUS_MONOID_T monoid and the // corresponding GrB_SECOND_T multiplicative operator. -GrB_Semiring LAGraph_plus_second_int8 = NULL ; -GrB_Semiring LAGraph_plus_second_int16 = NULL ; -GrB_Semiring LAGraph_plus_second_int32 = NULL ; -GrB_Semiring LAGraph_plus_second_int64 = NULL ; -GrB_Semiring LAGraph_plus_second_uint8 = NULL ; -GrB_Semiring LAGraph_plus_second_uint16 = NULL ; -GrB_Semiring LAGraph_plus_second_uint32 = NULL ; -GrB_Semiring LAGraph_plus_second_uint64 = NULL ; -GrB_Semiring LAGraph_plus_second_fp32 = NULL ; -GrB_Semiring LAGraph_plus_second_fp64 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_int8 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_int16 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_int32 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_int64 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_uint8 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_uint16 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_uint32 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_uint64 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_fp32 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_second_fp64 = NULL ; // LAGraph_plus_one_T: using the GrB_PLUS_MONOID_T monoid and the // corresponding GrB_ONEB_T multiplicative operator. -GrB_Semiring LAGraph_plus_one_int8 = NULL ; -GrB_Semiring LAGraph_plus_one_int16 = NULL ; -GrB_Semiring LAGraph_plus_one_int32 = NULL ; -GrB_Semiring LAGraph_plus_one_int64 = NULL ; -GrB_Semiring LAGraph_plus_one_uint8 = NULL ; -GrB_Semiring LAGraph_plus_one_uint16 = NULL ; -GrB_Semiring LAGraph_plus_one_uint32 = NULL ; -GrB_Semiring LAGraph_plus_one_uint64 = NULL ; -GrB_Semiring LAGraph_plus_one_fp32 = NULL ; -GrB_Semiring LAGraph_plus_one_fp64 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_int8 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_int16 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_int32 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_int64 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_uint8 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_uint16 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_uint32 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_uint64 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_fp32 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_plus_one_fp64 = NULL ; // use LAGraph_any_one_bool, etc // LAGraph_any_one_T: using the GrB_MIN_MONOID_T for non-boolean types // or GrB_LOR_MONOID_BOOL for boolean, and the GrB_ONEB_T multiplicative op. -GrB_Semiring LAGraph_any_one_bool = NULL ; -GrB_Semiring LAGraph_any_one_int8 = NULL ; -GrB_Semiring LAGraph_any_one_int16 = NULL ; -GrB_Semiring LAGraph_any_one_int32 = NULL ; -GrB_Semiring LAGraph_any_one_int64 = NULL ; -GrB_Semiring LAGraph_any_one_uint8 = NULL ; -GrB_Semiring LAGraph_any_one_uint16 = NULL ; -GrB_Semiring LAGraph_any_one_uint32 = NULL ; -GrB_Semiring LAGraph_any_one_uint64 = NULL ; -GrB_Semiring LAGraph_any_one_fp32 = NULL ; -GrB_Semiring LAGraph_any_one_fp64 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_bool = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_int8 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_int16 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_int32 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_int64 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_uint8 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_uint16 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_uint32 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_uint64 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_fp32 = NULL ; +LAGRAPH_PUBLIC GrB_Semiring LAGraph_any_one_fp64 = NULL ; //------------------------------------------------------------------------------ // LAGr_Init @@ -109,9 +138,8 @@ int LAGr_Init GrB_Info info ; // ensure LAGr_Init has not already been called - LG_ASSERT_MSG (!LG_init_has_been_called, GrB_INVALID_VALUE, + LG_ASSERT_MSG (!LG_get_LAGr_Init_has_been_called ( ), GrB_INVALID_VALUE, "LAGr*_Init can only be called once") ; - LG_init_has_been_called = true ; //-------------------------------------------------------------------------- // start GraphBLAS @@ -297,5 +325,7 @@ int LAGr_Init GRB_TRY (GrB_Semiring_new (&LAGraph_any_one_fp64, GrB_MIN_MONOID_FP64 , GrB_ONEB_FP64 )) ; + LG_set_LAGr_Init_has_been_called (true) ; return (GrB_SUCCESS) ; } + diff --git a/src/utility/LAGr_SortByDegree.c b/src/utility/LAGr_SortByDegree.c index c2ed0aefc9..3e1f16a642 100644 --- a/src/utility/LAGr_SortByDegree.c +++ b/src/utility/LAGr_SortByDegree.c @@ -118,8 +118,9 @@ int LAGr_SortByDegree // construct the pair [D,P] to sort //-------------------------------------------------------------------------- + int64_t k; #pragma omp parallel for num_threads(nthreads) schedule(static) - for (int64_t k = 0 ; k < n ; k++) + for (k = 0 ; k < n ; k++) { D [k] = 0 ; P [k] = k ; @@ -133,7 +134,7 @@ int LAGr_SortByDegree { // sort [D,P] in ascending order of degree, tie-breaking on P #pragma omp parallel for num_threads(nthreads) schedule(static) - for (int64_t k = 0 ; k < nvals ; k++) + for (k = 0 ; k < nvals ; k++) { D [W0 [k]] = W1 [k] ; } @@ -142,7 +143,7 @@ int LAGr_SortByDegree { // sort [D,P] in descending order of degree, tie-breaking on P #pragma omp parallel for num_threads(nthreads) schedule(static) - for (int64_t k = 0 ; k < nvals ; k++) + for (k = 0 ; k < nvals ; k++) { D [W0 [k]] = -W1 [k] ; } diff --git a/src/utility/LAGraph_Calloc.c b/src/utility/LAGraph_Calloc.c index 17690d970d..23f5ffc630 100644 --- a/src/utility/LAGraph_Calloc.c +++ b/src/utility/LAGraph_Calloc.c @@ -40,8 +40,7 @@ int LAGraph_Calloc // compute the size and check for integer overflow size_t size ; - bool ok = LG_Multiply_size_t (&size, nitems, size_of_item) ; - if (!ok || nitems > GrB_INDEX_MAX || size_of_item > GrB_INDEX_MAX) + if (!LG_Multiply_size_t (&size, nitems, size_of_item)) { // overflow return (GrB_OUT_OF_MEMORY) ; diff --git a/src/utility/LAGraph_Global.c b/src/utility/LAGraph_Global.c index a74320f2d2..c102d297d8 100644 --- a/src/utility/LAGraph_Global.c +++ b/src/utility/LAGraph_Global.c @@ -22,10 +22,10 @@ //------------------------------------------------------------------------------ // These are modified by LAGraph_Init and LAGr_Init: -void * (* LAGraph_Malloc_function ) (size_t) = malloc ; -void * (* LAGraph_Calloc_function ) (size_t, size_t) = calloc ; -void * (* LAGraph_Realloc_function ) (void *, size_t) = realloc ; -void (* LAGraph_Free_function ) (void *) = free ; +LAGRAPH_PUBLIC void * (* LAGraph_Malloc_function ) (size_t) = malloc ; +LAGRAPH_PUBLIC void * (* LAGraph_Calloc_function ) (size_t, size_t) = calloc ; +LAGRAPH_PUBLIC void * (* LAGraph_Realloc_function ) (void *, size_t) = realloc ; +LAGRAPH_PUBLIC void (* LAGraph_Free_function ) (void *) = free ; //------------------------------------------------------------------------------ // threading control diff --git a/src/utility/LAGraph_Malloc.c b/src/utility/LAGraph_Malloc.c index 98461ad1a0..a178c3c316 100644 --- a/src/utility/LAGraph_Malloc.c +++ b/src/utility/LAGraph_Malloc.c @@ -40,8 +40,7 @@ int LAGraph_Malloc // compute the size and check for integer overflow size_t size ; - bool ok = LG_Multiply_size_t (&size, nitems, size_of_item) ; - if (!ok || nitems > GrB_INDEX_MAX || size_of_item > GrB_INDEX_MAX) + if (!LG_Multiply_size_t (&size, nitems, size_of_item)) { // overflow return (GrB_OUT_OF_MEMORY) ; diff --git a/src/utility/LAGraph_Realloc.c b/src/utility/LAGraph_Realloc.c index 4e1c4387b2..7e118d763c 100644 --- a/src/utility/LAGraph_Realloc.c +++ b/src/utility/LAGraph_Realloc.c @@ -82,8 +82,7 @@ int LAGraph_Realloc size_t newsize, oldsize ; bool ok = LG_Multiply_size_t (&newsize, nitems_new, size_of_item) && LG_Multiply_size_t (&oldsize, nitems_old, size_of_item) ; - - if (!ok || nitems_new > GrB_INDEX_MAX || size_of_item > GrB_INDEX_MAX) + if (!ok) { // overflow return (GrB_OUT_OF_MEMORY) ; diff --git a/src/utility/LG_internal.h b/src/utility/LG_internal.h index 30bc9e24ab..5935dfd25a 100644 --- a/src/utility/LG_internal.h +++ b/src/utility/LG_internal.h @@ -25,9 +25,9 @@ // include files //------------------------------------------------------------------------------ -#define LG_LIBRARY #include #include "LAGraph.h" +#undef I #if defined ( __linux__ ) #include @@ -353,11 +353,11 @@ MM_storage_enum ; // LG_PART and LG_PARTITION: definitions for partitioning an index range //------------------------------------------------------------------------------ -LAGRAPH_PUBLIC +LAGRAPH_PUBLIC extern int LG_nthreads_outer ; // # of threads to use at the higher level of a nested // parallel region in LAGraph. Default: 1. -LAGRAPH_PUBLIC +LAGRAPH_PUBLIC extern int LG_nthreads_inner ; // # of threads to use at the lower level of a nested // parallel region, or to use inside GraphBLAS. // Default: the value obtained by omp_get_max_threads diff --git a/src/utility/LG_msort1.c b/src/utility/LG_msort1.c index 4d8f8ec68d..b69a8ad9a2 100644 --- a/src/utility/LG_msort1.c +++ b/src/utility/LG_msort1.c @@ -409,7 +409,7 @@ int LG_msort1 // already sorted with respect to each other. // this could be done in parallel if ntasks was large - for (int tid = 0 ; tid < ntasks ; tid += 2*nt) + for (tid = 0 ; tid < ntasks ; tid += 2*nt) { // create 2*nt tasks to merge two A sublists into one W sublist LG_msort_1b_create_merge_tasks ( @@ -438,7 +438,7 @@ int LG_msort1 //---------------------------------------------------------------------- // this could be done in parallel if ntasks was large - for (int tid = 0 ; tid < ntasks ; tid += 2*nt) + for (tid = 0 ; tid < ntasks ; tid += 2*nt) { // create 2*nt tasks to merge two W sublists into one A sublist LG_msort_1b_create_merge_tasks ( diff --git a/src/utility/LG_msort2.c b/src/utility/LG_msort2.c index 14159c4e7d..f7baa47312 100644 --- a/src/utility/LG_msort2.c +++ b/src/utility/LG_msort2.c @@ -427,7 +427,7 @@ int LG_msort2 // already sorted with respect to each other. // this could be done in parallel if ntasks was large - for (int tid = 0 ; tid < ntasks ; tid += 2*nt) + for (tid = 0 ; tid < ntasks ; tid += 2*nt) { // create 2*nt tasks to merge two A sublists into one W sublist LG_msort_2b_create_merge_tasks ( @@ -456,7 +456,7 @@ int LG_msort2 //---------------------------------------------------------------------- // this could be done in parallel if ntasks was large - for (int tid = 0 ; tid < ntasks ; tid += 2*nt) + for (tid = 0 ; tid < ntasks ; tid += 2*nt) { // create 2*nt tasks to merge two W sublists into one A sublist LG_msort_2b_create_merge_tasks ( diff --git a/src/utility/LG_msort3.c b/src/utility/LG_msort3.c index f46ed6203e..031d4a302f 100644 --- a/src/utility/LG_msort3.c +++ b/src/utility/LG_msort3.c @@ -440,7 +440,7 @@ int LG_msort3 //---------------------------------------------------------------------- // this could be done in parallel if ntasks was large - for (int tid = 0 ; tid < ntasks ; tid += 2*nt) + for (tid = 0 ; tid < ntasks ; tid += 2*nt) { // create 2*nt tasks to merge two A sublists into one W sublist LG_msort_3b_create_merge_tasks ( @@ -469,7 +469,7 @@ int LG_msort3 //---------------------------------------------------------------------- // this could be done in parallel if ntasks was large - for (int tid = 0 ; tid < ntasks ; tid += 2*nt) + for (tid = 0 ; tid < ntasks ; tid += 2*nt) { // create 2*nt tasks to merge two W sublists into one A sublist LG_msort_3b_create_merge_tasks (