SpM Handbook 1.2.4
Loading...
Searching...
No Matches
s_spm_mergeduplicate.c
Go to the documentation of this file.
1/**
2 *
3 * @file s_spm_mergeduplicate.c
4 *
5 * SParse Matrix package precision dependent routines.
6 *
7 * @copyright 2016-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
8 * Univ. Bordeaux. All rights reserved.
9 *
10 * @version 1.2.4
11 * @author Mathieu Faverge
12 * @author Tony Delarue
13 * @author Alycia Lisito
14 * @date 2024-06-25
15 *
16 * @generated from /builds/2mk6rsew/0/fpruvost/spm/src/z_spm_mergeduplicate.c, normal z -> s, Fri Nov 29 11:34:30 2024
17 *
18 **/
19#include "common.h"
20#include <string.h>
21
22/**
23 *******************************************************************************
24 *
25 * @ingroup spm_dev_check
26 *
27 * @brief This routine merge the multiple entries in a sparse matrix by summing
28 * their values together.
29 *
30 * The sparse matrix needs to be sorted first (see s_spmSort()). In distributed,
31 * only local entries are merged together.
32 *
33 *******************************************************************************
34 *
35 * @param[inout] spm
36 * On entry, the pointer to the sparse matrix structure.
37 * On exit, the reducton of the input sparse matrix where multiple
38 * occurences of a same element are summed up together.
39 *
40 ********************************************************************************
41 *
42 * @return The number of vertices that were merged. -1 on error.
43 *
44 *******************************************************************************/
47{
48 spm_int_t *colptr = (spm->fmttype == SpmCSC) ? spm->colptr : spm->rowptr;
49 spm_int_t *oldrow = (spm->fmttype == SpmCSC) ? spm->rowptr : spm->colptr;
50 spm_int_t *newrow = oldrow;
51 float *newval = spm->values;
52 float *oldval = spm->values;
53 spm_int_t *loc2glob = spm->loc2glob;
54
55 spm_int_t merge = 0;
56 spm_int_t n = spm->n;
57 spm_int_t baseval = spm->baseval;
58 spm_int_t ig, jl, jg, dofi, dofj, dof2;
59 spm_int_t k, idx, size, valsize, savedcolptr;
60#if !defined(PRECISION_p)
61 spm_int_t d;
62#endif
63
64 if ( (spm->fmttype != SpmCSC) &&
65 (spm->fmttype != SpmCSR) )
66 {
67 fprintf(stderr, "Error : MergeDuplicate can only be called with SpmCSC or SpmCSR\n");
69 }
70
71 idx = baseval;
72 valsize = 0;
73 savedcolptr = colptr[0];
74 for (jl=0; jl<n; jl++, colptr++, loc2glob++)
75 {
76 jg = spm->replicated ? jl : *loc2glob - baseval;
77 dofj = (spm->dof > 0) ? spm->dof : spm->dofs[jg+1] - spm->dofs[jg];
78 size = colptr[1] - savedcolptr;
79 savedcolptr = colptr[1];
80
81 for ( k=0; k<size; k++, idx++ )
82 {
83 ig = *newrow - baseval;
84 dofi = (spm->dof > 0) ? spm->dof : spm->dofs[ig+1] - spm->dofs[ig];
85 dof2 = dofi * dofj;
86 valsize += dof2;
87
88 /*
89 * A shift has been introduced, we need to first compact the structure
90 */
91 if ( newrow != oldrow ) {
92 newrow[0] = oldrow[0];
93#if !defined(PRECISION_p)
94 memcpy( newval, oldval, dof2 * sizeof(float) );
95#endif
96 }
97
98 /*
99 * Let's sum together all identical elements
100 */
101 while( ((k+1) < size) && (newrow[0] == oldrow[1]) ) {
102 k++;
103 oldrow++;
104 oldval += dof2;
105#if !defined(PRECISION_p)
106 /* Merge the two sets of values */
107 for ( d=0; d<dof2; d++ ) {
108 newval[d] += oldval[d];
109 }
110#endif
111 merge++;
112 }
113
114 /* Shift arrays */
115 oldrow++;
116 newrow++;
117 oldval += dof2;
118 newval += dof2;
119 }
120 assert( ( (merge == 0) && (colptr[1] == idx) ) ||
121 ( (merge != 0) && (colptr[1] > idx) ) );
122
123 colptr[1] = idx;
124 }
125 assert( ((merge == 0) && (spm->nnz == (idx-baseval))) ||
126 ((merge != 0) && (spm->nnz - merge == (idx-baseval))) );
127
128 /*
129 * Realloc the arrays if they have been compacted
130 */
131 if ( merge > 0 ) {
132 spm->nnz = spm->nnz - merge;
133 spm->nnzexp = valsize;
134
135 if ( spm->fmttype == SpmCSC ) {
136 spm->rowptr = realloc( spm->rowptr, spm->nnz * sizeof( spm_int_t ) );
137 }
138 else {
139 spm->colptr = realloc( spm->colptr, spm->nnz * sizeof( spm_int_t ) );
140 }
141
142#if !defined(PRECISION_p)
143 spm->values = realloc( spm->values, valsize * sizeof( float ) );
144#endif
145 }
146
147 (void) newval;
148 (void) oldval;
149
150 return merge;
151}
@ SPM_ERR_BADPARAMETER
Definition const.h:89
@ SpmCSC
Definition const.h:73
@ SpmCSR
Definition const.h:74
spm_int_t s_spmMergeDuplicate(spmatrix_t *spm)
This routine merge the multiple entries in a sparse matrix by summing their values together.
spm_int_t * dofs
Definition spm.h:85
void * values
Definition spm.h:92
spm_int_t nnz
Definition spm.h:75
spm_int_t nnzexp
Definition spm.h:80
spm_int_t * rowptr
Definition spm.h:90
spm_fmttype_t fmttype
Definition spm.h:69
spm_int_t dof
Definition spm.h:82
spm_int_t n
Definition spm.h:73
spm_int_t * loc2glob
Definition spm.h:91
spm_int_t baseval
Definition spm.h:71
spm_int_t * colptr
Definition spm.h:89
int replicated
Definition spm.h:98
int spm_int_t
The main integer datatype used in spm arrays.
Definition datatypes.h:70
The sparse matrix data structure.
Definition spm.h:64