//------------------------------------------------------------------------------
// GB_subassign_06d: C(:,:) = A; C is full/bitmap, M and A are aliased
//------------------------------------------------------------------------------
// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2023, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//------------------------------------------------------------------------------
// JIT: done.
// Method 06d: C(:,:) = A ; no S, C is dense, M and A are aliased
// M: present, and aliased to A
// Mask_comp: false
// Mask_struct: true or false
// C_replace: false
// accum: NULL
// A: matrix, and aliased to M
// S: none
// C must be bitmap or full. No entries are deleted and thus no zombies
// are introduced into C. C can be hypersparse, sparse, bitmap, or full, and
// its sparsity structure does not change. If C is hypersparse, sparse, or
// full, then the pattern does not change (all entries are present, and this
// does not change), and these cases can all be treated the same (as if full).
// If C is bitmap, new entries can be inserted into the bitmap C->b.
// C and A can have any sparsity structure.
#include "GB_subassign_methods.h"
#include "GB_assign_shared_definitions.h"
#include "GB_subassign_dense.h"
#include "GB_stringify.h"
#ifndef GBCOMPACT
#include "GB_as__include.h"
#endif
#undef GB_FREE_ALL
#define GB_FREE_ALL ;
GrB_Info GB_subassign_06d
(
GrB_Matrix C,
// input:
const GrB_Matrix A,
bool Mask_struct,
GB_Werk Werk
)
{
//--------------------------------------------------------------------------
// get inputs
//--------------------------------------------------------------------------
GrB_Info info ;
ASSERT_MATRIX_OK (C, "C for subassign method_06d", GB0) ;
ASSERT (!GB_ZOMBIES (C)) ;
ASSERT (!GB_JUMBLED (C)) ;
ASSERT (!GB_PENDING (C)) ;
ASSERT (GB_IS_BITMAP (C) || GB_IS_FULL (C)) ;
ASSERT (!GB_any_aliased (C, A)) ; // NO ALIAS of C==A
ASSERT_MATRIX_OK (A, "A for subassign method_06d", GB0) ;
ASSERT (!GB_ZOMBIES (A)) ;
ASSERT (GB_JUMBLED_OK (A)) ;
ASSERT (!GB_PENDING (A)) ;
const GB_Type_code ccode = C->type->code ;
int nthreads_max = GB_Context_nthreads_max ( ) ;
double chunk = GB_Context_chunk ( ) ;
//--------------------------------------------------------------------------
// Method 06d: C(:,:) = A ; no S; C is dense, M and A are aliased
//--------------------------------------------------------------------------
// Time: Optimal: the method must iterate over all entries in A,
// and the time is O(nnz(A)).
//--------------------------------------------------------------------------
// C = A for built-in types
//--------------------------------------------------------------------------
info = GrB_NO_VALUE ;
if (C->iso)
{
//----------------------------------------------------------------------
// via the iso kernel
//----------------------------------------------------------------------
// Since C is iso, A must be iso (or effectively iso), which is also
// the mask M. An iso mask matrix M is converted into a structural
// mask by GB_get_mask, and thus Mask_struct must be true if C is iso.
ASSERT (Mask_struct) ;
#define GB_ISO_ASSIGN
#include "GB_subassign_06d_template.c"
info = GrB_SUCCESS ;
}
else
{
//----------------------------------------------------------------------
// via the factory kernel
//----------------------------------------------------------------------
#ifndef GBCOMPACT
GB_IF_FACTORY_KERNELS_ENABLED
{
//------------------------------------------------------------------
// define the worker for the switch factory
//------------------------------------------------------------------
#define GB_sub06d(cname) GB (_subassign_06d_ ## cname)
#define GB_WORKER(cname) \
{ \
info = GB_sub06d(cname) (C, A, Mask_struct, Werk) ; \
} \
break ;
//------------------------------------------------------------------
// launch the switch factory
//------------------------------------------------------------------
if (C->type == A->type && ccode < GB_UDT_code)
{
// C = A
switch (ccode)
{
case GB_BOOL_code : GB_WORKER (_bool )
case GB_INT8_code : GB_WORKER (_int8 )
case GB_INT16_code : GB_WORKER (_int16 )
case GB_INT32_code : GB_WORKER (_int32 )
case GB_INT64_code : GB_WORKER (_int64 )
case GB_UINT8_code : GB_WORKER (_uint8 )
case GB_UINT16_code : GB_WORKER (_uint16)
case GB_UINT32_code : GB_WORKER (_uint32)
case GB_UINT64_code : GB_WORKER (_uint64)
case GB_FP32_code : GB_WORKER (_fp32 )
case GB_FP64_code : GB_WORKER (_fp64 )
case GB_FC32_code : GB_WORKER (_fc32 )
case GB_FC64_code : GB_WORKER (_fc64 )
default: ;
}
}
}
#endif
//----------------------------------------------------------------------
// via the JIT or PreJIT kernel
//----------------------------------------------------------------------
if (info == GrB_NO_VALUE)
{
info = GB_subassign_jit (C,
/* C_replace: */ false,
/* I, ni, nI, Ikind, Icolon: */ NULL, 0, 0, GB_ALL, NULL,
/* J, nj, nJ, Jkind, Jcolon: */ NULL, 0, 0, GB_ALL, NULL,
/* M and A are aliased: */ A,
/* Mask_comp: */ false,
Mask_struct,
/* accum: */ NULL,
/* A: */ A,
/* scalar, scalar_type: */ NULL, NULL,
GB_SUBASSIGN, GB_JIT_KERNEL_SUBASSIGN_06d, "subassign_06d",
Werk) ;
}
//----------------------------------------------------------------------
// via the generic kernel
//----------------------------------------------------------------------
if (info == GrB_NO_VALUE)
{
#include "GB_generic.h"
GB_BURBLE_MATRIX (A, "(generic C(:,:)=A assign) ") ;
const size_t csize = C->type->size ;
const size_t asize = A->type->size ;
const GB_Type_code acode = A->type->code ;
GB_cast_function cast_A_to_C = GB_cast_factory (ccode, acode) ;
#define C_iso false
#undef GB_AX_MASK
#define GB_AX_MASK(Ax,pA,asize) GB_MCAST (Ax, pA, asize)
#include "GB_subassign_06d_template.c"
info = GrB_SUCCESS ;
}
}
//--------------------------------------------------------------------------
// free workspace and return result
//--------------------------------------------------------------------------
if (info == GrB_SUCCESS)
{
ASSERT_MATRIX_OK (C, "C output for subassign method_06d", GB0) ;
}
return (info) ;
}