From a6847f46555c7946261d3af585c0118f1a5ddd25 Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Wed, 20 Jun 2018 20:38:28 +0200 Subject: [PATCH 01/22] Add fortran pkg-config file --- cmake_modules/GenSPMPkgConfig.cmake | 52 +++++++++++++++++++---------- tools/spmf.pc.in | 23 +++++++++++++ 2 files changed, 58 insertions(+), 17 deletions(-) create mode 100644 tools/spmf.pc.in diff --git a/cmake_modules/GenSPMPkgConfig.cmake b/cmake_modules/GenSPMPkgConfig.cmake index 935b432f..33b8e79f 100644 --- a/cmake_modules/GenSPMPkgConfig.cmake +++ b/cmake_modules/GenSPMPkgConfig.cmake @@ -80,23 +80,41 @@ ### macro(spm_generate_pkgconfig_file) - set(SPM_PKGCONFIG_LIBS "-lspm") - set(SPM_PKGCONFIG_LIBS_PRIVATE "-lm") - set(SPM_PKGCONFIG_REQUIRED "") - set(SPM_PKGCONFIG_REQUIRED_PRIVATE "") - - #clean_lib_list(SPM) - - set(_output_spm_file "${CMAKE_BINARY_DIR}/spm.pc") - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/tools/spm.pc.in" - "${_output_spm_file}" - @ONLY - ) - install( - FILES ${_output_spm_file} - DESTINATION lib/pkgconfig - ) + # The link flags specific to this package and any required libraries + # that don't support PkgConfig + set(SPM_PKGCONFIG_LIBS spm) + + # The link flags for private libraries required by this package but not + # exposed to applications + set(SPM_PKGCONFIG_LIBS_PRIVATE "") + + # A list of packages required by this package + set(SPM_PKGCONFIG_REQUIRED "") + + # A list of private packages required by this package but not exposed to + # applications + set(SPM_PKGCONFIG_REQUIRED_PRIVATE "") + + # Define required package + # ----------------------- + clean_lib_list(SPM) + + # Create .pc file + # --------------- + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/tools/spm.pc.in" + "${CMAKE_BINARY_DIR}/lib/pkgconfig/spm.pc" @ONLY) + + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/tools/spmf.pc.in" + "${CMAKE_BINARY_DIR}/lib/pkgconfig/spmf.pc" @ONLY) + + # installation + # ------------ + install(FILES + "${CMAKE_BINARY_DIR}/lib/pkgconfig/spm.pc" + "${CMAKE_BINARY_DIR}/lib/pkgconfig/spmf.pc" + DESTINATION lib/pkgconfig) endmacro(spm_generate_pkgconfig_file) diff --git a/tools/spmf.pc.in b/tools/spmf.pc.in new file mode 100644 index 00000000..c368a6d7 --- /dev/null +++ b/tools/spmf.pc.in @@ -0,0 +1,23 @@ +# +# @file spmf.pc +# +# @copyright 2016-2018 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, +# Univ. Bordeaux. All rights reserved. +# +# @version 1.0.0 +# @author Mathieu Faverge +# @date 2017-06-24 +# +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${exec_prefix}/include + +Name: SPM - Fortran +Description: SParse Matrix package - Fortran interface +Version: @SPM_VERSION_MAJOR@.@SPM_VERSION_MINOR@.@SPM_VERSION_MICRO@ +Cflags: -I${includedir} +Libs: -L${libdir} -lspmf @SPM_PKGCONFIG_LIBS@ +Libs.private: @SPM_PKGCONFIG_LIBS_PRIVATE@ +Requires: spm @SPM_PKGCONFIG_REQUIRED@ +Requires.private: @SPM_PKGCONFIG_REQUIRED_PRIVATE@ -- GitLab From 64b6a9bbba917ec1b205228eb09a1b0336bb279f Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Wed, 20 Jun 2018 20:39:53 +0200 Subject: [PATCH 02/22] Fix issue with norm naming for forward error --- src/z_spm_genrhs.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/z_spm_genrhs.c b/src/z_spm_genrhs.c index e5b4783d..76f3a248 100644 --- a/src/z_spm_genrhs.c +++ b/src/z_spm_genrhs.c @@ -451,7 +451,7 @@ z_spmCheckAxb( spm_fixdbl_t eps, int nrhs, */ if ( x0 != NULL ) { double normX0; - double forw, nr, nx; + double forw, nr, nx, nx0; int fail; forward = 0.; @@ -461,14 +461,15 @@ z_spmCheckAxb( spm_fixdbl_t eps, int nrhs, for( i=0; i<nrhs; i++, zx += ldx, zx0 += ldx0 ) { - nx = LAPACKE_zlange( LAPACK_COL_MAJOR, 'I', spm->n, 1, zx0, ldx0 ); + nx0 = LAPACKE_zlange( LAPACK_COL_MAJOR, 'I', spm->n, 1, zx0, ldx0 ); + nx = LAPACKE_zlange( LAPACK_COL_MAJOR, 'I', spm->n, 1, zx, ldx ); cblas_zaxpy( spm->n, CBLAS_SADDR(mzone), zx, 1, zx0, 1); nr = LAPACKE_zlange( LAPACK_COL_MAJOR, 'I', spm->n, 1, zx0, ldx0 ); - forw = (nr / nx) / eps; + forw = (nr / nx0) / eps; normX0 = ( nx > normX0 ) ? nx : normX0; normR = ( nr > normR ) ? nr : normR; @@ -477,9 +478,11 @@ z_spmCheckAxb( spm_fixdbl_t eps, int nrhs, fail = isnan(nx) || isinf(nx) || isnan(forw) || isinf(forw) || (forw > 1.e2); if ( fail ) { fprintf( stdout, - " || x0_%d ||_oo %e\n" + " || x_%d ||_oo %e\n" + " || x0_%d - x_%d ||_oo %e\n" " || x0_%d - x_%d ||_oo / (||x0_%d||_oo * eps) %e (%s)\n", - i, nr, + i, nx, + i, i, nr, i, i, i, forw, fail ? "FAILED" : "SUCCESS" ); } @@ -488,7 +491,7 @@ z_spmCheckAxb( spm_fixdbl_t eps, int nrhs, } fprintf( stdout, - " max(|| x0_i ||_oo) %e\n" + " max(|| x_i ||_oo) %e\n" " max(|| x0_i - x_i ||_oo) %e\n" " max(|| x0_i - x_i ||_oo / || x0_i ||_oo) %e (%s)\n", normX0, normR, forward, -- GitLab From 8efaadfb0824997d14065117ac9524f582be3504 Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Wed, 20 Jun 2018 20:49:19 +0200 Subject: [PATCH 03/22] Remove the call to clean for now --- cmake_modules/GenSPMPkgConfig.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake_modules/GenSPMPkgConfig.cmake b/cmake_modules/GenSPMPkgConfig.cmake index 33b8e79f..c8780307 100644 --- a/cmake_modules/GenSPMPkgConfig.cmake +++ b/cmake_modules/GenSPMPkgConfig.cmake @@ -97,7 +97,7 @@ macro(spm_generate_pkgconfig_file) # Define required package # ----------------------- - clean_lib_list(SPM) + #clean_lib_list(SPM) # Create .pc file # --------------- -- GitLab From 38fcf0da1311934421f02f299db8d5e17f8110e6 Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Thu, 21 Jun 2018 04:47:20 +0200 Subject: [PATCH 04/22] Remove the GenSpmPkgConfig file for the generic one --- CMakeLists.txt | 14 ++- cmake_modules/GenSPMPkgConfig.cmake | 143 ---------------------------- 2 files changed, 11 insertions(+), 146 deletions(-) delete mode 100644 cmake_modules/GenSPMPkgConfig.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index ee61de10..8c904a5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -249,9 +249,17 @@ install(FILES DESTINATION include ) ### Build pkg-config and environment file -include(GenSPMPkgConfig) -spm_generate_pkgconfig_file() -spm_generate_env_file() +include(GenPkgConfig) +list(APPEND SPM_PKGCONFIG_LIBS_PRIVATE + ${LAPACKE_LIBRARIES_DEP} + ${CBLAS_LIBRARIES_DEP} + ) +generate_pkgconfig_files( + "${CMAKE_CURRENT_SOURCE_DIR}/tools/spm.pc.in" + "${CMAKE_CURRENT_SOURCE_DIR}/tools/spmf.pc.in" + PROJECTNAME SPM ) + +generate_env_file( PROJECTNAME SPM ) ### Add documented files to the global property add_documented_files( diff --git a/cmake_modules/GenSPMPkgConfig.cmake b/cmake_modules/GenSPMPkgConfig.cmake deleted file mode 100644 index c8780307..00000000 --- a/cmake_modules/GenSPMPkgConfig.cmake +++ /dev/null @@ -1,143 +0,0 @@ -### -# -# @copyright (c) 2009-2014 The University of Tennessee and The University -# of Tennessee Research Foundation. -# All rights reserved. -# @copyright (c) 2012-2017 Inria. All rights reserved. -# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved. -# -### -# -# @file GenPkgConfig.cmake -# -# @project MORSE -# MORSE is a software package provided by: -# Inria Bordeaux - Sud-Ouest, -# Univ. of Tennessee, -# King Abdullah Univesity of Science and Technology -# Univ. of California Berkeley, -# Univ. of Colorado Denver. -# -# @version 0.9.1 -# @author Cedric Castagnede -# @author Emmanuel Agullo -# @author Mathieu Faverge -# @author Florent Pruvost -# @date 10-11-2014 -# -### - -### -# -# CONVERT_LIBSTYLE_TO_PKGCONFIG: convert a libraries list to follow the pkg-config style -# used in CLEAN_LIB_LIST -# -### -# macro(CONVERT_LIBSTYLE_TO_PKGCONFIG _liblist) -# set(${_liblist}_CPY "${${_liblist}}") -# set(${_liblist} "") -# foreach(_dep ${${_liblist}_CPY}) -# if (${_dep} MATCHES "^/") -# get_filename_component(dep_libname ${_dep} NAME) -# get_filename_component(dep_libdir ${_dep} DIRECTORY) -# string(REPLACE "lib" "" dep_libname "${dep_libname}") -# string(REPLACE ".so" "" dep_libname "${dep_libname}") -# string(REPLACE ".a" "" dep_libname "${dep_libname}") -# string(REPLACE ".dylib" "" dep_libname "${dep_libname}") -# string(REPLACE ".dll" "" dep_libname "${dep_libname}") -# list(APPEND ${_liblist} -L${dep_libdir} -l${dep_libname}) -# elseif(NOT ${_dep} MATCHES "^-") -# list(APPEND ${_liblist} "-l${_dep}") -# else() -# list(APPEND ${_liblist} ${_dep}) -# endif() -# endforeach() -# endmacro(CONVERT_LIBSTYLE_TO_PKGCONFIG) - -### -# -# CLEAN_LIB_LIST: clean libraries lists to follow the pkg-config style -# used in GENERATE_PKGCONFIG_FILE -# -### -#macro(CLEAN_LIB_LIST _package) -# list(REMOVE_DUPLICATES ${_package}_PKGCONFIG_LIBS) -# list(REMOVE_DUPLICATES ${_package}_PKGCONFIG_LIBS_PRIVATE) -# list(REMOVE_DUPLICATES ${_package}_PKGCONFIG_REQUIRED) -# list(REMOVE_DUPLICATES ${_package}_PKGCONFIG_REQUIRED_PRIVATE) -# convert_libstyle_to_pkgconfig(${_package}_PKGCONFIG_LIBS) -# convert_libstyle_to_pkgconfig(${_package}_PKGCONFIG_LIBS_PRIVATE) -# string(REPLACE ";" " " ${_package}_PKGCONFIG_LIBS "${${_package}_PKGCONFIG_LIBS}") -# string(REPLACE ";" " " ${_package}_PKGCONFIG_LIBS_PRIVATE "${${_package}_PKGCONFIG_LIBS_PRIVATE}") -# string(REPLACE ";" " " ${_package}_PKGCONFIG_REQUIRED "${${_package}_PKGCONFIG_REQUIRED}") -# string(REPLACE ";" " " ${_package}_PKGCONFIG_REQUIRED_PRIVATE "${${_package}_PKGCONFIG_REQUIRED_PRIVATE}") -#endmacro(CLEAN_LIB_LIST) - -### -# -# GENERATE_PKGCONFIG_FILE: generate files spm.pc -# -### -macro(spm_generate_pkgconfig_file) - - # The link flags specific to this package and any required libraries - # that don't support PkgConfig - set(SPM_PKGCONFIG_LIBS spm) - - # The link flags for private libraries required by this package but not - # exposed to applications - set(SPM_PKGCONFIG_LIBS_PRIVATE "") - - # A list of packages required by this package - set(SPM_PKGCONFIG_REQUIRED "") - - # A list of private packages required by this package but not exposed to - # applications - set(SPM_PKGCONFIG_REQUIRED_PRIVATE "") - - # Define required package - # ----------------------- - #clean_lib_list(SPM) - - # Create .pc file - # --------------- - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/tools/spm.pc.in" - "${CMAKE_BINARY_DIR}/lib/pkgconfig/spm.pc" @ONLY) - - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/tools/spmf.pc.in" - "${CMAKE_BINARY_DIR}/lib/pkgconfig/spmf.pc" @ONLY) - - # installation - # ------------ - install(FILES - "${CMAKE_BINARY_DIR}/lib/pkgconfig/spm.pc" - "${CMAKE_BINARY_DIR}/lib/pkgconfig/spmf.pc" - DESTINATION lib/pkgconfig) - -endmacro(spm_generate_pkgconfig_file) - -### -# -# generate_env_file: generate files pastix.pc -# -### -macro(spm_generate_env_file) - - # Create .sh file - # --------------- - configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/tools/spm_env.sh.in" - "${CMAKE_BINARY_DIR}/bin/spm_env.sh" @ONLY) - - # installation - # ------------ - install(FILES "${CMAKE_BINARY_DIR}/bin/spm_env.sh" - DESTINATION bin) - -endmacro(spm_generate_env_file) - -## -## @end file GenPkgConfig.cmake -## -- GitLab From 9196b916683d7749f8a67c7817d1d4e2a3438f53 Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Thu, 28 Jun 2018 09:00:52 +0200 Subject: [PATCH 05/22] Update cmake --- cmake_modules/morse_cmake | 2 +- tools/spm.pc.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake_modules/morse_cmake b/cmake_modules/morse_cmake index 47b8241b..65647861 160000 --- a/cmake_modules/morse_cmake +++ b/cmake_modules/morse_cmake @@ -1 +1 @@ -Subproject commit 47b8241b579347ecc7213ccb7eba0b387f036c98 +Subproject commit 65647861f43e22c83f5be69c26b64b60461c8e86 diff --git a/tools/spm.pc.in b/tools/spm.pc.in index 56c3d7b3..42bea7f4 100644 --- a/tools/spm.pc.in +++ b/tools/spm.pc.in @@ -7,7 +7,7 @@ Name: SPM Description: SParse Matrix package Version: @SPM_VERSION_MAJOR@.@SPM_VERSION_MINOR@.@SPM_VERSION_MICRO@ Cflags: -I${includedir} -Libs: -L${libdir} @SPM_PKGCONFIG_LIBS@ +Libs: -L${libdir} -lspm @SPM_PKGCONFIG_LIBS@ Libs.private: @SPM_PKGCONFIG_LIBS_PRIVATE@ Requires: @SPM_PKGCONFIG_REQUIRED@ Requires.private: @SPM_PKGCONFIG_REQUIRED_PRIVATE@ -- GitLab From 5b2ea4e23b237e0d6e979b34b57bc9782c3b1cdf Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Thu, 28 Jun 2018 11:30:17 +0200 Subject: [PATCH 06/22] Apply some updates from pastix --- .gitlab-ci.yml | 13 +++++++------ tools/analysis.sh | 1 + tools/wrappers/wrap_fortran.py | 7 +------ 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f25b1b2b..acde4028 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,7 +4,7 @@ stages: - build - test - sonar -# - doc +# - deploy build_spm: stage: build @@ -16,7 +16,7 @@ build_spm: - git submodule update --init --recursive - mkdir build - cd build - - cmake .. -DCMAKE_INSTALL_PREFIX=${PWD}/../install -DBUILD_SHARED_LIBS=ON -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_C_FLAGS="-O0 -g -fPIC --coverage -Wall -fdiagnostics-show-option -fno-inline" -DCMAKE_EXE_LINKER_FLAGS="--coverage" -DPASTIX_INT64=OFF + - cmake .. -DCMAKE_INSTALL_PREFIX=${PWD}/../install -DBUILD_SHARED_LIBS=ON -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_C_FLAGS="-O0 -g -fPIC --coverage -Wall -fdiagnostics-show-option -fno-inline" -DCMAKE_EXE_LINKER_FLAGS="--coverage" -DSPM_INT64=OFF -DCMAKE_EXPORT_COMPILE_COMMANDS=ON - make -j 4 | tee ../pastix-build.log - make install | tee -a ../pastix-build.log only: @@ -34,6 +34,7 @@ test_spm: - spm.lcov - spm-gcov.log script: + - git submodule update --init --recursive - source install/bin/spm_env.sh - (cd build && eval "ctest @@ -68,9 +69,12 @@ sonar_spm: - master@solverstack/spm # pages: -# stage: doc +# stage: deploy # dependencies: # - build_spm +# artifacts: +# paths: +# - public # script: # - git submodule update --init --recursive # - mkdir -p build @@ -78,9 +82,6 @@ sonar_spm: # - cmake .. -DBUILD_DOCUMENTATION=ON -DSPM_INT64=OFF # - make docs # - mv docs/out/html ../public/ -# artifacts: -# paths: -# - public # only: # - master@solverstack/spm diff --git a/tools/analysis.sh b/tools/analysis.sh index 0ec0039d..83739173 100755 --- a/tools/analysis.sh +++ b/tools/analysis.sh @@ -62,6 +62,7 @@ sonar.c.compiler.reportPath=spm-build.log sonar.c.coverage.reportPath=spm-coverage.xml sonar.c.cppcheck.reportPath=spm-cppcheck.xml sonar.c.rats.reportPath=spm-rats.xml +sonar.c.jsonCompilationDatabase=build/compile_commands.json EOF # run sonar analysis + publish on sonarqube-dev diff --git a/tools/wrappers/wrap_fortran.py b/tools/wrappers/wrap_fortran.py index e4250f83..828a8115 100644 --- a/tools/wrappers/wrap_fortran.py +++ b/tools/wrappers/wrap_fortran.py @@ -87,7 +87,7 @@ def iso_c_wrapper_type(arg, args_list, args_size): else: is_pointer = False - if (is_pointer and arg[0].strip() == "void"): + if (is_pointer and (arg[0].strip() == "void")): f_type = "type(c_ptr), " else: f_type = types_dict[arg[0]] + ", " @@ -108,11 +108,6 @@ def iso_c_wrapper_type(arg, args_list, args_size): f_name = arg[2] - # Force case of myorder - if f_name == "myorder": - f_intent = "intent(in), " - f_target = "pointer" - # detect array argument if (is_pointer and f_name in arrays_names_2D): f_array = "(:,:)" -- GitLab From df72d824d8b4958825a359db3babd7db77394d6a Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Thu, 28 Jun 2018 11:53:01 +0200 Subject: [PATCH 07/22] Silent warning --- src/drivers/skitf.f | 251 ++++++++++++-------------------------------- 1 file changed, 69 insertions(+), 182 deletions(-) diff --git a/src/drivers/skitf.f b/src/drivers/skitf.f index 5c597345..cf609894 100644 --- a/src/drivers/skitf.f +++ b/src/drivers/skitf.f @@ -29,16 +29,16 @@ c for the rows: perm(i) is the destination of row i in the c permuted matrix -- also the destination of column i in case c permutation is symmetric (job .le. 2) c -c qperm = same thing for the columns. This should be provided only +c qperm = same thing for the columns. This should be provided only c if job=3 or job=4, i.e., only in the case of a nonsymmetric c permutation of rows and columns. Otherwise qperm is a dummy c -c job = integer indicating the work to be done: +c job = integer indicating the work to be done: c * job = 1,2 permutation is symmetric Ao :== P * A * transp(P) -c job = 1 permute a, ja, ia into ao, jao, iao +c job = 1 permute a, ja, ia into ao, jao, iao c job = 2 permute matrix ignoring real values. c * job = 3,4 permutation is non-symmetric Ao :== P * A * Q -c job = 3 permute a, ja, ia into ao, jao, iao +c job = 3 permute a, ja, ia into ao, jao, iao c job = 4 permute matrix ignoring real values. c c on return: @@ -168,7 +168,7 @@ c perm = integer array of length n containing the permutation arrays c for the rows: perm(i) is the destination of row i in the c permuted matrix -- also the destination of column i. c -c rperm = reverse permutation. defined by rperm(iperm(i))=i for all i +c rperm = reverse permutation. defined by rperm(iperm(i))=i for all i c c job = job indicator. if (job .ne.1) values are not copied (i.e., c only pattern is copied). @@ -351,17 +351,17 @@ c ao, jao, iao in csr format c c a, ja, ia = input matrix in csr format c -c iperm = integer array of length nrow containing the reverse permutation +c iperm = integer array of length nrow containing the reverse permutation c array for the rows. row number iperm(j) in permuted matrix PA c used to be row number j in unpermuted matrix. c ---> a(i,j) in the permuted matrix was a(iperm(i),j) c in the inout matrix. c -c job = integer indicating the work to be done: +c job = integer indicating the work to be done: c job .ne. 1 : get structure only of output matrix,, c i.e., ignore real values. (in which case arrays a c and ao are not used nor accessed). -c job = 1 get complete data structure of output matrix. +c job = 1 get complete data structure of output matrix. c (i.e., including arrays ao and iao). c------------ c on return: @@ -809,128 +809,15 @@ c c---------end-of-readmt------------------------------------------------- c----------------------------------------------------------------------- end -c----------------------------------------------------------------------- - subroutine roscal(nrow,job,nrm,a,ja,ia,diag,b,jb,ib,ierr) - real*8 a(*), b(*), diag(nrow) - integer nrow,job,nrm,ja(*),jb(*),ia(nrow+1),ib(nrow+1),ierr -c----------------------------------------------------------------------- -c scales the rows of A such that their norms are one on return -c 3 choices of norms: 1-norm, 2-norm, max-norm. -c----------------------------------------------------------------------- -c on entry: -c --------- -c nrow = integer. The row dimension of A -c -c job = integer. job indicator. Job=0 means get array b only -c job = 1 means get b, and the integer arrays ib, jb. -c -c nrm = integer. norm indicator. nrm = 1, means 1-norm, nrm =2 -c means the 2-nrm, nrm = 0 means max norm -c -c a, -c ja, -c ia = Matrix A in compressed sparse row format. -c -c on return: -c---------- -c -c diag = diagonal matrix stored as a vector containing the matrix -c by which the rows have been scaled, i.e., on return -c we have B = Diag*A. -c -c b, -c jb, -c ib = resulting matrix B in compressed sparse row sparse format. -c -c ierr = error message. ierr=0 : Normal return -c ierr=i > 0 : Row number i is a zero row. -c Notes: -c------- -c 1) The column dimension of A is not needed. -c 2) algorithm in place (B can take the place of A). -c----------------------------------------------------------------- - call rnrms (nrow,nrm,a,ja,ia,diag) - - ierr = 0 - do 1 j=1, nrow - if (diag(j) .eq. 0.0d0) then - ierr = j - return - else - diag(j) = 1.0d0/diag(j) - endif - 1 continue - call diamua(nrow,job,a,ja,ia,diag,b,jb,ib) - return -c-------end-of-roscal--------------------------------------------------- -c----------------------------------------------------------------------- - end -c----------------------------------------------------------------------- - subroutine coscal(nrow,job,nrm,a,ja,ia,diag,b,jb,ib,ierr) -c----------------------------------------------------------------------- - real*8 a(*),b(*),diag(nrow) - integer nrow,job,ja(*),jb(*),ia(nrow+1),ib(nrow+1),ierr -c----------------------------------------------------------------------- -c scales the columns of A such that their norms are one on return -c result matrix written on b, or overwritten on A. -c 3 choices of norms: 1-norm, 2-norm, max-norm. in place. -c----------------------------------------------------------------------- -c on entry: -c --------- -c nrow = integer. The row dimension of A -c -c job = integer. job indicator. Job=0 means get array b only -c job = 1 means get b, and the integer arrays ib, jb. -c -c nrm = integer. norm indicator. nrm = 1, means 1-norm, nrm =2 -c means the 2-nrm, nrm = 0 means max norm -c -c a, -c ja, -c ia = Matrix A in compressed sparse row format. -c -c on return: -c---------- -c -c diag = diagonal matrix stored as a vector containing the matrix -c by which the columns have been scaled, i.e., on return -c we have B = A * Diag -c -c b, -c jb, -c ib = resulting matrix B in compressed sparse row sparse format. -c -c ierr = error message. ierr=0 : Normal return -c ierr=i > 0 : Column number i is a zero row. -c Notes: -c------- -c 1) The column dimension of A is not needed. -c 2) algorithm in place (B can take the place of A). -c----------------------------------------------------------------- - call cnrms (nrow,nrm,a,ja,ia,diag) - ierr = 0 - do 1 j=1, nrow - if (diag(j) .eq. 0.0) then - ierr = j - return - else - diag(j) = 1.0d0/diag(j) - endif - 1 continue - call amudia (nrow,job,a,ja,ia,diag,b,jb,ib) - return -c--------end-of-coscal-------------------------------------------------- -c----------------------------------------------------------------------- - end - subroutine rnrms (nrow, nrm, a, ja, ia, diag) + subroutine rnrms (nrow, nrm, a, ia, diag) real*8 a(*), diag(nrow), scal - integer ja(*), ia(nrow+1) + integer ia(nrow+1) c----------------------------------------------------------------------- c gets the norms of each row of A. (choice of three norms) c----------------------------------------------------------------------- c on entry: c --------- -c nrow = integer. The row dimension of A +c nrow = integer. The row dimension of A c c nrm = integer. norm indicator. nrm = 1, means 1-norm, nrm =2 c means the 2-nrm, nrm = 0 means max norm @@ -981,7 +868,7 @@ c gets the norms of each column of A. (choice of three norms) c----------------------------------------------------------------------- c on entry: c --------- -c nrow = integer. The row dimension of A +c nrow = integer. The row dimension of A c c nrm = integer. norm indicator. nrm = 1, means 1-norm, nrm =2 c means the 2-nrm, nrm = 0 means max norm @@ -1030,7 +917,7 @@ c performs the matrix by matrix product B = Diag * A (in place) c----------------------------------------------------------------------- c on entry: c --------- -c nrow = integer. The row dimension of A +c nrow = integer. The row dimension of A c c job = integer. job indicator. Job=0 means get array b only c job = 1 means get b, and the integer arrays ib, jb. @@ -1046,7 +933,7 @@ c---------- c c b, c jb, -c ib = resulting matrix B in compressed sparse row sparse format. +c ib = resulting matrix B in compressed sparse row sparse format. c c Notes: c------- @@ -1087,7 +974,7 @@ c performs the matrix by matrix product B = A * Diag (in place) c----------------------------------------------------------------------- c on entry: c --------- -c nrow = integer. The row dimension of A +c nrow = integer. The row dimension of A c c job = integer. job indicator. Job=0 means get array b only c job = 1 means get b, and the integer arrays ib, jb. @@ -1103,7 +990,7 @@ c---------- c c b, c jb, -c ib = resulting matrix B in compressed sparse row sparse format. +c ib = resulting matrix B in compressed sparse row sparse format. c c Notes: c------- @@ -1144,7 +1031,7 @@ c performs the matrix sum C = A+B. c----------------------------------------------------------------------- c on entry: c --------- -c nrow = integer. The row dimension of A and B +c nrow = integer. The row dimension of A and B c ncol = integer. The column dimension of A and B. c job = integer. Job indicator. When job = 0, only the structure c (i.e. the arrays jc, ic) is computed and the @@ -1156,9 +1043,9 @@ c ia = Matrix A in compressed sparse row format. c c b, c jb, -c ib = Matrix B in compressed sparse row format. +c ib = Matrix B in compressed sparse row format. c -c nzmax = integer. The length of the arrays c and jc. +c nzmax = integer. The length of the arrays c and jc. c amub will stop if the result matrix C has a number c of elements that exceeds exceeds nzmax. See ierr. c @@ -1166,9 +1053,9 @@ c on return: c---------- c c, c jc, -c ic = resulting matrix C in compressed sparse row sparse format. +c ic = resulting matrix C in compressed sparse row sparse format. c -c ierr = integer. serving as error message. +c ierr = integer. serving as error message. c ierr = 0 means normal return, c ierr .gt. 0 means that amub stopped while computing the c i-th row of C with i=ierr, because the number @@ -1176,7 +1063,7 @@ c of elements in C exceeds nzmax. c c work arrays: c------------ -c iw = integer work array of length equal to the number of +c iw = integer work array of length equal to the number of c columns in A. c c----------------------------------------------------------------------- @@ -1239,8 +1126,8 @@ c this subroutine transposes a matrix stored in a, ja, ia format. c --------------- c on entry: c---------- -c n = dimension of A. -c job = integer to indicate whether to fill the values (job.eq.1) of the +c n = dimension of A. +c job = integer to indicate whether to fill the values (job.eq.1) of the c matrix ao or only the pattern., i.e.,ia, and ja (job .ne.1) c c ipos = starting position in ao, jao of the transposed matrix. @@ -1249,19 +1136,19 @@ c Note: this may be useful if one needs to append the data structure c of the transpose to that of A. In this case use for example c call csrcsc (n,1,n+2,a,ja,ia,a,ja,ia(n+2)) c for any other normal usage, enter ipos=1. -c a = real array of length nnz (nnz=number of nonzero elements in input +c a = real array of length nnz (nnz=number of nonzero elements in input c matrix) containing the nonzero elements. -c ja = integer array of length nnz containing the column positions +c ja = integer array of length nnz containing the column positions c of the corresponding elements in a. -c ia = integer of size n+1. ia(k) contains the position in a, ja of +c ia = integer of size n+1. ia(k) contains the position in a, ja of c the beginning of the k-th row. c c on return: c ---------- c output arguments: -c ao = real array of size nzz containing the "a" part of the transpose -c jao = integer array of size nnz containing the column indices. -c iao = integer array of size n+1 containing the "ia" index array of +c ao = real array of size nzz containing the "a" part of the transpose +c jao = integer array of size nnz containing the column indices. +c iao = integer array of size n+1 containing the "ia" index array of c the transpose. c c----------------------------------------------------------------------- @@ -1284,9 +1171,9 @@ c this subroutine transposes a matrix stored in a, ja, ia format. c --------------- c on entry: c---------- -c n = number of rows of CSR matrix. +c n = number of rows of CSR matrix. c n2 = number of columns of CSC matrix. -c job = integer to indicate whether to fill the values (job.eq.1) of the +c job = integer to indicate whether to fill the values (job.eq.1) of the c matrix ao or only the pattern., i.e.,ia, and ja (job .ne.1) c c ipos = starting position in ao, jao of the transposed matrix. @@ -1295,19 +1182,19 @@ c Note: this may be useful if one needs to append the data structure c of the transpose to that of A. In this case use for example c call csrcsc2 (n,n,1,n+2,a,ja,ia,a,ja,ia(n+2)) c for any other normal usage, enter ipos=1. -c a = real array of length nnz (nnz=number of nonzero elements in input +c a = real array of length nnz (nnz=number of nonzero elements in input c matrix) containing the nonzero elements. -c ja = integer array of length nnz containing the column positions +c ja = integer array of length nnz containing the column positions c of the corresponding elements in a. -c ia = integer of size n+1. ia(k) contains the position in a, ja of +c ia = integer of size n+1. ia(k) contains the position in a, ja of c the beginning of the k-th row. c c on return: c ---------- c output arguments: -c ao = real array of size nzz containing the "a" part of the transpose -c jao = integer array of size nnz containing the column indices. -c iao = integer array of size n+1 containing the "ia" index array of +c ao = real array of size nzz containing the "a" part of the transpose +c jao = integer array of size nnz containing the column indices. +c iao = integer array of size n+1 containing the "ia" index array of c the transpose. c c----------------------------------------------------------------------- @@ -1808,18 +1695,18 @@ c this subroutine performs an in-place permutation of a real vector x c according to the permutation array perm(*), i.e., on return, c the vector x satisfies, c -c x(perm(j)) :== x(j), j=1,2,.., n +c x(perm(j)) :== x(j), j=1,2,.., n c c----------------------------------------------------------------------- c on entry: c--------- c n = length of vector x. c perm = integer array of length n containing the permutation array. -c x = input vector +c x = input vector c c on return: c---------- -c x = vector x permuted according to x(perm(*)) := x(*) +c x = vector x permuted according to x(perm(*)) := x(*) c c----------------------------------------------------------------------c c Y. Saad, Sep. 21 1989 c @@ -1828,7 +1715,7 @@ c local variables real*8 tmp, tmp1 c init = 1 - tmp = x(init) + tmp = x(init) ii = perm(init) perm(init)= -perm(init) k = 0 @@ -1860,8 +1747,8 @@ c 65 init = init+1 if (init .gt. n) goto 101 if (perm(init) .lt. 0) goto 65 - tmp = x(init) - ii = perm(init) + tmp = x(init) + ii = perm(init) perm(init)=-perm(init) goto 6 c @@ -1883,18 +1770,18 @@ c this subroutine performs an in-place permutation of an integer vector c ix according to the permutation array perm(*), i.e., on return, c the vector x satisfies, c -c ix(perm(j)) :== ix(j), j=1,2,.., n +c ix(perm(j)) :== ix(j), j=1,2,.., n c c----------------------------------------------------------------------- c on entry: c--------- c n = length of vector x. c perm = integer array of length n containing the permutation array. -c ix = input vector +c ix = input vector c c on return: c---------- -c ix = vector x permuted according to ix(perm(*)) := ix(*) +c ix = vector x permuted according to ix(perm(*)) := ix(*) c c----------------------------------------------------------------------c c Y. Saad, Sep. 21 1989 c @@ -1903,7 +1790,7 @@ c local variables integer tmp, tmp1 c init = 1 - tmp = ix(init) + tmp = ix(init) ii = perm(init) perm(init)= -perm(init) k = 0 @@ -1935,8 +1822,8 @@ c 65 init = init+1 if (init .gt. n) goto 101 if (perm(init) .lt. 0) goto 65 - tmp = ix(init) - ii = perm(init) + tmp = ix(init) + ii = perm(init) perm(init)=-perm(init) goto 6 c @@ -1972,8 +1859,8 @@ c permuted matrix. c ---> a(i,j) in the original matrix becomes a(perm(i),j) c in the output matrix. c -c job = integer indicating the work to be done: -c job = 1 permute a, ja, ia into ao, jao, iao +c job = integer indicating the work to be done: +c job = 1 permute a, ja, ia into ao, jao, iao c (including the copying of real values ao and c the array iao). c job .ne. 1 : ignore real values. @@ -2042,13 +1929,13 @@ c nrow = row dimension of the matrix c c a, ja, ia = input matrix in csr format. c -c perm = integer array of length ncol (number of columns of A +c perm = integer array of length ncol (number of columns of A c containing the permutation array the columns: c a(i,j) in the original matrix becomes a(i,perm(j)) c in the output matrix. c -c job = integer indicating the work to be done: -c job = 1 permute a, ja, ia into ao, jao, iao +c job = integer indicating the work to be done: +c job = 1 permute a, ja, ia into ao, jao, iao c (including the copying of real values ao and c the array iao). c job .ne. 1 : ignore real values ao and ignore iao. @@ -2558,6 +2445,7 @@ c c select domain with largest size c maxsiz = 0 + nextdom = 0 do j=1, idom if (size(j) .gt. maxsiz) then maxsiz = size(j) @@ -2830,11 +2718,10 @@ c print *,'mask',riord(j),j,nfirst mask(riord(j)) = 0 12 continue c----------------------------------------------------------------------- - 13 continue c 1 nlev = nlev+1 levels(nlev) = istart + 1 - call add_lvst (istart,iend,nlev,riord,ja,ia,mask,maskval) + call add_lvst (istart,iend,riord,ja,ia,mask,maskval) if (istart .lt. iend) goto 1 2 ii = ii+1 if (ii .le. n) then @@ -2854,7 +2741,7 @@ c endif endif c----------------------------------------------------------------------- - 3 levels(nlev+1) = iend+1 + levels(nlev+1) = iend+1 do j=1, iend mask(riord(j)) = maskval enddo @@ -2862,8 +2749,8 @@ c----------------------------------------------------------------------- return end c----------------------------------------------------------------------- - subroutine add_lvst(istart,iend,nlev,riord,ja,ia,mask,maskval) - integer nlev, nod, riord(*), ja(*), ia(*), mask(*) + subroutine add_lvst(istart,iend,riord,ja,ia,mask,maskval) + integer nod, riord(*), ja(*), ia(*), mask(*) c------------------------------------------------------------- c adds one level set to the previous sets.. c span all nodes of previous mask @@ -3120,7 +3007,7 @@ c nstuck = 0 c----------------------------------------------------------------------- 100 continue - idom = mindom(n,ndom,levst,link) + idom = mindom(n,ndom,link) c----------------------------------------------------------------------- c begin level-set loop c----------------------------------------------------------------------- @@ -3141,7 +3028,7 @@ c do 2 kk=ia(i), ia(i+1)-1 j = ja(kk) if (marker(j) .eq. 0) then - call add_lk(j,nod,idom,ndom,lkend,levst,link,nodes,marker) + call add_lk(j,nod,idom,lkend,levst,link,nodes,marker) endif 2 continue c @@ -3192,11 +3079,11 @@ c c c if no neighboring domain select smallest one c - if (idom .eq. 0) idom = mindom(n,ndom,levst,link) + if (idom .eq. 0) idom = mindom(n,ndom,link) c c add ii to sudomain idom at end of linked list c - call add_lk(ii,nod,idom,ndom,lkend,levst,link,nodes,marker) + call add_lk(ii,nod,idom,lkend,levst,link,nodes,marker) goto 3 else goto 20 @@ -3242,9 +3129,9 @@ c c----------------------------------------------------------------------- end c----------------------------------------------------------------------- - function mindom(n, ndom, levst, link) + function mindom(n, ndom, link) implicit none - integer mindom, n, ndom, levst(2*ndom),link(n) + integer mindom, n, ndom, link(n) c----------------------------------------------------------------------- c returns the domain with smallest size c----------------------------------------------------------------------- @@ -3252,6 +3139,7 @@ c locals c integer i, nsize, isiz c + mindom = -1 isiz = n+1 do 10 i=1, ndom nsize = - link(i) @@ -3264,9 +3152,9 @@ c return end c----------------------------------------------------------------------- - subroutine add_lk(new,nod,idom,ndom,lkend,levst,link,nodes,marker) + subroutine add_lk(new,nod,idom,lkend,levst,link,nodes,marker) implicit none - integer new,nod,idom,ndom,lkend,levst(*),link(*),nodes(*), + integer new,nod,idom,lkend,levst(*),link(*),nodes(*), * marker(*) c----------------------------------------------------------------------- c adds from head -- @@ -3275,7 +3163,6 @@ c adds one entry (new) to linked list and ipdates everything. c new = node to be added c nod = current number of marked nodes c idom = domain to which new is to be added -c ndom = total number of domains c lkend= location of end of structure (link and nodes) c levst= pointer array for link, nodes c link = link array -- GitLab From 11362f25b152c012c1f748b8b765ee45a952f7a7 Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Thu, 28 Jun 2018 11:53:32 +0200 Subject: [PATCH 08/22] Fix issue with complex numbers on double --- wrappers/fortran90/examples/spm_user.f90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wrappers/fortran90/examples/spm_user.f90 b/wrappers/fortran90/examples/spm_user.f90 index cdf8df9b..d511aa1a 100644 --- a/wrappers/fortran90/examples/spm_user.f90 +++ b/wrappers/fortran90/examples/spm_user.f90 @@ -73,19 +73,19 @@ program spm_user if (i < dim1) then rowptr(l) = i + dim1 * (j-1) + dim1 * dim2 * (k-1) + 1 colptr(l) = (i-1) + dim1 * (j-1) + dim1 * dim2 * (k-1) + 1 - values(l) = - 1. - 1. * I + values(l) = - 1. l = l + 1 end if if (j < dim2) then rowptr(l) = (i-1) + dim1 * j + dim1 * dim2 * (k-1) + 1 colptr(l) = (i-1) + dim1 * (j-1) + dim1 * dim2 * (k-1) + 1 - values(l) = - 1. - 1. * I + values(l) = - 1. l = l + 1 end if if (k < dim3) then rowptr(l) = (i-1) + dim1 * (j-1) + dim1 * dim2 * k + 1 colptr(l) = (i-1) + dim1 * (j-1) + dim1 * dim2 * (k-1) + 1 - values(l) = -1. - 1. * I + values(l) = -1. l = l + 1 end if end do -- GitLab From 77c7232ba39d0066804f340b0ecbd37c9ad53499 Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Thu, 28 Jun 2018 11:55:43 +0200 Subject: [PATCH 09/22] Update the wrapper with last changes on pastix --- tools/gen_wrappers.py | 5 ++--- wrappers/fortran90/CMakeLists.txt | 4 ++-- wrappers/fortran90/src/spm_enums.F90 | 3 +-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/tools/gen_wrappers.py b/tools/gen_wrappers.py index e03a3c5b..b923b517 100755 --- a/tools/gen_wrappers.py +++ b/tools/gen_wrappers.py @@ -450,14 +450,13 @@ enums_python_coeftype=''' return -1 ''' -enums_fortran_footer=''' - integer, parameter :: spm_int_t = SPM_INT_KIND +enums_fortran_footer=''' integer, parameter :: spm_int_t = SPM_INT_KIND contains function spm_getintsize() integer :: spm_getintsize - spm_getintsize = SPM_INT_KIND + spm_getintsize = kind(SPM_INT_KIND) return end function spm_getintsize ''' diff --git a/wrappers/fortran90/CMakeLists.txt b/wrappers/fortran90/CMakeLists.txt index dd80adc3..a7a81fea 100644 --- a/wrappers/fortran90/CMakeLists.txt +++ b/wrappers/fortran90/CMakeLists.txt @@ -21,11 +21,11 @@ add_library( spmf if ( SPM_INT64 ) set_source_files_properties( src/spm_enums.F90 - PROPERTIES COMPILE_DEFINITIONS "SPM_INT_KIND=8") + PROPERTIES COMPILE_DEFINITIONS "SPM_INT_KIND=c_int64_t") else() set_source_files_properties( src/spm_enums.F90 - PROPERTIES COMPILE_DEFINITIONS "SPM_INT_KIND=4") + PROPERTIES COMPILE_DEFINITIONS "SPM_INT_KIND=c_int32_t") endif() target_link_libraries( spmf spm ) diff --git a/wrappers/fortran90/src/spm_enums.F90 b/wrappers/fortran90/src/spm_enums.F90 index 5b7f9c93..c1919678 100644 --- a/wrappers/fortran90/src/spm_enums.F90 +++ b/wrappers/fortran90/src/spm_enums.F90 @@ -129,14 +129,13 @@ module spm_enums enumerator :: SpmDirBackward = 392 end enum - integer, parameter :: spm_int_t = SPM_INT_KIND contains function spm_getintsize() integer :: spm_getintsize - spm_getintsize = SPM_INT_KIND + spm_getintsize = kind(SPM_INT_KIND) return end function spm_getintsize -- GitLab From 97754cda904f76e11614cc0e2391b83650a953f9 Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Thu, 28 Jun 2018 14:23:25 +0200 Subject: [PATCH 10/22] Update cmake module --- cmake_modules/morse_cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake_modules/morse_cmake b/cmake_modules/morse_cmake index 65647861..d44efd0e 160000 --- a/cmake_modules/morse_cmake +++ b/cmake_modules/morse_cmake @@ -1 +1 @@ -Subproject commit 65647861f43e22c83f5be69c26b64b60461c8e86 +Subproject commit d44efd0e4af75cf4be6b9483198c595b03ec083a -- GitLab From 34a9a90e1ef9ce050acf6b3b1ba654c35fcbe7e3 Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Fri, 29 Jun 2018 17:46:20 +0200 Subject: [PATCH 11/22] Silent warnigns with icc --- src/spm_io.c | 8 ++++---- src/z_spm.c | 6 ++++-- src/z_spm_expand.c | 10 ++++++---- src/z_spm_laplacian.c | 2 +- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/spm_io.c b/src/spm_io.c index 11da33cf..9d536cbe 100644 --- a/src/spm_io.c +++ b/src/spm_io.c @@ -508,14 +508,14 @@ spmLoad( spmatrix_t *spm, return SPM_ERR_BADPARAMETER; } - spm->mtxtype = mtxtype; - spm->flttype = flttype; - spm->fmttype = fmttype; + spm->mtxtype = (spm_mtxtype_t)mtxtype; + spm->flttype = (spm_coeftype_t)flttype; + spm->fmttype = (spm_fmttype_t)fmttype; spm->gN = gN; spm->n = n; spm->nnz = nnz; spm->dof = dof; - spm->layout = layout; + spm->layout = (spm_layout_t)layout; spmUpdateComputedFields( spm ); diff --git a/src/z_spm.c b/src/z_spm.c index e0d45d07..457e7ba9 100644 --- a/src/z_spm.c +++ b/src/z_spm.c @@ -139,8 +139,11 @@ z_spmMergeDuplicate( spmatrix_t *spm ) spm_int_t n = spm->n; spm_int_t baseval = spm->colptr[0]; spm_int_t dof2 = spm->dof * spm->dof; - spm_int_t idx, i, j, d, size; + spm_int_t idx, i, j, size; spm_int_t merge = 0; +#if !defined(PRECISION_p) + spm_int_t d; +#endif if ( spm->fmttype == SpmCSC ) { idx = 0; @@ -196,7 +199,6 @@ z_spmMergeDuplicate( spmatrix_t *spm ) } } - (void)d; return merge; } diff --git a/src/z_spm_expand.c b/src/z_spm_expand.c index 78a3785c..ad4280a1 100644 --- a/src/z_spm_expand.c +++ b/src/z_spm_expand.c @@ -46,7 +46,8 @@ z_spmCSCExpand(const spmatrix_t *spm) spm_int_t i, j, k, ii, jj, dofi, dofj, col, row, baseval, lda; spm_int_t diag, height; spm_int_t *newcol, *newrow, *oldcol, *oldrow, *dofs; - spm_complex64_t *newval, *oldval, *oldval2; + spm_complex64_t *newval = NULL; + spm_complex64_t *oldval2, *oldval = NULL; assert( spm->fmttype == SpmCSC ); assert( spm->flttype == SpmComplex64 ); @@ -200,7 +201,6 @@ z_spmCSCExpand(const spmatrix_t *spm) assert(spm->loc2glob == NULL); - (void)newval; (void)lda; return newspm; } @@ -234,7 +234,8 @@ z_spmCSRExpand(const spmatrix_t *spm) spm_int_t i, j, k, ii, jj, dofi, dofj, col, row, baseval, lda; spm_int_t diag, height; spm_int_t *newcol, *newrow, *oldcol, *oldrow, *dofs; - spm_complex64_t *newval, *oldval, *oldval2; + spm_complex64_t *newval = NULL; + spm_complex64_t *oldval2, *oldval = NULL; assert( spm->fmttype == SpmCSR ); assert( spm->flttype == SpmComplex64 ); @@ -419,7 +420,8 @@ z_spmIJVExpand(const spmatrix_t *spm) spmatrix_t *newspm; spm_int_t i, j, k, ii, jj, dofi, dofj, col, row, baseval; spm_int_t *newcol, *newrow, *oldcol, *oldrow, *dofs; - spm_complex64_t *newval, *oldval=NULL; + spm_complex64_t *newval = NULL; + spm_complex64_t *oldval = NULL; assert( spm->fmttype == SpmIJV ); assert( spm->flttype == SpmComplex64 ); diff --git a/src/z_spm_laplacian.c b/src/z_spm_laplacian.c index 68fc4361..135e61cd 100644 --- a/src/z_spm_laplacian.c +++ b/src/z_spm_laplacian.c @@ -310,10 +310,10 @@ z_spmLaplacian_27points( spmatrix_t *spm, /* Diagonal value */ *rowptr = l; -#if !defined(PRECISION_p) degree = 1; d = 1; +#if !defined(PRECISION_p) if (k > 1) { d++; } -- GitLab From a134134ba4ae422f52b3ff6688093d22b0b4de13 Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Mon, 2 Jul 2018 18:10:27 +0200 Subject: [PATCH 12/22] Change the spmcheckandcorrect to fix the C/fortran issue of compatibility with malloc/free and allocate/deallocate --- include/spm.h | 10 ++++--- src/spm.c | 33 ++++++++++++++-------- src/z_spm_expand.c | 6 ++-- tools/wrappers/wrap_fortran.py | 1 + tools/wrappers/wrap_python.py | 1 + wrappers/fortran90/examples/spm_driver.f90 | 6 ++-- wrappers/fortran90/examples/spm_user.f90 | 13 +++++++-- wrappers/fortran90/src/spmf.f90 | 17 ++++++----- wrappers/python/spm/__spm__.py | 12 ++++---- 9 files changed, 63 insertions(+), 36 deletions(-) diff --git a/include/spm.h b/include/spm.h index 6fb956e2..90940b10 100644 --- a/include/spm.h +++ b/include/spm.h @@ -48,6 +48,8 @@ * */ typedef struct spmatrix_s { + int8_t alloc; /**< Internal field to detect if the internal buffers has been + user allocated or not. */ spm_mtxtype_t mtxtype; /**< Matrix structure: SpmGeneral, SpmSymmetric or SpmHermitian. */ spm_coeftype_t flttype; /**< values datatype: SpmPattern, SpmFloat, SpmDouble, @@ -110,10 +112,10 @@ void spmScalVector( spm_coeftype_t flt, double alpha, spm_int_t n, void *x, sp * @name SPM subroutines to check format * @{ */ -int spmSort( spmatrix_t *spm ); -spm_int_t spmMergeDuplicate( spmatrix_t *spm ); -spm_int_t spmSymmetrize( spmatrix_t *spm ); -spmatrix_t *spmCheckAndCorrect( spmatrix_t *spm ); +int spmSort( spmatrix_t *spm ); +spm_int_t spmMergeDuplicate( spmatrix_t *spm ); +spm_int_t spmSymmetrize( spmatrix_t *spm ); +int spmCheckAndCorrect( const spmatrix_t *in, spmatrix_t *out ); /** * @} diff --git a/src/spm.c b/src/spm.c index 49d1daf9..c2279a82 100644 --- a/src/spm.c +++ b/src/spm.c @@ -676,24 +676,28 @@ spmSymmetrize( spmatrix_t *spm ) * ******************************************************************************* * - * @param[inout] spm + * @param[in] in * The pointer to the sparse matrix structure to check, and correct. * + * @param[inout] out + * On entry, an allocated structure to hold the corrected spm. + * On exit, holds the pointer to spm corrected. + * ******************************************************************************* * - * @return if no changes have been made, the initial sparse matrix is returned, - * otherwise a copy of the sparse matrix, fixed to meet the PaStiX requirements, - * is returned. + * @return 0 if no changes have been made to the spm matrix. + * @return 1 if corrections have been applied to the in sparse matrix. * *******************************************************************************/ -spmatrix_t * -spmCheckAndCorrect( spmatrix_t *spm ) +int +spmCheckAndCorrect( const spmatrix_t *in, + spmatrix_t *out ) { spmatrix_t *newspm = NULL; spm_int_t count; /* Let's work on a copy */ - newspm = spmCopy( spm ); + newspm = spmCopy( in ); /* PaStiX works on CSC matrices */ spmConvert( SpmCSC, newspm ); @@ -733,15 +737,18 @@ spmCheckAndCorrect( spmatrix_t *spm ) * Check if we return the new one, or the original one because no changes * have been made */ - if (( spm->fmttype != newspm->fmttype ) || - ( spm->nnzexp != newspm->nnzexp ) ) + if (( in->fmttype != newspm->fmttype ) || + ( in->nnzexp != newspm->nnzexp ) ) { - return newspm; + memcpy( out, newspm, sizeof(spmatrix_t) ); + free( newspm ); + return 1; } else { + memcpy( out, in, sizeof(spmatrix_t) ); spmExit( newspm ); - free(newspm); - return (spmatrix_t*)spm; + free( newspm ); + return 0; } } @@ -815,6 +822,8 @@ spmCopy( const spmatrix_t *spm ) newspm->values = malloc(valsize); memcpy( newspm->values, spm->values, valsize ); } + + newspm->alloc = 1; return newspm; } diff --git a/src/z_spm_expand.c b/src/z_spm_expand.c index ad4280a1..0fa2d278 100644 --- a/src/z_spm_expand.c +++ b/src/z_spm_expand.c @@ -46,7 +46,9 @@ z_spmCSCExpand(const spmatrix_t *spm) spm_int_t i, j, k, ii, jj, dofi, dofj, col, row, baseval, lda; spm_int_t diag, height; spm_int_t *newcol, *newrow, *oldcol, *oldrow, *dofs; +#if !defined(PRECISION_p) spm_complex64_t *newval = NULL; +#endif spm_complex64_t *oldval2, *oldval = NULL; assert( spm->fmttype == SpmCSC ); @@ -420,9 +422,10 @@ z_spmIJVExpand(const spmatrix_t *spm) spmatrix_t *newspm; spm_int_t i, j, k, ii, jj, dofi, dofj, col, row, baseval; spm_int_t *newcol, *newrow, *oldcol, *oldrow, *dofs; +#if !defined(PRECISION_p) spm_complex64_t *newval = NULL; +#endif spm_complex64_t *oldval = NULL; - assert( spm->fmttype == SpmIJV ); assert( spm->flttype == SpmComplex64 ); @@ -568,7 +571,6 @@ z_spmIJVExpand(const spmatrix_t *spm) assert(spm->loc2glob == NULL); - (void)newval; return newspm; } diff --git a/tools/wrappers/wrap_fortran.py b/tools/wrappers/wrap_fortran.py index 828a8115..69242d33 100644 --- a/tools/wrappers/wrap_fortran.py +++ b/tools/wrappers/wrap_fortran.py @@ -30,6 +30,7 @@ iindent=3 # translation_table of types types_dict = { "int": ("integer(kind=c_int)"), + "int8_t": ("integer(kind=c_int8_t)"), "spm_coeftype_t": ("integer(c_int)"), "spm_dir_t": ("integer(c_int)"), "spm_trans_t": ("integer(c_int)"), diff --git a/tools/wrappers/wrap_python.py b/tools/wrappers/wrap_python.py index 60945858..f1371f77 100644 --- a/tools/wrappers/wrap_python.py +++ b/tools/wrappers/wrap_python.py @@ -26,6 +26,7 @@ iindent=4 # translation_table of types types_dict = { "int": ("c_int"), + "int8_t": ("c_int8)"), "spm_coeftype_t": ("c_int"), "spm_dir_t": ("c_int"), "spm_trans_t": ("c_int"), diff --git a/wrappers/fortran90/examples/spm_driver.f90 b/wrappers/fortran90/examples/spm_driver.f90 index fc7f05e4..3e856d21 100644 --- a/wrappers/fortran90/examples/spm_driver.f90 +++ b/wrappers/fortran90/examples/spm_driver.f90 @@ -17,7 +17,7 @@ program spm_driver implicit none type(spmatrix_t), target :: spm - type(spmatrix_t), pointer :: spm2 + type(spmatrix_t), target :: spm2 real(kind=c_double) :: normA real(kind=c_double) :: eps = 1.e-15 integer(c_int) :: info @@ -30,8 +30,8 @@ program spm_driver ! 1- The matrix call spmReadDriver( SpmDriverLaplacian, "d:10:10:10:4.", spm, info ) - call spmCheckAndCorrect( spm, spm2 ) - if (.not. c_associated(c_loc(spm), c_loc(spm2))) then + call spmCheckAndCorrect( spm, spm2, info ) + if ( info .ne. 0 ) then call spmExit( spm ) spm = spm2 end if diff --git a/wrappers/fortran90/examples/spm_user.f90 b/wrappers/fortran90/examples/spm_user.f90 index d511aa1a..8e5f8789 100644 --- a/wrappers/fortran90/examples/spm_user.f90 +++ b/wrappers/fortran90/examples/spm_user.f90 @@ -22,10 +22,11 @@ program spm_user type(c_ptr) :: x0_ptr, x_ptr, b_ptr real(kind=c_double) :: eps = 1.e-15 type(spmatrix_t), target :: spm - type(spmatrix_t), pointer :: spm2 + type(spmatrix_t), target :: spm2 integer(kind=spm_int_t) :: dim1, dim2, dim3, n, nnz integer(kind=spm_int_t) :: i, j, k, l, nrhs integer(c_int) :: info + logical :: spm_modified ! ! Generate a 10x10x10 complex Laplacian in IJV format @@ -112,8 +113,9 @@ program spm_user call spmUpdateComputedFields( spm ) - call spmCheckAndCorrect( spm, spm2 ) - if (.not. c_associated(c_loc(spm), c_loc(spm2))) then + call spmCheckAndCorrect( spm, spm2, info ) + spm_modified = .not. ( info .eq. 0 ) + if ( spm_modified ) then deallocate(rowptr) deallocate(colptr) deallocate(values) @@ -149,6 +151,11 @@ program spm_user call spmCheckAxb( eps, nrhs, spm, x0_ptr, spm%n, b_ptr, spm%n, x_ptr, spm%n, info ) call spmExit( spm ) + if ( .not. spm_modified ) then + deallocate(rowptr) + deallocate(colptr) + deallocate(values) + end if deallocate(x0) deallocate(x) deallocate(b) diff --git a/wrappers/fortran90/src/spmf.f90 b/wrappers/fortran90/src/spmf.f90 index f3c722a0..4a85b145 100644 --- a/wrappers/fortran90/src/spmf.f90 +++ b/wrappers/fortran90/src/spmf.f90 @@ -19,6 +19,7 @@ module spmf implicit none type, bind(c) :: spmatrix_t + integer(kind=c_int8_t) :: alloc integer(c_int) :: mtxtype integer(c_int) :: flttype integer(c_int) :: fmttype @@ -234,13 +235,14 @@ module spmf end interface interface - function spmCheckAndCorrect_c(spm) & + function spmCheckAndCorrect_c(in, out) & bind(c, name='spmCheckAndCorrect') use iso_c_binding import spmatrix_t implicit none - type(c_ptr) :: spmCheckAndCorrect_c - type(c_ptr), value :: spm + integer(kind=c_int) :: spmCheckAndCorrect_c + type(c_ptr), value :: in + type(c_ptr), value :: out end function spmCheckAndCorrect_c end interface @@ -566,13 +568,14 @@ contains value = spmSymmetrize_c(c_loc(spm)) end subroutine spmSymmetrize - subroutine spmCheckAndCorrect(spm, spmo) + subroutine spmCheckAndCorrect(in, out, info) use iso_c_binding implicit none - type(spmatrix_t), intent(inout), target :: spm - type(spmatrix_t), intent(out), pointer :: spmo + type(spmatrix_t), intent(in), target :: in + type(spmatrix_t), intent(inout), target :: out + integer(kind=c_int), intent(out) :: info - call c_f_pointer(spmCheckAndCorrect_c(c_loc(spm)), spmo) + info = spmCheckAndCorrect_c(c_loc(in), c_loc(out)) end subroutine spmCheckAndCorrect subroutine spmGenRHS(type, nrhs, spm, x, ldx, b, ldb, info) diff --git a/wrappers/python/spm/__spm__.py b/wrappers/python/spm/__spm__.py index a4b902fb..507e0d83 100644 --- a/wrappers/python/spm/__spm__.py +++ b/wrappers/python/spm/__spm__.py @@ -23,7 +23,8 @@ from . import libspm from .enum import __spm_int__ class pyspm_spmatrix_t(Structure): - _fields_ = [("mtxtype", c_int ), + _fields_ = [("alloc", c_int8) ), + ("mtxtype", c_int ), ("flttype", c_int ), ("fmttype", c_int ), ("gN", __spm_int__ ), @@ -119,10 +120,11 @@ def pyspm_spmSymmetrize( spm ): libspm.spmSymmetrize.restype = __spm_int__ return libspm.spmSymmetrize( spm ) -def pyspm_spmCheckAndCorrect( spm ): - libspm.spmCheckAndCorrect.argtypes = [ POINTER(pyspm_spmatrix_t) ] - libspm.spmCheckAndCorrect.restype = POINTER(pyspm_spmatrix_t) - return libspm.spmCheckAndCorrect( spm ) +def pyspm_spmCheckAndCorrect( in, out ): + libspm.spmCheckAndCorrect.argtypes = [ POINTER(pyspm_spmatrix_t), + POINTER(pyspm_spmatrix_t) ] + libspm.spmCheckAndCorrect.restype = c_int + return libspm.spmCheckAndCorrect( in, out ) def pyspm_spmGenRHS( type, nrhs, spm, x, ldx, b, ldb ): libspm.spmGenRHS.argtypes = [ c_int, __spm_int__, POINTER(pyspm_spmatrix_t), -- GitLab From db5e70bc7aecf169da090beeae1630540483cbf7 Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Mon, 2 Jul 2018 18:10:56 +0200 Subject: [PATCH 13/22] Missing assert --- src/z_spm_convert_to_ijv.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/z_spm_convert_to_ijv.c b/src/z_spm_convert_to_ijv.c index 6404b208..47328e87 100644 --- a/src/z_spm_convert_to_ijv.c +++ b/src/z_spm_convert_to_ijv.c @@ -41,6 +41,12 @@ z_spmConvertCSC2IJV( spmatrix_t *spm ) spm_int_t *col_ijv, *colptr; spm_int_t i, j, baseval, nnz; + /* + * Make sure that the spm has been internally allocated to avoid freeing + * user's allocated array + */ + assert( spm->alloc ); + /* * Check the baseval */ @@ -91,6 +97,12 @@ z_spmConvertCSR2IJV( spmatrix_t *spm ) spm_int_t *row_ijv, *rowptr; spm_int_t i, j, baseval, nnz; + /* + * Make sure that the spm has been internally allocated to avoid freeing + * user's allocated array + */ + assert( spm->alloc ); + /* * Check the baseval */ -- GitLab From 85c682753eeab112d72e208f01d4a2dc58ef865b Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Mon, 2 Jul 2018 19:36:33 +0200 Subject: [PATCH 14/22] Chane in/out as it is keaywords in python/fortran --- include/spm.h | 2 +- src/spm.c | 14 ++--- tools/wrappers/wrap_python.py | 2 +- wrappers/fortran90/src/spmf.f90 | 14 ++--- wrappers/python/spm/__spm__.py | 6 +- wrappers/python/spm/spm.py | 105 ++++++++++++++++++++++++++++---- 6 files changed, 113 insertions(+), 30 deletions(-) diff --git a/include/spm.h b/include/spm.h index 90940b10..8c04dbe0 100644 --- a/include/spm.h +++ b/include/spm.h @@ -115,7 +115,7 @@ void spmScalVector( spm_coeftype_t flt, double alpha, spm_int_t n, void *x, sp int spmSort( spmatrix_t *spm ); spm_int_t spmMergeDuplicate( spmatrix_t *spm ); spm_int_t spmSymmetrize( spmatrix_t *spm ); -int spmCheckAndCorrect( const spmatrix_t *in, spmatrix_t *out ); +int spmCheckAndCorrect( const spmatrix_t *spm_in, spmatrix_t *spm_out ); /** * @} diff --git a/src/spm.c b/src/spm.c index c2279a82..bfb6d47e 100644 --- a/src/spm.c +++ b/src/spm.c @@ -690,14 +690,14 @@ spmSymmetrize( spmatrix_t *spm ) * *******************************************************************************/ int -spmCheckAndCorrect( const spmatrix_t *in, - spmatrix_t *out ) +spmCheckAndCorrect( const spmatrix_t *spm_in, + spmatrix_t *spm_out ) { spmatrix_t *newspm = NULL; spm_int_t count; /* Let's work on a copy */ - newspm = spmCopy( in ); + newspm = spmCopy( spm_in ); /* PaStiX works on CSC matrices */ spmConvert( SpmCSC, newspm ); @@ -737,15 +737,15 @@ spmCheckAndCorrect( const spmatrix_t *in, * Check if we return the new one, or the original one because no changes * have been made */ - if (( in->fmttype != newspm->fmttype ) || - ( in->nnzexp != newspm->nnzexp ) ) + if (( spm_in->fmttype != newspm->fmttype ) || + ( spm_in->nnzexp != newspm->nnzexp ) ) { - memcpy( out, newspm, sizeof(spmatrix_t) ); + memcpy( spm_out, newspm, sizeof(spmatrix_t) ); free( newspm ); return 1; } else { - memcpy( out, in, sizeof(spmatrix_t) ); + memcpy( spm_out, spm_in, sizeof(spmatrix_t) ); spmExit( newspm ); free( newspm ); return 0; diff --git a/tools/wrappers/wrap_python.py b/tools/wrappers/wrap_python.py index f1371f77..44a75e53 100644 --- a/tools/wrappers/wrap_python.py +++ b/tools/wrappers/wrap_python.py @@ -26,7 +26,7 @@ iindent=4 # translation_table of types types_dict = { "int": ("c_int"), - "int8_t": ("c_int8)"), + "int8_t": ("c_int8"), "spm_coeftype_t": ("c_int"), "spm_dir_t": ("c_int"), "spm_trans_t": ("c_int"), diff --git a/wrappers/fortran90/src/spmf.f90 b/wrappers/fortran90/src/spmf.f90 index 4a85b145..f71a02d0 100644 --- a/wrappers/fortran90/src/spmf.f90 +++ b/wrappers/fortran90/src/spmf.f90 @@ -235,14 +235,14 @@ module spmf end interface interface - function spmCheckAndCorrect_c(in, out) & + function spmCheckAndCorrect_c(spm_in, spm_out) & bind(c, name='spmCheckAndCorrect') use iso_c_binding import spmatrix_t implicit none integer(kind=c_int) :: spmCheckAndCorrect_c - type(c_ptr), value :: in - type(c_ptr), value :: out + type(c_ptr), value :: spm_in + type(c_ptr), value :: spm_out end function spmCheckAndCorrect_c end interface @@ -568,14 +568,14 @@ contains value = spmSymmetrize_c(c_loc(spm)) end subroutine spmSymmetrize - subroutine spmCheckAndCorrect(in, out, info) + subroutine spmCheckAndCorrect(spm_in, spm_out, info) use iso_c_binding implicit none - type(spmatrix_t), intent(in), target :: in - type(spmatrix_t), intent(inout), target :: out + type(spmatrix_t), intent(in), target :: spm_in + type(spmatrix_t), intent(inout), target :: spm_out integer(kind=c_int), intent(out) :: info - info = spmCheckAndCorrect_c(c_loc(in), c_loc(out)) + info = spmCheckAndCorrect_c(c_loc(spm_in), c_loc(spm_out)) end subroutine spmCheckAndCorrect subroutine spmGenRHS(type, nrhs, spm, x, ldx, b, ldb, info) diff --git a/wrappers/python/spm/__spm__.py b/wrappers/python/spm/__spm__.py index 507e0d83..b39def3c 100644 --- a/wrappers/python/spm/__spm__.py +++ b/wrappers/python/spm/__spm__.py @@ -23,7 +23,7 @@ from . import libspm from .enum import __spm_int__ class pyspm_spmatrix_t(Structure): - _fields_ = [("alloc", c_int8) ), + _fields_ = [("alloc", c_int8 ), ("mtxtype", c_int ), ("flttype", c_int ), ("fmttype", c_int ), @@ -120,11 +120,11 @@ def pyspm_spmSymmetrize( spm ): libspm.spmSymmetrize.restype = __spm_int__ return libspm.spmSymmetrize( spm ) -def pyspm_spmCheckAndCorrect( in, out ): +def pyspm_spmCheckAndCorrect( spm_in, spm_out ): libspm.spmCheckAndCorrect.argtypes = [ POINTER(pyspm_spmatrix_t), POINTER(pyspm_spmatrix_t) ] libspm.spmCheckAndCorrect.restype = c_int - return libspm.spmCheckAndCorrect( in, out ) + return libspm.spmCheckAndCorrect( spm_in, spm_out ) def pyspm_spmGenRHS( type, nrhs, spm, x, ldx, b, ldb ): libspm.spmGenRHS.argtypes = [ c_int, __spm_int__, POINTER(pyspm_spmatrix_t), diff --git a/wrappers/python/spm/spm.py b/wrappers/python/spm/spm.py index 016a4cb0..eb8ca174 100644 --- a/wrappers/python/spm/spm.py +++ b/wrappers/python/spm/spm.py @@ -38,14 +38,15 @@ class spmatrix(): if mtxtype_ == mtxtype.HerPosDef: mtxtype_ = mtxtype.Hermitian - self.spm_c = pyspm_spmatrix_t( mtxtype_, - coeftype.Double, - fmttype.CSC, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, None, - layout.ColMajor, - None, None, None, None ) + self.spm_c = pyspm_spmatrix_t( 0, mtxtype_, + coeftype.Double, + fmttype.CSC, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, None, + layout.ColMajor, + None, None, None, None ) self.id_ptr = pointer( self.spm_c ) + if A is not None: self.fromsps( A, mtxtype_ ) elif driver is not None: @@ -124,7 +125,55 @@ class spmatrix(): pyspm_spmReadDriver( driver, filename.encode('utf-8'), self.id_ptr ) + print( "After driver") self.dtype = coeftype.getnptype( self.spm_c.flttype ) + print( "Before Check") + self.checkAndCorrect() + print( "After Check") + + def fromnull( self, A ): + """ + Initialize the SPM wrapper by loading the libraries + """ + + if not sps.isspmatrix(A): + raise TypeError( "A must be of type scipy.sparse matrix" ) + + # Assume A is already in Scipy sparse format + self.dtype = A.dtype + flttype = coeftype.getptype( A.dtype ) + if flttype == -1: + raise TypeError( "Invalid data type. Must be part of (f4, f8, c8 or c16)" ) + + A = sps.csc_matrix( A ) + A.sort_indices() + + # Pointer variables + self.py_colptr = np.array( A.indptr[:], dtype=__spm_int__ ) + self.py_rowptr = np.array( A.indices[:], dtype=__spm_int__ ) + self.py_values = np.array( A.data[:] ) + + if mtxtype_ == mtxtype.SymPosDef: + mtxtype_ = mtxtype.Symmetric + if mtxtype_ == mtxtype.HerPosDef: + mtxtype_ = mtxtype.Hermitian + + self.spm_c.mtxtype = mtxtype_ + self.spm_c.flttype = flttype + self.spm_c.fmttype = fmttype.CSC + self.spm_c.n = A.shape[0] + self.spm_c.nnz = A.getnnz() + self.spm_c.dof = 1 + self.spm_c.dofs = None + self.spm_c.layout = layout.ColMajor + self.spm_c.colptr = self.py_colptr.ctypes.data_as(POINTER(__spm_int__)) + self.spm_c.rowptr = self.py_rowptr.ctypes.data_as(POINTER(__spm_int__)) + self.spm_c.loc2glob = None + self.spm_c.values = self.py_values.ctypes.data_as(c_void_p) + + self.id_ptr = pointer( self.spm_c ) + + self.updateComputedField() self.checkAndCorrect() def scale( self, alpha ): @@ -150,13 +199,16 @@ class spmatrix(): def checkAndCorrect( self ): spm1 = self.id_ptr - spm2 = pyspm_spmCheckAndCorrect( self.id_ptr ) - if (( spm1.contents.fmttype == spm2.contents.fmttype ) and - ( spm1.contents.nnzexp == spm2.contents.nnzexp ) ): + spm2 = spmatrix() + print( spm1 ) + print( spm2 ) + rc = pyspm_spmCheckAndCorrect( self.id_ptr, spm2.id_ptr ) + if ( rc == 0 ): return + self = spm2 self.spm_c = cast( spm2, POINTER(pyspm_spmatrix_t) ).contents self.id_ptr = pointer( self.spm_c ) - + # self.py_colptr = np.frombuffer( (__spm_int__ * (n+1)).from_address( cast(self.spm_c.colptr, c_void_p).value ), __spm_int__ ).copy() self.py_rowptr = np.frombuffer( (__spm_int__ * nnz ).from_address( cast(self.spm_c.rowptr, c_void_p).value ), __spm_int__ ).copy() self.py_values = np.frombuffer( (cflt * nnz ).from_address( self.spm_c.values ), nflt ).copy() @@ -225,3 +277,34 @@ class spmatrix(): x.ctypes.data_as(c_void_p), ldx, b.ctypes.data_as(c_void_p), ldb ) return x, b + + def mult( self, B, C, trans=trans.NoTrans, n=-1, alpha=1.0, beta=0. ): + + m = self.spm_c.n + + B = np.asarray(B, self.dtype) + C = np.asarray(C, self.dtype) + + if n == -1: + if B.ndim == 1: + n = 1 + else: + n = B.shape[1] + + self.__checkVector( m, n, B ) + self.__checkVector( m, n, C ) + + ldb = B.shape[0] + ldc = B.shape[0] + + if n == 1: + pyspm_spmMatVec( trans, alpha, self.id_ptr, + B.ctypes.data_as(c_void_p), + beta, + C.ctypes.data_as(c_void_p) ) + else: + pyspm_spmMatMat( trans, n, alpha, self.id_ptr, + B.ctypes.data_as(c_void_p), ldb, + beta, + C.ctypes.data_as(c_void_p), ldc ) + -- GitLab From 4b1912571149ff7eacd18f5c919ee6ec05e01d33 Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Mon, 2 Jul 2018 19:36:56 +0200 Subject: [PATCH 15/22] Silent warings --- tests/spm_dof_matvec_tests.c | 5 ----- tests/spm_matvec_tests.c | 5 ----- tests/spm_tests.h | 8 ++++---- tests/z_spm_tests.c | 5 +++-- 4 files changed, 7 insertions(+), 16 deletions(-) diff --git a/tests/spm_dof_matvec_tests.c b/tests/spm_dof_matvec_tests.c index 8d5e1a98..1a9c9738 100644 --- a/tests/spm_dof_matvec_tests.c +++ b/tests/spm_dof_matvec_tests.c @@ -23,11 +23,6 @@ #include <time.h> #include "spm_tests.h" -int z_spm_matvec_check( int trans, const spmatrix_t *spm ); -int c_spm_matvec_check( int trans, const spmatrix_t *spm ); -int d_spm_matvec_check( int trans, const spmatrix_t *spm ); -int s_spm_matvec_check( int trans, const spmatrix_t *spm ); - #define PRINT_RES(_ret_) \ if(_ret_) { \ printf("FAILED(%d)\n", _ret_); \ diff --git a/tests/spm_matvec_tests.c b/tests/spm_matvec_tests.c index 1a7c5e40..5cb80698 100644 --- a/tests/spm_matvec_tests.c +++ b/tests/spm_matvec_tests.c @@ -22,11 +22,6 @@ #include <time.h> #include "spm_tests.h" -int z_spm_matvec_check( int trans, const spmatrix_t *spm ); -int c_spm_matvec_check( int trans, const spmatrix_t *spm ); -int d_spm_matvec_check( int trans, const spmatrix_t *spm ); -int s_spm_matvec_check( int trans, const spmatrix_t *spm ); - #define PRINT_RES(_ret_) \ if(_ret_) { \ printf("FAILED(%d)\n", _ret_); \ diff --git a/tests/spm_tests.h b/tests/spm_tests.h index 765de234..7d79984f 100644 --- a/tests/spm_tests.h +++ b/tests/spm_tests.h @@ -72,19 +72,19 @@ int core_sgeadd( spm_trans_t trans, spm_int_t LDB ); void z_spm_print_check( char *filename, const spmatrix_t *spm ); -int z_spm_matvec_check( int trans, const spmatrix_t *spm ); +int z_spm_matvec_check( spm_trans_t trans, const spmatrix_t *spm ); int z_spm_norm_check( const spmatrix_t *spm ); void c_spm_print_check( char *filename, const spmatrix_t *spm ); -int c_spm_matvec_check( int trans, const spmatrix_t *spm ); +int c_spm_matvec_check( spm_trans_t trans, const spmatrix_t *spm ); int c_spm_norm_check( const spmatrix_t *spm ); void d_spm_print_check( char *filename, const spmatrix_t *spm ); -int d_spm_matvec_check( int trans, const spmatrix_t *spm ); +int d_spm_matvec_check( spm_trans_t trans, const spmatrix_t *spm ); int d_spm_norm_check( const spmatrix_t *spm ); void s_spm_print_check( char *filename, const spmatrix_t *spm ); -int s_spm_matvec_check( int trans, const spmatrix_t *spm ); +int s_spm_matvec_check( spm_trans_t trans, const spmatrix_t *spm ); int s_spm_norm_check( const spmatrix_t *spm ); static inline int diff --git a/tests/z_spm_tests.c b/tests/z_spm_tests.c index f6487f29..7c1fdc19 100644 --- a/tests/z_spm_tests.c +++ b/tests/z_spm_tests.c @@ -109,7 +109,7 @@ z_spm_print_check( char *filename, const spmatrix_t *spm ) * Check the accuracy of the solution */ int -z_spm_matvec_check( int trans, const spmatrix_t *spm ) +z_spm_matvec_check( spm_trans_t trans, const spmatrix_t *spm ) { unsigned long long int seed = 35469; spm_complex64_t *A, *x, *y0, *ys, *yd; @@ -161,7 +161,8 @@ z_spm_matvec_check( int trans, const spmatrix_t *spm ) } /* Compute the dense matrix-vector product */ - cblas_zgemm( CblasColMajor, trans, CblasNoTrans, spm->gNexp, 1, spm->gNexp, + cblas_zgemm( CblasColMajor, (enum CBLAS_TRANSPOSE)trans, CblasNoTrans, + spm->gNexp, 1, spm->gNexp, CBLAS_SADDR(zalpha), A, spm->gNexp, x, spm->gNexp, CBLAS_SADDR(zbeta), yd, spm->gNexp ); -- GitLab From 34b2733d01fde802a89281e494d809a427b4bc30 Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Mon, 2 Jul 2018 19:38:06 +0200 Subject: [PATCH 16/22] Remove useless forward check --- wrappers/python/spm_driver.py | 3 +-- wrappers/python/spm_scipy.py | 8 +++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/wrappers/python/spm_driver.py b/wrappers/python/spm_driver.py index fa88e594..99317ab7 100755 --- a/wrappers/python/spm_driver.py +++ b/wrappers/python/spm_driver.py @@ -37,6 +37,5 @@ nrhs = 10 x0, b = A.genRHS( spm.rhstype.RndX, nrhs ) # Check that A * x = b -x = x0.copy() -A.checkAxb( x0, b, x ) +A.checkAxb( None, b, x0 ) diff --git a/wrappers/python/spm_scipy.py b/wrappers/python/spm_scipy.py index 6a574b6a..d2167238 100755 --- a/wrappers/python/spm_scipy.py +++ b/wrappers/python/spm_scipy.py @@ -26,11 +26,13 @@ n = 9 A = sps.spdiags([np.ones(n)*i for i in [4, -1, -1, -1, -1]], [0, 1, 3, -1, -3], n, n) x0 = np.arange(n) -b = A.dot(x0) +b = np.zeros(n) spmA = spm.spmatrix( A ) +# Multiply A by x +spmA.mult( x0, b, trans=spm.trans.NoTrans, alpha=1., beta=0. ) + # Check that A * x = b -x = x0.copy() -spmA.checkAxb( x0, b, x ) +spmA.checkAxb( None, b, x0 ) -- GitLab From 9db56173cafa9503aa214311ca739b6a902e1367 Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Mon, 2 Jul 2018 22:43:58 +0200 Subject: [PATCH 17/22] Silent icc warings --- include/cblas.h | 10 +++++----- tests/get_options.c | 2 +- tests/spm_convert_tests.c | 5 +++-- tests/spm_dof_expand_tests.c | 8 +++++--- tests/spm_dof_matvec_tests.c | 4 +++- tests/spm_dof_norm_tests.c | 10 ++++++---- tests/spm_matvec_tests.c | 6 +++++- tests/spm_norm_tests.c | 6 ++++-- tests/z_spm_tests.c | 2 +- 9 files changed, 33 insertions(+), 20 deletions(-) diff --git a/include/cblas.h b/include/cblas.h index 14756f24..fa70cffa 100644 --- a/include/cblas.h +++ b/include/cblas.h @@ -16,11 +16,11 @@ extern "C" { /* Assume C declarations for C++ */ #define CBLAS_INDEX int #endif -typedef enum {CblasRowMajor=101, CblasColMajor=102} CBLAS_LAYOUT; -typedef enum {CblasNoTrans=111, CblasTrans=112, CblasConjTrans=113} CBLAS_TRANSPOSE; -typedef enum {CblasUpper=121, CblasLower=122} CBLAS_UPLO; -typedef enum {CblasNonUnit=131, CblasUnit=132} CBLAS_DIAG; -typedef enum {CblasLeft=141, CblasRight=142} CBLAS_SIDE; +typedef enum CBLAS_LAYOUT {CblasRowMajor=101, CblasColMajor=102} CBLAS_LAYOUT; +typedef enum CBLAS_TRANSPOSE {CblasNoTrans=111, CblasTrans=112, CblasConjTrans=113} CBLAS_TRANSPOSE; +typedef enum CBLAS_UPLO {CblasUpper=121, CblasLower=122} CBLAS_UPLO; +typedef enum CBLAS_DIAG {CblasNonUnit=131, CblasUnit=132} CBLAS_DIAG; +typedef enum CBLAS_SIDE {CblasLeft=141, CblasRight=142} CBLAS_SIDE; typedef CBLAS_LAYOUT CBLAS_ORDER; /* this for backward compatibility with CBLAS_ORDER */ diff --git a/tests/get_options.c b/tests/get_options.c index 8d8a227b..683d8da0 100644 --- a/tests/get_options.c +++ b/tests/get_options.c @@ -105,7 +105,7 @@ spmGetOptions( int argc, char **argv, exit(0); } - *driver = -1; + *driver = (spm_driver_t)-1; do { #if defined(HAVE_GETOPT_LONG) diff --git a/tests/spm_convert_tests.c b/tests/spm_convert_tests.c index 1bc33bb8..d644cd10 100644 --- a/tests/spm_convert_tests.c +++ b/tests/spm_convert_tests.c @@ -45,7 +45,7 @@ int spmComp( const spmatrix_t *spm1, { spm_int_t *colptr1, *colptr2; spm_int_t *rowptr1, *rowptr2; - int *valptr1, *valptr2; + int *valptr1, *valptr2; spm_int_t i; if ( spm1->fmttype != SpmCSC ) { @@ -108,7 +108,8 @@ int main (int argc, char **argv) char *filename; spmatrix_t spm, *spm2; spm_driver_t driver; - int mtxtype, baseval; + spm_mtxtype_t mtxtype; + int baseval; int ret = SPM_SUCCESS; int err = 0; FILE *f; diff --git a/tests/spm_dof_expand_tests.c b/tests/spm_dof_expand_tests.c index 0a343aa9..e27e495c 100644 --- a/tests/spm_dof_expand_tests.c +++ b/tests/spm_dof_expand_tests.c @@ -54,8 +54,10 @@ int main (int argc, char **argv) spmatrix_t original, *spm; spm_driver_t driver; char *filename; - int spmtype, mtxtype, fmttype, baseval; - int i, rc, dofmax = 3; + spm_mtxtype_t spmtype; + spm_mtxtype_t mtxtype; + spm_fmttype_t fmttype; + int baseval, i, rc, dofmax = 3; /** * Get options from command line @@ -95,7 +97,7 @@ int main (int argc, char **argv) { spmBase( &original, baseval ); - for( fmttype=0; fmttype<3; fmttype++ ) + for( fmttype=SpmCSC; fmttype<=SpmIJV; fmttype++ ) { spmConvert( fmttype, &original ); spm = spmDofExtend( &original, i, dofmax ); diff --git a/tests/spm_dof_matvec_tests.c b/tests/spm_dof_matvec_tests.c index 1a9c9738..41723259 100644 --- a/tests/spm_dof_matvec_tests.c +++ b/tests/spm_dof_matvec_tests.c @@ -41,7 +41,9 @@ int main (int argc, char **argv) spmatrix_t original, *spm; spm_driver_t driver; char *filename; - int spmtype, mtxtype, fmttype, baseval; + spm_mtxtype_t spmtype, mtxtype; + spm_fmttype_t fmttype; + int baseval; int ret = SPM_SUCCESS; int err = 0; int rc, i, dofmax = 3; diff --git a/tests/spm_dof_norm_tests.c b/tests/spm_dof_norm_tests.c index 6d4e74f6..fe229a3a 100644 --- a/tests/spm_dof_norm_tests.c +++ b/tests/spm_dof_norm_tests.c @@ -43,9 +43,11 @@ char* mtxnames[] = { "General", "Symmetric", "Hermitian" }; int main (int argc, char **argv) { spmatrix_t original, *spm; - spm_driver_t driver; - char *filename; - int spmtype, mtxtype, fmttype, baseval; + spm_driver_t driver; + char *filename; + spm_mtxtype_t spmtype, mtxtype; + spm_fmttype_t fmttype; + int baseval; int rc = SPM_SUCCESS; int err = 0; int i, dofmax = 4; @@ -92,7 +94,7 @@ int main (int argc, char **argv) { spmBase( &original, baseval ); - for( fmttype=0; fmttype<3; fmttype++ ) + for( fmttype=SpmCSC; fmttype<=SpmIJV; fmttype++ ) { spmConvert( fmttype, &original ); spm = spmDofExtend( &original, i, dofmax ); diff --git a/tests/spm_matvec_tests.c b/tests/spm_matvec_tests.c index 5cb80698..2ccd492b 100644 --- a/tests/spm_matvec_tests.c +++ b/tests/spm_matvec_tests.c @@ -41,7 +41,11 @@ int main (int argc, char **argv) spmatrix_t spm; spm_driver_t driver; char *filename; - int t,spmtype, mtxtype, fmttype, baseval; + spm_trans_t t; + spm_mtxtype_t spmtype; + spm_mtxtype_t mtxtype; + spm_fmttype_t fmttype; + int baseval; int rc = SPM_SUCCESS; int err = 0; diff --git a/tests/spm_norm_tests.c b/tests/spm_norm_tests.c index d6824b73..b2ae5a42 100644 --- a/tests/spm_norm_tests.c +++ b/tests/spm_norm_tests.c @@ -45,7 +45,9 @@ int main (int argc, char **argv) spmatrix_t spm; spm_driver_t driver; char *filename; - int spmtype, mtxtype, fmttype, baseval; + spm_mtxtype_t spmtype, mtxtype; + spm_fmttype_t fmttype; + int baseval; int rc = SPM_SUCCESS; int err = 0; @@ -70,7 +72,7 @@ int main (int argc, char **argv) spmtype = spm.mtxtype; printf(" -- SPM Norms Test --\n"); - for( fmttype=0; fmttype<3; fmttype++ ) { + for( fmttype=SpmCSC; fmttype<=SpmIJV; fmttype++ ) { spmConvert( fmttype, &spm ); diff --git a/tests/z_spm_tests.c b/tests/z_spm_tests.c index 7c1fdc19..17f0bb8c 100644 --- a/tests/z_spm_tests.c +++ b/tests/z_spm_tests.c @@ -161,7 +161,7 @@ z_spm_matvec_check( spm_trans_t trans, const spmatrix_t *spm ) } /* Compute the dense matrix-vector product */ - cblas_zgemm( CblasColMajor, (enum CBLAS_TRANSPOSE)trans, CblasNoTrans, + cblas_zgemm( CblasColMajor, (CBLAS_TRANSPOSE)trans, CblasNoTrans, spm->gNexp, 1, spm->gNexp, CBLAS_SADDR(zalpha), A, spm->gNexp, x, spm->gNexp, -- GitLab From 0145394fb512d3621f19794b2da21bcfc283d77c Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Mon, 2 Jul 2018 23:06:29 +0200 Subject: [PATCH 18/22] remove the useless fromnull --- wrappers/python/spm/spm.py | 45 -------------------------------------- 1 file changed, 45 deletions(-) diff --git a/wrappers/python/spm/spm.py b/wrappers/python/spm/spm.py index eb8ca174..3803f7d4 100644 --- a/wrappers/python/spm/spm.py +++ b/wrappers/python/spm/spm.py @@ -131,51 +131,6 @@ class spmatrix(): self.checkAndCorrect() print( "After Check") - def fromnull( self, A ): - """ - Initialize the SPM wrapper by loading the libraries - """ - - if not sps.isspmatrix(A): - raise TypeError( "A must be of type scipy.sparse matrix" ) - - # Assume A is already in Scipy sparse format - self.dtype = A.dtype - flttype = coeftype.getptype( A.dtype ) - if flttype == -1: - raise TypeError( "Invalid data type. Must be part of (f4, f8, c8 or c16)" ) - - A = sps.csc_matrix( A ) - A.sort_indices() - - # Pointer variables - self.py_colptr = np.array( A.indptr[:], dtype=__spm_int__ ) - self.py_rowptr = np.array( A.indices[:], dtype=__spm_int__ ) - self.py_values = np.array( A.data[:] ) - - if mtxtype_ == mtxtype.SymPosDef: - mtxtype_ = mtxtype.Symmetric - if mtxtype_ == mtxtype.HerPosDef: - mtxtype_ = mtxtype.Hermitian - - self.spm_c.mtxtype = mtxtype_ - self.spm_c.flttype = flttype - self.spm_c.fmttype = fmttype.CSC - self.spm_c.n = A.shape[0] - self.spm_c.nnz = A.getnnz() - self.spm_c.dof = 1 - self.spm_c.dofs = None - self.spm_c.layout = layout.ColMajor - self.spm_c.colptr = self.py_colptr.ctypes.data_as(POINTER(__spm_int__)) - self.spm_c.rowptr = self.py_rowptr.ctypes.data_as(POINTER(__spm_int__)) - self.spm_c.loc2glob = None - self.spm_c.values = self.py_values.ctypes.data_as(c_void_p) - - self.id_ptr = pointer( self.spm_c ) - - self.updateComputedField() - self.checkAndCorrect() - def scale( self, alpha ): return pyspm_spmScalMatrix( float(alpha), self.id_ptr ) -- GitLab From c02380654b45ea7d3727911a9d9390be072549de Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Mon, 2 Jul 2018 23:10:41 +0200 Subject: [PATCH 19/22] Remove dirty lines added for debug --- wrappers/python/spm/spm.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/wrappers/python/spm/spm.py b/wrappers/python/spm/spm.py index 3803f7d4..1543aff1 100644 --- a/wrappers/python/spm/spm.py +++ b/wrappers/python/spm/spm.py @@ -125,11 +125,8 @@ class spmatrix(): pyspm_spmReadDriver( driver, filename.encode('utf-8'), self.id_ptr ) - print( "After driver") self.dtype = coeftype.getnptype( self.spm_c.flttype ) - print( "Before Check") self.checkAndCorrect() - print( "After Check") def scale( self, alpha ): return pyspm_spmScalMatrix( float(alpha), self.id_ptr ) @@ -155,15 +152,12 @@ class spmatrix(): def checkAndCorrect( self ): spm1 = self.id_ptr spm2 = spmatrix() - print( spm1 ) - print( spm2 ) rc = pyspm_spmCheckAndCorrect( self.id_ptr, spm2.id_ptr ) if ( rc == 0 ): return self = spm2 self.spm_c = cast( spm2, POINTER(pyspm_spmatrix_t) ).contents self.id_ptr = pointer( self.spm_c ) - # self.py_colptr = np.frombuffer( (__spm_int__ * (n+1)).from_address( cast(self.spm_c.colptr, c_void_p).value ), __spm_int__ ).copy() self.py_rowptr = np.frombuffer( (__spm_int__ * nnz ).from_address( cast(self.spm_c.rowptr, c_void_p).value ), __spm_int__ ).copy() self.py_values = np.frombuffer( (cflt * nnz ).from_address( self.spm_c.values ), nflt ).copy() -- GitLab From 3599defee996d846d4d9dd0b346894dde7e8e92c Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Tue, 3 Jul 2018 14:51:15 +0200 Subject: [PATCH 20/22] Remove the alloc field --- include/spm.h | 2 -- src/spm.c | 1 - src/z_spm_convert_to_ijv.c | 12 ------------ wrappers/fortran90/src/spmf.f90 | 1 - wrappers/python/spm/__spm__.py | 3 +-- wrappers/python/spm/spm.py | 2 +- 6 files changed, 2 insertions(+), 19 deletions(-) diff --git a/include/spm.h b/include/spm.h index 8c04dbe0..5f11776a 100644 --- a/include/spm.h +++ b/include/spm.h @@ -48,8 +48,6 @@ * */ typedef struct spmatrix_s { - int8_t alloc; /**< Internal field to detect if the internal buffers has been - user allocated or not. */ spm_mtxtype_t mtxtype; /**< Matrix structure: SpmGeneral, SpmSymmetric or SpmHermitian. */ spm_coeftype_t flttype; /**< values datatype: SpmPattern, SpmFloat, SpmDouble, diff --git a/src/spm.c b/src/spm.c index bfb6d47e..64d74e91 100644 --- a/src/spm.c +++ b/src/spm.c @@ -823,7 +823,6 @@ spmCopy( const spmatrix_t *spm ) memcpy( newspm->values, spm->values, valsize ); } - newspm->alloc = 1; return newspm; } diff --git a/src/z_spm_convert_to_ijv.c b/src/z_spm_convert_to_ijv.c index 47328e87..6404b208 100644 --- a/src/z_spm_convert_to_ijv.c +++ b/src/z_spm_convert_to_ijv.c @@ -41,12 +41,6 @@ z_spmConvertCSC2IJV( spmatrix_t *spm ) spm_int_t *col_ijv, *colptr; spm_int_t i, j, baseval, nnz; - /* - * Make sure that the spm has been internally allocated to avoid freeing - * user's allocated array - */ - assert( spm->alloc ); - /* * Check the baseval */ @@ -97,12 +91,6 @@ z_spmConvertCSR2IJV( spmatrix_t *spm ) spm_int_t *row_ijv, *rowptr; spm_int_t i, j, baseval, nnz; - /* - * Make sure that the spm has been internally allocated to avoid freeing - * user's allocated array - */ - assert( spm->alloc ); - /* * Check the baseval */ diff --git a/wrappers/fortran90/src/spmf.f90 b/wrappers/fortran90/src/spmf.f90 index f71a02d0..639aaacf 100644 --- a/wrappers/fortran90/src/spmf.f90 +++ b/wrappers/fortran90/src/spmf.f90 @@ -19,7 +19,6 @@ module spmf implicit none type, bind(c) :: spmatrix_t - integer(kind=c_int8_t) :: alloc integer(c_int) :: mtxtype integer(c_int) :: flttype integer(c_int) :: fmttype diff --git a/wrappers/python/spm/__spm__.py b/wrappers/python/spm/__spm__.py index b39def3c..55116cd1 100644 --- a/wrappers/python/spm/__spm__.py +++ b/wrappers/python/spm/__spm__.py @@ -23,8 +23,7 @@ from . import libspm from .enum import __spm_int__ class pyspm_spmatrix_t(Structure): - _fields_ = [("alloc", c_int8 ), - ("mtxtype", c_int ), + _fields_ = [("mtxtype", c_int ), ("flttype", c_int ), ("fmttype", c_int ), ("gN", __spm_int__ ), diff --git a/wrappers/python/spm/spm.py b/wrappers/python/spm/spm.py index 1543aff1..79aab068 100644 --- a/wrappers/python/spm/spm.py +++ b/wrappers/python/spm/spm.py @@ -38,7 +38,7 @@ class spmatrix(): if mtxtype_ == mtxtype.HerPosDef: mtxtype_ = mtxtype.Hermitian - self.spm_c = pyspm_spmatrix_t( 0, mtxtype_, + self.spm_c = pyspm_spmatrix_t( mtxtype_, coeftype.Double, fmttype.CSC, 0, 0, 0, 0, 0, 0, 0, 0, -- GitLab From 6290c5185f9c1368ffb5ce466fa0d80b87e5a86a Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Tue, 3 Jul 2018 17:19:30 +0200 Subject: [PATCH 21/22] PRovide an spmAlloc function to allocate arrays in C --- include/spm.h | 5 ++-- src/spm.c | 52 +++++++++++++++++++++++++++++++++ wrappers/fortran90/src/spmf.f90 | 18 ++++++++++++ wrappers/python/spm/__spm__.py | 4 +++ 4 files changed, 77 insertions(+), 2 deletions(-) diff --git a/include/spm.h b/include/spm.h index 5f11776a..9d4ac2f9 100644 --- a/include/spm.h +++ b/include/spm.h @@ -81,8 +81,9 @@ typedef struct spmatrix_s { * @name SPM basic subroutines * @{ */ -void spmInit( spmatrix_t *spm ); -void spmExit( spmatrix_t *spm ); +void spmInit ( spmatrix_t *spm ); +void spmAlloc( spmatrix_t *spm ); +void spmExit ( spmatrix_t *spm ); spmatrix_t *spmCopy( const spmatrix_t *spm ); void spmBase( spmatrix_t *spm, int baseval ); diff --git a/src/spm.c b/src/spm.c index 64d74e91..5af62625 100644 --- a/src/spm.c +++ b/src/spm.c @@ -190,6 +190,58 @@ spmUpdateComputedFields( spmatrix_t *spm ) spm->gnnzexp = spm->nnzexp; } +/** + ******************************************************************************* + * + * @brief Allocate the arrays of an spm structure with PaStiX internal + * allocations. + * + * This function must be called after initialization of the non-computed fields, + * and the call to spmUpdateComputedFields(). It allocates the colptr, rowptr, + * dof, and values arrays with PaStiX C malloc function. This is highly + * recommended to use this function when using PaStiX from Fortran. + * + ******************************************************************************* + * + * @param[inout] spm + * The sparse matrix fr which the internal arrays needs to be allocated. + * + *******************************************************************************/ +void +spmAlloc( spmatrix_t *spm ) +{ + switch(spm->fmttype){ + case SpmCSC: + colsize = spm->n + 1; + rowsize = spm->nnz; + valsize = spm->nnzexp; + dofsize = spm->n + 1; + break; + case SpmCSR: + colsize = spm->nnz; + rowsize = spm->n + 1; + valsize = spm->nnzexp; + dofsize = spm->n + 1; + break; + case SpmIJV: + default: + colsize = spm->nnz; + rowsize = spm->nnz; + valsize = spm->nnzexp; + dofsize = spm->n + 1; + } + + spm->colptr = (spm_int_t*)malloc( colsize * sizeof(spm_int_t) ); + spm->rowptr = (spm_int_t*)malloc( rowsize * sizeof(spm_int_t) ); + if ( spm->dof < 1 ) { + spm->dofs = (spm_int_t*)malloc( dofsize * sizeof(spm_int_t) ); + } + if(spm->values != NULL) { + valsize = valsize * spm_size_of( spm->flttype ); + spm->values = malloc(valsize); + } +} + /** ******************************************************************************* * diff --git a/wrappers/fortran90/src/spmf.f90 b/wrappers/fortran90/src/spmf.f90 index 639aaacf..ac0ce6d6 100644 --- a/wrappers/fortran90/src/spmf.f90 +++ b/wrappers/fortran90/src/spmf.f90 @@ -49,6 +49,16 @@ module spmf end subroutine spmInit_c end interface + interface + subroutine spmAlloc_c(spm) & + bind(c, name='spmAlloc') + use iso_c_binding + import spmatrix_t + implicit none + type(c_ptr), value :: spm + end subroutine spmAlloc_c + end interface + interface subroutine spmExit_c(spm) & bind(c, name='spmExit') @@ -417,6 +427,14 @@ contains call spmInit_c(c_loc(spm)) end subroutine spmInit + subroutine spmAlloc(spm) + use iso_c_binding + implicit none + type(spmatrix_t), intent(inout), target :: spm + + call spmAlloc_c(c_loc(spm)) + end subroutine spmAlloc + subroutine spmExit(spm) use iso_c_binding implicit none diff --git a/wrappers/python/spm/__spm__.py b/wrappers/python/spm/__spm__.py index 55116cd1..97148fc1 100644 --- a/wrappers/python/spm/__spm__.py +++ b/wrappers/python/spm/__spm__.py @@ -46,6 +46,10 @@ def pyspm_spmInit( spm ): libspm.spmInit.argtypes = [ POINTER(pyspm_spmatrix_t) ] libspm.spmInit( spm ) +def pyspm_spmAlloc( spm ): + libspm.spmAlloc.argtypes = [ POINTER(pyspm_spmatrix_t) ] + libspm.spmAlloc( spm ) + def pyspm_spmExit( spm ): libspm.spmExit.argtypes = [ POINTER(pyspm_spmatrix_t) ] libspm.spmExit( spm ) -- GitLab From 006fe1a920f92749d88ec702ab752e97e51c784f Mon Sep 17 00:00:00 2001 From: Mathieu Faverge <mathieu.faverge@inria.fr> Date: Tue, 3 Jul 2018 17:37:39 +0200 Subject: [PATCH 22/22] Use spmalloc in spm_user --- src/spm.c | 8 ++-- wrappers/fortran90/examples/spm_user.f90 | 59 +++++++++--------------- 2 files changed, 25 insertions(+), 42 deletions(-) diff --git a/src/spm.c b/src/spm.c index 5af62625..c38e807d 100644 --- a/src/spm.c +++ b/src/spm.c @@ -210,6 +210,8 @@ spmUpdateComputedFields( spmatrix_t *spm ) void spmAlloc( spmatrix_t *spm ) { + spm_int_t colsize, rowsize, valsize, dofsize; + switch(spm->fmttype){ case SpmCSC: colsize = spm->n + 1; @@ -236,10 +238,8 @@ spmAlloc( spmatrix_t *spm ) if ( spm->dof < 1 ) { spm->dofs = (spm_int_t*)malloc( dofsize * sizeof(spm_int_t) ); } - if(spm->values != NULL) { - valsize = valsize * spm_size_of( spm->flttype ); - spm->values = malloc(valsize); - } + valsize = valsize * spm_size_of( spm->flttype ); + spm->values = malloc(valsize); } /** diff --git a/wrappers/fortran90/examples/spm_user.f90 b/wrappers/fortran90/examples/spm_user.f90 index 8e5f8789..833bd409 100644 --- a/wrappers/fortran90/examples/spm_user.f90 +++ b/wrappers/fortran90/examples/spm_user.f90 @@ -15,9 +15,9 @@ program spm_user use spmf implicit none - integer(kind=spm_int_t), dimension(:), allocatable, target :: rowptr - integer(kind=spm_int_t), dimension(:), allocatable, target :: colptr - real(kind=c_double), dimension(:), allocatable, target :: values + integer(kind=spm_int_t), dimension(:), pointer :: rowptr + integer(kind=spm_int_t), dimension(:), pointer :: colptr + real(kind=c_double), dimension(:), pointer :: values real(kind=c_double), dimension(:,:), allocatable, target :: x0, x, b type(c_ptr) :: x0_ptr, x_ptr, b_ptr real(kind=c_double) :: eps = 1.e-15 @@ -26,7 +26,6 @@ program spm_user integer(kind=spm_int_t) :: dim1, dim2, dim3, n, nnz integer(kind=spm_int_t) :: i, j, k, l, nrhs integer(c_int) :: info - logical :: spm_modified ! ! Generate a 10x10x10 complex Laplacian in IJV format @@ -37,9 +36,23 @@ program spm_user n = dim1 * dim2 * dim3 nnz = (2*(dim1)-1) * dim2 * dim3 + (dim2-1)*dim1*dim3 + dim2*dim1*(dim3-1) - allocate(rowptr(nnz)) - allocate(colptr(nnz)) - allocate(values(nnz)) + ! + ! Create the spm out of the internal data + ! + call spmInit( spm ) + spm%mtxtype = SpmSymmetric + spm%flttype = SpmDouble + spm%fmttype = SpmIJV + spm%n = n + spm%nnz = nnz + spm%dof = 1 + + call spmUpdateComputedFields( spm ) + call spmAlloc( spm ) + + call c_f_pointer( spm%rowptr, rowptr, [nnz] ) + call c_f_pointer( spm%colptr, colptr, [nnz] ) + call c_f_pointer( spm%values, values, [nnz] ) l = 1 do i=1,dim1 @@ -97,33 +110,8 @@ program spm_user write(6,*) 'l ', l, " nnz ", nnz end if - ! - ! Create the spm out of the internal data - ! - call spmInit( spm ) - spm%mtxtype = SpmSymmetric - spm%flttype = SpmDouble - spm%fmttype = SpmIJV - spm%n = n - spm%nnz = nnz - spm%dof = 1 - spm%rowptr = c_loc(rowptr) - spm%colptr = c_loc(colptr) - spm%values = c_loc(values) - - call spmUpdateComputedFields( spm ) - call spmCheckAndCorrect( spm, spm2, info ) - spm_modified = .not. ( info .eq. 0 ) - if ( spm_modified ) then - deallocate(rowptr) - deallocate(colptr) - deallocate(values) - - spm%rowptr = c_null_ptr - spm%colptr = c_null_ptr - spm%values = c_null_ptr - + if ( info .ne. 0 ) then call spmExit( spm ) spm = spm2 end if @@ -151,11 +139,6 @@ program spm_user call spmCheckAxb( eps, nrhs, spm, x0_ptr, spm%n, b_ptr, spm%n, x_ptr, spm%n, info ) call spmExit( spm ) - if ( .not. spm_modified ) then - deallocate(rowptr) - deallocate(colptr) - deallocate(values) - end if deallocate(x0) deallocate(x) deallocate(b) -- GitLab