From fb6ff07b22cfcc8df2dd3f2046ef665fd1f14b1c Mon Sep 17 00:00:00 2001
From: Mathieu Faverge <mathieu.faverge@inria.fr>
Date: Tue, 4 Jul 2017 16:30:18 +0200
Subject: [PATCH] Add spmNew, spmFree function for better handling of the spm
 in Fortran

---
 spm.c | 177 ++++++++++++++++++++++++++++++++++++++++++++--------------
 spm.h |  31 +++++-----
 2 files changed, 150 insertions(+), 58 deletions(-)

diff --git a/spm.c b/spm.c
index ec492b5b..0fb03d1d 100644
--- a/spm.c
+++ b/spm.c
@@ -191,37 +191,99 @@ spmUpdateComputedFields( pastix_spm_t *spm )
 /**
  *******************************************************************************
  *
- * @brief Init the spm structure.
+ * @brief Generate a new spm structure out of the provided information.
  *
  *******************************************************************************
  *
- * @param[inout] spm
- *          The sparse matrix to init.
+ * @param[in] mtxtype
+ *          Specify the matrix symmetry property
+ *          - PastixGeneral, if the matrix is general
+ *          - PastixSymmetric, if the matrix is symmetric
+ *          - PastixHermitian, if the matrix is complex hermitian
+ *
+ * @param[in] flttype
+ *          Specify the floating point arithmetic used by the matrix
+ *          - PastixPattern, if only the pattern is provided and no values
+ *          - PastixFloat, if the values are real single precision
+ *          - PastixDouble, if the values are real double precision
+ *          - PastixComplex32, if the values are complex single precision
+ *          - PastixComplex64, if the values are complex double precision
+ *
+ * @param[in] fmttype
+ *          Specify the format used to store the matrix
+ *          - PastixIJV, if in the IJV format
+ *          - PastixCSC, if in the compressed sparse column format
+ *          - PastixCSR, if in the compressed sparse row format
+ *
+ * @param[in] n
+ *          Specify the number of unknow in the matrix graph
+ *
+ * @param[in] nnz
+ *          Specify the number of non-zeros in the matrix graph (ie the number
+ *          of edges)
+ *
+ * @param[in] colptr
+ *          The column index array of size n+1 if fmttype == PastixCSC, nnz
+ *          otherwise.
+ *
+ * @param[in] rowptr
+ *          The row index array of size n+1 if fmttype == PastixCSR, nnz
+ *          otherwise.
+ *
+ * @param[in] values
+ *          The values array in type flttype and of size nnz, or nnz * (the size
+ *          of each elemental matrix) if the numbef of degrees of freedom is
+ *          different from 1.
+ *
+ * @param[in] loc2glob
+ *          The correspondance array of local indices vertices to global
+ *          numbering. (Unused for now)
+ *
+ * @param[in] dof Sepecify the degrees of freedom of each elementary. It must be
+ *          1 by default. If dof > 1, the a constant degree of freedom is used,
+ *          otherwise if dof < 1, variadic degrees are used and specified by
+ *          dofs.
+ *
+ * @param[in] layout
+ *          Specify the layout used to stotre each elementatry matrix in the
+ *          values array.
+ *          - PastixRowMajor, if row major layout
+ *          - PastixColMajor, if column major layout
+ *
+ * @param[in] dofs
+ *          The index array of each local vertex in the expanded matrix of size
+ *          n+1. The degree of freedom of the vertex i is given by
+ *          dofs[i+1]-dofs[i].
+ *
+ *******************************************************************************
+ *
+ * @return The newly allocated matrix on success, and NULL otherwise.
  *
  *******************************************************************************/
-void
-spm( pastix_spm_t      *spm,
-     pastix_symmetry_t  mtxtype,
-     pastix_coeftype_t  flttype,
-     pastix_fmttype_t   fmttype,
-     pastix_int_t       n,
-     pastix_int_t       nnz,
-     pastix_int_t      *colptr,
-     pastix_int_t      *rowptr,
-     void              *values,
-     pastix_int_t      *loc2glob,
-     pastix_int_t       dof,
-     pastix_layout_t    layout,
-     pastix_int_t      *dofs )
+pastix_spm_t *
+spmNew( pastix_symmetry_t  mtxtype,
+        pastix_coeftype_t  flttype,
+        pastix_fmttype_t   fmttype,
+        pastix_int_t       n,
+        pastix_int_t       nnz,
+        pastix_int_t      *colptr,
+        pastix_int_t      *rowptr,
+        void              *values,
+        pastix_int_t      *loc2glob,
+        pastix_int_t       dof,
+        pastix_layout_t    layout,
+        pastix_int_t      *dofs )
 {
+    pastix_spm_t *spm = malloc( sizeof(pastix_spm_t) );
     spmInit( spm );
 
-    if ( ( mtxtype != PastixGeneral ) &&
-         ( mtxtype != PastixGeneral ) &&
-         ( mtxtype != PastixGeneral ) )
+    if ( ( mtxtype != PastixGeneral   ) &&
+         ( mtxtype != PastixSymmetric ) &&
+         ( mtxtype != PastixHermitian ) )
     {
-        fprintf(stderr, "spm: The sparse matrix type must be PastixGeneral, PastixSymmetric or PastixHermitian\n");
-        return;
+        fprintf(stderr, "spmNew: The sparse matrix type must be PastixGeneral, PastixSymmetric or PastixHermitian\n");
+        free( spm );
+        return NULL;
     }
     spm->mtxtype = mtxtype;
 
@@ -231,8 +293,9 @@ spm( pastix_spm_t      *spm,
          ( flttype != PastixComplex32 ) &&
          ( flttype != PastixComplex64 ) )
     {
-        fprintf(stderr, "spm: The sparse matrix coefficient type must be PastixPattern, PastixFloat, PastixDouble, PastixComplex32, or PastixComplex64\n");
-        return;
+        fprintf(stderr, "spmNew: The sparse matrix coefficient type must be PastixPattern, PastixFloat, PastixDouble, PastixComplex32, or PastixComplex64\n");
+        free( spm );
+        return NULL;
     }
     spm->flttype = flttype;
 
@@ -240,47 +303,54 @@ spm( pastix_spm_t      *spm,
          ( fmttype != PastixCSR ) &&
          ( fmttype != PastixIJV ) )
     {
-        fprintf(stderr, "spm: The sparse matrix format type must be PastixCSC, PastixCSR, or PastixIJV\n");
-        return;
+        fprintf(stderr, "spmNew: The sparse matrix format type must be PastixCSC, PastixCSR, or PastixIJV\n");
+        free( spm );
+        return NULL;
     }
     spm->fmttype = fmttype;
 
     if ( n <= 0 )
     {
-        fprintf(stderr, "spm: The local matrix size n, must be strictly positive\n");
-        return;
+        fprintf(stderr, "spmNew: The local matrix size n, must be strictly positive\n");
+        free( spm );
+        return NULL;
     }
     spm->n = n;
 
     if ( nnz <= 0 )
     {
-        fprintf(stderr, "spm: The number of non zeros in the local matrix must be strictly positive\n");
-        return;
+        fprintf(stderr, "spmNew: The number of non zeros in the local matrix must be strictly positive\n");
+        free( spm );
+        return NULL;
     }
     spm->nnz = nnz;
 
     if ( colptr == NULL ) {
-        fprintf(stderr, "spm: The colptr array must be provided and of size n+1, if PastixCSC, nnz otherwise\n");
-        return;
+        fprintf(stderr, "spmNew: The colptr array must be provided and of size n+1, if PastixCSC, nnz otherwise\n");
+        free( spm );
+        return NULL;
     }
     spm->colptr   = colptr;
 
     if ( rowptr == NULL ) {
-        fprintf(stderr, "spm: The rowptr array must be provided and of size n+1, if PastixCSR, nnz otherwise\n");
-        return;
+        fprintf(stderr, "spmNew: The rowptr array must be provided and of size n+1, if PastixCSR, nnz otherwise\n");
+        free( spm );
+        return NULL;
     }
     spm->rowptr   = rowptr;
 
 
     if ( loc2glob != NULL ) {
-        fprintf(stderr, "spm: The distributed interface is not supported for now\n");
-        return;
+        fprintf(stderr, "spmNew: The distributed interface is not supported for now\n");
+        free( spm );
+        return NULL;
     }
     spm->loc2glob = NULL;
 
     if ( (flttype != PastixPattern) && (values == NULL) ) {
-        fprintf(stderr, "spm: The values array of size nnz, and of type flttype must be provided\n");
-        return;
+        fprintf(stderr, "spmNew: The values array of size nnz, and of type flttype must be provided\n");
+        free( spm );
+        return NULL;
     }
     spm->values = values;
 
@@ -291,15 +361,17 @@ spm( pastix_spm_t      *spm,
         if ( ( layout != PastixColMajor ) &&
              ( layout != PastixRowMajor ) )
         {
-            fprintf(stderr, "spm: The sparse matrix layout for multi-dof must be PastixColMajor or PastixRowMajor\n");
-            return;
+            fprintf(stderr, "spmNew: The sparse matrix layout for multi-dof must be PastixColMajor or PastixRowMajor\n");
+            free( spm );
+            return NULL;
         }
         spm->layout = layout;
 
         if ( dof < 1 ) {
             if ( dofs == NULL ) {
-                fprintf(stderr, "spm: The dofs array must be provided when dof < 1\n");
-                return;
+                fprintf(stderr, "spmNew: The dofs array must be provided when dof < 1\n");
+                free( spm );
+                return NULL;
             }
             spm->dofs = dofs;
         }
@@ -308,12 +380,13 @@ spm( pastix_spm_t      *spm,
         }
     }
     spmUpdateComputedFields( spm );
+    return spm;
 }
 
 /**
  *******************************************************************************
  *
- * @brief Free the spm structure.
+ * @brief Cleanup the spm structure but do not free the spm pointer.
  *
  *******************************************************************************
  *
@@ -336,6 +409,24 @@ spmExit( pastix_spm_t *spm )
         memFree_null(spm->dofs);
 }
 
+/**
+ *******************************************************************************
+ *
+ * @brief Cleanup the spm structure and free the spm pointer.
+ *
+ *******************************************************************************
+ *
+ * @param[inout] spm
+ *          The sparse matrix to free.
+ *
+ *******************************************************************************/
+void
+spmFree( pastix_spm_t *spm )
+{
+    spmExit( spm );
+    free( spm );
+}
+
 /**
  *******************************************************************************
  *
diff --git a/spm.h b/spm.h
index 44c214d0..3c470ce1 100644
--- a/spm.h
+++ b/spm.h
@@ -75,27 +75,28 @@ typedef struct pastix_spm_s {
  * @name SPM basic subroutines
  * @{
  */
-void          spmInit( pastix_spm_t *spm );
-void          spmExit( pastix_spm_t *spm );
+pastix_spm_t *spmNew(  pastix_symmetry_t  mtxtype,
+                       pastix_coeftype_t  flttype,
+                       pastix_fmttype_t   fmttype,
+                       pastix_int_t       n,
+                       pastix_int_t       nnz,
+                       pastix_int_t      *colptr,
+                       pastix_int_t      *rowptr,
+                       void              *values,
+                       pastix_int_t      *loc2glob,
+                       pastix_int_t       dof,
+                       pastix_layout_t    layout,
+                       pastix_int_t      *dofs );
+void          spmInit( pastix_spm_t      *spm );
+void          spmExit( pastix_spm_t      *spm );
+void          spmFree( pastix_spm_t      *spm );
+
 pastix_spm_t *spmCopy( const pastix_spm_t *spm );
 void          spmBase( pastix_spm_t *spm, int baseval );
 pastix_int_t  spmFindBase( const pastix_spm_t *spm );
 int           spmConvert( int ofmttype, pastix_spm_t *ospm );
 void          spmUpdateComputedFields( pastix_spm_t *spm );
 
-void          spm( pastix_spm_t      *spm,
-                   pastix_symmetry_t  mtxtype,
-                   pastix_coeftype_t  flttype,
-                   pastix_fmttype_t   fmttype,
-                   pastix_int_t       n,
-                   pastix_int_t       nnz,
-                   pastix_int_t      *colptr,
-                   pastix_int_t      *rowptr,
-                   void              *values,
-                   pastix_int_t      *loc2glob,
-                   pastix_int_t       dof,
-                   pastix_layout_t    layout,
-                   pastix_int_t      *dofs );
 
 /**
  * @}
-- 
GitLab