Esempio n. 1
0
void GB_free_memory
(
    void *p                 // pointer to allocated block of memory to free
    #ifdef GB_MALLOC_TRACKING
    , size_t nitems         // number of items to free
    , size_t size_of_item   // sizeof each item
    #endif
)
{
    if (p != NULL)
    { 

        #ifdef GB_MALLOC_TRACKING
        {
            // at least one item is always allocated
            nitems = GB_IMAX (1, nitems) ;
            int nmalloc = --GB_Global.nmalloc ;
            GB_Global.inuse -= nitems * size_of_item ;
            #ifdef GB_PRINT_MALLOC
            printf ("free:    %14p %3d %1d n "GBd" size "GBd"\n",
                p, nmalloc, GB_Global.malloc_debug,
                (int64_t) nitems, (int64_t) size_of_item) ;
            if (nmalloc < 0)
            {
                printf ("%d free    %p negative mallocs!\n", nmalloc, p) ;
            }
            #endif
            ASSERT (nmalloc >= 0) ;
        }
        #endif

        GB_FREE (p) ;
    }
}
Esempio n. 2
0
bool GB_to_nonhyper_test    // test for conversion to hypersparse
(
    GrB_Matrix A,           // matrix to test
    int64_t k,              // # of non-empty vectors of A, an estimate is OK,
                            // but normally A->nvec_nonempty
    int64_t vdim            // normally A->vdim
)
{

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

    ASSERT (A != NULL) ;

    //--------------------------------------------------------------------------
    // test for conversion
    //--------------------------------------------------------------------------

    if (!A->is_hyper)
    { 

        //----------------------------------------------------------------------
        // A is already non-hypersparse: no need to convert it
        //----------------------------------------------------------------------

        return (false) ;

    }
    else
    { 

        //----------------------------------------------------------------------
        // A is hypersparse; test for conversion to non-hypersparse
        //----------------------------------------------------------------------

        // get the vector dimension of this matrix
        float n = (float) vdim ;

        // get the hyper ratio for this matrix
        float r = A->hyper_ratio ;

        // ensure k is in the range 0 to n, inclusive
        k = GB_IMAX (k, 0) ;
        k = GB_IMIN (k, n) ;

        return (n <= 1 || (((float) k) > n * r * 2)) ;
    }
}
Esempio n. 3
0
GrB_Info GB_ijproperties        // check I and determine its properties
(
    const GrB_Index *I,         // list of indices, or special
    const int64_t ni,           // length I, or special
    const int64_t nI,           // actual length from GB_ijlength
    const int64_t limit,        // I must be in the range 0 to limit-1
    const int64_t Ikind,        // kind of I, from GB_ijlength
    const int64_t Icolon [3],   // begin:inc:end from GB_ijlength
    bool *I_is_unsorted,        // true if I is out of order
    bool *I_is_contig,          // true if I is a contiguous list, imin:imax
    int64_t *imin_result,       // min (I)
    int64_t *imax_result,       // max (I)
    bool is_I,                  // true if I, false if J (debug only)
    GB_Context Context
)
{

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

    // limit: the matrix dimension (# of rows or # of columns)
    // ni: only used if Ikind is GB_LIST: the length of the array I
    // nI: the length of the list I, either actual or implicit
    // Ikind: GB_ALL, GB_RANGE, GB_STRIDE (both +/- inc), or GB_LIST
    // Icolon: begin:inc:end for all but GB_LIST

    // outputs:
    // I_is_unsorted: true if Ikind == GB_LIST and not in ascending order
    // I_is_contig: true if I has the form I = begin:end
    // imin, imax: min (I) and max (I), but only including actual indices
    //      in the sequence.  The end value of I=begin:inc:end may not be
    //      reached.  For example if I=1:2:10 then max(I)=9, not 10.

    ASSERT (I != NULL) ;
    ASSERT (limit >= 0) ;
    ASSERT (limit <= GB_INDEX_MAX) ;
    int64_t imin, imax ;

    //--------------------------------------------------------------------------
    // scan I
    //--------------------------------------------------------------------------

    // scan the list of indices: check if OK, determine if they are
    // jumbled, or contiguous, their min and max index, and actual length
    bool I_unsorted = false ;
    bool I_contig = true ;

    if (Ikind == GB_ALL)
    { 

        //----------------------------------------------------------------------
        // I = 0:limit-1
        //----------------------------------------------------------------------

        imin = 0 ;
        imax = limit-1 ;

    }
    else if (Ikind == GB_RANGE)
    {

        //----------------------------------------------------------------------
        // I = imin:imax
        //----------------------------------------------------------------------

        imin = Icolon [GxB_BEGIN] ;
        imax = Icolon [GxB_END  ] ;

        if (imin > imax)
        { 
            // imin > imax: list is empty
            imin = limit ;
            imax = -1 ;
        }
        else
        { 
            // check the limits
            GB_ICHECK (imin, limit) ;
            GB_ICHECK (imax, limit) ;
        }

    }
    else if (Ikind == GB_STRIDE)
    {

        //----------------------------------------------------------------------
        // I = imin:iinc:imax
        //----------------------------------------------------------------------

        int64_t ibegin = Icolon [GxB_BEGIN] ;
        int64_t iinc   = Icolon [GxB_INC  ] ;
        int64_t iend   = Icolon [GxB_END  ] ;

        // if iinc == 1 on input, the kind has been changed to GB_RANGE
        ASSERT (iinc != 1) ;

        if (iinc == 0)
        { 
            // stride is zero: list is empty, contiguous, and sorted
            imin = limit ;
            imax = -1 ;
        }
        else if (iinc > 0)
        { 
            // stride is positive, get the first and last indices
            imin = GB_ijlist (I, 0,    GB_STRIDE, Icolon) ;
            imax = GB_ijlist (I, nI-1, GB_STRIDE, Icolon) ;
        }
        else
        { 
            // stride is negative, get the first and last indices
            imin = GB_ijlist (I, nI-1, GB_STRIDE, Icolon) ;
            imax = GB_ijlist (I, 0,    GB_STRIDE, Icolon) ;
        }

        if (imin > imax)
        { 
            // list is empty: so it is contiguous and sorted
            imin = limit ;
            imax = -1 ;
        }
        else
        { 
            // list is contiguous if the stride is 1, not contiguous otherwise
            I_contig = false ;

            // check the limits
            GB_ICHECK (imin, limit) ;
            GB_ICHECK (imax, limit) ;
        }

    }
    else // Ikind == GB_LIST
    {

        //----------------------------------------------------------------------
        // I is an array of indices
        //----------------------------------------------------------------------

        // scan I to find imin and imax, and validate the list. Also determine
        // if it is sorted or not.

        imin = limit ;
        imax = -1 ;
        int64_t ilast = -1 ;
        for (int64_t inew = 0 ; inew < ni ; inew++)
        {
            int64_t i = I [inew] ;
            GB_ICHECK (i, limit) ;
            if (i < ilast)
            { 
                // The list I of row indices is out of order, and C=A(I,J) will
                // need to use qsort to sort each column.  If C=A(I,J)' is
                // computed, however, this flag will be set back to false,
                // since qsort is not needed if the result is transposed.
                I_unsorted = true ;
            }
            if (inew > 0 && i != ilast + 1)
            { 
                I_contig = false ;
            }
            imin = GB_IMIN (imin, i) ;
            imax = GB_IMAX (imax, i) ;
            ilast = i ;
        }
        if (ni == 1)
        {
            // a single entry does not need to be sorted
            ASSERT (I [0] == imin && I [0] == imax && !I_unsorted) ;
        }
        if (ni == 0)
        {
            // the list is empty
            ASSERT (imin == limit && imax == -1) ;
        }
    }

    ASSERT (GB_IMPLIES (I_contig, !I_unsorted)) ;
    ASSERT (GB_IMPLIES (Ikind == GB_ALL, I_contig)) ;
    ASSERT (GB_IMPLIES (Ikind == GB_RANGE, I_contig)) ;

    // I_is_contig is true if the list of row indices is a contiguous list,
    // imin:imax in MATLAB notation.  This is an important special case.

    // I_is_unsorted is true if I is an explicit list, the list is non-empty,
    // and the indices are not sorted in ascending order.

    (*I_is_contig) = I_contig ;
    (*I_is_unsorted) = I_unsorted ;
    (*imin_result) = imin ;
    (*imax_result) = imax ;
    return (GrB_SUCCESS) ;
}
Esempio n. 4
0
GrB_Info GB_Type_new
(
    GrB_Type *type,             // handle of user type to create
    const size_t sizeof_ctype,  // size of the user type
    const char *name            // name of the type, as "sizeof (ctype)"
)
{ 

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

    GB_WHERE ("GrB_Type_new (&type, sizeof (ctype))") ;
    GB_RETURN_IF_NULL (type) ;
    (*type) = NULL ;

    //--------------------------------------------------------------------------
    // create the type
    //--------------------------------------------------------------------------

    // allocate the type
    GB_CALLOC_MEMORY (*type, 1, sizeof (struct GB_Type_opaque)) ;
    if (*type == NULL)
    { 
        return (GB_NO_MEMORY) ;
    }

    // initialize the type
    GrB_Type t = *type ;
    t->magic = GB_MAGIC ;
    t->size = GB_IMAX (sizeof_ctype, 1) ;
    t->code = GB_UDT_code ;     // run-time user-defined type

    //--------------------------------------------------------------------------
    // get the name
    //--------------------------------------------------------------------------

    // if no name found, a generic name is used instead
    strncpy (t->name, "user-type", GB_LEN-1) ;

    char input2 [GB_LEN+1] ;
    char *p = NULL ;

    // look for "sizeof" in the input string
    if (name != NULL)
    { 
        strncpy (input2, name, GB_LEN) ;
        p = strstr (input2, "sizeof") ;
    }

    if (p != NULL)
    { 

        // "sizeof" appears in the input string, advance past it
        p += 6 ;

        // find leading "(" if it appears, and advance to one character past it
        char *p2 = strstr (p, "(") ;
        if (p2 != NULL) p = p2 + 1 ;

        // find trailing ")" if it appears, and delete it
        p2 = strstr (p, ")") ;
        if (p2 != NULL) *p2 = '\0' ;

        // p now contains the final name, copy it to the output name
        strncpy (t->name, p, GB_LEN-1) ;
    }

    return (GrB_SUCCESS) ;
}