File: GB_cast_array.c

package info (click to toggle)
suitesparse-graphblas 7.4.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 67,112 kB
  • sloc: ansic: 1,072,243; cpp: 8,081; sh: 512; makefile: 506; asm: 369; python: 125; awk: 10
file content (98 lines) | stat: -rw-r--r-- 3,737 bytes parent folder | download | duplicates (3)
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
//------------------------------------------------------------------------------
// GB_cast_array: typecast an array
//------------------------------------------------------------------------------

// SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2022, All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

//------------------------------------------------------------------------------

// Casts an input array Ax to an output array Cx with a different type.  The
// two types are always different, so this does not need to handle user-defined
// types.  The iso case is not handled; Ax and Cx must be the same size and no
// iso expansion is done.

#include "GB.h"
#ifndef GBCUDA_DEV
#include "GB_unop__include.h"
#endif

GB_PUBLIC
void GB_cast_array              // typecast an array
(
    GB_void *Cx,                // output array
    const GB_Type_code code1,   // type code for Cx
    GB_void *Ax,                // input array
    const GB_Type_code code2,   // type code for Ax
    const int8_t *restrict Ab,  // bitmap for Ax
    const int64_t anz,          // number of entries in Cx and Ax
    const int nthreads          // number of threads to use
)
{

    //--------------------------------------------------------------------------
    // check inputs
    //--------------------------------------------------------------------------

    if (anz == 0 || Cx == Ax)
    { 
        // if anz is zero: no work to do, and the Ax and Cx pointer may be NULL
        // as well.  If Cx and Ax are aliased, then no copy is needed.
        return ;
    }

    ASSERT (Cx != NULL) ;
    ASSERT (Ax != NULL) ;
    ASSERT (anz > 0) ;
    ASSERT (GB_code_compatible (code1, code2)) ;
    ASSERT (code1 != code2) ;
    ASSERT (code1 != GB_UDT_code) ;

    //--------------------------------------------------------------------------
    // typecast the array
    //--------------------------------------------------------------------------

    #ifndef GBCUDA_DEV

        //----------------------------------------------------------------------
        // define the worker for the switch factory
        //----------------------------------------------------------------------

        #define GB_unop_apply(zname,xname)                                  \
            GB (_unop_apply__identity ## zname ## xname)

        #define GB_WORKER(ignore1,zname,ztype,xname,xtype)                  \
        {                                                                   \
            GrB_Info info = GB_unop_apply (zname,xname)                     \
                ((ztype *) Cx, (xtype *) Ax, Ab, anz, nthreads) ;           \
            if (info == GrB_SUCCESS) return ;                               \
        }                                                                   \
        break ;

        //----------------------------------------------------------------------
        // launch the switch factory
        //----------------------------------------------------------------------

        #define GB_EXCLUDE_SAME_TYPES
        #include "GB_2type_factory.c"

    #endif

    //--------------------------------------------------------------------------
    // generic worker: only used for GBCUDA_DEV case
    //--------------------------------------------------------------------------

    int64_t csize = GB_code_size (code1, 0) ;
    int64_t asize = GB_code_size (code2, 0) ;
    GB_cast_function cast_A_to_C = GB_cast_factory (code1, code2) ;

    int64_t p ;
    #pragma omp parallel for num_threads(nthreads) schedule(static)
    for (p = 0 ; p < anz ; p++)
    {
        if (!GBB (Ab, p)) continue ;
        // Cx [p] = Ax [p]
        cast_A_to_C (Cx +(p*csize), Ax +(p*asize), asize) ;
    }
}