diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..49e7a27f --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# line endings in repository match line endings on disc +* -text diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..dfde282e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,28 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior. + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - compiler [e.g. gcc 7.4, icc 19.0] + - BLAS and LAPACK library, if applicable + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..bbcbbe7d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..df4d15b3 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 +updates: + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + # Check for updates to GitHub Actions every week + interval: "weekly" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..94813bcc --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1 @@ +No pull request can be accepted unless you first sign the Contributor License Agreement [ CONTRIBUTOR-LICENSE.txt ]. Print it as a PDF and email me a signed PDF (digital signature OK). Submit all PRs to the dev2 branch only. diff --git a/.github/workflows/build-arch-emu.yaml b/.github/workflows/build-arch-emu.yaml new file mode 100644 index 00000000..3c91029f --- /dev/null +++ b/.github/workflows/build-arch-emu.yaml @@ -0,0 +1,195 @@ +name: arch-emu +on: + workflow_dispatch: + push: + branches-ignore: + - '**/dev2' + - '**/*dev2' + pull_request: + +concurrency: ci-arch-emu-${{ github.ref }} + +env: + # string with name of libraries to be built + BUILD_LIBS: "SuiteSparse_config:AMD:COLAMD:SPEX" + # string with name of libraries to be checked + CHECK_LIBS: "SuiteSparse_config:AMD:COLAMD:SPEX" + # string with name of libraries that are installed + INSTALLED_LIBS: "SuiteSparse_config:AMD:COLAMD:SPEX" + + +jobs: + + alpine: + runs-on: ubuntu-latest + + defaults: + run: + # Use emulated shell as default + shell: alpine.sh {0} + + strategy: + # Allow other runners in the matrix to continue if some fail + fail-fast: false + + matrix: + # For available CPU architectures, see: + # https://github.com/marketplace/actions/setup-alpine-linux-environment + arch: [x86, aarch64, armv7, ppc64le, s390x] + include: + - arch: x86 + ccache-max: 80M + - arch: aarch64 + ccache-max: 42M + - arch: armv7 + ccache-max: 42M + - arch: ppc64le + ccache-max: 45M + - arch: s390x + ccache-max: 42M + + name: alpine (${{ matrix.arch }}) + + steps: + - name: get CPU information (host) + shell: bash + run: lscpu + + - name: checkout repository + uses: actions/checkout@v4 + # shell: bash + + - name: install dependencies + uses: jirutka/setup-alpine@v1 + # shell: bash + with: + arch: ${{ matrix.arch }} + packages: > + build-base + ccache + cmake + gfortran + m4 + gmp-dev + mpfr-dev + lapack-dev + python3 + valgrind + util-linux-misc + autoconf + automake + libtool + + - name: get CPU information (emulated) + run: lscpu + + - name: prepare ccache + # create key with human readable timestamp + # used in action/cache/restore and action/cache/save steps + id: ccache-prepare + run: | + echo "key=ccache:alpine:${{ matrix.arch }}:${{ github.ref }}:$(date +"%Y-%m-%d_%H-%M-%S"):${{ github.sha }}" >> $GITHUB_OUTPUT + + - name: restore ccache + # setup the GitHub cache used to maintain the ccache from one job to the next + uses: actions/cache/restore@v4 + with: + # location of the ccache of the chroot in the root file system + path: /home/runner/rootfs/alpine-latest-${{ matrix.arch }}/home/runner/.ccache + key: ${{ steps.ccache-prepare.outputs.key }} + # Prefer caches from the same branch. Fall back to caches from the dev branch. + restore-keys: | + ccache:alpine:${{ matrix.arch }}:${{ github.ref }} + ccache:alpine:${{ matrix.arch }} + + - name: configure ccache + env: + CCACHE_MAX: ${{ matrix.ccache-max }} + run: | + test -d ~/.ccache || mkdir ~/.ccache + echo "max_size = $CCACHE_MAX" >> ~/.ccache/ccache.conf + echo "compression = true" >> ~/.ccache/ccache.conf + ccache -s + which ccache + # echo "/usr/lib/ccache" >> $GITHUB_PATH + + - name: build + run: | + echo "gcc --version" + gcc --version + echo "gcc -dumpmachine" + gcc -dumpmachine + IFS=: + BUILD_LIBS="${BUILD_LIBS}${{ matrix.extra-build-libs }}" + for lib in ${BUILD_LIBS}; do + printf " \033[0;32m==>\033[0m Building library \033[0;32m${lib}\033[0m\n" + echo "::group::Configure $lib" + cd ${GITHUB_WORKSPACE}/${lib}/build + cmake -DCMAKE_BUILD_TYPE="Release" \ + -DCMAKE_INSTALL_PREFIX="${GITHUB_WORKSPACE}" \ + -DCMAKE_C_COMPILER_LAUNCHER="ccache" \ + -DCMAKE_CXX_COMPILER_LAUNCHER="ccache" \ + -DCMAKE_Fortran_COMPILER_LAUNCHER="ccache" \ + -DBUILD_SHARED_LIBS=ON \ + -DBUILD_STATIC_LIBS=OFF \ + -DBLA_VENDOR="Generic" \ + -DGRAPHBLAS_COMPACT=ON \ + -DSUITESPARSE_DEMOS=OFF \ + -DBUILD_TESTING=OFF \ + .. + echo "::endgroup::" + echo "::group::Build $lib" + cmake --build . --config Release + echo "::endgroup::" + done + + - name: check + timeout-minutes: 60 + run: | + IFS=':' + CHECK_LIBS="${CHECK_LIBS}${{ matrix.extra-check-libs }}" + for lib in ${CHECK_LIBS}; do + printf "::group:: \033[0;32m==>\033[0m Checking library \033[0;32m${lib}\033[0m\n" + cd ${GITHUB_WORKSPACE}/${lib} + make demos CMAKE_OPTIONS="-DSUITESPARSE_DEMOS=ON -DBUILD_TESTING=ON" + echo "::endgroup::" + done + + - name: ccache status + continue-on-error: true + run: ccache -s + + - name: save ccache + # Save the cache after we are done (successfully) building + # This helps to retain the ccache even if the subsequent steps are failing. + uses: actions/cache/save@v4 + with: + path: /home/runner/rootfs/alpine-latest-${{ matrix.arch }}/home/runner/.ccache + key: ${{ steps.ccache-prepare.outputs.key }} + + - name: install + run: | + IFS=':' + BUILD_LIBS="${BUILD_LIBS}${{ matrix.extra-build-libs }}" + for lib in ${BUILD_LIBS}; do + printf "::group::\033[0;32m==>\033[0m Installing library \033[0;32m${lib}\033[0m\n" + cd ${GITHUB_WORKSPACE}/${lib}/build + cmake --install . + echo "::endgroup::" + done + + - name: test Config + run: | + IFS=: + INSTALLED_LIBS="${INSTALLED_LIBS}${{ matrix.extra-build-libs }}" + for lib in ${INSTALLED_LIBS}; do + printf "::group:: \033[0;32m==>\033[0m Building with Config.cmake with library \033[0;32m${lib}\033[0m\n" + cd ${GITHUB_WORKSPACE}/TestConfig/${lib} + cd build + cmake \ + -DCMAKE_PREFIX_PATH="${GITHUB_WORKSPACE}/lib/cmake" \ + .. + cmake --build . --config Release + echo "::endgroup::" + done + diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 00000000..1d6b8535 --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,399 @@ +name: build +on: + workflow_dispatch: + push: + branches-ignore: + - '**/dev2' + - '**/*dev2' + pull_request: + +concurrency: ci-${{ github.ref }} + +env: + # string with name of libraries to be built + BUILD_LIBS: "SuiteSparse_config:AMD:COLAMD:SPEX" + # string with name of libraries to be checked + CHECK_LIBS: "SuiteSparse_config:AMD:COLAMD:SPEX" + # string with name of libraries that are installed + INSTALLED_LIBS: "SuiteSparse_config:AMD:COLAMD:SPEX" + +jobs: + + ubuntu: + # For available GitHub-hosted runners, see: + # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners + runs-on: ubuntu-latest + + name: ubuntu (${{ matrix.compiler }} ${{ matrix.cuda }} CUDA ${{ matrix.openmp }} OpenMP, ${{ matrix.link }}) + + strategy: + # Allow other runners in the matrix to continue if some fail + fail-fast: false + + matrix: + compiler: [gcc, clang] + cuda: [without] + openmp: [with] + link: [both] + include: + - compiler: gcc + compiler-pkgs: "g++ gcc" + cc: "gcc" + cxx: "g++" + - compiler: clang + compiler-pkgs: "clang libomp-dev" + cc: "clang" + cxx: "clang++" + # Clang seems to generally require less cache size (smaller object files?). + - compiler: gcc + ccache-max: 600M + - compiler: clang + ccache-max: 500M + - cuda: without +# - cuda: with +# cuda-pkgs: "nvidia-cuda-dev nvidia-cuda-toolkit" +# cuda-cmake-flags: +# -DSUITESPARSE_USE_CUDA=ON +# -DSUITESPARSE_USE_STRICT=ON +# -DCUDAToolkit_INCLUDE_DIRS="/usr/include" +# -DCMAKE_CUDA_COMPILER_LAUNCHER="ccache" + - compiler: gcc + compiler-pkgs: "g++ gcc" + cc: "gcc" + cxx: "g++" + ccache-max: 600M + cuda: without + openmp: without + openmp-cmake-flags: "-DSUITESPARSE_USE_OPENMP=OFF" + - compiler: gcc + compiler-pkgs: "g++ gcc" + cc: "gcc" + cxx: "g++" + ccache-max: 600M + cuda: without +# cuda: with +# cuda-pkgs: "nvidia-cuda-dev nvidia-cuda-toolkit" +# cuda-cmake-flags: +# -DSUITESPARSE_USE_CUDA=ON +# -DSUITESPARSE_USE_STRICT=ON +# -DCUDAToolkit_INCLUDE_DIRS="/usr/include" +# -DCMAKE_CUDA_COMPILER_LAUNCHER="ccache" + openmp: with + link: static + # "Fake" a cross-compilation to exercise that build system path + link-cmake-flags: + -DBUILD_SHARED_LIBS=OFF + -DBUILD_STATIC_LIBS=ON + -DCMAKE_SYSTEM_NAME="Linux" + + env: + CC: ${{ matrix.cc }} + CXX: ${{ matrix.cxx }} + + steps: + - name: get CPU information + run: lscpu + + - name: checkout repository + uses: actions/checkout@v4 + + - name: install dependencies + env: + COMPILER_PKGS: ${{ matrix.compiler-pkgs }} + CUDA_PKGS: ${{ matrix.cuda-pkgs }} + run: | + sudo apt -qq update + sudo apt install -y ${COMPILER_PKGS} autoconf automake ccache cmake \ + dvipng gfortran libgmp-dev liblapack-dev libmpfr-dev valgrind \ + libopenblas-dev ${CUDA_PKGS} + + - name: prepare ccache + # create key with human readable timestamp + # used in action/cache/restore and action/cache/save steps + id: ccache-prepare + run: | + echo "key=ccache:ubuntu:${{ matrix.compiler }}:${{ matrix.cuda }}:${{ matrix.openmp }}:${{ matrix.link }}:${{ github.ref }}:$(date +"%Y-%m-%d_%H-%M-%S"):${{ github.sha }}" >> $GITHUB_OUTPUT + + - name: restore ccache + # setup the GitHub cache used to maintain the ccache from one job to the next + uses: actions/cache/restore@v4 + with: + path: ~/.ccache + key: ${{ steps.ccache-prepare.outputs.key }} + # Prefer caches from the same branch. Fall back to caches from the dev branch. + restore-keys: | + ccache:ubuntu:${{ matrix.compiler }}:${{ matrix.cuda }}:${{ matrix.openmp }}:${{ matrix.link }}:${{ github.ref }} + ccache:ubuntu:${{ matrix.compiler }}:${{ matrix.cuda }}:${{ matrix.openmp }}:${{ matrix.link }}: + + - name: create empty libraries + # This is to work around a bug in nvlink. + # See: https://forums.developer.nvidia.com/t/nvlink-fatal-could-not-open-input-file-when-linking-with-empty-static-library/208517 + if: matrix.cuda == 'with' + run: | + touch empty.c + gcc -fPIC -c empty.c -oempty.o + ar rcsv libdl.a empty.o + ar rcsv librt.a empty.o + ar rcsv libpthread.a empty.o + # overwrite system libraries with "valid" empty libraries + sudo mv ./libdl.a /usr/lib/x86_64-linux-gnu/libdl.a + sudo mv ./librt.a /usr/lib/x86_64-linux-gnu/librt.a + sudo mv ./libpthread.a /usr/lib/x86_64-linux-gnu/libpthread.a + + - name: configure ccache + env: + CCACHE_MAX: ${{ matrix.ccache-max }} + run: | + test -d ~/.ccache || mkdir ~/.ccache + echo "max_size = $CCACHE_MAX" >> ~/.ccache/ccache.conf + echo "compression = true" >> ~/.ccache/ccache.conf + ccache -s + echo "/usr/lib/ccache" >> $GITHUB_PATH + + - name: build + run: | + IFS=':' read -r -a libs <<< "${BUILD_LIBS}" + for lib in "${libs[@]}"; do + printf " \033[0;32m==>\033[0m Building library \033[0;32m${lib}\033[0m\n" + echo "::group::Configure $lib" + cd ${GITHUB_WORKSPACE}/${lib}/build + cmake -DCMAKE_BUILD_TYPE="Release" \ + -DCMAKE_INSTALL_PREFIX="${GITHUB_WORKSPACE}" \ + -DCMAKE_C_COMPILER_LAUNCHER="ccache" \ + -DCMAKE_CXX_COMPILER_LAUNCHER="ccache" \ + -DCMAKE_Fortran_COMPILER_LAUNCHER="ccache" \ + -DBLA_VENDOR="OpenBLAS" \ + -DSUITESPARSE_DEMOS=OFF \ + -DBUILD_TESTING=OFF \ + ${{ matrix.cuda-cmake-flags }} \ + ${{ matrix.openmp-cmake-flags }} \ + ${{ matrix.link-cmake-flags }} \ + .. + echo "::endgroup::" + echo "::group::Build $lib" + cmake --build . --config Release + echo "::endgroup::" + done + + - name: check + timeout-minutes: 20 + run: | + IFS=':' read -r -a libs <<< "${CHECK_LIBS}" + for lib in "${libs[@]}"; do + printf "::group:: \033[0;32m==>\033[0m Checking library \033[0;32m${lib}\033[0m\n" + cd ${GITHUB_WORKSPACE}/${lib} + make demos CMAKE_OPTIONS="-DSUITESPARSE_DEMOS=ON -DBUILD_TESTING=ON" + echo "::endgroup::" + done + + - name: ccache status + continue-on-error: true + run: ccache -s + + - name: save ccache + # Save the cache after we are done (successfully) building + # This helps to retain the ccache even if the subsequent steps are failing. + uses: actions/cache/save@v4 + with: + path: ~/.ccache + key: ${{ steps.ccache-prepare.outputs.key }} + + - name: install + run: | + IFS=':' read -r -a libs <<< "${BUILD_LIBS}" + for lib in "${libs[@]}"; do + printf "::group::\033[0;32m==>\033[0m Installing library \033[0;32m${lib}\033[0m\n" + cd ${GITHUB_WORKSPACE}/${lib}/build + cmake --install . + echo "::endgroup::" + done + + - name: test Config + run: | + IFS=':' read -r -a libs <<< "${INSTALLED_LIBS}" + for lib in "${libs[@]}"; do + printf "::group:: \033[0;32m==>\033[0m Building with Config.cmake with library \033[0;32m${lib}\033[0m\n" + cd ${GITHUB_WORKSPACE}/TestConfig/${lib} + cd build + cmake \ + -DCMAKE_PREFIX_PATH="${GITHUB_WORKSPACE}/lib/cmake" \ + .. + cmake --build . --config Release + echo "::endgroup::" + done + + mingw: + # For available GitHub-hosted runners, see: + # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners + runs-on: windows-latest + + defaults: + run: + # Use MSYS2 as default shell + shell: msys2 {0} + + strategy: + # Allow other runners in the matrix to continue if some fail + fail-fast: false + + # CLANG32 is broken, as of Mar 21, 2024. The stable branch CI also fails + # the same way, even though it succeeded on Mar 2, with the same + # SuiteSparse 7.6.1 and same workflow file. Between that time, clang and + # openmp were upgraded. clang-openmp went from 17.0.6-1 to 18.1.1-1, and + # clang itself went from 17.0.6-7 to 18.1.1-3. Nothing else changed, so + # it must be a problem with the github runner (changed from 2.313.0 to + # 2.314.1). So for now, CLANG32 is excluded from this CI test. + + matrix: +# CLANG32 disabled for now: +# msystem: [MINGW64, MINGW32, CLANG64, CLANG32] + msystem: [MINGW64, MINGW32, UCRT64, CLANG64] + include: + - msystem: MINGW64 + target-prefix: mingw-w64-x86_64 + f77-package: mingw-w64-x86_64-fc + - msystem: MINGW32 + target-prefix: mingw-w64-i686 + f77-package: mingw-w64-i686-fc + - msystem: UCRT64 + target-prefix: mingw-w64-ucrt-x86_64 + # Purposefully don't install a Fortran compiler to test that configuration + f77-package: mingw-w64-ucrt-x86_64-cc + - msystem: CLANG64 + target-prefix: mingw-w64-clang-x86_64 + f77-package: mingw-w64-clang-x86_64-fc +# CLANG32 disabled for now: +# - msystem: CLANG32 +# target-prefix: mingw-w64-clang-i686 +# # There's no Fortran compiler for this environment. +# f77-package: mingw-w64-clang-i686-cc + + env: + CHERE_INVOKING: 1 + + steps: + - name: get CPU name + shell: pwsh + run : | + Get-CIMInstance -Class Win32_Processor | Select-Object -Property Name + + - name: install MSYS2 build environment + uses: msys2/setup-msys2@v2 + with: + update: true + + # Use pre-installed version to save disc space on partition with source. + release: false + + install: >- + base-devel + ${{ matrix.target-prefix }}-autotools + ${{ matrix.target-prefix }}-cmake + ${{ matrix.target-prefix }}-cc + ${{ matrix.f77-package }} + ${{ matrix.target-prefix }}-ccache + ${{ matrix.target-prefix }}-openblas + ${{ matrix.target-prefix }}-omp + ${{ matrix.target-prefix }}-python + ${{ matrix.target-prefix }}-gmp + ${{ matrix.target-prefix }}-mpfr + + msystem: ${{ matrix.msystem }} + + - name: checkout repository + uses: actions/checkout@v4 + + - name: prepare ccache + # create key with human readable timestamp + # used in action/cache/restore and action/cache/save steps + id: ccache-prepare + run: | + echo "ccachedir=$(cygpath -m $(ccache -k cache_dir))" >> $GITHUB_OUTPUT + echo "key=ccache:mingw:${{ matrix.msystem }}:${{ github.ref }}:$(date +"%Y-%m-%d_%H-%M-%S"):${{ github.sha }}" >> $GITHUB_OUTPUT + + - name: restore ccache + # Setup the GitHub cache used to maintain the ccache from one job to the next + uses: actions/cache/restore@v4 + with: + path: ${{ steps.ccache-prepare.outputs.ccachedir }} + key: ${{ steps.ccache-prepare.outputs.key }} + # Prefer caches from the same branch. Fall back to caches from the dev branch. + restore-keys: | + ccache:mingw:${{ matrix.msystem }}:${{ github.ref }} + ccache:mingw:${{ matrix.msystem }} + + - name: configure ccache + # Limit the maximum size and switch on compression to avoid exceeding the total disk or cache quota. + run: | + which ccache + test -d ${{ steps.ccache_cache_timestamp.outputs.ccachedir }} || mkdir -p ${{ steps.ccache_cache_timestamp.outputs.ccachedir }} + echo "max_size = 250M" > ${{ steps.ccache_cache_timestamp.outputs.ccachedir }}/ccache.conf + echo "compression = true" >> ${{ steps.ccache_cache_timestamp.outputs.ccachedir }}/ccache.conf + ccache -p + ccache -s + + - name: build + run: | + IFS=':' read -r -a libs <<< "${BUILD_LIBS}" + for lib in "${libs[@]}"; do + printf " \033[0;32m==>\033[0m Building library \033[0;32m${lib}\033[0m\n" + echo "::group::Configure $lib" + cd ${GITHUB_WORKSPACE}/${lib}/build + cmake -DCMAKE_BUILD_TYPE="Release" \ + -DCMAKE_INSTALL_PREFIX="${GITHUB_WORKSPACE}" \ + -DCMAKE_C_COMPILER_LAUNCHER="ccache" \ + -DCMAKE_CXX_COMPILER_LAUNCHER="ccache" \ + -DCMAKE_Fortran_COMPILER_LAUNCHER="ccache" \ + -DBLA_VENDOR="OpenBLAS" \ + -DPython_EXECUTABLE="$(which python)" \ + -DSUITESPARSE_DEMOS=OFF \ + -DBUILD_TESTING=OFF \ + .. + echo "::endgroup::" + echo "::group::Build $lib" + cmake --build . --config Release + echo "::endgroup::" + done + + - name: check + timeout-minutes: 20 + # Need to install the libraries for the tests + run: | + echo "::group::Install libraries" + make install + echo "::endgroup::" + IFS=':' read -r -a libs <<< "${CHECK_LIBS}" + for lib in "${libs[@]}"; do + printf "::group:: \033[0;32m==>\033[0m Checking library \033[0;32m${lib}\033[0m\n" + cd ${GITHUB_WORKSPACE}/${lib} + PATH="${GITHUB_WORKSPACE}/bin:${PATH}" \ + make demos CMAKE_OPTIONS="-DSUITESPARSE_DEMOS=ON -DBUILD_TESTING=ON" + echo "::endgroup::" + done + + - name: ccache status + continue-on-error: true + run: ccache -s + + - name: save ccache + # Save the cache after we are done (successfully) building + # This helps to retain the ccache even if the subsequent steps are failing. + uses: actions/cache/save@v4 + with: + path: ${{ steps.ccache-prepare.outputs.ccachedir }} + key: ${{ steps.ccache-prepare.outputs.key }} + + - name: test Config + run: | + IFS=':' read -r -a libs <<< "${INSTALLED_LIBS}" + for lib in "${libs[@]}"; do + printf "::group:: \033[0;32m==>\033[0m Building with Config.cmake with library \033[0;32m${lib}\033[0m\n" + cd ${GITHUB_WORKSPACE}/TestConfig/${lib} + cd build + cmake \ + -DCMAKE_PREFIX_PATH="${GITHUB_WORKSPACE}/lib/cmake" \ + .. + cmake --build . --config Release + echo "::endgroup::" + done + diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml new file mode 100644 index 00000000..b098e21e --- /dev/null +++ b/.github/workflows/codeql-analysis.yaml @@ -0,0 +1,204 @@ +name: "CodeQL" + +on: + workflow_dispatch: + schedule: + # Run job every Saturday at 10:20 UTC + - cron: '20 10 * * 6' + +concurrency: codeql-${{ github.ref }} + +# # See: https://github.com/github/codeql-action/issues/1082 +# env: +# CODEQL_ACTION_EXTRA_OPTIONS: '{"database": {"run-queries": ["--off-heap-ram=0"]}}' + + +jobs: + + ubuntu: + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + # Override automatic language detection by changing the below list + # Supported options are ['c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'] + language: ['c-cpp'] + # Learn more... + # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection + group: [other] +# GraphBLAS and LAGraph disabled (the runners run out of memory or +# disk space) +# group: [other, graph] + include: + - group: other + build-libs: SuiteSparse_config:AMD:COLAMD:SPEX +# - group: graph +# build-libs: GraphBLAS:LAGraph + + name: CodeQL (Ubuntu, ${{ matrix.group }}) + + steps: + - name: checkout repository + uses: actions/checkout@v4 + + - name: install dependencies + run: | + sudo apt -qq update + sudo apt install -y g++ gcc autoconf automake cmake \ + dvipng gfortran libgmp-dev liblapack-dev libmpfr-dev \ + libopenblas-dev nvidia-cuda-dev nvidia-cuda-toolkit + + - name: create empty libraries + # This is to work around a bug in nvlink. + # See: https://forums.developer.nvidia.com/t/nvlink-fatal-could-not-open-input-file-when-linking-with-empty-static-library/208517 + run: | + touch empty.c + gcc -fPIC -c empty.c -oempty.o + ar rcsv libdl.a empty.o + ar rcsv librt.a empty.o + ar rcsv libpthread.a empty.o + # overwrite system libraries with "valid" empty libraries + sudo mv ./libdl.a /usr/lib/x86_64-linux-gnu/libdl.a + sudo mv ./librt.a /usr/lib/x86_64-linux-gnu/librt.a + sudo mv ./libpthread.a /usr/lib/x86_64-linux-gnu/libpthread.a + + - name: initialize CodeQL + # Initialize the CodeQL tools for scanning. + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + - name: build + # The analysis with factory kernels of the GraphBLAS library is too + # extensive for the free GitHub-hosted runners. Disable them to work + # around that. That means they aren't scanned. + run: | + IFS=':' + BUILD_LIBS="${{ matrix.build-libs }}" + for lib in ${BUILD_LIBS}; do + printf " \033[0;32m==>\033[0m Building library \033[0;32m${lib}\033[0m\n" + echo "::group::Configure $lib" + cd ${GITHUB_WORKSPACE}/${lib}/build + cmake -DCMAKE_BUILD_TYPE="Release" \ + -DCMAKE_INSTALL_PREFIX="${GITHUB_WORKSPACE}" \ + -DBLA_VENDOR="OpenBLAS" \ + -DNSTATIC=ON \ + -DCOMPACT=ON \ + -DSUITESPARSE_USE_CUDA=ON \ + -DCUDAToolkit_INCLUDE_DIRS="/usr/include" \ + .. + echo "::endgroup::" + echo "::group::Build $lib" + cmake --build . --config Release + echo "::endgroup::" + done + + - name: perform CodeQL analysis + uses: github/codeql-action/analyze@v3 + with: + category: ${{ matrix.group }}-64 + + + mingw32: + runs-on: windows-latest + + defaults: + run: + # Use MSYS2 as default shell + shell: msys2 {0} + + strategy: + # Allow other runners in the matrix to continue if some fail + fail-fast: false + + matrix: + # Override automatic language detection by changing the below list + # Supported options are ['c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'] + language: ['c-cpp'] + # Learn more... + # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection + group: [other] +# group: [other, graph] + include: + - group: other + build-libs: SuiteSparse_config:AMD:COLAMD:SPEX +# - group: graph +# build-libs: GraphBLAS:LAGraph + + env: + CHERE_INVOKING: 1 + + name: CodeQL (mingw32, ${{ matrix.group }}) + + steps: + - name: get CPU name + shell: pwsh + run : | + Get-CIMInstance -Class Win32_Processor | Select-Object -Property Name + + - name: install MSYS2 build environment + uses: msys2/setup-msys2@v2 + with: + update: true + + # Use pre-installed version to save disc space on partition with source. + release: false + + install: >- + base-devel + mingw-w64-i686-autotools + mingw-w64-i686-cmake + mingw-w64-i686-cc + mingw-w64-i686-fc + mingw-w64-i686-openblas + mingw-w64-i686-omp + mingw-w64-i686-gmp + mingw-w64-i686-mpfr + + msystem: MINGW32 + + - name: checkout repository + uses: actions/checkout@v4 + + - name: initialize CodeQL + # Initialize the CodeQL tools for scanning. + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + - name: build + # The analysis with factory kernels of the GraphBLAS library is too + # extensive for the free GitHub-hosted runners. Disable them to work + # around that. That means they aren't scanned. + run: | + BUILD_LIBS="${{ matrix.build-libs }}" + IFS=':' read -r -a libs <<< "${BUILD_LIBS}" + for lib in "${libs[@]}"; do + printf " \033[0;32m==>\033[0m Building library \033[0;32m${lib}\033[0m\n" + echo "::group::Configure $lib" + cd ${GITHUB_WORKSPACE}/${lib}/build + cmake -DCMAKE_BUILD_TYPE="Release" \ + -DCMAKE_INSTALL_PREFIX="${GITHUB_WORKSPACE}" \ + -DBLA_VENDOR="OpenBLAS" \ + -DNSTATIC=ON \ + -DCOMPACT=ON \ + .. + echo "::endgroup::" + echo "::group::Build $lib" + cmake --build . --config Release + echo "::endgroup::" + done + + - name: perform CodeQL analysis + uses: github/codeql-action/analyze@v3 + with: + category: ${{ matrix.group }}-32 diff --git a/.github/workflows/macos.yaml b/.github/workflows/macos.yaml new file mode 100644 index 00000000..f358ac5f --- /dev/null +++ b/.github/workflows/macos.yaml @@ -0,0 +1,137 @@ +name: macos +on: + workflow_dispatch: +# push: +# branches-ignore: +# - '**/dev2' +# - '**/*dev2' +# pull_request: + +# This workflow hangs intermittently at random places, after building a demo +# program and just before running it. Something is broken but it's not +# SuiteSparse; it's github. Tests on an M1 Mac and Intel Mac have never shown +# this behavior outside of github. As a result, this workflow has been +# relegated to a "workflow_dispatch" only. It is not run on push or pull +# requests. The hang has nothing to do with parallelism; it can hang in +# check_AMD, which does not use OpenMP. + +concurrency: ci-macos-${{ github.ref }} + +env: + # string with name of libraries to be built + BUILD_LIBS: "SuiteSparse_config:AMD:COLAMD:SPEX" + +jobs: + + macos: + # For available GitHub-hosted runners, see: + # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners + runs-on: macos-latest + + steps: + - name: get runner hardware information + run: | + sysctl hw + sysctl machdep + + - name: checkout repository + uses: actions/checkout@v4 + + - name: install dependencies + # Homebrew's Python conflicts with the Python that comes pre-installed + # on the GitHub runners. Some of SuiteSparse's dependencies depend on + # different versions of Homebrew's Python. Enforce using the ones from + # Homebrew to avoid errors on updates. + # See: https://github.com/orgs/Homebrew/discussions/3928 + + # It looks like "gfortran" isn't working correctly unless "gcc" is + # re-installed. + run: | + brew update + brew install --overwrite python@3.10 python@3.11 python@3.12 + brew reinstall gcc + brew install autoconf automake ccache cmake gmp lapack libomp mpfr openblas + + - name: prepare ccache + # create key with human readable timestamp + # used in action/cache/restore and action/cache/save steps + id: ccache-prepare + run: | + echo "key=ccache:macos-latest:${{ github.ref }}:$(date +"%Y-%m-%d_%H-%M-%S"):${{ github.sha }}" >> $GITHUB_OUTPUT + + - name: restore ccache + # setup the GitHub cache used to maintain the ccache from one job to the next + uses: actions/cache/restore@v4 + with: + path: /Users/runner/Library/Caches/ccache + key: ${{ steps.ccache-prepare.outputs.key }} + # Prefer caches from the same branch. Fall back to caches from the dev branch. + restore-keys: | + ccache:macos-latest:${{ github.ref }} + ccache:macos-latest + + - name: configure ccache + # Limit the maximum size to avoid exceeding the total cache limits. + run: | + test -d /Users/runner/Library/Preferences/ccache || mkdir /Users/runner/Library/Preferences/ccache + echo "max_size = 300M" >> /Users/runner/Library/Preferences/ccache/ccache.conf + ccache -s + + - name: build + run: | + IFS=':' read -r -a libs <<< "${BUILD_LIBS}" + for lib in "${libs[@]}"; do + printf " \033[0;32m==>\033[0m Building library \033[0;32m${lib}\033[0m\n" + echo "::group::Configure $lib" + cd ${GITHUB_WORKSPACE}/${lib}/build + cmake -DCMAKE_BUILD_TYPE="Release" \ + -DCMAKE_INSTALL_PREFIX="${GITHUB_WORKSPACE}" \ + -DCMAKE_C_COMPILER_LAUNCHER="ccache" \ + -DCMAKE_CXX_COMPILER_LAUNCHER="ccache" \ + -DCMAKE_Fortran_COMPILER_LAUNCHER="ccache" \ + -DBLA_VENDOR="OpenBLAS" \ + -DCMAKE_PREFIX_PATH="/usr/local/opt/lapack;/usr/local/opt/openblas;/usr/local/opt/libomp" \ + .. + echo "::endgroup::" + echo "::group::Build $lib" + cmake --build . --config Release + echo "::endgroup::" + done + + - name: check_AMD + run: | + cd ${GITHUB_WORKSPACE}/AMD + make demos + + - name: check_COLAMD + run: | + cd ${GITHUB_WORKSPACE}/COLAMD + make demos + + - name: check_SPEX + run: | + cd ${GITHUB_WORKSPACE}/SPEX + make demos + + - name: ccache status + continue-on-error: true + run: ccache -s + + - name: save ccache + # Save the cache after we are done (successfully) building + # This helps to retain the ccache even if the subsequent steps are failing. + uses: actions/cache/save@v4 + with: + path: /Users/runner/Library/Caches/ccache + key: ${{ steps.ccache-prepare.outputs.key }} + + - name: install + run: | + IFS=':' read -r -a libs <<< "${BUILD_LIBS}" + for lib in "${libs[@]}"; do + printf "::group::\033[0;32m==>\033[0m Installing library \033[0;32m${lib}\033[0m\n" + cd ${GITHUB_WORKSPACE}/${lib}/build + cmake --install . + echo "::endgroup::" + done + diff --git a/.github/workflows/root-cmakelists.yaml b/.github/workflows/root-cmakelists.yaml new file mode 100644 index 00000000..d32fa3b8 --- /dev/null +++ b/.github/workflows/root-cmakelists.yaml @@ -0,0 +1,477 @@ +# Build SuiteSparse using the root CMakeLists.txt + +name: root-cmakelists + +on: + workflow_dispatch: + push: + branches-ignore: + - '**/dev2' + - '**/*dev2' + pull_request: + +concurrency: ci-root-cmakelists-${{ github.ref }} + +env: + # string with name of libraries that are installed + INSTALLED_LIBS: "SuiteSparse_config:AMD:COLAMD:SPEX" + +jobs: + + ubuntu: + # For available GitHub-hosted runners, see: + # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners + runs-on: ubuntu-latest + + name: ubuntu (${{ matrix.compiler }} ${{ matrix.cuda }} CUDA, ${{ matrix.link }}) + + strategy: + # Allow other runners in the matrix to continue if some fail + fail-fast: false + + matrix: + compiler: [gcc, clang] + cuda: [without] +# cuda: [with, without] + link: [both] + include: + - compiler: gcc + compiler-pkgs: "g++ gcc" + cc: "gcc" + cxx: "g++" + - compiler: clang + compiler-pkgs: "clang libomp-dev" + cc: "clang" + cxx: "clang++" + # Clang seems to generally require less cache size (smaller object files?). + - compiler: gcc + ccache-max: 600M + - compiler: clang + ccache-max: 500M + - cuda: without +# - cuda: with +# cuda-pkgs: "nvidia-cuda-dev nvidia-cuda-toolkit" +# cuda-cmake-flags: +# -DSUITESPARSE_USE_CUDA=ON +# -DSUITESPARSE_USE_STRICT=ON +# -DCUDAToolkit_INCLUDE_DIRS="/usr/include" +# -DCMAKE_CUDA_COMPILER_LAUNCHER="ccache" + - compiler: gcc + compiler-pkgs: "g++ gcc" + cc: "gcc" + cxx: "g++" + ccache-max: 600M + cuda: without +# cuda: with +# cuda-pkgs: "nvidia-cuda-dev nvidia-cuda-toolkit" +# cuda-cmake-flags: +# -DSUITESPARSE_USE_CUDA=ON +# -DSUITESPARSE_USE_STRICT=ON +# -DCUDAToolkit_INCLUDE_DIRS="/usr/include" +# -DCMAKE_CUDA_COMPILER_LAUNCHER="ccache" + link: static + link-cmake-flags: + -DBUILD_SHARED_LIBS=OFF + -DBUILD_STATIC_LIBS=ON + + env: + CC: ${{ matrix.cc }} + CXX: ${{ matrix.cxx }} + + steps: + - name: get CPU information + run: lscpu + + - name: checkout repository + uses: actions/checkout@v4 + + - name: install dependencies + env: + COMPILER_PKGS: ${{ matrix.compiler-pkgs }} + CUDA_PKGS: ${{ matrix.cuda-pkgs }} + run: | + sudo apt -qq update + sudo apt install -y ${COMPILER_PKGS} autoconf automake ccache cmake \ + dvipng gfortran libgmp-dev liblapack-dev libmpfr-dev \ + libopenblas-dev ${CUDA_PKGS} + + - name: prepare ccache + # create key with human readable timestamp + # used in action/cache/restore and action/cache/save steps + id: ccache-prepare + run: | + echo "key=ccache:ubuntu:root:${{ matrix.compiler }}:${{ matrix.cuda }}:${{ matrix.link }}:${{ github.ref }}:$(date +"%Y-%m-%d_%H-%M-%S"):${{ github.sha }}" >> $GITHUB_OUTPUT + + - name: restore ccache + # setup the GitHub cache used to maintain the ccache from one job to the next + uses: actions/cache/restore@v4 + with: + path: ~/.ccache + key: ${{ steps.ccache-prepare.outputs.key }} + # Prefer caches from the same branch. Fall back to caches from the dev branch. + restore-keys: | + ccache:ubuntu:root:${{ matrix.compiler }}:${{ matrix.cuda }}:${{ matrix.link }}:${{ github.ref }} + ccache:ubuntu:root:${{ matrix.compiler }}:${{ matrix.cuda }}:${{ matrix.link }} + + - name: create empty libraries + # This is to work around a bug in nvlink. + # See: https://forums.developer.nvidia.com/t/nvlink-fatal-could-not-open-input-file-when-linking-with-empty-static-library/208517 + if: matrix.cuda == 'with' + run: | + touch empty.c + gcc -fPIC -c empty.c -oempty.o + ar rcsv libdl.a empty.o + ar rcsv librt.a empty.o + ar rcsv libpthread.a empty.o + # overwrite system libraries with "valid" empty libraries + sudo mv ./libdl.a /usr/lib/x86_64-linux-gnu/libdl.a + sudo mv ./librt.a /usr/lib/x86_64-linux-gnu/librt.a + sudo mv ./libpthread.a /usr/lib/x86_64-linux-gnu/libpthread.a + + - name: configure ccache + env: + CCACHE_MAX: ${{ matrix.ccache-max }} + run: | + test -d ~/.ccache || mkdir ~/.ccache + echo "max_size = $CCACHE_MAX" >> ~/.ccache/ccache.conf + echo "compression = true" >> ~/.ccache/ccache.conf + ccache -s + echo "/usr/lib/ccache" >> $GITHUB_PATH + + - name: check auto-dependency resolution + # no need to check this with all runners. One is enough. + if: ${{ matrix.cc == 'gcc' && matrix.cuda == 'without' }} + run: | + mkdir -p ${GITHUB_WORKSPACE}/build-dep && cd ${GITHUB_WORKSPACE}/build-dep + IFS=':' read -r -a libs <<< "${INSTALLED_LIBS}" + for lib in "${libs[@]}"; do + printf "::group:: \033[0;32m==>\033[0m Configuring to build only \033[0;32m${lib}\033[0m\n" + cmake --fresh \ + -DCMAKE_BUILD_TYPE="Release" \ + -DBLA_VENDOR="OpenBLAS" \ + -DSUITESPARSE_ENABLE_PROJECTS="${lib,,}" \ + .. + echo "::endgroup::" + done + + - name: configure + run: | + mkdir -p ${GITHUB_WORKSPACE}/build && cd ${GITHUB_WORKSPACE}/build + cmake -DCMAKE_BUILD_TYPE="Release" \ + -DCMAKE_INSTALL_PREFIX=".." \ + -DCMAKE_C_COMPILER_LAUNCHER="ccache" \ + -DCMAKE_CXX_COMPILER_LAUNCHER="ccache" \ + -DCMAKE_Fortran_COMPILER_LAUNCHER="ccache" \ + -DBLA_VENDOR="OpenBLAS" \ + -DSUITESPARSE_DEMOS=OFF \ + -DBUILD_TESTING=OFF \ + ${{ matrix.cuda-cmake-flags }} \ + ${{ matrix.link-cmake-flags }} \ + .. + + - name: build libraries + run: | + cd ${GITHUB_WORKSPACE}/build + cmake --build . + + - name: build demos + run: | + printf "::group:: \033[0;32m==>\033[0m Configuring for demos\n" + cd ${GITHUB_WORKSPACE}/build + cmake -DSUITESPARSE_DEMOS=ON -DBUILD_TESTING=ON .. + echo "::endgroup::" + printf "::group:: \033[0;32m==>\033[0m Building demos\n" + cd ${GITHUB_WORKSPACE}/build + cmake --build . + echo "::endgroup::" + # FIXME: How to run the demos without Makefile? + + - name: ccache status + continue-on-error: true + run: ccache -s + + - name: save ccache + # Save the cache after we are done (successfully) building. + # This helps to retain the ccache even if the subsequent steps are failing. + uses: actions/cache/save@v4 + with: + path: ~/.ccache + key: ${{ steps.ccache-prepare.outputs.key }} + + - name: check + run: | + cd ${GITHUB_WORKSPACE}/build + ctest . || ctest . --rerun-failed --output-on-failure + + - name: install + run: | + printf "\033[0;32m==>\033[0m Installing libraries\n" + cd ${GITHUB_WORKSPACE}/build + cmake --install . + + - name: test Config + run: | + IFS=':' read -r -a libs <<< "${INSTALLED_LIBS}" + for lib in "${libs[@]}"; do + printf "::group:: \033[0;32m==>\033[0m Building Config.cmake with library \033[0;32m${lib}\033[0m\n" + cd ${GITHUB_WORKSPACE}/TestConfig/${lib} + cd build + cmake \ + -DCMAKE_PREFIX_PATH="${GITHUB_WORKSPACE}/lib/cmake" \ + .. + cmake --build . --config Release + echo "::endgroup::" + done + + + msvc: + # For available GitHub-hosted runners, see: + # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners + runs-on: windows-latest + + name: msvc (${{ matrix.cc }} ${{ matrix.openmp }} OpenMP ${{ matrix.cuda }} CUDA, ${{ matrix.link }}) + + defaults: + run: + # Use bash as default shell + shell: bash -el {0} + + strategy: + # Allow other runners in the matrix to continue if some fail + fail-fast: false + + matrix: + openmp: [with, without] + cuda: [without] + link: [both] + cc: [cl] + include: + - openmp: without + openmp-cmake-flags: "-DSUITESPARSE_USE_OPENMP=OFF" +# - openmp: with + cuda: without +# cuda: with +# cuda-cmake-flags: +# -DSUITESPARSE_USE_CUDA=ON +# -DCMAKE_CUDA_COMPILER_LAUNCHER="ccache" +# link: both +# cc: cl + - openmp: with + cuda: without +# cuda: with +# cuda-cmake-flags: +# -DSUITESPARSE_USE_CUDA=ON +# -DCMAKE_CUDA_COMPILER_LAUNCHER="ccache" + link: static + link-cmake-flags: + -DBUILD_SHARED_LIBS=OFF + -DBUILD_STATIC_LIBS=ON + cc: cl + - openmp: with + cuda: without + link: both + cc: clang-cl + + env: + CHERE_INVOKING: 1 + + steps: + - name: get CPU name + shell: pwsh + run : | + Get-CIMInstance -Class Win32_Processor | Select-Object -Property Name + + - name: checkout repository + uses: actions/checkout@v4 + + - uses: conda-incubator/setup-miniconda@v3 + with: + auto-update-conda: true + + - name: cache conda packages + id: conda-cache + uses: actions/cache/restore@v4 + with: + path: C:/Miniconda/envs/test + key: conda:msvc + + - name: install packages with conda + if: ${{ steps.conda-cache.outputs.cache-hit != 'true' }} + run: | + echo ${{ steps.conda-cache.outputs.cache-hit }} + conda info + conda list + conda install -y -c intel mkl-devel + conda install -y -c conda-forge --override-channels ccache + + - name: save conda cache + if: ${{ steps.conda-cache.outputs.cache-hit != 'true' }} + uses: actions/cache/save@v4 + with: + path: C:/Miniconda/envs/test + key: ${{ steps.conda-cache.outputs.cache-primary-key }} + + - name: install libraries from MSYS2 + uses: msys2/setup-msys2@v2 + with: + update: true + + # Use pre-installed version to save disc space on partition with source. + release: false + + install: >- + mingw-w64-ucrt-x86_64-gmp + mingw-w64-ucrt-x86_64-mpfr + mingw-w64-ucrt-x86_64-python + + msystem: UCRT64 + + - uses: Jimver/cuda-toolkit@v0.2.14 + name: install CUDA toolkit + if: matrix.cuda == 'with' + id: cuda-toolkit + with: + cuda: '12.2.0' + #See https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/index.html#install-the-cuda-software + method: 'local' + # Do not cache the installer (~3 GiB). It doesn't speed up the + # installation significantly. And we need the space for ccache. + use-github-cache: 'false' + + - name: setup build environment + # get packages from MSYS2 + # Copy only relevant parts to avoid picking up headers and libraries + # that are thought for MinGW only. + run: | + mkdir -p ./dependencies/{bin,lib,include} + # GMP + cp C:/msys64/ucrt64/bin/libgmp*.dll ./dependencies/bin/ + cp C:/msys64/ucrt64/include/gmp.h ./dependencies/include/ + cp C:/msys64/ucrt64/lib/libgmp.dll.a ./dependencies/lib/gmp.lib + # MPFR + cp C:/msys64/ucrt64/bin/libmpfr*.dll ./dependencies/bin/ + cp C:/msys64/ucrt64/include/mpf2mpfr.h ./dependencies/include/ + cp C:/msys64/ucrt64/include/mpfr.h ./dependencies/include/ + cp C:/msys64/ucrt64/lib/libmpfr.dll.a ./dependencies/lib/mpfr.lib + # run-time dependencies + cp C:/msys64/ucrt64/bin/libgcc_s_seh*.dll ./dependencies/bin/ + cp C:/msys64/ucrt64/bin/libwinpthread*.dll ./dependencies/bin/ + # create environment variable for easier access + echo "CCACHE=C:/Miniconda/envs/test/Library/bin/ccache.exe" >> ${GITHUB_ENV} + + - name: prepare ccache + # create key with human readable timestamp + # used in action/cache/restore and action/cache/save steps + id: ccache-prepare + shell: msys2 {0} + run: | + echo "ccachedir=$(cygpath -m $(${CCACHE} -k cache_dir))" >> $GITHUB_OUTPUT + echo "key=ccache:msvc:root:${{ matrix.cc }}:${{ matrix.openmp }}:${{ matrix.cuda }}:${{ matrix.link }}:${{ github.ref }}:$(date +"%Y-%m-%d_%H-%M-%S"):${{ github.sha }}" >> $GITHUB_OUTPUT + + - name: restore ccache + # Setup the GitHub cache used to maintain the ccache from one job to the next + uses: actions/cache/restore@v4 + with: + path: ${{ steps.ccache-prepare.outputs.ccachedir }} + key: ${{ steps.ccache-prepare.outputs.key }} + # Prefer caches from the same branch. Fall back to caches from the dev branch. + restore-keys: | + ccache:msvc:root:${{ matrix.cc }}:${{ matrix.openmp }}:${{ matrix.cuda }}:${{ matrix.link }}:${{ github.ref }} + ccache:msvc:root:${{ matrix.cc }}:${{ matrix.openmp }}:${{ matrix.cuda }}:${{ matrix.link }}: + + - name: configure ccache + # Limit the maximum size and switch on compression to avoid exceeding the total disk or cache quota. + run: | + test -d ${{ steps.ccache-prepare.outputs.ccachedir }} || mkdir -p ${{ steps.ccache-prepare.outputs.ccachedir }} + echo "max_size = 250M" > ${{ steps.ccache-prepare.outputs.ccachedir }}/ccache.conf + echo "compression = true" >> ${{ steps.ccache-prepare.outputs.ccachedir }}/ccache.conf + ${CCACHE} -p + ${CCACHE} -s + + - name: setup MSVC toolchain + uses: ilammy/msvc-dev-cmd@v1 + + - name: configure + run: | + declare -a _extra_config + if [ ${{ matrix.cuda }} = 'with' ]; then + _extra_config+=(-DCUDAToolkit_ROOT="$(cygpath -m "${{ steps.cuda-toolkit.outputs.CUDA_PATH }}")") + _extra_config+=(-DCMAKE_CUDA_COMPILER="$(cygpath -m "${{ steps.cuda-toolkit.outputs.CUDA_PATH }}")/bin/nvcc.exe") + fi + mkdir -p ${GITHUB_WORKSPACE}/build && cd ${GITHUB_WORKSPACE}/build + cmake -G"Ninja Multi-Config" \ + -DCMAKE_C_COMPILER=${{ matrix.cc }} \ + -DCMAKE_CXX_COMPILER=${{ matrix.cc }} \ + -DCMAKE_BUILD_TYPE="Release" \ + -DCMAKE_INSTALL_PREFIX=".." \ + -DCMAKE_PREFIX_PATH="C:/Miniconda/envs/test/Library;${GITHUB_WORKSPACE}/dependencies" \ + -DCMAKE_C_COMPILER_LAUNCHER="ccache" \ + -DCMAKE_CXX_COMPILER_LAUNCHER="ccache" \ + -DCMAKE_Fortran_COMPILER_LAUNCHER="ccache" \ + -DSUITESPARSE_USE_FORTRAN=OFF \ + -DBLA_VENDOR="All" \ + -DPython_EXECUTABLE="C:/msys64/ucrt64/bin/python.exe" \ + -DSUITESPARSE_DEMOS=OFF \ + -DBUILD_TESTING=OFF \ + ${{ matrix.openmp-cmake-flags }} \ + ${{ matrix.cuda-cmake-flags }} \ + ${{ matrix.link-cmake-flags }} \ + "${_extra_config[@]}" \ + .. + + - name: build libraries + run: | + cd ${GITHUB_WORKSPACE}/build + cmake --build . --config Release + + - name: build demos + run: | + printf "::group:: \033[0;32m==>\033[0m Configuring for demos\n" + cd ${GITHUB_WORKSPACE}/build + cmake -DSUITESPARSE_DEMOS=ON -DBUILD_TESTING=ON .. + echo "::endgroup::" + printf "::group:: \033[0;32m==>\033[0m Building demos\n" + cd ${GITHUB_WORKSPACE}/build + cmake --build . --config Release + echo "::endgroup::" + # FIXME: How to run the demos without Makefile? + + - name: ccache status + continue-on-error: true + run: ${CCACHE} -s + + - name: save ccache + # Save the cache after we are done (successfully) building + # This helps to retain the ccache even if the subsequent steps are failing. + uses: actions/cache/save@v4 + with: + path: ${{ steps.ccache-prepare.outputs.ccachedir }} + key: ${{ steps.ccache-prepare.outputs.key }} + + - name: check + run: | + cd ${GITHUB_WORKSPACE}/build + PATH="${GITHUB_WORKSPACE}/bin;${GITHUB_WORKSPACE}/dependencies/bin;C:/msys64/ucrt64/bin;${PATH}" \ + ctest -C Release . || ctest -C Release . --rerun-failed --output-on-failure + + - name: install + run: | + printf "\033[0;32m==>\033[0m Installing libraries\n" + cd ${GITHUB_WORKSPACE}/build + cmake --install . + + - name: test Config + run: | + IFS=':' read -r -a libs <<< "${INSTALLED_LIBS}" + for lib in "${libs[@]}"; do + printf "::group:: \033[0;32m==>\033[0m Building with Config.cmake with library \033[0;32m${lib}\033[0m\n" + cd ${GITHUB_WORKSPACE}/TestConfig/${lib} + cd build + cmake -G"Ninja Multi-Config" \ + -DCMAKE_C_COMPILER=${{ matrix.cc }} \ + -DCMAKE_CXX_COMPILER=${{ matrix.cc }} \ + -DCMAKE_PREFIX_PATH="${GITHUB_WORKSPACE}/lib/cmake;C:/Miniconda/envs/test/Library;${GITHUB_WORKSPACE}/dependencies" \ + .. + cmake --build . --config Release + echo "::endgroup::" + done diff --git a/.gitignore b/.gitignore index d0d4223f..82b356ef 100644 --- a/.gitignore +++ b/.gitignore @@ -127,6 +127,7 @@ CSparse/Tcov/cov.sort CSparse/Tcov/cover.out CSparse/Tcov/covs.out CSparse/Tcov/cs_*.c +CSparse/Tcov/csparse_version.c CSparse/Tcov/cstcov_test CSparse/Tcov/*.out CSparse/Tcov/cs_demo1 @@ -138,6 +139,7 @@ CXSparse/Tcov/cov.sort CXSparse/Tcov/cover.out CXSparse/Tcov/covs.out CXSparse/Tcov/cs_*.c +CXSparse/Tcov/cxsparse_version.c CXSparse/Tcov/*.out CXSparse/Tcov/cs_demo1_ci CXSparse/Tcov/cs_demo1_cl @@ -168,7 +170,9 @@ SPQR/Tcov/gpu_results.txt SPQR/Tcov/gpuqrengine_demo SPQR/Tcov/qrdemo_gpu SPQR/Tcov/qrtest +SPQR/Tcov/qrtest32 SPQR/Tcov/qrtest_out.txt +SPQR/Tcov/qrtest_out32.txt SPQR/Tcov/troll.m SPQR/Tcov/cov.out diff --git a/AMD/CMakeLists.txt b/AMD/CMakeLists.txt index 4fdf6149..372e60e6 100644 --- a/AMD/CMakeLists.txt +++ b/AMD/CMakeLists.txt @@ -2,7 +2,7 @@ # SuiteSparse/AMD/CMakeLists.txt: cmake for AMD #------------------------------------------------------------------------------- -# Copyright (c) 1996-2022, Timothy A. Davis, Patrick Amestoy, Iain Duff. +# Copyright (c) 1996-2023, Timothy A. Davis, Patrick Amestoy, Iain Duff. # All Rights Reserved. # SPDX-License-Identifier: BSD-3-clause @@ -10,12 +10,12 @@ # get the version #------------------------------------------------------------------------------- -cmake_minimum_required ( VERSION 3.19 ) +cmake_minimum_required ( VERSION 3.22 ) -set ( AMD_DATE "Jan 17, 2023" ) -set ( AMD_VERSION_MAJOR 3 ) -set ( AMD_VERSION_MINOR 0 ) -set ( AMD_VERSION_SUB 3 ) +set ( AMD_DATE "Mar 22, 2024" ) +set ( AMD_VERSION_MAJOR 3 CACHE STRING "" FORCE ) +set ( AMD_VERSION_MINOR 3 CACHE STRING "" FORCE ) +set ( AMD_VERSION_SUB 2 CACHE STRING "" FORCE ) message ( STATUS "Building AMD version: v" ${AMD_VERSION_MAJOR}. @@ -23,41 +23,38 @@ message ( STATUS "Building AMD version: v" ${AMD_VERSION_SUB} " (" ${AMD_DATE} ")" ) #------------------------------------------------------------------------------- -# SuiteSparse policies +# define the project #------------------------------------------------------------------------------- -set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} - ${CMAKE_SOURCE_DIR}/cmake_modules - ${CMAKE_SOURCE_DIR}/../SuiteSparse_config/cmake_modules ) - -include ( SuiteSparsePolicy ) +project ( AMD + VERSION "${AMD_VERSION_MAJOR}.${AMD_VERSION_MINOR}.${AMD_VERSION_SUB}" + LANGUAGES C ) #------------------------------------------------------------------------------- -# define the project +# SuiteSparse policies #------------------------------------------------------------------------------- -if ( WIN32 ) - # disable Fortran in AMD when compiling on Windows - set ( NFORTRAN true ) -endif ( ) +set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} + ${PROJECT_SOURCE_DIR}/../SuiteSparse_config/cmake_modules ) + +include ( SuiteSparsePolicy ) -if ( NOT NFORTRAN ) +if ( SUITESPARSE_HAS_FORTRAN ) # Fortan is available and enabled - project ( amd - VERSION "${AMD_VERSION_MAJOR}.${AMD_VERSION_MINOR}.${AMD_VERSION_SUB}" - LANGUAGES C Fortran ) -else ( ) - # no Fortran compiler available; do not compile Source/*.f or Demo/*.f - project ( amd - VERSION "${AMD_VERSION_MAJOR}.${AMD_VERSION_MINOR}.${AMD_VERSION_SUB}" - LANGUAGES C ) + enable_language ( Fortran ) endif ( ) #------------------------------------------------------------------------------- # find library dependencies #------------------------------------------------------------------------------- -find_package ( SuiteSparse_config 7.0.0 REQUIRED ) +if ( NOT SUITESPARSE_ROOT_CMAKELISTS ) + find_package ( SuiteSparse_config 7.7.0 + PATHS ${CMAKE_SOURCE_DIR}/../SuiteSparse_config/build NO_DEFAULT_PATH ) + if ( NOT TARGET SuiteSparse::SuiteSparseConfig ) + find_package ( SuiteSparse_config 7.7.0 REQUIRED ) + endif ( ) +endif ( ) #------------------------------------------------------------------------------- # configure files @@ -72,59 +69,91 @@ configure_file ( "Config/amd_version.tex.in" "${PROJECT_SOURCE_DIR}/Doc/amd_vers # include directories #------------------------------------------------------------------------------- -include_directories ( Source Include ${SUITESPARSE_CONFIG_INCLUDE_DIR} ) +include_directories ( Source Include ) #------------------------------------------------------------------------------- # dynamic amd library properties #------------------------------------------------------------------------------- -if ( NOT NFORTRAN ) +if ( SUITESPARSE_HAS_FORTRAN ) file ( GLOB AMD_SOURCES "Source/*.c" "Source/*.f" ) else ( ) file ( GLOB AMD_SOURCES "Source/*.c" ) endif ( ) -add_library ( amd SHARED ${AMD_SOURCES} ) -set_target_properties ( amd PROPERTIES - VERSION ${AMD_VERSION_MAJOR}.${AMD_VERSION_MINOR}.${AMD_VERSION_SUB} - C_STANDARD_REQUIRED 11 - SOVERSION ${AMD_VERSION_MAJOR} - PUBLIC_HEADER "Include/amd.h" - WINDOWS_EXPORT_ALL_SYMBOLS ON ) +if ( BUILD_SHARED_LIBS ) + add_library ( AMD SHARED ${AMD_SOURCES} ) + set_target_properties ( AMD PROPERTIES + VERSION ${AMD_VERSION_MAJOR}.${AMD_VERSION_MINOR}.${AMD_VERSION_SUB} + C_STANDARD 11 + C_STANDARD_REQUIRED ON + OUTPUT_NAME amd + SOVERSION ${AMD_VERSION_MAJOR} + PUBLIC_HEADER "Include/amd.h" + WINDOWS_EXPORT_ALL_SYMBOLS ON ) + + if ( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.25" ) + set_target_properties ( AMD PROPERTIES EXPORT_NO_SYSTEM ON ) + endif ( ) + + target_include_directories ( AMD + INTERFACE $ + $ ) +endif ( ) #------------------------------------------------------------------------------- # static amd library properties #------------------------------------------------------------------------------- -if ( NOT NSTATIC ) - add_library ( amd_static STATIC ${AMD_SOURCES} ) - set_target_properties ( amd_static PROPERTIES - VERSION ${AMD_VERSION_MAJOR}.${AMD_VERSION_MINOR}.${AMD_VERSION_SUB} - C_STANDARD_REQUIRED 11 +if ( BUILD_STATIC_LIBS ) + add_library ( AMD_static STATIC ${AMD_SOURCES} ) + set_target_properties ( AMD_static PROPERTIES + C_STANDARD 11 + C_STANDARD_REQUIRED ON OUTPUT_NAME amd - SOVERSION ${AMD_VERSION_MAJOR} ) + PUBLIC_HEADER "Include/amd.h" ) - if ( MSVC ) - set_target_properties ( amd_static PROPERTIES + if ( MSVC OR ("${CMAKE_C_SIMULATE_ID}" STREQUAL "MSVC") ) + set_target_properties ( AMD_static PROPERTIES OUTPUT_NAME amd_static ) endif ( ) + + if ( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.25" ) + set_target_properties ( AMD_static PROPERTIES EXPORT_NO_SYSTEM ON ) + endif ( ) + + target_include_directories ( AMD_static + INTERFACE $ + $ ) + endif ( ) #------------------------------------------------------------------------------- # add the library dependencies #------------------------------------------------------------------------------- -# suitesparseconfig: -target_link_libraries ( amd PUBLIC ${SUITESPARSE_CONFIG_LIBRARIES} ) -if ( NOT NSTATIC ) - target_link_libraries ( amd_static PUBLIC ${SUITESPARSE_CONFIG_STATIC} ) +# SuiteSparseConfig: +if ( BUILD_SHARED_LIBS ) + target_link_libraries ( AMD PRIVATE SuiteSparse::SuiteSparseConfig ) + target_include_directories ( AMD PUBLIC + "$" ) +endif ( ) +if ( BUILD_STATIC_LIBS ) + if ( TARGET SuiteSparse::SuiteSparseConfig_static ) + target_link_libraries ( AMD_static PUBLIC SuiteSparse::SuiteSparseConfig_static ) + else ( ) + target_link_libraries ( AMD_static PUBLIC SuiteSparse::SuiteSparseConfig ) + endif ( ) endif ( ) # libm: if ( NOT WIN32 ) - target_link_libraries ( amd PUBLIC m ) - if ( NOT NSTATIC ) - target_link_libraries ( amd_static PUBLIC m ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries ( AMD PRIVATE m ) + endif ( ) + if ( BUILD_STATIC_LIBS ) + set ( AMD_STATIC_LIBS "${AMD_STATIC_LIBS} -lm" ) + target_link_libraries ( AMD_static PUBLIC m ) endif ( ) endif ( ) @@ -132,25 +161,99 @@ endif ( ) # AMD installation location #------------------------------------------------------------------------------- -install ( TARGETS amd - LIBRARY DESTINATION ${SUITESPARSE_LIBDIR} - ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} - RUNTIME DESTINATION ${SUITESPARSE_BINDIR} - PUBLIC_HEADER DESTINATION ${SUITESPARSE_INCLUDEDIR} ) -install ( FILES ${CMAKE_SOURCE_DIR}/cmake_modules/FindAMD.cmake - DESTINATION ${SUITESPARSE_LIBDIR}/cmake/SuiteSparse - COMPONENT Development ) -if ( NOT NSTATIC ) - install ( TARGETS amd_static - ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} ) +include ( CMakePackageConfigHelpers ) + +if ( BUILD_SHARED_LIBS ) + install ( TARGETS AMD + EXPORT AMDTargets + LIBRARY DESTINATION ${SUITESPARSE_LIBDIR} + ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} + RUNTIME DESTINATION ${SUITESPARSE_BINDIR} + PUBLIC_HEADER DESTINATION ${SUITESPARSE_INCLUDEDIR} ) +endif ( ) +if ( BUILD_STATIC_LIBS ) + install ( TARGETS AMD_static + EXPORT AMDTargets + ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} + PUBLIC_HEADER DESTINATION ${SUITESPARSE_INCLUDEDIR} ) +endif ( ) + +# create (temporary) export target file during build +export ( EXPORT AMDTargets + NAMESPACE SuiteSparse:: + FILE ${CMAKE_CURRENT_BINARY_DIR}/AMDTargets.cmake ) + +# install export target, config and version files for find_package +install ( EXPORT AMDTargets + NAMESPACE SuiteSparse:: + DESTINATION ${SUITESPARSE_PKGFILEDIR}/cmake/AMD ) + +# generate config file to be used in common build tree +set ( SUITESPARSE_IN_BUILD_TREE ON ) +configure_package_config_file ( + Config/AMDConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/AMDConfig.cmake + INSTALL_DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/AMDConfig.cmake ) + +# generate config file to be installed +set ( SUITESPARSE_IN_BUILD_TREE OFF ) +configure_package_config_file ( + Config/AMDConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/target/AMDConfig.cmake + INSTALL_DESTINATION ${SUITESPARSE_PKGFILEDIR}/cmake/AMD ) + +write_basic_package_version_file ( + ${CMAKE_CURRENT_BINARY_DIR}/AMDConfigVersion.cmake + COMPATIBILITY SameMajorVersion ) + +install ( FILES + ${CMAKE_CURRENT_BINARY_DIR}/target/AMDConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/AMDConfigVersion.cmake + DESTINATION ${SUITESPARSE_PKGFILEDIR}/cmake/AMD ) + +#------------------------------------------------------------------------------- +# create pkg-config file +#------------------------------------------------------------------------------- + +if ( NOT MSVC ) + 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/AMD.pc.in + AMD.pc.out + @ONLY + NEWLINE_STYLE LF ) + file ( GENERATE + OUTPUT AMD.pc + INPUT ${CMAKE_CURRENT_BINARY_DIR}/AMD.pc.out + NEWLINE_STYLE LF ) + install ( FILES + ${CMAKE_CURRENT_BINARY_DIR}/AMD.pc + DESTINATION ${SUITESPARSE_PKGFILEDIR}/pkgconfig ) endif ( ) #------------------------------------------------------------------------------- # Demo library and programs #------------------------------------------------------------------------------- -option ( DEMO "ON: Build the demo programs. OFF (default): do not build the demo programs." off ) -if ( DEMO ) +if ( SUITESPARSE_DEMOS ) #--------------------------------------------------------------------------- # demo library @@ -166,19 +269,30 @@ if ( DEMO ) add_executable ( amd_l_demo "Demo/amd_l_demo.c" ) add_executable ( amd_demo2 "Demo/amd_demo2.c" ) add_executable ( amd_simple "Demo/amd_simple.c" ) - if ( NOT NFORTRAN ) + if ( SUITESPARSE_HAS_FORTRAN ) add_executable ( amd_f77demo "Demo/amd_f77demo.f" ) add_executable ( amd_f77simple "Demo/amd_f77simple.f" ) endif ( ) # Libraries required for Demo programs - target_link_libraries ( amd_demo PUBLIC amd ) - target_link_libraries ( amd_l_demo PUBLIC amd ) - target_link_libraries ( amd_demo2 PUBLIC amd ) - target_link_libraries ( amd_simple PUBLIC amd ) - if ( NOT NFORTRAN ) - target_link_libraries ( amd_f77demo PUBLIC amd ) - target_link_libraries ( amd_f77simple PUBLIC amd ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries ( amd_demo PUBLIC AMD ) + target_link_libraries ( amd_l_demo PUBLIC AMD ) + target_link_libraries ( amd_demo2 PUBLIC AMD ) + target_link_libraries ( amd_simple PUBLIC AMD ) + if ( SUITESPARSE_HAS_FORTRAN ) + target_link_libraries ( amd_f77demo PUBLIC AMD ) + target_link_libraries ( amd_f77simple PUBLIC AMD ) + endif ( ) + else ( ) + target_link_libraries ( amd_demo PUBLIC AMD_static ) + target_link_libraries ( amd_l_demo PUBLIC AMD_static ) + target_link_libraries ( amd_demo2 PUBLIC AMD_static ) + target_link_libraries ( amd_simple PUBLIC AMD_static ) + if ( SUITESPARSE_HAS_FORTRAN ) + target_link_libraries ( amd_f77demo PUBLIC AMD_static ) + target_link_libraries ( amd_f77simple PUBLIC AMD_static ) + endif ( ) endif ( ) else ( ) @@ -192,4 +306,3 @@ endif ( ) #------------------------------------------------------------------------------- include ( SuiteSparseReport ) - diff --git a/AMD/Config/AMD.pc.in b/AMD/Config/AMD.pc.in new file mode 100644 index 00000000..e5b50986 --- /dev/null +++ b/AMD/Config/AMD.pc.in @@ -0,0 +1,17 @@ +# AMD, Copyright (c) 1996-2023, Timothy A. Davis. +# All Rights Reserved. +# SPDX-License-Identifier: BSD-3-Clause + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: AMD +URL: https://github.com/DrTimothyAldenDavis/SuiteSparse +Description: Routines for permuting sparse matrices prior to factorization in SuiteSparse +Version: @AMD_VERSION_MAJOR@.@AMD_VERSION_MINOR@.@AMD_VERSION_SUB@ +Requires.private: SuiteSparse_config +Libs: -L${libdir} -l@SUITESPARSE_LIB_BASE_NAME@ +Libs.private: @AMD_STATIC_LIBS@ +Cflags: -I${includedir} diff --git a/AMD/Config/AMDConfig.cmake.in b/AMD/Config/AMDConfig.cmake.in new file mode 100644 index 00000000..d21e0501 --- /dev/null +++ b/AMD/Config/AMDConfig.cmake.in @@ -0,0 +1,152 @@ +#------------------------------------------------------------------------------- +# SuiteSparse/AMD/cmake_modules/AMDConfig.cmake +#------------------------------------------------------------------------------- + +# The following copyright and license applies to just this file only, not to +# the library itself: +# AMDConfig.cmake, Copyright (c) 2023, Timothy A. Davis. All Rights Reserved. +# SPDX-License-Identifier: BSD-3-clause + +#------------------------------------------------------------------------------- + +# Finds the AMD include file and compiled library. +# The following targets are defined: +# SuiteSparse::AMD - for the shared library (if available) +# SuiteSparse::AMD_static - for the static library (if available) + +# For backward compatibility the following variables are set: + +# AMD_INCLUDE_DIR - where to find amd.h +# AMD_LIBRARY - dynamic AMD library +# AMD_STATIC - static AMD library +# AMD_LIBRARIES - libraries when using AMD +# AMD_FOUND - true if AMD found + +# Set ``CMAKE_MODULE_PATH`` to the parent folder where this module file is +# installed. + +#------------------------------------------------------------------------------- + +@PACKAGE_INIT@ + +set ( AMD_DATE "@AMD_DATE@" ) +set ( AMD_VERSION_MAJOR @AMD_VERSION_MAJOR@ ) +set ( AMD_VERSION_MINOR @AMD_VERSION_MINOR@ ) +set ( AMD_VERSION_PATCH @AMD_VERSION_SUB@ ) +set ( AMD_VERSION "@AMD_VERSION_MAJOR@.@AMD_VERSION_MINOR@.@AMD_VERSION_SUB@" ) + +# Check for dependent targets +include ( CMakeFindDependencyMacro ) + +# Look for SuiteSparse_config target +if ( @SUITESPARSE_IN_BUILD_TREE@ ) + if ( NOT TARGET SuiteSparse::SuiteSparseConfig ) + # First check in a common build tree + find_dependency ( SuiteSparse_config @SUITESPARSE_CONFIG_VERSION_MAJOR@.@SUITESPARSE_CONFIG_VERSION_MINOR@ + PATHS ${CMAKE_SOURCE_DIR}/../SuiteSparse_config/build NO_DEFAULT_PATH ) + # Then, check in the currently active CMAKE_MODULE_PATH + if ( NOT SuiteSparse_config_FOUND ) + find_dependency ( SuiteSparse_config @SUITESPARSE_CONFIG_VERSION_MAJOR@.@SUITESPARSE_CONFIG_VERSION_MINOR@ ) + endif ( ) + endif ( ) +else ( ) + if ( NOT TARGET SuiteSparse::SuiteSparseConfig ) + find_dependency ( SuiteSparse_config @SUITESPARSE_CONFIG_VERSION_MAJOR@.@SUITESPARSE_CONFIG_VERSION_MINOR@ ) + endif ( ) +endif ( ) +if ( NOT SuiteSparse_config_FOUND ) + set ( AMD_FOUND OFF ) + return ( ) +endif ( ) + + +# Import target +include ( ${CMAKE_CURRENT_LIST_DIR}/AMDTargets.cmake ) + +# The following is only for backward compatibility with FindAMD. + +set ( _target_shared SuiteSparse::AMD ) +set ( _target_static SuiteSparse::AMD_static ) +set ( _var_prefix "AMD" ) + +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 ( ) + +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 ( AMD_LIBRARIES ${AMD_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 ( AMD_INCLUDE_DIR ${AMD_INCLUDE_DIR} ) +suitesparse_check_exist ( AMD_LIBRARY ${AMD_LIBRARY} ) + +message ( STATUS "AMD version: ${AMD_VERSION}" ) +message ( STATUS "AMD include: ${AMD_INCLUDE_DIR}") +message ( STATUS "AMD library: ${AMD_LIBRARY}") +message ( STATUS "AMD static: ${AMD_STATIC}") diff --git a/AMD/Config/amd.h.in b/AMD/Config/amd.h.in index f2a69166..956af010 100644 --- a/AMD/Config/amd.h.in +++ b/AMD/Config/amd.h.in @@ -2,7 +2,7 @@ // AMD/Include/amd.h: approximate minimum degree ordering //------------------------------------------------------------------------------ -// AMD, Copyright (c) 1996-2022, Timothy A. Davis, Patrick R. Amestoy, and +// AMD, Copyright (c) 1996-2024, Timothy A. Davis, Patrick R. Amestoy, and // Iain S. Duff. All Rights Reserved. // SPDX-License-Identifier: BSD-3-clause @@ -35,13 +35,13 @@ #ifndef AMD_H #define AMD_H +#include "SuiteSparse_config.h" + /* make it easy for C++ programs to include AMD */ #ifdef __cplusplus extern "C" { #endif -#include "SuiteSparse_config.h" - int amd_order /* returns AMD_OK, AMD_OK_BUT_JUMBLED, * AMD_INVALID, or AMD_OUT_OF_MEMORY */ ( @@ -313,6 +313,14 @@ void amd_l_control (double Control [ ]) ; void amd_info (double Info [ ]) ; void amd_l_info (double Info [ ]) ; +// amd_version: return AMD version. The version array is returned with +// version [0..2] = {AMD_MAIN_VERSION, AMD_SUB_VERSION, AMD_SUBSUB_VERSION} +void amd_version (int version [3]) ; + +#ifdef __cplusplus +} +#endif + #define AMD_CONTROL 5 /* size of Control array */ #define AMD_INFO 20 /* size of Info array */ @@ -379,11 +387,13 @@ void amd_l_info (double Info [ ]) ; #define AMD_SUB_VERSION @AMD_VERSION_MINOR@ #define AMD_SUBSUB_VERSION @AMD_VERSION_SUB@ -#define AMD_VERSION_CODE(main,sub) ((main) * 1000 + (sub)) -#define AMD_VERSION AMD_VERSION_CODE(AMD_MAIN_VERSION,AMD_SUB_VERSION) +#define AMD_VERSION_CODE(main,sub) SUITESPARSE_VER_CODE(main,sub) +#define AMD_VERSION AMD_VERSION_CODE(@AMD_VERSION_MAJOR@,@AMD_VERSION_MINOR@) -#ifdef __cplusplus -} +#define AMD__VERSION SUITESPARSE__VERCODE(@AMD_VERSION_MAJOR@,@AMD_VERSION_MINOR@,@AMD_VERSION_SUB@) +#if !defined (SUITESPARSE__VERSION) || \ + (SUITESPARSE__VERSION < SUITESPARSE__VERCODE(7,7,0)) +#error "AMD @AMD_VERSION_MAJOR@.@AMD_VERSION_MINOR@.@AMD_VERSION_SUB@ requires SuiteSparse_config 7.7.0 or later" #endif #endif diff --git a/AMD/Demo/amd_demo.c b/AMD/Demo/amd_demo.c index 507ab7cc..b599d06d 100644 --- a/AMD/Demo/amd_demo.c +++ b/AMD/Demo/amd_demo.c @@ -52,14 +52,17 @@ int main (void) double Control [AMD_CONTROL], Info [AMD_INFO] ; char A [24][24] ; - /* here is an example of how to use AMD_VERSION. This code will work in - * any version of AMD. */ -#if defined(AMD_VERSION) && (AMD_VERSION >= AMD_VERSION_CODE(1,2)) printf ("AMD version %d.%d.%d, date: %s\n", AMD_MAIN_VERSION, AMD_SUB_VERSION, AMD_SUBSUB_VERSION, AMD_DATE) ; -#else - printf ("AMD version: 1.1 or earlier\n") ; -#endif + int version [3] ; + amd_version (version) ; + if ((version [0] != AMD_MAIN_VERSION) || + (version [1] != AMD_SUB_VERSION) || + (version [2] != AMD_SUBSUB_VERSION)) + { + fprintf (stderr, "version in header does not match library\n") ; + abort ( ) ; + } printf ("AMD demo, with the 24-by-24 Harwell/Boeing matrix, can_24:\n") ; diff --git a/AMD/Demo/amd_demo.out b/AMD/Demo/amd_demo.out index 8180f3a8..0422dc5b 100644 --- a/AMD/Demo/amd_demo.out +++ b/AMD/Demo/amd_demo.out @@ -1,7 +1,7 @@ -AMD version 3.0.3, date: Jan 17, 2023 +AMD version 3.3.2, date: Mar 22, 2024 AMD demo, with the 24-by-24 Harwell/Boeing matrix, can_24: -AMD version 3.0.3, Jan 17, 2023: approximate minimum degree ordering +AMD version 3.3.2, Mar 22, 2024: approximate minimum degree ordering dense row parameter: 10 (rows with more than max (10 * sqrt (n), 16) entries are considered "dense", and placed last in output permutation) @@ -115,7 +115,7 @@ Plot of input matrix pattern: 23: . . . . . . X . . . . X X . . . . . . . . . . X return value from amd_order: 0 (should be 0) -AMD version 3.0.3, Jan 17, 2023, results: +AMD version 3.3.2, Mar 22, 2024, results: status: OK n, dimension of A: 24 nz, number of nonzeros in A: 160 diff --git a/AMD/Demo/amd_demo2.out b/AMD/Demo/amd_demo2.out index aebf70ab..f384d828 100644 --- a/AMD/Demo/amd_demo2.out +++ b/AMD/Demo/amd_demo2.out @@ -1,7 +1,7 @@ AMD demo, with a jumbled version of the 24-by-24 Harwell/Boeing matrix, can_24: -AMD version 3.0.3, Jan 17, 2023: approximate minimum degree ordering +AMD version 3.3.2, Mar 22, 2024: approximate minimum degree ordering dense row parameter: 10 (rows with more than max (10 * sqrt (n), 16) entries are considered "dense", and placed last in output permutation) @@ -144,7 +144,7 @@ Plot of symmetric matrix to be ordered by amd_order: 23: . . . . . . X . . . . X X . . . . . . . . . . X return value from amd_order: 1 (should be 1) -AMD version 3.0.3, Jan 17, 2023, results: +AMD version 3.3.2, Mar 22, 2024, results: status: OK, but jumbled n, dimension of A: 24 nz, number of nonzeros in A: 102 diff --git a/AMD/Demo/amd_l_demo.c b/AMD/Demo/amd_l_demo.c index 7def82c7..ff5816ae 100644 --- a/AMD/Demo/amd_l_demo.c +++ b/AMD/Demo/amd_l_demo.c @@ -53,14 +53,17 @@ int main (void) double Control [AMD_CONTROL], Info [AMD_INFO] ; char A [24][24] ; - /* here is an example of how to use AMD_VERSION. This code will work in - * any version of AMD. */ -#if defined(AMD_VERSION) && (AMD_VERSION >= AMD_VERSION_CODE(1,2)) printf ("AMD version %d.%d.%d, date: %s\n", AMD_MAIN_VERSION, AMD_SUB_VERSION, AMD_SUBSUB_VERSION, AMD_DATE) ; -#else - printf ("AMD version: 1.1 or earlier\n") ; -#endif + int version [3] ; + amd_version (version) ; + if ((version [0] != AMD_MAIN_VERSION) || + (version [1] != AMD_SUB_VERSION) || + (version [2] != AMD_SUBSUB_VERSION)) + { + fprintf (stderr, "version in header does not match library\n") ; + abort ( ) ; + } printf ("AMD demo, with the 24-by-24 Harwell/Boeing matrix, can_24:\n") ; diff --git a/AMD/Demo/amd_l_demo.out b/AMD/Demo/amd_l_demo.out index 5265f5a0..019ce0ce 100644 --- a/AMD/Demo/amd_l_demo.out +++ b/AMD/Demo/amd_l_demo.out @@ -1,7 +1,7 @@ -AMD version 3.0.3, date: Jan 17, 2023 +AMD version 3.3.2, date: Mar 22, 2024 AMD demo, with the 24-by-24 Harwell/Boeing matrix, can_24: -AMD version 3.0.3, Jan 17, 2023: approximate minimum degree ordering +AMD version 3.3.2, Mar 22, 2024: approximate minimum degree ordering dense row parameter: 10 (rows with more than max (10 * sqrt (n), 16) entries are considered "dense", and placed last in output permutation) @@ -115,7 +115,7 @@ Plot of input matrix pattern: 23: . . . . . . X . . . . X X . . . . . . . . . . X return value from amd_l_order: 0 (should be 0) -AMD version 3.0.3, Jan 17, 2023, results: +AMD version 3.3.2, Mar 22, 2024, results: status: OK n, dimension of A: 24 nz, number of nonzeros in A: 160 diff --git a/AMD/Doc/AMD_UserGuide.pdf b/AMD/Doc/AMD_UserGuide.pdf index 4cdcddc5..7b3fd6bf 100644 Binary files a/AMD/Doc/AMD_UserGuide.pdf and b/AMD/Doc/AMD_UserGuide.pdf differ diff --git a/AMD/Doc/AMD_UserGuide.tex b/AMD/Doc/AMD_UserGuide.tex index 2e5e1ede..794a29cd 100644 --- a/AMD/Doc/AMD_UserGuide.tex +++ b/AMD/Doc/AMD_UserGuide.tex @@ -46,7 +46,7 @@ \end{abstract} %------------------------------------------------------------------------------ -AMD Copyright\copyright 1996-2022 by Timothy A. +AMD Copyright\copyright 1996-2023 by Timothy A. Davis, Patrick R. Amestoy, and Iain S. Duff. All Rights Reserved. AMD is available under alternate licences; contact T. Davis for details. @@ -202,8 +202,8 @@ \section{Using AMD in a C program} \label{Cversion} %------------------------------------------------------------------------------ -The C-callable AMD library consists of seven user-callable routines and one -include file. There are two versions of each of the routines, with +The C-callable AMD library consists of eight user-callable routines and one +include file. There are two versions of seven of the routines, with \verb'int32_t' and \verb'int64_t' integers. The routines with prefix {\tt amd\_l\_} use \verb'int64_t' integer arguments; the others use @@ -303,6 +303,8 @@ \section{Using AMD in a C program} but it destroys the matrix on output. Additional workspace must be passed. Refer to the source file {\tt AMD/Source/amd\_2.c} for a description. +\item \verb'amd_version': returns the AMD version. + \end{itemize} The nonzero pattern of the matrix $\m{A}$ is represented in compressed column @@ -480,6 +482,16 @@ \section{Synopsis of C-callable routines} \end{verbatim} } +The \verb'amd_version' function uses plain \verb'int': + +{\footnotesize +\begin{verbatim} +#include "amd.h" +int version [3] ; +amd_version (version) ; +\end{verbatim} +} + %------------------------------------------------------------------------------ \section{Using AMD in a Fortran program} %------------------------------------------------------------------------------ diff --git a/AMD/Doc/ChangeLog b/AMD/Doc/ChangeLog index 97dbc0d8..134b5ca9 100644 --- a/AMD/Doc/ChangeLog +++ b/AMD/Doc/ChangeLog @@ -1,3 +1,29 @@ +Mar 22, 2024: version 3.3.2 + + * minor updates to build system + +Jan 10, 2024: version 3.3.1 + + * minor updates to build system + +Dec 30, 2023: version 3.3.0 + + * major change to build system: by Markus Mützel + * revised test for integer overflow: for CHOLMOD 5.1.0 tests + * amd_version: added to return version of AMD + +Sept 18, 2023: version 3.2.1 + + * cmake update: add "None" build type, from Antonio Rojas, for Arch Linux + +Sept 8, 2023: version 3.2.0 + + * cmake updates: SuiteSparse:: namespace by Markus Muetzel + +June 16, 2023: version 3.0.4 + + * cmake build system updates: update by Markus Muetzel + Jan 17, 2023: version 3.0.3 * NFORTRAN: option added to disable Fortran entirely diff --git a/AMD/Doc/amd_version.tex b/AMD/Doc/amd_version.tex index e24c8cda..c36dbd40 100644 --- a/AMD/Doc/amd_version.tex +++ b/AMD/Doc/amd_version.tex @@ -1,2 +1,2 @@ % version of SuiteSparse/AMD -\date{VERSION 3.0.3, Jan 17, 2023} +\date{VERSION 3.3.2, Mar 22, 2024} diff --git a/AMD/Include/amd.h b/AMD/Include/amd.h index 94aa96f1..a253a310 100644 --- a/AMD/Include/amd.h +++ b/AMD/Include/amd.h @@ -2,7 +2,7 @@ // AMD/Include/amd.h: approximate minimum degree ordering //------------------------------------------------------------------------------ -// AMD, Copyright (c) 1996-2022, Timothy A. Davis, Patrick R. Amestoy, and +// AMD, Copyright (c) 1996-2024, Timothy A. Davis, Patrick R. Amestoy, and // Iain S. Duff. All Rights Reserved. // SPDX-License-Identifier: BSD-3-clause @@ -35,13 +35,13 @@ #ifndef AMD_H #define AMD_H +#include "SuiteSparse_config.h" + /* make it easy for C++ programs to include AMD */ #ifdef __cplusplus extern "C" { #endif -#include "SuiteSparse_config.h" - int amd_order /* returns AMD_OK, AMD_OK_BUT_JUMBLED, * AMD_INVALID, or AMD_OUT_OF_MEMORY */ ( @@ -313,6 +313,14 @@ void amd_l_control (double Control [ ]) ; void amd_info (double Info [ ]) ; void amd_l_info (double Info [ ]) ; +// amd_version: return AMD version. The version array is returned with +// version [0..2] = {AMD_MAIN_VERSION, AMD_SUB_VERSION, AMD_SUBSUB_VERSION} +void amd_version (int version [3]) ; + +#ifdef __cplusplus +} +#endif + #define AMD_CONTROL 5 /* size of Control array */ #define AMD_INFO 20 /* size of Info array */ @@ -374,16 +382,18 @@ void amd_l_info (double Info [ ]) ; * Versions 1.1 and earlier of AMD do not include a #define'd version number. */ -#define AMD_DATE "Jan 17, 2023" +#define AMD_DATE "Mar 22, 2024" #define AMD_MAIN_VERSION 3 -#define AMD_SUB_VERSION 0 -#define AMD_SUBSUB_VERSION 3 +#define AMD_SUB_VERSION 3 +#define AMD_SUBSUB_VERSION 2 -#define AMD_VERSION_CODE(main,sub) ((main) * 1000 + (sub)) -#define AMD_VERSION AMD_VERSION_CODE(AMD_MAIN_VERSION,AMD_SUB_VERSION) +#define AMD_VERSION_CODE(main,sub) SUITESPARSE_VER_CODE(main,sub) +#define AMD_VERSION AMD_VERSION_CODE(3,3) -#ifdef __cplusplus -} +#define AMD__VERSION SUITESPARSE__VERCODE(3,3,2) +#if !defined (SUITESPARSE__VERSION) || \ + (SUITESPARSE__VERSION < SUITESPARSE__VERCODE(7,7,0)) +#error "AMD 3.3.2 requires SuiteSparse_config 7.7.0 or later" #endif #endif diff --git a/AMD/Include/amd_internal.h b/AMD/Include/amd_internal.h index 85d43930..b5649cbc 100644 --- a/AMD/Include/amd_internal.h +++ b/AMD/Include/amd_internal.h @@ -2,7 +2,7 @@ // AMD/Include/amd_internal.h: internal definitions for AMD //------------------------------------------------------------------------------ -// AMD, Copyright (c) 1996-2022, Timothy A. Davis, Patrick R. Amestoy, and +// AMD, Copyright (c) 1996-2023, Timothy A. Davis, Patrick R. Amestoy, and // Iain S. Duff. All Rights Reserved. // SPDX-License-Identifier: BSD-3-clause @@ -37,12 +37,9 @@ #define NDEBUG #endif -/* - To enable debugging, uncomment the following line: -#undef NDEBUG -*/ +// To enable debugging, uncomment the following line: +// #undef NDEBUG -#define SUITESPARSE_LIBRARY #include "amd.h" /* ------------------------------------------------------------------------- */ diff --git a/AMD/Makefile b/AMD/Makefile index ad08cc1d..15da7cea 100644 --- a/AMD/Makefile +++ b/AMD/Makefile @@ -36,36 +36,36 @@ default: library # default is to install only in /usr/local library: - ( cd build && cmake $(CMAKE_OPTIONS) .. && cmake --build . -j${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) -DLOCAL_INSTALL=1 .. && cmake --build . -j${JOBS} ) + ( cd build && cmake $(CMAKE_OPTIONS) -USUITESPARSE_PKGFILEDIR -DSUITESPARSE_LOCAL_INSTALL=1 .. && cmake --build . --config Release -j${JOBS} ) # install only in /usr/local (default) global: - ( cd build && cmake $(CMAKE_OPTIONS) -DLOCAL_INSTALL=0 .. && cmake --build . -j${JOBS} ) + ( cd build && cmake $(CMAKE_OPTIONS) -USUITESPARSE_PKGFILEDIR -DSUITESPARSE_LOCAL_INSTALL=0 .. && cmake --build . --config Release -j${JOBS} ) debug: - ( cd build && cmake $(CMAKE_OPTIONS) -DCMAKE_BUILD_TYPE=Debug .. && cmake --build . -j${JOBS} ) + ( cd build && cmake $(CMAKE_OPTIONS) -DCMAKE_BUILD_TYPE=Debug .. && cmake --build . --config Debug -j${JOBS} ) all: library demos: library - ( cd build && cmake $(CMAKE_OPTIONS) -DDEMO=1 .. && cmake --build . -j${JOBS} ) - ./build/amd_demo > build/amd_demo.out - - diff --strip-trailing-cr Demo/amd_demo.out build/amd_demo.out - ./build/amd_l_demo > build/amd_l_demo.out - - diff --strip-trailing-cr Demo/amd_l_demo.out build/amd_l_demo.out - ./build/amd_demo2 > build/amd_demo2.out - - diff --strip-trailing-cr Demo/amd_demo2.out build/amd_demo2.out - ./build/amd_simple > build/amd_simple.out - - diff --strip-trailing-cr Demo/amd_simple.out build/amd_simple.out + ( cd build && cmake $(CMAKE_OPTIONS) -DSUITESPARSE_DEMOS=1 .. && cmake --build . --config Release -j${JOBS} ) + ./build/amd_demo > build/amd_demo.out && ( command -v d2u && d2u ./build/amd_demo.out || true ) + - diff Demo/amd_demo.out build/amd_demo.out + ./build/amd_l_demo > build/amd_l_demo.out && ( command -v d2u && d2u ./build/amd_l_demo.out || true ) + - diff Demo/amd_l_demo.out build/amd_l_demo.out + ./build/amd_demo2 > build/amd_demo2.out && ( command -v d2u && d2u ./build/amd_demo2.out || true ) + - diff Demo/amd_demo2.out build/amd_demo2.out + ./build/amd_simple > build/amd_simple.out && ( command -v d2u && d2u ./build/amd_simple.out || true ) + - diff Demo/amd_simple.out build/amd_simple.out # Fortran demos will fail if no Fortran compiler is available - - ./build/amd_f77simple > build/amd_f77simple.out - - diff --strip-trailing-cr Demo/amd_f77simple.out build/amd_f77simple.out - - ./build/amd_f77demo > build/amd_f77demo.out - - diff --strip-trailing-cr Demo/amd_f77demo.out build/amd_f77demo.out + - ./build/amd_f77simple > build/amd_f77simple.out && ( command -v d2u && d2u ./build/amd_f77simple.out || true ) + - diff Demo/amd_f77simple.out build/amd_f77simple.out + - ./build/amd_f77demo > build/amd_f77demo.out && ( command -v d2u && d2u ./build/amd_f77demo.out || true ) + - diff Demo/amd_f77demo.out build/amd_f77demo.out # just compile after running cmake; do not run cmake again remake: diff --git a/AMD/Source/amd_order.c b/AMD/Source/amd_order.c index 1dcc15a0..9df32164 100644 --- a/AMD/Source/amd_order.c +++ b/AMD/Source/amd_order.c @@ -71,9 +71,9 @@ int AMD_order return (AMD_INVALID) ; } - /* check if n or nz will cause size_t overflow */ - if (((size_t) n) >= SIZE_T_MAX / sizeof (Int) - || ((size_t) nz) >= SIZE_T_MAX / sizeof (Int)) + /* check if n or nz will cause integer overflow */ + if (((size_t) n) >= Int_MAX / sizeof (Int) + || ((size_t) nz) >= Int_MAX / sizeof (Int)) { if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ; return (AMD_OUT_OF_MEMORY) ; /* problem too large */ @@ -89,8 +89,9 @@ int AMD_order } /* allocate two size-n integer workspaces */ - Len = SuiteSparse_malloc (n, sizeof (Int)) ; - Pinv = SuiteSparse_malloc (n, sizeof (Int)) ; + size_t nn = (size_t) n ; + Len = SuiteSparse_malloc (nn, sizeof (Int)) ; + Pinv = SuiteSparse_malloc (nn, sizeof (Int)) ; mem += n ; mem += n ; if (!Len || !Pinv) @@ -106,7 +107,7 @@ int AMD_order { /* sort the input matrix and remove duplicate entries */ AMD_DEBUG1 (("Matrix is jumbled\n")) ; - Rp = SuiteSparse_malloc (n+1, sizeof (Int)) ; + Rp = SuiteSparse_malloc (nn+1, sizeof (Int)) ; Ri = SuiteSparse_malloc (nz, sizeof (Int)) ; mem += (n+1) ; mem += MAX (nz,1) ; @@ -152,8 +153,8 @@ int AMD_order slen += nzaat/5 ; /* add elbow room */ for (i = 0 ; ok && i < 7 ; i++) { - ok = ((slen + n) > slen) ; /* check for size_t overflow */ - slen += n ; /* size-n elbow room, 6 size-n work */ + ok = ((slen + nn) > slen) ; /* check for size_t overflow */ + slen += nn ; /* size-n elbow room, 6 size-n work */ } mem += slen ; ok = ok && (slen < SIZE_T_MAX / sizeof (Int)) ; /* check for overflow */ diff --git a/AMD/Source/amd_version.c b/AMD/Source/amd_version.c new file mode 100644 index 00000000..7d045f35 --- /dev/null +++ b/AMD/Source/amd_version.c @@ -0,0 +1,19 @@ +//------------------------------------------------------------------------------ +// AMD/Source/amd_version: return AMD version +//------------------------------------------------------------------------------ + +// AMD, Copyright (c) 1996-2023, Timothy A. Davis, Patrick R. Amestoy, and +// Iain S. Duff. All Rights Reserved. +// SPDX-License-Identifier: BSD-3-clause + +//------------------------------------------------------------------------------ + +#include "amd_internal.h" + +void amd_version (int version [3]) +{ + version [0] = AMD_MAIN_VERSION ; + version [1] = AMD_SUB_VERSION ; + version [2] = AMD_SUBSUB_VERSION ; +} + diff --git a/AMD/cmake_modules/FindAMD.cmake b/AMD/cmake_modules/FindAMD.cmake deleted file mode 100644 index 1b135e05..00000000 --- a/AMD/cmake_modules/FindAMD.cmake +++ /dev/null @@ -1,129 +0,0 @@ -#------------------------------------------------------------------------------- -# SuiteSparse/AMD/cmake_modules/FindAMD.cmake -#------------------------------------------------------------------------------- - -# The following copyright and license applies to just this file only, not to -# the library itself: -# FindAMD.cmake, Copyright (c) 2022-2023, Timothy A. Davis. All Rights Reserved. -# SPDX-License-Identifier: BSD-3-clause - -#------------------------------------------------------------------------------- - -# Finds the AMD include file and compiled library and sets: - -# AMD_INCLUDE_DIR - where to find amd.h -# AMD_LIBRARY - dynamic AMD library -# AMD_STATIC - static AMD library -# AMD_LIBRARIES - libraries when using AMD -# AMD_FOUND - true if AMD found - -# set ``AMD_ROOT`` to an AMD installation root to -# tell this module where to look. - -# 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: -# -# set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} -# ${CMAKE_INSTALL_PREFIX}/lib/cmake/SuiteSparse ) - -#------------------------------------------------------------------------------- - -# include files for AMD -find_path ( AMD_INCLUDE_DIR - NAMES amd.h - HINTS ${CMAKE_SOURCE_DIR}/.. - HINTS ${CMAKE_SOURCE_DIR}/../SuiteSparse/AMD - HINTS ${CMAKE_SOURCE_DIR}/../AMD - PATH_SUFFIXES include Include -) - -# dynamic AMD library (or static if no dynamic library was built) -find_library ( AMD_LIBRARY - NAMES amd amd_static - HINTS ${CMAKE_SOURCE_DIR}/.. - HINTS ${CMAKE_SOURCE_DIR}/../SuiteSparse/AMD - HINTS ${CMAKE_SOURCE_DIR}/../AMD - PATH_SUFFIXES lib build build/Release build/Debug -) - -if ( MSVC ) - set ( STATIC_NAME amd_static ) -else ( ) - set ( STATIC_NAME amd ) - set ( save ${CMAKE_FIND_LIBRARY_SUFFIXES} ) - set ( CMAKE_FIND_LIBRARY_SUFFIXES - ${CMAKE_STATIC_LIBRARY_SUFFIX} ${CMAKE_FIND_LIBRARY_SUFFIXES} ) -endif ( ) - -# static AMD library -find_library ( AMD_STATIC - NAMES ${STATIC_NAME} - HINTS ${CMAKE_SOURCE_DIR}/.. - HINTS ${CMAKE_SOURCE_DIR}/../SuiteSparse/AMD - HINTS ${CMAKE_SOURCE_DIR}/../AMD - PATH_SUFFIXES lib build build/Release build/Debug -) - -if ( NOT MSVC ) - # restore the CMAKE_FIND_LIBRARY_SUFFIXES variable - set ( CMAKE_FIND_LIBRARY_SUFFIXES ${save} ) -endif ( ) - -# get version of the library from the dynamic library name -get_filename_component ( AMD_LIBRARY ${AMD_LIBRARY} REALPATH ) -get_filename_component ( AMD_FILENAME ${AMD_LIBRARY} NAME ) -string ( - REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" - AMD_VERSION - ${AMD_FILENAME} -) - -# set ( AMD_VERSION "" ) -if ( EXISTS "${AMD_INCLUDE_DIR}" AND NOT AMD_VERSION ) - # if the version does not appear in the filename, read the include file - file ( STRINGS ${AMD_INCLUDE_DIR}/amd.h AMD_MAJOR_STR - REGEX "define AMD_MAIN_VERSION" ) - file ( STRINGS ${AMD_INCLUDE_DIR}/amd.h AMD_MINOR_STR - REGEX "define AMD_SUB_VERSION" ) - file ( STRINGS ${AMD_INCLUDE_DIR}/amd.h AMD_PATCH_STR - REGEX "define AMD_SUBSUB_VERSION" ) - message ( STATUS "major: ${AMD_MAJOR_STR}" ) - message ( STATUS "minor: ${AMD_MINOR_STR}" ) - message ( STATUS "patch: ${AMD_PATCH_STR}" ) - string ( REGEX MATCH "[0-9]+" AMD_MAJOR ${AMD_MAJOR_STR} ) - string ( REGEX MATCH "[0-9]+" AMD_MINOR ${AMD_MINOR_STR} ) - string ( REGEX MATCH "[0-9]+" AMD_PATCH ${AMD_PATCH_STR} ) - set (AMD_VERSION "${AMD_MAJOR}.${AMD_MINOR}.${AMD_PATCH}") -endif ( ) - -set ( AMD_LIBRARIES ${AMD_LIBRARY} ) - -include (FindPackageHandleStandardArgs) - -find_package_handle_standard_args ( AMD - REQUIRED_VARS AMD_LIBRARY AMD_INCLUDE_DIR - VERSION_VAR AMD_VERSION -) - -mark_as_advanced ( - AMD_INCLUDE_DIR - AMD_LIBRARY - AMD_STATIC - AMD_LIBRARIES -) - -if ( AMD_FOUND ) - message ( STATUS "AMD version: ${AMD_VERSION}" ) - message ( STATUS "AMD include: ${AMD_INCLUDE_DIR}") - message ( STATUS "AMD library: ${AMD_LIBRARY}") - message ( STATUS "AMD static: ${AMD_STATIC}") -else ( ) - message ( STATUS "AMD not found" ) - set ( AMD_INCLUDE_DIR "" ) - set ( AMD_LIBRARIES "" ) - set ( AMD_LIBRARY "" ) - set ( AMD_STATIC "" ) -endif ( ) - diff --git a/CITATION.bib b/CITATION.bib new file mode 100644 index 00000000..54df4255 --- /dev/null +++ b/CITATION.bib @@ -0,0 +1,91 @@ + +@article{10.1145/1024074.1024081, +author = {Amestoy, Patrick R. and Davis, Timothy A. and Duff, Iain S.}, +title = {Algorithm 837: AMD, an Approximate Minimum Degree Ordering Algorithm}, +year = {2004}, +issue_date = {September 2004}, +publisher = {Association for Computing Machinery}, +address = {New York, NY, USA}, +volume = {30}, +number = {3}, +issn = {0098-3500}, +url = {https://doi.org/10.1145/1024074.1024081}, +doi = {10.1145/1024074.1024081}, +abstract = {AMD is a set of routines that implements the approximate minimum degree ordering algorithm to permute sparse matrices prior to numerical factorization. There are versions written in both C and Fortran 77. A MATLAB interface is included.}, +journal = {ACM Trans. Math. Softw.}, +month = {sep}, +pages = {381–388}, +numpages = {8}, +keywords = {sparse matrices, Linear equations, ordering methods, minimum degree} +} + +@article{doi:10.1137/S0895479894278952, +author = {Amestoy, Patrick R. and Davis, Timothy A. and Duff, Iain S.}, +title = {An Approximate Minimum Degree Ordering Algorithm}, +journal = {SIAM Journal on Matrix Analysis and Applications}, +volume = {17}, +number = {4}, +pages = {886-905}, +year = {1996}, +doi = {10.1137/S0895479894278952}, +URL = { https://doi.org/10.1137/S0895479894278952 }, +eprint = { https://doi.org/10.1137/S0895479894278952 } , + abstract = { Abstract. An approximate minimum degree (AMD), ordering algorithm for preordering a symmetric sparse matrix prior to numerical factorization is presented. We use techniques based on the quotient graph for matrix factorization that allow us to obtain computationally cheap bounds for the minimum degree. We show that these bounds are often equal to the actual degree. The resulting algorithm is typically much faster than previous minimum degree ordering algorithms and produces results that are comparable in quality with the best orderings from other minimum degree algorithms. } +} + + +@article{10.1145/1024074.1024080, +author = {Davis, Timothy A. and Gilbert, John R. and Larimore, Stefan I. and Ng, Esmond G.}, +title = {Algorithm 836: COLAMD, a Column Approximate Minimum Degree Ordering Algorithm}, +year = {2004}, +issue_date = {September 2004}, +publisher = {Association for Computing Machinery}, +address = {New York, NY, USA}, +volume = {30}, +number = {3}, +issn = {0098-3500}, +url = {https://doi.org/10.1145/1024074.1024080}, +doi = {10.1145/1024074.1024080}, +abstract = {Two codes are discussed, COLAMD and SYMAMD, that compute approximate minimum degree orderings for sparse matrices in two contexts: (1) sparse partial pivoting, which requires a sparsity preserving column pre-ordering prior to numerical factorization, and (2) sparse Cholesky factorization, which requires a symmetric permutation of both the rows and columns of the matrix being factorized. These orderings are computed by COLAMD and SYMAMD, respectively. The ordering from COLAMD is also suitable for sparse QR factorization, and the factorization of matrices of the form ATA and AAT, such as those that arise in least-squares problems and interior point methods for linear programming problems. The two routines are available both in MATLAB and C-callable forms. They appear as built-in routines in MATLAB Version 6.0.}, +journal = {ACM Trans. Math. Softw.}, +month = {sep}, +pages = {377–380}, +numpages = {4}, +keywords = {sparse nonsymmetric matrices, ordering methods, Linear equations} +} + +@article{10.1145/1024074.1024079, +author = {Davis, Timothy A. and Gilbert, John R. and Larimore, Stefan I. and Ng, Esmond G.}, +title = {A Column Approximate Minimum Degree Ordering Algorithm}, +year = {2004}, +issue_date = {September 2004}, +publisher = {Association for Computing Machinery}, +address = {New York, NY, USA}, +volume = {30}, +number = {3}, +issn = {0098-3500}, +url = {https://doi.org/10.1145/1024074.1024079}, +doi = {10.1145/1024074.1024079}, +abstract = {Sparse Gaussian elimination with partial pivoting computes the factorization PAQ = LU of a sparse matrix A, where the row ordering P is selected during factorization using standard partial pivoting with row interchanges. The goal is to select a column preordering, Q, based solely on the nonzero pattern of A, that limits the worst-case number of nonzeros in the factorization. The fill-in also depends on P, but Q is selected to reduce an upper bound on the fill-in for any subsequent choice of P. The choice of Q can have a dramatic impact on the number of nonzeros in L and U. One scheme for determining a good column ordering for A is to compute a symmetric ordering that reduces fill-in in the Cholesky factorization of ATA. A conventional minimum degree ordering algorithm would require the sparsity structure of ATA to be computed, which can be expensive both in terms of space and time since ATA may be much denser than A. An alternative is to compute Q directly from the sparsity structure of A; this strategy is used by MATLAB's COLMMD preordering algorithm. A new ordering algorithm, COLAMD, is presented. It is based on the same strategy but uses a better ordering heuristic. COLAMD is faster and computes better orderings, with fewer nonzeros in the factors of the matrix.}, +journal = {ACM Trans. Math. Softw.}, +month = {sep}, +pages = {353–376}, +numpages = {24}, +keywords = {linear equations, Sparse nonsymmetric matrices, ordering methods} +} + +@article{10.1145/3519024, +author = {Lourenco, Christopher and Chen, Jinhao and Moreno-Centeno, Erick and Davis, Timothy A.}, +title = {Algorithm 1021: SPEX Left LU, Exactly Solving Sparse Linear Systems via a Sparse Left-Looking Integer-Preserving LU Factorization}, +year = {2022}, +publisher = {Association for Computing Machinery}, +address = {New York, NY, USA}, +issn = {0098-3500}, +url = {https://doi.org/10.1145/3519024}, +doi = {10.1145/3519024}, +abstract = {SPEX Left LU is a software package for exactly solving unsymmetric sparse linear systems. As a component of the sparse exact (SPEX) software package, SPEX Left LU can be applied to any input matrix, A, whose entries are integral, rational, or decimal, and provides a solution to the system Ax = b which is either exact or accurate to user-specified precision. SPEX Left LU preorders the matrix A with a user-specified fill-reducing ordering and computes a left-looking LU factorization with the special property that each operation used to compute the L and U matrices is integral. Notable additional applications of this package include benchmarking the stability and accuracy of state-of-the-art linear solvers, and determining whether singular-to-double-precision matrices are indeed singular. Computationally, this paper evaluates the impact of several novel pivoting schemes in exact arithmetic, benchmarks the exact iterative solvers within Linbox, and benchmarks the accuracy of MATLAB sparse backslash. Most importantly, it is shown that SPEX Left LU outperforms the exact iterative solvers in run time on easy instances and in stability as the iterative solver fails on a sizeable subset of the tested (both easy and hard) instances. The SPEX Left LU package is written in ANSI C, comes with a MATLAB interface, and is distributed via GitHub, as a component of the SPEX software package, and as a component of SuiteSparse.}, +journal = {ACM Trans. Math. Softw.}, +month = {jun}, +keywords = {exact matrix factorization, sparse linear systems, sparse matrix algorithms, exactly solving linear systems, roundoff errors} +} + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..018dffd0 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,218 @@ +#------------------------------------------------------------------------------- +# SPEX/CMakeLists.txt: root CMake build rules +#------------------------------------------------------------------------------- + +# Copyright (c) 2023-2024, Timothy A. Davis, All Rights Reserved. FIXME +# Just this particular file is under the Apache-2.0 license; each package has +# its own license. +# SPDX-License-Identifier: Apache-2.0 + +# This file and most packages in SuiteSparse require cmake 3.22 or later. + +cmake_minimum_required ( VERSION 3.22 ) + +project ( "SuiteSparse" ) + +#------------------------------------------------------------------------------- +# SuiteSparse policies +#------------------------------------------------------------------------------- + +set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} + ${PROJECT_SOURCE_DIR}/SuiteSparse_config/cmake_modules ) + +#------------------------------------------------------------------------------- +# build options +#------------------------------------------------------------------------------- + +# lower-case list of all projects that can be built by this root CMake file +set ( SUITESPARSE_ALL_PROJECTS + "suitesparse_config;amd;colamd;spex" ) + +# lower-case list of extra projects that can be built by this root CMake file +set ( SUITESPARSE_EXTRA_PROJECTS + "" ) + +# lower-case list of known projects that can be built by this root CMake file +set ( SUITESPARSE_KNOWN_PROJECTS "${SUITESPARSE_ALL_PROJECTS};${SUITESPARSE_EXTRA_PROJECTS}" ) + +set ( SUITESPARSE_ENABLE_PROJECTS "all" CACHE STRING + "Semicolon-separated list of SuiteSparse projects to be built (${SUITESPARSE_KNOWN_PROJECTS}, or \"all\")" ) + +# expand "all" early on +if ( "all" IN_LIST SUITESPARSE_ENABLE_PROJECTS ) + set ( SUITESPARSE_ENABLE_PROJECTS "${SUITESPARSE_ENABLE_PROJECTS};${SUITESPARSE_ALL_PROJECTS}" ) + list ( REMOVE_ITEM SUITESPARSE_ENABLE_PROJECTS "all" ) + list ( REMOVE_DUPLICATES SUITESPARSE_ENABLE_PROJECTS ) +endif ( ) + +# check for unknown projects in list +foreach ( proj ${SUITESPARSE_ENABLE_PROJECTS} ) + if ( NOT "${proj}" IN_LIST SUITESPARSE_KNOWN_PROJECTS ) + message ( FATAL_ERROR "${proj} is not a known project: ${SUITESPARSE_KNOWN_PROJECTS}." ) + endif ( ) +endforeach ( ) + +# options to build with libraries installed on the system instead of building +# dependencies automatically +option ( SUITESPARSE_USE_SYSTEM_AMD "ON: use AMD libraries installed on the build system. OFF (default): Automatically build AMD as dependency if needed." OFF ) +option ( SUITESPARSE_USE_SYSTEM_COLAMD "ON: use COLAMD libraries installed on the build system. OFF (default): Automatically build COLAMD as dependency if needed." OFF ) +option ( SUITESPARSE_USE_SYSTEM_SUITESPARSE_CONFIG "ON: use SuiteSparse_config libraries installed on the build system. OFF (default): Automatically build SuiteSparse_config as dependency if needed." OFF ) + +#------------------------------------------------------------------------------- +# global variables +#------------------------------------------------------------------------------- + +# Set to indicate that we are building from a root CMake file. +# That will change the directory layout and (imported) target names (namespace!) +# during the build process. +set ( SUITESPARSE_ROOT_CMAKELISTS ON ) + +#------------------------------------------------------------------------------- +# common SuiteSparse modules +#------------------------------------------------------------------------------- + +set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} + ${CMAKE_SOURCE_DIR}/SuiteSparse_config/cmake_modules ) + +include ( SuiteSparsePolicy ) + +#------------------------------------------------------------------------------- +# check/add project dependencies +#------------------------------------------------------------------------------- + +if ( SUITESPARSE_USE_SYSTEM_AMD ) + list ( REMOVE_ITEM SUITESPARSE_ENABLE_PROJECTS "amd" ) + find_package ( AMD 3.3.2 REQUIRED ) +else ( ) + if ( NOT "amd" IN_LIST SUITESPARSE_ENABLE_PROJECTS ) + message ( STATUS "Adding \"amd\" to the list of built targets." ) + list ( APPEND SUITESPARSE_ENABLE_PROJECTS "amd" ) + endif ( ) +endif ( ) + +if ( SUITESPARSE_USE_SYSTEM_COLAMD ) + list ( REMOVE_ITEM SUITESPARSE_ENABLE_PROJECTS "colamd" ) + find_package ( COLAMD 3.3.3 REQUIRED ) +else ( ) + if ( NOT "colamd" IN_LIST SUITESPARSE_ENABLE_PROJECTS ) + message ( STATUS "Adding \"colamd\" to the list of built targets." ) + list ( APPEND SUITESPARSE_ENABLE_PROJECTS "colamd" ) + endif ( ) +endif ( ) + +if ( SUITESPARSE_USE_SYSTEM_SUITESPARSE_CONFIG ) + list ( REMOVE_ITEM SUITESPARSE_ENABLE_PROJECTS "suitesparse_config" ) + find_package ( SuiteSparse_config 7.7.0 REQUIRED ) +else ( ) + if ( NOT "suitesparse_config" IN_LIST SUITESPARSE_ENABLE_PROJECTS ) + message ( STATUS "Adding \"suitesparse_config\" to the list of built targets." ) + list ( APPEND SUITESPARSE_ENABLE_PROJECTS "suitesparse_config" ) + endif ( ) +endif ( ) + +if ( CMAKE_VERSION VERSION_LESS 3.24 ) + # work around missing GLOBAL option of find_package in older CMake versions + # If SuiteSparse is included as a sub-project in other projects, they might + # need to manually import the OpenMP targets for older CMake versions, too. + find_package ( OpenMP COMPONENTS C ) +endif ( ) + + +#------------------------------------------------------------------------------- +# include selected projects +#------------------------------------------------------------------------------- + +if ( "suitesparse_config" IN_LIST SUITESPARSE_ENABLE_PROJECTS ) + add_subdirectory ( "SuiteSparse_config" ) + if ( TARGET SuiteSparseConfig ) + add_library ( SuiteSparse::SuiteSparseConfig ALIAS SuiteSparseConfig ) + else ( ) + add_library ( SuiteSparse::SuiteSparseConfig ALIAS SuiteSparseConfig_static ) + endif ( ) + if ( TARGET SuiteSparseConfig_static ) + add_library ( SuiteSparse::SuiteSparseConfig_static ALIAS SuiteSparseConfig_static ) + endif ( ) +endif ( ) + +if ( "amd" IN_LIST SUITESPARSE_ENABLE_PROJECTS ) + add_subdirectory ( "AMD" ) + if ( TARGET AMD ) + add_library ( SuiteSparse::AMD ALIAS AMD ) + else ( ) + add_library ( SuiteSparse::AMD ALIAS AMD_static ) + endif ( ) + if ( TARGET AMD_static ) + add_library ( SuiteSparse::AMD_static ALIAS AMD_static ) + endif ( ) +endif ( ) + +if ( "colamd" IN_LIST SUITESPARSE_ENABLE_PROJECTS ) + add_subdirectory ( "COLAMD" ) + if ( TARGET COLAMD ) + add_library ( SuiteSparse::COLAMD ALIAS COLAMD ) + else ( ) + add_library ( SuiteSparse::COLAMD ALIAS COLAMD_static ) + endif ( ) + if ( TARGET COLAMD_static ) + add_library ( SuiteSparse::COLAMD_static ALIAS COLAMD_static ) + endif ( ) +endif ( ) + +if ( "spex" IN_LIST SUITESPARSE_ENABLE_PROJECTS ) + add_subdirectory ( "SPEX" ) + if ( TARGET SPEX ) + add_library ( SuiteSparse::SPEX ALIAS SPEX ) + else ( ) + add_library ( SuiteSparse::SPEX ALIAS SPEX_static ) + endif ( ) + if ( TARGET SPEX_static ) + add_library ( SuiteSparse::SPEX_static ALIAS SPEX_static ) + endif ( ) +endif ( ) + +#------------------------------------------------------------------------------- +# report status +#------------------------------------------------------------------------------- + +include ( SuiteSparseReport ) + +#------------------------------------------------------------------------------- +# enable testing facilities +#------------------------------------------------------------------------------- + +# Currently, only LAGraph, Mongoose, and CHOLMOD have ctests. + +# FIXME: convert more of the existing demos to ctests. + +# Most packages have a ./Tcov folder with a full statement coverage test, +# but these are not imported into cmake yet. + +# Most packages also have a ./Demo folder, with shorter examples. These would +# be nice to add as quick ctests. + +# CHOLMOD/Tcov takes about 20 minutes to run. It is also a full coverage +# test of AMD, CAMD, COLAMD, and CCOLAMD, however. The current CHOLMOD +# ctest is based on a few ./Demo programs. It's fast but not a full coverate +# test. + +# The CSparse/CXSparse Tcov tests are very fast and would be good candidates to +# add. + +include ( CTest ) + +#------------------------------------------------------------------------------- +# rule to remove all files in build directory +#------------------------------------------------------------------------------- + +file ( GLOB SUITESPARSE_BUILT_FILES ${PROJECT_BINARY_DIR}/* ) +file ( REAL_PATH ${PROJECT_SOURCE_DIR} _real_project_source_dir ) +file ( REAL_PATH ${PROJECT_BINARY_DIR} _real_project_binary_dir ) +if ( _real_project_source_dir STREQUAL _real_project_binary_dir ) + add_custom_target ( purge + COMMENT "The target 'purge' is a no-op for in-tree builds. Consider building out of the source tree." ) +else ( ) + add_custom_target ( purge + COMMAND ${CMAKE_COMMAND} -E echo "Removing files..." + COMMAND ${CMAKE_COMMAND} -E rm -rf ${SUITESPARSE_BUILT_FILES} + COMMENT "Purge all files in the build tree" ) +endif ( ) diff --git a/COLAMD/CMakeLists.txt b/COLAMD/CMakeLists.txt index 0f9603c9..4d4b17cf 100644 --- a/COLAMD/CMakeLists.txt +++ b/COLAMD/CMakeLists.txt @@ -2,19 +2,19 @@ # SuiteSparse/COLAMD/CMakeLists.txt: cmake for COLAMD #------------------------------------------------------------------------------- -# Copyright (c) 1998-2023, Timothy A. Davis. All Rights Reserved. +# Copyright (c) 1998-2024, Timothy A. Davis. All Rights Reserved. # SPDX-License-Identifier: BSD-3-clause #------------------------------------------------------------------------------- # get the version #------------------------------------------------------------------------------- -cmake_minimum_required ( VERSION 3.19 ) +cmake_minimum_required ( VERSION 3.22 ) -set ( COLAMD_DATE "Jan 17, 2023" ) -set ( COLAMD_VERSION_MAJOR 3 ) -set ( COLAMD_VERSION_MINOR 0 ) -set ( COLAMD_VERSION_SUB 3 ) +set ( COLAMD_DATE "Mar 22, 2024" ) +set ( COLAMD_VERSION_MAJOR 3 CACHE STRING "" FORCE ) +set ( COLAMD_VERSION_MINOR 3 CACHE STRING "" FORCE ) +set ( COLAMD_VERSION_SUB 3 CACHE STRING "" FORCE ) message ( STATUS "Building COLAMD version: v" ${COLAMD_VERSION_MAJOR}. @@ -22,28 +22,33 @@ message ( STATUS "Building COLAMD version: v" ${COLAMD_VERSION_SUB} " (" ${COLAMD_DATE} ")" ) #------------------------------------------------------------------------------- -# SuiteSparse policies +# define the project #------------------------------------------------------------------------------- -set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} - ${CMAKE_SOURCE_DIR}/cmake_modules - ${CMAKE_SOURCE_DIR}/../SuiteSparse_config/cmake_modules ) - -include ( SuiteSparsePolicy ) +project ( COLAMD + VERSION "${COLAMD_VERSION_MAJOR}.${COLAMD_VERSION_MINOR}.${COLAMD_VERSION_SUB}" + LANGUAGES C ) #------------------------------------------------------------------------------- -# define the project +# SuiteSparse policies #------------------------------------------------------------------------------- -project ( colamd - VERSION "${COLAMD_VERSION_MAJOR}.${COLAMD_VERSION_MINOR}.${COLAMD_VERSION_SUB}" - LANGUAGES C ) +set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} + ${PROJECT_SOURCE_DIR}/../SuiteSparse_config/cmake_modules ) + +include ( SuiteSparsePolicy ) #------------------------------------------------------------------------------- # find library dependencies #------------------------------------------------------------------------------- -find_package ( SuiteSparse_config 7.0.0 REQUIRED ) +if ( NOT SUITESPARSE_ROOT_CMAKELISTS ) + find_package ( SuiteSparse_config 7.7.0 + PATHS ${CMAKE_SOURCE_DIR}/../SuiteSparse_config/build NO_DEFAULT_PATH ) + if ( NOT TARGET SuiteSparse::SuiteSparseConfig ) + find_package ( SuiteSparse_config 7.7.0 REQUIRED ) + endif ( ) +endif ( ) #------------------------------------------------------------------------------- # configure files @@ -57,7 +62,7 @@ configure_file ( "Config/colamd.h.in" # include directories #------------------------------------------------------------------------------- -include_directories ( Source Include ${SUITESPARSE_CONFIG_INCLUDE_DIR} ) +include_directories ( Source Include ) #------------------------------------------------------------------------------- # dynamic colamd library properties @@ -65,48 +70,79 @@ include_directories ( Source Include ${SUITESPARSE_CONFIG_INCLUDE_DIR} ) file ( GLOB COLAMD_SOURCES "Source/*.c" ) -add_library ( colamd SHARED ${COLAMD_SOURCES} ) +if ( BUILD_SHARED_LIBS ) + add_library ( COLAMD SHARED ${COLAMD_SOURCES} ) + + set_target_properties ( COLAMD PROPERTIES + VERSION ${COLAMD_VERSION_MAJOR}.${COLAMD_VERSION_MINOR}.${COLAMD_VERSION_SUB} + C_STANDARD 11 + C_STANDARD_REQUIRED ON + OUTPUT_NAME colamd + SOVERSION ${COLAMD_VERSION_MAJOR} + PUBLIC_HEADER "Include/colamd.h" + WINDOWS_EXPORT_ALL_SYMBOLS ON ) + + if ( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.25" ) + set_target_properties ( COLAMD PROPERTIES EXPORT_NO_SYSTEM ON ) + endif ( ) -set_target_properties ( colamd PROPERTIES - VERSION ${COLAMD_VERSION_MAJOR}.${COLAMD_VERSION_MINOR}.${COLAMD_VERSION_SUB} - C_STANDARD_REQUIRED 11 - SOVERSION ${COLAMD_VERSION_MAJOR} - PUBLIC_HEADER "Include/colamd.h" - WINDOWS_EXPORT_ALL_SYMBOLS ON ) + target_include_directories ( COLAMD + INTERFACE $ + $ ) +endif ( ) #------------------------------------------------------------------------------- # static colamd library properties #------------------------------------------------------------------------------- -if ( NOT NSTATIC ) - add_library ( colamd_static STATIC ${COLAMD_SOURCES} ) +if ( BUILD_STATIC_LIBS ) + add_library ( COLAMD_static STATIC ${COLAMD_SOURCES} ) - set_target_properties ( colamd_static PROPERTIES - VERSION ${COLAMD_VERSION_MAJOR}.${COLAMD_VERSION_MINOR}.${COLAMD_VERSION_SUB} + set_target_properties ( COLAMD_static PROPERTIES OUTPUT_NAME colamd - C_STANDARD_REQUIRED 11 - SOVERSION ${COLAMD_VERSION_MAJOR} ) + C_STANDARD 11 + C_STANDARD_REQUIRED ON + PUBLIC_HEADER "Include/colamd.h" ) - if ( MSVC ) - set_target_properties ( colamd_static PROPERTIES + if ( MSVC OR ("${CMAKE_C_SIMULATE_ID}" STREQUAL "MSVC") ) + set_target_properties ( COLAMD_static PROPERTIES OUTPUT_NAME colamd_static ) endif ( ) + + if ( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.25" ) + set_target_properties ( COLAMD_static PROPERTIES EXPORT_NO_SYSTEM ON ) + endif ( ) + + target_include_directories ( COLAMD_static + INTERFACE $ + $ ) endif ( ) #------------------------------------------------------------------------------- # add the library dependencies #------------------------------------------------------------------------------- -target_link_libraries ( colamd PUBLIC ${SUITESPARSE_CONFIG_LIBRARY} ) -if ( NOT NSTATIC ) - target_link_libraries ( colamd_static PUBLIC ${SUITESPARSE_CONFIG_STATIC} ) +if ( BUILD_SHARED_LIBS ) + target_link_libraries ( COLAMD PRIVATE SuiteSparse::SuiteSparseConfig ) + target_include_directories ( COLAMD PUBLIC + "$" ) +endif ( ) +if ( BUILD_STATIC_LIBS ) + if ( TARGET SuiteSparse::SuiteSparseConfig_static ) + target_link_libraries ( COLAMD_static PUBLIC SuiteSparse::SuiteSparseConfig_static ) + else ( ) + target_link_libraries ( COLAMD_static PUBLIC SuiteSparse::SuiteSparseConfig ) + endif ( ) endif ( ) # libm: if ( NOT WIN32 ) - target_link_libraries ( colamd PUBLIC m ) - if ( NOT NSTATIC ) - target_link_libraries ( colamd_static PUBLIC m ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries ( COLAMD PRIVATE m ) + endif ( ) + if ( BUILD_STATIC_LIBS ) + set ( COLAMD_STATIC_LIBS "${COLAMD_STATIC_LIBS} -lm" ) + target_link_libraries ( COLAMD_static PUBLIC m ) endif ( ) endif ( ) @@ -114,25 +150,99 @@ endif ( ) # COLAMD installation location #------------------------------------------------------------------------------- -install ( TARGETS colamd - LIBRARY DESTINATION ${SUITESPARSE_LIBDIR} - ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} - RUNTIME DESTINATION ${SUITESPARSE_BINDIR} - PUBLIC_HEADER DESTINATION ${SUITESPARSE_INCLUDEDIR} ) -install ( FILES ${CMAKE_SOURCE_DIR}/cmake_modules/FindCOLAMD.cmake - DESTINATION ${SUITESPARSE_LIBDIR}/cmake/SuiteSparse - COMPONENT Development ) -if ( NOT NSTATIC ) - install ( TARGETS colamd_static - ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} ) +include ( CMakePackageConfigHelpers ) + +if ( BUILD_SHARED_LIBS ) + install ( TARGETS COLAMD + EXPORT COLAMDTargets + LIBRARY DESTINATION ${SUITESPARSE_LIBDIR} + ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} + RUNTIME DESTINATION ${SUITESPARSE_BINDIR} + PUBLIC_HEADER DESTINATION ${SUITESPARSE_INCLUDEDIR} ) +endif ( ) +if ( BUILD_STATIC_LIBS ) + install ( TARGETS COLAMD_static + EXPORT COLAMDTargets + ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} + PUBLIC_HEADER DESTINATION ${SUITESPARSE_INCLUDEDIR} ) +endif ( ) + +# create (temporary) export target file during build +export ( EXPORT COLAMDTargets + NAMESPACE SuiteSparse:: + FILE ${CMAKE_CURRENT_BINARY_DIR}/COLAMDTargets.cmake ) + +# install export target, config and version files for find_package +install ( EXPORT COLAMDTargets + NAMESPACE SuiteSparse:: + DESTINATION ${SUITESPARSE_PKGFILEDIR}/cmake/COLAMD ) + +# generate config file to be used in common build tree +set ( SUITESPARSE_IN_BUILD_TREE ON ) +configure_package_config_file ( + Config/COLAMDConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/COLAMDConfig.cmake + INSTALL_DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/COLAMDConfig.cmake ) + +# generate config file to be installed +set ( SUITESPARSE_IN_BUILD_TREE OFF ) +configure_package_config_file ( + Config/COLAMDConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/target/COLAMDConfig.cmake + INSTALL_DESTINATION ${SUITESPARSE_PKGFILEDIR}/cmake/COLAMD ) + +write_basic_package_version_file ( + ${CMAKE_CURRENT_BINARY_DIR}/COLAMDConfigVersion.cmake + COMPATIBILITY SameMajorVersion ) + +install ( FILES + ${CMAKE_CURRENT_BINARY_DIR}/target/COLAMDConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/COLAMDConfigVersion.cmake + DESTINATION ${SUITESPARSE_PKGFILEDIR}/cmake/COLAMD ) + +#------------------------------------------------------------------------------- +# create pkg-config file +#------------------------------------------------------------------------------- + +if ( NOT MSVC ) + 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/COLAMD.pc.in + COLAMD.pc.out + @ONLY + NEWLINE_STYLE LF ) + file ( GENERATE + OUTPUT COLAMD.pc + INPUT ${CMAKE_CURRENT_BINARY_DIR}/COLAMD.pc.out + NEWLINE_STYLE LF ) + install ( FILES + ${CMAKE_CURRENT_BINARY_DIR}/COLAMD.pc + DESTINATION ${SUITESPARSE_PKGFILEDIR}/pkgconfig ) endif ( ) #------------------------------------------------------------------------------- # Demo library and programs #------------------------------------------------------------------------------- -option ( DEMO "ON: Build the demo programs. OFF (default): do not build the demo programs." off ) -if ( DEMO ) +if ( SUITESPARSE_DEMOS ) #--------------------------------------------------------------------------- # demo library @@ -148,8 +258,13 @@ if ( DEMO ) add_executable ( colamd_l_example "Demo/colamd_l_example.c" ) # Libraries required for Demo programs - target_link_libraries ( colamd_example PUBLIC colamd ) - target_link_libraries ( colamd_l_example PUBLIC colamd ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries ( colamd_example PUBLIC COLAMD ) + target_link_libraries ( colamd_l_example PUBLIC COLAMD ) + else ( ) + target_link_libraries ( colamd_example PUBLIC COLAMD_static ) + target_link_libraries ( colamd_l_example PUBLIC COLAMD_static ) + endif ( ) else ( ) @@ -162,4 +277,3 @@ endif ( ) #------------------------------------------------------------------------------- include ( SuiteSparseReport ) - diff --git a/COLAMD/Config/COLAMD.pc.in b/COLAMD/Config/COLAMD.pc.in new file mode 100644 index 00000000..5444c608 --- /dev/null +++ b/COLAMD/Config/COLAMD.pc.in @@ -0,0 +1,17 @@ +# COLAMD, Copyright (c) 1998-2023, Timothy A. Davis. +# All Rights Reserved. +# SPDX-License-Identifier: BSD-3-Clause + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: COLAMD +URL: https://github.com/DrTimothyAldenDavis/SuiteSparse +Description: Routines for column approximate minimum degree ordering algorithm in SuiteSparse +Version: @COLAMD_VERSION_MAJOR@.@COLAMD_VERSION_MINOR@.@COLAMD_VERSION_SUB@ +Requires.private: SuiteSparse_config +Libs: -L${libdir} -l@SUITESPARSE_LIB_BASE_NAME@ +Libs.private: @COLAMD_STATIC_LIBS@ +Cflags: -I${includedir} diff --git a/COLAMD/Config/COLAMDConfig.cmake.in b/COLAMD/Config/COLAMDConfig.cmake.in new file mode 100644 index 00000000..7bb4701f --- /dev/null +++ b/COLAMD/Config/COLAMDConfig.cmake.in @@ -0,0 +1,152 @@ +#------------------------------------------------------------------------------- +# SuiteSparse/COLAMD/cmake_modules/COLAMDConfig.cmake +#------------------------------------------------------------------------------- + +# The following copyright and license applies to just this file only, not to +# the library itself: +# COLAMDConfig.cmake, Copyright (c) 2023, Timothy A. Davis. All Rights Reserved. +# SPDX-License-Identifier: BSD-3-clause + +#------------------------------------------------------------------------------- + +# Finds the COLAMD include file and compiled library. +# The following targets are defined: +# SuiteSparse::COLAMD - for the shared library (if available) +# SuiteSparse::COLAMD_static - for the static library (if available) + +# For backward compatibility the following variables are set: + +# COLAMD_INCLUDE_DIR - where to find colamd.h +# COLAMD_LIBRARY - dynamic COLAMD library +# COLAMD_STATIC - static COLAMD library +# COLAMD_LIBRARIES - libraries when using COLAMD +# COLAMD_FOUND - true if COLAMD found + +# Set ``CMAKE_MODULE_PATH`` to the parent folder where this module file is +# installed. + +#------------------------------------------------------------------------------- + +@PACKAGE_INIT@ + +set ( COLAMD_DATE "@COLAMD_DATE@" ) +set ( COLAMD_VERSION_MAJOR @COLAMD_VERSION_MAJOR@ ) +set ( COLAMD_VERSION_MINOR @COLAMD_VERSION_MINOR@ ) +set ( COLAMD_VERSION_PATCH @COLAMD_VERSION_SUB@ ) +set ( COLAMD_VERSION "@COLAMD_VERSION_MAJOR@.@COLAMD_VERSION_MINOR@.@COLAMD_VERSION_SUB@" ) + +# Check for dependent targets +include ( CMakeFindDependencyMacro ) + +# Look for SuiteSparse_config target +if ( @SUITESPARSE_IN_BUILD_TREE@ ) + if ( NOT TARGET SuiteSparse::SuiteSparseConfig ) + # First check in a common build tree + find_dependency ( SuiteSparse_config @SUITESPARSE_CONFIG_VERSION_MAJOR@.@SUITESPARSE_CONFIG_VERSION_MINOR@ + PATHS ${CMAKE_SOURCE_DIR}/../SuiteSparse_config/build NO_DEFAULT_PATH ) + # Then, check in the currently active CMAKE_MODULE_PATH + if ( NOT SuiteSparse_config_FOUND ) + find_dependency ( SuiteSparse_config @SUITESPARSE_CONFIG_VERSION_MAJOR@.@SUITESPARSE_CONFIG_VERSION_MINOR@ ) + endif ( ) + endif ( ) +else ( ) + if ( NOT TARGET SuiteSparse::SuiteSparseConfig ) + find_dependency ( SuiteSparse_config @SUITESPARSE_CONFIG_VERSION_MAJOR@.@SUITESPARSE_CONFIG_VERSION_MINOR@ ) + endif ( ) +endif ( ) +if ( NOT SuiteSparse_config_FOUND ) + set ( COLAMD_FOUND OFF ) + return ( ) +endif ( ) + + +# Import target +include ( ${CMAKE_CURRENT_LIST_DIR}/COLAMDTargets.cmake ) + +# The following is only for backward compatibility with FindCOLAMD. + +set ( _target_shared SuiteSparse::COLAMD ) +set ( _target_static SuiteSparse::COLAMD_static ) +set ( _var_prefix "COLAMD" ) + +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 ( ) + +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 ( COLAMD_LIBRARIES ${COLAMD_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 ( COLAMD_INCLUDE_DIR ${COLAMD_INCLUDE_DIR} ) +suitesparse_check_exist ( COLAMD_LIBRARY ${COLAMD_LIBRARY} ) + +message ( STATUS "COLAMD version: ${COLAMD_VERSION}" ) +message ( STATUS "COLAMD include: ${COLAMD_INCLUDE_DIR}" ) +message ( STATUS "COLAMD library: ${COLAMD_LIBRARY}" ) +message ( STATUS "COLAMD static: ${COLAMD_STATIC}" ) diff --git a/COLAMD/Config/colamd.h.in b/COLAMD/Config/colamd.h.in index fb0450ac..915f81c5 100644 --- a/COLAMD/Config/colamd.h.in +++ b/COLAMD/Config/colamd.h.in @@ -1,8 +1,8 @@ //------------------------------------------------------------------------------ -// COLAMD/Source/colamd.h: include file for COLAMD +// COLAMD/Include/colamd.h: include file for COLAMD //------------------------------------------------------------------------------ -// COLAMD, Copyright (c) 1998-2022, Timothy A. Davis and Stefan Larimore, +// COLAMD, Copyright (c) 1998-2024, Timothy A. Davis and Stefan Larimore, // All Rights Reserved. // SPDX-License-Identifier: BSD-3-clause @@ -37,11 +37,6 @@ #ifndef COLAMD_H #define COLAMD_H -/* make it easy for C++ programs to include COLAMD */ -#ifdef __cplusplus -extern "C" { -#endif - /* ========================================================================== */ /* === Include files ======================================================== */ /* ========================================================================== */ @@ -75,9 +70,14 @@ extern "C" { #define COLAMD_SUB_VERSION @COLAMD_VERSION_MINOR@ #define COLAMD_SUBSUB_VERSION @COLAMD_VERSION_SUB@ -#define COLAMD_VERSION_CODE(main,sub) ((main) * 1000 + (sub)) -#define COLAMD_VERSION \ - COLAMD_VERSION_CODE(COLAMD_MAIN_VERSION,COLAMD_SUB_VERSION) +#define COLAMD_VERSION_CODE(main,sub) SUITESPARSE_VER_CODE(main,sub) +#define COLAMD_VERSION COLAMD_VERSION_CODE(@COLAMD_VERSION_MAJOR@,@COLAMD_VERSION_MINOR@) + +#define COLAMD__VERSION SUITESPARSE__VERCODE(@COLAMD_VERSION_MAJOR@,@COLAMD_VERSION_MINOR@,@COLAMD_VERSION_SUB@) +#if !defined (SUITESPARSE__VERSION) || \ + (SUITESPARSE__VERSION < SUITESPARSE__VERCODE(7,7,0)) +#error "COLAMD @COLAMD_VERSION_MAJOR@.@COLAMD_VERSION_MINOR@.@COLAMD_VERSION_SUB@ requires SuiteSparse_config 7.7.0 or later" +#endif /* ========================================================================== */ /* === Knob and statistics definitions ====================================== */ @@ -129,6 +129,11 @@ extern "C" { /* === Prototypes of user-callable routines ================================= */ /* ========================================================================== */ +/* make it easy for C++ programs to include COLAMD */ +#ifdef __cplusplus +extern "C" { +#endif + size_t colamd_recommended /* returns recommended value of Alen, */ /* or 0 if input arguments are erroneous */ ( @@ -229,6 +234,8 @@ void symamd_l_report int64_t stats [COLAMD_STATS] ) ; +void colamd_version (int version [3]) ; + #ifdef __cplusplus } #endif diff --git a/COLAMD/Demo/colamd_example.c b/COLAMD/Demo/colamd_example.c index e478f7d2..b64ca33e 100644 --- a/COLAMD/Demo/colamd_example.c +++ b/COLAMD/Demo/colamd_example.c @@ -98,6 +98,21 @@ int main (void) int row, col, pp, length, ok ; + //-------------------------------------------------------------------------- + // colamd version + //-------------------------------------------------------------------------- + + int version [3] ; + colamd_version (version) ; + printf ("COLAMD v%d.%d.%d\n", version [0], version [1], version [2]) ; + if ((version [0] != COLAMD_MAIN_VERSION) || + (version [1] != COLAMD_SUB_VERSION) || + (version [2] != COLAMD_SUBSUB_VERSION)) + { + fprintf (stderr, "version in header does not match library\n") ; + abort ( ) ; + } + /* ====================================================================== */ /* dump the input matrix A */ /* ====================================================================== */ diff --git a/COLAMD/Demo/colamd_example.out b/COLAMD/Demo/colamd_example.out index 56be3fb0..1b6c81fc 100644 --- a/COLAMD/Demo/colamd_example.out +++ b/COLAMD/Demo/colamd_example.out @@ -1,3 +1,4 @@ +COLAMD v3.3.3 colamd 5-by-4 input matrix: Column 0, with 3 entries: row 0 @@ -15,7 +16,7 @@ Column 3, with 2 entries: row 1 row 3 -colamd version 3.0.3, Jan 17, 2023: OK. +colamd version 3.3.3, Mar 22, 2024: OK. colamd: number of dense or empty rows ignored: 0 colamd: number of dense or empty columns ignored: 0 colamd: number of garbage collections performed: 0 @@ -38,7 +39,7 @@ Column 3, with 1 entries: row 4 Column 4, with 0 entries: -symamd version 3.0.3, Jan 17, 2023: OK. +symamd version 3.3.3, Mar 22, 2024: OK. symamd: number of dense or empty rows ignored: 0 symamd: number of dense or empty columns ignored: 0 symamd: number of garbage collections performed: 0 diff --git a/COLAMD/Demo/colamd_l_example.c b/COLAMD/Demo/colamd_l_example.c index b48a55bf..3bf4c18c 100644 --- a/COLAMD/Demo/colamd_l_example.c +++ b/COLAMD/Demo/colamd_l_example.c @@ -99,6 +99,21 @@ int main (void) int64_t row, col, pp, length ; int ok ; + //-------------------------------------------------------------------------- + // colamd version + //-------------------------------------------------------------------------- + + int version [3] ; + colamd_version (version) ; + printf ("COLAMD v%d.%d.%d\n", version [0], version [1], version [2]) ; + if ((version [0] != COLAMD_MAIN_VERSION) || + (version [1] != COLAMD_SUB_VERSION) || + (version [2] != COLAMD_SUBSUB_VERSION)) + { + fprintf (stderr, "version in header does not match library\n") ; + abort ( ) ; + } + /* ====================================================================== */ /* dump the input matrix A */ /* ====================================================================== */ diff --git a/COLAMD/Demo/colamd_l_example.out b/COLAMD/Demo/colamd_l_example.out index c75474b9..104688ee 100644 --- a/COLAMD/Demo/colamd_l_example.out +++ b/COLAMD/Demo/colamd_l_example.out @@ -1,3 +1,4 @@ +COLAMD v3.3.3 colamd 5-by-4 input matrix: Column 0, with 3 entries: row 0 @@ -15,7 +16,7 @@ Column 3, with 2 entries: row 1 row 3 -colamd version 3.0.3, Jan 17, 2023: OK. +colamd version 3.3.3, Mar 22, 2024: OK. colamd: number of dense or empty rows ignored: 0 colamd: number of dense or empty columns ignored: 0 colamd: number of garbage collections performed: 0 @@ -38,7 +39,7 @@ Column 3, with 1 entries: row 4 Column 4, with 0 entries: -symamd version 3.0.3, Jan 17, 2023: OK. +symamd version 3.3.3, Mar 22, 2024: OK. symamd: number of dense or empty rows ignored: 0 symamd: number of dense or empty columns ignored: 0 symamd: number of garbage collections performed: 0 diff --git a/COLAMD/Doc/ChangeLog b/COLAMD/Doc/ChangeLog index f7a3dcf3..b9e700d9 100644 --- a/COLAMD/Doc/ChangeLog +++ b/COLAMD/Doc/ChangeLog @@ -1,3 +1,32 @@ +Mar 22, 2024: version 3.3.3 + + * minor updates to build system + +Jan 20, 2024: version 3.3.2 + + * minor updates to build system + +Jan 10, 2024: version 3.3.1 + + * minor updates to build system + +Dec 30, 2023: version 3.3.0 + + * major change to build system: by Markus Mützel + * colamd_version: added to return version of COLAMD + +Sept 18, 2023: version 3.2.1 + + * cmake update: add "None" build type, from Antonio Rojas, for Arch Linux + +Sept 8, 2023: version 3.2.0 + + * cmake updates: SuiteSparse:: namespace by Markus Muetzel + +June 16, 2023: version 3.0.4 + + * cmake build system updates: update by Markus Muetzel + Jan 17, 2023: version 3.0.3 * SuiteSparse_config: now v7.0.0 diff --git a/COLAMD/Include/colamd.h b/COLAMD/Include/colamd.h index f258ef68..7b2e77f1 100644 --- a/COLAMD/Include/colamd.h +++ b/COLAMD/Include/colamd.h @@ -1,8 +1,8 @@ //------------------------------------------------------------------------------ -// COLAMD/Source/colamd.h: include file for COLAMD +// COLAMD/Include/colamd.h: include file for COLAMD //------------------------------------------------------------------------------ -// COLAMD, Copyright (c) 1998-2022, Timothy A. Davis and Stefan Larimore, +// COLAMD, Copyright (c) 1998-2024, Timothy A. Davis and Stefan Larimore, // All Rights Reserved. // SPDX-License-Identifier: BSD-3-clause @@ -37,11 +37,6 @@ #ifndef COLAMD_H #define COLAMD_H -/* make it easy for C++ programs to include COLAMD */ -#ifdef __cplusplus -extern "C" { -#endif - /* ========================================================================== */ /* === Include files ======================================================== */ /* ========================================================================== */ @@ -70,14 +65,19 @@ extern "C" { * Versions 2.3 and earlier of COLAMD do not include a #define'd version number. */ -#define COLAMD_DATE "Jan 17, 2023" +#define COLAMD_DATE "Mar 22, 2024" #define COLAMD_MAIN_VERSION 3 -#define COLAMD_SUB_VERSION 0 +#define COLAMD_SUB_VERSION 3 #define COLAMD_SUBSUB_VERSION 3 -#define COLAMD_VERSION_CODE(main,sub) ((main) * 1000 + (sub)) -#define COLAMD_VERSION \ - COLAMD_VERSION_CODE(COLAMD_MAIN_VERSION,COLAMD_SUB_VERSION) +#define COLAMD_VERSION_CODE(main,sub) SUITESPARSE_VER_CODE(main,sub) +#define COLAMD_VERSION COLAMD_VERSION_CODE(3,3) + +#define COLAMD__VERSION SUITESPARSE__VERCODE(3,3,3) +#if !defined (SUITESPARSE__VERSION) || \ + (SUITESPARSE__VERSION < SUITESPARSE__VERCODE(7,7,0)) +#error "COLAMD 3.3.3 requires SuiteSparse_config 7.7.0 or later" +#endif /* ========================================================================== */ /* === Knob and statistics definitions ====================================== */ @@ -129,6 +129,11 @@ extern "C" { /* === Prototypes of user-callable routines ================================= */ /* ========================================================================== */ +/* make it easy for C++ programs to include COLAMD */ +#ifdef __cplusplus +extern "C" { +#endif + size_t colamd_recommended /* returns recommended value of Alen, */ /* or 0 if input arguments are erroneous */ ( @@ -229,6 +234,8 @@ void symamd_l_report int64_t stats [COLAMD_STATS] ) ; +void colamd_version (int version [3]) ; + #ifdef __cplusplus } #endif diff --git a/COLAMD/Makefile b/COLAMD/Makefile index 2c7de9ee..787ee26f 100644 --- a/COLAMD/Makefile +++ b/COLAMD/Makefile @@ -36,27 +36,27 @@ default: library # default is to install only in /usr/local library: - ( cd build && cmake $(CMAKE_OPTIONS) .. && cmake --build . -j${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) -DLOCAL_INSTALL=1 .. && cmake --build . -j${JOBS} ) + ( cd build && cmake $(CMAKE_OPTIONS) -USUITESPARSE_PKGFILEDIR -DSUITESPARSE_LOCAL_INSTALL=1 .. && cmake --build . --config Release -j${JOBS} ) # install only in /usr/local (default) global: - ( cd build && cmake $(CMAKE_OPTIONS) -DLOCAL_INSTALL=0 .. && cmake --build . -j${JOBS} ) + ( cd build && cmake $(CMAKE_OPTIONS) -USUITESPARSE_PKGFILEDIR -DSUITESPARSE_LOCAL_INSTALL=0 .. && cmake --build . --config Release -j${JOBS} ) debug: - ( cd build && cmake $(CMAKE_OPTIONS) -DCMAKE_BUILD_TYPE=Debug .. && cmake --build . -j${JOBS} ) + ( cd build && cmake $(CMAKE_OPTIONS) -DCMAKE_BUILD_TYPE=Debug .. && cmake --build . --config Debug -j${JOBS} ) all: library demos: library - ( cd build && cmake $(CMAKE_OPTIONS) -DDEMO=1 .. && cmake --build . -j${JOBS} ) - - ./build/colamd_example > ./build/colamd_example.out - - diff --strip-trailing-cr ./Demo/colamd_example.out ./build/colamd_example.out - - ./build/colamd_l_example > ./build/colamd_l_example.out - - diff --strip-trailing-cr ./Demo/colamd_l_example.out ./build/colamd_l_example.out + ( cd build && cmake $(CMAKE_OPTIONS) -DSUITESPARSE_DEMOS=1 .. && cmake --build . --config Release -j${JOBS} ) + - ./build/colamd_example > ./build/colamd_example.out && ( command -v d2u && d2u ./build/colamd_example.out || true ) + - diff ./Demo/colamd_example.out ./build/colamd_example.out + - ./build/colamd_l_example > ./build/colamd_l_example.out && ( command -v d2u && d2u ./build/colamd_l_example.out || true ) + - diff ./Demo/colamd_l_example.out ./build/colamd_l_example.out # just compile after running cmake; do not run cmake again remake: @@ -64,7 +64,7 @@ remake: # just run cmake to set things up setup: - ( cd build ; cmake $(CMAKE_OPTIONS) .. ) + ( cd build && cmake $(CMAKE_OPTIONS) .. ) install: ( cd build && cmake --install . ) diff --git a/COLAMD/Source/colamd.c b/COLAMD/Source/colamd.c index af5b27f7..968d90fc 100644 --- a/COLAMD/Source/colamd.c +++ b/COLAMD/Source/colamd.c @@ -1046,7 +1046,6 @@ size_t COLAMD_recommended /* returns recommended value of Alen. */ return (ok ? s : 0) ; } - /* ========================================================================== */ /* === colamd_set_defaults ================================================== */ /* ========================================================================== */ diff --git a/COLAMD/Source/colamd_version.c b/COLAMD/Source/colamd_version.c new file mode 100644 index 00000000..9184817e --- /dev/null +++ b/COLAMD/Source/colamd_version.c @@ -0,0 +1,19 @@ +//------------------------------------------------------------------------------ +// COLAMD/Source/colamd_version.c: return COLAMD version +//------------------------------------------------------------------------------ + +// COLAMD, Copyright (c) 1998-2022, Timothy A. Davis and Stefan Larimore, +// All Rights Reserved. +// SPDX-License-Identifier: BSD-3-clause + +//------------------------------------------------------------------------------ + +#include "colamd.h" + +void colamd_version (int version [3]) +{ + version [0] = COLAMD_MAIN_VERSION ; + version [1] = COLAMD_SUB_VERSION ; + version [2] = COLAMD_SUBSUB_VERSION ; +} + diff --git a/COLAMD/cmake_modules/FindCOLAMD.cmake b/COLAMD/cmake_modules/FindCOLAMD.cmake deleted file mode 100644 index 00e8a9ac..00000000 --- a/COLAMD/cmake_modules/FindCOLAMD.cmake +++ /dev/null @@ -1,129 +0,0 @@ -#------------------------------------------------------------------------------- -# SuiteSparse/COLAMD/cmake_modules/FindCOLAMD.cmake -#------------------------------------------------------------------------------- - -# The following copyright and license applies to just this file only, not to -# the library itself: -# FindCOLAMD.cmake, Copyright (c) 2022-2023, Timothy A. Davis. All Rights Reserved. -# SPDX-License-Identifier: BSD-3-clause - -#------------------------------------------------------------------------------- - -# Finds the COLAMD include file and compiled library and sets: - -# COLAMD_INCLUDE_DIR - where to find colamd.h -# COLAMD_LIBRARY - dynamic COLAMD library -# COLAMD_STATIC - static COLAMD library -# COLAMD_LIBRARIES - libraries when using COLAMD -# COLAMD_FOUND - true if COLAMD found - -# set ``COLAMD_ROOT`` to a COLAMD installation root to -# tell this module where to look. - -# 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: -# -# set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} -# ${CMAKE_INSTALL_PREFIX}/lib/cmake/SuiteSparse ) - -#------------------------------------------------------------------------------- - -# include files for COLAMD -find_path ( COLAMD_INCLUDE_DIR - NAMES colamd.h - HINTS ${CMAKE_SOURCE_DIR}/.. - HINTS ${CMAKE_SOURCE_DIR}/../SuiteSparse/COLAMD - HINTS ${CMAKE_SOURCE_DIR}/../COLAMD - PATH_SUFFIXES include Include -) - -# dynamic COLAMD library (or static if no dynamic library was built) -find_library ( COLAMD_LIBRARY - NAMES colamd colamd_static - HINTS ${CMAKE_SOURCE_DIR}/.. - HINTS ${CMAKE_SOURCE_DIR}/../SuiteSparse/COLAMD - HINTS ${CMAKE_SOURCE_DIR}/../COLAMD - PATH_SUFFIXES lib build build/Release build/Debug -) - -if ( MSVC ) - set ( STATIC_NAME colamd_static ) -else ( ) - set ( STATIC_NAME colamd ) - set ( save ${CMAKE_FIND_LIBRARY_SUFFIXES} ) - set ( CMAKE_FIND_LIBRARY_SUFFIXES - ${CMAKE_STATIC_LIBRARY_SUFFIX} ${CMAKE_FIND_LIBRARY_SUFFIXES} ) -endif ( ) - -# static COLAMD library -find_library ( COLAMD_STATIC - NAMES ${STATIC_NAME} - HINTS ${CMAKE_SOURCE_DIR}/.. - HINTS ${CMAKE_SOURCE_DIR}/../SuiteSparse/COLAMD - HINTS ${CMAKE_SOURCE_DIR}/../COLAMD - PATH_SUFFIXES lib build build/Release build/Debug -) - -if ( NOT MSVC ) - # restore the CMAKE_FIND_LIBRARY_SUFFIXES variable - set ( CMAKE_FIND_LIBRARY_SUFFIXES ${save} ) -endif ( ) - -# get version of the library from the dynamic library name -get_filename_component ( COLAMD_LIBRARY ${COLAMD_LIBRARY} REALPATH ) -get_filename_component ( COLAMD_FILENAME ${COLAMD_LIBRARY} NAME ) -string ( - REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" - COLAMD_VERSION - ${COLAMD_FILENAME} -) - -# set ( COLAMD_VERSION "" ) -if ( EXISTS "${COLAMD_INCLUDE_DIR}" AND NOT COLAMD_VERSION ) - # if the version does not appear in the filename, read the include file - file ( STRINGS ${COLAMD_INCLUDE_DIR}/colamd.h COLAMD_MAJOR_STR - REGEX "define COLAMD_MAIN_VERSION" ) - file ( STRINGS ${COLAMD_INCLUDE_DIR}/colamd.h COLAMD_MINOR_STR - REGEX "define COLAMD_SUB_VERSION" ) - file ( STRINGS ${COLAMD_INCLUDE_DIR}/colamd.h COLAMD_PATCH_STR - REGEX "define COLAMD_SUBSUB_VERSION" ) - message ( STATUS "major: ${COLAMD_MAJOR_STR}" ) - message ( STATUS "minor: ${COLAMD_MINOR_STR}" ) - message ( STATUS "patch: ${COLAMD_PATCH_STR}" ) - string ( REGEX MATCH "[0-9]+" COLAMD_MAJOR ${COLAMD_MAJOR_STR} ) - string ( REGEX MATCH "[0-9]+" COLAMD_MINOR ${COLAMD_MINOR_STR} ) - string ( REGEX MATCH "[0-9]+" COLAMD_PATCH ${COLAMD_PATCH_STR} ) - set (COLAMD_VERSION "${COLAMD_MAJOR}.${COLAMD_MINOR}.${COLAMD_PATCH}") -endif ( ) - -set (COLAMD_LIBRARIES ${COLAMD_LIBRARY}) - -include (FindPackageHandleStandardArgs) - -find_package_handle_standard_args ( COLAMD - REQUIRED_VARS COLAMD_LIBRARY COLAMD_INCLUDE_DIR - VERSION_VAR COLAMD_VERSION -) - -mark_as_advanced ( - COLAMD_INCLUDE_DIR - COLAMD_LIBRARY - COLAMD_STATIC - COLAMD_LIBRARIES -) - -if ( COLAMD_FOUND ) - message ( STATUS "COLAMD version: ${COLAMD_VERSION}" ) - message ( STATUS "COLAMD include: ${COLAMD_INCLUDE_DIR}" ) - message ( STATUS "COLAMD library: ${COLAMD_LIBRARY}" ) - message ( STATUS "COLAMD static: ${COLAMD_STATIC}" ) -else ( ) - message ( STATUS "COLAMD not found" ) - set ( COLAMD_INCLUDE_DIR "" ) - set ( COLAMD_LIBRARIES "" ) - set ( COLAMD_LIBRARY "" ) - set ( COLAMD_STATIC "" ) -endif ( ) - diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..a81e104c --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,18 @@ +# Contributing to SuiteSparse + +To add an issue for a bug report (gasp!) or a feature request, +you can use the issue tracker on github.com, at +[`https://github.com/DrTimothyAldenDavis/SuiteSparse/issues`] +(https://github.com/DrTimothyAldenDavis/SuiteSparse/issues). + +To contribute code, you can submit a pull request. To do so, +you must first agree to the Contributor License Agreement +[`CONTRIBUTOR-LICENSE.txt`](CONTRIBUTOR-LICENSE.txt). +Print a copy of the txt file (as a PDF), sign and date it, +and email it to me at DrTimothyAldenDavis@gmail.com. Pull +requests will only be included into SuiteSparse after I receive +your email with the signed PDF. + +Do not submit a pull request to the default branch. +Instead, use the dev or dev2 branches. + diff --git a/CONTRIBUTOR-LICENSE.txt b/CONTRIBUTOR-LICENSE.txt new file mode 100644 index 00000000..7cd19eec --- /dev/null +++ b/CONTRIBUTOR-LICENSE.txt @@ -0,0 +1,177 @@ +SuiteSparse Individual Contributor License Agreement + +Thank you for your interest in contributing to SuiteSparse ("We" or "Us"). + +This contributor agreement ("Agreement") documents the rights granted by +contributors to Us. To make this document effective, please sign it and send it +to Us by electronic submission. This is a legally binding document, so please +read it carefully before agreeing to it. The Agreement may cover more than one +software project managed by Us. + +1. Definitions + + "You" means the individual who Submits a Contribution to Us. + + "Contribution" means any work of authorship that is Submitted by You to Us + in which You own or assert ownership of the Copyright. + + "Copyright" means all rights protecting works of authorship owned or + controlled by You, including copyright, moral and neighboring rights, as + appropriate, for the full term of their existence including any extensions + by You. + + "Material" means the work of authorship which is made available by Us to + third parties. When this Agreement covers more than one software project, + the Material means the work of authorship to which the Contribution was + Submitted. After You Submit the Contribution, it may be included in the + Material. + + "Submit" means any form of electronic, verbal, or written communication + sent to Us or our representatives, including but not limited to electronic + mailing lists, source code control systems, and issue tracking systems that + are managed by, or on behalf of, Us for the purpose of discussing and + improving the Material, but excluding communication that is conspicuously + marked or otherwise designated in writing by You as "Not a Contribution." + + "Submission Date" means the date on which You Submit a Contribution to Us. + + "Effective Date" means the date You execute this Agreement or the date You + first Submit a Contribution to Us, whichever is earlier. + +2. Grant of Rights + + 2.1 Copyright License + + (a) You retain ownership of the Copyright in Your Contribution and have + the same rights to use or license the Contribution which You would have + had without entering into the Agreement. + + (b) To the maximum extent permitted by the relevant law, You grant to + Us a perpetual, worldwide, non-exclusive, transferable, royalty-free, + irrevocable license under the Copyright covering the Contribution, with + the right to sublicense such rights through multiple tiers of + sublicensees, to reproduce, modify, display, perform and distribute the + Contribution as part of the Material; provided that this license is + conditioned upon compliance with Section 2.3. + + 2.2 Patent License + + For patent claims including, without limitation, method, process, and + apparatus claims which You own, control or have the right to grant, now + or in the future, You grant to Us a perpetual, worldwide, + non-exclusive, transferable, royalty-free, irrevocable patent license, + with the right to sublicense these rights to multiple tiers of + sublicensees, to make, have made, use, sell, offer for sale, import and + otherwise transfer the Contribution and the Contribution in combination + with the Material (and portions of such combination). This license is + granted only to the extent that the exercise of the licensed rights + infringes such patent claims; and provided that this license is + conditioned upon compliance with Section 2.3. + + 2.3 Outbound License + + Based on the grant of rights in Sections 2.1 and 2.2, if We include + Your Contribution in a Material, We may license the Contribution under + any license, including copyleft, permissive, commercial, or proprietary + licenses. + + 2.4 Moral Rights. + + If moral rights apply to the Contribution, to the maximum extent + permitted by law, You waive and agree not to assert such moral rights + against Us or our successors in interest, or any of our licensees, + either direct or indirect. + + 2.5 Our Rights. + + You acknowledge that We are not obligated to use Your Contribution as + part of the Material and may decide to include any Contribution We + consider appropriate. + + 2.6 Reservation of Rights. + + Any rights not expressly licensed under this section are expressly + reserved by You. + +3. Agreement + + You confirm that: + + (a) You have the legal authority to enter into this Agreement. + + (b) You own the Copyright and patent claims covering the Contribution which + are required to grant the rights under Section 2. + + (c) The grant of rights under Section 2 does not violate any grant of + rights which You have made to third parties, including Your employer. If + You are an employee, You have had Your employer approve this Agreement or + sign the Entity version of this document. If You are less than eighteen + years old, please have Your parents or guardian sign the Agreement. + +4. Disclaimer + + EXCEPT FOR THE EXPRESS WARRANTIES IN SECTION 3, THE CONTRIBUTION IS + PROVIDED "AS IS". MORE PARTICULARLY, ALL EXPRESS OR IMPLIED WARRANTIES + INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTY OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY + DISCLAIMED BY YOU TO US. TO THE EXTENT THAT ANY SUCH WARRANTIES CANNOT BE + DISCLAIMED, SUCH WARRANTY IS LIMITED IN DURATION TO THE MINIMUM PERIOD + PERMITTED BY LAW. + +5. Consequential Damage Waiver + + TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL YOU BE + LIABLE FOR ANY LOSS OF PROFITS, LOSS OF ANTICIPATED SAVINGS, LOSS OF DATA, + INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL AND EXEMPLARY DAMAGES ARISING + OUT OF THIS AGREEMENT REGARDLESS OF THE LEGAL OR EQUITABLE THEORY + (CONTRACT, TORT OR OTHERWISE) UPON WHICH THE CLAIM IS BASED. + +6. Miscellaneous + + 6.1 This Agreement will be governed by and construed in accordance with the + laws of the State of Texas excluding its conflicts of law provisions. Under + certain circumstances, the governing law in this section might be + superseded by the United Nations Convention on Contracts for the + International Sale of Goods ("UN Convention") and the parties intend to + avoid the application of the UN Convention to this Agreement and, thus, + exclude the application of the UN Convention in its entirety to this + Agreement. + + 6.2 This Agreement sets out the entire agreement between You and Us for + Your Contributions to Us and overrides all other agreements or + understandings. + + 6.3 If You or We assign the rights or obligations received through this + Agreement to a third party, as a condition of the assignment, that third + party must agree in writing to abide by all the rights and obligations in + the Agreement. + + 6.4 The failure of either party to require performance by the other party + of any provision of this Agreement in one situation shall not affect the + right of a party to require such performance at any time in the future. A + waiver of performance under a provision in one situation shall not be + considered a waiver of the performance of the provision in the future or a + waiver of the provision in its entirety. + + 6.5 If any provision of this Agreement is found void and unenforceable, + such provision will be replaced to the extent possible with a provision + that comes closest to the meaning of the original provision and which is + enforceable. The terms and conditions set forth in this Agreement shall + apply notwithstanding any failure of essential purpose of this Agreement or + any limited remedy to the maximum extent possible under law. + +Us +Timothy A. Davis, and all SuiteSparse co-authors (varies according to +the SuiteSparse package) + + +You: + + Your Name (printed): + + + Your Signature: + + + Date: + diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..2516bc71 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,113 @@ +This file lists all licenses for all packages in SPEX, for your +convenience. Each package has its own separate license, which can be +found in the lists below. + +==> SPEX/LICENSE <== + + SPEX: a SParse EXact Factorization Framework for solving SLEs + + Copyright (c) 2019-2024, Christopher Lourenco, Jinhao Chen, + Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. + + Available at: + https://github.com/clouren/SPEX + http://suitesparse.com + + Contact Chris Lourenco, chrisjlourenco@gmail.com, or Tim Davis + (timdavis@aldenmath.com or DrTimothyAldenDavis@gmail.com) for a commercial + license. + + -------------------------------------------------------------------------------- + + SPEX is free software; you can redistribute it and/or modify + it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + + or both in parallel, as here. + + SPEX is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received copies of the GNU General Public License and the + GNU Lesser General Public License along with this software. If not, + see https://www.gnu.org/licenses/. + +==> AMD/Doc/License.txt <== + + AMD, Copyright (c), 1996-2015, Timothy A. Davis, + Patrick R. Amestoy, and Iain S. Duff. All Rights Reserved. + + Availability: + + http://www.suitesparse.com + + ------------------------------------------------------------------------------- + AMD License: BSD 3-clause: + ------------------------------------------------------------------------------- + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the organizations to which the authors are + affiliated, nor the names of its contributors may be used to endorse + or promote products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. + +==> COLAMD/Doc/License.txt <== + + COLAMD, Copyright 1998-2016, Timothy A. Davis. http://www.suitesparse.com + http://www.suitesparse.com + + COLAMD License: BSD 3-clause + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the organizations to which the authors are + affiliated, nor the names of its contributors may be used to endorse + or promote products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. + diff --git a/Makefile b/Makefile index d733c223..3cfd3029 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,11 @@ # Makefile for SPEX and its dependent packages (AMD, COLAMD, SuiteSparse_config) #------------------------------------------------------------------------------- +# Copyright (c) 2023-2024, Timothy A. Davis, All Rights Reserved. FIXME +# Just this particular file is under the Apache-2.0 license; each package has +# its own license. +# SPDX-License-Identifier: Apache-2.0 + # edit this variable to pass options to cmake: export CMAKE_OPTIONS ?= @@ -15,8 +20,7 @@ export SUITESPARSE = $(CURDIR) # Compile the default rules for each package. -# default: "make install" will install all libraries in /usr/local/lib -# and include files in /usr/local/include. Not installed in SuiteSparse/lib. +# default: compile and install in SPEX/lib and SPEX/include default: local install # compile; "sudo make install" will install only in /usr/local @@ -27,7 +31,7 @@ library: ( cd COLAMD && $(MAKE) ) ( cd SPEX && $(MAKE) ) -# compile; "make install" only in SuiteSparse/lib and SuiteSparse/include +# compile; "make install" only in SPEX/lib and SPEX/include local: ( cd SuiteSparse_config && $(MAKE) local ) ( cd AMD && $(MAKE) local ) @@ -64,8 +68,8 @@ purge: - ( cd SuiteSparse_config && $(MAKE) purge ) - ( cd AMD && $(MAKE) purge ) - ( cd COLAMD && $(MAKE) purge ) - - $(RM) -r include/* bin/* lib/* - ( cd SPEX && $(MAKE) purge ) + - $(RM) -r include/* bin/* lib/* clean: purge @@ -85,3 +89,9 @@ docs: cov: local install ( cd SPEX && $(MAKE) cov ) +debug: + ( cd SuiteSparse_config && $(MAKE) debug ) + ( cd AMD && $(MAKE) debug ) + ( cd COLAMD && $(MAKE) debug ) + ( cd SPEX && $(MAKE) debug ) + diff --git a/README.md b/README.md index ad1d4e85..225ef135 100644 --- a/README.md +++ b/README.md @@ -83,42 +83,162 @@ is provided. All it does is use cmake to build each of the packages. keeps compiled libraries and demoes, ./lib and ./include. +You can also use cmake or ccmake directly. For example, try: + + cd AMD/build + ccmake .. + make + +----------------------------------------------------------------------------- +How to cite the SPEX meta-package and its component packages: +----------------------------------------------------------------------------- + +* for AMD: + + P. Amestoy, T. A. Davis, and I. S. Duff, Algorithm 837: An approximate + minimum degree ordering algorithm, ACM Trans. on Mathematical Software, + 30(3), 2004, pp. 381--388. + https://dl.acm.org/doi/abs/10.1145/1024074.1024081 + + P. Amestoy, T. A. Davis, and I. S. Duff, An approximate minimum degree + ordering algorithm, SIAM J. Matrix Analysis and Applications, 17(4), 1996, + pp. 886--905. https://doi.org/10.1137/S0895479894278952 + +* for COLAMD: + + T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, Algorithm 836: COLAMD, an + approximate column minimum degree ordering algorithm, ACM Trans. on + Mathematical Software, 30(3), 2004, pp. 377--380. + https://doi.org/10.1145/1024074.1024080 + + T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, A column approximate minimum + degree ordering algorithm, ACM Trans. on Mathematical Software, 30(3), 2004, + pp. 353--376. https://doi.org/10.1145/1024074.1024079 + +* for SPEX: + + Christopher Lourenco, Jinhao Chen, Erick Moreno-Centeno, and T. A. Davis. + 2022. Algorithm 1021: SPEX Left LU, Exactly Solving Sparse Linear Systems via + a Sparse Left-Looking Integer-Preserving LU Factorization. ACM Trans. Math. + Softw. June 2022. https://doi.org/10.1145/3519024 + +----------------------------------------------------------------------------- +Compilation options +----------------------------------------------------------------------------- + You can set specific options for CMake with the command (for example): +``` + cmake -DBUILD_STATIC_LIBS=OFF -DCMAKE_BUILD_TYPE=Debug .. +``` - CMAKE_OPTIONS="-DNSTATIC=1 -DCMAKE_BUILD_TYPE=Debug" make +That command will compile SPEX, AMD, COLAMD, and `SuiteSparse_config`. +Debug mode will be used (the build type). The static libraries will not be +built (since `-DBUILD_STATIC_LIBS=OFF` is set). -That command will compile all of SPEX and it dependencies. -Debug mode will be used. The static libraries will not be built -(NSTATIC is true). +* `SUITESPARSE_ENABLE_PROJECTS`: - CMAKE_BUILD_TYPE: Default: "Release", use "Debug" for debugging. + Semicolon separated list of projects to be built or `all`. + Default: `all` in which case the following projects are built: - GLOBAL_INSTALL: if true, "make install" will install - into /usr/local/lib and /usr/local/include. - Default: true + `suitesparse_config;amd;colamd;spex` - LOCAL_INSTALL: if true, "make install" will install - into SuiteSparse/lib and SuiteSparse/include. - Default: false +* `CMAKE_BUILD_TYPE`: - NSTATIC: if true, static libraries are not built. - Default: false, except for GraphBLAS, which - takes a long time to compile so the default for - GraphBLAS is true. For Mongoose, the NSTATIC setting - is treated as if it always false, since the mongoose - program is built with the static library. + Default: `Release`, use `Debug` for debugging. - NOPENMP if true: OpenMP is not used. Default: false. - Only used by SuiteSparse_config. +* `SUITESPARSE_USE_STRICT`: - DEMO if true: build the demo programs for each package. - Default: false. + 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`. -You can also use cmake or ccmake directly. For example, try: +* `CMAKE_INSTALL_PREFIX`: - cd AMD/build - ccmake .. - make + Defines the install location (default on Linux is `/usr/local`). For example, + this command while in a folder `build` in the top level SuiteSparse folder + will set the install directory to `/stuff`, used by the subsequent + `sudo cmake --install .`: +``` + cmake -DCMAKE_INSTALL_PREFIX=/stuff .. + sudo cmake --install . +``` + +* `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. + + This option allows to install them at a location different from the (static) + libraries. This allows to install multiple configurations of the SuiteSparse + libraries at the same time (e.g., by also setting a different + `CMAKE_RELEASE_POSTFIX` and `CMAKE_INSTALL_LIBDIR` for each of them). To pick + up the respective configuration in downstream projects, set, e.g., + `CMAKE_PREFIX_PATH` (for CMake) or `PKG_CONFIG_PATH` (for build systems using + pkg-config) to the path containing the respective CMake Config files or + pkg-config files. + +* `SUITESPARSE_INCLUDEDIR_POSTFIX`: + + Postfix for installation target of header from SuiteSparse. Default: + suitesparse, so the default include directory is: + `CMAKE_INSTALL_PREFIX/include/suitesparse` + +* `BUILD_SHARED_LIBS`: + + If `ON`, shared libraries are built. + Default: `ON`. + +* `BUILD_STATIC_LIBS`: + + If `ON`, static libraries are built. + Default: `ON`, except for GraphBLAS, which takes a long time to compile so + the default for GraphBLAS is `OFF` unless `BUILD_SHARED_LIBS` is `OFF`. + +* `SUITESPARSE_USE_OPENMP`: + + If `ON`, OpenMP is used by default if it is available. Default: `ON`. + SPEX relies on OpenMP for its thread safety. + +* `SUITESPARSE_CONFIG_USE_OPENMP`: + + If `ON`, `SuiteSparse_config` uses OpenMP if it is available. + Default: `SUITESPARSE_USE_OPENMP`. + It is not essential and only used to let `SuiteSparse_time` call + `omp_get_wtime`. + +* `SPEX_USE_OPENMP`: + + If `ON`, OpenMP is used in SPEX if it is available. + Default: `SUITESPARSE_USE_OPENMP`. + +* `SUITESPARSE_DEMOS`: + + If `ON`, build the demo programs for each package. Default: `OFF`. + +* `SUITESPARSE_USE_SYSTEM_AMD`: + + If `ON`, use AMD libraries installed on the build system. If `OFF`, + automatically build AMD as dependency if needed. Default: `OFF`. + +* `SUITESPARSE_USE_SYSTEM_COLAMD`: + + If `ON`, use COLAMD libraries installed on the build system. If `OFF`, + automatically build COLAMD as dependency if needed. Default: `OFF`. + +* `SUITESPARSE_USE_SYSTEM_SUITESPARSE_CONFIG`: + + If `ON`, use `SuiteSparse_config` libraries installed on the build system. If + `OFF`, automatically build `SuiteSparse_config` as dependency if needed. + Default: `OFF`. ----------------------------------------------------------------------------- Acknowledgements @@ -133,9 +253,9 @@ to contact us if there's anything we can do to make your life easier. See also the various Acknowledgements within each package. -Primary Author: Chris Lourenco +Primary Author of SPEX: Chris Lourenco -Coauthors (alphabetical order): +SPEX Coauthors (alphabetical order): Jinhao Chen Timothy A Davis diff --git a/SPEX/CMakeLists.txt b/SPEX/CMakeLists.txt index 976a040c..b9a3929b 100644 --- a/SPEX/CMakeLists.txt +++ b/SPEX/CMakeLists.txt @@ -2,73 +2,110 @@ # SuiteSparse/SPEX/CMakeLists.txt: cmake for SPEX #------------------------------------------------------------------------------- -# Copyright (c) 2022-2023, Timothy A. Davis. +# SPEX: (c) 2019-2024, Chris Lourenco (US Naval Academy), Jinhao Chen, +# Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis, Texas A&M. # All Rights Reserved. -# SPDX-License-Identifier: BSD-3-clause +# SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later #------------------------------------------------------------------------------- # get the version #------------------------------------------------------------------------------- -cmake_minimum_required ( VERSION 3.19 ) +cmake_minimum_required ( VERSION 3.22 ) -set ( SPEX_DATE "Jul 26, 2023" ) -set ( SPEX_VERSION_MAJOR 3 ) -set ( SPEX_VERSION_MINOR 0 ) -set ( SPEX_VERSION_SUB 0 ) +set ( SPEX_DATE "Mar 22, 2024" ) +set ( SPEX_VERSION_MAJOR 3 CACHE STRING "" FORCE ) +set ( SPEX_VERSION_MINOR 1 CACHE STRING "" FORCE ) +set ( SPEX_VERSION_SUB 0 CACHE STRING "" FORCE ) message ( STATUS "Building SPEX version: v" ${SPEX_VERSION_MAJOR}. ${SPEX_VERSION_MINOR}. ${SPEX_VERSION_SUB} " (" ${SPEX_DATE} ")" ) +#------------------------------------------------------------------------------- +# define the project +#------------------------------------------------------------------------------- + +project ( SPEX + VERSION "${SPEX_VERSION_MAJOR}.${SPEX_VERSION_MINOR}.${SPEX_VERSION_SUB}" + LANGUAGES C ) + #------------------------------------------------------------------------------- # SuiteSparse policies #------------------------------------------------------------------------------- set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} - ${CMAKE_SOURCE_DIR}/cmake_modules - ${CMAKE_SOURCE_DIR}/../COLAMD/cmake_modules - ${CMAKE_SOURCE_DIR}/../AMD/cmake_modules - ${CMAKE_SOURCE_DIR}/../SuiteSparse_config/cmake_modules ) + ${PROJECT_SOURCE_DIR}/cmake_modules + ${PROJECT_SOURCE_DIR}/../SuiteSparse_config/cmake_modules ) include ( SuiteSparsePolicy ) #------------------------------------------------------------------------------- -# define the project +# find OpenMP #------------------------------------------------------------------------------- -project ( spex - VERSION "${SPEX_VERSION_MAJOR}.${SPEX_VERSION_MINOR}.${SPEX_VERSION_SUB}" - LANGUAGES C ) +option ( SPEX_USE_OPENMP "ON: Use OpenMP in SPEX if available. OFF: Do not use OpenMP. (Default: SUITESPARSE_USE_OPENMP)" ${SUITESPARSE_USE_OPENMP} ) +if ( SPEX_USE_OPENMP ) + if ( CMAKE_VERSION VERSION_LESS 3.24 ) + find_package ( OpenMP COMPONENTS C ) + else ( ) + find_package ( OpenMP COMPONENTS C GLOBAL ) + endif ( ) +else ( ) + # OpenMP has been disabled + set ( OpenMP_C_FOUND OFF ) +endif ( ) + +if ( SPEX_USE_OPENMP AND OpenMP_C_FOUND ) + set ( SPEX_HAS_OPENMP ON ) +else ( ) + set ( SPEX_HAS_OPENMP OFF ) +endif ( ) +message ( STATUS "SPEX has OpenMP: ${SPEX_HAS_OPENMP}" ) + +# check for strict usage +if ( SUITESPARSE_USE_STRICT AND SPEX_USE_OPENMP AND NOT SPEX_HAS_OPENMP ) + message ( FATAL_ERROR "OpenMP required for SPEX but not found" ) +endif ( ) #------------------------------------------------------------------------------- # find library dependencies #------------------------------------------------------------------------------- -find_package ( SuiteSparse_config 6.0.2 REQUIRED ) -find_package ( COLAMD 3.0.2 REQUIRED ) -find_package ( AMD 3.0.2 REQUIRED ) -find_package ( GMP 6.1.2 REQUIRED ) # from SPEX/cmake_modules -find_package ( MPFR 4.0.2 REQUIRED ) # from SPEX/cmake_modules +if ( NOT SUITESPARSE_ROOT_CMAKELISTS ) + find_package ( SuiteSparse_config 7.7.0 + PATHS ${CMAKE_SOURCE_DIR}/../SuiteSparse_config/build NO_DEFAULT_PATH ) + if ( NOT TARGET SuiteSparse::SuiteSparseConfig ) + find_package ( SuiteSparse_config 7.7.0 REQUIRED ) + endif ( ) -option ( NOPENMP "ON (default): do not use OpenMP. OFF: use OpenMP" on ) -if ( NOPENMP ) - set ( OPENMP_FOUND false ) -else ( ) - find_package ( OpenMP ) + find_package ( AMD 3.3.2 + PATHS ${CMAKE_SOURCE_DIR}/../AMD/build NO_DEFAULT_PATH ) + if ( NOT TARGET SuiteSparse::AMD ) + find_package ( AMD 3.3.2 REQUIRED ) + endif ( ) + + find_package ( COLAMD 3.3.3 + PATHS ${CMAKE_SOURCE_DIR}/../COLAMD/build NO_DEFAULT_PATH ) + if ( NOT TARGET SuiteSparse::COLAMD ) + find_package ( COLAMD 3.3.3 REQUIRED ) + endif ( ) endif ( ) -include ( SuiteSparse__thread ) +find_package ( GMP 6.1.2 REQUIRED ) # from SPEX/cmake_modules +find_package ( MPFR 4.0.2 REQUIRED ) # from SPEX/cmake_modules #------------------------------------------------------------------------------- # configure files #------------------------------------------------------------------------------- configure_file ( "Config/SPEX.h.in" - "${PROJECT_SOURCE_DIR}/Include/SPEX.h") + "${PROJECT_SOURCE_DIR}/Include/SPEX.h" + NEWLINE_STYLE LF ) configure_file ( "Config/SPEX_version.tex.in" - "${PROJECT_SOURCE_DIR}/Doc/SPEX_version.tex") + "${PROJECT_SOURCE_DIR}/Doc/SPEX_version.tex" + NEWLINE_STYLE LF ) #------------------------------------------------------------------------------- # include directories @@ -81,96 +118,154 @@ include_directories ( Include ${GMP_INCLUDE_DIR} ${MPFR_INCLUDE_DIR} ${AMD_INCLUDE_DIR} ${COLAMD_INCLUDE_DIR} ) -#------------------------------------------------------------------------------- -# compiler flags -#------------------------------------------------------------------------------- - -# (for example): -# if ( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" ) -# set ( CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O2" ) -# endif ( ) - #------------------------------------------------------------------------------- # dynamic spex library properties #------------------------------------------------------------------------------- file ( GLOB SPEX_SOURCES "SPEX*/Source/*.c" ) -add_library ( spex SHARED ${SPEX_SOURCES} ) +if ( BUILD_SHARED_LIBS ) + add_library ( SPEX SHARED ${SPEX_SOURCES} ) + + set_target_properties ( SPEX PROPERTIES + VERSION ${SPEX_VERSION_MAJOR}.${SPEX_VERSION_MINOR}.${SPEX_VERSION_SUB} + C_STANDARD 11 + C_STANDARD_REQUIRED ON + OUTPUT_NAME spex + SOVERSION ${SPEX_VERSION_MAJOR} + PUBLIC_HEADER "Include/SPEX.h" + WINDOWS_EXPORT_ALL_SYMBOLS ON ) -set_target_properties ( spex PROPERTIES - VERSION ${SPEX_VERSION_MAJOR}.${SPEX_VERSION_MINOR}.${SPEX_VERSION_SUB} - C_STANDARD_REQUIRED 11 - SOVERSION ${SPEX_VERSION_MAJOR} - PUBLIC_HEADER "Include/SPEX.h" ) + if ( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.25" ) + set_target_properties ( SPEX PROPERTIES EXPORT_NO_SYSTEM ON ) + endif ( ) + + target_include_directories ( SPEX + INTERFACE $ + $ ) +endif ( ) #------------------------------------------------------------------------------- # static spex library properties #------------------------------------------------------------------------------- -if ( NOT NSTATIC ) -add_library ( spex_static STATIC ${SPEX_SOURCES} ) +if ( BUILD_STATIC_LIBS ) + add_library ( SPEX_static STATIC ${SPEX_SOURCES} ) -set_target_properties ( spex_static PROPERTIES - VERSION ${SPEX_VERSION_MAJOR}.${SPEX_VERSION_MINOR}.${SPEX_VERSION_SUB} - C_STANDARD_REQUIRED 11 - OUTPUT_NAME spex - SOVERSION ${SPEX_VERSION_MAJOR} ) + set_target_properties ( SPEX_static PROPERTIES + C_STANDARD 11 + C_STANDARD_REQUIRED ON + OUTPUT_NAME spex + PUBLIC_HEADER "Include/SPEX.h" ) + + if ( MSVC OR ("${CMAKE_C_SIMULATE_ID}" STREQUAL "MSVC") ) + set_target_properties ( SPEX_static PROPERTIES + OUTPUT_NAME spex_static ) + endif ( ) + + if ( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.25" ) + set_target_properties ( SPEX_static PROPERTIES EXPORT_NO_SYSTEM ON ) + endif ( ) + + target_include_directories ( SPEX_static + INTERFACE $ + $ ) endif ( ) #------------------------------------------------------------------------------- # add the library dependencies #------------------------------------------------------------------------------- -# suitesparseconfig: -target_link_libraries ( spex PUBLIC ${SUITESPARSE_CONFIG_LIBRARIES} ) -if ( NOT NSTATIC ) - target_link_libraries ( spex_static PUBLIC ${SUITESPARSE_CONFIG_LIBRARIES} ) +# SuiteSparseConfig: +if ( BUILD_SHARED_LIBS ) + target_link_libraries ( SPEX PRIVATE SuiteSparse::SuiteSparseConfig ) + target_include_directories ( SPEX PUBLIC + "$" ) endif ( ) - -# OpenMP: -if ( OPENMP_FOUND ) - message ( STATUS "OpenMP C libraries: ${OpenMP_C_LIBRARIES} ") - message ( STATUS "OpenMP C include: ${OpenMP_C_INCLUDE_DIRS} ") - message ( STATUS "OpenMP C flags: ${OpenMP_C_FLAGS} ") - target_link_libraries ( spex PUBLIC ${OpenMP_C_LIBRARIES} ) - if ( NOT NSTATIC ) - target_link_libraries ( spex_static PUBLIC ${OpenMP_C_LIBRARIES} ) +if ( BUILD_STATIC_LIBS ) + if ( TARGET SuiteSparse::SuiteSparseConfig_static ) + target_link_libraries ( SPEX_static PUBLIC SuiteSparse::SuiteSparseConfig_static ) + else ( ) + target_link_libraries ( SPEX_static PUBLIC SuiteSparse::SuiteSparseConfig ) endif ( ) - set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS} " ) - include_directories ( ${OpenMP_C_INCLUDE_DIRS} ) endif ( ) # AMD: -target_link_libraries ( spex PUBLIC ${AMD_LIBRARIES} ) -if ( NOT NSTATIC ) - target_link_libraries ( spex_static PUBLIC ${AMD_STATIC} ) +if ( BUILD_SHARED_LIBS ) + target_link_libraries ( SPEX PRIVATE SuiteSparse::AMD ) +endif ( ) +if ( BUILD_STATIC_LIBS ) + if ( TARGET SuiteSparse::AMD_static ) + target_link_libraries ( SPEX_static PRIVATE SuiteSparse::AMD_static ) + else ( ) + target_link_libraries ( SPEX_static PRIVATE SuiteSparse::AMD ) + endif ( ) endif ( ) # COLAMD: -target_link_libraries ( spex PUBLIC ${COLAMD_LIBRARIES} ) -if ( NOT NSTATIC ) - target_link_libraries ( spex_static PUBLIC ${COLAMD_STATIC} ) +if ( BUILD_SHARED_LIBS ) + target_link_libraries ( SPEX PRIVATE SuiteSparse::COLAMD ) +endif ( ) +if ( BUILD_STATIC_LIBS ) + if ( TARGET SuiteSparse::COLAMD_static ) + target_link_libraries ( SPEX_static PRIVATE SuiteSparse::COLAMD_static ) + else ( ) + target_link_libraries ( SPEX_static PRIVATE SuiteSparse::COLAMD ) + endif ( ) endif ( ) # MPFR: -target_link_libraries ( spex PUBLIC ${MPFR_LIBRARIES} ) -if ( NOT NSTATIC ) - target_link_libraries ( spex_static PUBLIC ${MPFR_STATIC} ) +if ( BUILD_SHARED_LIBS ) + target_link_libraries ( SPEX PRIVATE ${MPFR_LIBRARIES} ) + target_include_directories ( SPEX SYSTEM AFTER PUBLIC ${MPFR_INCLUDE_DIR} ) +endif ( ) +if ( BUILD_STATIC_LIBS ) + list ( APPEND SPEX_STATIC_LIBS ${MPFR_STATIC} ) + target_link_libraries ( SPEX_static PUBLIC ${MPFR_STATIC} ) + target_include_directories ( SPEX_static SYSTEM AFTER PUBLIC ${MPFR_INCLUDE_DIR} ) endif ( ) # GMP: # must occur after MPFR -target_link_libraries ( spex PUBLIC ${GMP_LIBRARIES} ) -if ( NOT NSTATIC ) - target_link_libraries ( spex_static PUBLIC ${GMP_STATIC} ) +if ( BUILD_SHARED_LIBS ) + target_link_libraries ( SPEX PRIVATE ${GMP_LIBRARIES} ) + target_include_directories ( SPEX SYSTEM AFTER PUBLIC ${GMP_INCLUDE_DIR} ) +endif ( ) +if ( BUILD_STATIC_LIBS ) + list ( APPEND SPEX_STATIC_LIBS ${GMP_STATIC} ) + target_link_libraries ( SPEX_static PUBLIC ${GMP_STATIC} ) + target_include_directories ( SPEX_static SYSTEM AFTER PUBLIC ${GMP_INCLUDE_DIR} ) +endif ( ) + +# OpenMP: +if ( SPEX_HAS_OPENMP ) + message ( STATUS "OpenMP C libraries: ${OpenMP_C_LIBRARIES}" ) + message ( STATUS "OpenMP C include: ${OpenMP_C_INCLUDE_DIRS}" ) + message ( STATUS "OpenMP C flags: ${OpenMP_C_FLAGS}" ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries ( SPEX PRIVATE OpenMP::OpenMP_C ) + endif ( ) + if ( BUILD_STATIC_LIBS ) + target_link_libraries ( SPEX_static PRIVATE OpenMP::OpenMP_C ) + list ( APPEND SPEX_STATIC_LIBS ${OpenMP_C_LIBRARIES} ) + endif ( ) +else ( ) + # use threadprivate variables for SPEX instead of globals, so multiple user + # threads can call SPEX in parallel on different matrices. Otherwise, SPEX + # is not thread-safe (see SPEX_Utilities/Source/SPEX_gmp.c). + include ( SuiteSparse__thread ) endif ( ) # libm: -if ( NOT WIN32 ) - target_link_libraries ( spex PUBLIC m ) - if ( NOT NSTATIC ) - target_link_libraries ( spex_static PUBLIC m ) +include ( CheckSymbolExists ) +check_symbol_exists ( fmax "math.h" NO_LIBM ) +if ( NOT NO_LIBM ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries ( SPEX PRIVATE m ) + endif ( ) + if ( BUILD_STATIC_LIBS ) + list ( APPEND SPEX_STATIC_LIBS "m" ) + target_link_libraries ( SPEX_static PUBLIC m ) endif ( ) endif ( ) @@ -178,54 +273,179 @@ endif ( ) # SPEX installation location #------------------------------------------------------------------------------- -install ( TARGETS spex - LIBRARY DESTINATION ${SUITESPARSE_LIBDIR} - ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} - RUNTIME DESTINATION ${SUITESPARSE_BINDIR} - PUBLIC_HEADER DESTINATION ${SUITESPARSE_INCLUDEDIR} ) -install ( FILES ${CMAKE_SOURCE_DIR}/cmake_modules/FindSPEX.cmake - DESTINATION ${SUITESPARSE_LIBDIR}/cmake/SuiteSparse - COMPONENT Development ) -if ( NOT NSTATIC ) - install ( TARGETS spex_static - ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} ) +include ( CMakePackageConfigHelpers ) + +if ( BUILD_SHARED_LIBS ) + install ( TARGETS SPEX + EXPORT SPEXTargets + LIBRARY DESTINATION ${SUITESPARSE_LIBDIR} + ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} + RUNTIME DESTINATION ${SUITESPARSE_BINDIR} + PUBLIC_HEADER DESTINATION ${SUITESPARSE_INCLUDEDIR} ) +endif ( ) +if ( BUILD_STATIC_LIBS ) + install ( TARGETS SPEX_static + EXPORT SPEXTargets + ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} + PUBLIC_HEADER DESTINATION ${SUITESPARSE_INCLUDEDIR} ) +endif ( ) + +# create (temporary) export target file during build +export ( EXPORT SPEXTargets + NAMESPACE SuiteSparse:: + FILE ${CMAKE_CURRENT_BINARY_DIR}/SPEXTargets.cmake ) + +# install export target, config and version files for find_package +install ( EXPORT SPEXTargets + NAMESPACE SuiteSparse:: + DESTINATION ${SUITESPARSE_PKGFILEDIR}/cmake/SPEX ) + +# generate config file to be used in common build tree +set ( SUITESPARSE_IN_BUILD_TREE ON ) +configure_package_config_file ( + Config/SPEXConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/SPEXConfig.cmake + INSTALL_DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/SPEXConfig.cmake ) + +# generate config file to be installed +set ( SUITESPARSE_IN_BUILD_TREE OFF ) +configure_package_config_file ( + Config/SPEXConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/target/SPEXConfig.cmake + INSTALL_DESTINATION ${SUITESPARSE_PKGFILEDIR}/cmake/SPEX ) + +write_basic_package_version_file ( + ${CMAKE_CURRENT_BINARY_DIR}/SPEXConfigVersion.cmake + COMPATIBILITY SameMajorVersion ) + +install ( FILES + ${CMAKE_CURRENT_BINARY_DIR}/target/SPEXConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/SPEXConfigVersion.cmake + ${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules/FindGMP.cmake + ${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules/FindMPFR.cmake + DESTINATION ${SUITESPARSE_PKGFILEDIR}/cmake/SPEX ) + +#------------------------------------------------------------------------------- +# configure MATLAB +#------------------------------------------------------------------------------- + +cmake_path ( IS_ABSOLUTE SUITESPARSE_LIBDIR SUITESPARSE_LIBDIR_IS_ABSOLUTE ) +if (SUITESPARSE_LIBDIR_IS_ABSOLUTE) + set ( matlab_libdir "${SUITESPARSE_LIBDIR}") +else ( ) + set ( matlab_libdir "${CMAKE_INSTALL_PREFIX}/${SUITESPARSE_LIBDIR}") +endif ( ) +cmake_path ( IS_ABSOLUTE SUITESPARSE_INCLUDEDIR SUITESPARSE_INCLUDEDIR_IS_ABSOLUTE ) +if (SUITESPARSE_INCLUDEDIR_IS_ABSOLUTE) + set ( matlab_includedir "${SUITESPARSE_INCLUDEDIR}") +else ( ) + set ( matlab_includedir "${CMAKE_INSTALL_PREFIX}/${SUITESPARSE_INCLUDEDIR}") +endif ( ) + +#------------------------------------------------------------------------------- +# create pkg-config file +#------------------------------------------------------------------------------- + +if ( NOT MSVC ) + # 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 ( SPEX_STATIC_LIBS_LIST ${SPEX_STATIC_LIBS} ) + set ( SPEX_STATIC_LIBS "" ) + foreach ( _lib ${SPEX_STATIC_LIBS_LIST} ) + string ( FIND ${_lib} "." _pos REVERSE ) + if ( ${_pos} EQUAL "-1" ) + set ( SPEX_STATIC_LIBS "${SPEX_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 ( SPEX_STATIC_LIBS "${SPEX_STATIC_LIBS} -l${_libname}" ) + break () + endif ( ) + endif ( ) + endforeach ( ) + endforeach ( ) + + 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/SPEX.pc.in + SPEX.pc.out + @ONLY + NEWLINE_STYLE LF ) + file ( GENERATE + OUTPUT SPEX.pc + INPUT ${CMAKE_CURRENT_BINARY_DIR}/SPEX.pc.out + NEWLINE_STYLE LF ) + install ( FILES + ${CMAKE_CURRENT_BINARY_DIR}/SPEX.pc + DESTINATION ${SUITESPARSE_PKGFILEDIR}/pkgconfig ) endif ( ) #------------------------------------------------------------------------------- # python interface #------------------------------------------------------------------------------- -file ( GLOB SPEX_PYTHON_SOURCES "Python/SPEXpy/Source/*.c" ) +if ( BUILD_SHARED_LIBS ) -add_library ( spexpython SHARED ${SPEX_PYTHON_SOURCES} ) + file ( GLOB SPEX_PYTHON_SOURCES "Python/SPEXpy/Source/*.c" ) + add_library ( spexpython SHARED ${SPEX_PYTHON_SOURCES} ) -set_target_properties ( spexpython PROPERTIES - VERSION ${SPEX_VERSION_MAJOR}.${SPEX_VERSION_MINOR}.${SPEX_VERSION_SUB} - C_STANDARD_REQUIRED 11 - SOVERSION ${SPEX_VERSION_MAJOR} - PUBLIC_HEADER "Python/SPEXpy/Source/spex_python_connect.h" ) + set_target_properties ( spexpython PROPERTIES + VERSION ${SPEX_VERSION_MAJOR}.${SPEX_VERSION_MINOR}.${SPEX_VERSION_SUB} + C_STANDARD 11 + C_STANDARD_REQUIRED ON + SOVERSION ${SPEX_VERSION_MAJOR} + PUBLIC_HEADER "Python/SPEXpy/Source/spex_python_connect.h" ) -# MPFR: -target_link_libraries ( spexpython PUBLIC ${MPFR_LIBRARIES} ) + # MPFR: + target_link_libraries ( spexpython PRIVATE ${MPFR_LIBRARIES} ) -# GMP: -# must occur after MPFR -target_link_libraries ( spexpython PUBLIC ${GMP_LIBRARIES} ) + # GMP: + # must occur after MPFR + target_link_libraries ( spexpython PRIVATE ${GMP_LIBRARIES} ) -target_link_libraries ( spexpython PUBLIC spex ) + target_link_libraries ( spexpython PRIVATE SuiteSparse::COLAMD ) + target_link_libraries ( spexpython PRIVATE SuiteSparse::AMD ) + target_link_libraries ( spexpython PRIVATE SPEX ) -install ( TARGETS spexpython - LIBRARY DESTINATION ${SUITESPARSE_LIBDIR} - ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} - RUNTIME DESTINATION ${SUITESPARSE_BINDIR} - PUBLIC_HEADER DESTINATION ${SUITESPARSE_INCLUDEDIR} ) + install ( TARGETS spexpython + LIBRARY DESTINATION ${SUITESPARSE_LIBDIR} + ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} + RUNTIME DESTINATION ${SUITESPARSE_BINDIR} + PUBLIC_HEADER DESTINATION ${SUITESPARSE_INCLUDEDIR} ) +endif ( ) #------------------------------------------------------------------------------- # Demo library and programs #------------------------------------------------------------------------------- -option ( DEMO "ON: Build the demo programs. OFF (default): do not build the demo programs." off ) -if ( DEMO ) +if ( SUITESPARSE_DEMOS ) #--------------------------------------------------------------------------- # demo library @@ -250,14 +470,34 @@ if ( DEMO ) add_executable ( spex_demo_threaded "Demo/spex_demo_threaded.c" ${SPEX_DEMO_SOURCES} ) # Libraries required for Demo programs - target_link_libraries ( spex_demo_backslash PUBLIC spex ) - target_link_libraries ( spex_demo_cholesky_extended PUBLIC spex ) - target_link_libraries ( spex_demo_cholesky_simple PUBLIC spex ) - target_link_libraries ( spex_demo_lu_doub PUBLIC spex ) - target_link_libraries ( spex_demo_lu_extended PUBLIC spex ) - target_link_libraries ( spex_demo_lu_simple1 PUBLIC spex ) - target_link_libraries ( spex_demo_lu_simple2 PUBLIC spex ) - target_link_libraries ( spex_demo_threaded PUBLIC spex ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries ( spex_demo_backslash PUBLIC SPEX SuiteSparse::SuiteSparseConfig ${MPFR_LIBRARIES} ${GMP_LIBRARIES} SuiteSparse::AMD SuiteSparse::COLAMD ) + target_link_libraries ( spex_demo_cholesky_extended PUBLIC SPEX SuiteSparse::SuiteSparseConfig ${MPFR_LIBRARIES} ${GMP_LIBRARIES} SuiteSparse::AMD SuiteSparse::COLAMD ) + target_link_libraries ( spex_demo_cholesky_simple PUBLIC SPEX SuiteSparse::SuiteSparseConfig ${MPFR_LIBRARIES} ${GMP_LIBRARIES} SuiteSparse::AMD SuiteSparse::COLAMD ) + target_link_libraries ( spex_demo_lu_doub PUBLIC SPEX SuiteSparse::SuiteSparseConfig ${MPFR_LIBRARIES} ${GMP_LIBRARIES} SuiteSparse::AMD SuiteSparse::COLAMD ) + target_link_libraries ( spex_demo_lu_extended PUBLIC SPEX SuiteSparse::SuiteSparseConfig ${MPFR_LIBRARIES} ${GMP_LIBRARIES} SuiteSparse::AMD SuiteSparse::COLAMD ) + target_link_libraries ( spex_demo_lu_simple1 PUBLIC SPEX SuiteSparse::SuiteSparseConfig ${MPFR_LIBRARIES} ${GMP_LIBRARIES} SuiteSparse::AMD SuiteSparse::COLAMD ) + target_link_libraries ( spex_demo_lu_simple2 PUBLIC SPEX SuiteSparse::SuiteSparseConfig ${MPFR_LIBRARIES} ${GMP_LIBRARIES} SuiteSparse::AMD SuiteSparse::COLAMD ) + target_link_libraries ( spex_demo_threaded PUBLIC SPEX SuiteSparse::SuiteSparseConfig ${MPFR_LIBRARIES} ${GMP_LIBRARIES} SuiteSparse::AMD SuiteSparse::COLAMD ) + else ( ) + target_link_libraries ( spex_demo_backslash PUBLIC SPEX_static SuiteSparse::AMD_static SuiteSparse::COLAMD_static ) + target_link_libraries ( spex_demo_cholesky_extended PUBLIC SPEX_static SuiteSparse::AMD_static SuiteSparse::COLAMD_static ) + target_link_libraries ( spex_demo_cholesky_simple PUBLIC SPEX_static SuiteSparse::AMD_static SuiteSparse::COLAMD_static ) + target_link_libraries ( spex_demo_lu_doub PUBLIC SPEX_static SuiteSparse::AMD_static SuiteSparse::COLAMD_static ) + target_link_libraries ( spex_demo_lu_extended PUBLIC SPEX_static SuiteSparse::AMD_static SuiteSparse::COLAMD_static ) + target_link_libraries ( spex_demo_lu_simple1 PUBLIC SPEX_static SuiteSparse::AMD_static SuiteSparse::COLAMD_static ) + target_link_libraries ( spex_demo_lu_simple2 PUBLIC SPEX_static SuiteSparse::AMD_static SuiteSparse::COLAMD_static ) + target_link_libraries ( spex_demo_threaded PUBLIC SPEX_static SuiteSparse::AMD_static SuiteSparse::COLAMD_static ) + endif ( ) + + if ( SPEX_USE_OPENMP ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries ( spex_demo_threaded PUBLIC OpenMP::OpenMP_C ) + endif ( ) + if ( BUILD_STATIC_LIBS ) + target_link_libraries ( spex_demo_threaded PUBLIC OpenMP::OpenMP_C ) + endif ( ) + endif ( ) else ( ) @@ -269,50 +509,66 @@ endif ( ) # configure MATLAB and Tcov #------------------------------------------------------------------------------- -# get paths to libraries -get_filename_component ( GMP_PATH ${GMP_LIBRARY} DIRECTORY ) -get_filename_component ( SUITESPARSE_CONFIG_PATH ${SUITESPARSE_CONFIG_LIBRARY} DIRECTORY ) -get_filename_component ( COLAMD_PATH ${COLAMD_LIBRARY} DIRECTORY ) -get_filename_component ( AMD_PATH ${AMD_LIBRARY} DIRECTORY ) -get_filename_component ( MPFR_PATH ${MPFR_LIBRARY} DIRECTORY ) - -# message ( STATUS "suitesparseconfig path ${SUITESPARSE_CONFIG_PATH}" ) -# message ( STATUS "colamd path ${COLAMD_PATH}" ) -# message ( STATUS "amd path ${AMD_PATH}" ) -# message ( STATUS "gmp path ${GMP_PATH}" ) -# message ( STATUS "mpfr path ${MPFR_PATH}" ) - -# construct the -I list -get_target_property ( INCS spex INCLUDE_DIRECTORIES ) -list ( TRANSFORM INCS PREPEND " -I" ) -set ( SPEX_INC "" ) -foreach ( INC ${INCS} ) - string ( APPEND SPEX_INC " " ${INC} ) -endforeach ( ) -# message ( STATUS "Incs: ${SPEX_INC}" ) - -# construct the library list -set ( SPEX_LIB_SUFFIX "${CMAKE_SHARED_LIBRARY_SUFFIX}" ) -get_target_property ( LIBS spex LINK_LIBRARIES ) -string ( REPLACE "." "\\." LIBSUFFIX ${SPEX_LIB_SUFFIX} ) -set ( SPEX_LIBRARIES "" ) -foreach ( LIB_NAME ${LIBS} ) -# message ( STATUS "Lib: ${LIB_NAME}" ) - if ( LIB_NAME MATCHES ${LIBSUFFIX} ) -# message ( STATUS "has suffix" ) - string ( APPEND SPEX_LIBRARIES " " ${LIB_NAME} ) - else ( ) -# message ( STATUS "no suffix" ) - string ( APPEND SPEX_LIBRARIES " -l" ${LIB_NAME} ) - endif ( ) -endforeach ( ) -# message ( STATUS "Libs: ${SPEX_LIBRARIES}" ) - -configure_file ( "Config/spex_deps.m.in" - "${PROJECT_SOURCE_DIR}/MATLAB/spex_deps.m") +if ( BUILD_SHARED_LIBS AND NOT SUITESPARSE_ROOT_CMAKELISTS ) + + # get paths to libraries + get_filename_component ( GMP_PATH ${GMP_LIBRARY} DIRECTORY ) + get_filename_component ( SUITESPARSE_CONFIG_PATH ${SUITESPARSE_CONFIG_LIBRARY} DIRECTORY ) + get_filename_component ( COLAMD_PATH ${COLAMD_LIBRARY} DIRECTORY ) + get_filename_component ( AMD_PATH ${AMD_LIBRARY} DIRECTORY ) + get_filename_component ( MPFR_PATH ${MPFR_LIBRARY} DIRECTORY ) + + # message ( STATUS "suitesparseconfig path ${SUITESPARSE_CONFIG_PATH}" ) + # message ( STATUS "colamd path ${COLAMD_PATH}" ) + # message ( STATUS "amd path ${AMD_PATH}" ) + # message ( STATUS "gmp path ${GMP_PATH}" ) + # message ( STATUS "mpfr path ${MPFR_PATH}" ) + + # construct the -I list + get_target_property ( INCS SPEX INCLUDE_DIRECTORIES ) + list ( TRANSFORM INCS PREPEND " -I" ) + set ( SPEX_INCS "" ) + foreach ( INC ${INCS} ) + # message ( STATUS "check inc: ${INC}" ) + if ( NOT ${INC} MATCHES "TARGET_PROPERTY" ) + # message ( STATUS "add inc: ${INC}" ) + string ( APPEND SPEX_INCS " " ${INC} ) + endif ( ) + endforeach ( ) + # message ( STATUS "Incs: ${SPEX_INCS}" ) + + # construct the library list for Tcov/Makefile + set ( SPEX_LIB_SUFFIX "${CMAKE_SHARED_LIBRARY_SUFFIX}" ) + get_target_property ( LIBS SPEX LINK_LIBRARIES ) + string ( REPLACE "." "\\." LIBSUFFIX ${SPEX_LIB_SUFFIX} ) + set ( SPEX_LIBS "" ) + foreach ( LIB_NAME ${LIBS} ) + # message ( STATUS "Lib: ${LIB_NAME}" ) + if ( LIB_NAME MATCHES "::" ) + # do nothing + elseif ( LIB_NAME MATCHES ${LIBSUFFIX} ) + # message ( STATUS "has suffix" ) + string ( APPEND SPEX_LIBS " " ${LIB_NAME} ) + else ( ) + # message ( STATUS "no suffix" ) + string ( APPEND SPEX_LIBS " -l" ${LIB_NAME} ) + endif ( ) + endforeach ( ) + # message ( STATUS "Libs: ${SPEX_LIBS}" ) + + configure_file ( + "Config/spex_deps.m.in" + "${PROJECT_SOURCE_DIR}/MATLAB/spex_deps.m" + @ONLY + NEWLINE_STYLE LF ) + + configure_file ( + "Config/Tcov_Makefile.in" + "${PROJECT_SOURCE_DIR}/Tcov/Makefile" + @ONLY + NEWLINE_STYLE LF ) -configure_file ( "Config/Tcov_Makefile.in" - "${PROJECT_SOURCE_DIR}/Tcov/Makefile") +endif ( ) #------------------------------------------------------------------------------- # report status diff --git a/SPEX/Config/SPEX.h.in b/SPEX/Config/SPEX.h.in index 2961797b..cbdb791f 100644 --- a/SPEX/Config/SPEX.h.in +++ b/SPEX/Config/SPEX.h.in @@ -2,8 +2,8 @@ // SPEX/Include/SPEX.h: Include file for SPEX Library //------------------------------------------------------------------------------ -// SPEX: (c) 2019-2023, Chris Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -27,7 +27,7 @@ //------------------------------------------------------------------------------ // Unless otherwise noted all functions are authored by: // -// Christopher Lourenco, Jinhao Chen, +// Christopher Lourenco, Jinhao Chen, // Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis // @@ -66,8 +66,8 @@ // // See license.txt for license info. // -// This software is copyright by Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Erick Moreno-Centeno and Timothy A. Davis. +// This software is copyright by Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // @@ -95,13 +95,40 @@ #include #include #include -#include -#include -#include -#include +// #include +// #include +// #include +// #include #include "SuiteSparse_config.h" -#include "amd.h" -#include "colamd.h" + +//------------------------------------------------------------------------------ +// SPEX Version +//------------------------------------------------------------------------------ + +// Current version of the code +#define SPEX_DATE "@SPEX_DATE@" +#define SPEX_VERSION_STRING "@SPEX_VERSION_MAJOR@.@SPEX_VERSION_MINOR@.@SPEX_VERSION_SUB@" +#define SPEX_VERSION_MAJOR @SPEX_VERSION_MAJOR@ +#define SPEX_VERSION_MINOR @SPEX_VERSION_MINOR@ +#define SPEX_VERSION_SUB @SPEX_VERSION_SUB@ + +#define SPEX_VERSION_NUMBER(major,minor,sub) \ + (((major)*1000ULL + (minor))*1000ULL + (sub)) +#define SPEX_VERSION \ + SPEX_VERSION_NUMBER (SPEX_VERSION_MAJOR, \ + SPEX_VERSION_MINOR, \ + SPEX_VERSION_SUB) + +#define SPEX__VERSION SUITESPARSE__VERCODE(@SPEX_VERSION_MAJOR@,@SPEX_VERSION_MINOR@,@SPEX_VERSION_SUB@) +#if !defined (SUITESPARSE__VERSION) || \ + (SUITESPARSE__VERSION < SUITESPARSE__VERCODE(7,7,0)) +#error "SPEX @SPEX_VERSION_MAJOR@.@SPEX_VERSION_MINOR@.@SPEX_VERSION_SUB@ requires SuiteSparse_config 7.7.0 or later" +#endif + +#if defined ( __cplusplus ) +extern "C" +{ +#endif //------------------------------------------------------------------------------ // Error codes @@ -128,23 +155,9 @@ typedef enum SPEX_info ; //------------------------------------------------------------------------------ -// SPEX Version +// SPEX Version, continued //------------------------------------------------------------------------------ -// Current version of the code -#define SPEX_DATE "@SPEX_DATE@" -#define SPEX_VERSION_STRING "@SPEX_VERSION_MAJOR@.@SPEX_VERSION_MINOR@.@SPEX_VERSION_SUB@" -#define SPEX_VERSION_MAJOR @SPEX_VERSION_MAJOR@ -#define SPEX_VERSION_MINOR @SPEX_VERSION_MINOR@ -#define SPEX_VERSION_SUB @SPEX_VERSION_SUB@ - -#define SPEX_VERSION_NUMBER(major,minor,sub) \ - (((major)*1000ULL + (minor))*1000ULL + (sub)) -#define SPEX_VERSION \ - SPEX_VERSION_NUMBER (SPEX_VERSION_MAJOR, \ - SPEX_VERSION_MINOR, \ - SPEX_VERSION_SUB) - SPEX_info SPEX_version ( int version [3], // SPEX major, minor, and sub version @@ -166,6 +179,42 @@ SPEX_info SPEX_version #error "MPFR v4.0.2 or later is required." #endif +//------------------------------------------------------------------------------ +// SPEX_TRY: try a SPEX method and check for errors +//------------------------------------------------------------------------------ + +// In a robust application, the return values from each call to SPEX should be +// checked, and corrective action should be taken if an error occurs. The +// SPEX_TRY macros assist in this effort. +// +// SPEX is written in C, and so it cannot rely on the try/catch mechanism of +// C++. To accomplish a similar goal, we provide our mechanism. The SPEX_TRY +// macro calls a single SPEX method and then takes corrected action based on a +// user-defined macro SPEX_CATCH. + +#define SPEX_TRY(method) \ +{ \ + SPEX_info info = (method) ; \ + if (info != SPEX_OK) \ + { \ + SPEX_CATCH (info) ; \ + } \ +} + +// A typical example user application might #define SPEX_CATCH as follows. +// Suppose the user function needs to free some workspace and return to the +// caller if an error occurs: + +/* + #define SPEX_CATCH(info) \ + { \ + SPEX_matrix_free (&A, NULL) ; \ + fprintf (stderr, "SPEX failed: info %d, line %d, file %s\n", \ + info, __LINE__, __FILE__) ; \ + return (info) ; \ + } \ +*/ + //------------------------------------------------------------------------------ // Pivot scheme codes //------------------------------------------------------------------------------ @@ -339,7 +388,7 @@ SPEX_type ; // A->x. For example, if A->p_shallow is true, then a non-NULL A->p is a // pointer to a read-only array, and the A->p array is not freed by // SPEX_matrix_free. If A->p is NULL (for a triplet or dense matrix), then -// A->p_shallow has no effect. +// A->p_shallow has no effect. typedef struct { @@ -405,6 +454,20 @@ typedef struct // A SPEX_matrix is a pointer to a SPEX_matrix_struct typedef SPEX_matrix_struct *SPEX_matrix ; +//------------------------------------------------------------------------------ +// SPEX_matrix macros +//------------------------------------------------------------------------------ + +// These macros simplify the access to entries in a SPEX_matrix. +// The type parameter is one of: mpq, mpz, mpfr, int64, or fp64. + +// To access the kth entry in a SPEX_matrix using 1D linear addressing, +// in any matrix kind (CSC, triplet, or dense), in any type: +#define SPEX_1D(A,k,type) ((A)->x.type [k]) + +// To access the (i,j)th entry in a 2D dense SPEX_matrix, in any type: +#define SPEX_2D(A,i,j,type) SPEX_1D (A, (i)+(j)*((A)->m), type) + //------------------------------------------------------------------------------ // SPEX_matrix_allocate: allocate an m-by-n SPEX_matrix //------------------------------------------------------------------------------ @@ -487,7 +550,7 @@ SPEX_info SPEX_matrix_check // returns a SPEX status code // SPEX_matrix_copy: make a copy of a SPEX_matrix, into another kind and type. // SPEX supports 16 matrix formats: 15 of them are all combinations of -// (CSC, triplet, dense) x (mpz, mpq, mpfr, int64, double). +// (CSC, triplet, dense) x (mpz, mpq, mpfr, int64, double). SPEX_info SPEX_matrix_copy ( @@ -792,8 +855,6 @@ SPEX_info SPEX_determine_symmetry const SPEX_options option // Command options ) ; -// ended HERE on Apr 10. - //------------------------------------------------------------------------------ //---------------------------SPEX GMP/MPFR Functions---------------------------- //------------------------------------------------------------------------------ @@ -915,6 +976,8 @@ SPEX_info SPEX_mpq_equal (int *r, const mpq_t x, const mpq_t y) ; SPEX_info SPEX_mpfr_init2(mpfr_t x, const uint64_t size) ; +SPEX_info SPEX_mpfr_set_prec(mpfr_t x, const uint64_t size) ; + SPEX_info SPEX_mpfr_set (mpfr_t x, const mpfr_t y, const mpfr_rnd_t rnd) ; SPEX_info SPEX_mpfr_set_d (mpfr_t x, const double y, const mpfr_rnd_t rnd) ; @@ -951,6 +1014,13 @@ SPEX_info SPEX_mpfr_free_cache (void) ; SPEX_info SPEX_mpfr_free_str (char *str) ; +SPEX_info SPEX_mpz_set_null (mpz_t x) ; +SPEX_info SPEX_mpq_set_null (mpq_t x) ; +SPEX_info SPEX_mpfr_set_null (mpfr_t x) ; +SPEX_info SPEX_mpz_clear (mpz_t x) ; +SPEX_info SPEX_mpq_clear (mpq_t x) ; +SPEX_info SPEX_mpfr_clear (mpfr_t x) ; + //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ @@ -964,7 +1034,7 @@ SPEX_info SPEX_mpfr_free_str (char *str) ; // "Algorithm 1021: SPEX Left LU, Exactly Solving Sparse Linear Systems via // a Sparse Left-looking Integer-preserving LU Factorization", -// C. Lourenco, J. Chen, E. Moreno-Centeno, T. Davis, +// C. Lourenco, J. Chen, E. Moreno-Centeno, T. Davis, // ACM Trans. Mathematical Software. pp 1-23, vol 48, no 2, 2022. // The theory associated with this software can be found in the paper @@ -990,7 +1060,7 @@ SPEX_info SPEX_mpfr_free_str (char *str) ; //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -// Christopher Lourenco, Jinhao Chen, Timothy A. Davis, and Erick Moreno-Centeno +// Christopher Lourenco, Jinhao Chen, Erick Moreno-Centeno, and Timothy A. Davis //------------------------------------------------------------------------------ @@ -1141,7 +1211,7 @@ SPEX_info SPEX_lu_solve // solves the linear system LD^(-1)U x = b //------------------------------------------------------------------------------ // Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. //------------------------------------------------------------------------------ @@ -1299,5 +1369,9 @@ SPEX_info SPEX_backslash SPEX_options option // Command options (NULL: means use defaults) ) ; +#if defined ( __cplusplus ) +} +#endif + #endif diff --git a/SPEX/Config/SPEX.pc.in b/SPEX/Config/SPEX.pc.in new file mode 100644 index 00000000..2f347cfa --- /dev/null +++ b/SPEX/Config/SPEX.pc.in @@ -0,0 +1,18 @@ +# SPEX, Copyright (c) 2019-2024, Chris Lourenco (US Naval Academy), Jinhao Chen +# Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis, Texas A&M. +# All Rights Reserved. +# SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: SPEX +URL: https://github.com/DrTimothyAldenDavis/SuiteSparse +Description: Software package for SParse EXact algebra in SuiteSparse +Version: @SPEX_VERSION_MAJOR@.@SPEX_VERSION_MINOR@.@SPEX_VERSION_SUB@ +Requires.private: SuiteSparse_config AMD COLAMD +Libs: -L${libdir} -l@SUITESPARSE_LIB_BASE_NAME@ +Libs.private: @SPEX_STATIC_LIBS@ +Cflags: -I${includedir} diff --git a/SPEX/Config/SPEXConfig.cmake.in b/SPEX/Config/SPEXConfig.cmake.in new file mode 100644 index 00000000..d61890d6 --- /dev/null +++ b/SPEX/Config/SPEXConfig.cmake.in @@ -0,0 +1,190 @@ +#------------------------------------------------------------------------------- +# SuiteSparse/SPEX/cmake_modules/SPEXConfig.cmake +#------------------------------------------------------------------------------- + +# SPEX, Copyright (c) 2019-2024, Chris Lourenco (US Naval Academy), Jinhao Chen +# Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis, Texas A&M. +# All Rights Reserved. +# SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later + +#------------------------------------------------------------------------------- + +# Finds the SPEX include file and compiled library. +# The following targets are defined: +# SuiteSparse::SPEX - for the shared library (if available) +# SuiteSparse::SPEX_static - for the static library (if available) + +# For backward compatibility the following variables are set: + +# SPEX_INCLUDE_DIR - where to find SPEX.h +# SPEX_LIBRARY - dynamic SPEX library +# SPEX_STATIC - static SPEX library +# SPEX_LIBRARIES - libraries when using SPEX +# SPEX_FOUND - true if SPEX found + +# Set ``CMAKE_MODULE_PATH`` to the parent folder where this module file is +# installed. + +#------------------------------------------------------------------------------- + +@PACKAGE_INIT@ + +set ( SPEX_DATE "@SPEX_DATE@" ) +set ( SPEX_VERSION_MAJOR @SPEX_VERSION_MAJOR@ ) +set ( SPEX_VERSION_MINOR @SPEX_VERSION_MINOR@ ) +set ( SPEX_VERSION_PATCH @SPEX_VERSION_SUB@ ) +set ( SPEX_VERSION "@SPEX_VERSION_MAJOR@.@SPEX_VERSION_MINOR@.@SPEX_VERSION_SUB@" ) + +# Check for dependent targets +include ( CMakeFindDependencyMacro ) + +# Look for SuiteSparse_config, AMD and COLAMD targets +if ( @SUITESPARSE_IN_BUILD_TREE@ ) + if ( NOT TARGET SuiteSparse::SuiteSparseConfig ) + # First check in a common build tree + find_dependency ( SuiteSparse_config @SUITESPARSE_CONFIG_VERSION_MAJOR@.@SUITESPARSE_CONFIG_VERSION_MINOR@ + PATHS ${CMAKE_SOURCE_DIR}/../SuiteSparse_config/build NO_DEFAULT_PATH ) + # Then, check in the currently active CMAKE_MODULE_PATH + if ( NOT SuiteSparse_config_FOUND ) + find_dependency ( SuiteSparse_config @SUITESPARSE_CONFIG_VERSION_MAJOR@.@SUITESPARSE_CONFIG_VERSION_MINOR@ ) + endif ( ) + endif ( ) + + if ( NOT TARGET SuiteSparse::AMD ) + # First check in a common build tree + find_dependency ( AMD @AMD_VERSION_MAJOR@.@AMD_VERSION_MINOR@ + PATHS ${CMAKE_SOURCE_DIR}/../AMD/build NO_DEFAULT_PATH ) + # Then, check in the currently active CMAKE_MODULE_PATH + if ( NOT AMD_FOUND ) + find_dependency ( AMD @AMD_VERSION_MAJOR@.@AMD_VERSION_MINOR@ ) + endif ( ) + endif ( ) + + if ( NOT TARGET SuiteSparse::COLAMD ) + # First check in a common build tree + find_dependency ( COLAMD @COLAMD_VERSION_MAJOR@.@COLAMD_VERSION_MINOR@ + PATHS ${CMAKE_SOURCE_DIR}/../COLAMD/build NO_DEFAULT_PATH ) + # Then, check in the currently active CMAKE_MODULE_PATH + if ( NOT COLAMD_FOUND ) + find_dependency ( COLAMD @COLAMD_VERSION_MAJOR@.@COLAMD_VERSION_MINOR@ ) + endif ( ) + endif ( ) + +else ( ) + if ( NOT TARGET SuiteSparse::SuiteSparseConfig ) + find_dependency ( SuiteSparse_config @SUITESPARSE_CONFIG_VERSION_MAJOR@.@SUITESPARSE_CONFIG_VERSION_MINOR@ ) + endif ( ) + if ( NOT TARGET SuiteSparse::AMD ) + find_dependency ( AMD @AMD_VERSION_MAJOR@.@AMD_VERSION_MINOR@ ) + endif ( ) + if ( NOT TARGET SuiteSparse::COLAMD ) + find_dependency ( COLAMD @COLAMD_VERSION_MAJOR@.@COLAMD_VERSION_MINOR@ ) + endif ( ) +endif ( ) + +# Look for GMP and MPFR modules +list ( PREPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR} ) +if ( NOT GMP_FOUND ) + find_dependency ( GMP 6.1.2 ) +endif ( ) +if ( NOT MPFR_FOUND ) + find_dependency ( MPFR 4.0.2 ) +endif ( ) + +if ( NOT SuiteSparse_config_FOUND OR NOT AMD_FOUND OR NOT COLAMD_FOUND + OR NOT GMP_FOUND OR NOT MPFR_FOUND) + set ( SPEX_FOUND OFF ) + return ( ) +endif ( ) + + +# Import target +include ( ${CMAKE_CURRENT_LIST_DIR}/SPEXTargets.cmake ) + +# The following is only for backward compatibility with FindSPEX. + +set ( _target_shared SuiteSparse::SPEX ) +set ( _target_static SuiteSparse::SPEX_static ) +set ( _var_prefix "SPEX" ) + +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 ( ) + +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 ( SPEX_LIBRARIES ${SPEX_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 ( SPEX_INCLUDE_DIR ${SPEX_INCLUDE_DIR} ) +suitesparse_check_exist ( SPEX_LIBRARY ${SPEX_LIBRARY} ) + +message ( STATUS "SPEX version: ${SPEX_VERSION}" ) +message ( STATUS "SPEX include: ${SPEX_INCLUDE_DIR}" ) +message ( STATUS "SPEX library: ${SPEX_LIBRARY}" ) +message ( STATUS "SPEX static: ${SPEX_STATIC}" ) diff --git a/SPEX/Config/Tcov_Makefile.in b/SPEX/Config/Tcov_Makefile.in index cd861fb2..450815fe 100644 --- a/SPEX/Config/Tcov_Makefile.in +++ b/SPEX/Config/Tcov_Makefile.in @@ -2,8 +2,8 @@ # SPEX/Tcov/Makefile: compile and run SPEX test coverage #------------------------------------------------------------------------------- -# SPEX: (c) 2019-2023, Chris Lourenco, Jinhao Chen, -# Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +# SPEX: (c) 2019-2024, Chris Lourenco, Jinhao Chen, +# Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. # All Rights Reserved. # SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -16,8 +16,11 @@ SUITESPARSE ?= $(realpath $(CURDIR)/../..) ################################################################################ # configured by CMake: -INC = @SPEX_INC@ -LIBS = @SPEX_LIBRARIES@ +INC = @SPEX_INCS@ +LIBS = ../../SuiteSparse_config/build/libsuitesparseconfig.so \ + ../../AMD/build/libamd.so \ + ../../COLAMD/build/libcolamd.so \ + @SPEX_LIBS@ SUITESPARSE_CONFIG_PATH = @SUITESPARSE_CONFIG_PATH@ COLAMD_PATH = @COLAMD_PATH@ @@ -42,10 +45,13 @@ MPFR_PATH = @MPFR_PATH@ ################################################################################ -# select the thread-safety mechanism to test: none, openmp, or pthreads. +# select the thread-safety mechanism to test: none, openmp, etc +# none: # THREADS = +# opemp: # THREADS = -fopenmp - THREADS = -DSPEX_USE_PTHREADS -pthread +# __thread keyword (gcc and many compilers): + THREADS = -DHAVE_KEYWORD__THREAD # Linux test coverage (gcc is required for test coverage) CC = gcc @@ -60,7 +66,8 @@ CFLAGS = -g -fprofile-arcs -ftest-coverage \ cov: runtests ./covall -all: tcov_for_lu spex_demo_lu_extended tcov_for_cholesky tcov_for_lu2 +all: tcov_for_lu spex_demo_lu_extended tcov_for_cholesky tcov_for_lu2 \ + tcov_for_other #------------------------------------------------------------------------------- # compile .c file in this folder @@ -81,6 +88,9 @@ OBJ_Util = \ spex_create_mpfr_array.o \ spex_create_mpq_array.o \ spex_create_mpz_array.o \ + spex_free_mpfr_array.o \ + spex_free_mpq_array.o \ + spex_free_mpz_array.o \ spex_cumsum.o \ spex_expand_double_array.o \ spex_expand_mpfr_array.o \ @@ -106,8 +116,7 @@ OBJ_Util = \ SPEX_determine_symmetry.o \ SPEX_transpose.o \ spex_amd.o \ - spex_colamd.o \ - spex_create_mpq.o + spex_colamd.o $(OBJ_Util): ../Include/SPEX.h ../SPEX_Utilities/Source/spex_util_internal.h @@ -211,6 +220,9 @@ spex_demo_lu_extended: $(OBJ_Util) $(OBJ_LU) ../Demo/spex_demo_lu_extended.c $( tcov_for_cholesky: $(OBJ_Tcov) $(OBJ_Util) $(OBJ_Cholesky) tcov_for_cholesky.c simple_rand.c simple_rand.h $(DEMO_SRC) $(CC) $(LDFLAGS) $(CFLAGS) tcov_for_cholesky.c simple_rand.c $(DEMO_SRC) -o tcov_for_cholesky $(OBJ_Tcov) $(OBJ_Util) $(OBJ_Cholesky) $(LIBS) +tcov_for_other: $(OBJ_Tcov) $(OBJ_Util) $(OBJ_LU) tcov_for_other.c + $(CC) $(LDFLAGS) tcov_for_other.c $(CFLAGS) -o tcov_for_other $(OBJ_Tcov) $(OBJ_Util) $(OBJ_LU) $(LIBS) + #------------------------------------------------------------------------------- # run all statement coverage tests @@ -218,18 +230,19 @@ runtests: runtests4llu runtests4chol # only run test for SPEX_LU runtests4llu: all - - ./spex_demo_lu_extended p 2 q 1 f ../ExampleMats/10teams.mat.txt ../ExampleMats/10teams.rhs.txt > lu1.out - - ./spex_demo_lu_extended p 3 q 2 o 1 f ../ExampleMats/10teams.mat.txt ../ExampleMats/10teams.rhs.txt > lu2.out - - ./spex_demo_lu_extended p 4 q 3 o 1 f ../ExampleMats/test.mat.txt ../ExampleMats/test.rhs.txt > lu3.out - - ./spex_demo_lu_extended p 5 f ../ExampleMats/10teams.mat.txt ../ExampleMats/10teams.rhs.txt > lu4.out - - ./tcov_for_lu > test_for_lu.out - - ./tcov_for_lu 0 1 1 > lu5.out - - ./tcov_for_lu2 ../ExampleMats/Trefethen_500.mat.txt ../ExampleMats/Trefethen_500.rhs.txt > test_for_lu2.out + ./tcov_for_other + ./spex_demo_lu_extended q 1 f ../ExampleMats/10teams.mat.txt ../ExampleMats/10teams.rhs.txt > lu1.out + ./spex_demo_lu_extended q 2 o 1 f ../ExampleMats/10teams.mat.txt ../ExampleMats/10teams.rhs.txt > lu2.out + ./spex_demo_lu_extended q 3 o 1 f ../ExampleMats/test.mat.txt ../ExampleMats/test.rhs.txt > lu3.out + ./spex_demo_lu_extended f ../ExampleMats/10teams.mat.txt ../ExampleMats/10teams.rhs.txt > lu4.out + ./tcov_for_lu > test_for_lu.out + ./tcov_for_lu 0 1 1 > lu5.out + ./tcov_for_lu2 ../ExampleMats/Trefethen_500.mat.txt ../ExampleMats/Trefethen_500.rhs.txt > test_for_lu2.out # only run test for SPEX_Cholesky runtests4chol: all - - ./tcov_for_cholesky ../ExampleMats/mesh1e1.mat.txt ../ExampleMats/mesh1e1.rhs.txt > test_for_cholesky.out + ./tcov_for_cholesky ../ExampleMats/mesh1e1.mat.txt ../ExampleMats/mesh1e1.rhs.txt > test_for_cholesky.out #------------------------------------------------------------------------------- @@ -242,24 +255,28 @@ vtests: vtests4llu vtests4chol # run test for SPEX_LU with valgrind vtests4llu: all - - $(V) ./spex_demo_lu_extended p 2 q 0 f ../ExampleMats/10teams_mat.txt ../ExampleMats/10teams_v.txt > lu1.out - - $(V) ./spex_demo_lu_extended p 3 q 1 o 1 f ../ExampleMats/10teams_mat.txt ../ExampleMats/10teams_v.txt > lu2.out - - $(V) ./spex_demo_lu_extended p 4 q 2 o 1 f ../ExampleMats/test_mat.txt ../ExampleMats/test_rhs.txt > lu3.out - - $(V) ./spex_demo_lu_extended p 5 f ../ExampleMats/10teams_mat.txt ../ExampleMats/10teams_v.txt > lu4.out - - $(V) ./tcov_for_lu > test_for_lu.out - - $(V) ./tcov_for_lu 0 1 1 > lu5.out - + $(V) ./tcov_for_other + $(V) ./spex_demo_lu_extended q 1 f ../ExampleMats/10teams.mat.txt ../ExampleMats/10teams.rhs.txt > lu1.out + $(V) ./spex_demo_lu_extended q 2 o 1 f ../ExampleMats/10teams.mat.txt ../ExampleMats/10teams.rhs.txt > lu2.out + $(V) ./spex_demo_lu_extended q 3 o 1 f ../ExampleMats/test.mat.txt ../ExampleMats/test.rhs.txt > lu3.out + $(V) ./spex_demo_lu_extended f ../ExampleMats/10teams.mat.txt ../ExampleMats/10teams.rhs.txt > lu4.out + $(V) ./tcov_for_lu > test_for_lu.out + $(V) ./tcov_for_lu 0 1 1 > lu5.out + $(V) ./tcov_for_lu2 ../ExampleMats/Trefethen_500.mat.txt ../ExampleMats/Trefethen_500.rhs.txt > test_for_lu2.out + +vtest2: all + $(V) ./tcov_for_lu2 ../ExampleMats/Trefethen_500.mat.txt ../ExampleMats/Trefethen_500.rhs.txt > test_for_lu2.out # run test for SPEX_Cholesky with valgrind vtests4chol: all - - $(V) ./tcov_for_cholesky ../ExampleMats/872.mat.txt > test_for_cholesky.out + $(V) ./tcov_for_cholesky ../ExampleMats/mesh1e1.mat.txt ../ExampleMats/mesh1e1.rhs.txt > test_for_cholesky.out #------------------------------------------------------------------------------- # remove all files not in the original distribution, including symbolic links clean: - $(RM) *.o *.bbg *.da *.gcov *.gcda *gcno - - $(RM) tcov_for_lu spex_demo_lu_extended *.out *.a out tcov_for_lu2 + - $(RM) tcov_for_lu spex_demo_lu_extended *.out *.a out tcov_for_lu2 tcov_for_other - $(RM) -r SPEX_*.c spex_*.c *.dSYM - $(RM) -r tcov_for_cholesky diff --git a/SPEX/Config/spex_deps.m.in b/SPEX/Config/spex_deps.m.in index f9953068..73e347c8 100644 --- a/SPEX/Config/spex_deps.m.in +++ b/SPEX/Config/spex_deps.m.in @@ -6,15 +6,15 @@ function [suitesparse_libdir, suitesparse_incdir, gmp_lib, gmp_include, mpfr_lib % On Linux you may need to add the following to your shell script (typically % .bashrc), start a new shell, and then start MATLAB again. % -% LD_LIBRARY_PATH=$LD_LIBRARY_PATH:@SUITESPARSE_LIBDIR@ +% LD_LIBRARY_PATH=$LD_LIBRARY_PATH:@matlab_libdir@ -% SPEX: (c) 2022-2023, Chris Lourenco, Jinhao Chen, -% Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +% SPEX: (c) 2022-2024, Chris Lourenco, Jinhao Chen, +% Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. % All Rights Reserved. % SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later -suitesparse_libdir = '@SUITESPARSE_LIBDIR@' ; -suitesparse_incdir = '@SUITESPARSE_INCLUDEDIR@' ; +suitesparse_libdir = '@matlab_libdir@' ; +suitesparse_incdir = '@matlab_includedir@' ; gmp_lib = '@GMP_LIBRARY@' ; gmp_include = '@GMP_INCLUDE_DIR@' ; mpfr_lib = '@MPFR_LIBRARY@' ; diff --git a/SPEX/Demo/Utilities/spex_demo_check_solution.c b/SPEX/Demo/Utilities/spex_demo_check_solution.c index 9e2a8c8a..adaf402b 100644 --- a/SPEX/Demo/Utilities/spex_demo_check_solution.c +++ b/SPEX/Demo/Utilities/spex_demo_check_solution.c @@ -2,25 +2,23 @@ // Demo/spex_check_solution: checks whether a given vector exactly solves Ax=b //------------------------------------------------------------------------------ -// SPEX: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ - #include "spex_demos.h" #undef FREE_WORKSPACE #define FREE_WORKSPACE \ { \ - SPEX_MPQ_CLEAR(temp); \ - SPEX_MPQ_CLEAR(scale); \ + SPEX_mpq_clear (temp) ; \ + SPEX_mpq_clear (scale) ; \ SPEX_matrix_free(&b2, NULL); \ } - SPEX_info spex_demo_check_solution ( const SPEX_matrix A, // Input matrix @@ -29,34 +27,30 @@ SPEX_info spex_demo_check_solution const SPEX_options option // Command options ) { - if (!SPEX_initialize ( )) return (SPEX_PANIC); - - //-------------------------------------------------------------------------- - // check inputs. Input are also checked by the two callers - //-------------------------------------------------------------------------- - - SPEX_info info ; - /*SPEX_REQUIRE (A, SPEX_CSC, SPEX_MPZ); - SPEX_REQUIRE (x, SPEX_DENSE, SPEX_MPQ); - SPEX_REQUIRE (b, SPEX_DENSE, SPEX_MPZ);*/ //-------------------------------------------------------------------------- // Declare vars //-------------------------------------------------------------------------- + mpq_t temp; + mpq_t scale; int64_t p, j, i, nz; SPEX_matrix b2 = NULL; // b2 stores the solution of A*x - mpq_t temp; SPEX_MPQ_SET_NULL(temp); - mpq_t scale; SPEX_MPQ_SET_NULL(scale); + int r; + SPEX_mpq_set_null (temp) ; + SPEX_mpq_set_null (scale) ; - SPEX_MPQ_INIT(temp); - SPEX_MPQ_INIT(scale); - SPEX_CHECK (SPEX_matrix_allocate(&b2, SPEX_DENSE, SPEX_MPQ, b->m, b->n, - b->nzmax, false, true, option)); + //-------------------------------------------------------------------------- + // initialize + //-------------------------------------------------------------------------- + SPEX_TRY (SPEX_mpq_init(temp)); + SPEX_TRY (SPEX_mpq_init(scale)); + SPEX_TRY (SPEX_matrix_allocate(&b2, SPEX_DENSE, SPEX_MPQ, b->m, b->n, + b->nzmax, false, true, option)); //-------------------------------------------------------------------------- - // perform SPEX_mpq_addmul in loops to compute b2 = A'*x, where A' is the + // perform SPEX_mpq_add,mul in loops to compute b2 = A'*x, where A' is the // scaled matrix with all entries in integer //-------------------------------------------------------------------------- @@ -68,15 +62,15 @@ SPEX_info spex_demo_check_solution { // temp = A[p][i] (note this must be done seperately since A is // mpz and temp is mpq) - SPEX_MPQ_SET_Z(temp, A->x.mpz[p]); + SPEX_TRY (SPEX_mpq_set_z(temp, A->x.mpz[p])); // temp = temp*x[i] - SPEX_MPQ_MUL(temp, temp, - SPEX_2D(x, i, j, mpq)); + SPEX_TRY (SPEX_mpq_mul(temp, temp, + SPEX_2D(x, i, j, mpq))); // b2[p] = b2[p]-temp - SPEX_MPQ_ADD(SPEX_2D(b2, A->i[p], j, mpq), - SPEX_2D(b2, A->i[p], j, mpq),temp); + SPEX_TRY (SPEX_mpq_add(SPEX_2D(b2, A->i[p], j, mpq), + SPEX_2D(b2, A->i[p], j, mpq),temp)); } } } @@ -85,17 +79,16 @@ SPEX_info spex_demo_check_solution // Apply scales of A and b to b2 before comparing the b2 with scaled b' //-------------------------------------------------------------------------- - SPEX_MPQ_DIV(scale, b->scale, A->scale); + SPEX_TRY (SPEX_mpq_div(scale, b->scale, A->scale)); // Apply scaling factor, but ONLY if it is not 1 - int r; - SPEX_MPQ_CMP_UI(&r, scale, 1, 1); + SPEX_TRY (SPEX_mpq_cmp_ui(&r, scale, 1, 1)); if (r != 0) { nz = x->m * x->n; for (i = 0; i < nz; i++) { - SPEX_MPQ_MUL(b2->x.mpq[i], b2->x.mpq[i], scale); + SPEX_TRY (SPEX_mpq_mul(b2->x.mpq[i], b2->x.mpq[i], scale)); } } @@ -108,40 +101,25 @@ SPEX_info spex_demo_check_solution for (i = 0; i < b->m; i++) { // temp = b[i] (correct b) - SPEX_MPQ_SET_Z(temp, SPEX_2D(b, i, j, mpz)); + SPEX_TRY (SPEX_mpq_set_z(temp, SPEX_2D(b, i, j, mpz))); // set check false if b!=b2 - SPEX_MPQ_EQUAL(&r, temp, SPEX_2D(b2, i, j, mpq)); + SPEX_TRY (SPEX_mpq_equal(&r, temp, SPEX_2D(b2, i, j, mpq))); if (r == 0) { - //printf("ERROR\n"); - info = SPEX_PANIC; - j = b->n; - break; + // This can "never" happen. + fprintf (stderr, "ERROR! Solution is wrong. This is a bug;" + "please contact the authors of SPEX.\n"); + SPEX_TRY (SPEX_PANIC) ; } } } - //-------------------------------------------------------------------------- - // Print info - //-------------------------------------------------------------------------- - - int pr = SPEX_OPTION_PRINT_LEVEL (option); - if (info == SPEX_OK) - { - SPEX_PR1 ("Solution is verified to be exact.\n"); - } - else if (info == SPEX_PANIC) - { - // This can never happen. - SPEX_PR1 ("ERROR! Solution is wrong. This is a bug; please " - "contact the authors of SPEX.\n"); - } - //-------------------------------------------------------------------------- // Free memory //-------------------------------------------------------------------------- FREE_WORKSPACE ; - return info; + return SPEX_OK ; } + diff --git a/SPEX/Demo/Utilities/spex_demo_determine_error.c b/SPEX/Demo/Utilities/spex_demo_determine_error.c index 3cc1d980..d11d518c 100644 --- a/SPEX/Demo/Utilities/spex_demo_determine_error.c +++ b/SPEX/Demo/Utilities/spex_demo_determine_error.c @@ -1,9 +1,9 @@ //------------------------------------------------------------------------------ -// Demo/spex_determine_error: auxiliary file for test coverage (tcov) +// Demo/spex_determine_error: auxiliary file for user demos //------------------------------------------------------------------------------ -// SPEX: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -14,22 +14,24 @@ #include "spex_demos.h" - void spex_demo_determine_error ( - SPEX_info ok + SPEX_info info, + int line, + char *file ) { - if (ok == SPEX_OUT_OF_MEMORY) + if (info == SPEX_OUT_OF_MEMORY) { - printf("\nOut of memory\n"); + printf("\nSPEX: Out of memory\n"); } - else if (ok == SPEX_SINGULAR) + else if (info == SPEX_SINGULAR) { - printf("\nInput matrix is singular OR no diagonal pivot. Please ensure input is SPD\n"); + printf("\nSPEX: Input matrix is singular OR no diagonal pivot. Please ensure input is SPD\n"); } - else if (ok == SPEX_INCORRECT_INPUT) + else if (info == SPEX_INCORRECT_INPUT) { - printf("\nIncorrect input for a SPEX_Chol Function\n"); + printf("\nSPEX: Incorrect input for a SPEX_Chol Function\n"); } + printf ("line %d, file: %s\n", line, file) ; } diff --git a/SPEX/Demo/Utilities/spex_demo_process_command_line.c b/SPEX/Demo/Utilities/spex_demo_process_command_line.c index c05bcf25..84b8de43 100644 --- a/SPEX/Demo/Utilities/spex_demo_process_command_line.c +++ b/SPEX/Demo/Utilities/spex_demo_process_command_line.c @@ -2,8 +2,8 @@ // Demo/spex_process_command_line: processes command line for user specified options //------------------------------------------------------------------------------ -// SPEX: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/Demo/Utilities/spex_demo_read_dense.c b/SPEX/Demo/Utilities/spex_demo_read_dense.c index 19faff8a..2bd6d59c 100644 --- a/SPEX/Demo/Utilities/spex_demo_read_dense.c +++ b/SPEX/Demo/Utilities/spex_demo_read_dense.c @@ -2,8 +2,8 @@ // Demo/spex_read_dense: reads an integral dense matrix //------------------------------------------------------------------------------ -// SPEX: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/Demo/Utilities/spex_demo_tripread.c b/SPEX/Demo/Utilities/spex_demo_tripread.c index eb8bd8cd..363937e0 100644 --- a/SPEX/Demo/Utilities/spex_demo_tripread.c +++ b/SPEX/Demo/Utilities/spex_demo_tripread.c @@ -2,8 +2,8 @@ // Demo/spex_demo_tripread: reads a matrix stored in triplet format of a given type //------------------------------------------------------------------------------ -// SPEX: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -27,13 +27,16 @@ SPEX_info spex_demo_tripread ( SPEX_matrix *A_handle, // Matrix to be populated FILE *file, // file to read from (must already be open) - SPEX_type C_type, // C->type: mpz_t or double + SPEX_type C_type, // C->type: mpz_t or double SPEX_options option ) { SPEX_info info ; - ASSERT(A_handle!=NULL); - ASSERT(file!=NULL); + + if (A_handle == NULL || file == NULL) + { + return (SPEX_INCORRECT_INPUT) ; + } (*A_handle) = NULL ; diff --git a/SPEX/Demo/spex_demo_backslash.c b/SPEX/Demo/spex_demo_backslash.c index 50c3165b..59e0ea70 100644 --- a/SPEX/Demo/spex_demo_backslash.c +++ b/SPEX/Demo/spex_demo_backslash.c @@ -2,21 +2,29 @@ // Demo/spex_demo_backslash: example of SPEX_Blackslash //------------------------------------------------------------------------------ -// SPEX: (c) 2021-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2021-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ - -/* A demo of SPEX_Backslash in C - */ +// A demo of SPEX_Backslash in C # include "spex_demos.h" #define FREE_WORKSPACE \ { \ + if (mat_file != NULL) \ + { \ + fclose(mat_file); \ + } \ + mat_file = NULL ; \ + if (rhs_file != NULL) \ + { \ + fclose(rhs_file); \ + } \ + rhs_file = NULL ; \ SPEX_matrix_free(&A,NULL); \ SPEX_matrix_free(&b,NULL); \ SPEX_matrix_free(&x,NULL); \ @@ -25,35 +33,32 @@ SPEX_finalize(); \ } \ - int main( int argc, char *argv[] ) { - //-------------------------------------------------------------------------- - // Prior to using SPEX, its environment must be initialized. This is done - // by calling the SPEX_initialize() function. - //-------------------------------------------------------------------------- - SPEX_initialize(); - - //-------------------------------------------------------------------------- - // Declare memory & Process Command Line - //-------------------------------------------------------------------------- - int64_t n = 0, ok; - + int64_t n = 0 ; SPEX_matrix A = NULL; SPEX_matrix b = NULL; SPEX_matrix x = NULL; SPEX_matrix x2 = NULL; - - // Set default options + FILE *mat_file = NULL ; + FILE *rhs_file = NULL ; SPEX_options option = NULL; - DEMO_OK(SPEX_create_default_options(&option)); - char *mat_name = NULL, *rhs_name = NULL; int64_t rat = 1; + //-------------------------------------------------------------------------- + // Prior to using SPEX, its environment must be initialized. This is done + // by calling the SPEX_initialize() function. + //-------------------------------------------------------------------------- + + SPEX_TRY (SPEX_initialize ( )) ; + + // Set default options + SPEX_TRY (SPEX_create_default_options(&option)); + // Process the command line - DEMO_OK(spex_demo_process_command_line(argc, argv, option, + SPEX_TRY (spex_demo_process_command_line(argc, argv, option, &mat_name, &rhs_name, &rat)); //-------------------------------------------------------------------------- @@ -61,31 +66,33 @@ int main( int argc, char *argv[] ) //-------------------------------------------------------------------------- // Read in A - FILE *mat_file = fopen(mat_name,"r"); + mat_file = fopen(mat_name,"r"); if( mat_file == NULL ) { perror("Error while opening the file"); FREE_WORKSPACE; - return 0; + return (1) ; } // Note, there are a few matrices in BasisLIB that dont fit in double // Need to use the other tripread for those. - DEMO_OK(spex_demo_tripread(&A, mat_file, SPEX_MPZ, option)); + SPEX_TRY (spex_demo_tripread(&A, mat_file, SPEX_MPZ, option)); fclose(mat_file); + mat_file = NULL ; n = A->n; // Read in b. The output of this demo function is b in dense format with // mpz_t entries - FILE *rhs_file = fopen(rhs_name,"r"); + rhs_file = fopen(rhs_name,"r"); if( rhs_file == NULL ) { perror("Error while opening the file"); FREE_WORKSPACE; - return 0; + return (1) ; } - DEMO_OK(spex_demo_read_dense(&b, rhs_file, option)); + SPEX_TRY (spex_demo_read_dense(&b, rhs_file, option)); fclose(rhs_file); + rhs_file = NULL ; //-------------------------------------------------------------------------- // Solve Ax = b @@ -94,30 +101,31 @@ int main( int argc, char *argv[] ) printf("solving Ax=b ...\n"); fflush (stdout); fflush (stderr); - clock_t start = clock(); + double start = SuiteSparse_time (); option->print_level = 0; - DEMO_OK( SPEX_backslash(&x, SPEX_MPQ, A, b, option)); + SPEX_TRY ( SPEX_backslash(&x, SPEX_MPQ, A, b, option)); - clock_t end = clock(); + double end = SuiteSparse_time (); - double t_tot = (double) (end - start) / CLOCKS_PER_SEC; + double t_tot = (end - start) ; printf("\nSPEX Backslash Factor & Solve time: %lf\n", t_tot); option->print_level=1; - DEMO_OK( spex_demo_check_solution(A,x,b,option)); + SPEX_TRY ( spex_demo_check_solution(A,x,b,option)); // x2 is a copy of the solution. x2 is a dense matrix with double entries // Note: roundoff will have occured in converting the exact solution // to the double x. - DEMO_OK ( SPEX_matrix_copy(&x2, SPEX_DENSE, SPEX_FP64, x, option)); + SPEX_TRY ( SPEX_matrix_copy(&x2, SPEX_DENSE, SPEX_FP64, x, option)); //-------------------------------------------------------------------------- // Free Memory //-------------------------------------------------------------------------- FREE_WORKSPACE; + return (0) ; } diff --git a/SPEX/Demo/spex_demo_cholesky_extended.c b/SPEX/Demo/spex_demo_cholesky_extended.c index 742d7ccb..abe4595c 100644 --- a/SPEX/Demo/spex_demo_cholesky_extended.c +++ b/SPEX/Demo/spex_demo_cholesky_extended.c @@ -2,18 +2,27 @@ // Demo/spex_demo_cholesky_extended: example of extended call of SPEX_Cholesky //------------------------------------------------------------------------------ -// SPEX: (c) 2022-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ - #include "spex_demos.h" #define FREE_WORKSPACE \ { \ + if (mat_file != NULL) \ + { \ + fclose(mat_file); \ + } \ + mat_file = NULL ; \ + if (rhs_file != NULL) \ + { \ + fclose(rhs_file); \ + } \ + rhs_file = NULL ; \ SPEX_matrix_free(&A,NULL); \ SPEX_matrix_free(&b,NULL); \ SPEX_matrix_free(&x,NULL); \ @@ -26,33 +35,30 @@ int main( int argc, char *argv[] ) { - //-------------------------------------------------------------------------- - // Prior to using SPEX-Chol, its environment must be initialized. This is - // done by calling the SPEX_initialize() function. - //-------------------------------------------------------------------------- - - SPEX_initialize(); - - //-------------------------------------------------------------------------- - // Declare memory & Process Command Line - //-------------------------------------------------------------------------- - int64_t n = 0, ok; - + int64_t n = 0 ; SPEX_symbolic_analysis S = NULL; SPEX_factorization F = NULL ; SPEX_matrix A = NULL; SPEX_matrix b = NULL; SPEX_matrix x = NULL; - + FILE *mat_file = NULL ; + FILE *rhs_file = NULL; char *mat_name, *rhs_name; int64_t rat = 1; + SPEX_options option = NULL; + + //-------------------------------------------------------------------------- + // Prior to using SPEX-Chol, its environment must be initialized. This is + // done by calling the SPEX_initialize() function. + //-------------------------------------------------------------------------- + + SPEX_TRY (SPEX_initialize ( )) ; // Default options. - SPEX_options option = NULL; - DEMO_OK(SPEX_create_default_options(&option)); + SPEX_TRY (SPEX_create_default_options(&option)); // Process the command line - DEMO_OK(spex_demo_process_command_line(argc, argv, option, + SPEX_TRY (spex_demo_process_command_line(argc, argv, option, &mat_name, &rhs_name, &rat)); //-------------------------------------------------------------------------- @@ -60,93 +66,96 @@ int main( int argc, char *argv[] ) //-------------------------------------------------------------------------- // Read in A - FILE *mat_file = fopen(mat_name,"r"); + mat_file = fopen(mat_name,"r"); if( mat_file == NULL ) { perror("Error while opening the file"); FREE_WORKSPACE; - return 0; + return (1) ; } - DEMO_OK(spex_demo_tripread(&A, mat_file, SPEX_FP64, option)); + SPEX_TRY (spex_demo_tripread(&A, mat_file, SPEX_FP64, option)); fclose(mat_file); + mat_file = NULL ; n = A->n; // For this code, we utilize a vector of all ones as the RHS vector - SPEX_matrix_allocate(&b, SPEX_DENSE, SPEX_MPZ, n, 1, n, false, true, - option); + SPEX_TRY (SPEX_matrix_allocate(&b, SPEX_DENSE, SPEX_MPZ, n, 1, n, false, + true, option)); // Read in b. The output of this demo function is b in dense format with // mpz_t entries - FILE *rhs_file = fopen(rhs_name,"r"); + rhs_file = fopen(rhs_name,"r"); if( rhs_file == NULL ) { perror("Error while opening the file"); FREE_WORKSPACE; - return 0; + return (1) ; } - DEMO_OK(spex_demo_read_dense(&b, rhs_file, option)); + SPEX_TRY (spex_demo_read_dense(&b, rhs_file, option)); fclose(rhs_file); + rhs_file = NULL ; //-------------------------------------------------------------------------- // Perform Analysis of A //-------------------------------------------------------------------------- - clock_t start_col = clock(); + double start_col = SuiteSparse_time (); // Symmetric ordering of A. Uncomment the desired one, AMD is recommended //option->order = SPEX_NO_ORDERING; // No ordering option->order = SPEX_AMD; // AMD //option->order = SPEX_COLAMD; // COLAMD - DEMO_OK(SPEX_cholesky_analyze(&S, A, option)); + SPEX_TRY (SPEX_cholesky_analyze(&S, A, option)); - clock_t end_col = clock(); + double end_col = SuiteSparse_time (); //-------------------------------------------------------------------------- // Factorize PAP //-------------------------------------------------------------------------- //option->algo=SPEX_CHOL_LEFT; - clock_t start_factor = clock(); + double start_factor = SuiteSparse_time (); - DEMO_OK( SPEX_cholesky_factorize(&F, A, S, option)); + SPEX_TRY ( SPEX_cholesky_factorize(&F, A, S, option)); - clock_t end_factor = clock(); + double end_factor = SuiteSparse_time (); option->print_level=3; - //DEMO_OK(SPEX_matrix_check(F->L,option)); + //SPEX_TRY (SPEX_matrix_check(F->L,option)); //-------------------------------------------------------------------------- // Solve linear system //-------------------------------------------------------------------------- - clock_t start_solve = clock(); + double start_solve = SuiteSparse_time (); - DEMO_OK( SPEX_cholesky_solve(&x, F, b, option)); + SPEX_TRY ( SPEX_cholesky_solve(&x, F, b, option)); - clock_t end_solve = clock(); + double end_solve = SuiteSparse_time (); //-------------------------------------------------------------------------- // Output & Timing Stats //-------------------------------------------------------------------------- - double t_col = (double) (end_col-start_col)/CLOCKS_PER_SEC; - double t_factor = (double) (end_factor - start_factor) / CLOCKS_PER_SEC; - double t_solve = (double) (end_solve - start_solve) / CLOCKS_PER_SEC; + double t_col = (end_col-start_col) ; + double t_factor = (end_factor - start_factor) ; + double t_solve = (end_solve - start_solve) ; - printf("\nNumber of L nonzeros: \t\t\t%ld", - (F->L->p[F->L->n]) ); + printf("\nNumber of L nonzeros: \t\t\t%g", + (double) (F->L->p[F->L->n]) ); printf("\nSymbolic Analysis Check time: \t\t%lf", t_col); printf("\nIP Chol Factorization time: \t\t%lf", t_factor); printf("\nFB Substitution time: \t\t\t%lf\n\n", t_solve); // Check solution option->print_level=1; - //DEMO_OK ( SPEX_check_solution(A,x,b,option)); + // SPEX_TRY ( SPEX_check_solution(A,x,b,option)); //-------------------------------------------------------------------------- // Free Memory //-------------------------------------------------------------------------- FREE_WORKSPACE; + return (0) ; } diff --git a/SPEX/Demo/spex_demo_cholesky_simple.c b/SPEX/Demo/spex_demo_cholesky_simple.c index 5e35dc15..4652358e 100644 --- a/SPEX/Demo/spex_demo_cholesky_simple.c +++ b/SPEX/Demo/spex_demo_cholesky_simple.c @@ -2,47 +2,62 @@ // Demo/spex_demo_cholesky_simple.c: example of simple call of SPEX_Cholesky //------------------------------------------------------------------------------ -// SPEX: (c) 2022-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ -/* This example shows how to use SPEX Chol with a given input matrix and a - * double output. The input is read from a file */ - -// usage: -// example > out -// out is file for output calculated result +// This example shows how to use SPEX Chol with a given input matrix and a +// double output. The input is read from a file. #include "spex_demos.h" -#define FREE_WORKSPACE \ -{ \ - SPEX_matrix_free(&A, option); \ - SPEX_matrix_free(&b, option); \ - SPEX_matrix_free(&x, option); \ - SPEX_matrix_free(&x2, option); \ - SPEX_FREE(option); \ - SPEX_finalize(); \ +#define FREE_WORKSPACE \ +{ \ + if (mat_file != NULL) \ + { \ + fclose(mat_file); \ + } \ + mat_file = NULL ; \ + if (rhs_file != NULL) \ + { \ + fclose(rhs_file); \ + } \ + rhs_file = NULL ; \ + SPEX_matrix_free(&A, option); \ + SPEX_matrix_free(&b, option); \ + SPEX_matrix_free(&x, option); \ + SPEX_matrix_free(&x2, option); \ + SPEX_FREE(option); \ + SPEX_finalize(); \ } - int main (int argc, char **argv) { + + SPEX_matrix A = NULL ; // input matrix with mpz values + SPEX_matrix b = NULL ; // Right hand side vector + SPEX_matrix x = NULL ; // Solution vectors + SPEX_matrix x2 = NULL ; // copy of solution vectors + SPEX_options option = NULL; + FILE *mat_file = NULL; + FILE *rhs_file = NULL; + char *mat_name = NULL ; + char *rhs_name = NULL ; + //-------------------------------------------------------------------------- - // Prior to using SPEX Chol, its environment must be initialized. This is + // Prior to using SPEX, its environment must be initialized. This is // done by calling the SPEX_initialize() function. //-------------------------------------------------------------------------- - SPEX_initialize(); + + SPEX_TRY (SPEX_initialize ( )) ; //-------------------------------------------------------------------------- // Get matrix file name //-------------------------------------------------------------------------- - char *mat_name; - char *rhs_name; //this is actually ignored and we're using a rhs of 1s int64_t rat = 1; if (argc > 2) { @@ -50,25 +65,20 @@ int main (int argc, char **argv) } //-------------------------------------------------------------------------- - // Declare our data structures + // Get options and process the command line //-------------------------------------------------------------------------- - SPEX_info ok; - SPEX_matrix A = NULL ; // input matrix with mpz values - SPEX_matrix b = NULL ; // Right hand side vector - SPEX_matrix x = NULL ; // Solution vectors - SPEX_matrix x2 = NULL ; // copy of solution vectors - SPEX_options option = NULL; - DEMO_OK(SPEX_create_default_options(&option)); + + SPEX_TRY (SPEX_create_default_options(&option)); if (option == NULL) { fprintf (stderr, "Error! OUT of MEMORY!\n"); FREE_WORKSPACE; - return 0; + return (1) ; } option->order = SPEX_AMD; //AMD is default for Cholesky - + // Process the command line - DEMO_OK(spex_demo_process_command_line(argc, argv, option, + SPEX_TRY (spex_demo_process_command_line(argc, argv, option, &mat_name, &rhs_name, &rat)); //-------------------------------------------------------------------------- @@ -77,32 +87,34 @@ int main (int argc, char **argv) // Read in A. The output of this demo function is A in CSC format with // double entries. - FILE *mat_file = fopen(mat_name,"r"); + mat_file = fopen(mat_name,"r"); if( mat_file == NULL ) { perror("Error while opening the file"); FREE_WORKSPACE; - return 0; + return (1) ; } - - DEMO_OK(spex_demo_tripread(&A, mat_file, SPEX_FP64, option)); + + SPEX_TRY (spex_demo_tripread(&A, mat_file, SPEX_FP64, option)); fclose(mat_file); + mat_file = NULL ; int64_t n = A->n; - SPEX_matrix_allocate(&b, SPEX_DENSE, SPEX_MPZ, n, 1, n, false, true, - option); + SPEX_TRY (SPEX_matrix_allocate(&b, SPEX_DENSE, SPEX_MPZ, n, 1, n, false, + true, option) ); // Read in b. The output of this demo function is b in dense format with // mpz_t entries - FILE *rhs_file = fopen(rhs_name,"r"); + rhs_file = fopen(rhs_name,"r"); if( rhs_file == NULL ) { perror("Error while opening the file"); FREE_WORKSPACE; - return 0; + return (1) ; } - DEMO_OK(spex_demo_read_dense(&b, rhs_file, option)); + SPEX_TRY (spex_demo_read_dense(&b, rhs_file, option)); fclose(rhs_file); + rhs_file = NULL; // Check if the size of A matches b if (A->n != b->m) @@ -110,36 +122,37 @@ int main (int argc, char **argv) printf("%"PRId64" %"PRId64" \n", A->m,b->m); fprintf (stderr, "Error! Size of A and b do not match!\n"); FREE_WORKSPACE; - return 0; + return (1) ; } + //-------------------------------------------------------------------------- // solve //-------------------------------------------------------------------------- - clock_t start_s = clock(); + + double start_s = SuiteSparse_time (); option->algo=SPEX_CHOL_LEFT; - DEMO_OK(SPEX_cholesky_backslash( &x, SPEX_MPQ, A, b, option)); + SPEX_TRY (SPEX_cholesky_backslash( &x, SPEX_MPQ, A, b, option)); - clock_t end_s = clock(); + double end_s = SuiteSparse_time (); - double t_s = (double) (end_s - start_s) / CLOCKS_PER_SEC; + double t_s = (end_s - start_s) ; printf("\nSPEX Chol Factor & Solve time: %lf\n", t_s); // x2 is a copy of the solution. x2 is a dense matrix with mpfr entries - DEMO_OK ( SPEX_matrix_copy(&x2, SPEX_DENSE, SPEX_FP64, x, option)); + SPEX_TRY ( SPEX_matrix_copy(&x2, SPEX_DENSE, SPEX_FP64, x, option)); // check solution option->print_level=1; - DEMO_OK ( spex_demo_check_solution(A,x,b,option)); + SPEX_TRY ( spex_demo_check_solution(A,x,b,option)); //-------------------------------------------------------------------------- // Free memory //-------------------------------------------------------------------------- - FREE_WORKSPACE; + FREE_WORKSPACE; printf ("\n%s: all tests passed\n\n", __FILE__); - - return 0; + return (0) ; } diff --git a/SPEX/Demo/spex_demo_lu_doub.c b/SPEX/Demo/spex_demo_lu_doub.c index 84856671..fbe973bd 100644 --- a/SPEX/Demo/spex_demo_lu_doub.c +++ b/SPEX/Demo/spex_demo_lu_doub.c @@ -2,31 +2,26 @@ // Demo/spex_demo_lu_doub.c: example of simple SPEX_LU call on a double matrix //------------------------------------------------------------------------------ -// SPEX: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ -/* This program will exactly solve the sparse linear system Ax = b by - * performing the SPEX Left LU factorization. This is intended to be a - * demonstration of the "advanced interface" of SPEX Left LU. Refer to - * README.txt for information on how to properly use this code - */ - // usage: -// spex_lu_demo Followed by the listed args: +// spex_lu_demo_doub Followed by the listed args: // -// f (or file) Filename. e.g., spex_lu_demo f MATRIX_NAME RHS_NAME, which -// indicates spex_lu_demo will read matrix from MATRIX_NAME and right hand side -// from RHS_NAME. The matrix must be stored in Matrix Market format. Refer to -// http://math.nist.gov/MatrixMarket/formats.html for information on Matrix -// Market format. The right hand side vector must be stored as a dense vector. +// f (or file) Filename. e.g., spex_lu_demo_doub f MATRIX_NAME RHS_NAME, which +// indicates spex_lu_demo_doub will read matrix from MATRIX_NAME and right hand +// side from RHS_NAME. The matrix must be stored in Matrix Market format. +// Refer to http://math.nist.gov/MatrixMarket/formats.html for information on +// Matrix Market format. The right hand side vector must be stored as a dense +// vector. // -// p (or piv) Pivot_param. e.g., spex_lu_demo p 0, which indicates SPEX_LU will -// use smallest pivot for pivot scheme. Other available options are listed as -// follows: +// p (or piv) Pivot_param. e.g., spex_lu_demo_doub p 0, which indicates SPEX_LU +// will use smallest pivot for pivot scheme. Other available options are listed +// as follows: // // 0: Smallest pivot: Default and recommended // 1: Diagonal pivoting @@ -35,91 +30,57 @@ // 4: Diagonal pivoting with tolerance for largest pivot // 5: Largest pivot // -// q (or col) Column_order_param. e.g., spex_lu_demo q 1, which indicates +// q (or col) Column_order_param. e.g., spex_lu_demo_doub q 1, which indicates // SPEX_LU will use COLAMD for column ordering. Other available options are: // // 0: None: Not recommended for sparse matrices 1: COLAMD: Default 2: // AMD // -// t (or tol) tolerance_param. e.g., spex_lu_demo t 1e-10, which indicates +// t (or tol) tolerance_param. e.g., spex_lu_demo_doub t 1e-10, which indicates // SPEX_LU will use 1e-10 as the tolerance for pivot scheme 3 and 4 mentioned // above. Therefore, it is only necessary if pivot scheme 3 or 4 is used. // -// o (or out). e.g., spex_lu_demo o 1, which indicates SPEX_LU will output the -// errors and warnings during the process. Other available options are: 0: +// o (or out). e.g., spex_lu_demo_doub o 1, which indicates SPEX_LU will output +// the errors and warnings during the process. Other available options are: 0: // print nothing 1: just errors and warnings: Default 2: terse, with basic // stats from COLAMD/AMD and SPEX and solution -// -// If none of the above args is given, they are set to the following default: -// #include "spex_demos.h" -#define FREE_WORKSPACE \ -{ \ - SPEX_matrix_free(&A, option); \ - SPEX_factorization_free(&F, option); \ - SPEX_symbolic_analysis_free(&S, option); \ - SPEX_FREE(option); \ - SPEX_finalize(); \ +#define FREE_WORKSPACE \ +{ \ + if (mat_file != NULL) \ + { \ + fclose(mat_file); \ + } \ + mat_file = NULL ; \ + SPEX_matrix_free(&A, option); \ + SPEX_factorization_free(&F, option); \ + SPEX_symbolic_analysis_free(&S, option); \ + SPEX_FREE(option); \ + SPEX_finalize(); \ } int main (int argc, char *argv[]) { + SPEX_matrix A = NULL; + SPEX_symbolic_analysis S = NULL; + SPEX_factorization F = NULL; + FILE *mat_file = NULL; + SPEX_options option = NULL; + char *mat_name = NULL, *rhs_name = NULL; + int64_t rat = 1; + //-------------------------------------------------------------------------- // Prior to using SPEX Left LU, its environment must be initialized. This // is done by calling the SPEX_initialize() function. //-------------------------------------------------------------------------- - SPEX_initialize(); - - //-------------------------------------------------------------------------- - // We first initialize the default parameters. These parameters are modified - // either via command line arguments or when reading in data. The important - // initializations are in the block below. - // - // First, we initialize 6 SPEX_matrices. Note that these matrices must - // simply be declared, they will be created and allocated within their - // respective functions. These matrices are: - // - // A: User input matrix. Must be SPEX_CSC and SPEX_MPZ for routines - // - // L: Lower triangular matrix. Will be output as SPEX_CSC and SPEX_MPZ - // - // U: Upper triangular matrix. Will be output as SPEX_CSC and SPEX_MPZ - // - // x: Solution to the linear system. Will be output as SPEX_DENSE and - // SPEX_MPQ - // - // b: Set of right hand side vectors. Must be SPEX_DENSE and SPEX_MPZ - // - // Additionally, two other data structures are declared here: - // - // pinv: Inverse row permutation used for LDU factorization and - // permutation - // - // S: Symbolic analysis struct. - // - // Lastly, the following parameter is created: - // - // option: Command options for the factorization. In general, this can be - // set to default values and is almost always the last input - // argument for SPEX Left LU functions (except SPEX_malloc and - // such) - //-------------------------------------------------------------------------- - SPEX_matrix A = NULL; - SPEX_symbolic_analysis S = NULL; - SPEX_factorization F = NULL; - SPEX_info ok ; + SPEX_TRY (SPEX_initialize ( )) ; // Initialize option, command options for the factorization - SPEX_options option = NULL; - DEMO_OK(SPEX_create_default_options(&option)); - - // Extra parameters used to obtain A, b, etc - char *mat_name, *rhs_name; - int64_t rat = 1; + SPEX_TRY (SPEX_create_default_options(&option)); //-------------------------------------------------------------------------- // After initializing memory, we process the command line for this function. @@ -128,67 +89,38 @@ int main (int argc, char *argv[]) // option->order = SPEX_AMD. //-------------------------------------------------------------------------- - DEMO_OK(spex_demo_process_command_line(argc, argv, option, + SPEX_TRY (spex_demo_process_command_line(argc, argv, option, &mat_name, &rhs_name, &rat)); //-------------------------------------------------------------------------- - // In this demo file, we now read in the A and b matrices from external - // files. Refer to the example.c file or the user guide for other - // methods of creating the input matrix. In general, the user can create - // his/her matrix (say in double form) and then create a copy of it with - // SPEX_matrix_copy + // Read in A //-------------------------------------------------------------------------- - // Read in A - FILE *mat_file = fopen(mat_name,"r"); + mat_file = fopen(mat_name,"r"); if( mat_file == NULL ) { perror("Error while opening the file"); FREE_WORKSPACE; - return 0; + return (1) ; } - DEMO_OK(spex_demo_tripread(&A, mat_file, SPEX_FP64, option)); + SPEX_TRY (spex_demo_tripread(&A, mat_file, SPEX_FP64, option)); fclose(mat_file); - -#if 0 - // Read in right hand side - FILE *rhs_file = fopen(rhs_name,"r"); - if( rhs_file == NULL ) - { - perror("Error while opening the file"); - FREE_WORKSPACE; - return 0; - } - DEMO_OK(SPEX_read_dense(&b, rhs_file, option)); - fclose(rhs_file); - - // Check if the size of A matches b - if (A->n != b->m) - { - fprintf (stderr, "Error! Size of A and b do not match!\n"); - FREE_WORKSPACE; - return 0; - } -#endif + mat_file = NULL ; //-------------------------------------------------------------------------- // We now perform symbolic analysis by getting the column preordering of // the matrix A. This is done via the SPEX_lu_analyze function. The output // of this function is a column permutation Q where we factor the matrix AQ // and an estimate of the number of nonzeros in L and U. - // - // Note that in the simple interface demostrated in the example*.c files, - // all of the following code is condensed into the single SPEX_backslash - // function. //-------------------------------------------------------------------------- - clock_t start_col = clock(); + double start_col = SuiteSparse_time (); // Column ordering using either AMD, COLAMD or nothing - DEMO_OK(SPEX_lu_analyze(&S, A, option)); + SPEX_TRY (SPEX_lu_analyze(&S, A, option)); - clock_t end_col = clock(); + double end_col = SuiteSparse_time (); //-------------------------------------------------------------------------- // Now we perform the SPEX Left LU factorization to obtain matrices L and U @@ -196,27 +128,19 @@ int main (int argc, char *argv[]) // never explicitly constructed or used. //-------------------------------------------------------------------------- - clock_t start_factor = clock(); + double start_factor = SuiteSparse_time (); - ok = SPEX_lu_factorize(&F, A, S, option); - if (ok != SPEX_OK) - { - if (ok == SPEX_SINGULAR) - { - printf("\nSingular"); - } - return 0; - } + SPEX_TRY (SPEX_lu_factorize(&F, A, S, option)); - clock_t end_factor = clock(); + double end_factor = SuiteSparse_time (); //-------------------------------------------------------------------------- - // We now solve the system Ax=b using the L and U factors computed above. + // print results //-------------------------------------------------------------------------- // Timing stats - double t_sym = (double) (end_col-start_col)/CLOCKS_PER_SEC; - double t_factor = (double) (end_factor - start_factor) / CLOCKS_PER_SEC; + double t_sym = (end_col-start_col) ; + double t_factor = (end_factor - start_factor) ; printf("\nNumber of L+U nonzeros: \t\t%"PRId64, (F->L->p[F->L->n]) + (F->U->p[F->U->n]) - (F->L->m)); @@ -229,6 +153,6 @@ int main (int argc, char *argv[]) FREE_WORKSPACE; printf ("\n%s: all tests passed\n\n", __FILE__); - return 0; + return (0) ; } diff --git a/SPEX/Demo/spex_demo_lu_extended.c b/SPEX/Demo/spex_demo_lu_extended.c index d8ebe587..7502b6c2 100644 --- a/SPEX/Demo/spex_demo_lu_extended.c +++ b/SPEX/Demo/spex_demo_lu_extended.c @@ -1,32 +1,32 @@ //------------------------------------------------------------------------------ -// Demo/spex_demo_lu_extended.c: example of extended SPEX_LU call for a double matrix. +// Demo/spex_demo_lu_extended.c: extended SPEX_LU example for a double matrix //------------------------------------------------------------------------------ -// SPEX: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ -/* This program will exactly solve the sparse linear system Ax = b by - * performing the SPEX Left LU factorization. This is intended to be a - * demonstration of the "advanced interface" of SPEX Left LU. Refer to - * README.txt for information on how to properly use this code - */ +// This program will exactly solve the sparse linear system Ax = b by +// performing the SPEX Left LU factorization. This is intended to be a +// demonstration of the "advanced interface" of SPEX Left LU. Refer to +// README.txt for information on how to properly use this code // usage: -// spexlu_demo Followed by the listed args: +// spex_demo_lu_extended Followed by the listed args: // -// f (or file) Filename. e.g., spex_lu_demo f MATRIX_NAME RHS_NAME, which -// indicates spex_lu_demo will read matrix from MATRIX_NAME and right hand side -// from RHS_NAME. The matrix must be stored in Matrix Market format. Refer to -// http://math.nist.gov/MatrixMarket/formats.html for information on Matrix -// Market format. The right hand side vector must be stored as a dense vector. +// f (or file) Filename. e.g., spex_demo_lu_extended f MATRIX_NAME RHS_NAME, +// which indicates spex_demo_lu_extended will read matrix from MATRIX_NAME and +// right hand side from RHS_NAME. The matrix must be stored in Matrix Market +// format. Refer to http://math.nist.gov/MatrixMarket/formats.html for +// information on Matrix Market format. The right hand side vector must be +// stored as a dense vector. // -// p (or piv) Pivot_param. e.g., spex_lu_demo p 0, which indicates SPEX_LU will -// use smallest pivot for pivot scheme. Other available options are listed as -// follows: +// p (or piv) Pivot_param. e.g., spex_demo_lu_extended p 0, which indicates +// SPEX_LU will use smallest pivot for pivot scheme. Other available options +// are listed as follows: // // 0: Smallest pivot: Default and recommended // 1: Diagonal pivoting @@ -35,20 +35,23 @@ // 4: Diagonal pivoting with tolerance for largest pivot // 5: Largest pivot // -// q (or col) Column_order_param. e.g., spex_lu_demo q 1, which indicates -// SPEX_LU will use COLAMD for column ordering. Other available options are: +// q (or col) Column_order_param. e.g., spex_demo_lu_extended q 1, which +// indicates SPEX_LU will use COLAMD for column ordering. Other available +// options are: // // 0: Default: COLAMD // 1: None: Not recommended for sparse matrices // 2: COLAMD // 3: AMD // -// t (or tol) tolerance_param. e.g., spex_lu_demo t 1e-10, which indicates -// SPEX_LU will use 1e-10 as the tolerance for pivot scheme 3 and 4 mentioned -// above. Therefore, it is only necessary if pivot scheme 3 or 4 is used. +// t (or tol) tolerance_param. e.g., spex_demo_lu_extended t 1e-10, which +// indicates SPEX_LU will use 1e-10 as the tolerance for pivot scheme 3 and 4 +// mentioned above. Therefore, it is only necessary if pivot scheme 3 or 4 is +// used. // -// o (or out). e.g., spex_lu_demo o 1, which indicates SPEX_LU will output the -// errors and warnings during the process. Other available options are: +// o (or out). e.g., spex_demo_lu_extended o 1, which indicates SPEX_LU will +// output the errors and warnings during the process. Other available options +// are: // // 0: print nothing // 1: just errors and warnings: Default @@ -57,33 +60,55 @@ // // If none of the above args is given, they are set to the following default: // - // p = 0, i.e., using smallest pivot // q = 1, i.e., using COLAMD // t = 0.1, not being using since p != 3 or 4 #include "spex_demos.h" -#define FREE_WORKSPACE \ -{ \ - SPEX_matrix_free(&A, option); \ - SPEX_symbolic_analysis_free(&S, option); \ - SPEX_factorization_free(&F, option); \ - SPEX_matrix_free(&x, option); \ - SPEX_matrix_free(&b, option); \ - SPEX_FREE(option); \ - SPEX_finalize(); \ +#define FREE_WORKSPACE \ +{ \ + if (mat_file != NULL) \ + { \ + fclose(mat_file); \ + } \ + mat_file = NULL ; \ + if (rhs_file != NULL) \ + { \ + fclose(rhs_file); \ + } \ + rhs_file = NULL ; \ + SPEX_matrix_free(&A, option); \ + SPEX_symbolic_analysis_free(&S, option); \ + SPEX_factorization_free(&F, option); \ + SPEX_matrix_free(&x, option); \ + SPEX_matrix_free(&b, option); \ + SPEX_FREE(option); \ + SPEX_finalize(); \ } int main (int argc, char *argv[]) { + SPEX_matrix A = NULL; + SPEX_symbolic_analysis S = NULL; + SPEX_factorization F = NULL; + SPEX_matrix x = NULL; + SPEX_matrix b = NULL; + FILE *rhs_file = NULL; + FILE *mat_file = NULL ; + SPEX_options option = NULL; + + // Extra parameters used to obtain A, b, etc + char *mat_name = NULL, *rhs_name = NULL; + int64_t rat=1; + //-------------------------------------------------------------------------- // Prior to using SPEX Left LU, its environment must be initialized. This // is done by calling the SPEX_initialize() function. //-------------------------------------------------------------------------- - SPEX_initialize(); + SPEX_TRY (SPEX_initialize ( )) ; //-------------------------------------------------------------------------- // We first initialize the default parameters. These parameters are modified @@ -119,23 +144,11 @@ int main (int argc, char *argv[]) // argument for SPEX Left LU functions (except SPEX_malloc and // such) //-------------------------------------------------------------------------- - SPEX_matrix A = NULL; - SPEX_symbolic_analysis S = NULL; - SPEX_factorization F = NULL; - SPEX_matrix x = NULL; - SPEX_matrix b = NULL; - SPEX_info ok ; // Initialize option, command options for the factorization - SPEX_options option = NULL; - DEMO_OK(SPEX_create_default_options(&option)); + SPEX_TRY (SPEX_create_default_options(&option)); option->order=SPEX_NO_ORDERING; - // Extra parameters used to obtain A, b, etc - char *mat_name, *rhs_name; - int64_t rat=1; - - //-------------------------------------------------------------------------- // After initializing memory, we process the command line for this function. // Such a step is optional, a user can also manually set these parameters. @@ -143,7 +156,7 @@ int main (int argc, char *argv[]) // option->order = SPEX_AMD. //-------------------------------------------------------------------------- - DEMO_OK(spex_demo_process_command_line(argc, argv, option, + SPEX_TRY (spex_demo_process_command_line(argc, argv, option, &mat_name, &rhs_name, &rat)); //-------------------------------------------------------------------------- @@ -153,34 +166,37 @@ int main (int argc, char *argv[]) // his/her matrix (say in double form) and then create a copy of it with // SPEX_matrix_copy //-------------------------------------------------------------------------- + // Read in A - FILE *mat_file = fopen(mat_name,"r"); + mat_file = fopen(mat_name,"r"); if( mat_file == NULL ) { perror("Error while opening the file"); FREE_WORKSPACE; - return 0; + return (1) ; } - DEMO_OK(spex_demo_tripread(&A, mat_file, SPEX_MPZ, option)); + SPEX_TRY (spex_demo_tripread(&A, mat_file, SPEX_MPZ, option)); fclose(mat_file); + mat_file = NULL ; // Read in right hand side - FILE *rhs_file = fopen(rhs_name,"r"); + rhs_file = fopen(rhs_name,"r"); if( rhs_file == NULL ) { perror("Error while opening the file"); FREE_WORKSPACE; - return 0; + return (1) ; } - DEMO_OK(spex_demo_read_dense(&b, rhs_file, option)); + SPEX_TRY (spex_demo_read_dense(&b, rhs_file, option)); fclose(rhs_file); + rhs_file = NULL ; // Check if the size of A matches b if (A->n != b->m) { fprintf (stderr, "Error! Size of A and b do not match!\n"); FREE_WORKSPACE; - return 0; + return (1) ; } //-------------------------------------------------------------------------- @@ -194,12 +210,12 @@ int main (int argc, char *argv[]) // function. //-------------------------------------------------------------------------- - clock_t start_col = clock(); + double start_col = SuiteSparse_time (); // Column ordering using either AMD, COLAMD or nothing - DEMO_OK(SPEX_lu_analyze(&S, A, option)); + SPEX_TRY (SPEX_lu_analyze(&S, A, option)); - clock_t end_col = clock(); + double end_col = SuiteSparse_time (); //-------------------------------------------------------------------------- // Now we perform the SPEX Left LU factorization to obtain matrices L and U @@ -207,17 +223,17 @@ int main (int argc, char *argv[]) // never explicitly constructed or used. //-------------------------------------------------------------------------- - clock_t start_factor = clock(); + double start_factor = SuiteSparse_time (); - DEMO_OK(SPEX_lu_factorize(&F, A, S, option)); + SPEX_TRY (SPEX_lu_factorize(&F, A, S, option)); - clock_t end_factor = clock(); + double end_factor = SuiteSparse_time (); //-------------------------------------------------------------------------- // We now solve the system Ax=b using the L and U factors computed above. //-------------------------------------------------------------------------- - clock_t start_solve = clock(); + double start_solve = SuiteSparse_time (); // SPEX Left LU has an optional check step which can verify that the // solution vector x satisfies Ax=b in perfect precision intended for @@ -235,9 +251,9 @@ int main (int argc, char *argv[]) //option->check = true; // Solve LDU x = b - DEMO_OK(SPEX_lu_solve(&x, F, b, option)); + SPEX_TRY (SPEX_lu_solve(&x, F, b, option)); - clock_t end_solve = clock(); + double end_solve = SuiteSparse_time (); // Done, x now contains the exact solution of the linear system Ax=b in // dense rational form. There is an optional final step here where the user @@ -254,9 +270,9 @@ int main (int argc, char *argv[]) // SPEX_matrix_copy( &my_x, my_kind, my_type, x, option); // Timing stats - double t_sym = (double) (end_col-start_col)/CLOCKS_PER_SEC; - double t_factor = (double) (end_factor - start_factor) / CLOCKS_PER_SEC; - double t_solve = (double) (end_solve - start_solve) / CLOCKS_PER_SEC; + double t_sym = (end_col-start_col) ; + double t_factor = (end_factor - start_factor) ; + double t_solve = (end_solve - start_solve) ; printf("\nNumber of L+U nonzeros: \t\t%"PRId64, (F->L->p[F->L->n]) + (F->U->p[F->U->n]) - (F->L->m)); @@ -269,8 +285,7 @@ int main (int argc, char *argv[]) //-------------------------------------------------------------------------- FREE_WORKSPACE; - printf ("\n%s: all tests passed\n\n", __FILE__); - //fprintf (stderr, "%s: all tests passed\n\n", __FILE__); - return 0; + fprintf (stderr, "%s: all tests passed\n\n", __FILE__); + return (0) ; } diff --git a/SPEX/Demo/spex_demo_lu_simple1.c b/SPEX/Demo/spex_demo_lu_simple1.c index c294a442..7e8f654a 100644 --- a/SPEX/Demo/spex_demo_lu_simple1.c +++ b/SPEX/Demo/spex_demo_lu_simple1.c @@ -1,16 +1,16 @@ //------------------------------------------------------------------------------ -// Demo/example.c: example of simple SPEX_LU call using as input a random matrix +// Demo/spex_demo_lu_simple1.c: simple SPEX_LU example with a random matrix //------------------------------------------------------------------------------ -// SPEX: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ -/* This example shows how to use SPEX Left LU with a given input matrix and a - * double output. The input is a randomly generate dense matrix */ +// This example shows how to use SPEX Left LU with a given input matrix and a +// double output. The input is a randomly generate dense matrix. // usage: // example > out @@ -18,39 +18,40 @@ #include "spex_demos.h" -#define FREE_WORKSPACE \ -{ \ - SPEX_matrix_free(&A,option); \ - SPEX_matrix_free(&x,option); \ - SPEX_matrix_free(&b,option); \ - SPEX_matrix_free(&Rb,option); \ - SPEX_matrix_free(&R,option); \ - SPEX_FREE(option); \ - SPEX_finalize(); \ +#define FREE_WORKSPACE \ +{ \ + SPEX_matrix_free(&A,option); \ + SPEX_matrix_free(&x,option); \ + SPEX_matrix_free(&b,option); \ + SPEX_matrix_free(&Rb,option); \ + SPEX_matrix_free(&R,option); \ + SPEX_FREE(option); \ + SPEX_finalize(); \ } int main (void) { + int64_t n = 50, nz = 2500, num=0; + SPEX_matrix A = NULL ; // input matrix + SPEX_matrix R = NULL ; // Random matrix to create A + SPEX_matrix Rb = NULL; // Random matrix to create b + SPEX_matrix b = NULL ; // Right hand side vector + SPEX_matrix x = NULL ; // Solution vectors + SPEX_options option = NULL; + //-------------------------------------------------------------------------- // Prior to using SPEX Left LU, its environment must be initialized. This // is done by calling the SPEX_initialize() function. //-------------------------------------------------------------------------- - SPEX_info ok = SPEX_initialize(); + SPEX_TRY (SPEX_initialize ( )) ; //-------------------------------------------------------------------------- // Declare and initialize essential variables //-------------------------------------------------------------------------- - int64_t n = 50, nz = 2500, num=0; - SPEX_matrix A = NULL ; // input matrix - SPEX_matrix R = NULL ; // Random matrix to create A - SPEX_matrix Rb = NULL; // Random matrix to create b - SPEX_matrix b = NULL ; // Right hand side vector - SPEX_matrix x = NULL ; // Solution vectors - SPEX_options option = NULL; - DEMO_OK(SPEX_create_default_options(&option)); + SPEX_TRY (SPEX_create_default_options(&option)); //-------------------------------------------------------------------------- // Generate a random dense 50*50 matrix @@ -61,12 +62,12 @@ int main (void) // A->j, and A->x are calloc'd. The second boolean parameter is meaningless // for FP64 matrices, but it tells SPEX Left LU to allocate the values of // A->x for the mpz_t, mpq_t, and mpfr_t entries - SPEX_matrix_allocate(&R, SPEX_TRIPLET, SPEX_FP64, n, n, nz, - false, true, option); + SPEX_TRY (SPEX_matrix_allocate(&R, SPEX_TRIPLET, SPEX_FP64, n, n, nz, + false, true, option)) ; // Rb is a n*1 dense matrix whose entries are FP64 - SPEX_matrix_allocate(&Rb, SPEX_DENSE, SPEX_FP64, n, 1, n, - false, true, option); + SPEX_TRY (SPEX_matrix_allocate(&Rb, SPEX_DENSE, SPEX_FP64, n, 1, n, + false, true, option)); // Randomly generate the input unsigned int seed = 10; @@ -90,22 +91,22 @@ int main (void) //-------------------------------------------------------------------------- // A is a copy of the R matrix. A is a CSC matrix with mpz_t entries - DEMO_OK ( SPEX_matrix_copy(&A, SPEX_CSC, SPEX_MPZ, R, option)); + SPEX_TRY ( SPEX_matrix_copy(&A, SPEX_CSC, SPEX_MPZ, R, option)); // b is a copy of the Rb matrix. b is dense with mpz_t entries. - DEMO_OK ( SPEX_matrix_copy(&b, SPEX_DENSE, SPEX_MPZ, Rb, option)); + SPEX_TRY ( SPEX_matrix_copy(&b, SPEX_DENSE, SPEX_MPZ, Rb, option)); //-------------------------------------------------------------------------- // Solve //-------------------------------------------------------------------------- - clock_t start_s = clock(); + double start_s = SuiteSparse_time (); // Solve the system and give double solution - DEMO_OK(SPEX_lu_backslash( &x, SPEX_FP64, A, b, option)); + SPEX_TRY (SPEX_lu_backslash( &x, SPEX_FP64, A, b, option)); - clock_t end_s = clock(); + double end_s = SuiteSparse_time (); - double t_s = (double) (end_s - start_s) / CLOCKS_PER_SEC; + double t_s = (end_s - start_s) ; printf("\nSPEX Left LU Factor & Solve time: %lf\n", t_s); @@ -115,6 +116,6 @@ int main (void) FREE_WORKSPACE; printf ("\n%s: all tests passed\n\n", __FILE__); - return 0; + return (0) ; } diff --git a/SPEX/Demo/spex_demo_lu_simple2.c b/SPEX/Demo/spex_demo_lu_simple2.c index 0042d0e1..219316dc 100644 --- a/SPEX/Demo/spex_demo_lu_simple2.c +++ b/SPEX/Demo/spex_demo_lu_simple2.c @@ -2,8 +2,8 @@ // Demo/spex_demo_lu_simple2.c: example of simple SPEX_LU call for triplet format //------------------------------------------------------------------------------ -// SPEX: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -15,17 +15,27 @@ // mpq_t precision // usage: -// SPEX_LU_demo2 mat_file rhs_file > out +// spex_demo_lu_simple2 f mat_file rhs_file > out // mat_file is the Matrix Market file containing the A matrix // rhs_file is a list of entries for right hand side dense matrix // if input file names are not specified, they are defaulted to // ../ExampleMats/10teams.mat and ../ExampleMats/10teams.v, respectively. -// out is file for output calculated result +// out is the file for the output with the calculated result #include "spex_demos.h" #define FREE_WORKSPACE \ { \ + if (mat_file != NULL) \ + { \ + fclose(mat_file); \ + } \ + mat_file = NULL ; \ + if (rhs_file != NULL) \ + { \ + fclose(rhs_file); \ + } \ + rhs_file = NULL ; \ SPEX_symbolic_analysis_free(&S, option); \ SPEX_matrix_free(&A, option); \ SPEX_FREE(option); \ @@ -36,37 +46,40 @@ int main (int argc, char **argv) { + + SPEX_matrix A = NULL ; // input matrix + SPEX_matrix b = NULL ; // Right hand side vector + SPEX_matrix x = NULL ; // Solution vectors + SPEX_symbolic_analysis S = NULL ; // Column permutation + SPEX_options option = NULL; + FILE *mat_file = NULL; + FILE *rhs_file = NULL; + char *mat_name = NULL, *rhs_name = NULL; + //-------------------------------------------------------------------------- // Prior to using SPEX Left LU, its environment must be initialized. This is // done by calling the SPEX_initialize() function. //-------------------------------------------------------------------------- - SPEX_initialize(); + + SPEX_TRY (SPEX_initialize ( )) ; //-------------------------------------------------------------------------- // Get matrix and right hand side file names //-------------------------------------------------------------------------- - char *mat_name = NULL, *rhs_name = NULL; if (argc < 3) { perror ("usage: spex_demo_lu_simple2 matfile rhsfile"); - return 0 ; + return (1) ; } - mat_name = argv[1]; rhs_name = argv[2]; - //-------------------------------------------------------------------------- - // Declare our data structures + // Get default options //-------------------------------------------------------------------------- - SPEX_info ok; - SPEX_matrix A = NULL ; // input matrix - SPEX_matrix b = NULL ; // Right hand side vector - SPEX_matrix x = NULL ; // Solution vectors - SPEX_symbolic_analysis S = NULL ; // Column permutation - SPEX_options option = NULL; - DEMO_OK(SPEX_create_default_options(&option)); + + SPEX_TRY (SPEX_create_default_options(&option)); //-------------------------------------------------------------------------- // Allocate memory, read in A and b @@ -74,27 +87,29 @@ int main (int argc, char **argv) // Read in A. The output of this demo function is A in CSC format with // mpz_t entries. - FILE *mat_file = fopen(mat_name,"r"); + mat_file = fopen(mat_name,"r"); if( mat_file == NULL ) { perror("Error while opening the file"); FREE_WORKSPACE; - return 0; + return (1) ; } - DEMO_OK(spex_demo_tripread(&A, mat_file, SPEX_MPZ, option)); + SPEX_TRY (spex_demo_tripread(&A, mat_file, SPEX_MPZ, option)); fclose(mat_file); + mat_file = NULL ; // Read in b. The output of this demo function is b in dense format with // mpz_t entries - FILE *rhs_file = fopen(rhs_name,"r"); + rhs_file = fopen(rhs_name,"r"); if( rhs_file == NULL ) { perror("Error while opening the file"); FREE_WORKSPACE; - return 0; + return (1) ; } - DEMO_OK(spex_demo_read_dense(&b, rhs_file, option)); + SPEX_TRY (spex_demo_read_dense(&b, rhs_file, option)); fclose(rhs_file); + rhs_file = NULL ; // Check if the size of A matches b if (A->n != b->m) @@ -102,25 +117,25 @@ int main (int argc, char **argv) printf("%"PRId64" %"PRId64" \n", A->m,b->m); fprintf (stderr, "Error! Size of A and b do not match!\n"); FREE_WORKSPACE; - return 0; + return (1) ; } //-------------------------------------------------------------------------- // solve //-------------------------------------------------------------------------- - clock_t start_s = clock(); + double start_s = SuiteSparse_time (); // SPEX Left LU has an optional check, to enable it, one can set the // following parameter to be true. // option->check = true; // Solve the system and give MPQ solution - DEMO_OK(SPEX_lu_backslash( &x, SPEX_MPQ, A, b, option)); + SPEX_TRY (SPEX_lu_backslash( &x, SPEX_MPQ, A, b, option)); - clock_t end_s = clock(); + double end_s = SuiteSparse_time (); - double t_s = (double) (end_s - start_s) / CLOCKS_PER_SEC; + double t_s = (end_s - start_s) ; printf("\nSPEX Left LU Factor & Solve time: %lf\n", t_s); @@ -129,8 +144,7 @@ int main (int argc, char **argv) //-------------------------------------------------------------------------- FREE_WORKSPACE; - printf ("\n%s: all tests passed\n\n", __FILE__); - return 0; + return (0) ; } diff --git a/SPEX/Demo/spex_demo_threaded.c b/SPEX/Demo/spex_demo_threaded.c index 64eefa86..05753f2c 100644 --- a/SPEX/Demo/spex_demo_threaded.c +++ b/SPEX/Demo/spex_demo_threaded.c @@ -2,21 +2,30 @@ // Demo/spex_demo_threaded: example of SPEX_backslash with multiple threads //------------------------------------------------------------------------------ -// SPEX: (c) 2021-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2021-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ -/* A demo of SPEX_backslash in C: solving the same system with many different - * user threads, just to test user multithreading. - */ +// A demo of SPEX_backslash in C: solving the same system with many different +// user threads, just to test user multithreading. # include "spex_demos.h" #define FREE_WORKSPACE \ { \ + if (mat_file != NULL) \ + { \ + fclose(mat_file); \ + } \ + mat_file = NULL ; \ + if (rhs_file != NULL) \ + { \ + fclose(rhs_file); \ + } \ + rhs_file = NULL ; \ SPEX_matrix_free(&A,NULL); \ SPEX_matrix_free(&b,NULL); \ SPEX_FREE(option); \ @@ -30,29 +39,37 @@ int main( int argc, char *argv[] ) { + int64_t n = 0 ; + SPEX_matrix A = NULL; + SPEX_matrix b = NULL; + SPEX_options option = NULL; + FILE *mat_file = NULL ; + FILE *rhs_file = NULL; + char *mat_name = NULL, *rhs_name = NULL; + int64_t rat = 1; + //-------------------------------------------------------------------------- // Prior to using SPEX, its environment must be initialized. This is done // by calling the SPEX_initialize() function. //-------------------------------------------------------------------------- - SPEX_initialize(); + + #ifdef _OPENMP + printf ("spex_demo_threaded: with OpenMP\n") ; + #else + printf ("spex_demo_threaded: without OpenMP\n") ; + #endif + + SPEX_TRY (SPEX_initialize ( )) ; //-------------------------------------------------------------------------- // Declare memory & Process Command Line //-------------------------------------------------------------------------- - int64_t n = 0, ok ; - - SPEX_matrix A = NULL; - SPEX_matrix b = NULL; // Set default options - SPEX_options option = NULL; - DEMO_OK(SPEX_create_default_options(&option)); - - char *mat_name = NULL, *rhs_name = NULL; - int64_t rat = 1; + SPEX_TRY (SPEX_create_default_options(&option)); // Process the command line - DEMO_OK(spex_demo_process_command_line(argc, argv, option, + SPEX_TRY (spex_demo_process_command_line(argc, argv, option, &mat_name, &rhs_name, &rat)); //-------------------------------------------------------------------------- @@ -60,31 +77,34 @@ int main( int argc, char *argv[] ) //-------------------------------------------------------------------------- // Read in A - FILE *mat_file = fopen(mat_name,"r"); + mat_file = fopen(mat_name,"r"); if( mat_file == NULL ) { perror("Error while opening the file"); FREE_WORKSPACE; - return 0; + return (1) ; } // Note, there are a few matrices in BasisLIB that dont fit in double // Need to use the other tripread for those. - DEMO_OK(spex_demo_tripread(&A, mat_file, SPEX_MPZ, option)); + SPEX_TRY (spex_demo_tripread(&A, mat_file, SPEX_MPZ, option)); fclose(mat_file); + mat_file = NULL ; + n = A->n; // Read in b. The output of this demo function is b in dense format with // mpz_t entries - FILE *rhs_file = fopen(rhs_name,"r"); + rhs_file = fopen(rhs_name,"r"); if( rhs_file == NULL ) { perror("Error while opening the file"); FREE_WORKSPACE; - return 0; + return (1) ; } - DEMO_OK(spex_demo_read_dense(&b, rhs_file, option)); + SPEX_TRY (spex_demo_read_dense(&b, rhs_file, option)); fclose(rhs_file); + rhs_file = NULL ; //-------------------------------------------------------------------------- // Solve Ax = b @@ -113,9 +133,10 @@ int main( int argc, char *argv[] ) bool test_pass = true ; + int id ; #pragma omp parallel for num_threads(nthreads) schedule(static,1) \ reduction(&&:test_pass) - for (int id = 0 ; id < nthreads ; id++) + for (id = 0 ; id < nthreads ; id++) { SPEX_info info = SPEX_thread_initialize ( ) ; if (info != SPEX_OK) @@ -179,5 +200,6 @@ int main( int argc, char *argv[] ) //-------------------------------------------------------------------------- FREE_WORKSPACE; + return (test_pass ? 0 : 1) ; } diff --git a/SPEX/Demo/spex_demos.h b/SPEX/Demo/spex_demos.h index 8d8a8473..8c7fef40 100644 --- a/SPEX/Demo/spex_demos.h +++ b/SPEX/Demo/spex_demos.h @@ -2,37 +2,32 @@ // Demo/spex_demos.h: #include file the demo programs //------------------------------------------------------------------------------ -// SPEX: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ +#ifndef SPEX_DEMOS_H +#define SPEX_DEMOS_H #include "SPEX.h" -#include "spex_util_internal.h" -#include "spex_gmp.h" -#define DEMO_OK(method) \ -{ \ - ok = method ; \ - if (ok != SPEX_OK) \ - { \ - spex_demo_determine_error (ok) ; \ - FREE_WORKSPACE ; \ - return 0 ; \ - } \ +// used by SPEX_TRY if an error occurs: +#define SPEX_CATCH(info) \ +{ \ + spex_demo_determine_error (info, __LINE__, __FILE__) ; \ + FREE_WORKSPACE ; \ + return (info) ; \ } -#define SPEX_MIN(a,b) (((a) < (b)) ? (a) : (b)) - /* Purpose: This processes the command line for user specified options */ SPEX_info spex_demo_process_command_line //processes the command line ( int64_t argc, // number of command line arguments char *argv[], // set of command line arguments - SPEX_options option, // struct containing the command options + SPEX_options option, // struct containing the command options char **mat_name, // Name of the matrix to be read in char **rhs_name, // Name of the RHS vector to be read in int64_t *rat // data type of output solution. @@ -44,8 +39,8 @@ SPEX_info spex_demo_process_command_line //processes the command line */ SPEX_info spex_demo_tripread ( - SPEX_matrix *A_handle, // Matrix to be constructed - FILE *file, // file to read from (must already be open) + SPEX_matrix *A_handle, // Matrix to be constructed + FILE *file, // file to read from (must already be open) SPEX_type C_type, // C->type: mpz_t, mpq_t, mpfr_t, int64_t, or double SPEX_options option ) ; @@ -55,8 +50,8 @@ SPEX_info spex_demo_tripread */ SPEX_info spex_demo_tripread_double ( - SPEX_matrix *A_handle, // Matrix to be constructed - FILE *file, // file to read from (must already be open) + SPEX_matrix *A_handle, // Matrix to be constructed + FILE *file, // file to read from (must already be open) SPEX_options option ) ; @@ -65,27 +60,29 @@ SPEX_info spex_demo_tripread_double */ SPEX_info spex_demo_tripread_mpz ( - SPEX_matrix *A_handle, // Matrix to be constructed - FILE *file, // file to read from (must already be open) + SPEX_matrix *A_handle, // Matrix to be constructed + FILE *file, // file to read from (must already be open) SPEX_options option ) ; -/* Purpose: SPEX_read_dense: read a dense matrix. */ +/* Purpose: read a dense matrix. */ SPEX_info spex_demo_read_dense ( - SPEX_matrix *b_handle, // Matrix to be constructed - FILE *file, // file to read from (must already be open) + SPEX_matrix *b_handle, // Matrix to be constructed + FILE *file, // file to read from (must already be open) SPEX_options option ) ; -/* Purpose: Determine why a SPEX_Chol function failed +/* Purpose: Determine why a SPEX function failed */ void spex_demo_determine_error ( - SPEX_info ok + SPEX_info info, + int line, + char *file ); - +// Purpose: check if a solution is correct SPEX_info spex_demo_check_solution ( const SPEX_matrix A, // Input matrix @@ -93,3 +90,6 @@ SPEX_info spex_demo_check_solution const SPEX_matrix b, // Right hand side vectors const SPEX_options option // Command options ); + +#endif + diff --git a/SPEX/Doc/ChangeLog b/SPEX/Doc/ChangeLog index 5fd8ae1b..ee528f91 100644 --- a/SPEX/Doc/ChangeLog +++ b/SPEX/Doc/ChangeLog @@ -1,3 +1,19 @@ +Mar 22, 2024: version 3.1.0 + + * major update to build system + * Added new methods to SPEX.h, available to the end user: + SPEX_TRY + SPEX_CATCH + SPEX_1D + SPEX_2D + SPEX_mpz_set_null + SPEX_mpq_set_null + SPEX_mpfr_set_null + SPEX_mpz_clear + SPEX_mpq_clear + SPEX_mpfr_clear + SPEX_mpfr_set_proc + Jul 26, 2023: version 3.0.0 * major change to the API: new SPEX_factorization and SPEX_symbolic_analysis diff --git a/SPEX/Doc/Makefile b/SPEX/Doc/Makefile index 2d933eea..a210f9ee 100644 --- a/SPEX/Doc/Makefile +++ b/SPEX/Doc/Makefile @@ -2,8 +2,8 @@ # SPEX/Doc/Makefile #------------------------------------------------------------------------------- -# SPEX: (c) 2019-2023, Chris Lourenco, Jinhao Chen, -# Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +# SPEX: (c) 2019-2024, Chris Lourenco, Jinhao Chen, +# Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. # All Rights Reserved. # SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/Doc/SPEX-3.0_UserGuide.pdf b/SPEX/Doc/SPEX-3.0_UserGuide.pdf deleted file mode 100644 index 4495367f..00000000 Binary files a/SPEX/Doc/SPEX-3.0_UserGuide.pdf and /dev/null differ diff --git a/SPEX/Doc/SPEX-3.0_User_Guide.pdf b/SPEX/Doc/SPEX-3.0_User_Guide.pdf deleted file mode 100644 index 80eaa5c7..00000000 Binary files a/SPEX/Doc/SPEX-3.0_User_Guide.pdf and /dev/null differ diff --git a/SPEX/Doc/SPEX_UserGuide.pdf b/SPEX/Doc/SPEX_UserGuide.pdf new file mode 100644 index 00000000..fc415109 Binary files /dev/null and b/SPEX/Doc/SPEX_UserGuide.pdf differ diff --git a/SPEX/Doc/SPEX-3.0_UserGuide.tex b/SPEX/Doc/SPEX_UserGuide.tex similarity index 97% rename from SPEX/Doc/SPEX-3.0_UserGuide.tex rename to SPEX/Doc/SPEX_UserGuide.tex index 10a27e8f..e0d56eee 100644 --- a/SPEX/Doc/SPEX-3.0_UserGuide.tex +++ b/SPEX/Doc/SPEX_UserGuide.tex @@ -62,7 +62,7 @@ \textbf{User Guide for the SPEX Software Package} \\ \vspace{5mm} - Version 3.0, July 2023 % VERSION + Version 3.1, March, 2024 % VERSION \vspace{20mm} Jinhao Chen, Timothy A. Davis, Christopher Lourenco, Lorena Mejia-Domenzain, Erick Moreno-Centeno \\ @@ -1515,9 +1515,18 @@ \section{\texttt{SPEX\_gmp}: SPEX wrapper functions for GMP/MPFR} \verb|mpfr_free_str(buff)| & \verb|SPEX_mpfr_free_str(buff)| & Free string allocated by MPFR \\ \hline -\verb|mpfr_init2(x, size)| - & \verb|SPEX_mpfr_init2(x, size)| - & Initialize x with size bits \\ \hline +\verb|mpfr_init2(x, s)| + & \verb|SPEX_mpfr_init2(x, s)| + & Initialize x with \verb's' bits \\ \hline +\verb|mpfr_set_prec(x, s)| + & \verb|SPEX_mpfr_set_prec(x, s)| + & Set x to contain \verb's' bits \\ \hline +\verb|mpfr_clear(x)| + & \verb|SPEX_mpfr_clear(x)| + & Safely free \verb|mpfr_t| value \\ \hline +\verb|mpfr_set_null(x)| + & \verb|SPEX_mpfr_set_null(x)| + & Initialize the (pointer) contents of a \verb|mpfr_t| value \\ \hline \verb|mpfr_set(x, y, rnd)| & \verb|SPEX_mpfr_set(x, y, rnd)| & $x = y$ \\ \hline @@ -1579,9 +1588,15 @@ \section{\texttt{SPEX\_gmp}: SPEX wrapper functions for GMP/MPFR} \verb|mpz_init2(x, size)| & \verb|SPEX_mpz_init2(x, size)| & Initialize x to size bits \\ \hline +\verb|mpz_clear(x)| + & \verb|SPEX_mpz_clear(x)| + & Safely free \verb|mpz_t| value \\ \hline \verb|mpz_set(x, y)| & \verb|SPEX_mpz_set(x, y)| & $x = y$ (\verb|mpz_t|) \\ \hline +\verb|mpz_set_null(x)| + & \verb|SPEX_mpz_set_null(x)| + & Initialize the (pointer) contents of a \verb|mpz_t| value \\ \hline \verb|mpz_set_ui(x, y)| & \verb|SPEX_mpz_set_ui(x, y)| & $x = y$ (\verb|uint64_t|) \\ \hline @@ -1666,6 +1681,12 @@ \section{\texttt{SPEX\_gmp}: SPEX wrapper functions for GMP/MPFR} \verb|mpq_init(x)| & \verb|SPEX_mpq_init(x)| & Initialize x \\ \hline +\verb|mpq_set_null(x)| + & \verb|SPEX_mpq_set_null(x)| + & Initialize the (pointer) contents of a \verb|mpq_t| value \\ \hline +\verb|mpq_clear(x)| + & \verb|SPEX_mpq_clear(x)| + & Safely free \verb|mpq_t| value \\ \hline \verb|mpq_set(x, y)| & \verb|SPEX_mpq_set(x, y)| & $x = y$ \\ \hline @@ -1807,6 +1828,67 @@ \section{\texttt{SPEX\_gmp}: SPEX wrapper functions for GMP/MPFR} \end{verbatim} } \end{mdframed} +\section{SPEX Helper Macros} \label{ss:SPEX_helper_macros} + +In addition to the functionality described in this section; SPEX offers several helper macros to increase ease for the end user application. The first two macros are a simple try/catch mechanism which can be used to wrap functions for error handling. The next two give an easy interface to access entries $(i,j)$ in a matrix. + +\subsection{\texttt{SPEX\_TRY} and +\texttt{SPEX\_CATCH}} + +In a robust application, the return values from SPEX should be checked and properly handled in the case an error occurs. SPEX is written in C and thus it cannot rely on the try/catch mechanism of C++. Thus, \verb|SPEX_TRY| and \verb|SPEX_CHECK| aim to achieve this goal. We provide \verb|SPEX_TRY| and leave \verb|SPEX_CATCH| to the user to define. + +\begin{mdframed}[userdefinedwidth=\textwidth] +{\footnotesize +\begin{verbatim} + #define SPEX_TRY(method) \ + { \ + SPEX_info info = (method) ; \ + if (info != SPEX_OK) \ + { \ + SPEX_CATCH (info) ; \ + } \ + } +\end{verbatim} +} \end{mdframed} + +An example definition of a \verb|SPEX_CATCH| is below. This example assumes that the user needs to free a matrix and return an error code. +\begin{mdframed}[userdefinedwidth=\textwidth] +{\footnotesize +\begin{verbatim} + #define SPEX_CATCH(info) \ + { \ + SPEX_matrix_free (&A, NULL) ; \ + fprintf (stderr, "SPEX failed: info %d, \ + line %d, file %s\n", \ + info, __LINE__, __FILE__) ; \ + return (info) ; \ + } +\end{verbatim} +} \end{mdframed} + +With this mechanism, the user can safely wrap any SPEX function which returns \verb|SPEX_info| with \verb|SPEX_TRY|. For example, one can wrap. + +\subsection{\texttt{SPEX\_1D}: Access matrix entries with 1D linear indexing.} + +\begin{mdframed}[userdefinedwidth=\textwidth] +{\footnotesize +\begin{verbatim} + #define SPEX_1D(A,k,type) ((A)->x.type [k]) +\end{verbatim} +} \end{mdframed} + +This allows the $k$th entry of a matrix stored in any kind (CSC, triplet, dense) of any type (mpq, mpz, int64, double, int) to be returned. For example, to return the $n$th entry of a CSC matrix with \verb|mpz_t| data types, one would use \verb|SPEX_1D(A, n, mpz)|. + +\subsection{\texttt{SPEX\_2D}: Access dense matrix with 2D indexing.} + +\begin{mdframed}[userdefinedwidth=\textwidth] +{\footnotesize +\begin{verbatim} + #define SPEX_2D(A,i,j,type) SPEX_1D (A, (i)+(j)*((A)->m), type) +\end{verbatim} +} \end{mdframed} + +This allows the $(i,j)$ entry of a dense matrix of any type (mpq, mpz, int64, double, int). For example to return the $(m,n)$ entry of a dense matrix with \verb|mpq_t| data types, one would use \verb|SPEX_2D(A, m, n, mpq)|. %------------------------------------------------------------------------------- \chapter{SPEX LU}\vspace{-0.75in} \label{ch:LeftLU} @@ -1836,7 +1918,7 @@ \section{Overview} \label{s:LeftLU:intro} %------------------------------------------------------------------------------- \section{Licensing} \label{s:LeftLU:licensing} %------------------------------------------------------------------------------- -\textbf{Copyright:} The copyright of this software is held by Christopher Lourenco, Jinhao Chen, Erick Moreno-Centeno, and Timothy A. Davis.\\ +\textbf{Copyright:} The copyright of this software is held by Christopher Lourenco, Jinhao Chen, Erick Moreno-Centeno, and Timothy A. Davis.\\ \noindent \textbf{Contact Info:} Contact Chris Lourenco, \href{mailto:chrisjlourenco@gmail.com}{chrisjlourenco@gmail.com}, or Tim Davis, @@ -2291,7 +2373,7 @@ \section{Overview} \label{s:Chol:intro} %------------------------------------------------------------------------------- \section{Licensing} \label{s:Chol:licensing} %------------------------------------------------------------------------------- -\textbf{Copyright:} The copyright of this software is held by Christopher Lourenco, Lorena Mejia Domenzain, Jinhao Chen, Erick Moreno-Centeno, and Timothy A. Davis.\\ +\textbf{Copyright:} The copyright of this software is held by Christopher Lourenco, Lorena Mejia Domenzain, Jinhao Chen, Erick Moreno-Centeno, and Timothy A. Davis.\\ \noindent \textbf{Contact Info:} Contact Chris Lourenco, \href{mailto:chrisjlourenco@gmail.com}{chrisjlourenco@gmail.com}, or Tim Davis, @@ -2453,7 +2535,7 @@ \section{Overview} \label{s:Backslash:intro} %------------------------------------------------------------------------------- \section{Licensing} \label{s:Backslash:licensing} %------------------------------------------------------------------------------- -\textbf{Copyright:} The copyright of this software is held by Christopher Lourenco, Lorena Mejia Domenzain, Jinhao Chen, Erick Moreno-Centeno, and Timothy A. Davis.\\ +\textbf{Copyright:} The copyright of this software is held by Christopher Lourenco, Lorena Mejia Domenzain, Jinhao Chen, Erick Moreno-Centeno, and Timothy A. Davis.\\ \noindent \textbf{Contact Info:} Contact Chris Lourenco, \href{mailto:chrisjlourenco@gmail.com}{chrisjlourenco@gmail.com}, or Tim Davis, diff --git a/SPEX/Doc/SPEX_version.tex b/SPEX/Doc/SPEX_version.tex index 114b4ca5..3acbff0d 100644 --- a/SPEX/Doc/SPEX_version.tex +++ b/SPEX/Doc/SPEX_version.tex @@ -1,2 +1,2 @@ % version of SuiteSparse/SPEX -VERSION 3.0.0, Jul 26, 2023 +VERSION 3.1.0, Mar 22, 2024 diff --git a/SPEX/Include/SPEX.h b/SPEX/Include/SPEX.h index 07f51658..9d79d801 100644 --- a/SPEX/Include/SPEX.h +++ b/SPEX/Include/SPEX.h @@ -2,8 +2,8 @@ // SPEX/Include/SPEX.h: Include file for SPEX Library //------------------------------------------------------------------------------ -// SPEX: (c) 2019-2023, Chris Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -27,7 +27,7 @@ //------------------------------------------------------------------------------ // Unless otherwise noted all functions are authored by: // -// Christopher Lourenco, Jinhao Chen, +// Christopher Lourenco, Jinhao Chen, // Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis // @@ -66,8 +66,8 @@ // // See license.txt for license info. // -// This software is copyright by Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Erick Moreno-Centeno and Timothy A. Davis. +// This software is copyright by Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // @@ -95,13 +95,40 @@ #include #include #include -#include -#include -#include -#include +// #include +// #include +// #include +// #include #include "SuiteSparse_config.h" -#include "amd.h" -#include "colamd.h" + +//------------------------------------------------------------------------------ +// SPEX Version +//------------------------------------------------------------------------------ + +// Current version of the code +#define SPEX_DATE "Mar 22, 2024" +#define SPEX_VERSION_STRING "3.1.0" +#define SPEX_VERSION_MAJOR 3 +#define SPEX_VERSION_MINOR 1 +#define SPEX_VERSION_SUB 0 + +#define SPEX_VERSION_NUMBER(major,minor,sub) \ + (((major)*1000ULL + (minor))*1000ULL + (sub)) +#define SPEX_VERSION \ + SPEX_VERSION_NUMBER (SPEX_VERSION_MAJOR, \ + SPEX_VERSION_MINOR, \ + SPEX_VERSION_SUB) + +#define SPEX__VERSION SUITESPARSE__VERCODE(3,1,0) +#if !defined (SUITESPARSE__VERSION) || \ + (SUITESPARSE__VERSION < SUITESPARSE__VERCODE(7,7,0)) +#error "SPEX 3.1.0 requires SuiteSparse_config 7.7.0 or later" +#endif + +#if defined ( __cplusplus ) +extern "C" +{ +#endif //------------------------------------------------------------------------------ // Error codes @@ -128,7 +155,7 @@ typedef enum SPEX_info ; //------------------------------------------------------------------------------ -// SPEX Version +// SPEX Version, continued //------------------------------------------------------------------------------ // Current version of the code @@ -166,6 +193,42 @@ SPEX_info SPEX_version #error "MPFR v4.0.2 or later is required." #endif +//------------------------------------------------------------------------------ +// SPEX_TRY: try a SPEX method and check for errors +//------------------------------------------------------------------------------ + +// In a robust application, the return values from each call to SPEX should be +// checked, and corrective action should be taken if an error occurs. The +// SPEX_TRY macros assist in this effort. +// +// SPEX is written in C, and so it cannot rely on the try/catch mechanism of +// C++. To accomplish a similar goal, we provide our mechanism. The SPEX_TRY +// macro calls a single SPEX method and then takes corrected action based on a +// user-defined macro SPEX_CATCH. + +#define SPEX_TRY(method) \ +{ \ + SPEX_info info = (method) ; \ + if (info != SPEX_OK) \ + { \ + SPEX_CATCH (info) ; \ + } \ +} + +// A typical example user application might #define SPEX_CATCH as follows. +// Suppose the user function needs to free some workspace and return to the +// caller if an error occurs: + +/* + #define SPEX_CATCH(info) \ + { \ + SPEX_matrix_free (&A, NULL) ; \ + fprintf (stderr, "SPEX failed: info %d, line %d, file %s\n", \ + info, __LINE__, __FILE__) ; \ + return (info) ; \ + } \ +*/ + //------------------------------------------------------------------------------ // Pivot scheme codes //------------------------------------------------------------------------------ @@ -339,7 +402,7 @@ SPEX_type ; // A->x. For example, if A->p_shallow is true, then a non-NULL A->p is a // pointer to a read-only array, and the A->p array is not freed by // SPEX_matrix_free. If A->p is NULL (for a triplet or dense matrix), then -// A->p_shallow has no effect. +// A->p_shallow has no effect. typedef struct { @@ -405,6 +468,20 @@ typedef struct // A SPEX_matrix is a pointer to a SPEX_matrix_struct typedef SPEX_matrix_struct *SPEX_matrix ; +//------------------------------------------------------------------------------ +// SPEX_matrix macros +//------------------------------------------------------------------------------ + +// These macros simplify the access to entries in a SPEX_matrix. +// The type parameter is one of: mpq, mpz, mpfr, int64, or fp64. + +// To access the kth entry in a SPEX_matrix using 1D linear addressing, +// in any matrix kind (CSC, triplet, or dense), in any type: +#define SPEX_1D(A,k,type) ((A)->x.type [k]) + +// To access the (i,j)th entry in a 2D dense SPEX_matrix, in any type: +#define SPEX_2D(A,i,j,type) SPEX_1D (A, (i)+(j)*((A)->m), type) + //------------------------------------------------------------------------------ // SPEX_matrix_allocate: allocate an m-by-n SPEX_matrix //------------------------------------------------------------------------------ @@ -487,7 +564,7 @@ SPEX_info SPEX_matrix_check // returns a SPEX status code // SPEX_matrix_copy: make a copy of a SPEX_matrix, into another kind and type. // SPEX supports 16 matrix formats: 15 of them are all combinations of -// (CSC, triplet, dense) x (mpz, mpq, mpfr, int64, double). +// (CSC, triplet, dense) x (mpz, mpq, mpfr, int64, double). SPEX_info SPEX_matrix_copy ( @@ -792,8 +869,6 @@ SPEX_info SPEX_determine_symmetry const SPEX_options option // Command options ) ; -// ended HERE on Apr 10. - //------------------------------------------------------------------------------ //---------------------------SPEX GMP/MPFR Functions---------------------------- //------------------------------------------------------------------------------ @@ -915,6 +990,8 @@ SPEX_info SPEX_mpq_equal (int *r, const mpq_t x, const mpq_t y) ; SPEX_info SPEX_mpfr_init2(mpfr_t x, const uint64_t size) ; +SPEX_info SPEX_mpfr_set_prec(mpfr_t x, const uint64_t size) ; + SPEX_info SPEX_mpfr_set (mpfr_t x, const mpfr_t y, const mpfr_rnd_t rnd) ; SPEX_info SPEX_mpfr_set_d (mpfr_t x, const double y, const mpfr_rnd_t rnd) ; @@ -951,6 +1028,13 @@ SPEX_info SPEX_mpfr_free_cache (void) ; SPEX_info SPEX_mpfr_free_str (char *str) ; +SPEX_info SPEX_mpz_set_null (mpz_t x) ; +SPEX_info SPEX_mpq_set_null (mpq_t x) ; +SPEX_info SPEX_mpfr_set_null (mpfr_t x) ; +SPEX_info SPEX_mpz_clear (mpz_t x) ; +SPEX_info SPEX_mpq_clear (mpq_t x) ; +SPEX_info SPEX_mpfr_clear (mpfr_t x) ; + //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ @@ -964,7 +1048,7 @@ SPEX_info SPEX_mpfr_free_str (char *str) ; // "Algorithm 1021: SPEX Left LU, Exactly Solving Sparse Linear Systems via // a Sparse Left-looking Integer-preserving LU Factorization", -// C. Lourenco, J. Chen, E. Moreno-Centeno, T. Davis, +// C. Lourenco, J. Chen, E. Moreno-Centeno, T. Davis, // ACM Trans. Mathematical Software. pp 1-23, vol 48, no 2, 2022. // The theory associated with this software can be found in the paper @@ -990,7 +1074,7 @@ SPEX_info SPEX_mpfr_free_str (char *str) ; //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -// Christopher Lourenco, Jinhao Chen, Timothy A. Davis, and Erick Moreno-Centeno +// Christopher Lourenco, Jinhao Chen, Erick Moreno-Centeno, and Timothy A. Davis //------------------------------------------------------------------------------ @@ -1141,7 +1225,7 @@ SPEX_info SPEX_lu_solve // solves the linear system LD^(-1)U x = b //------------------------------------------------------------------------------ // Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. //------------------------------------------------------------------------------ @@ -1299,5 +1383,9 @@ SPEX_info SPEX_backslash SPEX_options option // Command options (NULL: means use defaults) ) ; +#if defined ( __cplusplus ) +} +#endif + #endif diff --git a/SPEX/LICENSE.txt b/SPEX/LICENSE.txt index 0020fe09..2516bc71 100644 --- a/SPEX/LICENSE.txt +++ b/SPEX/LICENSE.txt @@ -6,8 +6,8 @@ found in the lists below. SPEX: a SParse EXact Factorization Framework for solving SLEs - Copyright (c) 2019-2023, Christopher Lourenco, Jinhao Chen, - Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. + Copyright (c) 2019-2024, Christopher Lourenco, Jinhao Chen, + Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. Available at: https://github.com/clouren/SPEX diff --git a/SPEX/MATLAB/Source/SPEX_mex.h b/SPEX/MATLAB/Source/SPEX_mex.h index a951aefd..07f418cc 100644 --- a/SPEX/MATLAB/Source/SPEX_mex.h +++ b/SPEX/MATLAB/Source/SPEX_mex.h @@ -2,8 +2,8 @@ // SPEX/MATLAB/SPEX_mex.h: include file for MATLAB functions //------------------------------------------------------------------------------ -// SPEX: (c) 2022-2023, Chris Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/MATLAB/Source/spex_mex_check_for_inf.c b/SPEX/MATLAB/Source/spex_mex_check_for_inf.c index 6242b4f3..bfadbfbf 100644 --- a/SPEX/MATLAB/Source/spex_mex_check_for_inf.c +++ b/SPEX/MATLAB/Source/spex_mex_check_for_inf.c @@ -2,8 +2,8 @@ // SPEX/MATLAB/SPEX_mex_check_for_inf.c: Check A&B for inf/NAN //------------------------------------------------------------------------------ -// SPEX: (c) 2022-2023, Chris Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/MATLAB/Source/spex_mex_error.c b/SPEX/MATLAB/Source/spex_mex_error.c index 3d978a1a..f28cbd66 100644 --- a/SPEX/MATLAB/Source/spex_mex_error.c +++ b/SPEX/MATLAB/Source/spex_mex_error.c @@ -2,8 +2,8 @@ // SPEX/MATLAB/SPEX_mex_error.c: Check error codes for MATLAB //------------------------------------------------------------------------------ -// SPEX: (c) 2022-2023, Chris Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/MATLAB/Source/spex_mex_get_A_and_b.c b/SPEX/MATLAB/Source/spex_mex_get_A_and_b.c index f9c32d3d..10713b01 100644 --- a/SPEX/MATLAB/Source/spex_mex_get_A_and_b.c +++ b/SPEX/MATLAB/Source/spex_mex_get_A_and_b.c @@ -2,8 +2,8 @@ // SPEX/MATLAB/SPEX_mex_get_A_and_b.c: convert A&b to SPEX matrices //------------------------------------------------------------------------------ -// SPEX: (c) 2022-2023, Chris Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/MATLAB/Source/spex_mex_get_matlab_options.c b/SPEX/MATLAB/Source/spex_mex_get_matlab_options.c index 624b1f87..b2ee0980 100644 --- a/SPEX/MATLAB/Source/spex_mex_get_matlab_options.c +++ b/SPEX/MATLAB/Source/spex_mex_get_matlab_options.c @@ -2,8 +2,8 @@ // SPEX/MATLAB/SPEX_mex_get_matlab_optons.c: Get command options from user //------------------------------------------------------------------------------ -// SPEX: (c) 2022-2023, Chris Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/MATLAB/spex_backslash.m b/SPEX/MATLAB/spex_backslash.m index 73b30bda..b783ab29 100644 --- a/SPEX/MATLAB/spex_backslash.m +++ b/SPEX/MATLAB/spex_backslash.m @@ -88,8 +88,8 @@ % interfaces of all SPEX packages. Typing spex_mex_install in this directory % should do this correctly. -% SPEX: (c) 2022, Chris Lourenco, Jinhao Chen, -% Lorena Mejia Domenzain, Timothy A. Davis and Erick Moreno-Centeno. +% SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +% Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. % All Rights Reserved. % SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/MATLAB/spex_backslash_mex_soln.c b/SPEX/MATLAB/spex_backslash_mex_soln.c index a6b84e3a..664b5a3f 100644 --- a/SPEX/MATLAB/spex_backslash_mex_soln.c +++ b/SPEX/MATLAB/spex_backslash_mex_soln.c @@ -2,8 +2,8 @@ // SPEX/MATLAB/spex_backslash_mex_soln: Use SPEX Backslash within MATLAB //------------------------------------------------------------------------------ -// SPEX: (c) 2022-2023, Chris Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/MATLAB/spex_cholesky_backslash.m b/SPEX/MATLAB/spex_cholesky_backslash.m index 791af8ae..1f2c67fd 100644 --- a/SPEX/MATLAB/spex_cholesky_backslash.m +++ b/SPEX/MATLAB/spex_cholesky_backslash.m @@ -91,8 +91,8 @@ % interfaces of all SPEX packages. Typing spex_mex_install in this directory % should do this correctly. -% SPEX: (c) 2022, Chris Lourenco, Jinhao Chen, -% Lorena Mejia Domenzain, Timothy A. Davis and Erick Moreno-Centeno. +% SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +% Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. % All Rights Reserved. % SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/MATLAB/spex_cholesky_mex_soln.c b/SPEX/MATLAB/spex_cholesky_mex_soln.c index 7684c0e2..7c9b7389 100644 --- a/SPEX/MATLAB/spex_cholesky_mex_soln.c +++ b/SPEX/MATLAB/spex_cholesky_mex_soln.c @@ -2,8 +2,8 @@ // SPEX/MATLAB/spex_cholesky_mex_soln: Use SPEX Chol within MATLAB //------------------------------------------------------------------------------ -// SPEX: (c) 2022-2023, Chris Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/MATLAB/spex_lu_backslash.m b/SPEX/MATLAB/spex_lu_backslash.m index 15f45be0..1afe3942 100644 --- a/SPEX/MATLAB/spex_lu_backslash.m +++ b/SPEX/MATLAB/spex_lu_backslash.m @@ -94,8 +94,8 @@ % % See also vpa, SPEX_install, SPEX_test, SPEX_demo. -% SPEX: (c) 2022, Chris Lourenco, Jinhao Chen, -% Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +% SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +% Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. % All Rights Reserved. % SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/MATLAB/spex_lu_mex_soln.c b/SPEX/MATLAB/spex_lu_mex_soln.c index 151d55f8..8530b170 100644 --- a/SPEX/MATLAB/spex_lu_mex_soln.c +++ b/SPEX/MATLAB/spex_lu_mex_soln.c @@ -2,8 +2,8 @@ // SPEX/MATLAB/spex_lu_mex_soln: Use SPEX Left LU within MATLAB //------------------------------------------------------------------------------ -// SPEX: (c) 2022-2023, Chris Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/MATLAB/spex_mex_demo.m b/SPEX/MATLAB/spex_mex_demo.m index bb393a5c..e20780f0 100644 --- a/SPEX/MATLAB/spex_mex_demo.m +++ b/SPEX/MATLAB/spex_mex_demo.m @@ -5,8 +5,8 @@ % % See also vpa, spex_mex_install, spex_mex_test. -% SPEX: (c) 2022, Chris Lourenco, Jinhao Chen, -% Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +% SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +% Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. % All Rights Reserved. % SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/MATLAB/spex_mex_install.m b/SPEX/MATLAB/spex_mex_install.m index 267e65cb..91570067 100644 --- a/SPEX/MATLAB/spex_mex_install.m +++ b/SPEX/MATLAB/spex_mex_install.m @@ -1,27 +1,26 @@ function spex_mex_install(run_demo) -% spex_mex_INSTALL: install and test the MATLAB interface to SPEX MATLAB functions. +% spex_mex_install: install and test the MATLAB interface to SPEX MATLAB functions. % % Usage: spex_mex_install % -% Required Libraries: GMP, MPFR, AMD, COLAMD, SPEX. If -lamd and -lcolamd are -% not available, install them with 'make install' first, in the top-level -% SuiteSparse folder. +% Required Libraries: GMP, MPFR, AMD, COLAMD, SuiteSparse_config, SPEX. If +% -lamd, -lcolamd, and -lsuitesparseconfig are not available, install them with +% 'make install' first, in the top-level SuiteSparse folder. % % You may need to add the top-level lib folder (SPEX/lib, or SuiteSparse/lib % if SPEX is inside SuiteSparse) to your LD_LIBRARY_PATH (DYLD_LIBRARY_PATH % on the Mac). See instructions in the spex_deps.m file. -% SPEX: (c) 2022, Chris Lourenco, Jinhao Chen, -% Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +% SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +% Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. % All Rights Reserved. % SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later - if (nargin < 1) run_demo = true ; end -fprintf ('Compiling the SPEX mexFunctions for use:\n') ; +fprintf ('Compiling the SPEX for use in MATLAB:\n') ; % Find all source files and add them to the src string src = ''; @@ -63,12 +62,17 @@ function spex_mex_install(run_demo) src = [src, tmp]; end -% Compiler flags -flags = 'CFLAGS=''-std=c99 -fPIC'' LDFLAGS=''-Wl,-rpath=''../../lib'''''; - % External libraries: GMP, MPRF, AMD, and COLAMD [suitesparse_libdir, suitesparse_incdir, gmp_lib, gmp_include, mpfr_lib, mpfr_include] = spex_deps ; +% Compiler flags +openmp = '' ; +if (~ismac && isunix) + openmp = ' -fopenmp' ; +end +flags = sprintf ('CFLAGS=''-std=c11 -fPIC %s'' LDFLAGS=''-Wl,-rpath=''%s''''', ... + openmp, suitesparse_libdir) ; + % libraries: if (isempty (suitesparse_libdir)) suitesparse_libdir = ' ' ; @@ -105,13 +109,21 @@ function spex_mex_install(run_demo) m2 = ['mex ', verbose, ' -R2018a ', includes, ' spex_cholesky_mex_soln.c ' , src, ' ', flags, ' ', libs]; m3 = ['mex ', verbose, ' -R2018a ', includes, ' spex_backslash_mex_soln.c ' , src, ' ', flags, ' ', libs]; +% Now, we evaluate each one if (~isempty (verbose)) fprintf ('%s\n', m1) ; end - -% Now, we evaluate each one +fprintf ('Compiling MATLAB interface to SPEX LU:\n') ; eval (m1) ; +if (~isempty (verbose)) + fprintf ('%s\n', m2) ; +end +fprintf ('Compiling MATLAB interface to SPEX Cholesky:\n') ; eval (m2) ; +if (~isempty (verbose)) + fprintf ('%s\n', m3) ; +end +fprintf ('Compiling MATLAB interface to SPEX Backslash:\n') ; eval (m3) ; if (run_demo) diff --git a/SPEX/MATLAB/spex_mex_test.m b/SPEX/MATLAB/spex_mex_test.m index b10f041b..797092a1 100644 --- a/SPEX/MATLAB/spex_mex_test.m +++ b/SPEX/MATLAB/spex_mex_test.m @@ -5,8 +5,8 @@ % % See also spex_mex_install, spex_mex_demo. -% SPEX: (c) 2022, Chris Lourenco, Jinhao Chen, -% Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +% SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +% Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. % All Rights Reserved. % SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -83,7 +83,7 @@ fprintf ('\nmaxerr: %g\n', maxerr) ; if (maxerr < 1e-6) - fprintf('\nLeft LU installation successful\n') + fprintf('\nSPEX LU installation successful\n') else error ('\nTesting failure! error too high please reinstall\n') end diff --git a/SPEX/Makefile b/SPEX/Makefile index d4ae1a0e..4ededd71 100644 --- a/SPEX/Makefile +++ b/SPEX/Makefile @@ -2,8 +2,8 @@ # SuiteSparse/SPEX/Makefile: Makefile for SPEX #------------------------------------------------------------------------------- -# SPEX: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -# Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +# SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +# Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. # All Rights Reserved. # SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -37,33 +37,32 @@ default: library # default is to install only in /usr/local library: - ( cd build && cmake $(CMAKE_OPTIONS) .. && cmake --build . -j${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) -DLOCAL_INSTALL=1 .. && cmake --build . -j${JOBS} ) + ( cd build && cmake $(CMAKE_OPTIONS) -USUITESPARSE_PKGFILEDIR -DSUITESPARSE_LOCAL_INSTALL=1 .. && cmake --build . --config Release -j${JOBS} ) # install only in /usr/local (default) global: - ( cd build && cmake $(CMAKE_OPTIONS) -DLOCAL_INSTALL=0 .. && cmake --build . -j${JOBS} ) + ( cd build && cmake $(CMAKE_OPTIONS) -USUITESPARSE_PKGFILEDIR -DSUITESPARSE_LOCAL_INSTALL=0 .. && cmake --build . --config Release -j${JOBS} ) debug: - ( cd build && cmake $(CMAKE_OPTIONS) -DCMAKE_BUILD_TYPE=Debug .. && cmake --build . -j${JOBS} ) + ( cd build && cmake $(CMAKE_OPTIONS) -DCMAKE_BUILD_TYPE=Debug .. && cmake --build . --config Debug -j${JOBS} ) all: library demos: - ( cd build && cmake $(CMAKE_OPTIONS) -DDEMO=1 .. && cmake --build . -j${JOBS} ) + ( cd build && cmake $(CMAKE_OPTIONS) -DSUITESPARSE_DEMOS=1 .. && cmake --build . --config Release -j${JOBS} ) ./build/spex_demo_lu_simple1 ./build/spex_demo_lu_simple2 ExampleMats/10teams.mat.txt ExampleMats/10teams.rhs.txt ./build/spex_demo_lu_extended f ExampleMats/10teams.mat.txt ExampleMats/10teams.rhs.txt ./build/spex_demo_lu_doub f ExampleMats/10teams.mat.txt ExampleMats/10teams.rhs.txt ./build/spex_demo_backslash f ExampleMats/10teams.mat.txt ExampleMats/10teams.rhs.txt - ./build/spex_demo_backslash f ExampleMats/Trefethen_500.mat.txt ExampleMats/Trefethen_500.rhs.txt - ./build/spex_demo_cholesky_simple f ExampleMats/494_bus.mat.txt ExampleMats/494_bus.rhs.txt - ./build/spex_demo_cholesky_extended f ExampleMats/494_bus.mat.txt ExampleMats/494_bus.rhs.txt + ./build/spex_demo_cholesky_simple f ExampleMats/494_bus.mat.txt ExampleMats/494_bus.rhs.txt + ./build/spex_demo_cholesky_extended f ExampleMats/494_bus.mat.txt ExampleMats/494_bus.rhs.txt ./build/spex_demo_threaded f ExampleMats/10teams.mat.txt ExampleMats/10teams.rhs.txt - + ./build/spex_demo_backslash f ExampleMats/Trefethen_500.mat.txt ExampleMats/Trefethen_500.rhs.txt cov: ( cd Tcov && $(MAKE) ) diff --git a/SPEX/Python/SPEXpy/Options.py b/SPEX/Python/SPEXpy/Options.py index 85a28f75..54e07b01 100644 --- a/SPEX/Python/SPEXpy/Options.py +++ b/SPEX/Python/SPEXpy/Options.py @@ -2,8 +2,8 @@ # SPEX/Python/utilities/Options.py: class Options #------------------------------------------------------------------------------- -# SPEX: (c) 2022, Chris Lourenco, Jinhao Chen, -# Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +# SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +# Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. # All Rights Reserved. # SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/Python/SPEXpy/SPEX_error.py b/SPEX/Python/SPEXpy/SPEX_error.py index 5680bb2a..d15ae43d 100644 --- a/SPEX/Python/SPEXpy/SPEX_error.py +++ b/SPEX/Python/SPEXpy/SPEX_error.py @@ -2,8 +2,8 @@ # SPEX/Python/SPEXpy/SPEX_error.py: class SPEX_error #------------------------------------------------------------------------------- -# SPEX: (c) 2022, Chris Lourenco, Jinhao Chen, -# Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +# SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +# Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. # All Rights Reserved. # SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/Python/SPEXpy/Source/spex_python_connect.c b/SPEX/Python/SPEXpy/Source/spex_python_connect.c index 728505f8..d3fe5e10 100644 --- a/SPEX/Python/SPEXpy/Source/spex_python_connect.c +++ b/SPEX/Python/SPEXpy/Source/spex_python_connect.c @@ -2,8 +2,8 @@ // SPEX/Python/spex_connect.c: use SPEX in Python //------------------------------------------------------------------------------ -// SPEX: (c) 2022-2023, Chris Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/Python/SPEXpy/Source/spex_python_connect.h b/SPEX/Python/SPEXpy/Source/spex_python_connect.h index eb227efd..06d0e6d8 100644 --- a/SPEX/Python/SPEXpy/Source/spex_python_connect.h +++ b/SPEX/Python/SPEXpy/Source/spex_python_connect.h @@ -2,8 +2,8 @@ // SPEX/Python/spex_connect.h: use SPEX in Python //------------------------------------------------------------------------------ -// SPEX: (c) 2022-2023, Chris Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/Python/SPEXpy/__init__.py b/SPEX/Python/SPEXpy/__init__.py index 0d348eab..ab83e6df 100644 --- a/SPEX/Python/SPEXpy/__init__.py +++ b/SPEX/Python/SPEXpy/__init__.py @@ -2,8 +2,8 @@ # SPEX/Python/SPEXpy/__init__.py #------------------------------------------------------------------------------- -# SPEX: (c) 2022, Chris Lourenco, Jinhao Chen, -# Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +# SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +# Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. # All Rights Reserved. # SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/Python/SPEXpy/backslash.py b/SPEX/Python/SPEXpy/backslash.py index b057b94f..66ea49dc 100644 --- a/SPEX/Python/SPEXpy/backslash.py +++ b/SPEX/Python/SPEXpy/backslash.py @@ -2,8 +2,8 @@ # SPEX/Python/SPEXpy/backslash.py: solve Ax=b #------------------------------------------------------------------------------- -# SPEX: (c) 2022, Chris Lourenco, Jinhao Chen, -# Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +# SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +# Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. # All Rights Reserved. # SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/Python/SPEXpy/cholesky_backslash.py b/SPEX/Python/SPEXpy/cholesky_backslash.py index bde5ff4c..61b56bcc 100644 --- a/SPEX/Python/SPEXpy/cholesky_backslash.py +++ b/SPEX/Python/SPEXpy/cholesky_backslash.py @@ -2,8 +2,8 @@ # SPEX/Python/SPEXpy/cholesky_backslash.py: solve Ax=b using Cholesky factorization #------------------------------------------------------------------------------- -# SPEX: (c) 2022, Chris Lourenco, Jinhao Chen, -# Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +# SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +# Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. # All Rights Reserved. # SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/Python/SPEXpy/lu_backslash.py b/SPEX/Python/SPEXpy/lu_backslash.py index 3810af88..4db6b36c 100644 --- a/SPEX/Python/SPEXpy/lu_backslash.py +++ b/SPEX/Python/SPEXpy/lu_backslash.py @@ -2,8 +2,8 @@ # SPEX/Python/SPEXpy/lu_backslash.py: solve Ax=b using LU factorization #------------------------------------------------------------------------------- -# SPEX: (c) 2022, Chris Lourenco, Jinhao Chen, -# Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +# SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +# Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. # All Rights Reserved. # SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/Python/SPEXpy/spex_connect.py b/SPEX/Python/SPEXpy/spex_connect.py index b8c4a1a2..2a1c98f0 100644 --- a/SPEX/Python/SPEXpy/spex_connect.py +++ b/SPEX/Python/SPEXpy/spex_connect.py @@ -2,8 +2,8 @@ # SPEX/Python/SPEX/spex_connect.py: link SPEX to use in Python #------------------------------------------------------------------------------- -# SPEX: (c) 2022, Chris Lourenco, Jinhao Chen, -# Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +# SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +# Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. # All Rights Reserved. # SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/Python/SPEXpy/spex_matrix_from_file.py b/SPEX/Python/SPEXpy/spex_matrix_from_file.py index 37e15135..f70668b9 100644 --- a/SPEX/Python/SPEXpy/spex_matrix_from_file.py +++ b/SPEX/Python/SPEXpy/spex_matrix_from_file.py @@ -2,8 +2,8 @@ # SPEX/Python/SPEXpy/spex_from_matrix_file.py: read matrix from file #------------------------------------------------------------------------------- -# SPEX: (c) 2022, Chris Lourenco, Jinhao Chen, -# Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +# SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +# Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. # All Rights Reserved. # SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/Python/spex_python_demo.py b/SPEX/Python/spex_python_demo.py index f1e7e016..71c3a2a9 100644 --- a/SPEX/Python/spex_python_demo.py +++ b/SPEX/Python/spex_python_demo.py @@ -3,8 +3,8 @@ # matrices #------------------------------------------------------------------------------- -# SPEX: (c) 2022, Chris Lourenco, Jinhao Chen, -# Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +# SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, +# Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. # All Rights Reserved. # SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Backslash/License/license.txt b/SPEX/SPEX_Backslash/License/license.txt index f81e2816..d289a39f 100644 --- a/SPEX/SPEX_Backslash/License/license.txt +++ b/SPEX/SPEX_Backslash/License/license.txt @@ -1,7 +1,7 @@ SPEX Backslash: -Copyright (c) 2021-2023, Christopher Lourenco, Jinhao Chen, -Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +Copyright (c) 2021-2024, Christopher Lourenco, Jinhao Chen, +Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. Available at: https://github.com/clouren/SPEX diff --git a/SPEX/SPEX_Backslash/Source/SPEX_backslash.c b/SPEX/SPEX_Backslash/Source/SPEX_backslash.c index 76433e50..623a767e 100644 --- a/SPEX/SPEX_Backslash/Source/SPEX_backslash.c +++ b/SPEX/SPEX_Backslash/Source/SPEX_backslash.c @@ -2,8 +2,8 @@ // SPEX_Backslash/SPEX_backslash.c: Solve a system Ax=b //------------------------------------------------------------------------------ -// SPEX_Backslash: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Backslash: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Cholesky/License/license.txt b/SPEX/SPEX_Cholesky/License/license.txt index ac5cd4a9..b29eb690 100644 --- a/SPEX/SPEX_Cholesky/License/license.txt +++ b/SPEX/SPEX_Cholesky/License/license.txt @@ -1,7 +1,7 @@ SPEX_Chol: Integer-Preserving Cholesky Factorization -Copyright (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +Copyright (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. All Rights Reserved. Available at: diff --git a/SPEX/SPEX_Cholesky/Source/SPEX_cholesky_analyze.c b/SPEX/SPEX_Cholesky/Source/SPEX_cholesky_analyze.c index 05e16904..26173b29 100644 --- a/SPEX/SPEX_Cholesky/Source/SPEX_cholesky_analyze.c +++ b/SPEX/SPEX_Cholesky/Source/SPEX_cholesky_analyze.c @@ -2,8 +2,8 @@ // SPEX_Cholesky/SPEX_cholesky_analyze: Perform the symbolic analysis of A //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Cholesky/Source/SPEX_cholesky_backslash.c b/SPEX/SPEX_Cholesky/Source/SPEX_cholesky_backslash.c index 575812b0..88c9a106 100644 --- a/SPEX/SPEX_Cholesky/Source/SPEX_cholesky_backslash.c +++ b/SPEX/SPEX_Cholesky/Source/SPEX_cholesky_backslash.c @@ -2,8 +2,8 @@ // SPEX_Cholesky/SPEX_cholesky_backslash: solve Ax=b //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Cholesky/Source/SPEX_cholesky_factorize.c b/SPEX/SPEX_Cholesky/Source/SPEX_cholesky_factorize.c index c662cb9a..387f75cf 100644 --- a/SPEX/SPEX_Cholesky/Source/SPEX_cholesky_factorize.c +++ b/SPEX/SPEX_Cholesky/Source/SPEX_cholesky_factorize.c @@ -2,8 +2,8 @@ // SPEX_Cholesky/SPEX_cholesky_factorize: Perform SPEX Chol factorization of A //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Cholesky/Source/SPEX_cholesky_solve.c b/SPEX/SPEX_Cholesky/Source/SPEX_cholesky_solve.c index f42f15a7..5fa2a7d0 100644 --- a/SPEX/SPEX_Cholesky/Source/SPEX_cholesky_solve.c +++ b/SPEX/SPEX_Cholesky/Source/SPEX_cholesky_solve.c @@ -3,8 +3,8 @@ // factorization //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Cholesky/Source/spex_cholesky_backward_sub.c b/SPEX/SPEX_Cholesky/Source/spex_cholesky_backward_sub.c index 6e70d9f2..0f6d0fba 100644 --- a/SPEX/SPEX_Cholesky/Source/spex_cholesky_backward_sub.c +++ b/SPEX/SPEX_Cholesky/Source/spex_cholesky_backward_sub.c @@ -2,8 +2,8 @@ // SPEX_Cholesky/spex_cholesky_backward_sub: Solve L' x = b for Cholesky //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Cholesky/Source/spex_cholesky_counts.c b/SPEX/SPEX_Cholesky/Source/spex_cholesky_counts.c index 1802865a..91009aae 100644 --- a/SPEX/SPEX_Cholesky/Source/spex_cholesky_counts.c +++ b/SPEX/SPEX_Cholesky/Source/spex_cholesky_counts.c @@ -2,8 +2,8 @@ // SPEX_Cholesky/spex_cholesky_counts: Column counts for Cholesky factorization //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Cholesky/Source/spex_cholesky_ereach.c b/SPEX/SPEX_Cholesky/Source/spex_cholesky_ereach.c index a7559a0b..80e917d3 100644 --- a/SPEX/SPEX_Cholesky/Source/spex_cholesky_ereach.c +++ b/SPEX/SPEX_Cholesky/Source/spex_cholesky_ereach.c @@ -2,8 +2,8 @@ // SPEX_Cholesky/spex_cholesky_ereach: Compute reach of an elimination tree //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Cholesky/Source/spex_cholesky_etree.c b/SPEX/SPEX_Cholesky/Source/spex_cholesky_etree.c index 8c2d8f2f..dd352128 100644 --- a/SPEX/SPEX_Cholesky/Source/spex_cholesky_etree.c +++ b/SPEX/SPEX_Cholesky/Source/spex_cholesky_etree.c @@ -2,8 +2,8 @@ // SPEX_Cholesky/spex_cholesky_etree: Compute the elimination tree of a matrix A //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Cholesky/Source/spex_cholesky_factor.c b/SPEX/SPEX_Cholesky/Source/spex_cholesky_factor.c index e899145e..a8dab71d 100644 --- a/SPEX/SPEX_Cholesky/Source/spex_cholesky_factor.c +++ b/SPEX/SPEX_Cholesky/Source/spex_cholesky_factor.c @@ -2,14 +2,14 @@ // SPEX_Cholesky/spex_cholesky_factor: Integer preserving Cholesky factorization //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ -# define SPEX_FREE_ALL \ +#define SPEX_FREE_ALL \ { \ SPEX_factorization_free(&F, option); \ } diff --git a/SPEX/SPEX_Cholesky/Source/spex_cholesky_forward_sub.c b/SPEX/SPEX_Cholesky/Source/spex_cholesky_forward_sub.c index d4880ffe..38515168 100644 --- a/SPEX/SPEX_Cholesky/Source/spex_cholesky_forward_sub.c +++ b/SPEX/SPEX_Cholesky/Source/spex_cholesky_forward_sub.c @@ -2,8 +2,8 @@ // SPEX_Cholesky/spex_cholesky_forward_sub: Solve the system LDx = b //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Cholesky/Source/spex_cholesky_internal.h b/SPEX/SPEX_Cholesky/Source/spex_cholesky_internal.h index 67013e62..73a62061 100644 --- a/SPEX/SPEX_Cholesky/Source/spex_cholesky_internal.h +++ b/SPEX/SPEX_Cholesky/Source/spex_cholesky_internal.h @@ -2,8 +2,8 @@ // SPEX_Cholesky/spex_cholesky_internal.h: include file for internal use in SPEX_Cholesky //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Cholesky/Source/spex_cholesky_leaf.c b/SPEX/SPEX_Cholesky/Source/spex_cholesky_leaf.c index 1ac88142..cbbd375a 100644 --- a/SPEX/SPEX_Cholesky/Source/spex_cholesky_leaf.c +++ b/SPEX/SPEX_Cholesky/Source/spex_cholesky_leaf.c @@ -2,8 +2,8 @@ // SPEX_Cholesky/spex_cholesky_leaf: Subroutine for column counts of Cholesky //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Cholesky/Source/spex_cholesky_left_factor.c b/SPEX/SPEX_Cholesky/Source/spex_cholesky_left_factor.c index d9c03227..3611b416 100644 --- a/SPEX/SPEX_Cholesky/Source/spex_cholesky_left_factor.c +++ b/SPEX/SPEX_Cholesky/Source/spex_cholesky_left_factor.c @@ -2,8 +2,8 @@ // SPEX_Cholesky/spex_cholesky_left_factor: Left-looking REF Chol. factorization //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Cholesky/Source/spex_cholesky_left_triangular_solve.c b/SPEX/SPEX_Cholesky/Source/spex_cholesky_left_triangular_solve.c index 1caa721e..e3d7392c 100644 --- a/SPEX/SPEX_Cholesky/Source/spex_cholesky_left_triangular_solve.c +++ b/SPEX/SPEX_Cholesky/Source/spex_cholesky_left_triangular_solve.c @@ -3,8 +3,8 @@ // left-looking triangular solve //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -55,9 +55,11 @@ // Each iteration of the triangular solve requires that the nonzero pattern // is sorted prior to numeric operations. This is the helper function for // c's default qsort -static inline int compare (const void * a, const void * b) +static inline int compar (const void * a, const void * b) { - return ( *(int64_t*)a - *(int64_t*)b ); + int64_t x = (* ((int64_t *) a)) ; + int64_t y = (* ((int64_t *) b)) ; + return (x < y ? -1 : ((x == y) ? 0 : 1)) ; } SPEX_info spex_cholesky_left_triangular_solve @@ -218,7 +220,7 @@ SPEX_info spex_cholesky_left_triangular_solve } } // Sort the nonzero pattern xi using quicksort - qsort(&xi[top], n-top, sizeof(int64_t), compare); + qsort (&xi[top], n-top, sizeof (int64_t), compar) ; // Reset the history vector h for (i = top; i < n; i++) diff --git a/SPEX/SPEX_Cholesky/Source/spex_cholesky_permute_A.c b/SPEX/SPEX_Cholesky/Source/spex_cholesky_permute_A.c index bcc3a5d7..1280d974 100644 --- a/SPEX/SPEX_Cholesky/Source/spex_cholesky_permute_A.c +++ b/SPEX/SPEX_Cholesky/Source/spex_cholesky_permute_A.c @@ -2,8 +2,8 @@ // SPEX_Cholesky/spex_cholesky_permute_A: Symmetric permutation of matrix A //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Cholesky/Source/spex_cholesky_post.c b/SPEX/SPEX_Cholesky/Source/spex_cholesky_post.c index 6142df53..6ff7d721 100644 --- a/SPEX/SPEX_Cholesky/Source/spex_cholesky_post.c +++ b/SPEX/SPEX_Cholesky/Source/spex_cholesky_post.c @@ -2,8 +2,8 @@ // SPEX_Cholesky/spex_cholesky_post: Postorder a forest //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Cholesky/Source/spex_cholesky_pre_left_factor.c b/SPEX/SPEX_Cholesky/Source/spex_cholesky_pre_left_factor.c index 5b42a4e3..75871a45 100644 --- a/SPEX/SPEX_Cholesky/Source/spex_cholesky_pre_left_factor.c +++ b/SPEX/SPEX_Cholesky/Source/spex_cholesky_pre_left_factor.c @@ -2,8 +2,8 @@ // SPEX_Cholesky/spex_cholesky_pre_left_factor: Symbolic left-looking Cholesky //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Cholesky/Source/spex_cholesky_preorder.c b/SPEX/SPEX_Cholesky/Source/spex_cholesky_preorder.c index 4c953fdf..dd3560d3 100644 --- a/SPEX/SPEX_Cholesky/Source/spex_cholesky_preorder.c +++ b/SPEX/SPEX_Cholesky/Source/spex_cholesky_preorder.c @@ -2,8 +2,8 @@ // SPEX_Cholesky/spex_cholesky_preorder: symbolic ordering/analysis for Cholesky //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Cholesky/Source/spex_cholesky_symbolic_analysis.c b/SPEX/SPEX_Cholesky/Source/spex_cholesky_symbolic_analysis.c index 52836c3f..aac78c10 100644 --- a/SPEX/SPEX_Cholesky/Source/spex_cholesky_symbolic_analysis.c +++ b/SPEX/SPEX_Cholesky/Source/spex_cholesky_symbolic_analysis.c @@ -2,8 +2,8 @@ // SPEX_Cholesky/spex_cholesky_symbolic_analysis: Symbolic analysis for Cholesky //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -78,7 +78,7 @@ SPEX_info spex_cholesky_symbolic_analysis SPEX_CHECK( spex_cholesky_counts(&c, A, S->parent, post) ); // Set the column pointers of L - S->cp = (int64_t*) SPEX_malloc( (n+1)*sizeof(int64_t*)); + S->cp = (int64_t*) SPEX_malloc( (n+1)*sizeof(int64_t)); if (S->cp == NULL) { SPEX_FREE_ALL; diff --git a/SPEX/SPEX_Cholesky/Source/spex_cholesky_tdfs.c b/SPEX/SPEX_Cholesky/Source/spex_cholesky_tdfs.c index a1456cfc..9f7bf67d 100644 --- a/SPEX/SPEX_Cholesky/Source/spex_cholesky_tdfs.c +++ b/SPEX/SPEX_Cholesky/Source/spex_cholesky_tdfs.c @@ -2,8 +2,8 @@ // SPEX_Cholesky/spex_cholesky_tdfs: DFS of a tree rooted at a node //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Cholesky/Source/spex_cholesky_up_factor.c b/SPEX/SPEX_Cholesky/Source/spex_cholesky_up_factor.c index a223426c..06ef00a7 100644 --- a/SPEX/SPEX_Cholesky/Source/spex_cholesky_up_factor.c +++ b/SPEX/SPEX_Cholesky/Source/spex_cholesky_up_factor.c @@ -2,8 +2,8 @@ // SPEX_Cholesky/spex_cholesky_up_factor: Up-looking REF Cholesky factorization //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -92,7 +92,8 @@ SPEX_info spex_cholesky_up_factor int64_t *c = NULL; // Declare variables - int64_t n = A->n, top, i, j, jnew, k; + int64_t n = A->n, i, j, jnew, k; + int64_t top = n ; int sgn, prev_sgn; size_t size; @@ -182,7 +183,6 @@ SPEX_info spex_cholesky_up_factor L->p[k] = c[k] = S->cp[k]; } - //-------------------------------------------------------------------------- // Perform the up-looking factorization //-------------------------------------------------------------------------- diff --git a/SPEX/SPEX_Cholesky/Source/spex_cholesky_up_triangular_solve.c b/SPEX/SPEX_Cholesky/Source/spex_cholesky_up_triangular_solve.c index 79c5e0bf..e6c8a4d1 100644 --- a/SPEX/SPEX_Cholesky/Source/spex_cholesky_up_triangular_solve.c +++ b/SPEX/SPEX_Cholesky/Source/spex_cholesky_up_triangular_solve.c @@ -2,8 +2,8 @@ // SPEX_Cholesky/spex_cholesky_up_triangular_solve: Sparse sym REF tri. solve //------------------------------------------------------------------------------ -// SPEX_Cholesky: (c) 2020-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Cholesky: (c) 2020-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -53,9 +53,11 @@ // Each iteration of the triangular solve requires that the nonzero pattern // is sorted prior to numeric operations. This is the helper function for // c's default qsort -static inline int compare (const void * a, const void * b) +static inline int compar (const void * a, const void * b) { - return ( *(int64_t*)a - *(int64_t*)b ); + int64_t x = (* ((int64_t *) a)) ; + int64_t y = (* ((int64_t *) b)) ; + return (x < y ? -1 : ((x == y) ? 0 : 1)) ; } SPEX_info spex_cholesky_up_triangular_solve @@ -91,10 +93,17 @@ SPEX_info spex_cholesky_up_triangular_solve ASSERT(rhos->type == SPEX_MPZ); ASSERT(rhos->kind == SPEX_DENSE); - int64_t j, i, p, m, top, n = A->n; + int64_t j, i, p, m, n = A->n; int sgn; + (*top_output) = n ; + int64_t top = n ; - ASSERT(n >= 0); + ASSERT (n >= 0) ; + ASSERT (k >= 0 && k < n) ; + ASSERT (parent != NULL) ; + ASSERT (c != NULL) ; + ASSERT (h != NULL) ; + ASSERT (xi != NULL) ; //-------------------------------------------------------------------------- // Initialize REF Triangular Solve by getting the nonzero patern of x && @@ -105,13 +114,17 @@ SPEX_info spex_cholesky_up_triangular_solve // xi[top..n-1] SPEX_CHECK(spex_cholesky_ereach(&top, xi, A, k, parent, c)); + ASSERT (top >= 0 && top <= n) ; + // Sort the nonzero pattern using quicksort (required by IPGE unlike in GE) - qsort(&xi[top], n-top, sizeof(int64_t*), compare); + qsort (&xi[top], n-top, sizeof (int64_t), compar) ; // Reset x[i] = 0 for all i in nonzero pattern xi [top..n-1] for (i = top; i < n; i++) { - SPEX_MPZ_SET_UI(x->x.mpz[xi[i]],0); + j = xi [i] ; + ASSERT (j >= 0 && j <= k) ; + SPEX_MPZ_SET_UI(x->x.mpz[j],0); } // Reset value of x[k]. If the matrix is nonsingular, x[k] will @@ -147,6 +160,9 @@ SPEX_info spex_cholesky_up_triangular_solve { // Obtain the index of the current nonzero j = xi[p]; + + ASSERT (j >= 0 && j <= k) ; + SPEX_MPZ_SGN(&sgn, x->x.mpz[j]); if (sgn == 0) continue; // If x[j] == 0 no work must be done @@ -200,7 +216,6 @@ SPEX_info spex_cholesky_up_triangular_solve h[i] = j; } - //---------------------------------------------------------- /************ Both lij and x[i] are nonzero****************/ // x[i] != 0 --> History & IPGE update on x[i] @@ -255,6 +270,7 @@ SPEX_info spex_cholesky_up_triangular_solve } } } + // ------ History Update x[k] if necessary ----- if (h[k] < j - 1) { @@ -270,6 +286,7 @@ SPEX_info spex_cholesky_up_triangular_solve rhos->x.mpz[h[k]]); } } + // ---- IPGE Update x[k] = (x[k]*rhos[j] - xj*xj) / rho[j-1] ------ // x[k] = x[k] * rho[j] SPEX_MPZ_MUL(x->x.mpz[k],x->x.mpz[k],rhos->x.mpz[j]); @@ -278,12 +295,15 @@ SPEX_info spex_cholesky_up_triangular_solve // Only divide by previous pivot if the previous pivot is not 1 (which // is always the case in the first IPGE iteration) if (j > 0) + { // x[k] = x[k] / rho[j-1] SPEX_MPZ_DIVEXACT(x->x.mpz[k],x->x.mpz[k], rhos->x.mpz[j-1]); + } // Entry is up to date; h[k] = j; } + //---------------------------------------------------------- // At this point, x[k] has been updated throughout the // triangular solve. The last step is to make sure x[k] diff --git a/SPEX/SPEX_LU/License/license.txt b/SPEX/SPEX_LU/License/license.txt index 5174d2bd..a4615bf8 100644 --- a/SPEX/SPEX_LU/License/license.txt +++ b/SPEX/SPEX_LU/License/license.txt @@ -1,7 +1,7 @@ SPEX_LU: a Sparse Left-looking Integer-Preserving LU Factorization -Copyright (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -Timothy A. Davis, and Erick Moreno-Centeno. All Rights Reserved. +Copyright (c) 2019-2024, Christopher Lourenco, Jinhao Chen,, +Erick Moreno-Centeno, and Timothy A. Davis. All Rights Reserved. Available at: https://github.com/clouren/SPEX diff --git a/SPEX/SPEX_LU/Source/SPEX_lu_analyze.c b/SPEX/SPEX_LU/Source/SPEX_lu_analyze.c index 970a4347..63ed8f92 100644 --- a/SPEX/SPEX_LU/Source/SPEX_lu_analyze.c +++ b/SPEX/SPEX_LU/Source/SPEX_lu_analyze.c @@ -2,8 +2,8 @@ // SPEX_Utilities/SPEX_lu_analyze: symbolic ordering and analysis for sparse LU //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Timothy A. Davis, and Erick Moreno-Centeno. All Rights Reserved. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen,, +// Erick Moreno-Centeno, and Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ diff --git a/SPEX/SPEX_LU/Source/SPEX_lu_backslash.c b/SPEX/SPEX_LU/Source/SPEX_lu_backslash.c index 8739db22..db16f1ce 100644 --- a/SPEX/SPEX_LU/Source/SPEX_lu_backslash.c +++ b/SPEX/SPEX_LU/Source/SPEX_lu_backslash.c @@ -2,8 +2,8 @@ // SPEX_LU/SPEX_lu_backslash: solve Ax=b, return solution as desired data type //------------------------------------------------------------------------------ -// SPEX_LU: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Timothy A. Davis, and Erick Moreno-Centeno. All Rights Reserved. +// SPEX_LU: (c) 2019-2024, Christopher Lourenco, Jinhao Chen,, +// Erick Moreno-Centeno, and Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ diff --git a/SPEX/SPEX_LU/Source/SPEX_lu_factorize.c b/SPEX/SPEX_LU/Source/SPEX_lu_factorize.c index eac75058..0e79ac62 100644 --- a/SPEX/SPEX_LU/Source/SPEX_lu_factorize.c +++ b/SPEX/SPEX_LU/Source/SPEX_lu_factorize.c @@ -2,8 +2,8 @@ // SPEX_LU/SPEX_lu_factorize: exact sparse LU factorization //------------------------------------------------------------------------------ -// SPEX_LU: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Timothy A. Davis, and Erick Moreno-Centeno. All Rights Reserved. +// SPEX_LU: (c) 2019-2024, Christopher Lourenco, Jinhao Chen,, +// Erick Moreno-Centeno, and Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ diff --git a/SPEX/SPEX_LU/Source/SPEX_lu_solve.c b/SPEX/SPEX_LU/Source/SPEX_lu_solve.c index 4dca51d7..09ace23d 100644 --- a/SPEX/SPEX_LU/Source/SPEX_lu_solve.c +++ b/SPEX/SPEX_LU/Source/SPEX_lu_solve.c @@ -2,8 +2,8 @@ // SPEX_LU/SPEX_lu_solve: exact solution of Ax=b //------------------------------------------------------------------------------ -// SPEX_LU: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Timothy A. Davis, and Erick Moreno-Centeno. All Rights Reserved. +// SPEX_LU: (c) 2019-2024, Christopher Lourenco, Jinhao Chen,, +// Erick Moreno-Centeno, and Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ diff --git a/SPEX/SPEX_LU/Source/spex_left_lu_back_sub.c b/SPEX/SPEX_LU/Source/spex_left_lu_back_sub.c index 6cc147e7..a0ff47f8 100644 --- a/SPEX/SPEX_LU/Source/spex_left_lu_back_sub.c +++ b/SPEX/SPEX_LU/Source/spex_left_lu_back_sub.c @@ -2,8 +2,8 @@ // SPEX_LU/spex_left_lu_back_sub: sparse REF backward substitution (x = U\x) //------------------------------------------------------------------------------ -// SPEX_LU: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Timothy A. Davis, and Erick Moreno-Centeno. All Rights Reserved. +// SPEX_LU: (c) 2019-2024, Christopher Lourenco, Jinhao Chen,, +// Erick Moreno-Centeno, and Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ diff --git a/SPEX/SPEX_LU/Source/spex_left_lu_dfs.c b/SPEX/SPEX_LU/Source/spex_left_lu_dfs.c index 2f0b8cbe..1cb5f119 100644 --- a/SPEX/SPEX_LU/Source/spex_left_lu_dfs.c +++ b/SPEX/SPEX_LU/Source/spex_left_lu_dfs.c @@ -2,8 +2,8 @@ // SPEX_LU/spex_left_lu_dfs: depth-first search //------------------------------------------------------------------------------ -// SPEX_LU: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Timothy A. Davis, and Erick Moreno-Centeno. All Rights Reserved. +// SPEX_LU: (c) 2019-2024, Christopher Lourenco, Jinhao Chen,, +// Erick Moreno-Centeno, and Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ diff --git a/SPEX/SPEX_LU/Source/spex_left_lu_forward_sub.c b/SPEX/SPEX_LU/Source/spex_left_lu_forward_sub.c index 1e136690..4177697c 100644 --- a/SPEX/SPEX_LU/Source/spex_left_lu_forward_sub.c +++ b/SPEX/SPEX_LU/Source/spex_left_lu_forward_sub.c @@ -2,8 +2,8 @@ // SPEX_LU/spex_left_lu_forward_sub: sparse forward substitution (x = (LD)\x) //------------------------------------------------------------------------------ -// SPEX_LU: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Timothy A. Davis, and Erick Moreno-Centeno. All Rights Reserved. +// SPEX_LU: (c) 2019-2024, Christopher Lourenco, Jinhao Chen,, +// Erick Moreno-Centeno, and Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ diff --git a/SPEX/SPEX_LU/Source/spex_left_lu_get_largest_pivot.c b/SPEX/SPEX_LU/Source/spex_left_lu_get_largest_pivot.c index cd96bb01..a09a28dd 100644 --- a/SPEX/SPEX_LU/Source/spex_left_lu_get_largest_pivot.c +++ b/SPEX/SPEX_LU/Source/spex_left_lu_get_largest_pivot.c @@ -2,8 +2,8 @@ // SPEX_LU/spex_left_lu_get_largest_pivot: find a pivot entry in a column //------------------------------------------------------------------------------ -// SPEX_LU: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Timothy A. Davis, and Erick Moreno-Centeno. All Rights Reserved. +// SPEX_LU: (c) 2019-2024, Christopher Lourenco, Jinhao Chen,, +// Erick Moreno-Centeno, and Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ @@ -18,7 +18,7 @@ */ #define SPEX_FREE_ALL \ - SPEX_MPZ_CLEAR(big); + SPEX_mpz_clear (big); #include "spex_lu_internal.h" @@ -51,7 +51,7 @@ SPEX_info spex_left_lu_get_largest_pivot int r ; (*pivot) = -1 ; mpz_t big ; - SPEX_MPZ_SET_NULL (big); + SPEX_mpz_set_null (big); SPEX_MPZ_INIT (big); //-------------------------------------------------------------------------- diff --git a/SPEX/SPEX_LU/Source/spex_left_lu_get_nonzero_pivot.c b/SPEX/SPEX_LU/Source/spex_left_lu_get_nonzero_pivot.c index 3dc8e88b..0366c092 100644 --- a/SPEX/SPEX_LU/Source/spex_left_lu_get_nonzero_pivot.c +++ b/SPEX/SPEX_LU/Source/spex_left_lu_get_nonzero_pivot.c @@ -2,8 +2,8 @@ // SPEX_LU/spex_left_lu_get_nonzero_pivot: find a nonzero pivot in a column //------------------------------------------------------------------------------ -// SPEX_LU: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Timothy A. Davis, and Erick Moreno-Centeno. All Rights Reserved. +// SPEX_LU: (c) 2019-2024, Christopher Lourenco, Jinhao Chen,, +// Erick Moreno-Centeno, and Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ diff --git a/SPEX/SPEX_LU/Source/spex_left_lu_get_pivot.c b/SPEX/SPEX_LU/Source/spex_left_lu_get_pivot.c index 3e8753b1..21ae715d 100644 --- a/SPEX/SPEX_LU/Source/spex_left_lu_get_pivot.c +++ b/SPEX/SPEX_LU/Source/spex_left_lu_get_pivot.c @@ -2,8 +2,8 @@ // SPEX_LU/spex_left_lu_get_pivot: find a pivot entry in a column //------------------------------------------------------------------------------ -// SPEX_LU: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Timothy A. Davis, and Erick Moreno-Centeno. All Rights Reserved. +// SPEX_LU: (c) 2019-2024, Christopher Lourenco, Jinhao Chen,, +// Erick Moreno-Centeno, and Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ @@ -25,8 +25,8 @@ */ #define SPEX_FREE_ALL \ - SPEX_MPQ_CLEAR (tol); \ - SPEX_MPQ_CLEAR (ratio); + SPEX_mpq_clear (tol); \ + SPEX_mpq_clear (ratio); #include "spex_lu_internal.h" @@ -67,8 +67,8 @@ SPEX_info spex_left_lu_get_pivot int sgn, r; mpq_t tol, ratio; - SPEX_MPQ_SET_NULL(tol); - SPEX_MPQ_SET_NULL(ratio); + SPEX_mpq_set_null (tol); + SPEX_mpq_set_null (ratio); if (order == SPEX_SMALLEST) { diff --git a/SPEX/SPEX_LU/Source/spex_left_lu_get_smallest_pivot.c b/SPEX/SPEX_LU/Source/spex_left_lu_get_smallest_pivot.c index 27694711..e50cfb85 100644 --- a/SPEX/SPEX_LU/Source/spex_left_lu_get_smallest_pivot.c +++ b/SPEX/SPEX_LU/Source/spex_left_lu_get_smallest_pivot.c @@ -2,8 +2,8 @@ // SPEX_LU/spex_left_lu_get_smallest_pivot: find the smallest entry in a column //------------------------------------------------------------------------------ -// SPEX_LU: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Timothy A. Davis, and Erick Moreno-Centeno. All Rights Reserved. +// SPEX_LU: (c) 2019-2024, Christopher Lourenco, Jinhao Chen,, +// Erick Moreno-Centeno, and Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ @@ -16,7 +16,7 @@ */ #define SPEX_FREE_ALL \ - SPEX_MPZ_CLEAR(small); + SPEX_mpz_clear (small); #include "spex_lu_internal.h" @@ -49,7 +49,7 @@ SPEX_info spex_left_lu_get_smallest_pivot (*pivot) = -1; j = n; flag = top; - mpz_t small; SPEX_MPZ_SET_NULL(small); + mpz_t small; SPEX_mpz_set_null (small); SPEX_MPZ_INIT(small); //-------------------------------------------------------------------------- diff --git a/SPEX/SPEX_LU/Source/spex_left_lu_reach.c b/SPEX/SPEX_LU/Source/spex_left_lu_reach.c index e73d84f4..03cb5e6a 100644 --- a/SPEX/SPEX_LU/Source/spex_left_lu_reach.c +++ b/SPEX/SPEX_LU/Source/spex_left_lu_reach.c @@ -2,8 +2,8 @@ // SPEX_LU/spex_left_lu_reach: compute set of nodes reachable from an input set //------------------------------------------------------------------------------ -// SPEX_LU: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Timothy A. Davis, and Erick Moreno-Centeno. All Rights Reserved. +// SPEX_LU: (c) 2019-2024, Christopher Lourenco, Jinhao Chen,, +// Erick Moreno-Centeno, and Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ diff --git a/SPEX/SPEX_LU/Source/spex_left_lu_ref_triangular_solve.c b/SPEX/SPEX_LU/Source/spex_left_lu_ref_triangular_solve.c index f2816102..d5a7b89c 100644 --- a/SPEX/SPEX_LU/Source/spex_left_lu_ref_triangular_solve.c +++ b/SPEX/SPEX_LU/Source/spex_left_lu_ref_triangular_solve.c @@ -2,8 +2,8 @@ // SPEX_LU/spex_left_lu_ref_triangular_solve: sparse REF triangular solve //------------------------------------------------------------------------------ -// SPEX_LU: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Timothy A. Davis, and Erick Moreno-Centeno. All Rights Reserved. +// SPEX_LU: (c) 2019-2024, Christopher Lourenco, Jinhao Chen,, +// Erick Moreno-Centeno, and Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ @@ -74,6 +74,10 @@ static inline int compare (const void * a, const void * b) { return ( *(int64_t*)a - *(int64_t*)b ); + + int64_t x = (* ((int64_t *) a)) ; + int64_t y = (* ((int64_t *) b)) ; + return (x < y ? -1 : ((x == y) ? 0 : 1)) ; } SPEX_info spex_left_lu_ref_triangular_solve // sparse REF triangular solve @@ -132,7 +136,7 @@ SPEX_info spex_left_lu_ref_triangular_solve // sparse REF triangular solve } // Sort xi[top..n-1] - qsort(&xi[top], n-top, sizeof(int64_t), compare); + qsort (&xi[top], n-top, sizeof (int64_t), compare) ; // Place xi back in original value for (j = top; j < n; j++) diff --git a/SPEX/SPEX_LU/Source/spex_lu_internal.h b/SPEX/SPEX_LU/Source/spex_lu_internal.h index 577e4bf4..73ba8990 100644 --- a/SPEX/SPEX_LU/Source/spex_lu_internal.h +++ b/SPEX/SPEX_LU/Source/spex_lu_internal.h @@ -3,8 +3,8 @@ // SPEX_LU //------------------------------------------------------------------------------ -// SPEX_LU: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Timothy A. Davis, and Erick Moreno-Centeno. All Rights Reserved. +// SPEX_LU: (c) 2019-2024, Christopher Lourenco, Jinhao Chen,, +// Erick Moreno-Centeno, and Timothy A. Davis. All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ diff --git a/SPEX/SPEX_Utilities/License/license.txt b/SPEX/SPEX_Utilities/License/license.txt index 44cb8856..dc366870 100644 --- a/SPEX/SPEX_Utilities/License/license.txt +++ b/SPEX/SPEX_Utilities/License/license.txt @@ -1,7 +1,7 @@ SPEX_Utilities: Utility functions for SParse EXact package -Copyright (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +Copyright (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. All Rights Reserved. Available at: diff --git a/SPEX/SPEX_Utilities/Source/SPEX_calloc.c b/SPEX/SPEX_Utilities/Source/SPEX_calloc.c index 49bdc9d4..fa982af8 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_calloc.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_calloc.c @@ -2,8 +2,8 @@ // SPEX_Utilities/SPEX_calloc: wrapper for calloc //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/SPEX_create_default_options.c b/SPEX/SPEX_Utilities/Source/SPEX_create_default_options.c index e521a3e8..16366824 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_create_default_options.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_create_default_options.c @@ -2,8 +2,8 @@ // SPEX_Utilities/SPEX_create_default_options: set defaults //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/SPEX_determine_symmetry.c b/SPEX/SPEX_Utilities/Source/SPEX_determine_symmetry.c index a6f14b86..f85cc5f9 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_determine_symmetry.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_determine_symmetry.c @@ -3,8 +3,8 @@ // *numerically* (thus pattern-wise) symmetric //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/SPEX_factorization_free.c b/SPEX/SPEX_Utilities/Source/SPEX_factorization_free.c index c9ae0116..bce7d24f 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_factorization_free.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_factorization_free.c @@ -3,8 +3,8 @@ // SPEX_factorization data type. //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -29,7 +29,7 @@ SPEX_info SPEX_factorization_free if ((F_handle != NULL) && (*F_handle != NULL)) { - SPEX_MPQ_CLEAR((*F_handle)->scale_for_A); + SPEX_mpq_clear ((*F_handle)->scale_for_A); SPEX_matrix_free(&((*F_handle)->L), option); SPEX_matrix_free(&((*F_handle)->U), option); diff --git a/SPEX/SPEX_Utilities/Source/SPEX_finalize.c b/SPEX/SPEX_Utilities/Source/SPEX_finalize.c index 9276f9fc..5bfeed35 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_finalize.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_finalize.c @@ -2,8 +2,8 @@ // SPEX_Utilities/SPEX_finalize: finalize SPEX //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/SPEX_free.c b/SPEX/SPEX_Utilities/Source/SPEX_free.c index 28db44e2..c746a62e 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_free.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_free.c @@ -2,8 +2,8 @@ // SPEX_Utilities/SPEX_free: wrapper for free //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/SPEX_gmp.c b/SPEX/SPEX_Utilities/Source/SPEX_gmp.c index 56ed2b1f..217a9110 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_gmp.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_gmp.c @@ -2,8 +2,8 @@ // SPEX_Utilities/SPEX_gmp.c: interface to the gmp library //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -66,7 +66,9 @@ #include "spex_util_internal.h" // ignore warnings about unused parameters in this file +#if defined (__GNUC__) #pragma GCC diagnostic ignored "-Wunused-parameter" +#endif //------------------------------------------------------------------------------ // thread-local-storage @@ -118,6 +120,7 @@ // SPEX will not be thread-safe. spex_gmp_t *spex_gmp = NULL ; + #warning "SPEX not compiled with OpenMP or thread keyword; SPEX will not be thread-safe!" #endif @@ -128,10 +131,10 @@ #define SPEX_GMP_WRAPPER_START_HELPER(z1,z2,q,fr) \ /* spex_gmp_t *spex_gmp = spex_gmp_get ( ) ; */ \ if (spex_gmp == NULL) return (SPEX_OUT_OF_MEMORY); \ - spex_gmp->mpz_archive = (mpz_t *) z1 ; \ - spex_gmp->mpz_archive2 = (mpz_t *) z2 ; \ - spex_gmp->mpq_archive = (mpq_t *) q ; \ - spex_gmp->mpfr_archive = (mpfr_t *) fr ; \ + spex_gmp->mpz_archive = z1 ; \ + spex_gmp->mpz_archive2 = z2 ; \ + spex_gmp->mpq_archive = q ; \ + spex_gmp->mpfr_archive = fr ; \ /* setjmp returns 0 if called from here, or > 0 if from longjmp */ \ int status = setjmp (spex_gmp->environment) ; \ if (status != 0) \ @@ -368,38 +371,44 @@ void *spex_gmp_allocate // spex_gmp_safe_free: free a block of memory and remove it from the archive //------------------------------------------------------------------------------ +// see mpfr-4.2.1/src/mpfr-impl.h, for MPFR_GET_REAL_PTR +#define SPEX_MPFR_GET_REAL_PTR(x) ((x)->_mpfr_d - 1) + static inline void spex_gmp_safe_free (void *p) { if (spex_gmp != NULL) { if (spex_gmp->mpz_archive != NULL) { - if (p == SPEX_MPZ_PTR(*(spex_gmp->mpz_archive))) + if (p == SPEX_MPZ_PTR((spex_gmp->mpz_archive))) { - SPEX_MPZ_PTR(*(spex_gmp->mpz_archive)) = NULL ; + SPEX_MPZ_PTR((spex_gmp->mpz_archive)) = NULL ; } } if (spex_gmp->mpz_archive2 != NULL) { - if (p == SPEX_MPZ_PTR(*(spex_gmp->mpz_archive2))) + if (p == SPEX_MPZ_PTR((spex_gmp->mpz_archive2))) { - SPEX_MPZ_PTR(*(spex_gmp->mpz_archive2)) = NULL ; + SPEX_MPZ_PTR((spex_gmp->mpz_archive2)) = NULL ; } } if (spex_gmp->mpq_archive != NULL) { - if (p == SPEX_MPZ_PTR(SPEX_MPQ_NUM(*spex_gmp->mpq_archive))) + if (p == SPEX_MPZ_PTR(SPEX_MPQ_NUM(spex_gmp->mpq_archive))) { - SPEX_MPZ_PTR(SPEX_MPQ_NUM(*spex_gmp->mpq_archive)) = NULL ; + SPEX_MPZ_PTR(SPEX_MPQ_NUM(spex_gmp->mpq_archive)) = NULL ; } - if (p == SPEX_MPZ_PTR(SPEX_MPQ_DEN(*spex_gmp->mpq_archive))) + if (p == SPEX_MPZ_PTR(SPEX_MPQ_DEN(spex_gmp->mpq_archive))) { - SPEX_MPZ_PTR(SPEX_MPQ_DEN(*spex_gmp->mpq_archive)) = NULL ; + SPEX_MPZ_PTR(SPEX_MPQ_DEN(spex_gmp->mpq_archive)) = NULL ; } } if (spex_gmp->mpfr_archive != NULL) { - if (p == SPEX_MPFR_REAL_PTR(*spex_gmp->mpfr_archive)) SPEX_MPFR_MANT(*spex_gmp->mpfr_archive) = NULL ; + if (p == SPEX_MPFR_GET_REAL_PTR(spex_gmp->mpfr_archive)) + { + SPEX_MPFR_MANT(spex_gmp->mpfr_archive) = NULL ; + } } } SPEX_FREE (p) ; @@ -1155,7 +1164,7 @@ SPEX_info SPEX_mpz_divexact return (SPEX_PANIC); } - #ifdef SPEX_DEBUG +#ifdef SPEX_DEBUG mpq_t r ; mpq_init (r); // r = 0/1 mpz_fdiv_r (SPEX_MPQ_NUM (r), y, z); @@ -1169,7 +1178,7 @@ SPEX_info SPEX_mpz_divexact return (SPEX_PANIC); } mpq_clear (r); - #endif +#endif mpz_divexact (x, y, z); SPEX_GMP_WRAPPER_FINISH ; @@ -1778,7 +1787,10 @@ SPEX_info SPEX_mpfr_init2 ) { // ensure the mpfr number is not too big - if (size > MPFR_PREC_MAX/2) return (SPEX_PANIC); + if (size > MPFR_PREC_MAX/2) + { + return (SPEX_PANIC); + } // initialize the mpfr number SPEX_GMPFR_WRAPPER_START (x); @@ -1787,6 +1799,31 @@ SPEX_info SPEX_mpfr_init2 return (SPEX_OK); } +//------------------------------------------------------------------------------ +// SPEX_mpfr_set_prec +//------------------------------------------------------------------------------ + +/* Purpose: Set the precision of an mpfr_t number */ + +SPEX_info SPEX_mpfr_set_prec +( + mpfr_t x, // Floating point number to revise + const uint64_t size // # of bits in x +) +{ + // ensure the mpfr number is not too big + if (size > MPFR_PREC_MAX/2) + { + return (SPEX_PANIC); + } + + // set the precision of the mpfr number + SPEX_GMPFR_WRAPPER_START (x); + mpfr_set_prec (x, (mpfr_prec_t) size); + SPEX_GMP_WRAPPER_FINISH ; + return (SPEX_OK); +} + //------------------------------------------------------------------------------ // SPEX_mpfr_set //------------------------------------------------------------------------------ @@ -2101,3 +2138,96 @@ SPEX_info SPEX_mpfr_free_cache ( void ) return (SPEX_OK); } +//------------------------------------------------------------------------------ +// SPEX_mpz_set_null +//------------------------------------------------------------------------------ + +// Purpose: initialize the contents of an mpz_t value + +SPEX_info SPEX_mpz_set_null +( + mpz_t x +) +{ + SPEX_MPZ_SET_NULL (x) ; + return (SPEX_OK); +} + +//------------------------------------------------------------------------------ +// SPEX_mpq_set_null +//------------------------------------------------------------------------------ + +// Purpose: initialize the contents of an mpq_t value + +SPEX_info SPEX_mpq_set_null +( + mpq_t x +) +{ + SPEX_MPQ_SET_NULL (x) ; + return (SPEX_OK); +} + +//------------------------------------------------------------------------------ +// SPEX_mpfr_set_null +//------------------------------------------------------------------------------ + +// Purpose: initialize the contents of an mpfr_t value + +SPEX_info SPEX_mpfr_set_null +( + mpfr_t x +) +{ + SPEX_MPFR_SET_NULL (x) ; + return (SPEX_OK); +} + +//------------------------------------------------------------------------------ +// SPEX_mpz_clear +//------------------------------------------------------------------------------ + +// Purpose: safely clear an mpz_t value + +SPEX_info SPEX_mpz_clear +( + mpz_t x +) +{ + SPEX_MPZ_CLEAR (x) ; + return (SPEX_OK); +} + +//------------------------------------------------------------------------------ +// SPEX_mpq_clear +//------------------------------------------------------------------------------ + +// Purpose: safely clear an mpq_t value + +SPEX_info SPEX_mpq_clear +( + mpq_t x +) +{ + if (x != NULL) + { + SPEX_MPQ_CLEAR (x) ; + } + return (SPEX_OK); +} + +//------------------------------------------------------------------------------ +// SPEX_mpfr_clear +//------------------------------------------------------------------------------ + +// Purpose: safely clear an mpfr_t value + +SPEX_info SPEX_mpfr_clear +( + mpfr_t x +) +{ + SPEX_MPFR_CLEAR (x) ; + return (SPEX_OK); +} + diff --git a/SPEX/SPEX_Utilities/Source/SPEX_initialize.c b/SPEX/SPEX_Utilities/Source/SPEX_initialize.c index 424802b4..869eb915 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_initialize.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_initialize.c @@ -2,8 +2,8 @@ // SPEX_Utilities/SPEX_initialize: initialize SPEX //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -38,10 +38,11 @@ void spex_set_initialized (bool s) SPEX_info SPEX_initialize ( void ) { - if (spex_initialized( )) return (SPEX_PANIC); - - // SPEX requires GMP to support bit counts that are 64-bit integers - if (sizeof (mp_bitcnt_t) < sizeof (uint64_t)) return (SPEX_PANIC); + if (spex_initialized( )) + { + // SPEX is already initialized + return (SPEX_PANIC); + } // tell GMP and MPFR which memory allocation functions to use mp_set_memory_functions diff --git a/SPEX/SPEX_Utilities/Source/SPEX_initialize_expert.c b/SPEX/SPEX_Utilities/Source/SPEX_initialize_expert.c index 5d1d7e58..819ef97b 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_initialize_expert.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_initialize_expert.c @@ -2,8 +2,8 @@ // SPEX_Utilities/SPEX_initialize_expert: intialize SPEX memory functions for GMP //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/SPEX_malloc.c b/SPEX/SPEX_Utilities/Source/SPEX_malloc.c index 422a138f..ac93fdc7 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_malloc.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_malloc.c @@ -2,8 +2,8 @@ // SPEX_Utilities/SPEX_malloc: wrapper for malloc //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/SPEX_matrix_allocate.c b/SPEX/SPEX_Utilities/Source/SPEX_matrix_allocate.c index 1fb6dea4..95ac35c7 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_matrix_allocate.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_matrix_allocate.c @@ -2,8 +2,8 @@ // SPEX_Utilities/SPEX_matrix_allocate: allocate a SPEX_matrix //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -24,11 +24,20 @@ #define SPEX_FREE_ALL \ { \ - SPEX_matrix_free (&A, option); \ + SPEX_matrix_free (&A, option); \ } #include "spex_util_internal.h" +#if defined (__GNUC__) + #if ( __GNUC__ == 11) + // gcc 11 has a bug that triggers a spurious warning for the call + // to SPEX_MPQ_INIT (A->scale), from -Wstringop-overflow. see + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101854 + #pragma GCC diagnostic ignored "-Wstringop-overflow" + #endif +#endif + SPEX_info SPEX_matrix_allocate ( SPEX_matrix *A_handle, // matrix to allocate @@ -101,7 +110,7 @@ SPEX_info SPEX_matrix_allocate A->x_shallow = false ; // A->scale = 1 - SPEX_CHECK (spex_create_mpq (A->scale)); + SPEX_MPQ_INIT (A->scale) ; SPEX_MPQ_SET_UI (A->scale, 1, 1); //-------------------------------------------------------------------------- diff --git a/SPEX/SPEX_Utilities/Source/SPEX_matrix_check.c b/SPEX/SPEX_Utilities/Source/SPEX_matrix_check.c index a1c5da53..f40223b8 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_matrix_check.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_matrix_check.c @@ -2,17 +2,19 @@ // SPEX_Utilities/SPEX_matrix_check: check if a matrix is OK //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ -#define SPEX_FREE_ALL \ - SPEX_FREE (work); \ - SPEX_MPZ_CLEAR(q); \ - SPEX_MPZ_CLEAR(r); +#define SPEX_FREE_ALL \ +{ \ + SPEX_FREE (work); \ + SPEX_mpz_clear (q); \ + SPEX_mpz_clear (r); \ +} #include "spex_util_internal.h" @@ -21,7 +23,7 @@ lines++ ; \ if (pr == 2 && lines > 30) \ { \ - SPEX_PRINTF (" ...\n"); \ + SPEX_PRINTF (" ...\n"); \ pr = 1 ; \ } @@ -143,8 +145,8 @@ SPEX_info SPEX_matrix_check // returns a SPEX status code // paranoia: check prec here: cast to mprf_prec_t, and back, assert // equality, if not equal then return SPEX_PANIC mpz_t q, r; - SPEX_MPZ_SET_NULL(q); - SPEX_MPZ_SET_NULL(r); + SPEX_mpz_set_null (q); + SPEX_mpz_set_null (r); int64_t lines = 0 ; // # of lines printed so far @@ -418,7 +420,7 @@ SPEX_info SPEX_matrix_check // returns a SPEX status code } // sort the (i,j) indices - qsort (work, nz, 2 * sizeof (int64_t), compar); + qsort (work, nz, 2 * sizeof (int64_t), compar) ; // check for duplicates for (p = 1 ; p < nz ; p++) diff --git a/SPEX/SPEX_Utilities/Source/SPEX_matrix_copy.c b/SPEX/SPEX_Utilities/Source/SPEX_matrix_copy.c index efb5fafe..dc27a9b6 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_matrix_copy.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_matrix_copy.c @@ -2,8 +2,8 @@ // SPEX_Utilities/SPEX_matrix_copy: create a copy of a matrix //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/SPEX_matrix_free.c b/SPEX/SPEX_Utilities/Source/SPEX_matrix_free.c index c7a5d9f1..0edf8e5d 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_matrix_free.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_matrix_free.c @@ -2,15 +2,17 @@ // SPEX_Utilities/SPEX_matrix_free: free a SPEX_matrix //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ // Free a SPEX_matrix. Any shallow component is not freed. +#if defined (__GNUC__) #pragma GCC diagnostic ignored "-Wunused-variable" +#endif #include "spex_util_internal.h" SPEX_info SPEX_matrix_free @@ -37,67 +39,44 @@ SPEX_info SPEX_matrix_free // free any non-shallow components //-------------------------------------------------------------------------- - - // free the integer pattern - if (!(A->p_shallow)) SPEX_FREE (A->p); - if (!(A->i_shallow)) SPEX_FREE (A->i); - if (!(A->j_shallow)) SPEX_FREE (A->j); + // free the integer pattern + if (!(A->p_shallow)) SPEX_FREE (A->p); + if (!(A->i_shallow)) SPEX_FREE (A->i); + if (!(A->j_shallow)) SPEX_FREE (A->j); - // free the values - if (!(A->x_shallow)) + // free the values + if (!(A->x_shallow)) + { + switch (A->type) { - switch (A->type) - { - case SPEX_MPZ: - if ( A->x.mpz != NULL) - { - for (int64_t i = 0; i < A->nzmax; i++) - { - SPEX_MPZ_CLEAR( A->x.mpz[i]); - } - } - SPEX_FREE (A->x.mpz); - break ; - - case SPEX_MPQ: - if ( A->x.mpq != NULL) - { - for (int64_t i = 0; i < A->nzmax; i++) - { - SPEX_MPQ_CLEAR( A->x.mpq[i]); - } - } - SPEX_FREE (A->x.mpq); - break ; - - case SPEX_MPFR: - if ( A->x.mpfr != NULL) - { - for (int64_t i = 0; i < A->nzmax; i++) - { - SPEX_MPFR_CLEAR( A->x.mpfr[i]); - } - } - SPEX_FREE (A->x.mpfr); - break ; - - case SPEX_INT64: - SPEX_FREE (A->x.int64); - break ; - - case SPEX_FP64: - SPEX_FREE (A->x.fp64); - break ; - - default: - // do nothing - break ; - } - } + case SPEX_MPZ: + spex_free_mpz_array (&(A->x.mpz), A->nzmax) ; + break ; + + case SPEX_MPQ: + spex_free_mpq_array (&(A->x.mpq), A->nzmax) ; + break ; + + case SPEX_MPFR: + spex_free_mpfr_array (&(A->x.mpfr), A->nzmax) ; + break ; + case SPEX_INT64: + SPEX_FREE (A->x.int64) ; + break ; + + case SPEX_FP64: + SPEX_FREE (A->x.fp64) ; + break ; + + default: + // do nothing + break ; + } + } // A->scale is never shallow - SPEX_MPQ_CLEAR (A->scale); + SPEX_mpq_clear (A->scale); //-------------------------------------------------------------------------- // free the header diff --git a/SPEX/SPEX_Utilities/Source/SPEX_matrix_nnz.c b/SPEX/SPEX_Utilities/Source/SPEX_matrix_nnz.c index 2d5e8fe1..0747e676 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_matrix_nnz.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_matrix_nnz.c @@ -2,14 +2,16 @@ // SPEX_Utilities/SPEX_matrix_nnz: find # of entries in a matrix //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ +#if defined (__GNUC__) #pragma GCC diagnostic ignored "-Wunused-variable" +#endif #include "spex_util_internal.h" SPEX_info SPEX_matrix_nnz // find the # of entries in A diff --git a/SPEX/SPEX_Utilities/Source/SPEX_realloc.c b/SPEX/SPEX_Utilities/Source/SPEX_realloc.c index b5e9ebce..a8b0a526 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_realloc.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_realloc.c @@ -2,8 +2,8 @@ // SPEX_Utilities/SPEX_realloc: wrapper for realloc //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/SPEX_symbolic_analysis_free.c b/SPEX/SPEX_Utilities/Source/SPEX_symbolic_analysis_free.c index 7666123b..e32a7bf3 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_symbolic_analysis_free.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_symbolic_analysis_free.c @@ -3,8 +3,8 @@ // SPEX_symbolic_analysis data type. //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/SPEX_thread_finalize.c b/SPEX/SPEX_Utilities/Source/SPEX_thread_finalize.c index 2e53c7a8..fddb7f96 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_thread_finalize.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_thread_finalize.c @@ -2,8 +2,8 @@ // SPEX_Utilities/SPEX_thread_finalize: finish SPEX for a single user thread //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/SPEX_thread_initialize.c b/SPEX/SPEX_Utilities/Source/SPEX_thread_initialize.c index 67ab3bd2..f13b5bf7 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_thread_initialize.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_thread_initialize.c @@ -2,8 +2,8 @@ // SPEX_Utilities/SPEX_thread_initialize: init SPEX for a single user thread //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/SPEX_transpose.c b/SPEX/SPEX_Utilities/Source/SPEX_transpose.c index 177ee8c3..6fa83e82 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_transpose.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_transpose.c @@ -2,8 +2,8 @@ // SPEX_Utilities/SPEX_transpose: Transpose a CSC matrix //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/SPEX_version.c b/SPEX/SPEX_Utilities/Source/SPEX_version.c index de4c09d4..46918528 100644 --- a/SPEX/SPEX_Utilities/Source/SPEX_version.c +++ b/SPEX/SPEX_Utilities/Source/SPEX_version.c @@ -2,8 +2,8 @@ // SPEX_Utilities/SPEX_version: report SPEX version information //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/spex_amd.c b/SPEX/SPEX_Utilities/Source/spex_amd.c index 7f41ab89..d5dfa81d 100644 --- a/SPEX/SPEX_Utilities/Source/spex_amd.c +++ b/SPEX/SPEX_Utilities/Source/spex_amd.c @@ -2,8 +2,8 @@ // SPEX_Utilities/spex_amd: Call AMD for matrix ordering //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/spex_cast_array.c b/SPEX/SPEX_Utilities/Source/spex_cast_array.c index 6d54368e..f1bb6349 100644 --- a/SPEX/SPEX_Utilities/Source/spex_cast_array.c +++ b/SPEX/SPEX_Utilities/Source/spex_cast_array.c @@ -2,8 +2,8 @@ // SPEX_Utilities/spex_cast_array: scale and typecast an array //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -35,11 +35,12 @@ // y_scale = 1. // -#define SPEX_FREE_ALL \ -SPEX_MPQ_CLEAR(temp); \ +#define SPEX_FREE_ALL SPEX_mpq_clear (temp) ; #include "spex_util_internal.h" +#if defined (__GNUC__) #pragma GCC diagnostic ignored "-Wunused-variable" +#endif SPEX_info spex_cast_array ( @@ -65,7 +66,7 @@ SPEX_info spex_cast_array } SPEX_info info ; int r; - mpq_t temp; SPEX_MPQ_SET_NULL(temp); + mpq_t temp; SPEX_mpq_set_null (temp); mpfr_rnd_t round = SPEX_OPTION_ROUND (option); diff --git a/SPEX/SPEX_Utilities/Source/spex_cast_matrix.c b/SPEX/SPEX_Utilities/Source/spex_cast_matrix.c index 223971e2..38fdd594 100644 --- a/SPEX/SPEX_Utilities/Source/spex_cast_matrix.c +++ b/SPEX/SPEX_Utilities/Source/spex_cast_matrix.c @@ -2,8 +2,8 @@ // SPEX_Utilities/spex_cast_matrix: create a dense typecasted matrix //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/spex_colamd.c b/SPEX/SPEX_Utilities/Source/spex_colamd.c index ff9cfb27..b1abcd43 100644 --- a/SPEX/SPEX_Utilities/Source/spex_colamd.c +++ b/SPEX/SPEX_Utilities/Source/spex_colamd.c @@ -2,8 +2,8 @@ // SPEX_Utilities/spex_colamd: Call COLAMD for matrix ordering //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/spex_create_mpfr_array.c b/SPEX/SPEX_Utilities/Source/spex_create_mpfr_array.c index 7b737460..85b9e363 100644 --- a/SPEX/SPEX_Utilities/Source/spex_create_mpfr_array.c +++ b/SPEX/SPEX_Utilities/Source/spex_create_mpfr_array.c @@ -2,8 +2,8 @@ // SPEX_Utilities/spex_create_mpfr_array: create a dense mpfr array //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -38,12 +38,8 @@ mpfr_t *spex_create_mpfr_array { if (SPEX_mpfr_init2(x[i], prec) != SPEX_OK) { - SPEX_MPFR_SET_NULL(x[i]); - for (int64_t j = 0; j < i; j++) - { - SPEX_MPFR_CLEAR( x[j]); - } - SPEX_FREE(x); + SPEX_mpfr_set_null (x[i]); + spex_free_mpfr_array (&x, n) ; return NULL; } } diff --git a/SPEX/SPEX_Utilities/Source/spex_create_mpq.c b/SPEX/SPEX_Utilities/Source/spex_create_mpq.c deleted file mode 100644 index 1571e204..00000000 --- a/SPEX/SPEX_Utilities/Source/spex_create_mpq.c +++ /dev/null @@ -1,37 +0,0 @@ -//------------------------------------------------------------------------------ -// SPEX_Utilities/spex_create_mpq: create an mpq_t entry -//------------------------------------------------------------------------------ - -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. -// All Rights Reserved. -// SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later - -//------------------------------------------------------------------------------ - -/* Purpose: This function safely creates and initializes an mpq_t entry. - */ - -// The SPEX_mpq_init function is wrapped in this method to avoid a spurious -// compiler warning in SPEX_MPQ_SET_NULL, about writing past the size of a -// variable. The warning arises when a high level of optimization is used. -// The warning cannot be supressed entirely because it would require a -// modifcation to GMP itself. - -#include "spex_util_internal.h" -SPEX_info spex_create_mpq -( - mpq_t x // mpq_t entry to be initialized -) -{ - - SPEX_info info = SPEX_mpq_init(x); - if (info != SPEX_OK) - { - // Out of memory - SPEX_MPQ_SET_NULL(x); - return info; - } - return SPEX_OK; -} - diff --git a/SPEX/SPEX_Utilities/Source/spex_create_mpq_array.c b/SPEX/SPEX_Utilities/Source/spex_create_mpq_array.c index 4e28bc69..480b09fc 100644 --- a/SPEX/SPEX_Utilities/Source/spex_create_mpq_array.c +++ b/SPEX/SPEX_Utilities/Source/spex_create_mpq_array.c @@ -2,8 +2,8 @@ // SPEX_Utilities/spex_create_mpq_array: create a dense mpq array //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -37,12 +37,8 @@ mpq_t *spex_create_mpq_array if (SPEX_mpq_init(x[i]) != SPEX_OK) { // Out of memory - SPEX_MPQ_SET_NULL(x[i]); - for (int64_t j = 0; j < i; j++) - { - SPEX_MPQ_CLEAR( x[j]); - } - SPEX_FREE(x); + SPEX_mpq_set_null (x[i]); + spex_free_mpq_array (&x, n) ; return NULL; } } diff --git a/SPEX/SPEX_Utilities/Source/spex_create_mpz_array.c b/SPEX/SPEX_Utilities/Source/spex_create_mpz_array.c index 1e87b387..e758be61 100644 --- a/SPEX/SPEX_Utilities/Source/spex_create_mpz_array.c +++ b/SPEX/SPEX_Utilities/Source/spex_create_mpz_array.c @@ -2,8 +2,8 @@ // SPEX_Utilities/spex_create_mpz_array: create a dense mpz array //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -44,17 +44,10 @@ mpz_t *spex_create_mpz_array // out of memory. NOTE: This can be triggered only when using GMP // v6.1.2 or earlier versions. For GMP v6.2.0 or later versions, // there is no memory allocation, and thus such failure will never - // occur. As a result, this code cannot be untested by the tests + // occur. As a result, this code cannot be tested by the tests // in SPEX/Tcov, when using GMP v6.2.0 or later. - SPEX_MPZ_SET_NULL(x[i]); - for (int64_t j = 0; j < i; j++) - { - if ( x[j] != NULL) - { - SPEX_MPZ_CLEAR( x[j]); - } - } - SPEX_FREE(x); + SPEX_mpz_set_null (x[i]); + spex_free_mpz_array (&x, n) ; return NULL; } #endif diff --git a/SPEX/SPEX_Utilities/Source/spex_cumsum.c b/SPEX/SPEX_Utilities/Source/spex_cumsum.c index d7f8ccd8..6a386a2a 100644 --- a/SPEX/SPEX_Utilities/Source/spex_cumsum.c +++ b/SPEX/SPEX_Utilities/Source/spex_cumsum.c @@ -2,8 +2,8 @@ // SPEX_Utilities/spex_cumsum: cumulative sum //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/spex_expand_double_array.c b/SPEX/SPEX_Utilities/Source/spex_expand_double_array.c index ce6de0d8..57ce2bed 100644 --- a/SPEX/SPEX_Utilities/Source/spex_expand_double_array.c +++ b/SPEX/SPEX_Utilities/Source/spex_expand_double_array.c @@ -2,8 +2,8 @@ // SPEX_Utilities/spex_expand_double_array: convert double vector to mpz //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -16,9 +16,9 @@ */ #define SPEX_FREE_WORKSPACE \ - SPEX_MPZ_CLEAR(gcd); \ - SPEX_MPZ_CLEAR(one); \ - SPEX_MPQ_CLEAR(temp); \ + SPEX_mpz_clear (gcd); \ + SPEX_mpz_clear (one); \ + SPEX_mpq_clear (temp); \ SPEX_matrix_free(&x3, NULL); \ #define SPEX_FREE_ALL \ @@ -65,8 +65,8 @@ SPEX_info spex_expand_double_array // DOUBLE_MAX. In that case the multiplication could lead to inf. SPEX_matrix x3 = NULL; - mpz_t gcd, one; SPEX_MPZ_SET_NULL(gcd); SPEX_MPZ_SET_NULL(one); - mpq_t temp; SPEX_MPQ_SET_NULL(temp); + mpz_t gcd, one; SPEX_mpz_set_null (gcd); SPEX_mpz_set_null (one); + mpq_t temp; SPEX_mpq_set_null (temp); mpfr_rnd_t round = SPEX_OPTION_ROUND (option); diff --git a/SPEX/SPEX_Utilities/Source/spex_expand_mpfr_array.c b/SPEX/SPEX_Utilities/Source/spex_expand_mpfr_array.c index b3f06e2f..44ddb591 100644 --- a/SPEX/SPEX_Utilities/Source/spex_expand_mpfr_array.c +++ b/SPEX/SPEX_Utilities/Source/spex_expand_mpfr_array.c @@ -2,8 +2,8 @@ // SPEX_Utilities/spex_expand_mpfr_array: convert mpfr aray to mpz //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -15,21 +15,13 @@ * arrays to be used within SPEX. */ -#define SPEX_FREE_ALL \ - SPEX_MPZ_CLEAR(gcd); \ - SPEX_MPZ_CLEAR(one); \ - SPEX_MPQ_CLEAR(temp); \ - if (x_mpq) \ - { \ - for (i = 0; i < n; i++) \ - { \ - if ( x_mpq[i] != NULL) \ - { \ - SPEX_MPQ_CLEAR(x_mpq[i]); \ - } \ - } \ - } \ - SPEX_FREE(x_mpq); +#define SPEX_FREE_ALL \ +{ \ + SPEX_mpz_clear (gcd); \ + SPEX_mpz_clear (one); \ + SPEX_mpq_clear (temp); \ + spex_free_mpq_array (&x_mpq, n) ; \ +} #include "spex_util_internal.h" @@ -59,9 +51,9 @@ SPEX_info spex_expand_mpfr_array bool nz_found = false; mpz_t gcd, one; mpq_t *x_mpq = NULL; - SPEX_MPZ_SET_NULL(gcd); - SPEX_MPZ_SET_NULL(one); - mpq_t temp; SPEX_MPQ_SET_NULL(temp); + SPEX_mpz_set_null (gcd); + SPEX_mpz_set_null (one); + mpq_t temp; SPEX_mpq_set_null (temp); SPEX_MPQ_INIT(temp); SPEX_MPZ_INIT(gcd); diff --git a/SPEX/SPEX_Utilities/Source/spex_expand_mpq_array.c b/SPEX/SPEX_Utilities/Source/spex_expand_mpq_array.c index a7097fba..1904cee6 100644 --- a/SPEX/SPEX_Utilities/Source/spex_expand_mpq_array.c +++ b/SPEX/SPEX_Utilities/Source/spex_expand_mpq_array.c @@ -2,8 +2,8 @@ // SPEX_Utilities/spex_expand_mpq_array: convert mpq array to mpz //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -15,7 +15,7 @@ */ #define SPEX_FREE_ALL \ - SPEX_MPZ_CLEAR(temp); + SPEX_mpz_clear (temp); #include "spex_util_internal.h" @@ -33,7 +33,7 @@ SPEX_info spex_expand_mpq_array ASSERT(n >= 0); SPEX_info info ; mpz_t temp; - SPEX_MPZ_SET_NULL(temp); + SPEX_mpz_set_null (temp); SPEX_MPZ_INIT(temp); // Find LCM of denominators of x diff --git a/SPEX/SPEX_Utilities/Source/spex_free_mpfr_array.c b/SPEX/SPEX_Utilities/Source/spex_free_mpfr_array.c new file mode 100644 index 00000000..939e48a3 --- /dev/null +++ b/SPEX/SPEX_Utilities/Source/spex_free_mpfr_array.c @@ -0,0 +1,50 @@ +//------------------------------------------------------------------------------ +// SPEX_Utilities/spex_free_mpfr_array: free an mpfr_t array +//------------------------------------------------------------------------------ + +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. +// All Rights Reserved. +// SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later + +//------------------------------------------------------------------------------ + +// Free a spex mpfr_t array +#if defined (__GNUC__) +#pragma GCC diagnostic ignored "-Wunused-variable" +#endif + +#include "spex_util_internal.h" + +void spex_free_mpfr_array +( + mpfr_t **x_handle, // mpfr_t array of size n + int64_t n +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + if (x_handle == NULL || (*x_handle) == NULL) + { + // nothing to free (not an error) + return ; + } + + //-------------------------------------------------------------------------- + // free the mpfr_t array x + //-------------------------------------------------------------------------- + + mpfr_t *x = (*x_handle) ; + + for (int64_t i = 0 ; i < n ; i++) + { + SPEX_MPFR_CLEAR (x [i]) ; + } + + SPEX_FREE (x) ; + (*x_handle) = NULL ; +} + diff --git a/SPEX/SPEX_Utilities/Source/spex_free_mpq_array.c b/SPEX/SPEX_Utilities/Source/spex_free_mpq_array.c new file mode 100644 index 00000000..1abb64b9 --- /dev/null +++ b/SPEX/SPEX_Utilities/Source/spex_free_mpq_array.c @@ -0,0 +1,50 @@ +//------------------------------------------------------------------------------ +// SPEX_Utilities/spex_free_mpq_array: free an mpq_t array +//------------------------------------------------------------------------------ + +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. +// All Rights Reserved. +// SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later + +//------------------------------------------------------------------------------ + +// Free a spex mpq_t array +#if defined (__GNUC__) +#pragma GCC diagnostic ignored "-Wunused-variable" +#endif + +#include "spex_util_internal.h" + +void spex_free_mpq_array +( + mpq_t **x_handle, // mpq_t array of size n + int64_t n +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + if (x_handle == NULL || (*x_handle) == NULL) + { + // nothing to free (not an error) + return ; + } + + //-------------------------------------------------------------------------- + // free the mpq_t array x + //-------------------------------------------------------------------------- + + mpq_t *x = (*x_handle) ; + + for (int64_t i = 0 ; i < n ; i++) + { + SPEX_mpq_clear (x [i]) ; + } + + SPEX_FREE (x) ; + (*x_handle) = NULL ; +} + diff --git a/SPEX/SPEX_Utilities/Source/spex_free_mpz_array.c b/SPEX/SPEX_Utilities/Source/spex_free_mpz_array.c new file mode 100644 index 00000000..28b7fee8 --- /dev/null +++ b/SPEX/SPEX_Utilities/Source/spex_free_mpz_array.c @@ -0,0 +1,50 @@ +//------------------------------------------------------------------------------ +// SPEX_Utilities/spex_free_mpz_array: free an mpz_t array +//------------------------------------------------------------------------------ + +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. +// All Rights Reserved. +// SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later + +//------------------------------------------------------------------------------ + +// Free a spex mpz_t array +#if defined (__GNUC__) +#pragma GCC diagnostic ignored "-Wunused-variable" +#endif + +#include "spex_util_internal.h" + +void spex_free_mpz_array +( + mpz_t **x_handle, // mpz_t array of size n + int64_t n +) +{ + + //-------------------------------------------------------------------------- + // check inputs + //-------------------------------------------------------------------------- + + if (x_handle == NULL || (*x_handle) == NULL) + { + // nothing to free (not an error) + return ; + } + + //-------------------------------------------------------------------------- + // free the mpz_t array x + //-------------------------------------------------------------------------- + + mpz_t *x = (*x_handle) ; + + for (int64_t i = 0 ; i < n ; i++) + { + SPEX_MPZ_CLEAR (x [i]) ; + } + + SPEX_FREE (x) ; + (*x_handle) = NULL ; +} + diff --git a/SPEX/SPEX_Utilities/Source/spex_gmp.h b/SPEX/SPEX_Utilities/Source/spex_gmp.h index 466a3338..0c8cc7c4 100644 --- a/SPEX/SPEX_Utilities/Source/spex_gmp.h +++ b/SPEX/SPEX_Utilities/Source/spex_gmp.h @@ -2,8 +2,8 @@ // SPEX_Utilities/spex_gmp.h: definitions for SPEX_gmp.c //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -32,10 +32,10 @@ typedef struct int64_t nmalloc ; // # of malloc'd objects in spex_gmp->list int64_t nlist ; // size of the spex_gmp->list void **list ; // list of malloc'd objects - mpz_t *mpz_archive ; // current mpz object - mpz_t *mpz_archive2 ; // current second mpz object - mpq_t *mpq_archive ; // current mpq object - mpfr_t *mpfr_archive ; // current mpfr object + mpz_ptr mpz_archive ; // current mpz object + mpz_ptr mpz_archive2 ; // current second mpz object + mpq_ptr mpq_archive ; // current mpq object + mpfr_ptr mpfr_archive ; // current mpfr object int primary ; // 1 if created by SPEX_initialize; 0 for // SPEX_thread_initialize } spex_gmp_t ; @@ -80,94 +80,6 @@ void spex_gmp_dump ( void ) ; SPEX_info spex_gmp_failure (int status) ; -//------------------------------------------------------------------------------ -// Field access macros for MPZ/MPQ/MPFR struct -//------------------------------------------------------------------------------ -// FUTURE: make these accessible to the end user? - -// (similar definition in gmp-impl.h and mpfr-impl.h) - -#define SPEX_MPZ_SIZ(x) ((x)->_mp_size) -#define SPEX_MPZ_PTR(x) ((x)->_mp_d) -#define SPEX_MPZ_ALLOC(x) ((x)->_mp_alloc) -#define SPEX_MPQ_NUM(x) mpq_numref(x) -#define SPEX_MPQ_DEN(x) mpq_denref(x) -#define SPEX_MPFR_MANT(x) ((x)->_mpfr_d) -#define SPEX_MPFR_EXP(x) ((x)->_mpfr_exp) -#define SPEX_MPFR_PREC(x) ((x)->_mpfr_prec) -#define SPEX_MPFR_SIGN(x) ((x)->_mpfr_sign) - -/*re-define but same result: */ -#define SPEX_MPFR_REAL_PTR(x) (&((x)->_mpfr_d[-1])) - -/* Invalid exponent value (to track bugs...) */ -#define SPEX_MPFR_EXP_INVALID \ - ((mpfr_exp_t) 1 << (GMP_NUMB_BITS*sizeof(mpfr_exp_t)/sizeof(mp_limb_t)-2)) - -/* Macros to set the pointer in mpz_t/mpq_t/mpfr_t variable to NULL. It is best - * practice to call these macros immediately after mpz_t/mpq_t/mpfr_t variable - * is declared, and before the mp*_init function is called. It would help to - * prevent error when SPEX_MP*_CLEAR is called before the variable is - * successfully initialized. - */ - -#define SPEX_MPZ_SET_NULL(x) \ -{ \ - SPEX_MPZ_PTR(x) = NULL; \ - SPEX_MPZ_SIZ(x) = 0; \ - SPEX_MPZ_ALLOC(x) = 0; \ -} - -#define SPEX_MPQ_SET_NULL(x) \ -{ \ - SPEX_MPZ_PTR(SPEX_MPQ_NUM(x)) = NULL; \ - SPEX_MPZ_SIZ(SPEX_MPQ_NUM(x)) = 0; \ - SPEX_MPZ_ALLOC(SPEX_MPQ_NUM(x)) = 0; \ - SPEX_MPZ_PTR(SPEX_MPQ_DEN(x)) = NULL; \ - SPEX_MPZ_SIZ(SPEX_MPQ_DEN(x)) = 0; \ - SPEX_MPZ_ALLOC(SPEX_MPQ_DEN(x)) = 0; \ -} - -#define SPEX_MPFR_SET_NULL(x) \ -{ \ - SPEX_MPFR_MANT(x) = NULL; \ - SPEX_MPFR_PREC(x) = 0; \ - SPEX_MPFR_SIGN(x) = 1; \ - SPEX_MPFR_EXP(x) = SPEX_MPFR_EXP_INVALID; \ -} - -/* GMP does not give a mechanism to tell a user when an mpz, mpq, or mpfr - * item has been cleared; thus, if mp*_clear is called on an object that - * has already been cleared, gmp will crash. It is also not possible to - * set a mp*_t = NULL. Thus, this mechanism modifies the internal GMP - * size of entries to avoid crashing in the case that a mp*_t is cleared - * multiple times. - */ - -#define SPEX_MPZ_CLEAR(x) \ -{ \ - if ((x) != NULL && SPEX_MPZ_PTR(x) != NULL) \ - { \ - mpz_clear(x); \ - SPEX_MPZ_SET_NULL(x); \ - } \ -} - -#define SPEX_MPQ_CLEAR(x) \ -{ \ - SPEX_MPZ_CLEAR(SPEX_MPQ_NUM(x)); \ - SPEX_MPZ_CLEAR(SPEX_MPQ_DEN(x)); \ -} - -#define SPEX_MPFR_CLEAR(x) \ -{ \ - if ((x) != NULL && SPEX_MPFR_MANT(x) != NULL)\ - { \ - mpfr_clear(x); \ - SPEX_MPFR_SET_NULL(x); \ - } \ -} - //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //-------------------------------GMP/MPFR wrapper macros------------------------ @@ -242,5 +154,4 @@ SPEX_info spex_gmp_failure (int status) ; #define SPEX_MPFR_SGN(sgn,x) SPEX_CHECK( SPEX_mpfr_sgn (sgn,x) ) #define SPEX_MPFR_FREE_CACHE() SPEX_CHECK( SPEX_mpfr_free_cache () ) - #endif diff --git a/SPEX/SPEX_Utilities/Source/spex_matrix_mul.c b/SPEX/SPEX_Utilities/Source/spex_matrix_mul.c index bb7ba8a0..4cf2f29f 100644 --- a/SPEX/SPEX_Utilities/Source/spex_matrix_mul.c +++ b/SPEX/SPEX_Utilities/Source/spex_matrix_mul.c @@ -2,8 +2,8 @@ // SPEX_Utilities/spex_matrix_mul: multiplies a MPZ matrix by a scalar //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/spex_permute_dense_matrix.c b/SPEX/SPEX_Utilities/Source/spex_permute_dense_matrix.c index 0e886696..93378e22 100644 --- a/SPEX/SPEX_Utilities/Source/spex_permute_dense_matrix.c +++ b/SPEX/SPEX_Utilities/Source/spex_permute_dense_matrix.c @@ -3,8 +3,8 @@ // as A_out = P*A_in //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/spex_sparse_collapse.c b/SPEX/SPEX_Utilities/Source/spex_sparse_collapse.c index 3754bf6d..ff914337 100644 --- a/SPEX/SPEX_Utilities/Source/spex_sparse_collapse.c +++ b/SPEX/SPEX_Utilities/Source/spex_sparse_collapse.c @@ -2,8 +2,8 @@ // SPEX_Utilities/spex_sparse_collapse: shrink space required by CSC mpz matrix //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/spex_sparse_realloc.c b/SPEX/SPEX_Utilities/Source/spex_sparse_realloc.c index 0607a5cd..8428f773 100644 --- a/SPEX/SPEX_Utilities/Source/spex_sparse_realloc.c +++ b/SPEX/SPEX_Utilities/Source/spex_sparse_realloc.c @@ -2,8 +2,8 @@ // SPEX_Utilities/spex_sparse_realloc: double the space for a sparse mpz matrix //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/SPEX_Utilities/Source/spex_util_internal.h b/SPEX/SPEX_Utilities/Source/spex_util_internal.h index 3ca7c885..fbf11c41 100644 --- a/SPEX/SPEX_Utilities/Source/spex_util_internal.h +++ b/SPEX/SPEX_Utilities/Source/spex_util_internal.h @@ -2,8 +2,8 @@ // SPEX_Utilities/spex_util_internal: include file for internal use in SPEX_Utility functions //------------------------------------------------------------------------------ -// SPEX_Utilities: (c) 2019-2023, Christopher Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX_Utilities: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -15,8 +15,10 @@ #ifndef SPEX_UTIL_INTERNAL_H #define SPEX_UTIL_INTERNAL_H +#if defined (__GNUC__) #pragma GCC diagnostic ignored "-Wunused-parameter" #pragma GCC diagnostic ignored "-Wunused-value" +#endif //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ @@ -25,10 +27,11 @@ //------------------------------------------------------------------------------ // Standard C libraries +#include +#include #include - -// SuiteSparse headers -#include "SuiteSparse_config.h" +#include +#include // user-callable functions #include "SPEX.h" @@ -36,6 +39,11 @@ // SPEX interface to GMP and MPFR #include "spex_gmp.h" +// SuiteSparse headers +#include "SuiteSparse_config.h" +#include "colamd.h" +#include "amd.h" + //------------------------------------------------------------------------------ // debugging //------------------------------------------------------------------------------ @@ -143,31 +151,34 @@ // Local variables (only declared, allocated and freed inside an if, for // example) do not go inside the workspace. -#ifdef SPEX_DEBUG - #define SPEX_CHECK(method) \ - { \ - info = (method); \ - if (info != SPEX_OK) \ - { \ - printf("file %s line %d\n",__FILE__,__LINE__);\ - SPEX_FREE_ALL; \ - return (info); \ - } \ - } +// SPEX_CHECK: similar to SPEX_TRY (which is user-accessible). The SPEX_CHECK +// macro is used internally. -#else +#define SPEX_CHECK(method) \ +{ \ + info = (method); \ + if (info != SPEX_OK) \ + { \ + SPEX_FREE_ALL; \ + return (info); \ + } \ +} - #define SPEX_CHECK(method) \ - { \ - info = (method); \ - if (info != SPEX_OK) \ - { \ - SPEX_FREE_ALL; \ - return (info); \ - } \ - } +//------------------------------------------------------------------------------ +// check versions of SuiteSparse packages +//------------------------------------------------------------------------------ +#if !defined (SUITESPARSE__VERSION) || SUITESPARSE__VERSION < SUITESPARSE__VERCODE(7,7,0) +#error "SPEX requires SuiteSparse_config 7.7.0 or later" +#endif + +#if !defined (AMD__VERSION) || AMD__VERSION < SUITESPARSE__VERCODE(3,3,2) +#error "SPEX requires AMD 3.3.2 or later" +#endif + +#if !defined (COLAMD__VERSION) || COLAMD__VERSION < SUITESPARSE__VERCODE(3,3,3) +#error "SPEX requires COLAMD 3.3.3 or later" #endif //------------------------------------------------------------------------------ @@ -192,12 +203,8 @@ #define SPEX_PR2(...) { if (pr >= 2) SPEX_PRINTF (__VA_ARGS__) } #define SPEX_PR3(...) { if (pr >= 3) SPEX_PRINTF (__VA_ARGS__) } - - -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -//----------------------------------------------------- //------------------------------------------------------------------------------ +// Default parameter values //------------------------------------------------------------------------------ // Tolerance used in the pivoting schemes. This number can be anything in @@ -284,7 +291,88 @@ #define SPEX_OPTION_ALGORITHM(option) \ SPEX_OPTION (option, algo, SPEX_DEFAULT_ALGORITHM) +//------------------------------------------------------------------------------ +// Field access macros for MPZ/MPQ/MPFR struct +//------------------------------------------------------------------------------ + +// Thse macros rely on GMP and MPFR definitions in gmp.h, but which are not +// necessarily meant to be accessed by the application (SPEX) that is using +// GMP. They provide access to the internal structure for the MPZ, MPQ, and +// MPFR data types. + +#define SPEX_MPZ_SIZ(x) ((x)->_mp_size) +#define SPEX_MPZ_PTR(x) ((x)->_mp_d) +#define SPEX_MPZ_ALLOC(x) ((x)->_mp_alloc) +#define SPEX_MPQ_NUM(x) mpq_numref(x) +#define SPEX_MPQ_DEN(x) mpq_denref(x) +#define SPEX_MPFR_MANT(x) ((x)->_mpfr_d) +#define SPEX_MPFR_EXP(x) ((x)->_mpfr_exp) +#define SPEX_MPFR_PREC(x) ((x)->_mpfr_prec) +#define SPEX_MPFR_SIGN(x) ((x)->_mpfr_sign) + +// Invalid exponent value (to track bugs...) +#define SPEX_MPFR_EXP_INVALID \ + ((mpfr_exp_t) 1 << (GMP_NUMB_BITS*sizeof(mpfr_exp_t)/sizeof(mp_limb_t)-2)) + +/* Macros to set the pointer in mpz_t/mpq_t/mpfr_t variable to NULL. It is best + * practice to call these macros immediately after mpz_t/mpq_t/mpfr_t variable + * is declared, and before the mp*_init function is called. It would help to + * prevent error when SPEX_MP*_CLEAR is called before the variable is + * successfully initialized. + */ +#define SPEX_MPZ_SET_NULL(x) \ +{ \ + SPEX_MPZ_PTR(x) = NULL; \ + SPEX_MPZ_SIZ(x) = 0; \ + SPEX_MPZ_ALLOC(x) = 0; \ +} + +#define SPEX_MPQ_SET_NULL(x) \ +{ \ + SPEX_MPZ_SET_NULL (SPEX_MPQ_NUM (x)) ; \ + SPEX_MPZ_SET_NULL (SPEX_MPQ_DEN (x)) ; \ +} + +#define SPEX_MPFR_SET_NULL(x) \ +{ \ + SPEX_MPFR_MANT(x) = NULL; \ + SPEX_MPFR_PREC(x) = 0; \ + SPEX_MPFR_SIGN(x) = 1; \ + SPEX_MPFR_EXP(x) = SPEX_MPFR_EXP_INVALID; \ +} + +/* GMP does not give a mechanism to tell a user when an mpz, mpq, or mpfr + * item has been cleared; thus, if mp*_clear is called on an object that + * has already been cleared, gmp will crash. It is also not possible to + * set a mp*_t = NULL. Thus, this mechanism modifies the internal GMP + * size of entries to avoid crashing in the case that a mp*_t is cleared + * multiple times. + */ + +#define SPEX_MPZ_CLEAR(x) \ +{ \ + if ((x) != NULL && SPEX_MPZ_PTR(x) != NULL) \ + { \ + mpz_clear(x); \ + SPEX_MPZ_SET_NULL(x); \ + } \ +} + +#define SPEX_MPQ_CLEAR(x) \ +{ \ + SPEX_MPZ_CLEAR(SPEX_MPQ_NUM(x)); \ + SPEX_MPZ_CLEAR(SPEX_MPQ_DEN(x)); \ +} + +#define SPEX_MPFR_CLEAR(x) \ +{ \ + if ((x) != NULL && SPEX_MPFR_MANT(x) != NULL)\ + { \ + mpfr_clear(x); \ + SPEX_MPFR_SET_NULL(x); \ + } \ +} // ============================================================================ // Internal Functions @@ -309,6 +397,18 @@ mpfr_t *spex_create_mpfr_array const SPEX_options option // command options containing the prec for mpfr ) ; +//------------------------------------------------------------------------------ +// spex_free_mpfr_array: free a 1D mpfr_t array +//------------------------------------------------------------------------------ + +// Purpose: frees the array created by spex_create_mpfr_array. + +void spex_free_mpfr_array +( + mpfr_t **x_handle, // mpfr_t array of size n + int64_t n +) ; + //------------------------------------------------------------------------------ // spex_create_mpq_array: Creates a 1D array, whose entries are all mpq_t type. //------------------------------------------------------------------------------ @@ -324,11 +424,16 @@ mpq_t *spex_create_mpq_array int64_t n // size of the array ) ; -// Create and initialize a single mpq_t variable +//------------------------------------------------------------------------------ +// spex_free_mpq_array: delete a 1D mpq_t array +//------------------------------------------------------------------------------ + +// Purpose: frees the array created by spex_create_mpq_array. -SPEX_info spex_create_mpq +void spex_free_mpq_array ( - mpq_t x // mpq_t entry to be initialized + mpq_t **x_handle, // mpq_t array of size n + int64_t n ) ; //------------------------------------------------------------------------------ @@ -343,24 +448,25 @@ SPEX_info spex_create_mpq mpz_t *spex_create_mpz_array ( - int64_t n // size of the array + int64_t n // size of the array ) ; //------------------------------------------------------------------------------ -// spex_delete_mpz_array: delete a 1D mpz_t array +// spex_free_mpz_array: delete a 1D mpz_t array //------------------------------------------------------------------------------ -// Delete a simple 1D array, where A[i] is an entry of type mpz_t. +// Purpose: frees the array created by spex_create_mpz_array. -/* Purpose: This function deletes a mpz array of size n - */ - -void spex_delete_mpz_array +void spex_free_mpz_array ( - mpz_t **x, // mpz array to be deleted - int64_t n // Size of x + mpz_t **x_handle, // mpz_t array of size n + int64_t n ) ; +//------------------------------------------------------------------------------ +// spex_expand_double_array +//------------------------------------------------------------------------------ + /* Purpose: This function converts a double array of size n to an appropriate * mpz array of size n. To do this, the number is multiplied by 10^17 then, the * GCD is found. This function allows the use of matrices in double precision @@ -564,19 +670,5 @@ SPEX_info spex_amd ASSERT_KIND (A,required_kind) ; \ ASSERT_TYPE (A,required_type) ; -//------------------------------------------------------------------------------ -// SPEX_matrix macros -//------------------------------------------------------------------------------ - -// These macros simplify the access to entries in a SPEX_matrix. -// The type parameter is one of: mpq, mpz, mpfr, int64, or fp64. - -// To access the kth entry in a SPEX_matrix using 1D linear addressing, -// in any matrix kind (CSC, triplet, or dense), in any type: -#define SPEX_1D(A,k,type) ((A)->x.type [k]) - -// To access the (i,j)th entry in a 2D SPEX_matrix, in any type: -#define SPEX_2D(A,i,j,type) SPEX_1D (A, (i)+(j)*((A)->m), type) - #endif diff --git a/SPEX/Tcov/.gitignore b/SPEX/Tcov/.gitignore index 8b6d5d37..14492e71 100644 --- a/SPEX/Tcov/.gitignore +++ b/SPEX/Tcov/.gitignore @@ -1,15 +1,10 @@ -# Ignore all files: -* - -# except these files ... -!covall -!cov.awk -!cover -!covs -!gcovs -!Mats4Tcov/ -!README.txt -!simple_*.c -!simple_*.h -!tcov_*.c -!tcov_*.h +# Ignore these files: +Makefile +spex*.c +SPEX*.c +*.out +spex_demo_lu_extended +tcov_for_cholesky +tcov_for_lu +tcov_for_lu2 +tcov_for_other diff --git a/SPEX/Tcov/simple_rand.c b/SPEX/Tcov/simple_rand.c index c61c65a4..6902ec3f 100644 --- a/SPEX/Tcov/simple_rand.c +++ b/SPEX/Tcov/simple_rand.c @@ -2,8 +2,8 @@ // SPEX/Tcov/simple_rand.c: a very simple random number generator // ---------------------------------------------------------------------------- -// SPEX: (c) 2019-2023, Chris Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/Tcov/simple_rand.h b/SPEX/Tcov/simple_rand.h index ba362469..f6c1cb01 100644 --- a/SPEX/Tcov/simple_rand.h +++ b/SPEX/Tcov/simple_rand.h @@ -2,8 +2,8 @@ // SPEX/Tcov/simple_rand.h: a very simple random number generator // ---------------------------------------------------------------------------- -// SPEX: (c) 2019-2023, Chris Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/Tcov/tcov_for_cholesky.c b/SPEX/Tcov/tcov_for_cholesky.c index 3d4f7748..9721cf76 100644 --- a/SPEX/Tcov/tcov_for_cholesky.c +++ b/SPEX/Tcov/tcov_for_cholesky.c @@ -2,8 +2,8 @@ // SPEX/Tcov/tcov_for_cholesky.c: test coverage for SPEX_Cholesky // ---------------------------------------------------------------------------- -// SPEX: (c) 2019-2023, Chris Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -34,8 +34,6 @@ // BRUTAL: test a method with debug malloc, until it succeeds //------------------------------------------------------------------------------ -// The method must return a bool (true if successful, false if failure). - #define NTRIAL_MAX 10000 #define BRUTAL(method) \ @@ -49,7 +47,7 @@ if (info2 != SPEX_OUT_OF_MEMORY) break ; \ } \ if (info2 != SPEX_OK) TEST_ABORT (info2) ; \ - malloc_count = INT64_MAX ; \ + malloc_count = INT64_MAX ; \ printf ("\nBrutal Cholesky trials %ld: tests passed\n", trial); \ } @@ -122,8 +120,8 @@ SPEX_info spex_test_chol_backslash (SPEX_matrix A, SPEX_matrix b, #undef SPEX_FREE_ALL #define SPEX_FREE_ALL \ { \ - SPEX_MPZ_CLEAR(q1); \ - SPEX_MPZ_CLEAR(r1); \ + SPEX_mpz_clear (q1); \ + SPEX_mpz_clear (r1); \ } SPEX_info spex_test_cdiv_qr (mpz_t n, mpz_t d) ; @@ -132,8 +130,8 @@ SPEX_info spex_test_cdiv_qr (mpz_t n, mpz_t d) { //SPEX_info info ; mpz_t q1, r1; - SPEX_MPZ_SET_NULL(q1); - SPEX_MPZ_SET_NULL(r1); + SPEX_mpz_set_null (q1); + SPEX_mpz_set_null (r1); OK2 (SPEX_mpz_init2(q1,1)); OK2 (SPEX_mpz_init2(r1,1)); @@ -319,20 +317,27 @@ int main (int argc, char *argv []) //-------------------------------------------------------------------------- // test spex_expand_mpfr_array //-------------------------------------------------------------------------- + //create mpfr array where all elements are multiples of 220 mpfr_rnd_t round = SPEX_OPTION_ROUND (option); mpfr_t* x_mpfr = spex_create_mpfr_array (3, option); mpz_t* x_mpz = spex_create_mpz_array (3); mpq_t x_scale; - OK (spex_create_mpq (x_scale)); + SPEX_MPQ_INIT (x_scale) ; + SPEX_MPQ_SET_UI (x_scale, 1, 10); for (int64_t k = 0 ; k < 3 ; k++) { SPEX_MPFR_SET_SI( x_mpfr[k],(k+2)*220, round); } - + OK ( spex_expand_mpfr_array (x_mpz, x_mpfr, x_scale, 3, option)); - + + // free x_mpz, x_mpfr, and x_scale + spex_free_mpz_array (&x_mpz, 3) ; + spex_free_mpfr_array (&x_mpfr, 3) ; + SPEX_mpq_clear (x_scale) ; + //-------------------------------------------------------------------------- // missing gmp coverage //-------------------------------------------------------------------------- @@ -404,18 +409,19 @@ int main (int argc, char *argv []) ERR(SPEX_mpz_divexact(gmp_x,gmp_y,gmp_0),SPEX_PANIC); //Free - SPEX_MPZ_CLEAR(gmp_x); - SPEX_MPZ_CLEAR(gmp_y); - SPEX_MPQ_CLEAR(gmp_a); - SPEX_MPQ_CLEAR(gmp_b); - SPEX_MPQ_CLEAR(gmp_c); - SPEX_MPFR_CLEAR(gmp_e); - SPEX_MPFR_CLEAR(gmp_f); - SPEX_MPFR_CLEAR(gmp_g); - SPEX_MPFR_CLEAR(gmp_h); - SPEX_MPZ_CLEAR(gmp_n); - SPEX_MPZ_CLEAR(gmp_d); - SPEX_MPZ_CLEAR(tmpz); + SPEX_mpz_clear (gmp_x); + SPEX_mpz_clear (gmp_0); + SPEX_mpz_clear (gmp_y); + SPEX_mpq_clear (gmp_a); + SPEX_mpq_clear (gmp_b); + SPEX_mpq_clear (gmp_c); + SPEX_mpfr_clear (gmp_e); + SPEX_mpfr_clear (gmp_f); + SPEX_mpfr_clear (gmp_g); + SPEX_mpfr_clear (gmp_h); + SPEX_mpz_clear (gmp_n); + SPEX_mpz_clear (gmp_d); + SPEX_mpz_clear (tmpz); //-------------------------------------------------------------------------- // error handling @@ -556,6 +562,7 @@ int main (int argc, char *argv []) SPEX_PANIC); spex_set_initialized (true); SPEX_FREE_ALL; + SPEX_finalize ( ) ; printf ("%s: all tests passed\n\n", __FILE__); fprintf (stderr, "%s: all tests passed\n\n", __FILE__); diff --git a/SPEX/Tcov/tcov_for_lu.c b/SPEX/Tcov/tcov_for_lu.c index d967ac74..8cd13cb3 100644 --- a/SPEX/Tcov/tcov_for_lu.c +++ b/SPEX/Tcov/tcov_for_lu.c @@ -2,8 +2,8 @@ // SPEX/Tcov/tcov_for_lu.c: test coverage for SPEX_LU // ---------------------------------------------------------------------------- -// SPEX: (c) 2019-2023, Chris Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -263,11 +263,6 @@ int main ( int argc, char *argv[]) Ab_type, malloc_count); } - /*mpz_t mpz1, mpz2, mpz3; - SPEX_MPZ_SET_NULL(mpz1); - SPEX_MPZ_SET_NULL(mpz2); - SPEX_MPZ_SET_NULL(mpz3);*/ - int64_t n=4, numRHS=1, j, nz=11; //------------------------------------------------------------------ diff --git a/SPEX/Tcov/tcov_for_lu2.c b/SPEX/Tcov/tcov_for_lu2.c index 673aeb36..af4abec6 100644 --- a/SPEX/Tcov/tcov_for_lu2.c +++ b/SPEX/Tcov/tcov_for_lu2.c @@ -2,8 +2,8 @@ // SPEX/Tcov/tcov_for_lu2.c: test coverage for SPEX_Cholesky // ---------------------------------------------------------------------------- -// SPEX: (c) 2019-2023, Chris Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -127,8 +127,7 @@ int main (int argc, char *argv []) malloc_count = INT64_MAX ; OK (SPEX_create_default_options (&option)); - - + //-------------------------------------------------------------------------- // load the test matrix and create the right-hand-side //-------------------------------------------------------------------------- @@ -141,8 +140,7 @@ int main (int argc, char *argv []) printf ("\nInput matrix: %ld-by-%ld with %ld entries\n", n, m, anz); OK ((n != m) ? SPEX_PANIC : SPEX_OK); create_test_rhs (&b, A->n); - - + //TESTS option->pivot = SPEX_TOL_LARGEST; option->order = SPEX_AMD ; @@ -150,14 +148,14 @@ int main (int argc, char *argv []) printf ("LU backslash, AMD ordering, no malloc testing:\n"); OK (spex_test_lu_backslash (A, b, option)); option->print_level = 0 ; - + option->pivot = SPEX_FIRST_NONZERO ; option->order = SPEX_COLAMD ; option->print_level = 3 ; printf ("LU backslash, AMD ordering, no malloc testing:\n"); OK (spex_test_lu_backslash (A, b, option)); option->print_level = 0 ; - + option->pivot = SPEX_TOL_SMALLEST ; option->tol = 0; option->order = SPEX_COLAMD ; @@ -168,16 +166,21 @@ int main (int argc, char *argv []) OK (SPEX_matrix_free (&A, option)); OK (SPEX_matrix_free (&b, option)); - + option->order = SPEX_AMD ; read_test_matrix (&A, "../ExampleMats/test1.mat.txt"); OK (SPEX_lu_analyze( &S, A, option)); OK (SPEX_symbolic_analysis_free(&S, option)); OK (SPEX_matrix_free (&A, option)); - + read_test_matrix (&A, "../ExampleMats/test5.mat.txt"); - SPEX_lu_analyze( &S, A, option); - + SPEX_lu_analyze( &S, A, option); + SPEX_FREE_ALL; - + OK (SPEX_finalize ( )) ; + SPEX_FREE (option) ; + + printf ("%s: all tests passed\n\n", __FILE__); + fprintf (stderr, "%s: all tests passed\n\n", __FILE__); + return (0) ; } diff --git a/SPEX/Tcov/tcov_for_other.c b/SPEX/Tcov/tcov_for_other.c new file mode 100644 index 00000000..b0f9b08e --- /dev/null +++ b/SPEX/Tcov/tcov_for_other.c @@ -0,0 +1,104 @@ +// ---------------------------------------------------------------------------- +// SPEX/Tcov/tcov_for_other.c: test coverage for other methods +// ---------------------------------------------------------------------------- + +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. +// All Rights Reserved. +// SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later + +//----------------------------------------------------------------------------- + +#include "tcov_utilities.h" +#include "spex_demos.h" + +#undef SPEX_FREE_ALL +#define SPEX_FREE_ALL ; + +//------------------------------------------------------------------------------ +// ERR: test wrapper for SPEX_* function when expected error would produce +//------------------------------------------------------------------------------ + +#define ERR(method,expected_error) \ +{ \ + SPEX_info info5 = (method) ; \ + if (info5 != expected_error) \ + { \ + printf ("SPEX method was expected to fail, but succeeded!\n") ; \ + printf ("this error was expected:\n") ; \ + SPEX_PRINT_INFO (expected_error) ; \ + printf ("but this error was obtained:\n") ; \ + TEST_ABORT (info5) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// BRUTAL: test a method with debug malloc, until it succeeds +//------------------------------------------------------------------------------ + +#define NTRIAL_MAX 10000 + +#define BRUTAL(method) \ +{ \ + int64_t trial = 0 ; \ + SPEX_info info2 = SPEX_OK ; \ + for (trial = 0 ; trial <= NTRIAL_MAX ; trial++) \ + { \ + malloc_count = trial ; \ + info2 = (method) ; \ + if (info2 != SPEX_OUT_OF_MEMORY) break ; \ + } \ + if (info2 != SPEX_OK) TEST_ABORT (info2) ; \ + malloc_count = INT64_MAX ; \ +} + +//------------------------------------------------------------------------------ +// test program +//------------------------------------------------------------------------------ + +int main (int argc, char *argv []) +{ + + //-------------------------------------------------------------------------- + // start SPEX + //-------------------------------------------------------------------------- + + SPEX_options option = NULL ; + + OK (SPEX_initialize_expert (tcov_malloc, tcov_calloc, tcov_realloc, + tcov_free)) ; + + // disable malloc testing for the first part of the test + spex_set_gmp_ntrials (INT64_MAX) ; + malloc_count = INT64_MAX ; + + OK (SPEX_create_default_options (&option)) ; + + //-------------------------------------------------------------------------- + // basic tests of mpfr methods + //-------------------------------------------------------------------------- + + mpfr_t x ; + printf ("MPFR_PREC_MAX: %g\n", (double) MPFR_PREC_MAX) ; + ERR (SPEX_mpfr_init2 (x, MPFR_PREC_MAX), SPEX_PANIC) ; + BRUTAL (SPEX_mpfr_init2 (x, 4)) ; + ERR (SPEX_mpfr_set_prec (x, MPFR_PREC_MAX), SPEX_PANIC) ; + for (uint64_t k = 4 ; k < 32*1024 ; k = k*2) + { + BRUTAL (SPEX_mpfr_set_prec (x, k)) ; + } + OK (SPEX_mpfr_clear (x)) ; + + //-------------------------------------------------------------------------- + // finalize the tests + //-------------------------------------------------------------------------- + + SPEX_FREE_ALL ; + OK (SPEX_finalize ( )) ; + SPEX_FREE (option) ; + + printf ("%s: all tests passed\n\n", __FILE__) ; + fprintf (stderr, "%s: all tests passed\n\n", __FILE__) ; + return (0) ; +} + diff --git a/SPEX/Tcov/tcov_utilities.c b/SPEX/Tcov/tcov_utilities.c index 6c3ee5f1..c257d8d8 100644 --- a/SPEX/Tcov/tcov_utilities.c +++ b/SPEX/Tcov/tcov_utilities.c @@ -2,8 +2,8 @@ // SPEX/Tcov/tcov_utilities.c: utility functions for tcov tests // ---------------------------------------------------------------------------- -// SPEX: (c) 2019-2023, Chris Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later @@ -109,13 +109,13 @@ int spex_gmp_realloc_test /* Purpose: Given a solution vector x, check the solution of the linear system * Ax = b. This is done by computing a rational-arthmetic A*x == b. This * function is provided here only used for debugging purposes, as the routines - * within SPEX are gauranteed to be exact. + * within SPEX are guaranteed to be exact. */ #undef SPEX_FREE_ALL -#define SPEX_FREE_ALL \ - SPEX_MPQ_CLEAR(temp); \ - SPEX_MPQ_CLEAR(scale); \ +#define SPEX_FREE_ALL \ + SPEX_mpq_clear (temp); \ + SPEX_mpq_clear (scale); \ SPEX_matrix_free(&b2, NULL); SPEX_info spex_check_solution @@ -146,8 +146,8 @@ SPEX_info spex_check_solution int64_t p, j, i ; SPEX_matrix b2 = NULL; // b2 stores the solution of A*x - mpq_t temp; SPEX_MPQ_SET_NULL(temp); - mpq_t scale; SPEX_MPQ_SET_NULL(scale); + mpq_t temp; SPEX_mpq_set_null (temp); + mpq_t scale; SPEX_mpq_set_null (scale); SPEX_MPQ_INIT(temp); SPEX_MPQ_INIT(scale); diff --git a/SPEX/Tcov/tcov_utilities.h b/SPEX/Tcov/tcov_utilities.h index c1615b42..af23bdd5 100644 --- a/SPEX/Tcov/tcov_utilities.h +++ b/SPEX/Tcov/tcov_utilities.h @@ -2,8 +2,8 @@ // SPEX/Tcov/tcov_utilities.h: utilities for tcov tests // ---------------------------------------------------------------------------- -// SPEX: (c) 2019-2023, Chris Lourenco, Jinhao Chen, -// Lorena Mejia Domenzain, Timothy A. Davis, and Erick Moreno-Centeno. +// SPEX: (c) 2019-2024, Christopher Lourenco, Jinhao Chen, +// Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later diff --git a/SPEX/cmake_modules/FindGMP.cmake b/SPEX/cmake_modules/FindGMP.cmake index 2fa7773c..bd4a224f 100644 --- a/SPEX/cmake_modules/FindGMP.cmake +++ b/SPEX/cmake_modules/FindGMP.cmake @@ -4,7 +4,7 @@ # The following copyright and license applies to just this file only, not to # the library itself: -# FindGMP.cmake, Copyright (c) 2022-2023, Timothy A. Davis. All Rights Reserved. +# FindGMP.cmake, Copyright (c) 2022-2024, Timothy A. Davis. All Rights Reserved. # SPDX-License-Identifier: BSD-3-clause #------------------------------------------------------------------------------- @@ -27,7 +27,7 @@ if ( DEFINED ENV{CMAKE_PREFIX_PATH} ) # import CMAKE_PREFIX_PATH, typically created by spack - set ( CMAKE_PREFIX_PATH $ENV{CMAKE_PREFIX_PATH} ) + list ( APPEND CMAKE_PREFIX_PATH $ENV{CMAKE_PREFIX_PATH} ) endif ( ) # include files for gmp diff --git a/SPEX/cmake_modules/FindMPFR.cmake b/SPEX/cmake_modules/FindMPFR.cmake index fae9cb25..c5a3e037 100644 --- a/SPEX/cmake_modules/FindMPFR.cmake +++ b/SPEX/cmake_modules/FindMPFR.cmake @@ -4,7 +4,7 @@ # The following copyright and license applies to just this file only, not to # the library itself: -# FindMPFR.cmake, Copyright (c) 2022-2023, Timothy A. Davis. All Rights Reserved. +# FindMPFR.cmake, Copyright (c) 2022-2024, Timothy A. Davis. All Rights Reserved. # SPDX-License-Identifier: BSD-3-clause #------------------------------------------------------------------------------- @@ -27,7 +27,7 @@ if ( DEFINED ENV{CMAKE_PREFIX_PATH} ) # import CMAKE_PREFIX_PATH, typically created by spack - set ( CMAKE_PREFIX_PATH $ENV{CMAKE_PREFIX_PATH} ) + list ( APPEND CMAKE_PREFIX_PATH $ENV{CMAKE_PREFIX_PATH} ) endif ( ) # include files for mpfr diff --git a/SPEX/cmake_modules/FindSPEX.cmake b/SPEX/cmake_modules/FindSPEX.cmake deleted file mode 100644 index 8e4509f8..00000000 --- a/SPEX/cmake_modules/FindSPEX.cmake +++ /dev/null @@ -1,114 +0,0 @@ -#------------------------------------------------------------------------------- -# SuiteSparse/SPEX/cmake_modules/FindSPEX.cmake -#------------------------------------------------------------------------------- - -# The following copyright and license applies to just this file only, not to -# the library itself: -# FindSPEX.cmake, Copyright (c) 2022-2023, Timothy A. Davis. All Rights Reserved. -# SPDX-License-Identifier: BSD-3-clause - -#------------------------------------------------------------------------------- - -# Finds the SPEX include file and compiled library and sets: - -# SPEX_INCLUDE_DIR - where to find SPEX.h -# SPEX_LIBRARY - dynamic SPEX library -# SPEX_STATIC - static SPEX library -# SPEX_LIBRARIES - libraries when using SPEX -# SPEX_FOUND - true if SPEX found - -# set ``SPEX_ROOT`` to a SPEX installation root to -# tell this module where to look. - -# 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: -# -# set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} -# ${CMAKE_INSTALL_PREFIX}/lib/cmake/SuiteSparse ) - -#------------------------------------------------------------------------------- - -# include files for SPEX -find_path ( SPEX_INCLUDE_DIR - NAMES SPEX.h - HINTS ${CMAKE_SOURCE_DIR}/.. - HINTS ${CMAKE_SOURCE_DIR}/../SuiteSparse/SPEX - HINTS ${CMAKE_SOURCE_DIR}/../SPEX - PATH_SUFFIXES include Include -) - -# dynamic SPEX library -find_library ( SPEX_LIBRARY - NAMES spex - HINTS ${CMAKE_SOURCE_DIR}/.. - HINTS ${CMAKE_SOURCE_DIR}/../SuiteSparse/SPEX - HINTS ${CMAKE_SOURCE_DIR}/../SPEX - PATH_SUFFIXES lib build -) - -if ( MSVC ) - set ( STATIC_SUFFIX .lib ) -else ( ) - set ( STATIC_SUFFIX .a ) -endif ( ) - -# static SPEX library -set ( save ${CMAKE_FIND_LIBRARY_SUFFIXES} ) -set ( CMAKE_FIND_LIBRARY_SUFFIXES ${STATIC_SUFFIX} ${CMAKE_FIND_LIBRARY_SUFFIXES} ) -find_library ( SPEX_STATIC - NAMES spex - HINTS ${CMAKE_SOURCE_DIR}/.. - HINTS ${CMAKE_SOURCE_DIR}/../SuiteSparse/SPEX - HINTS ${CMAKE_SOURCE_DIR}/../SPEX - PATH_SUFFIXES lib build -) -set ( CMAKE_FIND_LIBRARY_SUFFIXES ${save} ) - -# get version of the library from the dynamic library name -get_filename_component ( SPEX_LIBRARY ${SPEX_LIBRARY} REALPATH ) -get_filename_component ( SPEX_FILENAME ${SPEX_LIBRARY} NAME ) -string ( - REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" - SPEX_VERSION - ${SPEX_FILENAME} -) - -if ( NOT SPEX_VERSION ) - # if the version does not appear in the filename, read the include file - foreach ( _VERSION MAIN_VERSION SUB_VERSION SUBSUB_VERSION ) - file ( STRINGS ${SPEX_INCLUDE_DIR}/SPEX.h _VERSION_LINE REGEX "define[ ]+SPEX_${_VERSION}" ) - if ( _VERSION_LINE ) - string ( REGEX REPLACE ".*define[ ]+SPEX_${_VERSION}[ ]+([0-9]*).*" "\\1" _SPEX_${_VERSION} "${_VERSION_LINE}" ) - endif ( ) - unset ( _VERSION_LINE ) - endforeach ( ) - set ( SPEX_VERSION "${_SPEX_MAIN_VERSION}.${_SPEX_SUB_VERSION}.${_SPEX_SUBSUB_VERSION}" ) -endif ( ) - -set ( SPEX_LIBRARIES ${SPEX_LIBRARY} ) - -include (FindPackageHandleStandardArgs) - -find_package_handle_standard_args ( SPEX - REQUIRED_VARS SPEX_LIBRARIES SPEX_INCLUDE_DIR - VERSION_VAR SPEX_VERSION -) - -mark_as_advanced ( - SPEX_INCLUDE_DIR - SPEX_LIBRARY - SPEX_STATIC - SPEX_LIBRARIES -) - -if ( SPEX_FOUND ) - message ( STATUS "SPEX version: ${SPEX_VERSION}" ) - message ( STATUS "SPEX include: ${SPEX_INCLUDE_DIR}" ) - message ( STATUS "SPEX library: ${SPEX_LIBRARY}" ) - message ( STATUS "SPEX static: ${SPEX_STATIC}" ) -else ( ) - message ( STATUS "SPEX not found" ) -endif ( ) - diff --git a/SuiteSparse_config/CMakeLists.txt b/SuiteSparse_config/CMakeLists.txt index 64f6695a..02250c98 100644 --- a/SuiteSparse_config/CMakeLists.txt +++ b/SuiteSparse_config/CMakeLists.txt @@ -10,30 +10,42 @@ # get the version #------------------------------------------------------------------------------- -# cmake 3.22 is required to find the BLAS +# cmake 3.22 is required to find BLAS/LAPACK for UMFPACK, CHOLMOD, SPQR, +# and ParU: cmake_minimum_required ( VERSION 3.22 ) # version of both SuiteSparse and SuiteSparse_config -set ( SUITESPARSE_DATE "Mar FIXME, 2023" ) +set ( SUITESPARSE_DATE "Mar 22, 2024" ) set ( SUITESPARSE_VERSION_MAJOR 7 ) -set ( SUITESPARSE_VERSION_MINOR 1 ) +set ( SUITESPARSE_VERSION_MINOR 7 ) set ( SUITESPARSE_VERSION_SUB 0 ) +set ( SUITESPARSE_CONFIG_VERSION_MAJOR ${SUITESPARSE_VERSION_MAJOR} CACHE STRING "" FORCE ) +set ( SUITESPARSE_CONFIG_VERSION_MINOR ${SUITESPARSE_VERSION_MINOR} CACHE STRING "" FORCE ) +set ( SUITESPARSE_CONFIG_VERSION_PATCH ${SUITESPARSE_VERSION_SUB} CACHE STRING "" FORCE ) message ( STATUS "Building SuiteSparse_config version: v" ${SUITESPARSE_VERSION_MAJOR}. ${SUITESPARSE_VERSION_MINOR}. ${SUITESPARSE_VERSION_SUB} " (" ${SUITESPARSE_DATE} ")" ) +#------------------------------------------------------------------------------- +# define the project +#------------------------------------------------------------------------------- + +project ( SuiteSparseConfig + VERSION "${SUITESPARSE_VERSION_MAJOR}.${SUITESPARSE_VERSION_MINOR}.${SUITESPARSE_VERSION_SUB}" + LANGUAGES C ) + #------------------------------------------------------------------------------- # SuiteSparse policies #------------------------------------------------------------------------------- set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} - ${CMAKE_SOURCE_DIR}/cmake_modules ) + ${PROJECT_SOURCE_DIR}/cmake_modules ) include ( SuiteSparsePolicy ) -if ( NOT NFORTRAN ) +if ( SUITESPARSE_HAS_FORTRAN ) include ( FortranCInterface ) else ( ) # No Fortran compiler available or enabled, configuration is not automatic. @@ -41,26 +53,72 @@ else ( ) set ( FortranCInterface_GLOBAL__MACRO ${SUITESPARSE_C_TO_FORTRAN} ) endif ( ) +message ( STATUS "C to Fortran calling protocol: ") +message ( STATUS " SUITESPARSE_HAS_FORTRAN : ${SUITESPARSE_HAS_FORTRAN}" ) +message ( STATUS " FortranCInterface_GLOBAL_MACRO : ${FortranCInterface_GLOBAL_MACRO}" ) +message ( STATUS " FortranCInterface_GLOBAL__MACRO : ${FortranCInterface_GLOBAL__MACRO}" ) + #------------------------------------------------------------------------------- -# define the project +# CUDA warning on Windows with MSVC #------------------------------------------------------------------------------- -project ( suitesparseconfig - VERSION "${SUITESPARSE_VERSION_MAJOR}.${SUITESPARSE_VERSION_MINOR}.${SUITESPARSE_VERSION_SUB}" - LANGUAGES C ) +if ( SUITESPARSE_HAS_CUDA AND MSVC ) + message ( WARNING "NOTE: CUDA on MSVC has only recently been revised. It appears to be functional but has not been as rigorously tested as I would like (I have limited resources for testing CUDA on Windows). If you encounter issues, set the cmake option SUITESPARSE_USE_CUDA to OFF and post an issue on GitHub." ) +endif ( ) #------------------------------------------------------------------------------- -# find library dependencies +# find OpenMP #------------------------------------------------------------------------------- -option ( NOPENMP "ON: do not use OpenMP. OFF (default): use OpenMP" off ) -if ( NOPENMP ) +option ( SUITESPARSE_CONFIG_USE_OPENMP "ON: Use OpenMP in SuiteSparse_config if available. OFF: Do not use OpenMP. (Default: SUITESPARSE_USE_OPENMP)" ${SUITESPARSE_USE_OPENMP} ) +if ( SUITESPARSE_CONFIG_USE_OPENMP ) + if ( CMAKE_VERSION VERSION_LESS 3.24 ) + find_package ( OpenMP COMPONENTS C ) + else ( ) + find_package ( OpenMP COMPONENTS C GLOBAL ) + endif ( ) +else ( ) # OpenMP has been disabled - message ( STATUS "OpenMP disabled" ) - set ( OPENMP_FOUND false ) + set ( OpenMP_C_FOUND OFF ) +endif ( ) + +if ( SUITESPARSE_CONFIG_USE_OPENMP AND OpenMP_C_FOUND ) + set ( SUITESPARSE_CONFIG_HAS_OPENMP ON ) else ( ) - find_package ( OpenMP ) + set ( SUITESPARSE_CONFIG_HAS_OPENMP OFF ) endif ( ) +message ( STATUS "SuiteSparse_config has OpenMP: ${SUITESPARSE_CONFIG_HAS_OPENMP}" ) + +# check for strict usage +if ( SUITESPARSE_USE_STRICT AND SUITESPARSE_CONFIG_USE_OPENMP AND NOT SUITESPARSE_CONFIG_HAS_OPENMP ) + message ( FATAL_ERROR "OpenMP required for SuiteSparse_config but not found" ) +endif ( ) + +# check for librt in case of fallback to "clock_gettime" +include ( CheckSymbolExists ) +check_symbol_exists ( clock_gettime "time.h" NO_RT ) +if ( NO_RT ) + message ( STATUS "Using clock_gettime without librt" ) + set ( SUITESPARSE_HAVE_CLOCK_GETTIME ON ) +else ( ) + # check if we need to link to librt for that function + set ( _orig_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ) + list ( APPEND CMAKE_REQUIRED_LIBRARIES "rt" ) + check_symbol_exists ( clock_gettime "time.h" WITH_RT ) + set ( CMAKE_REQUIRED_LIBRARIES ${_orig_CMAKE_REQUIRED_LIBRARIES} ) + if ( WITH_RT ) + message ( STATUS "Using clock_gettime with librt" ) + set ( SUITESPARSE_HAVE_CLOCK_GETTIME ON ) + endif ( ) +endif ( ) + +if ( NOT SUITESPARSE_CONFIG_USE_OPENMP AND NOT SUITESPARSE_HAVE_CLOCK_GETTIME ) + message ( STATUS "No OpenMP and no clock_gettime available. Timing functions won't work." ) +endif ( ) + +#------------------------------------------------------------------------------- +# find the BLAS +#------------------------------------------------------------------------------- include ( SuiteSparseBLAS ) @@ -77,38 +135,57 @@ configure_file ( "Config/SuiteSparse_config.h.in" # NEWLINE_STYLE LF ) #------------------------------------------------------------------------------- -# dynamic suitesparseconfig library properties +# dynamic SuiteSparseConfig library properties #------------------------------------------------------------------------------- file ( GLOB SUITESPARSECONFIG_SOURCES "*.c" ) -add_library ( suitesparseconfig SHARED ${SUITESPARSECONFIG_SOURCES} ) -set_target_properties ( suitesparseconfig PROPERTIES - VERSION ${SUITESPARSE_VERSION_MAJOR}.${SUITESPARSE_VERSION_MINOR}.${SUITESPARSE_VERSION_SUB} - C_STANDARD 11 - C_STANDARD_REQUIRED ON - SOVERSION ${SUITESPARSE_VERSION_MAJOR} - PUBLIC_HEADER "SuiteSparse_config.h" - WINDOWS_EXPORT_ALL_SYMBOLS ON ) +if ( BUILD_SHARED_LIBS ) + add_library ( SuiteSparseConfig SHARED ${SUITESPARSECONFIG_SOURCES} ) + + set_target_properties ( SuiteSparseConfig PROPERTIES + VERSION ${SUITESPARSE_VERSION_MAJOR}.${SUITESPARSE_VERSION_MINOR}.${SUITESPARSE_VERSION_SUB} + C_STANDARD 11 + C_STANDARD_REQUIRED ON + OUTPUT_NAME suitesparseconfig + SOVERSION ${SUITESPARSE_VERSION_MAJOR} + PUBLIC_HEADER "SuiteSparse_config.h" + WINDOWS_EXPORT_ALL_SYMBOLS ON ) + + if ( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.25" ) + set_target_properties ( SuiteSparseConfig PROPERTIES EXPORT_NO_SYSTEM ON ) + endif ( ) + + target_include_directories ( SuiteSparseConfig + INTERFACE $ + $ ) +endif ( ) #------------------------------------------------------------------------------- -# static suitesparseconfig library properties +# static SuiteSparseConfig library properties #------------------------------------------------------------------------------- -if ( NOT NSTATIC ) - add_library ( suitesparseconfig_static STATIC ${SUITESPARSECONFIG_SOURCES} ) +if ( BUILD_STATIC_LIBS ) + add_library ( SuiteSparseConfig_static STATIC ${SUITESPARSECONFIG_SOURCES} ) - set_target_properties ( suitesparseconfig_static PROPERTIES - VERSION ${SUITESPARSE_VERSION_MAJOR}.${SUITESPARSE_VERSION_MINOR}.${SUITESPARSE_VERSION_SUB} + set_target_properties ( SuiteSparseConfig_static PROPERTIES C_STANDARD 11 C_STANDARD_REQUIRED ON OUTPUT_NAME suitesparseconfig - SOVERSION ${SUITESPARSE_VERSION_MAJOR} ) + PUBLIC_HEADER "SuiteSparse_config.h" ) - if ( MSVC ) - set_target_properties ( suitesparseconfig_static PROPERTIES + if ( MSVC OR ("${CMAKE_C_SIMULATE_ID}" STREQUAL "MSVC") ) + set_target_properties ( SuiteSparseConfig_static PROPERTIES OUTPUT_NAME suitesparseconfig_static ) endif ( ) + + if ( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.25" ) + set_target_properties ( SuiteSparseConfig_static PROPERTIES EXPORT_NO_SYSTEM ON ) + endif ( ) + + target_include_directories ( SuiteSparseConfig_static + INTERFACE $ + $ ) endif ( ) #------------------------------------------------------------------------------- @@ -116,24 +193,45 @@ endif ( ) #------------------------------------------------------------------------------- # libm: -if ( NOT WIN32 ) - target_link_libraries ( suitesparseconfig PUBLIC m ) - if ( NOT NSTATIC ) - target_link_libraries ( suitesparseconfig_static PUBLIC m ) +include ( CheckSymbolExists ) +check_symbol_exists ( fmax "math.h" NO_LIBM ) +if ( NOT NO_LIBM ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries ( SuiteSparseConfig PRIVATE m ) + endif ( ) + if ( BUILD_STATIC_LIBS ) + target_link_libraries ( SuiteSparseConfig_static PUBLIC m ) + list ( APPEND SUITESPARSE_CONFIG_STATIC_LIBS "m" ) endif ( ) endif ( ) # OpenMP: -if ( OPENMP_FOUND ) +if ( SUITESPARSE_CONFIG_HAS_OPENMP ) message ( STATUS "OpenMP C libraries: ${OpenMP_C_LIBRARIES} ") message ( STATUS "OpenMP C include: ${OpenMP_C_INCLUDE_DIRS} ") message ( STATUS "OpenMP C flags: ${OpenMP_C_FLAGS} ") - target_link_libraries ( suitesparseconfig PUBLIC ${OpenMP_C_LIBRARIES} ) - if ( NOT NSTATIC ) - target_link_libraries ( suitesparseconfig_static PUBLIC ${OpenMP_C_LIBRARIES} ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries ( SuiteSparseConfig PRIVATE OpenMP::OpenMP_C ) + target_include_directories ( SuiteSparseConfig SYSTEM AFTER INTERFACE + "$" ) + endif ( ) + if ( BUILD_STATIC_LIBS ) + target_link_libraries ( SuiteSparseConfig_static PRIVATE OpenMP::OpenMP_C ) + target_include_directories ( SuiteSparseConfig_static SYSTEM AFTER INTERFACE + "$" ) + list ( APPEND SUITESPARSE_CONFIG_STATIC_LIBS ${OpenMP_C_LIBRARIES} ) + endif ( ) +else ( ) + # librt + if ( WITH_RT ) + if ( BUILD_SHARED_LIBS ) + target_link_libraries ( SuiteSparseConfig PRIVATE "rt" ) + endif ( ) + if ( BUILD_STATIC_LIBS ) + target_link_libraries ( SuiteSparseConfig_static PRIVATE "rt" ) + list ( APPEND SUITESPARSE_CONFIG_STATIC_LIBS "rt" ) + endif ( ) endif ( ) - set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS} " ) - include_directories ( ${OpenMP_C_INCLUDE_DIRS} ) endif ( ) # BLAS: @@ -147,23 +245,123 @@ if ( BLAS_FOUND ) endif ( ) #------------------------------------------------------------------------------- -# suitesparseconfig installation location +# SuiteSparseConfig installation location #------------------------------------------------------------------------------- +include ( CMakePackageConfigHelpers ) + file ( GLOB SUITESPARSE_CMAKE_MODULES "cmake_modules/*" ) -install ( TARGETS suitesparseconfig - LIBRARY DESTINATION ${SUITESPARSE_LIBDIR} - ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} - RUNTIME DESTINATION ${SUITESPARSE_BINDIR} - PUBLIC_HEADER DESTINATION ${SUITESPARSE_INCLUDEDIR} ) +if ( BUILD_SHARED_LIBS ) + install ( TARGETS SuiteSparseConfig + EXPORT SuiteSparse_configTargets + LIBRARY DESTINATION ${SUITESPARSE_LIBDIR} + ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} + RUNTIME DESTINATION ${SUITESPARSE_BINDIR} + PUBLIC_HEADER DESTINATION ${SUITESPARSE_INCLUDEDIR} ) +endif ( ) +if ( BUILD_STATIC_LIBS ) + install ( TARGETS SuiteSparseConfig_static + EXPORT SuiteSparse_configTargets + ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} + PUBLIC_HEADER DESTINATION ${SUITESPARSE_INCLUDEDIR} ) +endif ( ) install ( FILES ${SUITESPARSE_CMAKE_MODULES} - DESTINATION ${SUITESPARSE_LIBDIR}/cmake/SuiteSparse + DESTINATION ${SUITESPARSE_PKGFILEDIR}/cmake/SuiteSparse COMPONENT Development ) -if ( NOT NSTATIC ) - install ( TARGETS suitesparseconfig_static - ARCHIVE DESTINATION ${SUITESPARSE_LIBDIR} ) + +# create (temporary) export target file during build +export ( EXPORT SuiteSparse_configTargets + NAMESPACE SuiteSparse:: + FILE ${CMAKE_CURRENT_BINARY_DIR}/SuiteSparse_configTargets.cmake ) + +# install export target and config for find_package +install ( EXPORT SuiteSparse_configTargets + NAMESPACE SuiteSparse:: + DESTINATION ${SUITESPARSE_PKGFILEDIR}/cmake/SuiteSparse_config ) + +configure_package_config_file ( + Config/SuiteSparse_configConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/SuiteSparse_configConfig.cmake + INSTALL_DESTINATION ${SUITESPARSE_PKGFILEDIR}/cmake/SuiteSparse_config ) + +write_basic_package_version_file ( + ${CMAKE_CURRENT_BINARY_DIR}/SuiteSparse_configConfigVersion.cmake + COMPATIBILITY SameMajorVersion ) + +install ( FILES + ${CMAKE_CURRENT_BINARY_DIR}/SuiteSparse_configConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/SuiteSparse_configConfigVersion.cmake + DESTINATION ${SUITESPARSE_PKGFILEDIR}/cmake/SuiteSparse_config ) + +#------------------------------------------------------------------------------- +# create pkg-config file +#------------------------------------------------------------------------------- + +if ( NOT MSVC ) + # 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 ( SUITESPARSE_CONFIG_STATIC_LIBS_LIST ${SUITESPARSE_CONFIG_STATIC_LIBS} ) + set ( SUITESPARSE_CONFIG_STATIC_LIBS "" ) + foreach ( _lib ${SUITESPARSE_CONFIG_STATIC_LIBS_LIST} ) + string ( FIND ${_lib} "." _pos REVERSE ) + if ( ${_pos} EQUAL "-1" ) + set ( SUITESPARSE_CONFIG_STATIC_LIBS "${SUITESPARSE_CONFIG_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 ( SUITESPARSE_CONFIG_STATIC_LIBS "${SUITESPARSE_CONFIG_STATIC_LIBS} -l${_libname}" ) + break () + endif ( ) + endif ( ) + endforeach ( ) + endforeach ( ) + + 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/SuiteSparse_config.pc.in + SuiteSparse_config.pc.out + @ONLY + NEWLINE_STYLE LF ) + file ( GENERATE + OUTPUT SuiteSparse_config.pc + INPUT ${CMAKE_CURRENT_BINARY_DIR}/SuiteSparse_config.pc.out + NEWLINE_STYLE LF ) + install ( FILES + ${CMAKE_CURRENT_BINARY_DIR}/SuiteSparse_config.pc + DESTINATION ${SUITESPARSE_PKGFILEDIR}/pkgconfig ) endif ( ) +#------------------------------------------------------------------------------- +# report status +#------------------------------------------------------------------------------- + include ( SuiteSparseReport ) diff --git a/SuiteSparse_config/Config/README.md.in b/SuiteSparse_config/Config/README.md.in index e45ae9c0..16fbb9f9 100644 --- a/SuiteSparse_config/Config/README.md.in +++ b/SuiteSparse_config/Config/README.md.in @@ -9,11 +9,41 @@ by Tim Davis, available at https://github.com/DrTimothyAldenDavis/SuiteSparse . Primary author of SuiteSparse (codes and algorithms, excl. METIS): Tim Davis -Code co-authors, in alphabetical order (not including METIS): - Patrick Amestoy, David Bateman, Jinhao Chen, Yanqing Chen, Iain Duff, - Les Foster, William Hager, Scott Kolodziej, Chris Lourenco, Stefan - Larimore, Erick Moreno-Centeno, Ekanathan Palamadai, Sivasankaran - Rajamanickam, Sanjay Ranka, Wissam Sid-Lakhdar, Nuri Yeralan. +Code co-authors, in alphabetical order (not including METIS or LAGraph): + Patrick Amestoy, Mohsen Aznaveh, David Bateman, Jinhao Chen, Yanqing Chen, + Iain Duff, Joe Eaton, Les Foster, William Hager, Raye Kimmerer, Scott + Kolodziej, Chris Lourenco, Stefan Larimore, Lorena Mejia Domenzain, Erick + Moreno-Centeno, Markus Mützel, Corey Nolel, Ekanathan Palamadai, + Sivasankaran Rajamanickam, Sanjay Ranka, Wissam Sid-Lakhdar, and + Nuri Yeralan. + +LAGraph has been developed by the highest number of developers of any of +the packages in SuiteSparse and deserves its own list. The list also +appears in LAGraph/Contibutors.txt: + + Janos B. Antal, Budapest University of Technology and Economics, Hungary + Mohsen Aznaveh, Texas A&M University + David A. Bader New Jersey Institute of Technology + Aydin Buluc, Lawrence Berkeley National Lab + Jinhao Chen, Texas A&M University + Tim Davis, Texas A&M University + Florentin Dorre, Technische Univeritat Dresden, Neo4j + Marton Elekes, Budapest University of Technology and Economics, Hungary + Balint Hegyi, Budapest University of Technology and Economics, Hungary + Tanner Hoke, Texas A&M University + James Kitchen, Anaconda + Scott Kolodziej, Texas A&M University + Pranav Konduri, Texas A&M University + Roi Lipman, Redis Labs (now FalkorDB) + 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 California at Davis, Waymo + Yongzhe Zhang, SOKENDAI, Japan METIS is authored by George Karypis. @@ -21,17 +51,460 @@ Additional algorithm designers: Esmond Ng and John Gilbert. Refer to each package for license, copyright, and author information. +----------------------------------------------------------------------------- +Documentation +----------------------------------------------------------------------------- + +Refer to each package for the documentation on each package, typically in the +Doc subfolder. + ----------------------------------------------------------------------------- SuiteSparse branches ----------------------------------------------------------------------------- - * dev: the default branch, with recent updates of features to appear in - the next stable release. The intent is to keep this branch in - fully working order at all times, but the features will not be - finalized at any given time. - * stable: the most recent stable release. - * dev2: working branch. All submitted PRs should made to this branch. - This branch might not always be in working order. +* dev: the default branch, with recent updates of features to appear in + the next stable release. The intent is to keep this branch in + fully working order at all times, but the features will not be + finalized at any given time. +* stable: the most recent stable release. +* dev2: working branch. All submitted PRs should made to this branch. + This branch might not always be in working order. + +----------------------------------------------------------------------------- +SuiteSparse Packages +----------------------------------------------------------------------------- + +Packages in SuiteSparse, and files in this directory: + +* `AMD` + + approximate minimum degree ordering. This is the built-in AMD function in + MATLAB. + + authors: Tim Davis, Patrick Amestoy, Iain Duff + +* `bin` + + where programs are placed when compiled, for `make local` + +* `BTF` + + permutation to block triangular form + + authors: Tim Davis, Ekanathan Palamadai + +* `build` + + folder for default build tree + +* `CAMD` + + constrained approximate minimum degree ordering + + authors: Tim Davis, Patrick Amestoy, Iain Duff, Yanqing Chen + +* `CCOLAMD` + + constrained column approximate minimum degree ordering + + authors: Tim Davis, Sivasankaran Rajamanickam, Stefan Larimore. + + Algorithm design collaborators: Esmond Ng, John Gilbert (for COLAMD) + +* `ChangeLog` + + a summary of changes to SuiteSparse. See `*/Doc/ChangeLog` for details for + each package. + +* `CHOLMOD` + + sparse Cholesky factorization. Requires AMD, COLAMD, CCOLAMD, the BLAS, and + LAPACK. Optionally uses METIS. This is `chol` and `x=A\b` in MATLAB. + + author for all modules: Tim Davis + + CHOLMOD/Modify module authors: Tim Davis and William W. Hager + + CHOLMOD/SuiteSparse_metis: a modified version of METIS, embedded into the + CHOLMOD library. See the README.txt files for details. author: George + Karypis. This is a slightly modified copy included with SuiteSparse via the + open-source license provided by George Karypis. SuiteSparse cannot use an + unmodified copy of METIS. + +* `CITATION.bib` + + citations for SuiteSparse packages, in bibtex format. + +* `CMakeLists.txt` + + optional, to compile all of SuiteSparse. See below. + +* `CODE_OF_CONDUCT.md` + + community guidelines + +* `COLAMD` + + column approximate minimum degree ordering. This is the built-in COLAMD + function in MATLAB. + + authors (of the code): Tim Davis and Stefan Larimore + + Algorithm design collaborators: Esmond Ng, John Gilbert + +* `Contents.m` + + a list of contents for 'help SuiteSparse' in MATLAB. + +* `CONTRIBUTING.md` + + how to contribute to SuiteSparse + +* `CONTRIBUTOR-LICENSE.txt` + + required contributor agreement + +* `CSparse` + + a concise sparse matrix package, developed for my book, "Direct Methods for + Sparse Linear Systems", published by SIAM. Intended primarily for teaching. + Note that the code is (c) Tim Davis, as stated in the book. + + For production, use CXSparse instead. In particular, both CSparse and + CXSparse have the same include filename: `cs.h`. This package is used for + the built-in DMPERM in MATLAB. + + author: Tim Davis + +* `CXSparse` + + CSparse Extended. Includes support for complex matrices and both int or long + integers. Use this instead of CSparse for production use; it creates a + libcsparse.so (or dylib on the Mac) with the same name as CSparse. It is a + superset of CSparse. Any code that links against CSparse should also be able + to link against CXSparse instead. + + author: Tim Davis, David Bateman + +* `Example` + + a simple package that relies on almost all of SuiteSparse + +* `.github` + + workflows for CI testing on GitHub. + +* `GraphBLAS` + + graph algorithms in the language of linear algebra. + + https://graphblas.org + + authors: Tim Davis, Joe Eaton, Corey Nolet + +* `include` + + `make install` places user-visible include files for each package here, after + `make local`. + +* `KLU` + + sparse LU factorization, primarily for circuit simulation. Requires AMD, + COLAMD, and BTF. Optionally uses CHOLMOD, CAMD, CCOLAMD, and METIS. + + authors: Tim Davis, Ekanathan Palamadai + +* `LAGraph` + + a graph algorithms library based on GraphBLAS. See also + https://github.com/GraphBLAS/LAGraph + + Authors: many. + +* `LDL` + + a very concise LDL' factorization package + + author: Tim Davis + +* `lib` + + `make install` places shared libraries for each package here, after + `make local`. + +* `LICENSE.txt` + + collected licenses for each package. + +* `Makefile` + + optional, to compile all of SuiteSparse using `make`, which is used as a + simple wrapper for `cmake` in each subproject. + + * `make` + + compiles SuiteSparse libraries. Subsequent `make install` will install + in `CMAKE_INSTALL_PATH` (might default to `/usr/local/lib` on Linux or Mac). + + * `make local` + + compiles SuiteSparse. Subsequent `make install` will install in `./lib`, + `./include`. Does not install in `CMAKE_INSTALL_PATH`. + + * `make global` + + compiles SuiteSparse libraries. Subsequent `make install` will install in + `/usr/local/lib` (or whatever the configured `CMAKE_INSTALL_PREFIX` is). + Does not install in `./lib` and `./include`. + + * `make install` + + installs in the current directory (`./lib`, `./include`), or in + `/usr/local/lib` and `/usr/local/include`, (the latter defined by + `CMAKE_INSTALL_PREFIX`) depending on whether `make`, `make local`, or + `make global` has been done. + + * `make uninstall` + + undoes `make install`. + + * `make distclean` + + removes all files not in distribution, including `./bin`, `./share`, + `./lib`, and `./include`. + + * `make purge` + + same as `make distclean`. + + * `make clean` + + removes all files not in distribution, but keeps compiled libraries and + demos, `./lib`, `./share`, and `./include`. + + Each individual subproject also has each of the above `make` targets. + + Things you don't need to do: + + * `make docs` + + creates user guides from LaTeX files + + * `make cov` + + runs statement coverage tests (Linux only) + +* `MATLAB_Tools` + + various m-files for use in MATLAB + + author: Tim Davis (all parts) + + for `spqr_rank`: author Les Foster and Tim Davis + + * `Contents.m` + + list of contents + + * `dimacs10` + + loads matrices for DIMACS10 collection + + * `Factorize` + + object-oriented `x=A\b` for MATLAB + + * `find_components` + + finds connected components in an image + + * `GEE` + + simple Gaussian elimination + + * `getversion.m` + + determine MATLAB version + + * `gipper.m` + + create MATLAB archive + + * `hprintf.m` + + print hyperlinks in command window + + * `LINFACTOR` + + predecessor to `Factorize` package + + * `MESHND` + + nested dissection ordering of regular meshes + + * `pagerankdemo.m` + + illustrates how PageRank works + + * `SFMULT` + + `C=S*F` where `S` is sparse and `F` is full + + * `shellgui` + + display a seashell + + * `sparseinv` + + sparse inverse subset + + * `spok` + + check if a sparse matrix is valid + + * `spqr_rank` + + SPQR_RANK package. MATLAB toolbox for rank deficient sparse matrices: null + spaces, reliable factorizations, etc. With Leslie Foster, San Jose State + Univ. + + * `SSMULT` + + `C=A*B` where `A` and `B` are both sparse. + This was the basis for the built-in `C=A*B` in MATLAB, until it was + superseded by GraphBLAS in MATLAB R2021a. + + * `SuiteSparseCollection` + + for the SuiteSparse Matrix Collection + + * `waitmex` + + waitbar for use inside a mexFunction + +* `Mongoose` + + graph partitioning. + + authors: Nuri Yeralan, Scott Kolodziej, William Hager, Tim Davis + +* `ParU` + + a parallel unsymmetric pattern multifrontal method. + + Currently a pre-release. + + authors: Mohsen Aznaveh and Tim Davis + +* `RBio` + + read/write sparse matrices in Rutherford/Boeing format + + author: Tim Davis + +* `README.md` + + this file + +* `SPEX` + + solves sparse linear systems in exact arithmetic. + + Requires the GNU GMP and MPRF libraries. + + This will be soon replaced by a more general package, SPEX v3 that includes + this method (exact sparse LU) and others (sparse exact Cholesky, and sparse + exact update/downdate). The API of v3 will be changing significantly. + + authors: Chris Lourenco, Jinhao Chen, Erick Moreno-Centeno, + Lorena Lorena Mejia Domenzain, and Tim Davis. + + See https://github.com/clouren/SPEX for the latest version. + +* `SPQR` + + sparse QR factorization. This the built-in `qr` and `x=A\b` in MATLAB. Also + called SuiteSparseQR. + + Includes two GPU libraries: `SPQR/GPUQREngine` and + `SPQR/SuiteSparse_GPURuntime`. + + author of the CPU code: Tim Davis + + author of GPU modules: Tim Davis, Nuri Yeralan, Wissam Sid-Lakhdar, + Sanjay Ranka + +* `ssget` + + MATLAB interface to the SuiteSparse Matrix Collection + + author: Tim Davis + +* `SuiteSparse_config` + + library with common functions and configuration for all the above packages. + `CSparse`, `GraphBLAS`, `LAGraph`, and `MATLAB_Tools` do not use + `SuiteSparse_config`. + + author: Tim Davis + +* `SuiteSparse_demo.m` + + a demo of SuiteSparse for MATLAB + +* `SuiteSparse_install.m` + + install SuiteSparse for MATLAB + +* `SuiteSparse_paths.m` + + set paths for SuiteSparse MATLAB mexFunctions + +* `SuiteSparse_test.m` + + exhaustive test for SuiteSparse in MATLAB + +* `UMFPACK` + + sparse LU factorization. Requires `AMD` and the `BLAS`. + + This is the built-in `lu` and `x=A\b` in MATLAB. + + author: Tim Davis + + algorithm design collaboration: Iain Duff + +Refer to each package for license, copyright, and author information. All +codes are authored or co-authored by Timothy A. Davis (email: davis@tamu.edu), +except for METIS (by George Karypis), `GraphBLAS/cpu_features` (by Google), +GraphBLAS/lz4, zstd, and xxHash (by Yann Collet, now at Facebook), and +GraphBLAS/CUDA/jitify.hpp (by NVIDIA). Parts of GraphBLAS/CUDA are +Copyright (c) by NVIDIA. Please refer to each of these licenses. + +----------------------------------------------------------------------------- +For distro maintainers (Linux, homebrew, spack, R, Octave, Trilinos, ...): +----------------------------------------------------------------------------- + +Thanks for packaging SuiteSparse! Here are some suggestions: + +* GraphBLAS takes a long time to compile because it creates many fast + "FactoryKernels" at compile-time. If you want to reduce the compile time and + library size, enable the `GRAPHBLAS_COMPACT` mode, but keep the JIT compiler + enabled. Then GraphBLAS will compile the kernels it needs at run-time, via + its JIT compiler. Performance will be the same as the FactoryKernels once + the JIT kernels are compiled. User compiled kernels are placed in + `~/.SuiteSparse`, by default. You do not need to distribute the source for + GraphBLAS to enable the JIT compiler: just `libgraphblas.so` and + `GraphBLAS.h` is enough. + +* GraphBLAS needs OpenMP! It's fundamentally a parallel code so please + distribute it with OpenMP enabled. Performance will suffer otherwise. + +* CUDA acceleration: CHOLMOD and SPQR can benefit from their CUDA kernels. If + you do not have CUDA or do not want to include it in your distro, this + version of SuiteSparse skips the building of the `CHOLMOD_CUDA` and `SPQR_CUDA` + libraries, and does not link against the `GPUQREngine` and + `SuiteSparse_GPURuntime` libraries. ----------------------------------------------------------------------------- How to cite the SuiteSparse meta-package and its component packages: @@ -40,193 +513,180 @@ How to cite the SuiteSparse meta-package and its component packages: SuiteSparse is a meta-package of many packages, each with their own published papers. To cite the whole collection, use the URLs: - * https://github.com/DrTimothyAldenDavis/SuiteSparse - * http://suitesparse.com (which is a forwarding URL +* https://github.com/DrTimothyAldenDavis/SuiteSparse +* http://suitesparse.com (which is a forwarding URL to https://people.engr.tamu.edu/davis/suitesparse.html) Please also cite the specific papers for the packages you use. This is a long list; if you want a shorter list, just cite the most recent "Algorithm XXX:" papers in ACM TOMS, for each package. - * For the MATLAB x=A\b, see below for AMD, COLAMD, CHOLMOD, UMFPACK, - and SuiteSparseQR (SPQR). +* For the MATLAB x=A\b, see below for AMD, COLAMD, CHOLMOD, UMFPACK, + and SuiteSparseQR (SPQR). - * for GraphBLAS, and `C=A*B` in MATLAB (sparse-times-sparse): +* for GraphBLAS, and C=AB in MATLAB (sparse-times-sparse): - T. Davis, Algorithm 10xx: SuiteSparse:GraphBLAS: parallel graph - algorithms in the language of sparse linear algebra, ACM Trans on - Mathematical Software, to appear, 2023. See the pdf in - https://github.com/DrTimothyAldenDavis/GraphBLAS/tree/stable/Doc + T. A. Davis. Algorithm 1037: SuiteSparse:GraphBLAS: Parallel Graph Algorithms + in the Language of Sparse Linear Algebra. ACM Trans. Math. Softw. 49, 3, + Article 28 (September 2023), 30 pages. https://doi.org/10.1145/3577195 - T. Davis, Algorithm 1000: SuiteSparse:GraphBLAS: graph algorithms in - the language of sparse linear algebra, ACM Trans on Mathematical - Software, vol 45, no 4, Dec. 2019, Article No 44. - https://doi.org/10.1145/3322125. + T. Davis, Algorithm 1000: SuiteSparse:GraphBLAS: graph algorithms in the + language of sparse linear algebra, ACM Trans on Mathematical Software, vol + 45, no 4, Dec. 2019, Article No 44. https://doi.org/10.1145/3322125. - * for CSparse/CXSParse: +* for LAGraph: - T. A. Davis, Direct Methods for Sparse Linear Systems, SIAM Series on - the Fundamentals of Algorithms, SIAM, Philadelphia, PA, 2006. - https://doi.org/10.1137/1.9780898718881 + G. Szárnyas et al., "LAGraph: Linear Algebra, Network Analysis Libraries, and + the Study of Graph Algorithms," 2021 IEEE International Parallel and + Distributed Processing Symposium Workshops (IPDPSW), Portland, OR, USA, 2021, + pp. 243-252. https://doi.org/10.1109/IPDPSW52791.2021.00046. - * for SuiteSparseQR (SPQR): (also cite AMD, COLAMD): +* for CSparse/CXSParse: - T. A. Davis, Algorithm 915: SuiteSparseQR: Multifrontal multithreaded - rank-revealing sparse QR factorization, ACM Trans. on Mathematical - Software, 38(1), 2011, pp. 8:1--8:22. - https://doi.org/10.1145/2049662.2049670 + T. A. Davis, Direct Methods for Sparse Linear Systems, SIAM Series on the + Fundamentals of Algorithms, SIAM, Philadelphia, PA, 2006. + https://doi.org/10.1137/1.9780898718881 - * for SuiteSparseQR/GPU: +* for SuiteSparseQR (SPQR): (also cite AMD, COLAMD): - Sencer Nuri Yeralan, T. A. Davis, Wissam M. Sid-Lakhdar, and Sanjay - Ranka. 2017. Algorithm 980: Sparse QR Factorization on the GPU. ACM - Trans. Math. Softw. 44, 2, Article 17 (June 2018), 29 pages. - https://doi.org/10.1145/3065870 + T. A. Davis, Algorithm 915: SuiteSparseQR: Multifrontal multithreaded + rank-revealing sparse QR factorization, ACM Trans. on Mathematical Software, + 38(1), 2011, pp. 8:1--8:22. https://doi.org/10.1145/2049662.2049670 - * for CHOLMOD: (also cite AMD, COLAMD): +* for SuiteSparseQR/GPU: - Y. Chen, T. A. Davis, W. W. Hager, and S. Rajamanickam, Algorithm 887: - CHOLMOD, supernodal sparse Cholesky factorization and update/downdate, - ACM Trans. on Mathematical Software, 35(3), 2008, pp. 22:1--22:14. - https://dl.acm.org/doi/abs/10.1145/1391989.1391995 + Sencer Nuri Yeralan, T. A. Davis, Wissam M. Sid-Lakhdar, and Sanjay Ranka. + 2017. Algorithm 980: Sparse QR Factorization on the GPU. ACM Trans. Math. + Softw. 44, 2, Article 17 (June 2018), 29 pages. + https://doi.org/10.1145/3065870 - T. A. Davis and W. W. Hager, Dynamic supernodes in sparse Cholesky - update/downdate and triangular solves, ACM Trans. on Mathematical - Software, 35(4), 2009, pp. 27:1--27:23. - https://doi.org/10.1145/1462173.1462176 +* for CHOLMOD: (also cite AMD, COLAMD): - * for CHOLMOD/Modify Module: (also cite AMD, COLAMD): + Y. Chen, T. A. Davis, W. W. Hager, and S. Rajamanickam, Algorithm 887: + CHOLMOD, supernodal sparse Cholesky factorization and update/downdate, ACM + Trans. on Mathematical Software, 35(3), 2008, pp. 22:1--22:14. + https://dl.acm.org/doi/abs/10.1145/1391989.1391995 - T. A. Davis and William W. Hager, Row Modifications of a Sparse - Cholesky Factorization SIAM Journal on Matrix Analysis and Applications - 2005 26:3, 621-639 - https://doi.org/10.1137/S089547980343641X + T. A. Davis and W. W. Hager, Dynamic supernodes in sparse Cholesky + update/downdate and triangular solves, ACM Trans. on Mathematical Software, + 35(4), 2009, pp. 27:1--27:23. https://doi.org/10.1145/1462173.1462176 - T. A. Davis and William W. Hager, Multiple-Rank Modifications of a - Sparse Cholesky Factorization SIAM Journal on Matrix Analysis and - Applications 2001 22:4, 997-1013 - https://doi.org/10.1137/S0895479899357346 +* for CHOLMOD/Modify Module: (also cite AMD, COLAMD): - T. A. Davis and William W. Hager, Modifying a Sparse Cholesky - Factorization, SIAM Journal on Matrix Analysis and Applications 1999 - 20:3, 606-627 - https://doi.org/10.1137/S0895479897321076 + T. A. Davis and William W. Hager, Row Modifications of a Sparse Cholesky + Factorization SIAM Journal on Matrix Analysis and Applications 2005 26:3, + 621-639. https://doi.org/10.1137/S089547980343641X - * for CHOLMOD/GPU Modules: + T. A. Davis and William W. Hager, Multiple-Rank Modifications of a Sparse + Cholesky Factorization SIAM Journal on Matrix Analysis and Applications 2001 + 22:4, 997-1013. https://doi.org/10.1137/S0895479899357346 - Steven C. Rennich, Darko Stosic, Timothy A. Davis, Accelerating sparse - Cholesky factorization on GPUs, Parallel Computing, Vol 59, 2016, pp - 140-150. - https://doi.org/10.1016/j.parco.2016.06.004 + T. A. Davis and William W. Hager, Modifying a Sparse Cholesky Factorization, + SIAM Journal on Matrix Analysis and Applications 1999 20:3, 606-627. + https://doi.org/10.1137/S0895479897321076 - * for AMD and CAMD: +* for CHOLMOD/GPU Modules: - P. Amestoy, T. A. Davis, and I. S. Duff, Algorithm 837: An approximate - minimum degree ordering algorithm, ACM Trans. on Mathematical Software, - 30(3), 2004, pp. 381--388. - https://dl.acm.org/doi/abs/10.1145/1024074.1024081 + Steven C. Rennich, Darko Stosic, Timothy A. Davis, Accelerating sparse + Cholesky factorization on GPUs, Parallel Computing, Vol 59, 2016, pp 140-150. + https://doi.org/10.1016/j.parco.2016.06.004 - P. Amestoy, T. A. Davis, and I. S. Duff, An approximate minimum degree - ordering algorithm, SIAM J. Matrix Analysis and Applications, 17(4), - 1996, pp. 886--905. - https://doi.org/10.1137/S0895479894278952 +* for AMD and CAMD: - * for COLAMD, SYMAMD, CCOLAMD, and CSYMAMD: + P. Amestoy, T. A. Davis, and I. S. Duff, Algorithm 837: An approximate + minimum degree ordering algorithm, ACM Trans. on Mathematical Software, + 30(3), 2004, pp. 381--388. + https://dl.acm.org/doi/abs/10.1145/1024074.1024081 - T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, Algorithm 836: COLAMD, - an approximate column minimum degree ordering algorithm, ACM Trans. on - Mathematical Software, 30(3), 2004, pp. 377--380. - https://doi.org/10.1145/1024074.1024080 + P. Amestoy, T. A. Davis, and I. S. Duff, An approximate minimum degree + ordering algorithm, SIAM J. Matrix Analysis and Applications, 17(4), 1996, + pp. 886--905. https://doi.org/10.1137/S0895479894278952 - T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, A column approximate - minimum degree ordering algorithm, ACM Trans. on Mathematical Software, - 30(3), 2004, pp. 353--376. - https://doi.org/10.1145/1024074.1024079 +* for COLAMD, SYMAMD, CCOLAMD, and CSYMAMD: - * for UMFPACK: (also cite AMD and COLAMD): + T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, Algorithm 836: COLAMD, an + approximate column minimum degree ordering algorithm, ACM Trans. on + Mathematical Software, 30(3), 2004, pp. 377--380. + https://doi.org/10.1145/1024074.1024080 - T. A. Davis, Algorithm 832: UMFPACK - an unsymmetric-pattern - multifrontal method with a column pre-ordering strategy, ACM Trans. on - Mathematical Software, 30(2), 2004, pp. 196--199. - https://dl.acm.org/doi/abs/10.1145/992200.992206 + T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, A column approximate minimum + degree ordering algorithm, ACM Trans. on Mathematical Software, 30(3), 2004, + pp. 353--376. https://doi.org/10.1145/1024074.1024079 - T. A. Davis, A column pre-ordering strategy for the unsymmetric-pattern - multifrontal method, ACM Trans. on Mathematical Software, 30(2), 2004, - pp. 165--195. - https://dl.acm.org/doi/abs/10.1145/992200.992205 +* for UMFPACK: (also cite AMD and COLAMD): - T. A. Davis and I. S. Duff, A combined unifrontal/multifrontal method - for unsymmetric sparse matrices, ACM Trans. on Mathematical Software, - 25(1), 1999, pp. 1--19. - https://doi.org/10.1145/305658.287640 + T. A. Davis, Algorithm 832: UMFPACK - an unsymmetric-pattern multifrontal + method with a column pre-ordering strategy, ACM Trans. on Mathematical + Software, 30(2), 2004, pp. 196--199. + https://dl.acm.org/doi/abs/10.1145/992200.992206 - T. A. Davis and I. S. Duff, An unsymmetric-pattern multifrontal method - for sparse LU factorization, SIAM J. Matrix Analysis and Computations, - 18(1), 1997, pp. 140--158. - https://doi.org/10.1137/S0895479894246905 + T. A. Davis, A column pre-ordering strategy for the unsymmetric-pattern + multifrontal method, ACM Trans. on Mathematical Software, 30(2), 2004, pp. + 165--195. https://dl.acm.org/doi/abs/10.1145/992200.992205 - * for the FACTORIZE m-file: + T. A. Davis and I. S. Duff, A combined unifrontal/multifrontal method for + unsymmetric sparse matrices, ACM Trans. on Mathematical Software, 25(1), + 1999, pp. 1--19. https://doi.org/10.1145/305658.287640 - T. A. Davis, Algorithm 930: FACTORIZE, an object-oriented linear system - solver for MATLAB, ACM Trans. on Mathematical Software, 39(4), 2013, - pp. 28:1-28:18. - https://doi.org/10.1145/2491491.2491498 + T. A. Davis and I. S. Duff, An unsymmetric-pattern multifrontal method for + sparse LU factorization, SIAM J. Matrix Analysis and Computations, 18(1), + 1997, pp. 140--158. https://doi.org/10.1137/S0895479894246905 - * for KLU and BTF (also cite AMD and COLAMD): +* for the FACTORIZE m-file: - T. A. Davis and Ekanathan Palamadai Natarajan. 2010. Algorithm 907: - KLU, A Direct Sparse Solver for Circuit Simulation Problems. ACM Trans. - Math. Softw. 37, 3, Article 36 (September 2010), 17 pages. - https://dl.acm.org/doi/abs/10.1145/1824801.1824814 + T. A. Davis, Algorithm 930: FACTORIZE, an object-oriented linear system + solver for MATLAB, ACM Trans. on Mathematical Software, 39(4), 2013, pp. + 28:1-28:18. https://doi.org/10.1145/2491491.2491498 - * for LDL: +* for KLU and BTF (also cite AMD and COLAMD): - T. A. Davis. Algorithm 849: A concise sparse Cholesky factorization - package. ACM Trans. Math. Softw. 31, 4 (December 2005), 587–591. - https://doi.org/10.1145/1114268.1114277 + T. A. Davis and Ekanathan Palamadai Natarajan. 2010. Algorithm 907: KLU, A + Direct Sparse Solver for Circuit Simulation Problems. ACM Trans. Math. + Softw. 37, 3, Article 36 (September 2010), 17 pages. + https://dl.acm.org/doi/abs/10.1145/1824801.1824814 - * for ssget and the SuiteSparse Matrix Collection: +* for LDL: - T. A. Davis and Yifan Hu. 2011. The University of Florida sparse - matrix collection. ACM Trans. Math. Softw. 38, 1, Article 1 (November - 2011), 25 pages. - https://doi.org/10.1145/2049662.2049663 + T. A. Davis. Algorithm 849: A concise sparse Cholesky factorization package. + ACM Trans. Math. Softw. 31, 4 (December 2005), 587–591. + https://doi.org/10.1145/1114268.1114277 - Kolodziej et al., (2019). The SuiteSparse Matrix Collection Website - Interface. Journal of Open Source Software, 4(35), 1244, - https://doi.org/10.21105/joss.01244 +* for ssget and the SuiteSparse Matrix Collection: - * for `spqr_rank`: + T. A. Davis and Yifan Hu. 2011. The University of Florida sparse matrix + collection. ACM Trans. Math. Softw. 38, 1, Article 1 (November 2011), 25 + pages. https://doi.org/10.1145/2049662.2049663 - Leslie V. Foster and T. A. Davis. 2013. Algorithm 933: Reliable - calculation of numerical rank, null space bases, pseudoinverse - solutions, and basic solutions using suitesparseQR. ACM Trans. Math. - Softw. 40, 1, Article 7 (September 2013), 23 pages. - https://doi.org/10.1145/2513109.2513116 + Kolodziej et al., (2019). The SuiteSparse Matrix Collection Website + Interface. Journal of Open Source Software, 4(35), 1244. + https://doi.org/10.21105/joss.01244 - * for Mongoose: +* for `spqr_rank`: - T. A. Davis, William W. Hager, Scott P. Kolodziej, and S. Nuri Yeralan. - 2020. Algorithm 1003: Mongoose, a Graph Coarsening and Partitioning - Library. ACM Trans. Math. Softw. 46, 1, Article 7 (March 2020), 18 - pages. - https://doi.org/10.1145/3337792 + Leslie V. Foster and T. A. Davis. 2013. Algorithm 933: Reliable calculation + of numerical rank, null space bases, pseudoinverse solutions, and basic + solutions using suitesparseQR. ACM Trans. Math. Softw. 40, 1, Article 7 + (September 2013), 23 pages. https://doi.org/10.1145/2513109.2513116 - * for SPEX: +* for Mongoose: - Christopher Lourenco, Jinhao Chen, Erick Moreno-Centeno, and T. A. - Davis. 2022. Algorithm 1021: SPEX Left LU, Exactly Solving Sparse - Linear Systems via a Sparse Left-Looking Integer-Preserving LU - Factorization. ACM Trans. Math. Softw. June 2022. - https://doi.org/10.1145/3519024 + T. A. Davis, William W. Hager, Scott P. Kolodziej, and S. Nuri Yeralan. + 2020. Algorithm 1003: Mongoose, a Graph Coarsening and Partitioning Library. + ACM Trans. Math. Softw. 46, 1, Article 7 (March 2020), 18 pages. + https://doi.org/10.1145/3337792 + +* for SPEX: + + Christopher Lourenco, Jinhao Chen, Erick Moreno-Centeno, and T. A. Davis. + 2022. Algorithm 1021: SPEX Left LU, Exactly Solving Sparse Linear Systems via + a Sparse Left-Looking Integer-Preserving LU Factorization. ACM Trans. Math. + Softw. June 2022. https://doi.org/10.1145/3519024 ----------------------------------------------------------------------------- About the BLAS and LAPACK libraries ----------------------------------------------------------------------------- -NOTE: Use of the Intel MKL BLAS is strongly recommended. In a 2019 test, -OpenBLAS caused result in severe performance degradation. The reason for this -is being investigated, and this may be resolved in the near future. +NOTE: if you use OpenBLAS, be sure to use version 0.3.27 or later. To select your BLAS/LAPACK, see the instructions in SuiteSparseBLAS.cmake in `SuiteSparse_config/cmake_modules`. If `SuiteSparse_config` finds a BLAS with @@ -234,15 +694,17 @@ To select your BLAS/LAPACK, see the instructions in SuiteSparseBLAS.cmake in `SuiteSparse_config.h` with the `SUITESPARSE_BLAS_INT` defined as `int64_t`. Otherwise, if a 32-bit BLAS is found, this type is defined as `int32_t`. If later on, UMFPACK, CHOLMOD, or SPQR are compiled and linked with a BLAS that -has a different integer size, you must override the definition with -DBLAS64 -(to assert the use of 64-bit integers in the BLAS) or -DBLAS32, (to assert the -use of 32-bit integers in the BLAS). +has a different integer size, you must override the definition with `-DBLAS64` +(to assert the use of 64-bit integers in the BLAS) or `-DBLAS32`, (to assert +the use of 32-bit integers in the BLAS). + +The size of the BLAS integer has nothing to do with `sizeof(void *)`. When distributed in a binary form (such as a Debian, Ubuntu, Spack, or Brew package), SuiteSparse should probably be compiled to expect a 32-bit BLAS, since this is the most common case. The default is to use a 32-bit BLAS, but -this can be changed in SuiteSparseBLAS.cmake or by compiling with -`-DALLOW_64BIT_BLAS=1`. +this can be changed by setting the cmake variable +`SUITESPARSE_USE_64BIT_BLAS` to `ON`. By default, SuiteSparse hunts for a suitable BLAS library. To enforce a particular BLAS library use either: @@ -251,263 +713,140 @@ particular BLAS library use either: cd Package ; cmake -DBLA_VENDOR=OpenBLAS .. make To use the default (hunt for a BLAS), do not set `BLA_VENDOR`, or set it to -ANY. In this case, if `ALLOW_64BIT_BLAS` is set, preference is given to a -64-bit BLAS, but a 32-bit BLAS library will be used if no 64-bit library is -found. +`ANY`. In this case, if `SUITESPARSE_USE_64BIT_BLAS` is ON, preference is +given to a 64-bit BLAS, but a 32-bit BLAS library will be used if no 64-bit +library is found. However, if both `SUITESPARSE_USE_64BIT_BLAS` and +`SUITESPARSE_USE_STRICT` are ON, then only a 64-bit BLAS is considered. -When selecting a particular BLAS library, the `ALLOW_64BIT_BLAS` setting is -strictly followed. If set to true, only a 64-bit BLAS library will be used. -If false (the default), only a 32-bit BLAS library will be used. If no such -BLAS is found, the build will fail. +When selecting a particular BLAS library, the `SUITESPARSE_USE_64BIT_BLAS` +setting is strictly followed. If set to true, only a 64-bit BLAS library will +be used. If false (the default), only a 32-bit BLAS library will be used. If +no such BLAS is found, the build will fail. ------------------- -SuiteSparse/README ------------------- +----------------------------------------------------------------------------- +QUICK START FOR THE C/C++ LIBRARIES: +----------------------------------------------------------------------------- -Packages in SuiteSparse, and files in this directory: +Type the following in this directory (requires system priviledge to do the +`sudo make install`): +``` + mkdir -p build && cd build + cmake .. + cmake --build . + sudo cmake --install . +``` + +All libraries will be created and installed into the default system-wide folder +(/usr/local/lib on Linux). All include files needed by the applications that +use SuiteSparse are installed into /usr/local/include/suitesparse (on Linux). + +To build only a subset of libraries, set `SUITESPARSE_ENABLE_PROJECTS` when +configuring with CMake. E.g., to build and install CHOLMOD and CXSparse +(including their dependencies), use the following commands: +``` + mkdir -p build && cd build + cmake -DSUITESPARSE_ENABLE_PROJECTS="cholmod;cxsparse" .. + cmake --build . + sudo cmake --install . +``` + +For Windows (MSVC), import the `CMakeLists.txt` file into MS Visual Studio. +Be sure to specify the build type as Release; for example, to build SuiteSparse +on Windows in the command window, run: +``` + mkdir -p build && cd build + cmake .. + cmake --build . --config Release + cmake --install . +``` + +Be sure to first install all required libraries: BLAS and LAPACK for UMFPACK, +CHOLMOD, and SPQR, and GMP and MPFR for SPEX. Be sure to use the latest +libraries; SPEX requires MPFR 4.0.2 and GMP 6.1.2 (these version numbers +do NOT correspond to the X.Y.Z suffix of libgmp.so.X.Y.Z and libmpfr.so.X.Y.Z; +see the SPEX user guide for details). - GraphBLAS graph algorithms in the language of linear algebra. - https://graphblas.org - author: Tim Davis - - SPEX solves sparse linear systems in exact arithmetic. - Requires the GNU GMP and MPRF libraries. - This will be soon replaced by a more general package, SPEX v3 - that includes this method (exact sparse LU) and others (sparse - exact Cholesky, and sparse exact update/downdate). The API - of v3 will be changing significantly. - - AMD approximate minimum degree ordering. This is the built-in AMD - function in MATLAB. - authors: Tim Davis, Patrick Amestoy, Iain Duff - - bin where programs are placed when compiled - - BTF permutation to block triangular form - authors: Tim Davis, Ekanathan Palamadai - - CAMD constrained approximate minimum degree ordering - authors: Tim Davis, Patrick Amestoy, Iain Duff, Yanqing Chen - - CCOLAMD constrained column approximate minimum degree ordering - authors: Tim Davis, Sivasankaran Rajamanickam, Stefan Larimore. - Algorithm design collaborators: Esmond Ng, John Gilbert - (for COLAMD) - - ChangeLog a summary of changes to SuiteSparse. See */Doc/ChangeLog - for details for each package. - - CHOLMOD sparse Cholesky factorization. Requires AMD, COLAMD, CCOLAMD, - the BLAS, and LAPACK. Optionally uses METIS. This is chol and - x=A\b in MATLAB. - author for all modules: Tim Davis - CHOLMOD/Modify module authors: Tim Davis and William W. Hager - - COLAMD column approximate minimum degree ordering. This is the - built-in COLAMD function in MATLAB. - authors (of the code): Tim Davis and Stefan Larimore - Algorithm design collaborators: Esmond Ng, John Gilbert - - Contents.m a list of contents for 'help SuiteSparse' in MATLAB. - - CSparse a concise sparse matrix package, developed for my - book, "Direct Methods for Sparse Linear Systems", - published by SIAM. Intended primarily for teaching. - Note that the code is (c) Tim Davis, as stated in the book. - For production, use CXSparse instead. In particular, both - CSparse and CXSparse have the same include filename: cs.h. - This package is used for the built-in DMPERM in MATLAB. - author: Tim Davis - - CXSparse CSparse Extended. Includes support for complex matrices - and both int or long integers. Use this instead of CSparse - for production use; it creates a libcsparse.so (or *dylib on - the Mac) with the same name as CSparse. It is a superset - of CSparse. Any code that links against CSparse should - also be able to link against CXSparse instead. - author: Tim Davis, David Bateman - - include 'make install' places user-visible include files for each - package here, after 'make local' - - KLU sparse LU factorization, primarily for circuit simulation. - Requires AMD, COLAMD, and BTF. Optionally uses CHOLMOD, - CAMD, CCOLAMD, and METIS. - authors: Tim Davis, Ekanathan Palamadai - - LDL a very concise LDL' factorization package - author: Tim Davis - - lib 'make install' places shared libraries for each package - here, after 'make local' - - Makefile to compile all of SuiteSparse - - make compiles SuiteSparse libraries. - Subsequent "make install" will install - in just CMAKE_INSTALL_PATH (defaults to - /usr/local/lib on Linux or Mac). - - make both compiles SuiteSparse, and then "make install" - will instal in both ./lib and - CMAKE_INSTALL_PATH). - - make local compiles SuiteSparse. - Subsequent "make install will install only - in ./lib, ./include only. - Does not install in CMAKE_INSTALL_PATH. - - make global compiles SuiteSparse libraries. - Subsequent "make install" will install in - just /usr/local/lib (or whatever your - CMAKE_INSTALL_PREFIX is). - Does not install in ./lib and ./include. - - make install installs in the current directory - (./lib, ./include), and/or in - /usr/local/lib and /usr/local/include, - depending on whether "make", "make local", - "make global", or "make both", - etc has been done. - - make uninstall undoes 'make install' - - make distclean removes all files not in distribution, including - ./bin, ./share, ./lib, and ./include. - - make purge same as 'make distclean' - - make clean removes all files not in distribution, but - keeps compiled libraries and demoes, ./lib, - ./share, and ./include. - - Each individual package also has each of the above 'make' - targets. - - Things you don't need to do: - make docs creates user guides from LaTeX files - make cov runs statement coverage tests (Linux only) - - MATLAB_Tools various m-files for use in MATLAB - author: Tim Davis (all parts) - for spqr_rank: author Les Foster and Tim Davis - - Contents.m list of contents - dimacs10 loads matrices for DIMACS10 collection - Factorize object-oriented x=A\b for MATLAB - find_components finds connected components in an image - GEE simple Gaussian elimination - getversion.m determine MATLAB version - gipper.m create MATLAB archive - hprintf.m print hyperlinks in command window - LINFACTOR predecessor to Factorize package - MESHND nested dissection ordering of regular meshes - pagerankdemo.m illustrates how PageRank works - SFMULT C=S*F where S is sparse and F is full - shellgui display a seashell - sparseinv sparse inverse subset - spok check if a sparse matrix is valid - spqr_rank SPQR_RANK package. MATLAB toolbox for rank - deficient sparse matrices: null spaces, - reliable factorizations, etc. With Leslie - Foster, San Jose State Univ. - SSMULT C=A*B where A and B are both sparse - SuiteSparseCollection for the SuiteSparse Matrix Collection - waitmex waitbar for use inside a mexFunction - - The SSMULT and SFMULT functions are the basis for the - built-in C=A*B functions in MATLAB. - - Mongoose graph partitioning. - authors: Nuri Yeralan, Scott Kolodziej, William Hager, Tim Davis - - CHOLMOD/SuiteSparse_metis: a modified version of METIS, embedded into - the CHOLMOD library. See the README.txt files - for details. author: George Karypis. This is a slightly - modified copy included with SuiteSparse via the open-source - license provided by George Karypis. SuiteSparse cannot use - an unmodified copy METIS. - - RBio read/write sparse matrices in Rutherford/Boeing format - author: Tim Davis - - README.txt this file - - SPQR sparse QR factorization. This the built-in qr and x=A\b in - MATLAB. Also called SuiteSparseQR. - author of the CPU code: Tim Davis - author of GPU modules: Tim Davis, Nuri Yeralan, - Wissam Sid-Lakhdar, Sanjay Ranka - - GPUQREngine: GPU support package for SPQR - (not built into MATLAB, however) - authors: Tim Davis, Nuri Yeralan, Sanjay Ranka, - Wissam Sid-Lakhdar - - SuiteSparse_config configuration file for all the above packages. - CSparse and MATLAB_Tools do not use SuiteSparse_config. - author: Tim Davis - - SuiteSparse_GPURuntime GPU support package for SPQR and CHOLMOD - (not builtin to MATLAB, however). - - SuiteSparse_install.m install SuiteSparse for MATLAB - SuiteSparse_paths.m set paths for SuiteSparse MATLAB mexFunctions - - SuiteSparse_test.m exhaustive test for SuiteSparse in MATLAB - - ssget MATLAB interface to the SuiteSparse Matrix Collection - author: Tim Davis - - UMFPACK sparse LU factorization. Requires AMD and the BLAS. - This is the built-in lu and x=A\b in MATLAB. - author: Tim Davis - algorithm design collaboration: Iain Duff - -Some codes optionally use METIS 5.1.0. This package is located in SuiteSparse -in the `CHOLMOD/SuiteSparse_metis` directory. Its use is optional. To compile -CHOLMOD without it, use the CMAKE_OPTIONS="-DNPARTITION=1" setting. The use of -METIS can improve ordering quality for some matrices, particularly large 3D -discretizations. METIS has been slightly modified for use in SuiteSparse; see -the `CHOLMOD/SuiteSparse_metis/README.txt` file for details. +To compile the libraries and install them only in SuiteSparse/lib (not +/usr/local/lib), do this instead in the top-level of SuiteSparse: +``` + mkdir -p build && cd build + cmake -DCMAKE_INSTALL_PREFIX=.. .. + cmake --build . + cmake --install . +``` -Refer to each package for license, copyright, and author information. All -codes are authored or co-authored by Timothy A. Davis (email: davis@tamu.edu), -except for METIS (by George Karypis), GraphBLAS/cpu_features (by Google), -GraphBLAS/lz4 and zstd (by Yann Collet, now at Facebook), and -GraphBLAS/CUDA/jitify.hpp (by NVIDIA). Parts of GraphBLAS/CUDA are -Copyright (c) by NVIDIA. Please refer to each of these licenses. +If you add /home/me/SuiteSparse/lib to your library search path +(`LD_LIBRARY_PATH` in Linux), you can do the following (for example): +``` + S = /home/me/SuiteSparse + cc myprogram.c -I$(S)/include/suitesparse -lumfpack -lamd -lcholmod -lsuitesparseconfig -lm +``` + +To change the C and C++ compilers, and to compile in parallel use: +``` + cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER==g++ .. +``` + +for example, which changes the compiler to gcc and g++. + +This will work on Linux/Unix and the Mac. It should automatically detect if +you have the Intel compilers or not, and whether or not you have CUDA. + +See `SuiteSparse_config/cmake_modules/SuiteSparsePolicy.cmake` to select your BLAS. -Licenses for each package are located in the following files, all in -PACKAGENAME/Doc/License.txt, and these files are also concatenated into -the top-level LICENSE.txt file. +You may also need to add SuiteSparse/lib to your path. If your copy of +SuiteSparse is in /home/me/SuiteSparse, for example, then add this to your +`~/.bashrc` file: + +``` +LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/me/SuiteSparse/lib +export LD_LIBRARY_PATH +``` + +For the Mac, use this instead: +``` +DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:/home/me/SuiteSparse/lib +export DYLD_LIBRARY_PATH +``` + +Default install location of files is below, where PACKAGE is one of the +packages in SuiteSparse: + + * `CMAKE_INSTALL_PREFIX/include/suitesparse/`: include files + * `CMAKE_INSTALL_PREFIX/lib/`: compiled libraries + * `CMAKE_INSTALL_PREFIX/lib/cmake/SuiteSparse/`: `*.cmake` scripts + for all of SuiteSparse + * `CMAKE_INSTALL_PREFIX/lib/cmake/PACKAGE/`: `*Config.cmake` scripts for a + specific package + * `CMAKE_INSTALL_PREFIX/lib/pkgconfig/PACKAGE.pc`: `.pc` scripts for + a specific package pkgconfig ----------------------------------------------------------------------------- QUICK START FOR MATLAB USERS (Linux or Mac): ----------------------------------------------------------------------------- -Uncompress the SuiteSparse.zip or SuiteSparse.tar.gz archive file (they contain -the same thing). Suppose you place SuiteSparse in the /home/me/SuiteSparse -folder. - -Add the SuiteSparse/lib folder to your run-time library path. On Linux, add -this to your ~/.bashrc script, assuming /home/me/SuiteSparse is the location of -your copy of SuiteSparse: +Suppose you place SuiteSparse in the `/home/me/SuiteSparse` folder. +Add the `SuiteSparse/lib` folder to your run-time library path. On Linux, add +this to your `~/.bashrc` script, assuming `/home/me/SuiteSparse` is the +location of your copy of SuiteSparse: +``` LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/me/SuiteSparse/lib export LD_LIBRARY_PATH +``` -For the Mac, use this instead, in your ~/.zshrc script, assuming you place -SuiteSparse in /Users/me/SuiteSparse: - +For the Mac, use this instead, in your `~/.zshrc` script, assuming you place +SuiteSparse in `/Users/me/SuiteSparse`: +``` DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:/Users/me/SuiteSparse/lib export DYLD_LIBRARY_PATH +``` -Compile all of SuiteSparse with "make local". +Compile all of SuiteSparse with `make local`. Next, compile the GraphBLAS MATLAB library. In the system shell while in the -SuiteSparse folder, type "make gbmatlab" if you want to install it system-wide -with "make install", or "make gblocal" if you want to use the library in +SuiteSparse folder, type `make gbmatlab` if you want to install it system-wide +with `make install`, or `make gblocal` if you want to use the library in your own SuiteSparse/lib. Then in the MATLAB Command Window, cd to the SuiteSparse directory and type @@ -521,162 +860,391 @@ Documents/MATLAB/startup.m. You can also use the `SuiteSparse_paths` m-file to set all your paths at the start of each MATLAB session. ----------------------------------------------------------------------------- -QUICK START FOR THE C/C++ LIBRARIES: +Compilation options ----------------------------------------------------------------------------- -For Linux and Mac: type the following in this directory (requires system -priviledge to do the `sudo make install`): +You can set specific options for CMake with the command (for example): +``` + cmake -DCHOLMOD_PARTITION=OFF -DBUILD_STATIC_LIBS=OFF -DCMAKE_BUILD_TYPE=Debug .. +``` - make - sudo make install +That command will compile all of SuiteSparse except for CHOLMOD/Partition +Module (because of `-DCHOLMOD_PARTITION=OFF`). Debug mode will be used (the +build type). The static libraries will not be built (since +`-DBUILD_STATIC_LIBS=OFF` is set). -All libraries will be created and copied into SuiteSparse/lib and into -/usr/local/lib. All include files need by the applications that use -SuiteSparse are copied into SuiteSparse/include and into /usr/local/include. +* `SUITESPARSE_ENABLE_PROJECTS`: -For Windows, import each `*/CMakeLists.txt` file into MS Visual Studio. + Semicolon separated list of projects to be built or `all`. + Default: `all` in which case the following projects are built: -Be sure to first install all required libraries: BLAS and LAPACK for UMFPACK, -CHOLMOD, and SPQR, and GMP and MPFR for SPEX. Be sure to use the latest -libraries; SPEX requires MPFR 4.0.2 and GMP 6.1.2 (these version numbers -do NOT correspond to the X.Y.Z suffix of libgmp.so.X.Y.Z and libmpfr.so.X.Y.Z; -see the SPEX user guide for details). + `suitesparse_config;mongoose;amd;btf;camd;ccolamd;colamd;cholmod;cxsparse;ldl;klu;umfpack;paru;rbio;spqr;spex;graphblas;lagraph` -To compile the libraries and install them only in SuiteSparse/lib (not -/usr/local/lib), do this instead in the top-level of SuiteSparse: + Additionally, `csparse` can be included in that list to build CSparse. - make local +* `CMAKE_BUILD_TYPE`: -If you add /home/me/SuiteSparse/lib to your library search path -(`LD_LIBRARY_PATH` in Linux), you can do the following (for example): + Default: `Release`, use `Debug` for debugging. - S = /home/me/SuiteSparse - cc myprogram.c -I$(S)/include -lumfpack -lamd -lcholmod -lsuitesparseconfig -lm +* `SUITESPARSE_USE_STRICT`: -To change the C and C++ compilers, and to compile in parallel use: + 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`. - CC=gcc CX=g++ JOBS=32 make +* `SUITESPARSE_USE_CUDA`: -for example, which changes the compiler to gcc and g++, and runs make with -'make -j32', in parallel with 32 jobs. + If set to `ON`, CUDA is enabled for all of SuiteSparse. Default: `ON`, -This will work on Linux/Unix and the Mac. It should automatically detect if -you have the Intel compilers or not, and whether or not you have CUDA. + CUDA on Windows with MSVC appears to be working with this release, but it + should be considered as a prototype and may not be fully functional. I have + limited resources for testing CUDA on Windows. If you encounter issues, + disable CUDA and post this as an issue on GitHub. -NOTE: Use of the Intel MKL BLAS is strongly recommended. The OpenBLAS can -(rarely) result in severe performance degradation, in CHOLMOD in particular. -The reason for this is still under investigation and might already be resolved -in the current version of OpenBLAS. See -`SuiteSparse_config/cmake_modules/SuiteSparsePolicy.cmake` to select your BLAS. +* `CHOLMOD_USE_CUDA`: -You may also need to add SuiteSparse/lib to your path. If your copy of -SuiteSparse is in /home/me/SuiteSparse, for example, then add this to your -~/.bashrc file: + Default: `ON`. Both `SUITESPARSE_USE_CUDA` and `CHOLMOD_USE_CUDA` must be + enabled to use CUDA in CHOLMOD. - LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/me/SuiteSparse/lib - export LD_LIBRARY_PATH +* `SPQR_USE_CUDA`: -For the Mac, use this instead: + Default: `ON`. Both `SUITESPARSE_USE_CUDA` and `SPQR_USE_CUDA` must be + enabled to use CUDA in SPQR. - DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:/home/me/SuiteSparse/lib - export DYLD_LIBRARY_PATH +* `CMAKE_INSTALL_PREFIX`: ------------------------------------------------------------------------------ -Python interface ------------------------------------------------------------------------------ + Defines the install location (default on Linux is `/usr/local`). For example, + this command while in a folder `build` in the top level SuiteSparse folder + will set the install directory to `/stuff`, used by the subsequent + `sudo cmake --install .`: +``` + cmake -DCMAKE_INSTALL_PREFIX=/stuff .. + sudo cmake --install . +``` -See scikit-sparse and scikit-umfpack for the Python interface via SciPy: +* `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. + + This option allows to install them at a location different from the (static) + libraries. This allows to install multiple configurations of the SuiteSparse + libraries at the same time (e.g., by also setting a different + `CMAKE_RELEASE_POSTFIX` and `CMAKE_INSTALL_LIBDIR` for each of them). To pick + up the respective configuration in downstream projects, set, e.g., + `CMAKE_PREFIX_PATH` (for CMake) or `PKG_CONFIG_PATH` (for build systems using + pkg-config) to the path containing the respective CMake Config files or + pkg-config files. + +* `SUITESPARSE_INCLUDEDIR_POSTFIX`: + + Postfix for installation target of header from SuiteSparse. Default: + suitesparse, so the default include directory is: + `CMAKE_INSTALL_PREFIX/include/suitesparse` + +* `BUILD_SHARED_LIBS`: -https://github.com/scikit-sparse/scikit-sparse + If `ON`, shared libraries are built. + Default: `ON`. -https://github.com/scikit-umfpack/scikit-umfpack +* `BUILD_STATIC_LIBS`: + + If `ON`, static libraries are built. + Default: `ON`, except for GraphBLAS, which takes a long time to compile so + the default for GraphBLAS is `OFF` unless `BUILD_SHARED_LIBS` is `OFF`. + +* `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`: + + A string. Leave unset, or use `"ANY"` to select any BLAS library (the + default). Or set to the name of a `BLA_VENDOR` defined by FindBLAS.cmake. + See: + https://cmake.org/cmake/help/latest/module/FindBLAS.html#blas-lapack-vendors + +* `SUITESPARSE_USE_64BIT_BLAS`: + + If `ON`, look for a 64-bit BLAS. If `OFF`: 32-bit only. Default: `OFF`. + +* `SUITESPARSE_USE_OPENMP`: + + If `ON`, OpenMP is used by default if it is available. Default: `ON`. + + GraphBLAS, LAGraph, and ParU will be vastly slower if OpenMP is not used. + CHOLMOD will be somewhat slower without OpenMP (as long as it still has a + parallel BLAS/LAPACK). Three packages (UMFPACK, CHOLMOD, and SPQR) rely + heavily on parallel BLAS/LAPACK libraries and those libraries may use OpenMP + internally. If you wish to disable OpenMP in an entire application, select a + single-threaded BLAS/LAPACK, or a parallel BLAS/LAPACK that does not use + OpenMP (such as the Apple Accelerate Framework). Using a single-threaded + BLAS/LAPACK library will cause UMFPACK, CHOLMOD, and SPQR to be vastly + slower. + + WARNING: GraphBLAS may not be thread-safe if built without OpenMP or pthreads + (see the GraphBLAS User Guide for details). + +* `SUITESPARSE_CONFIG_USE_OPENMP`: + + If `ON`, `SuiteSparse_config` uses OpenMP if it is available. + Default: `SUITESPARSE_USE_OPENMP`. + It is not essential and only used to let `SuiteSparse_time` call + `omp_get_wtime`. + +* `CHOLMOD_USE_OPENMP`: + + If `ON`, OpenMP is used in CHOLMOD if it is available. + Default: `SUITESPARSE_USE_OPENMP`. + +* `GRAPHBLAS_USE_OPENMP`: + + If `ON`, OpenMP is used in GraphBLAS if it is available. + Default: `SUITESPARSE_USE_OPENMP`. + +* `LAGRAPH_USE_OPENMP`: + + If `ON`, OpenMP is used in LAGraph if it is available. + Default: `SUITESPARSE_USE_OPENMP`. + +* `PARU_USE_OPENMP`: + + If `ON`, OpenMP is used in ParU if it is available. + Default: `SUITESPARSE_USE_OPENMP`. + +* `SPEX_USE_OPENMP`: + + If `ON`, OpenMP is used in SPEX if it is available. + Default: `SUITESPARSE_USE_OPENMP`. + +* `SUITESPARSE_DEMOS`: + + If `ON`, build the demo programs for each package. Default: `OFF`. + +* `SUITESPARSE_USE_SYSTEM_BTF`: + + If `ON`, use BTF libraries installed on the build system. If `OFF`, + automatically build BTF as dependency if needed. Default: `OFF`. + +* `SUITESPARSE_USE_SYSTEM_CHOLMOD`: + + If `ON`, use CHOLMOD libraries installed on the build system. If `OFF`, + automatically build CHOLMOD as dependency if needed. Default: `OFF`. + +* `SUITESPARSE_USE_SYSTEM_AMD`: + + If `ON`, use AMD libraries installed on the build system. If `OFF`, + automatically build AMD as dependency if needed. Default: `OFF`. + +* `SUITESPARSE_USE_SYSTEM_COLAMD`: + + If `ON`, use COLAMD libraries installed on the build system. If `OFF`, + automatically build COLAMD as dependency if needed. Default: `OFF`. + +* `SUITESPARSE_USE_SYSTEM_CAMD`: + + If `ON`, use CAMD libraries installed on the build system. If `OFF`, + automatically build CAMD as dependency if needed. Default: `OFF`. + +* `SUITESPARSE_USE_SYSTEM_CCOLAMD`: + + If `ON`, use CCOLAMD libraries installed on the build system. If `OFF`, + automatically build CCOLAMD as dependency if needed. Default: `OFF`. + +* `SUITESPARSE_USE_SYSTEM_GRAPHBLAS`: + + If `ON`, use GraphBLAS libraries installed on the build system. If `OFF`, + automatically build GraphBLAS as dependency if needed. Default: `OFF`. + +* `SUITESPARSE_USE_SYSTEM_SUITESPARSE_CONFIG`: + + If `ON`, use `SuiteSparse_config` libraries installed on the build system. If + `OFF`, automatically build `SuiteSparse_config` as dependency if needed. + Default: `OFF`. + +* `SUITESPARSE_USE_FORTRAN` + + If `ON`, use the Fortran compiler to determine how C calls Fortan, and to + build several optional Fortran routines. If `OFF`, use + `SUITESPARSE_C_TO_FORTRAN` to define how C calls Fortran. + Default: `ON`. + +* `SUITESPARSE_C_TO_FORTRAN` + + A string that defines how C calls Fortran (i.e., functions exported by the + BLAS library). This setting is used if no working Fortran compiler could be + detected or `SUITESPARSE_USE_FORTRAN` is set to `OFF`. This string is to be + read as the argument list and the body of a preprocessor macro. The first + argument to that macro is any Fortran function name in lowercase letters. + The second argument is the same function name in uppercase letters. The body + defines by which function name Fortran functions are called. This is + necessary because Fortran is case-insensitive, and different Fortran + compilers use different name mangling conventions. If a MSVC C/C++ compiler + is used, this defaults to `"(name,NAME) name"` (i.e., lower case without + trailing underscore). That is the name mangling convention for the Intel + Fortran compiler on Windows. If any other C/C++ compilers are used, this + defaults to `"(name,NAME) name##_"` (i.e., lower case with trailing + underscore). That is the name mangling convention for most of the commonly + used Fortran compilers (like `ifx` on platforms other than Windows, + `gfortran`, `flang`, ...). The latter name mangling convention is also used + by default by OpenBLAS (independent on the platform or the compiler used to + build OpenBLAS). You might need to configure with + `-DSUITESPARSE_C_TO_FORTRAN="(name,NAME) name##_"` if you'd like to build + SuiteSparse using a MSVC compiler and link to OpenBLAS. + +Additional options are available for specific packages: + +* `UMFPACK_USE_CHOLMOD`: + + If `ON`, UMFPACK uses CHOLMOD for additional (optional) + ordering options. Default: `ON`. + +* `KLU_USE_CHOLMOD`: + + If `ON`, KLU uses CHOLMOD for additional (optional) + ordering options. Default: `ON`. + +CHOLMOD is composed of a set of Modules that can be independently selected; +all options default to `ON`: + +* `CHOLMOD_GPL` + + If `OFF`, do not build any GPL-licensed module (MatrixOps, Modify, Supernodal, + and GPU modules) + +* `CHOLMOD_CHECK` + + If `OFF`, do not build the Check module. + +* `CHOLMOD_MATRIXOPS` + + If `OFF`, do not build the MatrixOps module. + +* `CHOLMOD_CHOLESKY` + If `OFF`, do not build the Cholesky module. This also disables the Supernodal + and Modify modules. + +* `CHOLMOD_MODIFY` + + If `OFF`, do not build the Modify module. + +* `CHOLMOD_CAMD` + + If `OFF`, do not link against CAMD and CCOLAMD. This also disables the + Partition module. + +* `CHOLMOD_PARTITION` + + If `OFF`, do not build the Partition module. + +* `CHOLMOD_SUPERNODAL` + + If `OFF`, do not build the Supernodal module. ----------------------------------------------------------------------------- -Compilation options +Possible build/install issues ----------------------------------------------------------------------------- -You can set specific options for CMake with the command (for example): +One common issue can affect all packages: getting the right #include files +that match the current libraries being built. It's possible that your Linux +distro has an older copy of SuiteSparse headers in /usr/include or +/usr/local/include, or that Homebrew has installed its suite-sparse bundle into +/opt/homebrew/include or other places. Old libraries can appear in in +/usr/local/lib, /usr/lib, etc. When building a new copy of SuiteSparse, the +cmake build system is normally (or always?) able to avoid these, and use the +right header for the right version of each library. + +As an additional guard against this possible error, each time one SuiteSparse +package #include's a header from another one, it checks the version number in +the header file, and reports an #error to the compiler if a stale version is +detected. In addition, the Example package checks both the header version and +the library version (by calling a function in each library). If the versions +mismatch in any way, the Example package reports an error at run time. + +For example, CHOLMOD 5.1.0 requires AMD 3.3.0 or later. If it detects an +older one in `amd.h`, it will report an `#error`: + +``` + #include "amd.h" + #if ( ... AMD version is stale ... ) + #error "CHOLMOD 5.1.0 requires AMD 3.3.0 or later" + #endif +``` + +and the compilation will fail. The Example package makes another check, +by calling `amd_version` and comparing it with the versions from the `amd.h` +header file. + +If this error or one like it occurs, check to see if you have an old copy of +SuiteSparse, and uninstall it before compiling your new copy of SuiteSparse. + +There are other many possible build/install issues that are covered by the +corresponding user guides for each package, such as finding the right BLAS, +OpenMP, and other libraries, and how to compile on the Mac when using GraphBLAS +inside MATLAB, and so on. Refer to the User Guides for more details. - CMAKE_OPTIONS="-DNPARTITION=1 -DNSTATIC=1 -DCMAKE_BUILD_TYPE=Debug" make +----------------------------------------------------------------------------- +Interfaces to SuiteSparse +----------------------------------------------------------------------------- -That command will compile all of SuiteSparse except for CHOLMOD/Partition -Module. Debug mode will be used. The static libraries will not be built -(NSTATIC is true). - - CMAKE_BUILD_TYPE: Default: "Release", use "Debug" for debugging. - - ENABLE_CUDA: if set to true, CUDA is enabled for the project. - Default: true for CHOLMOD and SPQR; false otherwise - - 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). - Default: false - - NSTATIC: if true, static libraries are not built. - Default: false, except for GraphBLAS, which - takes a long time to compile so the default for - GraphBLAS is true. For Mongoose, the NSTATIC setting - is treated as if it always false, since the mongoose - program is built with the static library. - - 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 a string. Leave unset, or use "ANY" to select any BLAS - library (the default). Or set to the name of a - BLA_VENDOR defined by FindBLAS.cmake. See: - https://cmake.org/cmake/help/latest/module/FindBLAS.html#blas-lapack-vendors - - ALLOW_64BIT_BLAS if true: look for a 64-bit BLAS. If false: 32-bit only. - Default: false. - - NOPENMP if true: OpenMP is not used. Default: false. - UMFPACK, CHOLMOD, SPQR, and GraphBLAS will be slow. - Note that BLAS and LAPACK may still use OpenMP - internally; if you wish to disable OpenMP in an entire - application, select a single-threaded BLAS/LAPACK. - WARNING: GraphBLAS may not be thread-safe if built - without OpenMP (see the User Guide for details). - - DEMO if true: build the demo programs for each package. - Default: false. - -Additional options are available within specific packages: - - NCHOLMOD if true, UMFPACK and KLU do not use CHOLMOD for - additional (optional) ordering options +MATLAB/Octave/R/Mathematica interfaces: -CHOLMOD is composed of a set of Modules that can be independently selected; -all options default to false: - - NGL if true: do not build any GPL-licensed module - (MatrixOps, Modify, Supernodal, and GPU modules) - NCHECK if true: do not build the Check module. - NMATRIXOPS if true: do not build the MatrixOps module. - NCHOLESKY if true: do not build the Cholesky module. - This also disables the Supernodal and Modify modules. - NMODIFY if true: do not build the Modify module. - NCAMD if true: do not link against CAMD and CCOLAMD. - This also disables the Partition module. - NPARTITION if true: do not build the Partition module. - NSUPERNODAL if true: do not build the Supernodal module. + Many built-in methods in MATLAB and Octave rely on SuiteSparse, including + `C=A*B` `x=A\b`, `L=chol(A)`, `[L,U,P,Q]=lu(A)`, `R=qr(A)`, `dmperm(A)`, + `p=amd(A)`, `p=colamd(A)`, ... + See also Mathematica, R, and many many more. The list is too long. + +Julia interface: + + https://github.com/JuliaSparse/SparseArrays.jl + +python interface to GraphBLAS by Anaconda and NVIDIA: + + https://pypi.org/project/python-graphblas + +Intel's Go interface to GraphBLAS: + + https://pkg.go.dev/github.com/intel/forGraphBLASGo + +See scikit-sparse and scikit-umfpack for the Python interface via SciPy: + + https://github.com/scikit-sparse/scikit-sparse + https://github.com/scikit-umfpack/scikit-umfpack + +See math.js by Jos de Jong for a JavaScript port of CSparse: + + https://github.com/josdejong/mathjs + +See russell for a Rust interface: + + https://github.com/cpmech/russell ----------------------------------------------------------------------------- Acknowledgements ----------------------------------------------------------------------------- -I would like to thank François Bissey, Sebastien Villemot, Erik Welch, Jim -Kitchen, Markus Mützel, and Fabian Wein for their valuable feedback on the +Markus Mützel contributed the most recent update of the SuiteSparse build +system for all SuiteSparse packages, extensively porting it and modernizing it. + +I would also like to thank François Bissey, Sebastien Villemot, Erik Welch, Jim +Kitchen, and Fabian Wein for their valuable feedback on the SuiteSparse build system and how it works with various Linux / Python distros and other package managers. If you are a maintainer of a SuiteSparse packaging for a Linux distro, conda-forge, R, spack, brew, vcpkg, etc, please feel free to contact me if there's anything I can do to make your life easier. +I would also like to thank Raye Kimmerer for adding support for 32-bit +row/column indices in SPQR v4.2.0. See also the various Acknowledgements within each package. diff --git a/SuiteSparse_config/Config/SuiteSparse_config.h.in b/SuiteSparse_config/Config/SuiteSparse_config.h.in index 09d05c92..0d203f55 100644 --- a/SuiteSparse_config/Config/SuiteSparse_config.h.in +++ b/SuiteSparse_config/Config/SuiteSparse_config.h.in @@ -368,13 +368,24 @@ int SuiteSparse_divcomplex // determine which timer to use, if any #ifndef NTIMER + // SuiteSparse_config itself can be compiled without OpenMP, + // but other packages can themselves use OpenMP. In this case, + // those packages should use omp_get_wtime() directly. This can + // be done via the SUITESPARSE_TIME macro, defined below: + #cmakedefine SUITESPARSE_HAVE_CLOCK_GETTIME #if defined ( _OPENMP ) #define SUITESPARSE_TIMER_ENABLED - #elif defined ( _POSIX_C_SOURCE ) - #if _POSIX_C_SOURCE >= 199309L + #define SUITESPARSE_TIME (omp_get_wtime ( )) + #elif defined ( SUITESPARSE_HAVE_CLOCK_GETTIME ) #define SUITESPARSE_TIMER_ENABLED - #endif + #define SUITESPARSE_TIME (SuiteSparse_time ( )) + #else + // No timer is available + #define SUITESPARSE_TIME (0) #endif +#else + // The timer is explictly disabled + #define SUITESPARSE_TIME (0) #endif // SuiteSparse printf macro @@ -414,9 +425,14 @@ int SuiteSparse_version // returns SUITESPARSE_VERSION #define SUITESPARSE_SUB_VERSION @SUITESPARSE_VERSION_MINOR@ #define SUITESPARSE_SUBSUB_VERSION @SUITESPARSE_VERSION_SUB@ +// version format x.y #define SUITESPARSE_VER_CODE(main,sub) ((main) * 1000 + (sub)) -#define SUITESPARSE_VERSION \ - SUITESPARSE_VER_CODE(SUITESPARSE_MAIN_VERSION,SUITESPARSE_SUB_VERSION) +#define SUITESPARSE_VERSION SUITESPARSE_VER_CODE(@SUITESPARSE_VERSION_MAJOR@, @SUITESPARSE_VERSION_MINOR@) + +// version format x.y.z +#define SUITESPARSE__VERCODE(main,sub,patch) \ + (((main)*1000ULL + (sub))*1000ULL + (patch)) +#define SUITESPARSE__VERSION SUITESPARSE__VERCODE(@SUITESPARSE_VERSION_MAJOR@,@SUITESPARSE_VERSION_MINOR@,@SUITESPARSE_VERSION_SUB@) //============================================================================== // SuiteSparse interface to the BLAS and LAPACK libraries @@ -469,7 +485,7 @@ int SuiteSparse_version // returns SUITESPARSE_VERSION #elif defined ( BLAS_UNDERSCORE ) - // append an undescore, use lower case + // append an underscore, use lower case #define SUITESPARSE_FORTRAN(name,NAME) name ## _ #define SUITESPARSE__FORTRAN(name,NAME) name ## _ @@ -529,12 +545,12 @@ int SuiteSparse_version // returns SUITESPARSE_VERSION // If the suffix does not contain "_", use (Sun Perf., for example): -// cd build ; cmake -DBLAS64_SUFFIX="64" .. +// cd build && cmake -DBLAS64_SUFFIX="64" .. // If the suffix contains "_" (OpenBLAS in spack for example), use the // following: -// cd build ; cmake -DBLAS64_SUFFIX="_64" .. +// cd build && cmake -DBLAS64_SUFFIX="_64" .. // This setting could be used by the spack packaging of SuiteSparse when linked // with the spack-installed OpenBLAS with 64-bit integers. See @@ -572,6 +588,7 @@ int SuiteSparse_version // returns SUITESPARSE_VERSION // C names of Fortan BLAS and LAPACK functions used by SuiteSparse //------------------------------------------------------------------------------ +// double #define SUITESPARSE_BLAS_DTRSV SUITESPARSE_BLAS ( dtrsv , DTRSV ) #define SUITESPARSE_BLAS_DGEMV SUITESPARSE_BLAS ( dgemv , DGEMV ) #define SUITESPARSE_BLAS_DTRSM SUITESPARSE_BLAS ( dtrsm , DTRSM ) @@ -579,8 +596,15 @@ int SuiteSparse_version // returns SUITESPARSE_VERSION #define SUITESPARSE_BLAS_DSYRK SUITESPARSE_BLAS ( dsyrk , DSYRK ) #define SUITESPARSE_BLAS_DGER SUITESPARSE_BLAS ( dger , DGER ) #define SUITESPARSE_BLAS_DSCAL SUITESPARSE_BLAS ( dscal , DSCAL ) +#define SUITESPARSE_BLAS_DNRM2 SUITESPARSE_BLAS ( dnrm2 , DNRM2 ) + #define SUITESPARSE_LAPACK_DPOTRF SUITESPARSE_BLAS ( dpotrf , DPOTRF ) +#define SUITESPARSE_LAPACK_DLARF SUITESPARSE_BLAS ( dlarf , DLARF ) +#define SUITESPARSE_LAPACK_DLARFG SUITESPARSE_BLAS ( dlarfg , DLARFG ) +#define SUITESPARSE_LAPACK_DLARFT SUITESPARSE_BLAS ( dlarft , DLARFT ) +#define SUITESPARSE_LAPACK_DLARFB SUITESPARSE_BLAS ( dlarfb , DLARFB ) +// double complex #define SUITESPARSE_BLAS_ZTRSV SUITESPARSE_BLAS ( ztrsv , ZTRSV ) #define SUITESPARSE_BLAS_ZGEMV SUITESPARSE_BLAS ( zgemv , ZGEMV ) #define SUITESPARSE_BLAS_ZTRSM SUITESPARSE_BLAS ( ztrsm , ZTRSM ) @@ -588,20 +612,46 @@ int SuiteSparse_version // returns SUITESPARSE_VERSION #define SUITESPARSE_BLAS_ZHERK SUITESPARSE_BLAS ( zherk , ZHERK ) #define SUITESPARSE_BLAS_ZGERU SUITESPARSE_BLAS ( zgeru , ZGERU ) #define SUITESPARSE_BLAS_ZSCAL SUITESPARSE_BLAS ( zscal , ZSCAL ) -#define SUITESPARSE_LAPACK_ZPOTRF SUITESPARSE_BLAS ( zpotrf , ZPOTRF ) - -#define SUITESPARSE_BLAS_DNRM2 SUITESPARSE_BLAS ( dnrm2 , DNRM2 ) -#define SUITESPARSE_LAPACK_DLARF SUITESPARSE_BLAS ( dlarf , DLARF ) -#define SUITESPARSE_LAPACK_DLARFG SUITESPARSE_BLAS ( dlarfg , DLARFG ) -#define SUITESPARSE_LAPACK_DLARFT SUITESPARSE_BLAS ( dlarft , DLARFT ) -#define SUITESPARSE_LAPACK_DLARFB SUITESPARSE_BLAS ( dlarfb , DLARFB ) - #define SUITESPARSE_BLAS_DZNRM2 SUITESPARSE_BLAS ( dznrm2 , DZNRM2 ) + +#define SUITESPARSE_LAPACK_ZPOTRF SUITESPARSE_BLAS ( zpotrf , ZPOTRF ) #define SUITESPARSE_LAPACK_ZLARF SUITESPARSE_BLAS ( zlarf , ZLARF ) #define SUITESPARSE_LAPACK_ZLARFG SUITESPARSE_BLAS ( zlarfg , ZLARFG ) #define SUITESPARSE_LAPACK_ZLARFT SUITESPARSE_BLAS ( zlarft , ZLARFT ) #define SUITESPARSE_LAPACK_ZLARFB SUITESPARSE_BLAS ( zlarfb , ZLARFB ) +// single +#define SUITESPARSE_BLAS_STRSV SUITESPARSE_BLAS ( strsv , STRSV ) +#define SUITESPARSE_BLAS_SGEMV SUITESPARSE_BLAS ( sgemv , SGEMV ) +#define SUITESPARSE_BLAS_STRSM SUITESPARSE_BLAS ( strsm , STRSM ) +#define SUITESPARSE_BLAS_SGEMM SUITESPARSE_BLAS ( sgemm , SGEMM ) +#define SUITESPARSE_BLAS_SSYRK SUITESPARSE_BLAS ( ssyrk , SSYRK ) +#define SUITESPARSE_BLAS_SGER SUITESPARSE_BLAS ( sger , SGER ) +#define SUITESPARSE_BLAS_SSCAL SUITESPARSE_BLAS ( sscal , SSCAL ) +#define SUITESPARSE_BLAS_SNRM2 SUITESPARSE_BLAS ( snrm2 , SNRM2 ) + +#define SUITESPARSE_LAPACK_SPOTRF SUITESPARSE_BLAS ( spotrf , SPOTRF ) +#define SUITESPARSE_LAPACK_SLARF SUITESPARSE_BLAS ( slarf , SLARF ) +#define SUITESPARSE_LAPACK_SLARFG SUITESPARSE_BLAS ( slarfg , SLARFG ) +#define SUITESPARSE_LAPACK_SLARFT SUITESPARSE_BLAS ( slarft , SLARFT ) +#define SUITESPARSE_LAPACK_SLARFB SUITESPARSE_BLAS ( slarfb , SLARFB ) + +// single complex +#define SUITESPARSE_BLAS_CTRSV SUITESPARSE_BLAS ( ctrsv , CTRSV ) +#define SUITESPARSE_BLAS_CGEMV SUITESPARSE_BLAS ( cgemv , CGEMV ) +#define SUITESPARSE_BLAS_CTRSM SUITESPARSE_BLAS ( ctrsm , CTRSM ) +#define SUITESPARSE_BLAS_CGEMM SUITESPARSE_BLAS ( cgemm , CGEMM ) +#define SUITESPARSE_BLAS_CHERK SUITESPARSE_BLAS ( cherk , CHERK ) +#define SUITESPARSE_BLAS_CGERU SUITESPARSE_BLAS ( cgeru , CGERU ) +#define SUITESPARSE_BLAS_CSCAL SUITESPARSE_BLAS ( cscal , CSCAL ) +#define SUITESPARSE_BLAS_SCNRM2 SUITESPARSE_BLAS ( scnrm2 , SCNRM2 ) + +#define SUITESPARSE_LAPACK_CPOTRF SUITESPARSE_BLAS ( cpotrf , CPOTRF ) +#define SUITESPARSE_LAPACK_CLARF SUITESPARSE_BLAS ( clarf , CLARF ) +#define SUITESPARSE_LAPACK_CLARFG SUITESPARSE_BLAS ( clarfg , CLARFG ) +#define SUITESPARSE_LAPACK_CLARFT SUITESPARSE_BLAS ( clarft , CLARFT ) +#define SUITESPARSE_LAPACK_CLARFB SUITESPARSE_BLAS ( clarfb , CLARFB ) + //------------------------------------------------------------------------------ // prototypes of BLAS and SUITESPARSE_LAPACK functions //------------------------------------------------------------------------------ @@ -627,7 +677,11 @@ int SuiteSparse_version // returns SUITESPARSE_VERSION #if defined ( SUITESPARSE_BLAS_DEFINITIONS ) -void SUITESPARSE_BLAS_DGEMV // Y = alpha*A*x + beta*Y +//------------------------------------------------------------------------------ +// gemv: Y = alpha*A*x + beta*Y +//------------------------------------------------------------------------------ + +void SUITESPARSE_BLAS_DGEMV ( // input: const char *trans, @@ -659,7 +713,39 @@ void SUITESPARSE_BLAS_DGEMV // Y = alpha*A*x + beta*Y } \ } -void SUITESPARSE_BLAS_ZGEMV // Y = alpha*A*X + beta*Y +void SUITESPARSE_BLAS_SGEMV +( + // input: + const char *trans, + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const float *alpha, + const float *A, + const SUITESPARSE_BLAS_INT *lda, + const float *X, + const SUITESPARSE_BLAS_INT *incx, + const float *beta, + // input/output: + float *Y, + // input: + const SUITESPARSE_BLAS_INT *incy +) ; + +#define SUITESPARSE_BLAS_sgemv(trans,m,n,alpha,A,lda,X,incx,beta,Y,incy,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCY_blas_int, incy, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_SGEMV (trans, &M_blas_int, &N_blas_int, alpha, A, \ + &LDA_blas_int, X, &INCX_blas_int, beta, Y, &INCY_blas_int) ; \ + } \ +} + +void SUITESPARSE_BLAS_ZGEMV ( // input: const char *trans, @@ -691,7 +777,43 @@ void SUITESPARSE_BLAS_ZGEMV // Y = alpha*A*X + beta*Y } \ } -void SUITESPARSE_BLAS_DTRSV // solve Lx=b, Ux=b, L'x=b, or U'x=b +void SUITESPARSE_BLAS_CGEMV +( + // input: + const char *trans, + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const void *alpha, + const void *A, + const SUITESPARSE_BLAS_INT *lda, + const void *X, + const SUITESPARSE_BLAS_INT *incx, + const void *beta, + // input/output: + void *Y, + // input: + const SUITESPARSE_BLAS_INT *incy +) ; + +#define SUITESPARSE_BLAS_cgemv(trans,m,n,alpha,A,lda,X,incx,beta,Y,incy,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCY_blas_int, incy, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_CGEMV (trans, &M_blas_int, &N_blas_int, alpha, A, \ + &LDA_blas_int, X, &INCX_blas_int, beta, Y, &INCY_blas_int) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// trsv: solve Lx=b, Ux=b, L'x=b, or U'x=b +//------------------------------------------------------------------------------ + +void SUITESPARSE_BLAS_DTRSV ( // input: const char *uplo, @@ -718,7 +840,34 @@ void SUITESPARSE_BLAS_DTRSV // solve Lx=b, Ux=b, L'x=b, or U'x=b } \ } -void SUITESPARSE_BLAS_ZTRSV // solve (L, L', L^H, U, U', or U^H)x=b +void SUITESPARSE_BLAS_STRSV +( + // input: + const char *uplo, + const char *trans, + const char *diag, + const SUITESPARSE_BLAS_INT *n, + const float *A, + const SUITESPARSE_BLAS_INT *lda, + // input/output: + float *X, + // input: + const SUITESPARSE_BLAS_INT *incx +) ; + +#define SUITESPARSE_BLAS_strsv(uplo,trans,diag,n,A,lda,X,incx,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_STRSV (uplo, trans, diag, &N_blas_int, A, \ + &LDA_blas_int, X, &INCX_blas_int) ; \ + } \ +} + +void SUITESPARSE_BLAS_ZTRSV ( // input: const char *uplo, @@ -745,7 +894,38 @@ void SUITESPARSE_BLAS_ZTRSV // solve (L, L', L^H, U, U', or U^H)x=b } \ } -void SUITESPARSE_BLAS_DTRSM // solve LX=B, UX=B, L'X=B, or U'X=B +void SUITESPARSE_BLAS_CTRSV +( + // input: + const char *uplo, + const char *trans, + const char *diag, + const SUITESPARSE_BLAS_INT *n, + const void *A, + const SUITESPARSE_BLAS_INT *lda, + // input/output: + void *X, + // input: + const SUITESPARSE_BLAS_INT *incx +) ; + +#define SUITESPARSE_BLAS_ctrsv(uplo,trans,diag,n,A,lda,X,incx,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_CTRSV (uplo, trans, diag, &N_blas_int, A, \ + &LDA_blas_int, X, &INCX_blas_int) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// trsm: solve LX=B, UX=B, L'X=B, or U'X=B +//------------------------------------------------------------------------------ + +void SUITESPARSE_BLAS_DTRSM ( // input: const char *side, @@ -776,7 +956,38 @@ void SUITESPARSE_BLAS_DTRSM // solve LX=B, UX=B, L'X=B, or U'X=B } \ } -void SUITESPARSE_BLAS_ZTRSM // solve (L, L', L^H, U, U', or U^H)X=B +void SUITESPARSE_BLAS_STRSM +( + // input: + const char *side, + const char *uplo, + const char *transa, + const char *diag, + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const float *alpha, + const float *A, + const SUITESPARSE_BLAS_INT *lda, + // input/output: + float *B, + // input: + const SUITESPARSE_BLAS_INT *ldb +) ; + +#define SUITESPARSE_BLAS_strsm(side,uplo,transa,diag,m,n,alpha,A,lda,B,ldb,ok)\ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDB_blas_int, ldb, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_STRSM (side, uplo, transa, diag, &M_blas_int, \ + &N_blas_int, alpha, A, &LDA_blas_int, B, &LDB_blas_int) ; \ + } \ +} + +void SUITESPARSE_BLAS_ZTRSM ( // input: const char *side, @@ -807,7 +1018,42 @@ void SUITESPARSE_BLAS_ZTRSM // solve (L, L', L^H, U, U', or U^H)X=B } \ } -void SUITESPARSE_BLAS_DGEMM // C = alpha*A*B + beta*C +void SUITESPARSE_BLAS_CTRSM +( + // input: + const char *side, + const char *uplo, + const char *transa, + const char *diag, + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const void *alpha, + const void *A, + const SUITESPARSE_BLAS_INT *lda, + // input/output: + void *B, + // input: + const SUITESPARSE_BLAS_INT *ldb +) ; + +#define SUITESPARSE_BLAS_ctrsm(side,uplo,transa,diag,m,n,alpha,A,lda,B,ldb,ok)\ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDB_blas_int, ldb, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_CTRSM (side, uplo, transa, diag, &M_blas_int, \ + &N_blas_int, alpha, A, &LDA_blas_int, B, &LDB_blas_int) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// gemm: C = alpha*A*B + beta*C +//------------------------------------------------------------------------------ + +void SUITESPARSE_BLAS_DGEMM ( // input: const char *transa, @@ -844,7 +1090,7 @@ void SUITESPARSE_BLAS_DGEMM // C = alpha*A*B + beta*C } \ } -void SUITESPARSE_BLAS_ZGEMM // C = alpha*A*B + beta*C +void SUITESPARSE_BLAS_SGEMM ( // input: const char *transa, @@ -852,19 +1098,19 @@ void SUITESPARSE_BLAS_ZGEMM // C = alpha*A*B + beta*C const SUITESPARSE_BLAS_INT *m, const SUITESPARSE_BLAS_INT *n, const SUITESPARSE_BLAS_INT *k, - const void *alpha, - const void *A, + const float *alpha, + const float *A, const SUITESPARSE_BLAS_INT *lda, - const void *B, + const float *B, const SUITESPARSE_BLAS_INT *ldb, - const void *beta, + const float *beta, // input/output: - void *C, + float *C, // input: const SUITESPARSE_BLAS_INT *ldc ) ; -#define SUITESPARSE_BLAS_zgemm(transa,transb,m,n,k,alpha,A,lda,B,ldb,beta, \ +#define SUITESPARSE_BLAS_sgemm(transa,transb,m,n,k,alpha,A,lda,B,ldb,beta, \ C,ldc,ok) \ { \ SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ @@ -875,52 +1121,62 @@ void SUITESPARSE_BLAS_ZGEMM // C = alpha*A*B + beta*C SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ if (ok) \ { \ - SUITESPARSE_BLAS_ZGEMM (transa, transb, &M_blas_int, &N_blas_int, \ + SUITESPARSE_BLAS_SGEMM (transa, transb, &M_blas_int, &N_blas_int, \ &K_blas_int, alpha, A, &LDA_blas_int, B, &LDB_blas_int, beta, C, \ &LDC_blas_int) ; \ } \ } -void SUITESPARSE_BLAS_DSYRK // C = alpha*A*A' + beta*C, or A'A +void SUITESPARSE_BLAS_ZGEMM ( // input: - const char *uplo, - const char *trans, + const char *transa, + const char *transb, + const SUITESPARSE_BLAS_INT *m, const SUITESPARSE_BLAS_INT *n, const SUITESPARSE_BLAS_INT *k, - const double *alpha, - const double *A, + const void *alpha, + const void *A, const SUITESPARSE_BLAS_INT *lda, - const double *beta, + const void *B, + const SUITESPARSE_BLAS_INT *ldb, + const void *beta, // input/output: - double *C, + void *C, // input: const SUITESPARSE_BLAS_INT *ldc ) ; -#define SUITESPARSE_BLAS_dsyrk(uplo,trans,n,k,alpha,A,lda,beta,C,ldc,ok) \ +#define SUITESPARSE_BLAS_zgemm(transa,transb,m,n,k,alpha,A,lda,B,ldb,beta, \ + C,ldc,ok) \ { \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDB_blas_int, ldb, ok) ; \ SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ if (ok) \ { \ - SUITESPARSE_BLAS_DSYRK (uplo, trans, &N_blas_int, &K_blas_int, alpha, \ - A, &LDA_blas_int, beta, C, &LDC_blas_int) ; \ + SUITESPARSE_BLAS_ZGEMM (transa, transb, &M_blas_int, &N_blas_int, \ + &K_blas_int, alpha, A, &LDA_blas_int, B, &LDB_blas_int, beta, C, \ + &LDC_blas_int) ; \ } \ } -void SUITESPARSE_BLAS_ZHERK // C = alpha*A*A^H + beta*C, or A^H*A +void SUITESPARSE_BLAS_CGEMM ( // input: - const char *uplo, - const char *trans, + const char *transa, + const char *transb, + const SUITESPARSE_BLAS_INT *m, const SUITESPARSE_BLAS_INT *n, const SUITESPARSE_BLAS_INT *k, const void *alpha, const void *A, const SUITESPARSE_BLAS_INT *lda, + const void *B, + const SUITESPARSE_BLAS_INT *ldb, const void *beta, // input/output: void *C, @@ -928,47 +1184,206 @@ void SUITESPARSE_BLAS_ZHERK // C = alpha*A*A^H + beta*C, or A^H*A const SUITESPARSE_BLAS_INT *ldc ) ; -#define SUITESPARSE_BLAS_zherk(uplo,trans,n,k,alpha,A,lda,beta,C,ldc,ok) \ +#define SUITESPARSE_BLAS_cgemm(transa,transb,m,n,k,alpha,A,lda,B,ldb,beta, \ + C,ldc,ok) \ { \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDB_blas_int, ldb, ok) ; \ SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ if (ok) \ { \ - SUITESPARSE_BLAS_ZHERK (uplo, trans, &N_blas_int, &K_blas_int, alpha, \ - A, &LDA_blas_int, beta, C, &LDC_blas_int) ; \ + SUITESPARSE_BLAS_CGEMM (transa, transb, &M_blas_int, &N_blas_int, \ + &K_blas_int, alpha, A, &LDA_blas_int, B, &LDB_blas_int, beta, C, \ + &LDC_blas_int) ; \ } \ } -void SUITESPARSE_LAPACK_DPOTRF // Cholesky factorization +//------------------------------------------------------------------------------ +// syrk/herk: C = alpha*A*A' + beta*C ; or C = alpha*A'*A + beta*C +//------------------------------------------------------------------------------ + +void SUITESPARSE_BLAS_DSYRK ( // input: const char *uplo, + const char *trans, const SUITESPARSE_BLAS_INT *n, + const SUITESPARSE_BLAS_INT *k, + const double *alpha, + const double *A, + const SUITESPARSE_BLAS_INT *lda, + const double *beta, // input/output: - double *A, + double *C, // input: - const SUITESPARSE_BLAS_INT *lda, - // output: - SUITESPARSE_BLAS_INT *info + const SUITESPARSE_BLAS_INT *ldc ) ; -#define SUITESPARSE_LAPACK_dpotrf(uplo,n,A,lda,info,ok) \ +#define SUITESPARSE_BLAS_dsyrk(uplo,trans,n,k,alpha,A,lda,beta,C,ldc,ok) \ { \ SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ - info = 1 ; \ + SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ if (ok) \ { \ - SUITESPARSE_BLAS_INT LAPACK_Info = -999 ; \ - SUITESPARSE_LAPACK_DPOTRF (uplo, &N_blas_int, A, &LDA_blas_int, \ - &LAPACK_Info) ; \ - info = (Int) LAPACK_Info ; \ + SUITESPARSE_BLAS_DSYRK (uplo, trans, &N_blas_int, &K_blas_int, alpha, \ + A, &LDA_blas_int, beta, C, &LDC_blas_int) ; \ } \ } -void SUITESPARSE_LAPACK_ZPOTRF // Cholesky factorization +void SUITESPARSE_BLAS_SSYRK +( + // input: + const char *uplo, + const char *trans, + const SUITESPARSE_BLAS_INT *n, + const SUITESPARSE_BLAS_INT *k, + const float *alpha, + const float *A, + const SUITESPARSE_BLAS_INT *lda, + const float *beta, + // input/output: + float *C, + // input: + const SUITESPARSE_BLAS_INT *ldc +) ; + +#define SUITESPARSE_BLAS_ssyrk(uplo,trans,n,k,alpha,A,lda,beta,C,ldc,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_SSYRK (uplo, trans, &N_blas_int, &K_blas_int, alpha, \ + A, &LDA_blas_int, beta, C, &LDC_blas_int) ; \ + } \ +} + +void SUITESPARSE_BLAS_ZHERK +( + // input: + const char *uplo, + const char *trans, + const SUITESPARSE_BLAS_INT *n, + const SUITESPARSE_BLAS_INT *k, + const void *alpha, + const void *A, + const SUITESPARSE_BLAS_INT *lda, + const void *beta, + // input/output: + void *C, + // input: + const SUITESPARSE_BLAS_INT *ldc +) ; + +#define SUITESPARSE_BLAS_zherk(uplo,trans,n,k,alpha,A,lda,beta,C,ldc,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_ZHERK (uplo, trans, &N_blas_int, &K_blas_int, alpha, \ + A, &LDA_blas_int, beta, C, &LDC_blas_int) ; \ + } \ +} + +void SUITESPARSE_BLAS_CHERK +( + // input: + const char *uplo, + const char *trans, + const SUITESPARSE_BLAS_INT *n, + const SUITESPARSE_BLAS_INT *k, + const void *alpha, + const void *A, + const SUITESPARSE_BLAS_INT *lda, + const void *beta, + // input/output: + void *C, + // input: + const SUITESPARSE_BLAS_INT *ldc +) ; + +#define SUITESPARSE_BLAS_cherk(uplo,trans,n,k,alpha,A,lda,beta,C,ldc,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_CHERK (uplo, trans, &N_blas_int, &K_blas_int, alpha, \ + A, &LDA_blas_int, beta, C, &LDC_blas_int) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// potrf: Cholesky factorization +//------------------------------------------------------------------------------ + +void SUITESPARSE_LAPACK_DPOTRF +( + // input: + const char *uplo, + const SUITESPARSE_BLAS_INT *n, + // input/output: + double *A, + // input: + const SUITESPARSE_BLAS_INT *lda, + // output: + SUITESPARSE_BLAS_INT *info +) ; + +#define SUITESPARSE_LAPACK_dpotrf(uplo,n,A,lda,info,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + info = 1 ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_INT LAPACK_Info = -999 ; \ + SUITESPARSE_LAPACK_DPOTRF (uplo, &N_blas_int, A, &LDA_blas_int, \ + &LAPACK_Info) ; \ + info = (Int) LAPACK_Info ; \ + } \ +} + +void SUITESPARSE_LAPACK_SPOTRF +( + // input: + const char *uplo, + const SUITESPARSE_BLAS_INT *n, + // input/output: + float *A, + // input: + const SUITESPARSE_BLAS_INT *lda, + // output: + SUITESPARSE_BLAS_INT *info +) ; + +#define SUITESPARSE_LAPACK_spotrf(uplo,n,A,lda,info,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + info = 1 ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_INT LAPACK_Info = -999 ; \ + SUITESPARSE_LAPACK_SPOTRF (uplo, &N_blas_int, A, &LDA_blas_int, \ + &LAPACK_Info) ; \ + info = (Int) LAPACK_Info ; \ + } \ +} + +void SUITESPARSE_LAPACK_ZPOTRF ( // input: const char *uplo, @@ -995,7 +1410,38 @@ void SUITESPARSE_LAPACK_ZPOTRF // Cholesky factorization } \ } -void SUITESPARSE_BLAS_DSCAL // Y = alpha*Y +void SUITESPARSE_LAPACK_CPOTRF +( + // input: + const char *uplo, + const SUITESPARSE_BLAS_INT *n, + // input/output: + void *A, + // input: + const SUITESPARSE_BLAS_INT *lda, + // output: + SUITESPARSE_BLAS_INT *info +) ; + +#define SUITESPARSE_LAPACK_cpotrf(uplo,n,A,lda,info,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + info = 1 ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_INT LAPACK_Info = -999 ; \ + SUITESPARSE_LAPACK_CPOTRF (uplo, &N_blas_int, A, &LDA_blas_int, \ + &LAPACK_Info) ; \ + info = LAPACK_Info ; \ + } \ +} + +//------------------------------------------------------------------------------ +// scal: Y = alpha*Y +//------------------------------------------------------------------------------ + +void SUITESPARSE_BLAS_DSCAL ( // input: const SUITESPARSE_BLAS_INT *n, @@ -1016,7 +1462,28 @@ void SUITESPARSE_BLAS_DSCAL // Y = alpha*Y } \ } -void SUITESPARSE_BLAS_ZSCAL // Y = alpha*Y +void SUITESPARSE_BLAS_SSCAL +( + // input: + const SUITESPARSE_BLAS_INT *n, + const float *alpha, + // input/output: + float *Y, + // input: + const SUITESPARSE_BLAS_INT *incy +) ; + +#define SUITESPARSE_BLAS_sscal(n,alpha,Y,incy,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCY_blas_int, incy, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_SSCAL (&N_blas_int, alpha, Y, &INCY_blas_int) ; \ + } \ +} + +void SUITESPARSE_BLAS_ZSCAL ( // input: const SUITESPARSE_BLAS_INT *n, @@ -1037,7 +1504,32 @@ void SUITESPARSE_BLAS_ZSCAL // Y = alpha*Y } \ } -void SUITESPARSE_BLAS_DGER // A = alpha*x*y' + A +void SUITESPARSE_BLAS_CSCAL +( + // input: + const SUITESPARSE_BLAS_INT *n, + const void *alpha, + // input/output: + void *Y, + // input: + const SUITESPARSE_BLAS_INT *incy +) ; + +#define SUITESPARSE_BLAS_cscal(n,alpha,Y,incy,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCY_blas_int, incy, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_CSCAL (&N_blas_int, alpha, Y, &INCY_blas_int) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// ger/geru: A = alpha*x*y' + A +//------------------------------------------------------------------------------ + +void SUITESPARSE_BLAS_DGER ( // input: const SUITESPARSE_BLAS_INT *m, @@ -1067,7 +1559,37 @@ void SUITESPARSE_BLAS_DGER // A = alpha*x*y' + A } \ } -void SUITESPARSE_BLAS_ZGERU // A = alpha*x*y' + A +void SUITESPARSE_BLAS_SGER +( + // input: + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const float *alpha, + const float *X, + const SUITESPARSE_BLAS_INT *incx, + const float *Y, + const SUITESPARSE_BLAS_INT *incy, + // input/output: + float *A, + // input: + const SUITESPARSE_BLAS_INT *lda +) ; + +#define SUITESPARSE_BLAS_sger(m,n,alpha,X,incx,Y,incy,A,lda,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCY_blas_int, incy, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_SGER (&M_blas_int, &N_blas_int, alpha, X, \ + &INCX_blas_int, Y, &INCY_blas_int, A, &LDA_blas_int) ; \ + } \ +} + +void SUITESPARSE_BLAS_ZGERU ( // input: const SUITESPARSE_BLAS_INT *m, @@ -1097,7 +1619,41 @@ void SUITESPARSE_BLAS_ZGERU // A = alpha*x*y' + A } \ } -void SUITESPARSE_LAPACK_DLARFT // T = block Householder factor +void SUITESPARSE_BLAS_CGERU +( + // input: + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const void *alpha, + const void *X, + const SUITESPARSE_BLAS_INT *incx, + const void *Y, + const SUITESPARSE_BLAS_INT *incy, + // input/output: + void *A, + // input: + const SUITESPARSE_BLAS_INT *lda +) ; + +#define SUITESPARSE_BLAS_cgeru(m,n,alpha,X,incx,Y,incy,A,lda,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCY_blas_int, incy, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_CGERU (&M_blas_int, &N_blas_int, alpha, X, \ + &INCX_blas_int, Y, &INCY_blas_int, A, &LDA_blas_int) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// larft: T = block Householder factor +//------------------------------------------------------------------------------ + +void SUITESPARSE_LAPACK_DLARFT ( // input: const char *direct, @@ -1126,7 +1682,36 @@ void SUITESPARSE_LAPACK_DLARFT // T = block Householder factor } \ } -void SUITESPARSE_LAPACK_ZLARFT // T = block Householder factor +void SUITESPARSE_LAPACK_SLARFT +( + // input: + const char *direct, + const char *storev, + const SUITESPARSE_BLAS_INT *n, + const SUITESPARSE_BLAS_INT *k, + const float *V, + const SUITESPARSE_BLAS_INT *ldv, + const float *Tau, + // output: + float *T, + // input: + const SUITESPARSE_BLAS_INT *ldt +) ; + +#define SUITESPARSE_LAPACK_slarft(direct,storev,n,k,V,ldv,Tau,T,ldt,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDV_blas_int, ldv, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDT_blas_int, ldt, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_LAPACK_SLARFT (direct, storev, &N_blas_int, &K_blas_int, \ + V, &LDV_blas_int, Tau, T, &LDT_blas_int) ; \ + } \ +} + +void SUITESPARSE_LAPACK_ZLARFT ( // input: const char *direct, @@ -1155,7 +1740,40 @@ void SUITESPARSE_LAPACK_ZLARFT // T = block Householder factor } \ } -void SUITESPARSE_LAPACK_DLARFB // apply block Householder reflector +void SUITESPARSE_LAPACK_CLARFT +( + // input: + const char *direct, + const char *storev, + const SUITESPARSE_BLAS_INT *n, + const SUITESPARSE_BLAS_INT *k, + const void *V, + const SUITESPARSE_BLAS_INT *ldv, + const void *Tau, + // output: + void *T, + // input: + const SUITESPARSE_BLAS_INT *ldt +) ; + +#define SUITESPARSE_LAPACK_clarft(direct,storev,n,k,V,ldv,Tau,T,ldt,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDV_blas_int, ldv, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDT_blas_int, ldt, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_LAPACK_CLARFT (direct, storev, &N_blas_int, &K_blas_int, \ + V, &LDV_blas_int, Tau, T, &LDT_blas_int) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// larfb: apply block Householder reflector +//------------------------------------------------------------------------------ + +void SUITESPARSE_LAPACK_DLARFB ( // input: const char *side, @@ -1197,7 +1815,49 @@ void SUITESPARSE_LAPACK_DLARFB // apply block Householder reflector } \ } -void SUITESPARSE_LAPACK_ZLARFB // apply block Householder reflector +void SUITESPARSE_LAPACK_SLARFB +( + // input: + const char *side, + const char *trans, + const char *direct, + const char *storev, + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const SUITESPARSE_BLAS_INT *k, + const float *V, + const SUITESPARSE_BLAS_INT *ldv, + const float *T, + const SUITESPARSE_BLAS_INT *ldt, + // input/output: + float *C, + // input: + const SUITESPARSE_BLAS_INT *ldc, + // workspace: + float *Work, + // input: + const SUITESPARSE_BLAS_INT *ldwork +) ; + +#define SUITESPARSE_LAPACK_slarfb(side,trans,direct,storev,m,n,k,V,ldv,T,ldt, \ + C,ldc,Work,ldwork,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDV_blas_int, ldv, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDT_blas_int, ldt, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDWORK_blas_int, ldwork, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_LAPACK_SLARFB (side, trans, direct, storev, &M_blas_int, \ + &N_blas_int, &K_blas_int, V, &LDV_blas_int, T, &LDT_blas_int, C, \ + &LDC_blas_int, Work, &LDWORK_blas_int) ; \ + } \ +} + +void SUITESPARSE_LAPACK_ZLARFB ( // input: const char *side, @@ -1239,7 +1899,53 @@ void SUITESPARSE_LAPACK_ZLARFB // apply block Householder reflector } \ } -double SUITESPARSE_BLAS_DNRM2 // vector 2-norm +void SUITESPARSE_LAPACK_CLARFB +( + // input: + const char *side, + const char *trans, + const char *direct, + const char *storev, + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const SUITESPARSE_BLAS_INT *k, + const void *V, + const SUITESPARSE_BLAS_INT *ldv, + const void *T, + const SUITESPARSE_BLAS_INT *ldt, + // input/output: + void *C, + // input: + const SUITESPARSE_BLAS_INT *ldc, + // workspace: + void *Work, + // input: + const SUITESPARSE_BLAS_INT *ldwork +) ; + +#define SUITESPARSE_LAPACK_clarfb(side,trans,direct,storev,m,n,k,V,ldv,T,ldt, \ + C,ldc,Work,ldwork,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDV_blas_int, ldv, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDT_blas_int, ldt, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDWORK_blas_int, ldwork, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_LAPACK_CLARFB (side, trans, direct, storev, &M_blas_int, \ + &N_blas_int, &K_blas_int, V, &LDV_blas_int, T, &LDT_blas_int, C, \ + &LDC_blas_int, Work, &LDWORK_blas_int) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// nrm2: vector 2-norm +//------------------------------------------------------------------------------ + +double SUITESPARSE_BLAS_DNRM2 ( // input: const SUITESPARSE_BLAS_INT *n, @@ -1258,7 +1964,26 @@ double SUITESPARSE_BLAS_DNRM2 // vector 2-norm } \ } -double SUITESPARSE_BLAS_DZNRM2 // vector 2-norm +float SUITESPARSE_BLAS_SNRM2 +( + // input: + const SUITESPARSE_BLAS_INT *n, + const float *X, + const SUITESPARSE_BLAS_INT *incx +) ; + +#define SUITESPARSE_BLAS_snrm2(result,n,X,incx,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + result = 0 ; \ + if (ok) \ + { \ + result = SUITESPARSE_BLAS_SNRM2 (&N_blas_int, X, &INCX_blas_int) ; \ + } \ +} + +double SUITESPARSE_BLAS_DZNRM2 ( // input: const SUITESPARSE_BLAS_INT *n, @@ -1277,7 +2002,30 @@ double SUITESPARSE_BLAS_DZNRM2 // vector 2-norm } \ } -void SUITESPARSE_LAPACK_DLARFG // generate Householder reflector +float SUITESPARSE_BLAS_SCNRM2 +( + // input: + const SUITESPARSE_BLAS_INT *n, + const void *X, + const SUITESPARSE_BLAS_INT *incx +) ; + +#define SUITESPARSE_BLAS_scnrm2(result,n,X,incx,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + result = 0 ; \ + if (ok) \ + { \ + result = SUITESPARSE_BLAS_SCNRM2 (&N_blas_int, X, &INCX_blas_int) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// larfg: generate Householder reflector +//------------------------------------------------------------------------------ + +void SUITESPARSE_LAPACK_DLARFG ( // input: const SUITESPARSE_BLAS_INT *n, @@ -1301,7 +2049,31 @@ void SUITESPARSE_LAPACK_DLARFG // generate Householder reflector } \ } -void SUITESPARSE_LAPACK_ZLARFG // generate Householder reflector +void SUITESPARSE_LAPACK_SLARFG +( + // input: + const SUITESPARSE_BLAS_INT *n, + // input/output: + float *alpha, + float *X, + // input: + const SUITESPARSE_BLAS_INT *incx, + // output: + float *tau +) ; + +#define SUITESPARSE_LAPACK_slarfg(n,alpha,X,incx,tau,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_LAPACK_SLARFG (&N_blas_int, alpha, X, &INCX_blas_int, \ + tau) ; \ + } \ +} + +void SUITESPARSE_LAPACK_ZLARFG ( // input: const SUITESPARSE_BLAS_INT *n, @@ -1325,7 +2097,35 @@ void SUITESPARSE_LAPACK_ZLARFG // generate Householder reflector } \ } -void SUITESPARSE_LAPACK_DLARF // apply Householder reflector +void SUITESPARSE_LAPACK_CLARFG +( + // input: + const SUITESPARSE_BLAS_INT *n, + // input/output: + void *alpha, + void *X, + // input: + const SUITESPARSE_BLAS_INT *incx, + // output: + void *tau +) ; + +#define SUITESPARSE_LAPACK_clarfg(n,alpha,X,incx,tau,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_LAPACK_CLARFG (&N_blas_int, alpha, X, &INCX_blas_int, \ + tau) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// larf: apply Householder reflector +//------------------------------------------------------------------------------ + +void SUITESPARSE_LAPACK_DLARF ( // input: const char *side, @@ -1355,7 +2155,37 @@ void SUITESPARSE_LAPACK_DLARF // apply Householder reflector } \ } -void SUITESPARSE_LAPACK_ZLARF // apply Householder reflector +void SUITESPARSE_LAPACK_SLARF +( + // input: + const char *side, + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const float *V, + const SUITESPARSE_BLAS_INT *incv, + const float *tau, + // input/output: + float *C, + // input: + const SUITESPARSE_BLAS_INT *ldc, + // workspace: + float *Work +) ; + +#define SUITESPARSE_LAPACK_slarf(side,m,n,V,incv,tau,C,ldc,Work,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCV_blas_int, incv, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_LAPACK_SLARF (side, &M_blas_int, &N_blas_int, V, \ + &INCV_blas_int, tau, C, &LDC_blas_int, Work) ; \ + } \ +} + +void SUITESPARSE_LAPACK_ZLARF ( // input: const char *side, @@ -1385,6 +2215,36 @@ void SUITESPARSE_LAPACK_ZLARF // apply Householder reflector } \ } +void SUITESPARSE_LAPACK_CLARF +( + // input: + const char *side, + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const void *V, + const SUITESPARSE_BLAS_INT *incv, + const void *tau, + // input/output: + void *C, + // input: + const SUITESPARSE_BLAS_INT *ldc, + // workspace: + void *Work +) ; + +#define SUITESPARSE_LAPACK_clarf(side,m,n,V,incv,tau,C,ldc,Work,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCV_blas_int, incv, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_LAPACK_CLARF (side, &M_blas_int, &N_blas_int, V, \ + &INCV_blas_int, tau, C, &LDC_blas_int, Work) ; \ + } \ +} + #endif //------------------------------------------------------------------------------ diff --git a/SuiteSparse_config/Config/SuiteSparse_config.pc.in b/SuiteSparse_config/Config/SuiteSparse_config.pc.in new file mode 100644 index 00000000..f082c226 --- /dev/null +++ b/SuiteSparse_config/Config/SuiteSparse_config.pc.in @@ -0,0 +1,16 @@ +# SuiteSparse_config, Copyright (c) 2012-2023, Timothy A. Davis. +# All Rights Reserved. +# SPDX-License-Identifier: BSD-3-clause + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: SuiteSparseConfig +URL: https://github.com/DrTimothyAldenDavis/SuiteSparse +Description: Configuration for SuiteSparse +Version: @SUITESPARSE_VERSION_MAJOR@.@SUITESPARSE_VERSION_MINOR@.@SUITESPARSE_VERSION_SUB@ +Libs: -L${libdir} -l@SUITESPARSE_LIB_BASE_NAME@ +Libs.private: @SUITESPARSE_CONFIG_STATIC_LIBS@ +Cflags: -I${includedir} diff --git a/SuiteSparse_config/Config/SuiteSparse_configConfig.cmake.in b/SuiteSparse_config/Config/SuiteSparse_configConfig.cmake.in new file mode 100644 index 00000000..1831e466 --- /dev/null +++ b/SuiteSparse_config/Config/SuiteSparse_configConfig.cmake.in @@ -0,0 +1,171 @@ +#------------------------------------------------------------------------------- +# SuiteSparse/SuiteSparse_config/cmake_modules/SuiteSparse_configConfig.cmake +#------------------------------------------------------------------------------- + +# The following copyright and license applies to just this file only, not to +# the library itself: +# SuiteSparse_configConfig.cmake, Copyright (c) 2023, Timothy A. Davis. All Rights Reserved. +# SPDX-License-Identifier: BSD-3-clause + +#------------------------------------------------------------------------------- + +# Finds the SuiteSparse_config include file and compiled library. +# The following targets are defined: +# SuiteSparseConfig - for the shared library (if available) +# SuiteSparseConfig_static - for the static library (if available) + +# For backward compatibility the following variables are set: + +# SUITESPARSE_CONFIG_INCLUDE_DIR - where to find SuiteSparse_config.h +# SUITESPARSE_CONFIG_LIBRARY - dynamic SuiteSparse_config library +# SUITESPARSE_CONFIG_STATIC - static SuiteSparse_config library +# SUITESPARSE_CONFIG_LIBRARIES - libraries when using SuiteSparse_config +# SUITESPARSE_CONFIG_FOUND - true if SuiteSparse_config found + +# Set ``CMAKE_MODULE_PATH`` to the parent folder where this module file is +# installed. + +#------------------------------------------------------------------------------- + +@PACKAGE_INIT@ + +set ( SUITESPARSE_DATE "@SUITESPARSE_DATE@" ) +set ( SUITESPARSE_CONFIG_VERSION_MAJOR @SUITESPARSE_VERSION_MAJOR@ ) +set ( SUITESPARSE_CONFIG_VERSION_MINOR @SUITESPARSE_VERSION_MINOR@ ) +set ( SUITESPARSE_CONFIG_VERSION_PATCH @SUITESPARSE_VERSION_SUB@ ) +set ( SUITESPARSE_CONFIG_VERSION "@SUITESPARSE_VERSION_MAJOR@.@SUITESPARSE_VERSION_MINOR@.@SUITESPARSE_VERSION_SUB@" ) + +# Check for dependent targets +include ( CMakeFindDependencyMacro ) +set ( _dependencies_found ON ) + +# Look for OpenMP +if ( @SUITESPARSE_CONFIG_HAS_OPENMP@ AND NOT OpenMP_C_FOUND ) + find_dependency ( OpenMP COMPONENTS C ) + if ( NOT OpenMP_C_FOUND ) + set ( _dependencies_found OFF ) + endif ( ) +endif ( ) + +if ( NOT _dependencies_found ) + set ( SuiteSparse_config_FOUND OFF ) + return ( ) +endif ( ) + + +# Import target +include ( ${CMAKE_CURRENT_LIST_DIR}/SuiteSparse_configTargets.cmake ) + +if ( @SUITESPARSE_CONFIG_HAS_OPENMP@ ) + if ( TARGET SuiteSparse::SuiteSparseConfig ) + get_property ( _suitesparse_config_aliased TARGET SuiteSparse::SuiteSparseConfig + PROPERTY ALIASED_TARGET ) + if ( "${_suitesparse_config_aliased}" STREQUAL "" ) + target_include_directories ( SuiteSparse::SuiteSparseConfig SYSTEM AFTER INTERFACE + "$" ) + else ( ) + target_include_directories ( ${_suitesparse_config_aliased} SYSTEM AFTER INTERFACE + "$" ) + endif ( ) + endif ( ) + if ( TARGET SuiteSparse::SuiteSparseConfig_static ) + get_property ( _suitesparse_config_aliased TARGET SuiteSparse::SuiteSparseConfig_static + PROPERTY ALIASED_TARGET ) + if ( "${_suitesparse_config_aliased}" STREQUAL "" ) + target_include_directories ( SuiteSparse::SuiteSparseConfig_static SYSTEM AFTER INTERFACE + "$" ) + else ( ) + target_include_directories ( ${_suitesparse_config_aliased} SYSTEM AFTER INTERFACE + "$" ) + endif ( ) + endif ( ) +endif ( ) + + +# The following is only for backward compatibility with FindSuiteSparse_config. + +set ( _target_shared SuiteSparse::SuiteSparseConfig ) +set ( _target_static SuiteSparse::SuiteSparseConfig_static ) +set ( _var_prefix "SUITESPARSE_CONFIG" ) + +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 ( ) + +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 ( SUITESPARSE_CONFIG_LIBRARIES ${SUITESPARSE_CONFIG_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 ( SUITESPARSE_CONFIG_INCLUDE_DIR ${SUITESPARSE_CONFIG_INCLUDE_DIR} ) +suitesparse_check_exist ( SUITESPARSE_CONFIG_LIBRARY ${SUITESPARSE_CONFIG_LIBRARY} ) + +message ( STATUS "SuiteSparse_config version: ${SUITESPARSE_CONFIG_VERSION}" ) +message ( STATUS "SuiteSparse_config include: ${SUITESPARSE_CONFIG_INCLUDE_DIR}" ) +message ( STATUS "SuiteSparse_config library: ${SUITESPARSE_CONFIG_LIBRARY}" ) +message ( STATUS "SuiteSparse_config static: ${SUITESPARSE_CONFIG_STATIC}" ) diff --git a/SuiteSparse_config/Makefile b/SuiteSparse_config/Makefile index 9893afe7..a14ac2fd 100644 --- a/SuiteSparse_config/Makefile +++ b/SuiteSparse_config/Makefile @@ -37,18 +37,18 @@ default: library # default is to install only in /usr/local library: - ( cd build && cmake $(CMAKE_OPTIONS) .. && cmake --build . -j${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) -DLOCAL_INSTALL=1 .. && cmake --build . -j${JOBS} ) + ( cd build && cmake $(CMAKE_OPTIONS) -USUITESPARSE_PKGFILEDIR -DSUITESPARSE_LOCAL_INSTALL=1 .. && cmake --build . --config Release -j${JOBS} ) # install only in /usr/local (default) global: - ( cd build && cmake $(CMAKE_OPTIONS) -DLOCAL_INSTALL=0 .. && cmake --build . -j${JOBS} ) + ( cd build && cmake $(CMAKE_OPTIONS) -USUITESPARSE_PKGFILEDIR -DSUITESPARSE_LOCAL_INSTALL=0 .. && cmake --build . --config Release -j${JOBS} ) debug: - ( cd build ; cmake $(CMAKE_OPTIONS) -DCMAKE_BUILD_TYPE=Debug .. ; cmake --build . ) + ( cd build && cmake $(CMAKE_OPTIONS) -DCMAKE_BUILD_TYPE=Debug .. ; cmake --build . --config Debug ) all: library @@ -56,14 +56,14 @@ demos: library # just compile after running cmake; do not run cmake again remake: - ( cd build ; cmake --build . ) + ( cd build && cmake --build . ) # just run cmake to set things up setup: - ( cd build ; cmake $(CMAKE_OPTIONS) .. ) + ( cd build && cmake $(CMAKE_OPTIONS) .. ) install: - ( cd build ; cmake --install . ) + ( cd build && cmake --install . ) # remove any installed libraries and #include files uninstall: diff --git a/SuiteSparse_config/README.txt b/SuiteSparse_config/README.txt index 4ff01953..9d306c9e 100644 --- a/SuiteSparse_config/README.txt +++ b/SuiteSparse_config/README.txt @@ -1,4 +1,4 @@ -SuiteSparse_config, Copyright (c) 2012-2023, Timothy A. Davis. +SuiteSparse_config, Copyright (c) 2012-2024, Timothy A. Davis. All Rights Reserved. SPDX-License-Identifier: BSD-3-clause diff --git a/SuiteSparse_config/SuiteSparse_config.c b/SuiteSparse_config/SuiteSparse_config.c index 07909371..ee220a77 100644 --- a/SuiteSparse_config/SuiteSparse_config.c +++ b/SuiteSparse_config/SuiteSparse_config.c @@ -11,7 +11,6 @@ /* SuiteSparse configuration : memory manager and printf functions. */ -#define SUITESPARSE_LIBRARY #include "SuiteSparse_config.h" /* -------------------------------------------------------------------------- */ @@ -496,7 +495,7 @@ void *SuiteSparse_free /* always returns NULL */ tic [1] = 0 ; } -#else +#else /* ---------------------------------------------------------------------- */ /* POSIX timer */ @@ -617,7 +616,7 @@ double SuiteSparse_hypot (double x, double y) r = x / y ; s = y * sqrt (1.0 + r*r) ; } - } + } return (s) ; } @@ -760,6 +759,10 @@ const char *SuiteSparse_BLAS_library ( void ) return ((sizeof (SUITESPARSE_BLAS_INT) == 8) ? "OpenBLAS (64-bit integers)" : "OpenBLAS (32-bit integers)") ; + #elif defined ( BLAS_FLAME ) + return ((sizeof (SUITESPARSE_BLAS_INT) == 8) ? + "FLAME (64-bit integers)" : + "FLAME (32-bit integers)") ; #elif defined ( BLAS_Generic ) return ((sizeof (SUITESPARSE_BLAS_INT) == 8) ? "Reference BLAS (64-bit integers)" : diff --git a/SuiteSparse_config/SuiteSparse_config.h b/SuiteSparse_config/SuiteSparse_config.h index 7b0196f2..258e7601 100644 --- a/SuiteSparse_config/SuiteSparse_config.h +++ b/SuiteSparse_config/SuiteSparse_config.h @@ -368,13 +368,24 @@ int SuiteSparse_divcomplex // determine which timer to use, if any #ifndef NTIMER + // SuiteSparse_config itself can be compiled without OpenMP, + // but other packages can themselves use OpenMP. In this case, + // those packages should use omp_get_wtime() directly. This can + // be done via the SUITESPARSE_TIME macro, defined below: + #define SUITESPARSE_HAVE_CLOCK_GETTIME #if defined ( _OPENMP ) #define SUITESPARSE_TIMER_ENABLED - #elif defined ( _POSIX_C_SOURCE ) - #if _POSIX_C_SOURCE >= 199309L + #define SUITESPARSE_TIME (omp_get_wtime ( )) + #elif defined ( SUITESPARSE_HAVE_CLOCK_GETTIME ) #define SUITESPARSE_TIMER_ENABLED - #endif + #define SUITESPARSE_TIME (SuiteSparse_time ( )) + #else + // No timer is available + #define SUITESPARSE_TIME (0) #endif +#else + // The timer is explictly disabled + #define SUITESPARSE_TIME (0) #endif // SuiteSparse printf macro @@ -409,14 +420,19 @@ int SuiteSparse_version // returns SUITESPARSE_VERSION #define SUITESPARSE_HAS_VERSION_FUNCTION -#define SUITESPARSE_DATE "Mar FIXME, 2023" +#define SUITESPARSE_DATE "Mar 22, 2024" #define SUITESPARSE_MAIN_VERSION 7 -#define SUITESPARSE_SUB_VERSION 1 +#define SUITESPARSE_SUB_VERSION 7 #define SUITESPARSE_SUBSUB_VERSION 0 +// version format x.y #define SUITESPARSE_VER_CODE(main,sub) ((main) * 1000 + (sub)) -#define SUITESPARSE_VERSION \ - SUITESPARSE_VER_CODE(SUITESPARSE_MAIN_VERSION,SUITESPARSE_SUB_VERSION) +#define SUITESPARSE_VERSION SUITESPARSE_VER_CODE(7, 7) + +// version format x.y.z +#define SUITESPARSE__VERCODE(main,sub,patch) \ + (((main)*1000ULL + (sub))*1000ULL + (patch)) +#define SUITESPARSE__VERSION SUITESPARSE__VERCODE(7,7,0) //============================================================================== // SuiteSparse interface to the BLAS and LAPACK libraries @@ -469,7 +485,7 @@ int SuiteSparse_version // returns SUITESPARSE_VERSION #elif defined ( BLAS_UNDERSCORE ) - // append an undescore, use lower case + // append an underscore, use lower case #define SUITESPARSE_FORTRAN(name,NAME) name ## _ #define SUITESPARSE__FORTRAN(name,NAME) name ## _ @@ -529,12 +545,12 @@ int SuiteSparse_version // returns SUITESPARSE_VERSION // If the suffix does not contain "_", use (Sun Perf., for example): -// cd build ; cmake -DBLAS64_SUFFIX="64" .. +// cd build && cmake -DBLAS64_SUFFIX="64" .. // If the suffix contains "_" (OpenBLAS in spack for example), use the // following: -// cd build ; cmake -DBLAS64_SUFFIX="_64" .. +// cd build && cmake -DBLAS64_SUFFIX="_64" .. // This setting could be used by the spack packaging of SuiteSparse when linked // with the spack-installed OpenBLAS with 64-bit integers. See @@ -572,6 +588,7 @@ int SuiteSparse_version // returns SUITESPARSE_VERSION // C names of Fortan BLAS and LAPACK functions used by SuiteSparse //------------------------------------------------------------------------------ +// double #define SUITESPARSE_BLAS_DTRSV SUITESPARSE_BLAS ( dtrsv , DTRSV ) #define SUITESPARSE_BLAS_DGEMV SUITESPARSE_BLAS ( dgemv , DGEMV ) #define SUITESPARSE_BLAS_DTRSM SUITESPARSE_BLAS ( dtrsm , DTRSM ) @@ -579,8 +596,15 @@ int SuiteSparse_version // returns SUITESPARSE_VERSION #define SUITESPARSE_BLAS_DSYRK SUITESPARSE_BLAS ( dsyrk , DSYRK ) #define SUITESPARSE_BLAS_DGER SUITESPARSE_BLAS ( dger , DGER ) #define SUITESPARSE_BLAS_DSCAL SUITESPARSE_BLAS ( dscal , DSCAL ) +#define SUITESPARSE_BLAS_DNRM2 SUITESPARSE_BLAS ( dnrm2 , DNRM2 ) + #define SUITESPARSE_LAPACK_DPOTRF SUITESPARSE_BLAS ( dpotrf , DPOTRF ) +#define SUITESPARSE_LAPACK_DLARF SUITESPARSE_BLAS ( dlarf , DLARF ) +#define SUITESPARSE_LAPACK_DLARFG SUITESPARSE_BLAS ( dlarfg , DLARFG ) +#define SUITESPARSE_LAPACK_DLARFT SUITESPARSE_BLAS ( dlarft , DLARFT ) +#define SUITESPARSE_LAPACK_DLARFB SUITESPARSE_BLAS ( dlarfb , DLARFB ) +// double complex #define SUITESPARSE_BLAS_ZTRSV SUITESPARSE_BLAS ( ztrsv , ZTRSV ) #define SUITESPARSE_BLAS_ZGEMV SUITESPARSE_BLAS ( zgemv , ZGEMV ) #define SUITESPARSE_BLAS_ZTRSM SUITESPARSE_BLAS ( ztrsm , ZTRSM ) @@ -588,20 +612,46 @@ int SuiteSparse_version // returns SUITESPARSE_VERSION #define SUITESPARSE_BLAS_ZHERK SUITESPARSE_BLAS ( zherk , ZHERK ) #define SUITESPARSE_BLAS_ZGERU SUITESPARSE_BLAS ( zgeru , ZGERU ) #define SUITESPARSE_BLAS_ZSCAL SUITESPARSE_BLAS ( zscal , ZSCAL ) -#define SUITESPARSE_LAPACK_ZPOTRF SUITESPARSE_BLAS ( zpotrf , ZPOTRF ) - -#define SUITESPARSE_BLAS_DNRM2 SUITESPARSE_BLAS ( dnrm2 , DNRM2 ) -#define SUITESPARSE_LAPACK_DLARF SUITESPARSE_BLAS ( dlarf , DLARF ) -#define SUITESPARSE_LAPACK_DLARFG SUITESPARSE_BLAS ( dlarfg , DLARFG ) -#define SUITESPARSE_LAPACK_DLARFT SUITESPARSE_BLAS ( dlarft , DLARFT ) -#define SUITESPARSE_LAPACK_DLARFB SUITESPARSE_BLAS ( dlarfb , DLARFB ) - #define SUITESPARSE_BLAS_DZNRM2 SUITESPARSE_BLAS ( dznrm2 , DZNRM2 ) + +#define SUITESPARSE_LAPACK_ZPOTRF SUITESPARSE_BLAS ( zpotrf , ZPOTRF ) #define SUITESPARSE_LAPACK_ZLARF SUITESPARSE_BLAS ( zlarf , ZLARF ) #define SUITESPARSE_LAPACK_ZLARFG SUITESPARSE_BLAS ( zlarfg , ZLARFG ) #define SUITESPARSE_LAPACK_ZLARFT SUITESPARSE_BLAS ( zlarft , ZLARFT ) #define SUITESPARSE_LAPACK_ZLARFB SUITESPARSE_BLAS ( zlarfb , ZLARFB ) +// single +#define SUITESPARSE_BLAS_STRSV SUITESPARSE_BLAS ( strsv , STRSV ) +#define SUITESPARSE_BLAS_SGEMV SUITESPARSE_BLAS ( sgemv , SGEMV ) +#define SUITESPARSE_BLAS_STRSM SUITESPARSE_BLAS ( strsm , STRSM ) +#define SUITESPARSE_BLAS_SGEMM SUITESPARSE_BLAS ( sgemm , SGEMM ) +#define SUITESPARSE_BLAS_SSYRK SUITESPARSE_BLAS ( ssyrk , SSYRK ) +#define SUITESPARSE_BLAS_SGER SUITESPARSE_BLAS ( sger , SGER ) +#define SUITESPARSE_BLAS_SSCAL SUITESPARSE_BLAS ( sscal , SSCAL ) +#define SUITESPARSE_BLAS_SNRM2 SUITESPARSE_BLAS ( snrm2 , SNRM2 ) + +#define SUITESPARSE_LAPACK_SPOTRF SUITESPARSE_BLAS ( spotrf , SPOTRF ) +#define SUITESPARSE_LAPACK_SLARF SUITESPARSE_BLAS ( slarf , SLARF ) +#define SUITESPARSE_LAPACK_SLARFG SUITESPARSE_BLAS ( slarfg , SLARFG ) +#define SUITESPARSE_LAPACK_SLARFT SUITESPARSE_BLAS ( slarft , SLARFT ) +#define SUITESPARSE_LAPACK_SLARFB SUITESPARSE_BLAS ( slarfb , SLARFB ) + +// single complex +#define SUITESPARSE_BLAS_CTRSV SUITESPARSE_BLAS ( ctrsv , CTRSV ) +#define SUITESPARSE_BLAS_CGEMV SUITESPARSE_BLAS ( cgemv , CGEMV ) +#define SUITESPARSE_BLAS_CTRSM SUITESPARSE_BLAS ( ctrsm , CTRSM ) +#define SUITESPARSE_BLAS_CGEMM SUITESPARSE_BLAS ( cgemm , CGEMM ) +#define SUITESPARSE_BLAS_CHERK SUITESPARSE_BLAS ( cherk , CHERK ) +#define SUITESPARSE_BLAS_CGERU SUITESPARSE_BLAS ( cgeru , CGERU ) +#define SUITESPARSE_BLAS_CSCAL SUITESPARSE_BLAS ( cscal , CSCAL ) +#define SUITESPARSE_BLAS_SCNRM2 SUITESPARSE_BLAS ( scnrm2 , SCNRM2 ) + +#define SUITESPARSE_LAPACK_CPOTRF SUITESPARSE_BLAS ( cpotrf , CPOTRF ) +#define SUITESPARSE_LAPACK_CLARF SUITESPARSE_BLAS ( clarf , CLARF ) +#define SUITESPARSE_LAPACK_CLARFG SUITESPARSE_BLAS ( clarfg , CLARFG ) +#define SUITESPARSE_LAPACK_CLARFT SUITESPARSE_BLAS ( clarft , CLARFT ) +#define SUITESPARSE_LAPACK_CLARFB SUITESPARSE_BLAS ( clarfb , CLARFB ) + //------------------------------------------------------------------------------ // prototypes of BLAS and SUITESPARSE_LAPACK functions //------------------------------------------------------------------------------ @@ -627,7 +677,11 @@ int SuiteSparse_version // returns SUITESPARSE_VERSION #if defined ( SUITESPARSE_BLAS_DEFINITIONS ) -void SUITESPARSE_BLAS_DGEMV // Y = alpha*A*x + beta*Y +//------------------------------------------------------------------------------ +// gemv: Y = alpha*A*x + beta*Y +//------------------------------------------------------------------------------ + +void SUITESPARSE_BLAS_DGEMV ( // input: const char *trans, @@ -659,7 +713,39 @@ void SUITESPARSE_BLAS_DGEMV // Y = alpha*A*x + beta*Y } \ } -void SUITESPARSE_BLAS_ZGEMV // Y = alpha*A*X + beta*Y +void SUITESPARSE_BLAS_SGEMV +( + // input: + const char *trans, + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const float *alpha, + const float *A, + const SUITESPARSE_BLAS_INT *lda, + const float *X, + const SUITESPARSE_BLAS_INT *incx, + const float *beta, + // input/output: + float *Y, + // input: + const SUITESPARSE_BLAS_INT *incy +) ; + +#define SUITESPARSE_BLAS_sgemv(trans,m,n,alpha,A,lda,X,incx,beta,Y,incy,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCY_blas_int, incy, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_SGEMV (trans, &M_blas_int, &N_blas_int, alpha, A, \ + &LDA_blas_int, X, &INCX_blas_int, beta, Y, &INCY_blas_int) ; \ + } \ +} + +void SUITESPARSE_BLAS_ZGEMV ( // input: const char *trans, @@ -691,7 +777,43 @@ void SUITESPARSE_BLAS_ZGEMV // Y = alpha*A*X + beta*Y } \ } -void SUITESPARSE_BLAS_DTRSV // solve Lx=b, Ux=b, L'x=b, or U'x=b +void SUITESPARSE_BLAS_CGEMV +( + // input: + const char *trans, + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const void *alpha, + const void *A, + const SUITESPARSE_BLAS_INT *lda, + const void *X, + const SUITESPARSE_BLAS_INT *incx, + const void *beta, + // input/output: + void *Y, + // input: + const SUITESPARSE_BLAS_INT *incy +) ; + +#define SUITESPARSE_BLAS_cgemv(trans,m,n,alpha,A,lda,X,incx,beta,Y,incy,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCY_blas_int, incy, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_CGEMV (trans, &M_blas_int, &N_blas_int, alpha, A, \ + &LDA_blas_int, X, &INCX_blas_int, beta, Y, &INCY_blas_int) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// trsv: solve Lx=b, Ux=b, L'x=b, or U'x=b +//------------------------------------------------------------------------------ + +void SUITESPARSE_BLAS_DTRSV ( // input: const char *uplo, @@ -718,7 +840,34 @@ void SUITESPARSE_BLAS_DTRSV // solve Lx=b, Ux=b, L'x=b, or U'x=b } \ } -void SUITESPARSE_BLAS_ZTRSV // solve (L, L', L^H, U, U', or U^H)x=b +void SUITESPARSE_BLAS_STRSV +( + // input: + const char *uplo, + const char *trans, + const char *diag, + const SUITESPARSE_BLAS_INT *n, + const float *A, + const SUITESPARSE_BLAS_INT *lda, + // input/output: + float *X, + // input: + const SUITESPARSE_BLAS_INT *incx +) ; + +#define SUITESPARSE_BLAS_strsv(uplo,trans,diag,n,A,lda,X,incx,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_STRSV (uplo, trans, diag, &N_blas_int, A, \ + &LDA_blas_int, X, &INCX_blas_int) ; \ + } \ +} + +void SUITESPARSE_BLAS_ZTRSV ( // input: const char *uplo, @@ -745,7 +894,38 @@ void SUITESPARSE_BLAS_ZTRSV // solve (L, L', L^H, U, U', or U^H)x=b } \ } -void SUITESPARSE_BLAS_DTRSM // solve LX=B, UX=B, L'X=B, or U'X=B +void SUITESPARSE_BLAS_CTRSV +( + // input: + const char *uplo, + const char *trans, + const char *diag, + const SUITESPARSE_BLAS_INT *n, + const void *A, + const SUITESPARSE_BLAS_INT *lda, + // input/output: + void *X, + // input: + const SUITESPARSE_BLAS_INT *incx +) ; + +#define SUITESPARSE_BLAS_ctrsv(uplo,trans,diag,n,A,lda,X,incx,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_CTRSV (uplo, trans, diag, &N_blas_int, A, \ + &LDA_blas_int, X, &INCX_blas_int) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// trsm: solve LX=B, UX=B, L'X=B, or U'X=B +//------------------------------------------------------------------------------ + +void SUITESPARSE_BLAS_DTRSM ( // input: const char *side, @@ -776,7 +956,38 @@ void SUITESPARSE_BLAS_DTRSM // solve LX=B, UX=B, L'X=B, or U'X=B } \ } -void SUITESPARSE_BLAS_ZTRSM // solve (L, L', L^H, U, U', or U^H)X=B +void SUITESPARSE_BLAS_STRSM +( + // input: + const char *side, + const char *uplo, + const char *transa, + const char *diag, + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const float *alpha, + const float *A, + const SUITESPARSE_BLAS_INT *lda, + // input/output: + float *B, + // input: + const SUITESPARSE_BLAS_INT *ldb +) ; + +#define SUITESPARSE_BLAS_strsm(side,uplo,transa,diag,m,n,alpha,A,lda,B,ldb,ok)\ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDB_blas_int, ldb, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_STRSM (side, uplo, transa, diag, &M_blas_int, \ + &N_blas_int, alpha, A, &LDA_blas_int, B, &LDB_blas_int) ; \ + } \ +} + +void SUITESPARSE_BLAS_ZTRSM ( // input: const char *side, @@ -807,7 +1018,42 @@ void SUITESPARSE_BLAS_ZTRSM // solve (L, L', L^H, U, U', or U^H)X=B } \ } -void SUITESPARSE_BLAS_DGEMM // C = alpha*A*B + beta*C +void SUITESPARSE_BLAS_CTRSM +( + // input: + const char *side, + const char *uplo, + const char *transa, + const char *diag, + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const void *alpha, + const void *A, + const SUITESPARSE_BLAS_INT *lda, + // input/output: + void *B, + // input: + const SUITESPARSE_BLAS_INT *ldb +) ; + +#define SUITESPARSE_BLAS_ctrsm(side,uplo,transa,diag,m,n,alpha,A,lda,B,ldb,ok)\ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDB_blas_int, ldb, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_CTRSM (side, uplo, transa, diag, &M_blas_int, \ + &N_blas_int, alpha, A, &LDA_blas_int, B, &LDB_blas_int) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// gemm: C = alpha*A*B + beta*C +//------------------------------------------------------------------------------ + +void SUITESPARSE_BLAS_DGEMM ( // input: const char *transa, @@ -844,7 +1090,7 @@ void SUITESPARSE_BLAS_DGEMM // C = alpha*A*B + beta*C } \ } -void SUITESPARSE_BLAS_ZGEMM // C = alpha*A*B + beta*C +void SUITESPARSE_BLAS_SGEMM ( // input: const char *transa, @@ -852,19 +1098,19 @@ void SUITESPARSE_BLAS_ZGEMM // C = alpha*A*B + beta*C const SUITESPARSE_BLAS_INT *m, const SUITESPARSE_BLAS_INT *n, const SUITESPARSE_BLAS_INT *k, - const void *alpha, - const void *A, + const float *alpha, + const float *A, const SUITESPARSE_BLAS_INT *lda, - const void *B, + const float *B, const SUITESPARSE_BLAS_INT *ldb, - const void *beta, + const float *beta, // input/output: - void *C, + float *C, // input: const SUITESPARSE_BLAS_INT *ldc ) ; -#define SUITESPARSE_BLAS_zgemm(transa,transb,m,n,k,alpha,A,lda,B,ldb,beta, \ +#define SUITESPARSE_BLAS_sgemm(transa,transb,m,n,k,alpha,A,lda,B,ldb,beta, \ C,ldc,ok) \ { \ SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ @@ -875,52 +1121,62 @@ void SUITESPARSE_BLAS_ZGEMM // C = alpha*A*B + beta*C SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ if (ok) \ { \ - SUITESPARSE_BLAS_ZGEMM (transa, transb, &M_blas_int, &N_blas_int, \ + SUITESPARSE_BLAS_SGEMM (transa, transb, &M_blas_int, &N_blas_int, \ &K_blas_int, alpha, A, &LDA_blas_int, B, &LDB_blas_int, beta, C, \ &LDC_blas_int) ; \ } \ } -void SUITESPARSE_BLAS_DSYRK // C = alpha*A*A' + beta*C, or A'A +void SUITESPARSE_BLAS_ZGEMM ( // input: - const char *uplo, - const char *trans, + const char *transa, + const char *transb, + const SUITESPARSE_BLAS_INT *m, const SUITESPARSE_BLAS_INT *n, const SUITESPARSE_BLAS_INT *k, - const double *alpha, - const double *A, + const void *alpha, + const void *A, const SUITESPARSE_BLAS_INT *lda, - const double *beta, + const void *B, + const SUITESPARSE_BLAS_INT *ldb, + const void *beta, // input/output: - double *C, + void *C, // input: const SUITESPARSE_BLAS_INT *ldc ) ; -#define SUITESPARSE_BLAS_dsyrk(uplo,trans,n,k,alpha,A,lda,beta,C,ldc,ok) \ +#define SUITESPARSE_BLAS_zgemm(transa,transb,m,n,k,alpha,A,lda,B,ldb,beta, \ + C,ldc,ok) \ { \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDB_blas_int, ldb, ok) ; \ SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ if (ok) \ { \ - SUITESPARSE_BLAS_DSYRK (uplo, trans, &N_blas_int, &K_blas_int, alpha, \ - A, &LDA_blas_int, beta, C, &LDC_blas_int) ; \ + SUITESPARSE_BLAS_ZGEMM (transa, transb, &M_blas_int, &N_blas_int, \ + &K_blas_int, alpha, A, &LDA_blas_int, B, &LDB_blas_int, beta, C, \ + &LDC_blas_int) ; \ } \ } -void SUITESPARSE_BLAS_ZHERK // C = alpha*A*A^H + beta*C, or A^H*A +void SUITESPARSE_BLAS_CGEMM ( // input: - const char *uplo, - const char *trans, + const char *transa, + const char *transb, + const SUITESPARSE_BLAS_INT *m, const SUITESPARSE_BLAS_INT *n, const SUITESPARSE_BLAS_INT *k, const void *alpha, const void *A, const SUITESPARSE_BLAS_INT *lda, + const void *B, + const SUITESPARSE_BLAS_INT *ldb, const void *beta, // input/output: void *C, @@ -928,47 +1184,206 @@ void SUITESPARSE_BLAS_ZHERK // C = alpha*A*A^H + beta*C, or A^H*A const SUITESPARSE_BLAS_INT *ldc ) ; -#define SUITESPARSE_BLAS_zherk(uplo,trans,n,k,alpha,A,lda,beta,C,ldc,ok) \ +#define SUITESPARSE_BLAS_cgemm(transa,transb,m,n,k,alpha,A,lda,B,ldb,beta, \ + C,ldc,ok) \ { \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDB_blas_int, ldb, ok) ; \ SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ if (ok) \ { \ - SUITESPARSE_BLAS_ZHERK (uplo, trans, &N_blas_int, &K_blas_int, alpha, \ - A, &LDA_blas_int, beta, C, &LDC_blas_int) ; \ + SUITESPARSE_BLAS_CGEMM (transa, transb, &M_blas_int, &N_blas_int, \ + &K_blas_int, alpha, A, &LDA_blas_int, B, &LDB_blas_int, beta, C, \ + &LDC_blas_int) ; \ } \ } -void SUITESPARSE_LAPACK_DPOTRF // Cholesky factorization +//------------------------------------------------------------------------------ +// syrk/herk: C = alpha*A*A' + beta*C ; or C = alpha*A'*A + beta*C +//------------------------------------------------------------------------------ + +void SUITESPARSE_BLAS_DSYRK ( // input: const char *uplo, + const char *trans, const SUITESPARSE_BLAS_INT *n, + const SUITESPARSE_BLAS_INT *k, + const double *alpha, + const double *A, + const SUITESPARSE_BLAS_INT *lda, + const double *beta, // input/output: - double *A, + double *C, // input: - const SUITESPARSE_BLAS_INT *lda, - // output: - SUITESPARSE_BLAS_INT *info + const SUITESPARSE_BLAS_INT *ldc ) ; -#define SUITESPARSE_LAPACK_dpotrf(uplo,n,A,lda,info,ok) \ +#define SUITESPARSE_BLAS_dsyrk(uplo,trans,n,k,alpha,A,lda,beta,C,ldc,ok) \ { \ SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ - info = 1 ; \ + SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ if (ok) \ { \ - SUITESPARSE_BLAS_INT LAPACK_Info = -999 ; \ - SUITESPARSE_LAPACK_DPOTRF (uplo, &N_blas_int, A, &LDA_blas_int, \ - &LAPACK_Info) ; \ - info = (Int) LAPACK_Info ; \ + SUITESPARSE_BLAS_DSYRK (uplo, trans, &N_blas_int, &K_blas_int, alpha, \ + A, &LDA_blas_int, beta, C, &LDC_blas_int) ; \ } \ } -void SUITESPARSE_LAPACK_ZPOTRF // Cholesky factorization +void SUITESPARSE_BLAS_SSYRK +( + // input: + const char *uplo, + const char *trans, + const SUITESPARSE_BLAS_INT *n, + const SUITESPARSE_BLAS_INT *k, + const float *alpha, + const float *A, + const SUITESPARSE_BLAS_INT *lda, + const float *beta, + // input/output: + float *C, + // input: + const SUITESPARSE_BLAS_INT *ldc +) ; + +#define SUITESPARSE_BLAS_ssyrk(uplo,trans,n,k,alpha,A,lda,beta,C,ldc,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_SSYRK (uplo, trans, &N_blas_int, &K_blas_int, alpha, \ + A, &LDA_blas_int, beta, C, &LDC_blas_int) ; \ + } \ +} + +void SUITESPARSE_BLAS_ZHERK +( + // input: + const char *uplo, + const char *trans, + const SUITESPARSE_BLAS_INT *n, + const SUITESPARSE_BLAS_INT *k, + const void *alpha, + const void *A, + const SUITESPARSE_BLAS_INT *lda, + const void *beta, + // input/output: + void *C, + // input: + const SUITESPARSE_BLAS_INT *ldc +) ; + +#define SUITESPARSE_BLAS_zherk(uplo,trans,n,k,alpha,A,lda,beta,C,ldc,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_ZHERK (uplo, trans, &N_blas_int, &K_blas_int, alpha, \ + A, &LDA_blas_int, beta, C, &LDC_blas_int) ; \ + } \ +} + +void SUITESPARSE_BLAS_CHERK +( + // input: + const char *uplo, + const char *trans, + const SUITESPARSE_BLAS_INT *n, + const SUITESPARSE_BLAS_INT *k, + const void *alpha, + const void *A, + const SUITESPARSE_BLAS_INT *lda, + const void *beta, + // input/output: + void *C, + // input: + const SUITESPARSE_BLAS_INT *ldc +) ; + +#define SUITESPARSE_BLAS_cherk(uplo,trans,n,k,alpha,A,lda,beta,C,ldc,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_CHERK (uplo, trans, &N_blas_int, &K_blas_int, alpha, \ + A, &LDA_blas_int, beta, C, &LDC_blas_int) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// potrf: Cholesky factorization +//------------------------------------------------------------------------------ + +void SUITESPARSE_LAPACK_DPOTRF +( + // input: + const char *uplo, + const SUITESPARSE_BLAS_INT *n, + // input/output: + double *A, + // input: + const SUITESPARSE_BLAS_INT *lda, + // output: + SUITESPARSE_BLAS_INT *info +) ; + +#define SUITESPARSE_LAPACK_dpotrf(uplo,n,A,lda,info,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + info = 1 ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_INT LAPACK_Info = -999 ; \ + SUITESPARSE_LAPACK_DPOTRF (uplo, &N_blas_int, A, &LDA_blas_int, \ + &LAPACK_Info) ; \ + info = (Int) LAPACK_Info ; \ + } \ +} + +void SUITESPARSE_LAPACK_SPOTRF +( + // input: + const char *uplo, + const SUITESPARSE_BLAS_INT *n, + // input/output: + float *A, + // input: + const SUITESPARSE_BLAS_INT *lda, + // output: + SUITESPARSE_BLAS_INT *info +) ; + +#define SUITESPARSE_LAPACK_spotrf(uplo,n,A,lda,info,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + info = 1 ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_INT LAPACK_Info = -999 ; \ + SUITESPARSE_LAPACK_SPOTRF (uplo, &N_blas_int, A, &LDA_blas_int, \ + &LAPACK_Info) ; \ + info = (Int) LAPACK_Info ; \ + } \ +} + +void SUITESPARSE_LAPACK_ZPOTRF ( // input: const char *uplo, @@ -995,7 +1410,38 @@ void SUITESPARSE_LAPACK_ZPOTRF // Cholesky factorization } \ } -void SUITESPARSE_BLAS_DSCAL // Y = alpha*Y +void SUITESPARSE_LAPACK_CPOTRF +( + // input: + const char *uplo, + const SUITESPARSE_BLAS_INT *n, + // input/output: + void *A, + // input: + const SUITESPARSE_BLAS_INT *lda, + // output: + SUITESPARSE_BLAS_INT *info +) ; + +#define SUITESPARSE_LAPACK_cpotrf(uplo,n,A,lda,info,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + info = 1 ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_INT LAPACK_Info = -999 ; \ + SUITESPARSE_LAPACK_CPOTRF (uplo, &N_blas_int, A, &LDA_blas_int, \ + &LAPACK_Info) ; \ + info = LAPACK_Info ; \ + } \ +} + +//------------------------------------------------------------------------------ +// scal: Y = alpha*Y +//------------------------------------------------------------------------------ + +void SUITESPARSE_BLAS_DSCAL ( // input: const SUITESPARSE_BLAS_INT *n, @@ -1016,7 +1462,28 @@ void SUITESPARSE_BLAS_DSCAL // Y = alpha*Y } \ } -void SUITESPARSE_BLAS_ZSCAL // Y = alpha*Y +void SUITESPARSE_BLAS_SSCAL +( + // input: + const SUITESPARSE_BLAS_INT *n, + const float *alpha, + // input/output: + float *Y, + // input: + const SUITESPARSE_BLAS_INT *incy +) ; + +#define SUITESPARSE_BLAS_sscal(n,alpha,Y,incy,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCY_blas_int, incy, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_SSCAL (&N_blas_int, alpha, Y, &INCY_blas_int) ; \ + } \ +} + +void SUITESPARSE_BLAS_ZSCAL ( // input: const SUITESPARSE_BLAS_INT *n, @@ -1037,7 +1504,32 @@ void SUITESPARSE_BLAS_ZSCAL // Y = alpha*Y } \ } -void SUITESPARSE_BLAS_DGER // A = alpha*x*y' + A +void SUITESPARSE_BLAS_CSCAL +( + // input: + const SUITESPARSE_BLAS_INT *n, + const void *alpha, + // input/output: + void *Y, + // input: + const SUITESPARSE_BLAS_INT *incy +) ; + +#define SUITESPARSE_BLAS_cscal(n,alpha,Y,incy,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCY_blas_int, incy, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_CSCAL (&N_blas_int, alpha, Y, &INCY_blas_int) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// ger/geru: A = alpha*x*y' + A +//------------------------------------------------------------------------------ + +void SUITESPARSE_BLAS_DGER ( // input: const SUITESPARSE_BLAS_INT *m, @@ -1067,7 +1559,37 @@ void SUITESPARSE_BLAS_DGER // A = alpha*x*y' + A } \ } -void SUITESPARSE_BLAS_ZGERU // A = alpha*x*y' + A +void SUITESPARSE_BLAS_SGER +( + // input: + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const float *alpha, + const float *X, + const SUITESPARSE_BLAS_INT *incx, + const float *Y, + const SUITESPARSE_BLAS_INT *incy, + // input/output: + float *A, + // input: + const SUITESPARSE_BLAS_INT *lda +) ; + +#define SUITESPARSE_BLAS_sger(m,n,alpha,X,incx,Y,incy,A,lda,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCY_blas_int, incy, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_SGER (&M_blas_int, &N_blas_int, alpha, X, \ + &INCX_blas_int, Y, &INCY_blas_int, A, &LDA_blas_int) ; \ + } \ +} + +void SUITESPARSE_BLAS_ZGERU ( // input: const SUITESPARSE_BLAS_INT *m, @@ -1097,7 +1619,41 @@ void SUITESPARSE_BLAS_ZGERU // A = alpha*x*y' + A } \ } -void SUITESPARSE_LAPACK_DLARFT // T = block Householder factor +void SUITESPARSE_BLAS_CGERU +( + // input: + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const void *alpha, + const void *X, + const SUITESPARSE_BLAS_INT *incx, + const void *Y, + const SUITESPARSE_BLAS_INT *incy, + // input/output: + void *A, + // input: + const SUITESPARSE_BLAS_INT *lda +) ; + +#define SUITESPARSE_BLAS_cgeru(m,n,alpha,X,incx,Y,incy,A,lda,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCY_blas_int, incy, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDA_blas_int, lda, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_BLAS_CGERU (&M_blas_int, &N_blas_int, alpha, X, \ + &INCX_blas_int, Y, &INCY_blas_int, A, &LDA_blas_int) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// larft: T = block Householder factor +//------------------------------------------------------------------------------ + +void SUITESPARSE_LAPACK_DLARFT ( // input: const char *direct, @@ -1126,7 +1682,36 @@ void SUITESPARSE_LAPACK_DLARFT // T = block Householder factor } \ } -void SUITESPARSE_LAPACK_ZLARFT // T = block Householder factor +void SUITESPARSE_LAPACK_SLARFT +( + // input: + const char *direct, + const char *storev, + const SUITESPARSE_BLAS_INT *n, + const SUITESPARSE_BLAS_INT *k, + const float *V, + const SUITESPARSE_BLAS_INT *ldv, + const float *Tau, + // output: + float *T, + // input: + const SUITESPARSE_BLAS_INT *ldt +) ; + +#define SUITESPARSE_LAPACK_slarft(direct,storev,n,k,V,ldv,Tau,T,ldt,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDV_blas_int, ldv, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDT_blas_int, ldt, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_LAPACK_SLARFT (direct, storev, &N_blas_int, &K_blas_int, \ + V, &LDV_blas_int, Tau, T, &LDT_blas_int) ; \ + } \ +} + +void SUITESPARSE_LAPACK_ZLARFT ( // input: const char *direct, @@ -1155,7 +1740,40 @@ void SUITESPARSE_LAPACK_ZLARFT // T = block Householder factor } \ } -void SUITESPARSE_LAPACK_DLARFB // apply block Householder reflector +void SUITESPARSE_LAPACK_CLARFT +( + // input: + const char *direct, + const char *storev, + const SUITESPARSE_BLAS_INT *n, + const SUITESPARSE_BLAS_INT *k, + const void *V, + const SUITESPARSE_BLAS_INT *ldv, + const void *Tau, + // output: + void *T, + // input: + const SUITESPARSE_BLAS_INT *ldt +) ; + +#define SUITESPARSE_LAPACK_clarft(direct,storev,n,k,V,ldv,Tau,T,ldt,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDV_blas_int, ldv, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDT_blas_int, ldt, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_LAPACK_CLARFT (direct, storev, &N_blas_int, &K_blas_int, \ + V, &LDV_blas_int, Tau, T, &LDT_blas_int) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// larfb: apply block Householder reflector +//------------------------------------------------------------------------------ + +void SUITESPARSE_LAPACK_DLARFB ( // input: const char *side, @@ -1197,7 +1815,49 @@ void SUITESPARSE_LAPACK_DLARFB // apply block Householder reflector } \ } -void SUITESPARSE_LAPACK_ZLARFB // apply block Householder reflector +void SUITESPARSE_LAPACK_SLARFB +( + // input: + const char *side, + const char *trans, + const char *direct, + const char *storev, + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const SUITESPARSE_BLAS_INT *k, + const float *V, + const SUITESPARSE_BLAS_INT *ldv, + const float *T, + const SUITESPARSE_BLAS_INT *ldt, + // input/output: + float *C, + // input: + const SUITESPARSE_BLAS_INT *ldc, + // workspace: + float *Work, + // input: + const SUITESPARSE_BLAS_INT *ldwork +) ; + +#define SUITESPARSE_LAPACK_slarfb(side,trans,direct,storev,m,n,k,V,ldv,T,ldt, \ + C,ldc,Work,ldwork,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDV_blas_int, ldv, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDT_blas_int, ldt, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDWORK_blas_int, ldwork, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_LAPACK_SLARFB (side, trans, direct, storev, &M_blas_int, \ + &N_blas_int, &K_blas_int, V, &LDV_blas_int, T, &LDT_blas_int, C, \ + &LDC_blas_int, Work, &LDWORK_blas_int) ; \ + } \ +} + +void SUITESPARSE_LAPACK_ZLARFB ( // input: const char *side, @@ -1239,7 +1899,53 @@ void SUITESPARSE_LAPACK_ZLARFB // apply block Householder reflector } \ } -double SUITESPARSE_BLAS_DNRM2 // vector 2-norm +void SUITESPARSE_LAPACK_CLARFB +( + // input: + const char *side, + const char *trans, + const char *direct, + const char *storev, + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const SUITESPARSE_BLAS_INT *k, + const void *V, + const SUITESPARSE_BLAS_INT *ldv, + const void *T, + const SUITESPARSE_BLAS_INT *ldt, + // input/output: + void *C, + // input: + const SUITESPARSE_BLAS_INT *ldc, + // workspace: + void *Work, + // input: + const SUITESPARSE_BLAS_INT *ldwork +) ; + +#define SUITESPARSE_LAPACK_clarfb(side,trans,direct,storev,m,n,k,V,ldv,T,ldt, \ + C,ldc,Work,ldwork,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (K_blas_int, k, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDV_blas_int, ldv, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDT_blas_int, ldt, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDWORK_blas_int, ldwork, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_LAPACK_CLARFB (side, trans, direct, storev, &M_blas_int, \ + &N_blas_int, &K_blas_int, V, &LDV_blas_int, T, &LDT_blas_int, C, \ + &LDC_blas_int, Work, &LDWORK_blas_int) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// nrm2: vector 2-norm +//------------------------------------------------------------------------------ + +double SUITESPARSE_BLAS_DNRM2 ( // input: const SUITESPARSE_BLAS_INT *n, @@ -1258,7 +1964,26 @@ double SUITESPARSE_BLAS_DNRM2 // vector 2-norm } \ } -double SUITESPARSE_BLAS_DZNRM2 // vector 2-norm +float SUITESPARSE_BLAS_SNRM2 +( + // input: + const SUITESPARSE_BLAS_INT *n, + const float *X, + const SUITESPARSE_BLAS_INT *incx +) ; + +#define SUITESPARSE_BLAS_snrm2(result,n,X,incx,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + result = 0 ; \ + if (ok) \ + { \ + result = SUITESPARSE_BLAS_SNRM2 (&N_blas_int, X, &INCX_blas_int) ; \ + } \ +} + +double SUITESPARSE_BLAS_DZNRM2 ( // input: const SUITESPARSE_BLAS_INT *n, @@ -1277,7 +2002,30 @@ double SUITESPARSE_BLAS_DZNRM2 // vector 2-norm } \ } -void SUITESPARSE_LAPACK_DLARFG // generate Householder reflector +float SUITESPARSE_BLAS_SCNRM2 +( + // input: + const SUITESPARSE_BLAS_INT *n, + const void *X, + const SUITESPARSE_BLAS_INT *incx +) ; + +#define SUITESPARSE_BLAS_scnrm2(result,n,X,incx,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + result = 0 ; \ + if (ok) \ + { \ + result = SUITESPARSE_BLAS_SCNRM2 (&N_blas_int, X, &INCX_blas_int) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// larfg: generate Householder reflector +//------------------------------------------------------------------------------ + +void SUITESPARSE_LAPACK_DLARFG ( // input: const SUITESPARSE_BLAS_INT *n, @@ -1301,7 +2049,31 @@ void SUITESPARSE_LAPACK_DLARFG // generate Householder reflector } \ } -void SUITESPARSE_LAPACK_ZLARFG // generate Householder reflector +void SUITESPARSE_LAPACK_SLARFG +( + // input: + const SUITESPARSE_BLAS_INT *n, + // input/output: + float *alpha, + float *X, + // input: + const SUITESPARSE_BLAS_INT *incx, + // output: + float *tau +) ; + +#define SUITESPARSE_LAPACK_slarfg(n,alpha,X,incx,tau,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_LAPACK_SLARFG (&N_blas_int, alpha, X, &INCX_blas_int, \ + tau) ; \ + } \ +} + +void SUITESPARSE_LAPACK_ZLARFG ( // input: const SUITESPARSE_BLAS_INT *n, @@ -1325,7 +2097,35 @@ void SUITESPARSE_LAPACK_ZLARFG // generate Householder reflector } \ } -void SUITESPARSE_LAPACK_DLARF // apply Householder reflector +void SUITESPARSE_LAPACK_CLARFG +( + // input: + const SUITESPARSE_BLAS_INT *n, + // input/output: + void *alpha, + void *X, + // input: + const SUITESPARSE_BLAS_INT *incx, + // output: + void *tau +) ; + +#define SUITESPARSE_LAPACK_clarfg(n,alpha,X,incx,tau,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCX_blas_int, incx, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_LAPACK_CLARFG (&N_blas_int, alpha, X, &INCX_blas_int, \ + tau) ; \ + } \ +} + +//------------------------------------------------------------------------------ +// larf: apply Householder reflector +//------------------------------------------------------------------------------ + +void SUITESPARSE_LAPACK_DLARF ( // input: const char *side, @@ -1355,7 +2155,37 @@ void SUITESPARSE_LAPACK_DLARF // apply Householder reflector } \ } -void SUITESPARSE_LAPACK_ZLARF // apply Householder reflector +void SUITESPARSE_LAPACK_SLARF +( + // input: + const char *side, + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const float *V, + const SUITESPARSE_BLAS_INT *incv, + const float *tau, + // input/output: + float *C, + // input: + const SUITESPARSE_BLAS_INT *ldc, + // workspace: + float *Work +) ; + +#define SUITESPARSE_LAPACK_slarf(side,m,n,V,incv,tau,C,ldc,Work,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCV_blas_int, incv, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_LAPACK_SLARF (side, &M_blas_int, &N_blas_int, V, \ + &INCV_blas_int, tau, C, &LDC_blas_int, Work) ; \ + } \ +} + +void SUITESPARSE_LAPACK_ZLARF ( // input: const char *side, @@ -1385,6 +2215,36 @@ void SUITESPARSE_LAPACK_ZLARF // apply Householder reflector } \ } +void SUITESPARSE_LAPACK_CLARF +( + // input: + const char *side, + const SUITESPARSE_BLAS_INT *m, + const SUITESPARSE_BLAS_INT *n, + const void *V, + const SUITESPARSE_BLAS_INT *incv, + const void *tau, + // input/output: + void *C, + // input: + const SUITESPARSE_BLAS_INT *ldc, + // workspace: + void *Work +) ; + +#define SUITESPARSE_LAPACK_clarf(side,m,n,V,incv,tau,C,ldc,Work,ok) \ +{ \ + SUITESPARSE_TO_BLAS_INT (M_blas_int, m, ok) ; \ + SUITESPARSE_TO_BLAS_INT (N_blas_int, n, ok) ; \ + SUITESPARSE_TO_BLAS_INT (INCV_blas_int, incv, ok) ; \ + SUITESPARSE_TO_BLAS_INT (LDC_blas_int, ldc, ok) ; \ + if (ok) \ + { \ + SUITESPARSE_LAPACK_CLARF (side, &M_blas_int, &N_blas_int, V, \ + &INCV_blas_int, tau, C, &LDC_blas_int, Work) ; \ + } \ +} + #endif //------------------------------------------------------------------------------ diff --git a/SuiteSparse_config/cmake_modules/FindSuiteSparse_config.cmake b/SuiteSparse_config/cmake_modules/FindSuiteSparse_config.cmake deleted file mode 100644 index b9859150..00000000 --- a/SuiteSparse_config/cmake_modules/FindSuiteSparse_config.cmake +++ /dev/null @@ -1,141 +0,0 @@ -#------------------------------------------------------------------------------- -# SuiteSparse/SuiteSparse_config/cmake_modules/FindSuiteSparse_config.cmake -#------------------------------------------------------------------------------- - -# The following copyright and license applies to just this file only, not to -# the library itself: -# FindSuiteSparse_config.cmake, Copyright (c) 2022-2023, Timothy A. Davis. All Rights Reserved. -# SPDX-License-Identifier: BSD-3-clause - -#------------------------------------------------------------------------------- - -# Finds the SuiteSparse_config include file and compiled library and sets: - -# SUITESPARSE_CONFIG_INCLUDE_DIR - where to find SuiteSparse_config.h -# SUITESPARSE_CONFIG_LIBRARY - dynamic SuiteSparse_config library -# SUITESPARSE_CONFIG_STATIC - static SuiteSparse_config library -# SUITESPARSE_CONFIG_LIBRARIES - libraries when using SuiteSparse_config -# SUITESPARSE_CONFIG_FOUND - true if SuiteSparse_config found - -# set ``SUITESPARSE_CONFIG_ROOT`` or ``SuiteSparse_config_ROOT`` to a -# SuiteSparse_config installation root to tell this module where to look. - -# 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: -# -# set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} -# ${CMAKE_INSTALL_PREFIX}/lib/cmake/SuiteSparse ) - -#------------------------------------------------------------------------------- - -# include files for SuiteSparse_config -find_path ( SUITESPARSE_CONFIG_INCLUDE_DIR - NAMES SuiteSparse_config.h - HINTS ${SUITESPARSE_CONFIG_ROOT} - HINTS ENV SUITESPARSE_CONFIG_ROOT - HINTS ${CMAKE_SOURCE_DIR}/.. - HINTS ${CMAKE_SOURCE_DIR}/../SuiteSparse/SuiteSparse_config - HINTS ${CMAKE_SOURCE_DIR}/../SuiteSparse_config - PATH_SUFFIXES include Include -) - -# dynamic SuiteSparse_config (or static if no dynamic library was built) -find_library ( SUITESPARSE_CONFIG_LIBRARY - NAMES suitesparseconfig suitesparseconfig_static - HINTS ${SUITESPARSE_CONFIG_ROOT} - HINTS ENV SUITESPARSE_CONFIG_ROOT - HINTS ${CMAKE_SOURCE_DIR}/.. - HINTS ${CMAKE_SOURCE_DIR}/../SuiteSparse/SuiteSparse_config - HINTS ${CMAKE_SOURCE_DIR}/../SuiteSparse_config - PATH_SUFFIXES lib build build/Release build/Debug -) - -if ( MSVC ) - set ( STATIC_NAME suitesparseconfig_static suitesparseconfig ) -else ( ) - set ( STATIC_NAME suitesparseconfig ) - set ( save ${CMAKE_FIND_LIBRARY_SUFFIXES} ) - message ( STATUS "original library suffixes: ${CMAKE_FIND_LIBRARY_SUFFIXES}" ) - set ( CMAKE_FIND_LIBRARY_SUFFIXES - ${CMAKE_STATIC_LIBRARY_SUFFIX} ${CMAKE_FIND_LIBRARY_SUFFIXES} ) - message ( STATUS "revised for static search: ${CMAKE_FIND_LIBRARY_SUFFIXES}" ) -endif ( ) - -# static libraries for SuiteSparse_config -find_library ( SUITESPARSE_CONFIG_STATIC - NAMES ${STATIC_NAME} - HINTS ${SUITESPARSE_CONFIG_ROOT} - HINTS ENV SUITESPARSE_CONFIG_ROOT - HINTS ${CMAKE_SOURCE_DIR}/.. - HINTS ${CMAKE_SOURCE_DIR}/../SuiteSparse/SuiteSparse_config - HINTS ${CMAKE_SOURCE_DIR}/../SuiteSparse_config - PATH_SUFFIXES lib build build/Release build/Debug -) - -if ( NOT MSVC ) - # restore the CMAKE_FIND_LIBRARY_SUFFIXES variable - set ( CMAKE_FIND_LIBRARY_SUFFIXES ${save} ) -endif ( ) - -# get version of the library from the dynamic library filename, if present -get_filename_component ( SUITESPARSE_CONFIG_LIBRARY ${SUITESPARSE_CONFIG_LIBRARY} REALPATH ) -get_filename_component ( SUITESPARSE_CONFIG_FILENAME ${SUITESPARSE_CONFIG_LIBRARY} NAME ) -string ( - REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" - SUITESPARSE_CONFIG_VERSION - ${SUITESPARSE_CONFIG_FILENAME} -) - -# set ( SUITESPARSE_CONFIG_VERSION "" ) -if ( EXISTS "${SUITESPARSE_CONFIG_INCLUDE_DIR}" AND NOT SUITESPARSE_CONFIG_VERSION ) - # if the version does not appear in the filename, read the include file - file ( STRINGS ${SUITESPARSE_CONFIG_INCLUDE_DIR}/SuiteSparse_config.h SUITESPARSE_CONFIG_MAJOR_STR - REGEX "define SUITESPARSE_MAIN_VERSION" ) - file ( STRINGS ${SUITESPARSE_CONFIG_INCLUDE_DIR}/SuiteSparse_config.h SUITESPARSE_CONFIG_MINOR_STR - REGEX "define SUITESPARSE_SUB_VERSION" ) - file ( STRINGS ${SUITESPARSE_CONFIG_INCLUDE_DIR}/SuiteSparse_config.h SUITESPARSE_CONFIG_PATCH_STR - REGEX "define SUITESPARSE_SUBSUB_VERSION" ) - message ( STATUS "major: ${SUITESPARSE_CONFIG_MAJOR_STR}" ) - message ( STATUS "minor: ${SUITESPARSE_CONFIG_MINOR_STR}" ) - message ( STATUS "patch: ${SUITESPARSE_CONFIG_PATCH_STR}" ) - string ( REGEX MATCH "[0-9]+" SUITESPARSE_CONFIG_MAJOR ${SUITESPARSE_CONFIG_MAJOR_STR} ) - string ( REGEX MATCH "[0-9]+" SUITESPARSE_CONFIG_MINOR ${SUITESPARSE_CONFIG_MINOR_STR} ) - string ( REGEX MATCH "[0-9]+" SUITESPARSE_CONFIG_PATCH ${SUITESPARSE_CONFIG_PATCH_STR} ) - set (SUITESPARSE_CONFIG_VERSION "${SUITESPARSE_CONFIG_MAJOR}.${SUITESPARSE_CONFIG_MINOR}.${SUITESPARSE_CONFIG_PATCH}") -endif ( ) - -# libaries when using SuiteSparse_config -set (SUITESPARSE_CONFIG_LIBRARIES ${SUITESPARSE_CONFIG_LIBRARY}) - -include ( FindPackageHandleStandardArgs ) - -find_package_handle_standard_args ( SuiteSparse_config - REQUIRED_VARS SUITESPARSE_CONFIG_LIBRARY SUITESPARSE_CONFIG_INCLUDE_DIR - VERSION_VAR SUITESPARSE_CONFIG_VERSION - REASON_FAILURE_MESSAGE result -) - -message (STATUS "result: ${result}") - -mark_as_advanced ( - SUITESPARSE_CONFIG_INCLUDE_DIR - SUITESPARSE_CONFIG_LIBRARY - SUITESPARSE_CONFIG_STATIC - SUITESPARSE_CONFIG_LIBRARIES -) - -if ( SUITESPARSE_CONFIG_FOUND ) - message ( STATUS "SuiteSparse_config version: ${SUITESPARSE_CONFIG_VERSION}" ) - message ( STATUS "SuiteSparse_config include: ${SUITESPARSE_CONFIG_INCLUDE_DIR}" ) - message ( STATUS "SuiteSparse_config library: ${SUITESPARSE_CONFIG_LIBRARY}" ) - message ( STATUS "SuiteSparse_config static: ${SUITESPARSE_CONFIG_STATIC}" ) -else ( ) - message ( STATUS "SuiteSparse_config not found" ) - set ( SUITESPARSE_CONFIG_INCLUDE_DIR "" ) - set ( SUITESPARSE_CONFIG_LIBRARIES "" ) - set ( SUITESPARSE_CONFIG_LIBRARY "" ) - set ( SUITESPARSE_CONFIG_STATIC "" ) -endif ( ) - diff --git a/SuiteSparse_config/cmake_modules/SuiteSparseBLAS.cmake b/SuiteSparse_config/cmake_modules/SuiteSparseBLAS.cmake index 9e4b779a..adcd4266 100644 --- a/SuiteSparse_config/cmake_modules/SuiteSparseBLAS.cmake +++ b/SuiteSparse_config/cmake_modules/SuiteSparseBLAS.cmake @@ -24,13 +24,24 @@ endif ( ) set ( BLA_VENDOR "ANY" CACHE STRING "if ANY (default): searches for any BLAS. Otherwise: search for a specific BLAS" ) -# To allow the use of a BLAS with 64-bit integers, set this to true -option ( ALLOW_64BIT_BLAS - "OFF (default): use only 32-bit BLAS. ON: look for 32 or 64-bit BLAS" off ) +# To allow the use of a BLAS with 64-bit integers, set this to ON +option ( SUITESPARSE_USE_64BIT_BLAS + "OFF (default): use only 32-bit BLAS. ON: look for 32 or 64-bit BLAS" OFF ) # dynamic/static linking with BLAS option ( BLA_STATIC - "OFF (default): dynamic linking of BLAS. ON: static linking of BLAS" off ) + "OFF (default): dynamic linking of BLAS. ON: static linking of BLAS" OFF ) + +if ( DEFINED BLAS_LIBRARIES OR DEFINED BLAS_INCLUDE_DIRS ) + # User supplied variables for libraries and/or include directories. + # Use them as-is. + if ( SUITESPARSE_USE_64BIT_BLAS ) + include ( SuiteSparseBLAS64 ) + else ( ) + include ( SuiteSparseBLAS32 ) + endif ( ) + return ( ) +endif ( ) #------------------------------------------------------------------------------- # look for a specific BLAS library @@ -39,32 +50,34 @@ option ( BLA_STATIC # To request specific BLAS, use either (for example): # # CMAKE_OPTIONS="-DBLA_VENDOR=Apple" make -# cd build ; cmake -DBLA_VENDOR=Apple .. ; make +# cd build && cmake -DBLA_VENDOR=Apple .. ; make # -# Use the ALLOW_64BIT_BLAS to select 64-bit or 32-bit BLAS. This setting is -# strictly enforced. If set to true, then only a 64-bit BLAS is allowed. -# If this is not found, no 32-bit BLAS is considered, and the build will fail. +# Use SUITESPARSE_USE_64BIT_BLAS to select 64-bit or 32-bit BLAS. If +# BLA_VENDOR is also defined, this setting is strictly enforced. If set to +# ON, then only a 64-bit BLAS is allowed. If this is not found, no 32-bit +# BLAS is considered, and the build will fail. # -# If the BLA_VENDOR string implies a 64-bit BLAS, then ALLOW_64BIT_BLAS is set -# to true, ignoring the setting from the user (Intel10_64ilp* and Arm_64ilp*). +# If the BLA_VENDOR string implies a 64-bit BLAS, then +# SUITESPARSE_USE_64BIT_BLAS is set to ON, ignoring the setting of this value +# from the user (Intel10_64ilp* and Arm_64ilp*). # -# The default for ALLOW_64BIT_BLAS is false. +# The default for SUITESPARSE_USE_64BIT_BLAS is OFF. if ( NOT (BLA_VENDOR STREQUAL "ANY" ) ) # only look for the BLAS from a single vendor if ( ( BLA_VENDOR MATCHES "64ilp" ) OR ( BLA_VENDOR MATCHES "ilp64" ) ) # Intel10_64ilp* or Arm_ilp64* - set ( ALLOW_64BIT_BLAS true ) + set ( SUITESPARSE_USE_64BIT_BLAS ON ) # OK; overidden by BLA_VENDOR endif ( ) - if ( ALLOW_64BIT_BLAS ) + if ( SUITESPARSE_USE_64BIT_BLAS ) # only look for 64-bit BLAS set ( BLA_SIZEOF_INTEGER 8 ) message ( STATUS "Looking for 64-BLAS: " ${BLA_VENDOR} ) else ( ) # only look for 32-bit BLAS - message ( STATUS "Looking for 32-BLAS: " ${BLA_VENDOR} ) set ( BLA_SIZEOF_INTEGER 4 ) + message ( STATUS "Looking for 32-BLAS: " ${BLA_VENDOR} ) endif ( ) find_package ( BLAS REQUIRED ) if ( BLA_SIZEOF_INTEGER EQUAL 8 ) @@ -76,6 +89,7 @@ if ( NOT (BLA_VENDOR STREQUAL "ANY" ) ) include ( SuiteSparseBLAS32 ) endif ( ) message ( STATUS "Specific BLAS: ${BLA_VENDOR} found: ${BLAS_FOUND}" ) + message ( STATUS "BLAS integer size: ${BLA_SIZEOF_INTEGER}" ) return ( ) endif ( ) @@ -83,10 +97,19 @@ endif ( ) # Look for any 64-bit BLAS, if allowed #------------------------------------------------------------------------------- -# If ALLOW_64BIT_BLAS is true, then a 64-bit BLAS is preferred. -# If not found, a 32-bit BLAS is sought (below) +# If SUITESPARSE_USE_64BIT_BLAS is ON and SUITESPARSE_USE_STRICT is OFF, then a +# 64-bit BLAS is preferred. If not found, a 32-bit BLAS is sought. +# The setting of SUITESPARSE_USE_64BIT_BLAS not strict by default. + +# If SUITESPARSE_USE_64BIT_BLAS is ON and SUITESPARSE_USE_STRICT is ON, then a +# only a 64-bit BLAS is considered. An error occurs if a 64-bit BLAS is not +# found. -if ( ALLOW_64BIT_BLAS ) +# If SUITESPARSE_USE_64BIT_BLAS is OFF, only a 32-bit BLAS is considered. An +# error occurs if a 32-bit BLAS is not found (the SUITESPARSE_USE_STRICT +# setting is ignored). + +if ( SUITESPARSE_USE_64BIT_BLAS ) # Look for Intel MKL BLAS with 64-bit integers message ( STATUS "Looking for Intel 64-bit BLAS" ) @@ -139,6 +162,11 @@ if ( ALLOW_64BIT_BLAS ) return ( ) endif ( ) + # report an error if strict + if ( SUITESPARSE_USE_STRICT ) + message ( FATAL_ERROR "64-bit BLAS required, but not found" ) + endif ( ) + endif ( ) #------------------------------------------------------------------------------- diff --git a/SuiteSparse_config/cmake_modules/SuiteSparseBLAS64.cmake b/SuiteSparse_config/cmake_modules/SuiteSparseBLAS64.cmake index 744aaef9..72efcd5c 100644 --- a/SuiteSparse_config/cmake_modules/SuiteSparseBLAS64.cmake +++ b/SuiteSparse_config/cmake_modules/SuiteSparseBLAS64.cmake @@ -25,19 +25,19 @@ set ( SuiteSparse_BLAS_integer "int64_t" ) # If the suffix does not contain "_", use (Sun Perf., for example): -# cd build ; cmake -DBLAS64_SUFFIX="64" .. +# cd build && cmake -DBLAS64_SUFFIX="64" .. # If the suffix contains "_" (OpenBLAS in spack for example), use the # following: -# cd build ; cmake -DBLAS64_SUFFIX="_64" .. +# cd build && cmake -DBLAS64_SUFFIX="_64" .. # This setting could be used by the spack packaging of SuiteSparse when linked # with the spack-installed OpenBLAS with 64-bit integers. See # https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/suite-sparse/package.py if ( DEFINED BLAS64_SUFFIX ) - # append BLAS64_SUFFIX to each BLAS and LAPACK name + # append BLAS64_SUFFIX to each BLAS and LAPACK function name string ( FIND ${BLAS64_SUFFIX} "_" HAS_UNDERSCORE ) message ( STATUS "BLAS64_suffix: ${BLAS64_SUFFIX}" ) if ( HAS_UNDERSCORE EQUAL -1 ) diff --git a/SuiteSparse_config/cmake_modules/SuiteSparseLAPACK.cmake b/SuiteSparse_config/cmake_modules/SuiteSparseLAPACK.cmake index 27ff73ca..82366e0a 100644 --- a/SuiteSparse_config/cmake_modules/SuiteSparseLAPACK.cmake +++ b/SuiteSparse_config/cmake_modules/SuiteSparseLAPACK.cmake @@ -20,18 +20,19 @@ cmake_minimum_required ( VERSION 3.22 ) -if ( BLA_VENDOR STREQUAL "FLAME" ) - # FLAME has the BLAS but not LAPACK +if ( DEFINED LAPACK_LIBRARIES OR DEFINED LAPACK_INCLUDE_DIRS ) + # User supplied variables for libraries and/or include directories. + # Use them as-is. + return ( ) +endif ( ) - set ( BLA_VENDOR "Generic" ) - message ( STATUS "Looking for generic LAPACK to use with BLIS/FLAME BLAS" ) +if ( BLA_VENDOR STREQUAL "FLAME" ) - # look for the generic dynamic LAPACK library (usually liblagraph.so) find_library ( LAPACK_LIBRARY - NAMES lapack + NAMES flame PATH_SUFFIXES lib build ) - # look for the static LAPACK library (usually liblagraph.a) + # look for the static LAPACK library (usually liblapack.a) if ( MSVC ) set ( STATIC_SUFFIX .lib ) else ( ) diff --git a/SuiteSparse_config/cmake_modules/SuiteSparsePolicy.cmake b/SuiteSparse_config/cmake_modules/SuiteSparsePolicy.cmake index 88f956a3..b6b19540 100644 --- a/SuiteSparse_config/cmake_modules/SuiteSparsePolicy.cmake +++ b/SuiteSparse_config/cmake_modules/SuiteSparsePolicy.cmake @@ -14,22 +14,25 @@ # To use the "Debug" policy, precede this with # set ( CMAKE_BUILD_TYPE Debug ) # -# ENABLE_CUDA: if set to true, CUDA is enabled for the project. -# Default: true for CHOLMOD and SPQR, false for GraphBLAS -# (for which CUDA is in progress and not ready for -# production use). +# SUITESPARSE_USE_CUDA: if OFF, CUDA is disabled. if ON, CUDA is enabled, +# if available. Default: ON. # -# LOCAL_INSTALL: if true, "cmake --install" will install +# 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). -# Default: false +# CMAKE_INSTALL_PREFIX). Requires cmake 3.19. +# This is ignored when using the root CMakeLists.txt. +# Set CMAKE_INSTALL_PREFIX instead. +# Default: OFF # -# NSTATIC: if true, static libraries are not built. -# Default: false, except for GraphBLAS, which +# 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 true. +# GraphBLAS is false. # # SUITESPARSE_CUDA_ARCHITECTURES: a string, such as "all" or # "35;50;75;80" that lists the CUDA architectures to use @@ -45,12 +48,12 @@ # Both settings must appear, or neither. # Default: neither are defined. # -# BLA_STATIC: if true, use static linkage for BLAS and LAPACK. -# Default: false +# BLA_STATIC: if ON, use static linkage for BLAS and LAPACK. +# Default: not set (that is, the same as OFF) # -# ALLOW_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 +# 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. @@ -61,30 +64,64 @@ # This setting is only used if no Fortran compiler is # found. # -# NFORTRAN: if true, 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: false - -cmake_minimum_required ( VERSION 3.19 ) - -message ( STATUS "Source: ${CMAKE_SOURCE_DIR} ") -message ( STATUS "Build: ${CMAKE_BINARY_DIR} ") +# 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 ( ) -cmake_policy ( SET CMP0042 NEW ) # enable MACOSX_RPATH by default -cmake_policy ( SET CMP0048 NEW ) # VERSION variable policy -cmake_policy ( SET CMP0054 NEW ) # if ( expression ) handling policy -cmake_policy ( SET CMP0104 NEW ) # initialize CUDA architectures +# SuiteSparse packages have many intentional extra semicolons, for code +# readability (such as "/* do nothing */ ;" in SuiteSparse_config.c). Disable +# the clang warning for these statements: +if ( CMAKE_C_COMPILER_ID STREQUAL "Clang" ) + set ( CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Wno-extra-semi-stmt" ) +endif ( ) +if ( CMAKE_CXX_COMPILER_ID STREQUAL "Clang" ) + set ( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wno-extra-semi-stmt" ) +endif ( ) if ( WIN32 ) set ( CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS true ) add_compile_definitions ( _CRT_SECURE_NO_WARNINGS ) endif ( ) -set ( CMAKE_MACOSX_RPATH TRUE ) enable_language ( C ) include ( GNUInstallDirs ) @@ -92,15 +129,40 @@ include ( GNUInstallDirs ) set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake_modules ) -# NSTATIC option -if ( NSTATIC_DEFAULT_ON ) - option ( NSTATIC "ON (default): do not build static libraries. OFF: build static libraries" on ) +# Use OpenMP +option ( SUITESPARSE_USE_OPENMP "ON (default): Use OpenMP in libraries by default if available. OFF: Do not use OpenMP by default." 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 ( ) - option ( NSTATIC "ON: do not build static libraries. OFF (default): build static libraries" off ) + # 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 -option ( LOCAL_INSTALL "Install in SuiteSparse/lib" off ) +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 @@ -112,94 +174,127 @@ else ( ) ${CMAKE_SOURCE_DIR}/../lib/cmake ) endif ( ) -# add the ./build folder to the runpath so other SuiteSparse packages can -# find this one without "make install" -set ( CMAKE_BUILD_RPATH ${CMAKE_BUILD_RPATH} ${CMAKE_BINARY_DIR} ) - -# determine if this Package is inside the SuiteSparse folder -set ( INSIDE_SUITESPARSE false ) -if ( LOCAL_INSTALL ) - # if you do not want to install local copies of SuiteSparse - # packages in SuiteSparse/lib and SuiteSparse/, set - # 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 ) +# 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 ( ) - 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 ) + + if ( NOT INSIDE_SUITESPARSE ) + message ( FATAL_ERROR "Unsupported layout for local installation. Correct the directory layout or unset SUITESPARSE_LOCAL_INSTALL." ) endif ( ) - endif ( ) - if ( NOT INSIDE_SUITESPARSE ) - message ( FATAL_ERROR "Unsupported layout for local installation. Correct the directory layout or unset LOCAL_INSTALL." ) endif ( ) - endif ( ) -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_INCLUDEDIR_POSTFIX "suitesparse" CACHE STRING + "Postfix for installation target of header from SuiteSparse (default: \"suitesparse\")" ) -if ( LOCAL_INSTALL ) +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 ) + 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} ) + 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 - set ( CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_RPATH} ${SUITESPARSE_LIBDIR} ) - set ( CMAKE_BUILD_RPATH ${CMAKE_BUILD_RPATH} ${SUITESPARSE_LIBDIR} ) + list ( APPEND CMAKE_INSTALL_RPATH ${SUITESPARSE_LIBDIR} ) + list ( APPEND CMAKE_BUILD_RPATH ${SUITESPARSE_LIBDIR} ) endif ( ) -message ( STATUS "Install lib: ${SUITESPARSE_LIBDIR}" ) -message ( STATUS "Install include: ${SUITESPARSE_INCLUDEDIR}" ) -message ( STATUS "Install bin: ${SUITESPARSE_BINDIR}" ) -message ( STATUS "Install rpath: ${CMAKE_INSTALL_RPATH}" ) -message ( STATUS "Build rpath: ${CMAKE_BUILD_RPATH}" ) +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} ") +message ( STATUS "Build type: ${CMAKE_BUILD_TYPE} ") set ( CMAKE_INCLUDE_CURRENT_DIR ON ) +#------------------------------------------------------------------------------- +# Workaround for math.h on old macOS +#------------------------------------------------------------------------------- + +if ( APPLE AND CMAKE_SYSTEM_VERSION VERSION_LESS 11 ) + # Older versions of math.h on the Mac define Real and Imag, which + # conflict with the internal use of those symbols in CHOLMOD, KLU, SPQR, + # UMFPACK, and ParU. + # This can be disabled with -D__NOEXTENSIONS__ + message ( STATUS "MacOS: disable extensions in math.h" ) + add_compile_definitions ( "__NOEXTENSIONS__" ) +endif ( ) + #------------------------------------------------------------------------------- # check if Fortran is available and enabled #------------------------------------------------------------------------------- include ( CheckLanguage ) -option ( NFORTRAN "ON: do not try to use Fortran. OFF (default): try Fortran" off ) -if ( NFORTRAN ) - message ( STATUS "Fortran: not enabled" ) -else ( ) +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}" ) + message ( STATUS "Fortran: ${CMAKE_Fortran_COMPILER}" ) + set ( SUITESPARSE_HAS_FORTRAN ON ) else ( ) # Fortran not available: - set ( NFORTRAN true ) - message ( STATUS "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 @@ -217,48 +312,54 @@ endif ( ) # find CUDA #------------------------------------------------------------------------------- -if ( ENABLE_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" ) + # message ( STATUS "Looking for CUDA" ) if ( CMAKE_CUDA_COMPILER ) # with CUDA: - message ( STATUS "Find CUDA tool kit:" ) + # message ( STATUS "Find CUDA tool kit:" ) # FindCUDAToolKit needs to have C or CXX enabled first (see above) - include ( FindCUDAToolkit ) - message ( STATUS "CUDA toolkit found: " ${CUDAToolkit_FOUND} ) - message ( STATUS "CUDA toolkit version: " ${CUDAToolkit_VERSION} ) - message ( STATUS "CUDA toolkit include: " ${CUDAToolkit_INCLUDE_DIRS} ) - message ( STATUS "CUDA toolkit lib dir: " ${CUDAToolkit_LIBRARY_DIR} ) + 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_CUDA off ) + 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_CUDA on ) + set ( SUITESPARSE_HAS_CUDA ON ) endif ( ) else ( ) # without CUDA: - message ( STATUS "CUDA: not found" ) - set ( SUITESPARSE_CUDA off ) + message ( STATUS "CUDA: not found" ) + set ( SUITESPARSE_HAS_CUDA OFF ) endif ( ) else ( ) # CUDA is disabled - set ( SUITESPARSE_CUDA off ) + set ( SUITESPARSE_HAS_CUDA OFF ) endif ( ) -if ( SUITESPARSE_CUDA ) - message ( STATUS "CUDA: enabled" ) - add_compile_definitions ( SUITESPARSE_CUDA ) +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" ) + 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/SuiteSparse_config/cmake_modules/SuiteSparseReport.cmake b/SuiteSparse_config/cmake_modules/SuiteSparseReport.cmake index 9271c4a9..0b47f34c 100644 --- a/SuiteSparse_config/cmake_modules/SuiteSparseReport.cmake +++ b/SuiteSparse_config/cmake_modules/SuiteSparseReport.cmake @@ -10,21 +10,15 @@ #------------------------------------------------------------------------------- message ( STATUS "------------------------------------------------------------------------" ) -message ( STATUS "SuiteSparse CMAKE report for: ${CMAKE_PROJECT_NAME}" ) +message ( STATUS "SuiteSparse CMAKE report for: ${PROJECT_NAME}" ) message ( STATUS "------------------------------------------------------------------------" ) -message ( STATUS "inside common SuiteSparse root: ${INSIDE_SUITESPARSE}" ) -message ( STATUS "install in SuiteSparse/lib and SuiteSparse/include: ${LOCAL_INSTALL}" ) -message ( STATUS "build type: ${CMAKE_BUILD_TYPE}" ) -if ( NSTATIC ) - message ( STATUS "NSTATIC: true (do not build static library)" ) -else ( ) - message ( STATUS "NSTATIC: false (build static library)" ) -endif ( ) -if ( OPENMP_FOUND ) - message ( STATUS "use OpenMP: yes ") -else ( ) - message ( STATUS "use OpenMP: no ") +if ( NOT SUITESPARSE_ROOT_CMAKELISTS ) + message ( STATUS "inside common SuiteSparse root: ${INSIDE_SUITESPARSE}" ) + message ( STATUS "install in SuiteSparse/lib and SuiteSparse/include: ${SUITESPARSE_LOCAL_INSTALL}" ) endif ( ) +message ( STATUS "build type: ${CMAKE_BUILD_TYPE}" ) +message ( STATUS "BUILD_SHARED_LIBS: ${BUILD_SHARED_LIBS}" ) +message ( STATUS "BUILD_STATIC_LIBS: ${BUILD_STATIC_LIBS}" ) message ( STATUS "C compiler: ${CMAKE_C_COMPILER} ") message ( STATUS "C flags: ${CMAKE_C_FLAGS}" ) message ( STATUS "C++ compiler: ${CMAKE_CXX_COMPILER}" ) @@ -36,10 +30,10 @@ else ( ) message ( STATUS "C Flags release: ${CMAKE_C_FLAGS_RELEASE} ") message ( STATUS "C++ Flags release: ${CMAKE_CXX_FLAGS_RELEASE} ") endif ( ) -if ( NFORTRAN ) - message ( STATUS "Fortran compiler: none" ) -else ( ) +if ( SUITESPARSE_HAS_FORTRAN ) message ( STATUS "Fortran compiler: ${CMAKE_Fortran_COMPILER} " ) +else ( ) + message ( STATUS "Fortran compiler: none" ) endif ( ) get_property ( CDEFN DIRECTORY PROPERTY COMPILE_DEFINITIONS ) message ( STATUS "compile definitions: ${CDEFN}") @@ -49,7 +43,4 @@ endif ( ) if ( DEFINED CMAKE_CUDA_ARCHITECTURES ) message ( STATUS "CUDA architectures: ${CMAKE_CUDA_ARCHITECTURES}" ) endif ( ) -if ( NPARTITION ) - message ( STATUS "NPARTITION: do not use METIS" ) -endif ( ) message ( STATUS "------------------------------------------------------------------------" ) diff --git a/SuiteSparse_config/cmake_modules/SuiteSparse__thread.cmake b/SuiteSparse_config/cmake_modules/SuiteSparse__thread.cmake index 75c5cb61..1c52185b 100644 --- a/SuiteSparse_config/cmake_modules/SuiteSparse__thread.cmake +++ b/SuiteSparse_config/cmake_modules/SuiteSparse__thread.cmake @@ -10,7 +10,7 @@ # determine if the __thread keyword is available, which is an extension by # gcc but supported by many compilers, to indicate thread-local-storage. -include ( CheckCSourceRuns ) +include ( CheckCSourceCompiles ) set ( thread_src " #include @@ -43,11 +43,11 @@ set ( thread_local_src } " ) -check_c_source_runs ( "${declspec_thread_src}" HAVE_KEYWORD__DECLSPEC_THREAD ) +check_c_source_compiles ( "${declspec_thread_src}" HAVE_KEYWORD__DECLSPEC_THREAD ) -check_c_source_runs ( "${thread_src}" HAVE_KEYWORD__THREAD ) +check_c_source_compiles ( "${thread_src}" HAVE_KEYWORD__THREAD ) -check_c_source_runs ( "${thread_local_src}" HAVE_KEYWORD__THREAD_LOCAL ) +check_c_source_compiles ( "${thread_local_src}" HAVE_KEYWORD__THREAD_LOCAL ) if ( HAVE_KEYWORD__DECLSPEC_THREAD ) add_compile_definitions ( HAVE_KEYWORD__DECLSPEC_THREAD ) diff --git a/SuiteSparse_config/cmake_modules/SuiteSparse_ssize_t.cmake b/SuiteSparse_config/cmake_modules/SuiteSparse_ssize_t.cmake deleted file mode 100644 index 2b74bae8..00000000 --- a/SuiteSparse_config/cmake_modules/SuiteSparse_ssize_t.cmake +++ /dev/null @@ -1,32 +0,0 @@ -#------------------------------------------------------------------------------- -# SuiteSparse/cmake_modules/SuiteSparse_ssize_t.cmake -#------------------------------------------------------------------------------- - -# Copyright (c) 2023, Timothy A. Davis. All Rights Reserved. -# SPDX-License-Identifier: BSD-3-clause - -#------------------------------------------------------------------------------- - -# determine if the compiler defines ssize_t - -include ( CheckCSourceCompiles ) - -set ( ssize_t_source -" #include - int main (void) - { - ssize_t x = 0 ; - return (0) ; - } -" ) - -check_c_source_compiles ( "${ssize_t_source}" TEST_FOR_SSIZE_T ) - -if ( TEST_FOR_SSIZE_T ) - set ( HAVE_SSIZE_T true ) - message ( STATUS "#include and ssize_t: OK" ) -else ( ) - set ( HAVE_SSIZE_T false ) - message ( STATUS "#include and ssize_t: not found" ) -endif ( ) - diff --git a/TestConfig/AMD/CMakeLists.txt b/TestConfig/AMD/CMakeLists.txt new file mode 100644 index 00000000..5109972e --- /dev/null +++ b/TestConfig/AMD/CMakeLists.txt @@ -0,0 +1,91 @@ +#------------------------------------------------------------------------------- +# SuiteSparse/TestConfig/AMD/CMakeLists.txt: cmake for project linking to AMD +#------------------------------------------------------------------------------- + +# Copyright (c) 2024, Timothy A. Davis, All Rights Reserved. +# SPDX-License-Identifier: BSD-3-clause + +cmake_minimum_required ( VERSION 3.22 ) + +#------------------------------------------------------------------------------- +# configure options +#------------------------------------------------------------------------------- + +option ( BUILD_SHARED_LIBS "OFF: do not build shared libraries. ON (default): build shared libraries" ON ) +option ( BUILD_STATIC_LIBS "OFF: do not build static libraries. ON (default): build static libraries" ON ) + +#------------------------------------------------------------------------------- +# variables +#------------------------------------------------------------------------------- + +set ( TEST_PROJECT_NAME amd_demo ) +set ( TEST_PACKAGE_NAME AMD ) +set ( TEST_SHARED_BIN amd_demo ) +set ( TEST_STATIC_BIN amd_demo_static ) +set ( TEST_IMPORT_TARGET SuiteSparse::AMD ) +set ( TEST_IMPORT_TARGET_STATIC SuiteSparse::AMD_static ) + +#------------------------------------------------------------------------------- +# define project +#------------------------------------------------------------------------------- + +project ( ${TEST_PROJECT_NAME} LANGUAGES C CXX ) + +#------------------------------------------------------------------------------- +# find library dependencies +#------------------------------------------------------------------------------- + +find_package ( ${TEST_PACKAGE_NAME} REQUIRED ) + +#------------------------------------------------------------------------------- +# dynamically linked executable properties +#------------------------------------------------------------------------------- + +file ( GLOB MY_SOURCES "*.cc" ) +if ( BUILD_SHARED_LIBS ) + add_executable ( ${TEST_SHARED_BIN} ${MY_SOURCES} ) + set_target_properties ( ${TEST_SHARED_BIN} PROPERTIES + C_STANDARD 11 + C_STANDARD_REQUIRED ON ) +endif ( ) + +#------------------------------------------------------------------------------- +# staticcally linked executable properties +#------------------------------------------------------------------------------- + +if ( BUILD_STATIC_LIBS ) + add_executable ( ${TEST_STATIC_BIN} ${MY_SOURCES} ) + set_target_properties ( ${TEST_STATIC_BIN} PROPERTIES + C_STANDARD 11 + C_STANDARD_REQUIRED ON ) +endif ( ) + +#------------------------------------------------------------------------------- +# add library dependency +#------------------------------------------------------------------------------- + +if ( BUILD_SHARED_LIBS ) + target_link_libraries ( ${TEST_SHARED_BIN} PRIVATE ${TEST_IMPORT_TARGET} ) +endif ( ) +if ( BUILD_STATIC_LIBS ) + if ( TARGET ${TEST_IMPORT_TARGET_STATIC} ) + target_link_libraries ( ${TEST_STATIC_BIN} PUBLIC ${TEST_IMPORT_TARGET_STATIC} ) + else ( ) + target_link_libraries ( ${TEST_STATIC_BIN} PUBLIC ${TEST_IMPORT_TARGET} ) + endif ( ) +endif ( ) + +#------------------------------------------------------------------------------- +# installation location +#------------------------------------------------------------------------------- + +include ( GNUInstallDirs ) + +if ( BUILD_SHARED_LIBS ) + install ( TARGETS ${TEST_SHARED_BIN} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) +endif ( ) +if ( BUILD_STATIC_LIBS ) + install ( TARGETS ${TEST_STATIC_BIN} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) +endif ( ) diff --git a/TestConfig/AMD/Makefile.am b/TestConfig/AMD/Makefile.am new file mode 100644 index 00000000..8bf37d3f --- /dev/null +++ b/TestConfig/AMD/Makefile.am @@ -0,0 +1,17 @@ +#------------------------------------------------------------------------------- +# SuiteSparse/Example/.../Makefile +#------------------------------------------------------------------------------- + +# Example: Copyright (c) 2024, Timothy A. Davis, All Rights Reserved. +# SPDX-License-Identifier: BSD-3-Clause + +#------------------------------------------------------------------------------- + +demo_PROGRAMS = \ + %reldir%/suitesparse_demo + +demodir = %canon_reldir% + +%canon_reldir%_suitesparse_demo_SOURCES = %reldir%/demo.cc +%canon_reldir%_suitesparse_demo_CPPFLAGS = @SUITESPARSE_CFLAGS@ +%canon_reldir%_suitesparse_demo_LDADD = @SUITESPARSE_LIBS@ diff --git a/TestConfig/AMD/build/.gitignore b/TestConfig/AMD/build/.gitignore new file mode 100644 index 00000000..52e15321 --- /dev/null +++ b/TestConfig/AMD/build/.gitignore @@ -0,0 +1,4 @@ +# Ignore all files except this file. +* +*/ +!.gitignore diff --git a/TestConfig/AMD/configure.ac b/TestConfig/AMD/configure.ac new file mode 100644 index 00000000..20cf5ec0 --- /dev/null +++ b/TestConfig/AMD/configure.ac @@ -0,0 +1,25 @@ +# simple configure file for example project in SuiteSparse + +# initialize +AC_INIT([example], [1.6.0]) + +AM_INIT_AUTOMAKE([foreign subdir-objects]) + +LT_INIT + +# check for working compilers +AC_PROG_CXX + +# find pkg-config executable +PKG_PROG_PKG_CONFIG() + +if test "$enable_static" = yes; then + PKG_CONFIG="$PKG_CONFIG --static" +fi + +# find installed SuiteSparse library +PKG_CHECK_MODULES([SUITESPARSE], [AMD]) + +# create Makefile.in from Makefile.am +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/TestConfig/AMD/demo.cc b/TestConfig/AMD/demo.cc new file mode 100644 index 00000000..113f58d3 --- /dev/null +++ b/TestConfig/AMD/demo.cc @@ -0,0 +1,38 @@ +//------------------------------------------------------------------------------ +// SuiteSparse/TestConfig/AMD/demo.cc +//------------------------------------------------------------------------------ + +// Copyright (c) 2024, Timothy A. Davis, All Rights Reserved. +// SPDX-License-Identifier: BSD-3-clause + +//------------------------------------------------------------------------------ + +// TestConfig program + +#include + +#include "amd.h" + +int main (void) +{ + #define N 2 + #define NNZ 4 + int64_t n = N; + int64_t nzmax = NNZ; + int64_t Ap[N+1]; + int64_t Ai[NNZ]; + Ap [0] = 0; + Ap [1] = 2; + Ap [2] = NNZ; + Ai [0] = 0; + Ai [1] = 1; + Ai [2] = 0; + Ai [3] = 1; + + int64_t P [N]; + amd_l_order (n, Ap, Ai, P, nullptr, nullptr); + for (int k = 0; k < n; k++) + std::cout << "P [" << k << "] = " << P [k] << std::endl; + + return 0; +} diff --git a/TestConfig/COLAMD/CMakeLists.txt b/TestConfig/COLAMD/CMakeLists.txt new file mode 100644 index 00000000..9d19182d --- /dev/null +++ b/TestConfig/COLAMD/CMakeLists.txt @@ -0,0 +1,91 @@ +#------------------------------------------------------------------------------- +# SuiteSparse/TestConfig/COLAMD/CMakeLists.txt: cmake for project linking to COLAMD +#------------------------------------------------------------------------------- + +# Copyright (c) 2024, Timothy A. Davis, All Rights Reserved. +# SPDX-License-Identifier: BSD-3-clause + +cmake_minimum_required ( VERSION 3.22 ) + +#------------------------------------------------------------------------------- +# configure options +#------------------------------------------------------------------------------- + +option ( BUILD_SHARED_LIBS "OFF: do not build shared libraries. ON (default): build shared libraries" ON ) +option ( BUILD_STATIC_LIBS "OFF: do not build static libraries. ON (default): build static libraries" ON ) + +#------------------------------------------------------------------------------- +# variables +#------------------------------------------------------------------------------- + +set ( TEST_PROJECT_NAME colamd_demo ) +set ( TEST_PACKAGE_NAME COLAMD ) +set ( TEST_SHARED_BIN colamd_demo ) +set ( TEST_STATIC_BIN colamd_demo_static ) +set ( TEST_IMPORT_TARGET SuiteSparse::COLAMD ) +set ( TEST_IMPORT_TARGET_STATIC SuiteSparse::COLAMD_static ) + +#------------------------------------------------------------------------------- +# define project +#------------------------------------------------------------------------------- + +project ( ${TEST_PROJECT_NAME} LANGUAGES C CXX ) + +#------------------------------------------------------------------------------- +# find library dependencies +#------------------------------------------------------------------------------- + +find_package ( ${TEST_PACKAGE_NAME} REQUIRED ) + +#------------------------------------------------------------------------------- +# dynamically linked executable properties +#------------------------------------------------------------------------------- + +file ( GLOB MY_SOURCES "*.cc" ) +if ( BUILD_SHARED_LIBS ) + add_executable ( ${TEST_SHARED_BIN} ${MY_SOURCES} ) + set_target_properties ( ${TEST_SHARED_BIN} PROPERTIES + C_STANDARD 11 + C_STANDARD_REQUIRED ON ) +endif ( ) + +#------------------------------------------------------------------------------- +# staticcally linked executable properties +#------------------------------------------------------------------------------- + +if ( BUILD_STATIC_LIBS ) + add_executable ( ${TEST_STATIC_BIN} ${MY_SOURCES} ) + set_target_properties ( ${TEST_STATIC_BIN} PROPERTIES + C_STANDARD 11 + C_STANDARD_REQUIRED ON ) +endif ( ) + +#------------------------------------------------------------------------------- +# add library dependency +#------------------------------------------------------------------------------- + +if ( BUILD_SHARED_LIBS ) + target_link_libraries ( ${TEST_SHARED_BIN} PRIVATE ${TEST_IMPORT_TARGET} ) +endif ( ) +if ( BUILD_STATIC_LIBS ) + if ( TARGET ${TEST_IMPORT_TARGET_STATIC} ) + target_link_libraries ( ${TEST_STATIC_BIN} PUBLIC ${TEST_IMPORT_TARGET_STATIC} ) + else ( ) + target_link_libraries ( ${TEST_STATIC_BIN} PUBLIC ${TEST_IMPORT_TARGET} ) + endif ( ) +endif ( ) + +#------------------------------------------------------------------------------- +# installation location +#------------------------------------------------------------------------------- + +include ( GNUInstallDirs ) + +if ( BUILD_SHARED_LIBS ) + install ( TARGETS ${TEST_SHARED_BIN} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) +endif ( ) +if ( BUILD_STATIC_LIBS ) + install ( TARGETS ${TEST_STATIC_BIN} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) +endif ( ) diff --git a/TestConfig/COLAMD/Makefile.am b/TestConfig/COLAMD/Makefile.am new file mode 100644 index 00000000..8bf37d3f --- /dev/null +++ b/TestConfig/COLAMD/Makefile.am @@ -0,0 +1,17 @@ +#------------------------------------------------------------------------------- +# SuiteSparse/Example/.../Makefile +#------------------------------------------------------------------------------- + +# Example: Copyright (c) 2024, Timothy A. Davis, All Rights Reserved. +# SPDX-License-Identifier: BSD-3-Clause + +#------------------------------------------------------------------------------- + +demo_PROGRAMS = \ + %reldir%/suitesparse_demo + +demodir = %canon_reldir% + +%canon_reldir%_suitesparse_demo_SOURCES = %reldir%/demo.cc +%canon_reldir%_suitesparse_demo_CPPFLAGS = @SUITESPARSE_CFLAGS@ +%canon_reldir%_suitesparse_demo_LDADD = @SUITESPARSE_LIBS@ diff --git a/TestConfig/COLAMD/build/.gitignore b/TestConfig/COLAMD/build/.gitignore new file mode 100644 index 00000000..52e15321 --- /dev/null +++ b/TestConfig/COLAMD/build/.gitignore @@ -0,0 +1,4 @@ +# Ignore all files except this file. +* +*/ +!.gitignore diff --git a/TestConfig/COLAMD/configure.ac b/TestConfig/COLAMD/configure.ac new file mode 100644 index 00000000..81347ebb --- /dev/null +++ b/TestConfig/COLAMD/configure.ac @@ -0,0 +1,25 @@ +# simple configure file for example project in SuiteSparse + +# initialize +AC_INIT([example], [1.6.0]) + +AM_INIT_AUTOMAKE([foreign subdir-objects]) + +LT_INIT + +# check for working compilers +AC_PROG_CXX + +# find pkg-config executable +PKG_PROG_PKG_CONFIG() + +if test "$enable_static" = yes; then + PKG_CONFIG="$PKG_CONFIG --static" +fi + +# find installed SuiteSparse library +PKG_CHECK_MODULES([SUITESPARSE], [COLAMD]) + +# create Makefile.in from Makefile.am +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/TestConfig/COLAMD/demo.cc b/TestConfig/COLAMD/demo.cc new file mode 100644 index 00000000..7c6ae41d --- /dev/null +++ b/TestConfig/COLAMD/demo.cc @@ -0,0 +1,45 @@ +//------------------------------------------------------------------------------ +// SuiteSparse/TestConfig/COLAMD/demo.cc +//------------------------------------------------------------------------------ + +// Copyright (c) 2024, Timothy A. Davis, All Rights Reserved. +// SPDX-License-Identifier: BSD-3-clause + +//------------------------------------------------------------------------------ + +// TestConfig program + +#include + +#include "colamd.h" + +int main (void) +{ + #define N 2 + #define NNZ 4 + int64_t n = N; + int64_t nzmax = NNZ; + int64_t Ap[N+1]; + int64_t Ai[NNZ]; + Ap [0] = 0; + Ap [1] = 2; + Ap [2] = NNZ; + Ai [0] = 0; + Ai [1] = 1; + Ai [2] = 0; + Ai [3] = 1; + + int64_t stats [COLAMD_STATS] ; + int64_t P [N+1]; + int64_t Alen = colamd_l_recommended (NNZ, n, n); + int64_t *Awork = (int64_t *) malloc (Alen * sizeof (int64_t)); + memcpy (Awork, Ai, NNZ * sizeof (int64_t)); + memcpy (P, Ap, (N+1) * sizeof (int64_t)); + int result = colamd_l (n, n, Alen, Awork, P, nullptr, stats); + colamd_l_report (stats) ; + for (int k = 0; k < n; k++) + std::cout << "P [" << k << "] = " << P [k] << std::endl; + free (Awork); + + return ((result == 0) ? 1 : 0) ; +} diff --git a/TestConfig/Makefile b/TestConfig/Makefile new file mode 100644 index 00000000..e58f6646 --- /dev/null +++ b/TestConfig/Makefile @@ -0,0 +1,29 @@ +#------------------------------------------------------------------------------- +# Makefile for SuiteSparse/TestConfig packages +#------------------------------------------------------------------------------- + +# SuiteSparse/TestConfig, Copyright (c) 2024, Timothy A. Davis, All Rights Reserved. +# SPDX-License-Identifier: BSD-3-clause + +# precede this test with "make local ; make install" in the top-level +# SuiteSparse directory. + +CONFIG = cmake -DCMAKE_PREFIX_PATH="../../lib/cmake" .. +BUILD = cmake --build . --config Release +V = +# V = valgrind --leak-check=full --show-leak-kinds=all + +test: + (cd AMD/build && $(CONFIG) && $(BUILD) && $(V) ./amd_demo && ./amd_demo_static ) + (cd COLAMD/build && $(CONFIG) && $(BUILD) && $(V) ./colamd_demo && ./colamd_demo_static ) + (cd SPEX/build && $(CONFIG) && $(BUILD) && $(V) ./spex_demo && ./spex_demo_static ) + (cd SuiteSparse_config/build && $(CONFIG) && $(BUILD) && $(V) ./config_demo && ./config_demo_static ) + +# Remove all files not in the original distribution +distclean: purge + +purge: + - $(RM) -r */build/* + +clean: purge + diff --git a/TestConfig/README.md b/TestConfig/README.md new file mode 100644 index 00000000..cdbe23aa --- /dev/null +++ b/TestConfig/README.md @@ -0,0 +1,21 @@ +SuiteSparse/TestConfig: test `*Config.make` for each package in SuiteSparse + +Copyright (c) 2024, Timothy A. Davis, All Rights Reserved. +SPDX-License-Identifier: BSD-3-clause + +This folder provides a test for each `*Config.cmake` for each package. + +To run this test, first build and install all of SuiteSparse. In the top-level +folder, do: + + make local + make install + +Next, in this directory: + + make + +To remove files not in the original distribution, do: + + make clean + diff --git a/TestConfig/SPEX/CMakeLists.txt b/TestConfig/SPEX/CMakeLists.txt new file mode 100644 index 00000000..da58d85b --- /dev/null +++ b/TestConfig/SPEX/CMakeLists.txt @@ -0,0 +1,91 @@ +#------------------------------------------------------------------------------- +# SuiteSparse/TestConfig/SPEX/CMakeLists.txt: cmake for project linking to SPEX +#------------------------------------------------------------------------------- + +# Copyright (c) 2024, Timothy A. Davis, All Rights Reserved. +# SPDX-License-Identifier: BSD-3-clause + +cmake_minimum_required ( VERSION 3.22 ) + +#------------------------------------------------------------------------------- +# configure options +#------------------------------------------------------------------------------- + +option ( BUILD_SHARED_LIBS "OFF: do not build shared libraries. ON (default): build shared libraries" ON ) +option ( BUILD_STATIC_LIBS "OFF: do not build static libraries. ON (default): build static libraries" ON ) + +#------------------------------------------------------------------------------- +# variables +#------------------------------------------------------------------------------- + +set ( TEST_PROJECT_NAME spex_demo ) +set ( TEST_PACKAGE_NAME SPEX ) +set ( TEST_SHARED_BIN spex_demo ) +set ( TEST_STATIC_BIN spex_demo_static ) +set ( TEST_IMPORT_TARGET SuiteSparse::SPEX ) +set ( TEST_IMPORT_TARGET_STATIC SuiteSparse::SPEX_static ) + +#------------------------------------------------------------------------------- +# define project +#------------------------------------------------------------------------------- + +project ( ${TEST_PROJECT_NAME} LANGUAGES C CXX ) + +#------------------------------------------------------------------------------- +# find library dependencies +#------------------------------------------------------------------------------- + +find_package ( ${TEST_PACKAGE_NAME} REQUIRED ) + +#------------------------------------------------------------------------------- +# dynamically linked executable properties +#------------------------------------------------------------------------------- + +file ( GLOB MY_SOURCES "*.cc" ) +if ( BUILD_SHARED_LIBS ) + add_executable ( ${TEST_SHARED_BIN} ${MY_SOURCES} ) + set_target_properties ( ${TEST_SHARED_BIN} PROPERTIES + C_STANDARD 11 + C_STANDARD_REQUIRED ON ) +endif ( ) + +#------------------------------------------------------------------------------- +# staticcally linked executable properties +#------------------------------------------------------------------------------- + +if ( BUILD_STATIC_LIBS ) + add_executable ( ${TEST_STATIC_BIN} ${MY_SOURCES} ) + set_target_properties ( ${TEST_STATIC_BIN} PROPERTIES + C_STANDARD 11 + C_STANDARD_REQUIRED ON ) +endif ( ) + +#------------------------------------------------------------------------------- +# add library dependency +#------------------------------------------------------------------------------- + +if ( BUILD_SHARED_LIBS ) + target_link_libraries ( ${TEST_SHARED_BIN} PRIVATE ${TEST_IMPORT_TARGET} ) +endif ( ) +if ( BUILD_STATIC_LIBS ) + if ( TARGET ${TEST_IMPORT_TARGET_STATIC} ) + target_link_libraries ( ${TEST_STATIC_BIN} PUBLIC ${TEST_IMPORT_TARGET_STATIC} ) + else ( ) + target_link_libraries ( ${TEST_STATIC_BIN} PUBLIC ${TEST_IMPORT_TARGET} ) + endif ( ) +endif ( ) + +#------------------------------------------------------------------------------- +# installation location +#------------------------------------------------------------------------------- + +include ( GNUInstallDirs ) + +if ( BUILD_SHARED_LIBS ) + install ( TARGETS ${TEST_SHARED_BIN} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) +endif ( ) +if ( BUILD_STATIC_LIBS ) + install ( TARGETS ${TEST_STATIC_BIN} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) +endif ( ) diff --git a/TestConfig/SPEX/Makefile.am b/TestConfig/SPEX/Makefile.am new file mode 100644 index 00000000..8bf37d3f --- /dev/null +++ b/TestConfig/SPEX/Makefile.am @@ -0,0 +1,17 @@ +#------------------------------------------------------------------------------- +# SuiteSparse/Example/.../Makefile +#------------------------------------------------------------------------------- + +# Example: Copyright (c) 2024, Timothy A. Davis, All Rights Reserved. +# SPDX-License-Identifier: BSD-3-Clause + +#------------------------------------------------------------------------------- + +demo_PROGRAMS = \ + %reldir%/suitesparse_demo + +demodir = %canon_reldir% + +%canon_reldir%_suitesparse_demo_SOURCES = %reldir%/demo.cc +%canon_reldir%_suitesparse_demo_CPPFLAGS = @SUITESPARSE_CFLAGS@ +%canon_reldir%_suitesparse_demo_LDADD = @SUITESPARSE_LIBS@ diff --git a/TestConfig/SPEX/build/.gitignore b/TestConfig/SPEX/build/.gitignore new file mode 100644 index 00000000..52e15321 --- /dev/null +++ b/TestConfig/SPEX/build/.gitignore @@ -0,0 +1,4 @@ +# Ignore all files except this file. +* +*/ +!.gitignore diff --git a/TestConfig/SPEX/configure.ac b/TestConfig/SPEX/configure.ac new file mode 100644 index 00000000..0125de83 --- /dev/null +++ b/TestConfig/SPEX/configure.ac @@ -0,0 +1,25 @@ +# simple configure file for example project in SuiteSparse + +# initialize +AC_INIT([example], [1.6.0]) + +AM_INIT_AUTOMAKE([foreign subdir-objects]) + +LT_INIT + +# check for working compilers +AC_PROG_CXX + +# find pkg-config executable +PKG_PROG_PKG_CONFIG() + +if test "$enable_static" = yes; then + PKG_CONFIG="$PKG_CONFIG --static" +fi + +# find installed SuiteSparse library +PKG_CHECK_MODULES([SUITESPARSE], [SPEX]) + +# create Makefile.in from Makefile.am +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/TestConfig/SPEX/demo.cc b/TestConfig/SPEX/demo.cc new file mode 100644 index 00000000..f18372ae --- /dev/null +++ b/TestConfig/SPEX/demo.cc @@ -0,0 +1,22 @@ +//------------------------------------------------------------------------------ +// SuiteSparse/TestConfig/SPEX/demo.cc +//------------------------------------------------------------------------------ + +// Copyright (c) 2024, Timothy A. Davis, All Rights Reserved. +// SPDX-License-Identifier: BSD-3-clause + +//------------------------------------------------------------------------------ + +// TestConfig program + +#include + +#include "SPEX.h" + +int main (void) +{ + SPEX_initialize ( ); + SPEX_finalize ( ); + + return 0; +} diff --git a/TestConfig/SuiteSparse_config/CMakeLists.txt b/TestConfig/SuiteSparse_config/CMakeLists.txt new file mode 100644 index 00000000..8702ac52 --- /dev/null +++ b/TestConfig/SuiteSparse_config/CMakeLists.txt @@ -0,0 +1,91 @@ +#------------------------------------------------------------------------------- +# SuiteSparse/TestConfig/SuiteSparse_config/CMakeLists.txt: cmake for project linking to SuiteSparse_config +#------------------------------------------------------------------------------- + +# Copyright (c) 2024, Timothy A. Davis, All Rights Reserved. +# SPDX-License-Identifier: BSD-3-clause + +cmake_minimum_required ( VERSION 3.22 ) + +#------------------------------------------------------------------------------- +# configure options +#------------------------------------------------------------------------------- + +option ( BUILD_SHARED_LIBS "OFF: do not build shared libraries. ON (default): build shared libraries" ON ) +option ( BUILD_STATIC_LIBS "OFF: do not build static libraries. ON (default): build static libraries" ON ) + +#------------------------------------------------------------------------------- +# variables +#------------------------------------------------------------------------------- + +set ( TEST_PROJECT_NAME config_demo ) +set ( TEST_PACKAGE_NAME SuiteSparse_config ) +set ( TEST_SHARED_BIN config_demo ) +set ( TEST_STATIC_BIN config_demo_static ) +set ( TEST_IMPORT_TARGET SuiteSparse::SuiteSparseConfig ) +set ( TEST_IMPORT_TARGET_STATIC SuiteSparse::SuiteSparseConfig_static ) + +#------------------------------------------------------------------------------- +# define project +#------------------------------------------------------------------------------- + +project ( ${TEST_PROJECT_NAME} LANGUAGES C CXX ) + +#------------------------------------------------------------------------------- +# find library dependencies +#------------------------------------------------------------------------------- + +find_package ( ${TEST_PACKAGE_NAME} REQUIRED ) + +#------------------------------------------------------------------------------- +# dynamically linked executable properties +#------------------------------------------------------------------------------- + +file ( GLOB MY_SOURCES "*.cc" ) +if ( BUILD_SHARED_LIBS ) + add_executable ( ${TEST_SHARED_BIN} ${MY_SOURCES} ) + set_target_properties ( ${TEST_SHARED_BIN} PROPERTIES + C_STANDARD 11 + C_STANDARD_REQUIRED ON ) +endif ( ) + +#------------------------------------------------------------------------------- +# staticcally linked executable properties +#------------------------------------------------------------------------------- + +if ( BUILD_STATIC_LIBS ) + add_executable ( ${TEST_STATIC_BIN} ${MY_SOURCES} ) + set_target_properties ( ${TEST_STATIC_BIN} PROPERTIES + C_STANDARD 11 + C_STANDARD_REQUIRED ON ) +endif ( ) + +#------------------------------------------------------------------------------- +# add library dependency +#------------------------------------------------------------------------------- + +if ( BUILD_SHARED_LIBS ) + target_link_libraries ( ${TEST_SHARED_BIN} PRIVATE ${TEST_IMPORT_TARGET} ) +endif ( ) +if ( BUILD_STATIC_LIBS ) + if ( TARGET ${TEST_IMPORT_TARGET_STATIC} ) + target_link_libraries ( ${TEST_STATIC_BIN} PUBLIC ${TEST_IMPORT_TARGET_STATIC} ) + else ( ) + target_link_libraries ( ${TEST_STATIC_BIN} PUBLIC ${TEST_IMPORT_TARGET} ) + endif ( ) +endif ( ) + +#------------------------------------------------------------------------------- +# installation location +#------------------------------------------------------------------------------- + +include ( GNUInstallDirs ) + +if ( BUILD_SHARED_LIBS ) + install ( TARGETS ${TEST_SHARED_BIN} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) +endif ( ) +if ( BUILD_STATIC_LIBS ) + install ( TARGETS ${TEST_STATIC_BIN} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) +endif ( ) diff --git a/TestConfig/SuiteSparse_config/Makefile.am b/TestConfig/SuiteSparse_config/Makefile.am new file mode 100644 index 00000000..8bf37d3f --- /dev/null +++ b/TestConfig/SuiteSparse_config/Makefile.am @@ -0,0 +1,17 @@ +#------------------------------------------------------------------------------- +# SuiteSparse/Example/.../Makefile +#------------------------------------------------------------------------------- + +# Example: Copyright (c) 2024, Timothy A. Davis, All Rights Reserved. +# SPDX-License-Identifier: BSD-3-Clause + +#------------------------------------------------------------------------------- + +demo_PROGRAMS = \ + %reldir%/suitesparse_demo + +demodir = %canon_reldir% + +%canon_reldir%_suitesparse_demo_SOURCES = %reldir%/demo.cc +%canon_reldir%_suitesparse_demo_CPPFLAGS = @SUITESPARSE_CFLAGS@ +%canon_reldir%_suitesparse_demo_LDADD = @SUITESPARSE_LIBS@ diff --git a/TestConfig/SuiteSparse_config/build/.gitignore b/TestConfig/SuiteSparse_config/build/.gitignore new file mode 100644 index 00000000..52e15321 --- /dev/null +++ b/TestConfig/SuiteSparse_config/build/.gitignore @@ -0,0 +1,4 @@ +# Ignore all files except this file. +* +*/ +!.gitignore diff --git a/TestConfig/SuiteSparse_config/configure.ac b/TestConfig/SuiteSparse_config/configure.ac new file mode 100644 index 00000000..8f131f6d --- /dev/null +++ b/TestConfig/SuiteSparse_config/configure.ac @@ -0,0 +1,25 @@ +# simple configure file for example project in SuiteSparse + +# initialize +AC_INIT([example], [1.6.0]) + +AM_INIT_AUTOMAKE([foreign subdir-objects]) + +LT_INIT + +# check for working compilers +AC_PROG_CXX + +# find pkg-config executable +PKG_PROG_PKG_CONFIG() + +if test "$enable_static" = yes; then + PKG_CONFIG="$PKG_CONFIG --static" +fi + +# find installed SuiteSparse library +PKG_CHECK_MODULES([SUITESPARSE], [SuiteSparse_config]) + +# create Makefile.in from Makefile.am +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/TestConfig/SuiteSparse_config/demo.cc b/TestConfig/SuiteSparse_config/demo.cc new file mode 100644 index 00000000..9db08277 --- /dev/null +++ b/TestConfig/SuiteSparse_config/demo.cc @@ -0,0 +1,24 @@ +//------------------------------------------------------------------------------ +// SuiteSparse/TestConfig/SuiteSparse_config/demo.cc +//------------------------------------------------------------------------------ + +// Copyright (c) 2024, Timothy A. Davis, All Rights Reserved. +// SPDX-License-Identifier: BSD-3-clause + +//------------------------------------------------------------------------------ + +// TestConfig program + +#include + +#include "SuiteSparse_config.h" + +int main (void) +{ + int version [3]; + SuiteSparse_version (version); + std::cout << "SuiteSparse_config version: " << version[0] << "." + << version[1] << "." << version[2] << std::endl; + + return 0; +} diff --git a/build/.gitignore b/build/.gitignore new file mode 100644 index 00000000..5e7d2734 --- /dev/null +++ b/build/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore