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
|
//------------------------------------------------------------------------------
// GB_dup_worker: make a deep copy of a sparse matrix
//------------------------------------------------------------------------------
// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2022, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//------------------------------------------------------------------------------
// C = A, making a deep copy. The header for C may already exist.
// if numeric is false, C->x is allocated but not initialized.
// If *Chandle is not NULL, the header is reused. It may be a static or
// dynamic header, depending on C->static_header.
#include "GB.h"
#define GB_FREE_ALL ;
GrB_Info GB_dup_worker // make an exact copy of a matrix
(
GrB_Matrix *Chandle, // output matrix, NULL or existing static/dynamic
const bool C_iso, // if true, construct C as iso
const GrB_Matrix A, // input matrix to copy
const bool numeric, // if true, duplicate the numeric values; if A is
// iso, only the first entry is copied, regardless
// of C_iso on input
const GrB_Type ctype, // type of C, if numeric is false
GB_Context Context
)
{
//--------------------------------------------------------------------------
// check inputs
//--------------------------------------------------------------------------
GrB_Info info ;
ASSERT_MATRIX_OK (A, "A to duplicate", GB0) ;
ASSERT (Chandle != NULL) ;
ASSERT (!GB_PENDING (A)) ;
ASSERT (GB_JUMBLED_OK (A)) ;
ASSERT (GB_ZOMBIES_OK (A)) ;
//--------------------------------------------------------------------------
// determine the number of threads to use
//--------------------------------------------------------------------------
GB_GET_NTHREADS_MAX (nthreads_max, chunk, Context) ;
//--------------------------------------------------------------------------
// get A
//--------------------------------------------------------------------------
int64_t anz = GB_nnz_held (A) ;
int64_t *Ap = A->p ;
int64_t *Ah = A->h ;
int64_t *Ai = A->i ;
int8_t *Ab = A->b ;
GB_void *Ax = (GB_void *) A->x ;
int64_t anvec = A->nvec ;
int64_t anvals = A->nvals ;
int64_t anvec_nonempty = A->nvec_nonempty ;
int64_t A_nzombies = A->nzombies ;
bool A_jumbled = A->jumbled ;
int sparsity_control = A->sparsity_control ;
GrB_Type atype = A->type ;
//--------------------------------------------------------------------------
// create C
//--------------------------------------------------------------------------
// create C; allocate C->p and do not initialize it.
// C has the exact same sparsity structure as A.
// allocate a new user header for C if (*Chandle) is NULL, or reuse the
// existing static or dynamic header if (*Chandle) is not NULL.
GrB_Matrix C = (*Chandle) ;
// set C->iso = C_iso OK: burble in the caller
GB_OK (GB_new_bix (Chandle, // can be new or existing header
numeric ? atype : ctype, A->vlen, A->vdim, GB_Ap_malloc, A->is_csc,
GB_sparsity (A), false, A->hyper_switch, A->plen, anz, true, C_iso,
Context)) ;
C = (*Chandle) ;
//--------------------------------------------------------------------------
// copy the contents of A into C
//--------------------------------------------------------------------------
C->nvec = anvec ;
C->nvec_nonempty = anvec_nonempty ;
C->nvals = anvals ;
C->jumbled = A_jumbled ; // C is jumbled if A is jumbled
C->nzombies = A_nzombies ; // zombies can be duplicated
C->sparsity_control = sparsity_control ;
if (Ap != NULL)
{
GB_memcpy (C->p, Ap, (anvec+1) * sizeof (int64_t), nthreads_max) ;
}
if (Ah != NULL)
{
GB_memcpy (C->h, Ah, anvec * sizeof (int64_t), nthreads_max) ;
}
if (Ab != NULL)
{
GB_memcpy (C->b, Ab, anz * sizeof (int8_t), nthreads_max) ;
}
if (Ai != NULL)
{
GB_memcpy (C->i, Ai, anz * sizeof (int64_t), nthreads_max) ;
}
if (numeric)
{
ASSERT (C_iso == A->iso) ;
ASSERT (C->type == A->type) ;
GB_memcpy (C->x, Ax, (A->iso ? 1:anz) * atype->size, nthreads_max) ;
}
C->magic = GB_MAGIC ; // C->p and C->h are now initialized
#ifdef GB_DEBUG
if (numeric) ASSERT_MATRIX_OK (C, "C duplicate of A", GB0) ;
#endif
//--------------------------------------------------------------------------
// return the result
//--------------------------------------------------------------------------
return (GrB_SUCCESS) ;
}
|