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 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
|
//------------------------------------------------------------------------------
// GxB_Vector_subassign_[SCALAR]: assign scalar to vector, via scalar expansion
//------------------------------------------------------------------------------
// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2022, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//------------------------------------------------------------------------------
// Assigns a single scalar to a subvector, w(Rows)<M> = accum(w(Rows),x)
// The scalar x is implicitly expanded into a vector u of size nRows-by-1,
// with each entry in u equal to x.
// The actual work is done in GB_subassign_scalar.c.
#define GB_FREE_ALL ;
#include "GB_subassign.h"
#include "GB_ij.h"
#include "GB_get_mask.h"
#define GB_ASSIGN_SCALAR(type,T,ampersand) \
GrB_Info GB_EVAL2 (GXB (Vector_subassign_), T) /* w(I)<M> = accum (w(I),x) */ \
( \
GrB_Vector w, /* input/output vector for results */ \
const GrB_Vector M, /* optional mask for w(Rows) */ \
const GrB_BinaryOp accum, /* optional accum for Z=accum(w(Rows),x)*/ \
type x, /* scalar to assign to w(Rows) */ \
const GrB_Index *Rows, /* row indices */ \
GrB_Index nRows, /* number of row indices */ \
const GrB_Descriptor desc /* descriptor for w(Rows) and M */ \
) \
{ \
GB_WHERE (w, "GxB_Vector_subassign_" GB_STR(T) \
" (w, M, accum, x, Rows, nRows, desc)") ; \
GB_BURBLE_START ("GxB_subassign") ; \
GB_RETURN_IF_NULL_OR_FAULTY (w) ; \
GB_RETURN_IF_FAULTY (M) ; \
ASSERT (GB_VECTOR_OK (w)) ; \
ASSERT (GB_IMPLIES (M != NULL, GB_VECTOR_OK (M))) ; \
GrB_Info info = GB_subassign_scalar ((GrB_Matrix) w, (GrB_Matrix) M, \
accum, ampersand x, GB_## T ## _code, Rows, nRows, GrB_ALL, 1, desc, \
Context) ; \
GB_BURBLE_END ; \
return (info) ; \
}
GB_ASSIGN_SCALAR (bool , BOOL , &)
GB_ASSIGN_SCALAR (int8_t , INT8 , &)
GB_ASSIGN_SCALAR (uint8_t , UINT8 , &)
GB_ASSIGN_SCALAR (int16_t , INT16 , &)
GB_ASSIGN_SCALAR (uint16_t , UINT16 , &)
GB_ASSIGN_SCALAR (int32_t , INT32 , &)
GB_ASSIGN_SCALAR (uint32_t , UINT32 , &)
GB_ASSIGN_SCALAR (int64_t , INT64 , &)
GB_ASSIGN_SCALAR (uint64_t , UINT64 , &)
GB_ASSIGN_SCALAR (float , FP32 , &)
GB_ASSIGN_SCALAR (double , FP64 , &)
GB_ASSIGN_SCALAR (GxB_FC32_t, FC32 , &)
GB_ASSIGN_SCALAR (GxB_FC64_t, FC64 , &)
GB_ASSIGN_SCALAR (void * , UDT , )
//------------------------------------------------------------------------------
// GxB_Vector_subassign_Scalar: subassign a GrB_Scalar to a vector
//------------------------------------------------------------------------------
// If the GrB_Scalar s is non-empty, then this is the same as the non-opapue
// scalar assignment above.
// If the GrB_Scalar s is empty of type stype, then this is identical to:
// GrB_Vector_new (&S, stype, nRows) ;
// GxB_Vector_subassign (w, M, accum, S, Rows, nRows, desc) ;
// GrB_Vector_free (&S) ;
#undef GB_FREE_ALL
#define GB_FREE_ALL GB_Matrix_free (&S) ;
#include "GB_static_header.h"
GB_PUBLIC
GrB_Info GxB_Vector_subassign_Scalar // w<Mask>(I) = accum (w(I),s)
(
GrB_Vector w, // input/output matrix for results
const GrB_Vector M_in, // optional mask for w, unused if NULL
const GrB_BinaryOp accum, // optional accum for Z=accum(w(I),x)
GrB_Scalar scalar, // scalar to assign to w(I)
const GrB_Index *I, // row indices
GrB_Index ni, // number of row indices
const GrB_Descriptor desc // descriptor for w and Mask
)
{
//--------------------------------------------------------------------------
// check inputs
//--------------------------------------------------------------------------
GrB_Matrix S = NULL ;
GB_WHERE (w, "GxB_Vector_subassign_Scalar"
" (w, M, accum, s, Rows, nRows, desc)") ;
GB_BURBLE_START ("GxB_subassign") ;
GB_RETURN_IF_NULL_OR_FAULTY (w) ;
GB_RETURN_IF_NULL_OR_FAULTY (scalar) ;
GB_RETURN_IF_FAULTY (M_in) ;
GB_RETURN_IF_NULL (I) ;
ASSERT (GB_VECTOR_OK (w)) ;
ASSERT (M_in == NULL || GB_VECTOR_OK (M_in)) ;
// get the descriptor
GB_GET_DESCRIPTOR (info, desc, C_replace, Mask_comp, Mask_struct,
xx1, xx2, xx3, xx7) ;
// get the mask
GrB_Matrix M = GB_get_mask ((GrB_Matrix) M_in, &Mask_comp, &Mask_struct) ;
//--------------------------------------------------------------------------
// w(Rows)<M> = accum (w(Rows), scalar)
//--------------------------------------------------------------------------
GrB_Index nvals ;
GB_OK (GB_nvals (&nvals, (GrB_Matrix) scalar, Context)) ;
if (M == NULL && !Mask_comp && ni == 1 && !C_replace)
{
//----------------------------------------------------------------------
// scalar assignment
//----------------------------------------------------------------------
const GrB_Index row = I [0] ;
if (nvals == 1)
{
// set the element: w(row) += scalar or w(wrow) = scalar
info = GB_setElement ((GrB_Matrix) w, accum, scalar->x, row, 0,
scalar->type->code, Context) ;
}
else if (accum == NULL)
{
// delete the w(row) element
info = GB_Vector_removeElement (w, row, Context) ;
}
}
else if (nvals == 1)
{
//----------------------------------------------------------------------
// the opaque GrB_Scalar has a single entry
//----------------------------------------------------------------------
// This is identical to non-opaque scalar assignment
info = GB_subassign (
(GrB_Matrix) w, C_replace, // w vector and its descriptor
M, Mask_comp, Mask_struct, // mask vector and its descriptor
false, // do not transpose the mask
accum, // for accum (w(Rows),scalar)
NULL, false, // no explicit vector u
I, ni, // row indices
GrB_ALL, 1, // column indices
true, // do scalar expansion
scalar->x, // scalar to assign, expands to become u
scalar->type->code, // type code of scalar to expand
Context) ;
}
else
{
//----------------------------------------------------------------------
// the opaque GrB_Scalar has no entry
//----------------------------------------------------------------------
// determine the properites of the I index list
int64_t nRows, RowColon [3] ;
int RowsKind ;
GB_ijlength (I, ni, GB_NROWS (w), &nRows, &RowsKind, RowColon);
// create an empty matrix S of the right size, and use matrix assign
struct GB_Matrix_opaque S_header ;
GB_CLEAR_STATIC_HEADER (S, &S_header) ;
GB_OK (GB_new (&S, // existing header
scalar->type, nRows, 1, GB_Ap_calloc, true, GxB_AUTO_SPARSITY,
GB_HYPER_SWITCH_DEFAULT, 1, Context)) ;
info = GB_subassign (
(GrB_Matrix) w, C_replace, // w vector and its descriptor
M, Mask_comp, Mask_struct, // mask matrix and its descriptor
false, // do not transpose the mask
accum, // for accum (w(Rows),scalar)
S, false, // S matrix and its descriptor
I, ni, // row indices
GrB_ALL, 1, // column indices
false, NULL, GB_ignore_code, // no scalar expansion
Context) ;
GB_FREE_ALL ;
}
GB_BURBLE_END ;
return (info) ;
}
|