1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
//------------------------------------------------------------------------------
// GB_jappend.h: definitions of GB_jappend, and GB_jwrapup
//------------------------------------------------------------------------------
// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2022, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//------------------------------------------------------------------------------
// These methods are now only used by GB_wait.
#ifndef GB_JAPPEND_H
#define GB_JAPPEND_H
#include "GB.h"
//------------------------------------------------------------------------------
// GB_jappend: append a new vector to the end of a matrix
//------------------------------------------------------------------------------
// Append a new vector to the end of a matrix C.
// If C->h != NULL, C is in hypersparse form with
// C->nvec <= C->plen <= C->vdim. C->h has size C->plen.
// If C->h == NULL, C is in non-hypersparse form with
// C->nvec == C->plen == C->vdim. C->h is NULL.
// In both cases, C->p has size C->plen+1.
static inline GrB_Info GB_jappend
(
GrB_Matrix C, // matrix to append vector j to
int64_t j, // new vector to append
int64_t *jlast, // last vector appended, -1 if none
int64_t cnz, // nnz(C) after adding this vector j
int64_t *cnz_last, // nnz(C) before adding this vector j
GB_Context Context
)
{
//--------------------------------------------------------------------------
// check inputs
//--------------------------------------------------------------------------
ASSERT (C != NULL) ;
ASSERT (!C->p_shallow) ;
ASSERT (!C->h_shallow) ;
ASSERT (C->p != NULL) ;
ASSERT (!GB_IS_FULL (C)) ;
if (cnz <= (*cnz_last))
{
// nothing to do
return (GrB_SUCCESS) ;
}
// one more non-empty vector
C->nvec_nonempty++ ;
if (C->h != NULL)
{
//----------------------------------------------------------------------
// C is hypersparse; make sure space exists in the hyperlist
//----------------------------------------------------------------------
ASSERT (C->p [C->nvec] == (*cnz_last)) ;
ASSERT (C->h != NULL) ;
// check if space exists
if (C->nvec == C->plen)
{
// double the size of C->h and C->p
GrB_Info info ;
info = GB_hyper_realloc (C, GB_IMIN (C->vdim, 2*(C->plen+1)),
Context) ;
if (info != GrB_SUCCESS)
{
// out of memory
return (info) ;
}
}
ASSERT (C->nvec >= 0) ;
ASSERT (C->nvec < C->plen) ;
ASSERT (C->plen <= C->vdim) ;
ASSERT (C->p [C->nvec] == (*cnz_last)) ;
// add j to the hyperlist
C->h [C->nvec] = j ;
// mark the end of C(:,j)
C->p [C->nvec+1] = cnz ;
C->nvec++ ; // one more vector in the hyperlist
}
else
{
//----------------------------------------------------------------------
// C is non-hypersparse
//----------------------------------------------------------------------
int64_t *restrict Cp = C->p ;
ASSERT (C->nvec == C->plen && C->plen == C->vdim) ;
ASSERT (C->h == NULL) ;
ASSERT (Cp [(*jlast)+1] == (*cnz_last)) ;
// Even if C is non-hypersparse, the iteration that uses this function
// may iterate over a hypersparse input matrix, so not every vector j
// will be traversed. So when j is seen, the end of vectors jlast+1 to
// j must logged in Cp.
for (int64_t jprior = (*jlast)+1 ; jprior < j ; jprior++)
{
// mark the end of C(:,jprior)
Cp [jprior+1] = (*cnz_last) ;
}
// mark the end of C(:,j)
Cp [j+1] = cnz ;
}
// record the last vector added to C
(*cnz_last) = cnz ;
(*jlast) = j ;
return (GrB_SUCCESS) ;
}
//------------------------------------------------------------------------------
// GB_jwrapup: finish contructing a new matrix
//------------------------------------------------------------------------------
// Log the end of any vectors in C that are not yet terminated. Nothing
// happens if C is hypersparse (except for setting C->magic).
static inline void GB_jwrapup
(
GrB_Matrix C, // matrix to finish
int64_t jlast, // last vector appended, -1 if none
int64_t cnz // final nnz(C)
)
{
if (C->h == NULL)
{
//----------------------------------------------------------------------
// C is non-hypersparse
//----------------------------------------------------------------------
// log the end of C(:,jlast+1) to C(:,n-1), in case the last vector
// j=n-1 has not yet been seen, or has been seen but was empty.
int64_t *restrict Cp = C->p ;
int64_t j = C->vdim - 1 ;
for (int64_t jprior = jlast+1 ; jprior <= j ; jprior++)
{
// mark the end of C(:,jprior)
Cp [jprior+1] = cnz ;
}
}
// C->p and C->h are now valid
C->nvals = cnz ;
C->magic = GB_MAGIC ;
}
#endif
|