From d68f5d88496581568e487e7f33d60623c95f13b6 Mon Sep 17 00:00:00 2001 From: Michel Pelletier Date: Sun, 4 Aug 2024 15:47:18 -0700 Subject: [PATCH 1/6] checkpoint for ss 9 integration --- Dockerfile | 17 +- pggraphblas--0.0.1.sql | 22 +- src/LAGraph_pagerank.c | 677 ++++++++++++++++++++--------------------- src/matrix.c | 205 ++----------- src/matrix.h | 88 +++--- src/pggraphblas.c | 6 +- src/pggraphblas.h | 37 +-- src/type.c | 32 +- src/vector.c | 12 +- src/vector.h | 52 ++-- 10 files changed, 493 insertions(+), 655 deletions(-) diff --git a/Dockerfile b/Dockerfile index d17a00f..9ecf0fe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ FROM ubuntu:latest # install base dependences RUN apt-get update && \ apt-get install -y make cmake git curl build-essential m4 sudo gdbserver \ - gdb libreadline-dev bison flex zlib1g-dev tmux emacs25-nox zile zip vim gawk wget + gdb libreadline-dev bison flex zlib1g-dev libicu-dev icu-devtools tmux zile zip vim gawk wget # add postgres user and make data dir RUN groupadd -r postgres && useradd --no-log-init -r -m -s /bin/bash -g postgres -G sudo postgres @@ -12,9 +12,10 @@ RUN /bin/rm -Rf "$PGDATA" && mkdir "$PGDATA" WORKDIR "/home/postgres" # get postgres source and compile with debug and no optimization -RUN git clone --branch REL_12_STABLE https://github.com/postgres/postgres.git --depth=1 && \ +RUN git clone --branch REL_16_STABLE https://github.com/postgres/postgres.git --depth=1 && \ cd postgres && ./configure \ --prefix=/usr/ \ + --without-icu \ # --enable-debug \ # --enable-depend --enable-cassert --enable-profiling \ # CFLAGS="-ggdb -Og -g3 -fno-omit-frame-pointer" \ @@ -22,19 +23,19 @@ RUN git clone --branch REL_12_STABLE https://github.com/postgres/postgres.git -- && make -j 4 && make install # get GraphBLAS, compile with debug symbols -RUN curl -s -L http://faculty.cse.tamu.edu/davis/GraphBLAS/GraphBLAS-3.1.1.tar.gz | \ - tar zxvf - && cd GraphBLAS-3.1.1 && \ +RUN curl -s -L -J https://github.com/DrTimothyAldenDavis/GraphBLAS/archive/refs/tags/v9.2.0.tar.gz | \ + tar zxvf - && cd GraphBLAS-9.2.0 && \ # sed -i 's/^\/\/ #undef NDEBUG/#undef NDEBUG/g' Source/GB.h && \ # sed -i 's/^\/\/ #define GB_PRINT_MALLOC 1/#define GB_PRINT_MALLOC 1/g' Source/GB.h && \ make library \ CMAKE_OPTIONS='-DCMAKE_BUILD_TYPE=Debug' \ && make install -RUN git clone --branch 22July2019 https://github.com/GraphBLAS/LAGraph.git && \ - cd LAGraph && \ - make library \ +#RUN git clone --branch 22July2019 https://github.com/GraphBLAS/LAGraph.git && \ +# cd LAGraph && \ +# make library \ # CMAKE_OPTIONS='-DCMAKE_BUILD_TYPE=Debug' \ - && make install +# && make install RUN curl -s -L https://github.com/theory/pgtap/archive/v0.99.0.tar.gz | tar zxvf - && \ cd pgtap-0.99.0 && make && make install diff --git a/pggraphblas--0.0.1.sql b/pggraphblas--0.0.1.sql index 9a5f225..d82c2ce 100644 --- a/pggraphblas--0.0.1.sql +++ b/pggraphblas--0.0.1.sql @@ -624,19 +624,19 @@ RETURNS SETOF matrix_element_bool AS '$libdir/pggraphblas', 'matrix_elements_bool' LANGUAGE C STABLE STRICT; -CREATE FUNCTION bfs(A matrix, size bigint, AT matrix default null) -RETURNS vector -AS '$libdir/pggraphblas', 'matrix_bfs' -LANGUAGE C STABLE; - -CREATE TYPE pageranking AS (page bigint, rank float); +-- CREATE FUNCTION bfs(A matrix, size bigint, AT matrix default null) +-- RETURNS vector +-- AS '$libdir/pggraphblas', 'matrix_bfs' +-- LANGUAGE C STABLE; -CREATE FUNCTION pagerank(A matrix) -RETURNS pageranking -AS '$libdir/pggraphblas', 'matrix_pagerank' -LANGUAGE C STABLE; +-- CREATE TYPE pageranking AS (page bigint, rank float); + +-- CREATE FUNCTION pagerank(A matrix) +-- RETURNS pageranking +-- AS '$libdir/pggraphblas', 'matrix_pagerank' +-- LANGUAGE C STABLE; -CREATE TYPE ssspath AS (source bigint, distance float, parent bigint, hops bigint); +-- CREATE TYPE ssspath AS (source bigint, distance float, parent bigint, hops bigint); -- CREATE FUNCTION sssp_bf(A matrix, start bigint) -- RETURNS ssspath diff --git a/src/LAGraph_pagerank.c b/src/LAGraph_pagerank.c index e8887e2..ce2e6f6 100644 --- a/src/LAGraph_pagerank.c +++ b/src/LAGraph_pagerank.c @@ -1,346 +1,345 @@ -//------------------------------------------------------------------------------ -// SuiteSparse/GraphBLAS/Demo/Source/dpagerank: pagerank using a real semiring -//------------------------------------------------------------------------------ - -// A is a square unsymmetric binary matrix of size n-by-n, where A(i,j) is the -// edge (i,j). Self-edges are LAGRAPH_OK. A can be of any built-in type. - -// On output, P is pointer to an array of LAGraph_PageRank structs. P[0] is the -// highest ranked page, with pagerank P[0].pagerank and the page corresponds to -// node number P[0].page in the graph. P[1] is the next page, and so on, to -// the lowest-ranked page P[n-1].page with rank P[n-1].pagerank. - -// See dpagerank.m for the equivalent computation in MATLAB (except the random -// number generator differs). - -//------------------------------------------------------------------------------ -// helper macros -//------------------------------------------------------------------------------ - -// free all workspace -#define FREEWORK \ -{ \ - GrB_free (&D) ; \ - GrB_free (&C) ; \ - GrB_free (&r) ; \ - GrB_free (&t) ; \ - GrB_free (&d) ; \ - if (I != NULL) { free_function (I) ; I = NULL ; } \ - if (X != NULL) { free_function (X) ; X = NULL ; } \ - GrB_free (&op_div) ; \ - GrB_free (&op_diff) ; \ -} - -// error handler: free output P and all workspace -#define LAGRAPH_FREE_ALL \ -{ \ - if (P != NULL) { free_function (P) ; P = NULL ; } \ - FREEWORK ; \ -} - -//------------------------------------------------------------------------------ -// scalar operators -//------------------------------------------------------------------------------ - -#define DAMPING 0.85 - -float rsum ; -#pragma omp threadprivate(rsum) - -void fdiv (void *z, const void *x) -{ - (*((float *) z)) = (* ((float *) x)) / rsum ; -} - -void fdiff (void *z, const void *x, const void *y) -{ - float delta = (* ((float *) x)) - (* ((float *) y)) ; - (*((float *) z)) = delta * delta ; -} - -//------------------------------------------------------------------------------ -// comparison function for qsort -//------------------------------------------------------------------------------ - -int compar (const void *x, const void *y) -{ - LAGraph_PageRank *a = (LAGraph_PageRank *) x ; - LAGraph_PageRank *b = (LAGraph_PageRank *) y ; - - // sort by pagerank in descending order - if (a->pagerank > b->pagerank) - { - return (-1) ; - } - else if (a->pagerank == b->pagerank) - { - return (0) ; - } - else - { - return (1) ; - } -} - -//------------------------------------------------------------------------------ -// LAGraph_pagerank: compute the pagerank of all nodes in a graph -//------------------------------------------------------------------------------ - -GrB_Info LAGraph_pagerank2 // GrB_SUCCESS or error condition -( - LAGraph_PageRank **Phandle, // output: array of LAGraph_PageRank structs - GrB_Matrix A, // binary input graph, not modified - int itermax, // max number of iterations - double tol, // stop when norm (r-rnew,2) < tol - int *iters // number of iterations taken -) -{ - - //-------------------------------------------------------------------------- - // initializations - //-------------------------------------------------------------------------- - - double tic [2] ; - LAGraph_tic (tic) ; - - GrB_Info info ; - float *X = NULL ; - GrB_Index n, nvals, *I = NULL ; - LAGraph_PageRank *P = NULL ; - GrB_Vector r = NULL, t = NULL, d = NULL ; - GrB_UnaryOp op_div = NULL ; - GrB_BinaryOp op_diff = NULL ; - GrB_Matrix C = NULL, D = NULL ; - - if (Phandle == NULL) LAGRAPH_ERROR ("null pointer", GrB_NULL_POINTER) ; - (*Phandle) = NULL ; - - // n = size (A,1) ; // number of nodes - LAGRAPH_OK (GrB_Matrix_nrows (&n, A)) ; - if (n == 0) return (GrB_SUCCESS) ; - - // teleport = (1 - 0.85) / n - float one = 1.0 ; - float teleport = (one - DAMPING) / ((float) n) ; - - // r (i) = 1/n for all nodes i - float x = 1.0 / ((float) n) ; - LAGRAPH_OK (GrB_Vector_new (&r, GrB_FP32, n)) ; - LAGRAPH_OK (GrB_assign (r, NULL, NULL, x, GrB_ALL, n, NULL)) ; - - // d (i) = out deg of node i - LAGRAPH_OK (GrB_Vector_new (&d, GrB_FP32, n)) ; - LAGRAPH_OK (GrB_reduce (d, NULL, NULL, GrB_PLUS_FP32, A, NULL)) ; - - // D = (1/diag (d)) * DAMPING - #ifdef GxB_SUITESPARSE_GRAPHBLAS - GrB_Type type ; - LAGRAPH_OK (GxB_Vector_export (&d, &type, &n, &nvals, &I, (void **) (&X), - NULL)) ; - #else - nvals = n ; - I = malloc_function ((nvals + 1) * sizeof (GrB_Index)) ; - X = malloc_function ((nvals + 1) * sizeof (float)) ; - if (I == NULL || X == NULL) - { - LAGRAPH_ERROR ("out of memory", GrB_OUT_OF_MEMORY) ; - } - LAGRAPH_OK (GrB_Vector_extract (I, X, &nvals, d)) ; - LAGRAPH_OK (GrB_free (&d)) ; - #endif - - for (int64_t k = 0 ; k < nvals ; k++) X [k] = DAMPING / X [k] ; - LAGRAPH_OK (GrB_Matrix_new (&D, GrB_FP32, n, n)) ; - LAGRAPH_OK (GrB_Matrix_build (D, I, I, X, nvals, GrB_PLUS_FP32)) ; - free_function (I) ; - free_function (X) ; - - // GxB_print (D, 3) ; - - // C = diagonal matrix with all zeros on the diagonal. This ensures that - // the vectors r and t remain dense, which is faster. - LAGRAPH_OK (GrB_Matrix_new (&C, GrB_FP32, n, n)) ; - // GxB_set (C, GxB_HYPER, GxB_ALWAYS_HYPER) ; - - for (int64_t k = 0 ; k < n ; k++) - { - // C(k,k) = 0 - LAGRAPH_OK (GrB_Matrix_setElement (C, (float) 0, k, k)) ; - } - - - // GxB_print (A, 3) ; - - // GxB_print (C, 3) ; - - double tt = LAGraph_toc (tic) ; - fprintf (stderr, "init time %g\n", tt) ; - LAGraph_tic (tic) ; - - // C = C+(D*A)' = C+A'*D' using A(i,j)/D(i,i) as the multiplicative operator - LAGRAPH_OK (GrB_mxm (C, NULL, GrB_PLUS_FP32, GxB_PLUS_TIMES_FP32, A, D, - LAGraph_desc_ttoo)) ; +/* //------------------------------------------------------------------------------ */ +/* // SuiteSparse/GraphBLAS/Demo/Source/dpagerank: pagerank using a real semiring */ +/* //------------------------------------------------------------------------------ */ + +/* // A is a square unsymmetric binary matrix of size n-by-n, where A(i,j) is the */ +/* // edge (i,j). Self-edges are LAGRAPH_OK. A can be of any built-in type. */ + +/* // On output, P is pointer to an array of LAGraph_PageRank structs. P[0] is the */ +/* // highest ranked page, with pagerank P[0].pagerank and the page corresponds to */ +/* // node number P[0].page in the graph. P[1] is the next page, and so on, to */ +/* // the lowest-ranked page P[n-1].page with rank P[n-1].pagerank. */ + +/* // See dpagerank.m for the equivalent computation in MATLAB (except the random */ +/* // number generator differs). */ + +/* //------------------------------------------------------------------------------ */ +/* // helper macros */ +/* //------------------------------------------------------------------------------ */ + +/* // free all workspace */ +/* #define FREEWORK \ */ +/* { \ */ +/* GrB_free (&D) ; \ */ +/* GrB_free (&C) ; \ */ +/* GrB_free (&r) ; \ */ +/* GrB_free (&t) ; \ */ +/* GrB_free (&d) ; \ */ +/* if (I != NULL) { free_function (I) ; I = NULL ; } \ */ +/* if (X != NULL) { free_function (X) ; X = NULL ; } \ */ +/* GrB_free (&op_div) ; \ */ +/* GrB_free (&op_diff) ; \ */ +/* } */ + +/* // error handler: free output P and all workspace */ +/* #define LAGRAPH_FREE_ALL \ */ +/* { \ */ +/* if (P != NULL) { free_function (P) ; P = NULL ; } \ */ +/* FREEWORK ; \ */ +/* } */ + +/* //------------------------------------------------------------------------------ */ +/* // scalar operators */ +/* //------------------------------------------------------------------------------ */ + +/* #define DAMPING 0.85 */ + +/* float rsum ; */ +/* #pragma omp threadprivate(rsum) */ + +/* void fdiv (void *z, const void *x) */ +/* { */ +/* (*((float *) z)) = (* ((float *) x)) / rsum ; */ +/* } */ + +/* void fdiff (void *z, const void *x, const void *y) */ +/* { */ +/* float delta = (* ((float *) x)) - (* ((float *) y)) ; */ +/* (*((float *) z)) = delta * delta ; */ +/* } */ + +/* //------------------------------------------------------------------------------ */ +/* // comparison function for qsort */ +/* //------------------------------------------------------------------------------ */ + +/* int compar (const void *x, const void *y) */ +/* { */ +/* LAGraph_PageRank *a = (LAGraph_PageRank *) x ; */ +/* LAGraph_PageRank *b = (LAGraph_PageRank *) y ; */ + +/* // sort by pagerank in descending order */ +/* if (a->pagerank > b->pagerank) */ +/* { */ +/* return (-1) ; */ +/* } */ +/* else if (a->pagerank == b->pagerank) */ +/* { */ +/* return (0) ; */ +/* } */ +/* else */ +/* { */ +/* return (1) ; */ +/* } */ +/* } */ + +/* //------------------------------------------------------------------------------ */ +/* // LAGraph_pagerank: compute the pagerank of all nodes in a graph */ +/* //------------------------------------------------------------------------------ */ + +/* GrB_Info LAGraph_pagerank2 // GrB_SUCCESS or error condition */ +/* ( */ +/* LAGraph_PageRank **Phandle, // output: array of LAGraph_PageRank structs */ +/* GrB_Matrix A, // binary input graph, not modified */ +/* int itermax, // max number of iterations */ +/* double tol, // stop when norm (r-rnew,2) < tol */ +/* int *iters // number of iterations taken */ +/* ) */ +/* { */ + +/* //-------------------------------------------------------------------------- */ +/* // initializations */ +/* //-------------------------------------------------------------------------- */ + +/* double tic [2] ; */ +/* LAGraph_tic (tic) ; */ + +/* GrB_Info info ; */ +/* float *X = NULL ; */ +/* GrB_Index n, nvals, *I = NULL ; */ +/* LAGraph_PageRank *P = NULL ; */ +/* GrB_Vector r = NULL, t = NULL, d = NULL ; */ +/* GrB_UnaryOp op_div = NULL ; */ +/* GrB_BinaryOp op_diff = NULL ; */ +/* GrB_Matrix C = NULL, D = NULL ; */ + +/* if (Phandle == NULL) LAGRAPH_ERROR ("null pointer", GrB_NULL_POINTER) ; */ +/* (*Phandle) = NULL ; */ + +/* // n = size (A,1) ; // number of nodes */ +/* LAGRAPH_OK (GrB_Matrix_nrows (&n, A)) ; */ +/* if (n == 0) return (GrB_SUCCESS) ; */ + +/* // teleport = (1 - 0.85) / n */ +/* float one = 1.0 ; */ +/* float teleport = (one - DAMPING) / ((float) n) ; */ + +/* // r (i) = 1/n for all nodes i */ +/* float x = 1.0 / ((float) n) ; */ +/* LAGRAPH_OK (GrB_Vector_new (&r, GrB_FP32, n)) ; */ +/* LAGRAPH_OK (GrB_assign (r, NULL, NULL, x, GrB_ALL, n, NULL)) ; */ + +/* // d (i) = out deg of node i */ +/* LAGRAPH_OK (GrB_Vector_new (&d, GrB_FP32, n)) ; */ +/* LAGRAPH_OK (GrB_reduce (d, NULL, NULL, GrB_PLUS_FP32, A, NULL)) ; */ + +/* // D = (1/diag (d)) * DAMPING */ +/* #ifdef GxB_SUITESPARSE_GRAPHBLAS */ +/* GrB_Type type ; */ +/* LAGRAPH_OK (GxB_Vector_export (&d, &type, &n, &nvals, &I, (void **) (&X), */ +/* NULL)) ; */ +/* #else */ +/* nvals = n ; */ +/* I = malloc_function ((nvals + 1) * sizeof (GrB_Index)) ; */ +/* X = malloc_function ((nvals + 1) * sizeof (float)) ; */ +/* if (I == NULL || X == NULL) */ +/* { */ +/* LAGRAPH_ERROR ("out of memory", GrB_OUT_OF_MEMORY) ; */ +/* } */ +/* LAGRAPH_OK (GrB_Vector_extract (I, X, &nvals, d)) ; */ +/* LAGRAPH_OK (GrB_free (&d)) ; */ +/* #endif */ + +/* for (int64_t k = 0 ; k < nvals ; k++) X [k] = DAMPING / X [k] ; */ +/* LAGRAPH_OK (GrB_Matrix_new (&D, GrB_FP32, n, n)) ; */ +/* LAGRAPH_OK (GrB_Matrix_build (D, I, I, X, nvals, GrB_PLUS_FP32)) ; */ +/* free_function (I) ; */ +/* free_function (X) ; */ + +/* // GxB_print (D, 3) ; */ + +/* // C = diagonal matrix with all zeros on the diagonal. This ensures that */ +/* // the vectors r and t remain dense, which is faster. */ +/* LAGRAPH_OK (GrB_Matrix_new (&C, GrB_FP32, n, n)) ; */ +/* // GxB_set (C, GxB_HYPER, GxB_ALWAYS_HYPER) ; */ + +/* for (int64_t k = 0 ; k < n ; k++) */ +/* { */ +/* // C(k,k) = 0 */ +/* LAGRAPH_OK (GrB_Matrix_setElement (C, (float) 0, k, k)) ; */ +/* } */ + + +/* // GxB_print (A, 3) ; */ + +/* // GxB_print (C, 3) ; */ + +/* double tt = LAGraph_toc (tic) ; */ +/* fprintf (stderr, "init time %g\n", tt) ; */ +/* LAGraph_tic (tic) ; */ + +/* // C = C+(D*A)' = C+A'*D' using A(i,j)/D(i,i) as the multiplicative operator */ +/* LAGRAPH_OK (GrB_mxm (C, NULL, GrB_PLUS_FP32, GxB_PLUS_TIMES_FP32, A, D, */ +/* LAGraph_desc_ttoo)) ; */ -/* - // C = C+(D*A) - LAGRAPH_OK (GrB_mxm (C, NULL, GrB_PLUS_FP32, GxB_PLUS_TIMES_FP32, D, A, - NULL)) ; -*/ +/* /\* */ +/* // C = C+(D*A) */ +/* LAGRAPH_OK (GrB_mxm (C, NULL, GrB_PLUS_FP32, GxB_PLUS_TIMES_FP32, D, A, */ +/* NULL)) ; */ +/* *\/ */ - LAGRAPH_OK (GrB_free (&D)) ; +/* LAGRAPH_OK (GrB_free (&D)) ; */ - // create operators - LAGRAPH_OK (GrB_UnaryOp_new (&op_div, fdiv, GrB_FP32, GrB_FP32)) ; - LAGRAPH_OK (GrB_BinaryOp_new (&op_diff, fdiff, GrB_FP32, GrB_FP32, - GrB_FP32)) ; +/* // create operators */ +/* LAGRAPH_OK (GrB_UnaryOp_new (&op_div, fdiv, GrB_FP32, GrB_FP32)) ; */ +/* LAGRAPH_OK (GrB_BinaryOp_new (&op_diff, fdiff, GrB_FP32, GrB_FP32, */ +/* GrB_FP32)) ; */ - float ftol = tol*tol ; // use tol^2 so sqrt(rdiff) not needed - float rdiff = 1 ; // so first iteration is always done - - LAGRAPH_OK (GrB_Vector_new (&t, GrB_FP32, n)) ; - - // GxB_print (C, 2) ; - // GxB_fprint (C, 2, stderr) ; - - tt = LAGraph_toc (tic) ; - fprintf (stderr, "C time %g\n", tt) ; - LAGraph_tic (tic) ; - - //-------------------------------------------------------------------------- - // iterate to compute the pagerank of each node - //-------------------------------------------------------------------------- - - double t2 = 0 ; - - for ((*iters) = 0 ; (*iters) < itermax && rdiff > ftol ; (*iters)++) - { - - //---------------------------------------------------------------------- - // t = r*C + (teleport * sum (r)) ; - //---------------------------------------------------------------------- - - // GxB_print (r, 2) ; - - float s = 1 ; - LAGRAPH_OK (GrB_reduce (&s, NULL, GxB_PLUS_FP32_MONOID, r, NULL)) ; - // printf ("s %g\n", s) ; - - double tic2 [2] ; - LAGraph_tic (tic2) ; - -// LAGRAPH_OK (GrB_vxm (t, NULL, NULL, GxB_PLUS_TIMES_FP32, r, C, NULL)) ; - LAGRAPH_OK (GrB_mxv (t, NULL, NULL, GxB_PLUS_TIMES_FP32, C, r, NULL)) ; - - double t3 = LAGraph_toc (tic2) ; - t2 += t3 ; -// fprintf (stderr, "one mxv %g\n", t3) ; - -// LAGraph_tic (tic2) ; -// LAGRAPH_OK (GrB_mxv (t, NULL, NULL, GxB_PLUS_TIMES_FP32, C, r, NULL)) ; -// t3 = LAGraph_toc (tic2) ; -// fprintf (stderr, "another mxv %g\n", t3) ; - - s *= teleport ; - LAGRAPH_OK (GrB_assign (t, NULL, GrB_PLUS_FP32, s, GrB_ALL, n, NULL)) ; - - //---------------------------------------------------------------------- - // rdiff = sum ((r-t).^2) - //---------------------------------------------------------------------- +/* float ftol = tol*tol ; // use tol^2 so sqrt(rdiff) not needed */ +/* float rdiff = 1 ; // so first iteration is always done */ + +/* LAGRAPH_OK (GrB_Vector_new (&t, GrB_FP32, n)) ; */ + +/* // GxB_print (C, 2) ; */ +/* // GxB_fprint (C, 2, stderr) ; */ + +/* tt = LAGraph_toc (tic) ; */ +/* fprintf (stderr, "C time %g\n", tt) ; */ +/* LAGraph_tic (tic) ; */ + +/* //-------------------------------------------------------------------------- */ +/* // iterate to compute the pagerank of each node */ +/* //-------------------------------------------------------------------------- */ + +/* double t2 = 0 ; */ + +/* for ((*iters) = 0 ; (*iters) < itermax && rdiff > ftol ; (*iters)++) */ +/* { */ + +/* //---------------------------------------------------------------------- */ +/* // t = r*C + (teleport * sum (r)) ; */ +/* //---------------------------------------------------------------------- */ + +/* // GxB_print (r, 2) ; */ + +/* float s = 1 ; */ +/* LAGRAPH_OK (GrB_reduce (&s, NULL, GxB_PLUS_FP32_MONOID, r, NULL)) ; */ +/* // printf ("s %g\n", s) ; */ + +/* double tic2 [2] ; */ +/* LAGraph_tic (tic2) ; */ + +/* // LAGRAPH_OK (GrB_vxm (t, NULL, NULL, GxB_PLUS_TIMES_FP32, r, C, NULL)) ; */ +/* LAGRAPH_OK (GrB_mxv (t, NULL, NULL, GxB_PLUS_TIMES_FP32, C, r, NULL)) ; */ + +/* double t3 = LAGraph_toc (tic2) ; */ +/* t2 += t3 ; */ +/* // fprintf (stderr, "one mxv %g\n", t3) ; */ + +/* // LAGraph_tic (tic2) ; */ +/* // LAGRAPH_OK (GrB_mxv (t, NULL, NULL, GxB_PLUS_TIMES_FP32, C, r, NULL)) ; */ +/* // t3 = LAGraph_toc (tic2) ; */ +/* // fprintf (stderr, "another mxv %g\n", t3) ; */ + +/* s *= teleport ; */ +/* LAGRAPH_OK (GrB_assign (t, NULL, GrB_PLUS_FP32, s, GrB_ALL, n, NULL)) ; */ + +/* //---------------------------------------------------------------------- */ +/* // rdiff = sum ((r-t).^2) */ +/* //---------------------------------------------------------------------- */ + +/* LAGRAPH_OK (GrB_eWiseAdd (r, NULL, NULL, op_diff, r, t, NULL)) ; */ +/* LAGRAPH_OK (GrB_reduce (&rdiff, NULL, GxB_PLUS_FP32_MONOID, r, NULL)) ; */ + +/* //---------------------------------------------------------------------- */ +/* // swap r and t */ +/* //---------------------------------------------------------------------- */ - LAGRAPH_OK (GrB_eWiseAdd (r, NULL, NULL, op_diff, r, t, NULL)) ; - LAGRAPH_OK (GrB_reduce (&rdiff, NULL, GxB_PLUS_FP32_MONOID, r, NULL)) ; +/* GrB_Vector temp = r ; */ +/* r = t ; */ +/* t = temp ; */ +/* // LAGRAPH_OK (GrB_Vector_clear (t)) ; */ + +/* // GxB_print (r, 3) ; */ +/* } */ - //---------------------------------------------------------------------- - // swap r and t - //---------------------------------------------------------------------- - - GrB_Vector temp = r ; - r = t ; - t = temp ; -// LAGRAPH_OK (GrB_Vector_clear (t)) ; - - // GxB_print (r, 3) ; - } - - fprintf (stderr, "mxv %g\n", t2) ; - - LAGRAPH_OK (GrB_free (&C)) ; - LAGRAPH_OK (GrB_free (&t)) ; - - tt = LAGraph_toc (tic) ; - fprintf (stderr, "rank time %g\n", tt) ; - LAGraph_tic (tic) ; - - //-------------------------------------------------------------------------- - // scale the result - //-------------------------------------------------------------------------- - - // rsum = sum (r) - LAGRAPH_OK (GrB_reduce (&rsum, NULL, GxB_PLUS_FP32_MONOID, r, NULL)) ; - - // r = r / rsum - LAGRAPH_OK (GrB_apply (r, NULL, NULL, op_div, r, NULL)) ; - - //-------------------------------------------------------------------------- - // sort the nodes by pagerank - //-------------------------------------------------------------------------- - - // [r,irank] = sort (r, 'descend') ; - - // extract the contents of r - #ifdef GxB_SUITESPARSE_GRAPHBLAS - LAGRAPH_OK (GxB_Vector_export (&r, &type, &n, &nvals, &I, (void **) (&X), - NULL)) ; - #else - nvals = n ; - I = malloc_function (n * sizeof (GrB_Index)) ; - X = malloc_function (n * sizeof (float)) ; - if (I == NULL || X == NULL) - { - LAGRAPH_ERROR ("out of memory", GrB_OUT_OF_MEMORY) ; - } - LAGRAPH_OK (GrB_Vector_extractTuples (I, X, &nvals, r)) ; - LAGRAPH_OK (GrB_free (&r)) ; - #endif - - // this will always be true since r is dense, but check anyway: - if (nvals != n) return (GrB_PANIC) ; - - // P = struct (X,I) - P = malloc_function (n * sizeof (LAGraph_PageRank)) ; - if (P == NULL) - { - LAGRAPH_ERROR ("out of memory", GrB_OUT_OF_MEMORY) ; - } - for (int64_t k = 0 ; k < nvals ; k++) - { - // The kth ranked page is P[k].page (with k=0 being the highest rank), - // and its pagerank is P[k].pagerank. - P [k].pagerank = X [k] ; - // I [k] == k will be true for SuiteSparse:GraphBLAS but in general I - // can be returned in any order, so use I [k] instead of k, for other - // GraphBLAS implementations. - #ifdef GxB_SUITESPARSE_GRAPHBLAS - P [k].page = k ; - #else - P [k].page = I [k] ; - #endif - } - - // free workspace - FREEWORK ; - - // qsort (P) in descending order - qsort (P, n, sizeof (LAGraph_PageRank), compar) ; - - //-------------------------------------------------------------------------- - // return result - //-------------------------------------------------------------------------- - - tt = LAGraph_toc (tic) ; - fprintf (stderr, "fini time %g\n", tt) ; - - (*Phandle) = P ; - return (GrB_SUCCESS) ; -} +/* fprintf (stderr, "mxv %g\n", t2) ; */ + +/* LAGRAPH_OK (GrB_free (&C)) ; */ +/* LAGRAPH_OK (GrB_free (&t)) ; */ +/* tt = LAGraph_toc (tic) ; */ +/* fprintf (stderr, "rank time %g\n", tt) ; */ +/* LAGraph_tic (tic) ; */ + +/* //-------------------------------------------------------------------------- */ +/* // scale the result */ +/* //-------------------------------------------------------------------------- */ + +/* // rsum = sum (r) */ +/* LAGRAPH_OK (GrB_reduce (&rsum, NULL, GxB_PLUS_FP32_MONOID, r, NULL)) ; */ + +/* // r = r / rsum */ +/* LAGRAPH_OK (GrB_apply (r, NULL, NULL, op_div, r, NULL)) ; */ + +/* //-------------------------------------------------------------------------- */ +/* // sort the nodes by pagerank */ +/* //-------------------------------------------------------------------------- */ + +/* // [r,irank] = sort (r, 'descend') ; */ + +/* // extract the contents of r */ +/* #ifdef GxB_SUITESPARSE_GRAPHBLAS */ +/* LAGRAPH_OK (GxB_Vector_export (&r, &type, &n, &nvals, &I, (void **) (&X), */ +/* NULL)) ; */ +/* #else */ +/* nvals = n ; */ +/* I = malloc_function (n * sizeof (GrB_Index)) ; */ +/* X = malloc_function (n * sizeof (float)) ; */ +/* if (I == NULL || X == NULL) */ +/* { */ +/* LAGRAPH_ERROR ("out of memory", GrB_OUT_OF_MEMORY) ; */ +/* } */ +/* LAGRAPH_OK (GrB_Vector_extractTuples (I, X, &nvals, r)) ; */ +/* LAGRAPH_OK (GrB_free (&r)) ; */ +/* #endif */ + +/* // this will always be true since r is dense, but check anyway: */ +/* if (nvals != n) return (GrB_PANIC) ; */ + +/* // P = struct (X,I) */ +/* P = malloc_function (n * sizeof (LAGraph_PageRank)) ; */ +/* if (P == NULL) */ +/* { */ +/* LAGRAPH_ERROR ("out of memory", GrB_OUT_OF_MEMORY) ; */ +/* } */ +/* for (int64_t k = 0 ; k < nvals ; k++) */ +/* { */ +/* // The kth ranked page is P[k].page (with k=0 being the highest rank), */ +/* // and its pagerank is P[k].pagerank. */ +/* P [k].pagerank = X [k] ; */ +/* // I [k] == k will be true for SuiteSparse:GraphBLAS but in general I */ +/* // can be returned in any order, so use I [k] instead of k, for other */ +/* // GraphBLAS implementations. */ +/* #ifdef GxB_SUITESPARSE_GRAPHBLAS */ +/* P [k].page = k ; */ +/* #else */ +/* P [k].page = I [k] ; */ +/* #endif */ +/* } */ + +/* // free workspace */ +/* FREEWORK ; */ + +/* // qsort (P) in descending order */ +/* qsort (P, n, sizeof (LAGraph_PageRank), compar) ; */ + +/* //-------------------------------------------------------------------------- */ +/* // return result */ +/* //-------------------------------------------------------------------------- */ + +/* tt = LAGraph_toc (tic) ; */ +/* fprintf (stderr, "fini time %g\n", tt) ; */ + +/* (*Phandle) = P ; */ +/* return (GrB_SUCCESS) ; */ +/* } */ diff --git a/src/matrix.c b/src/matrix.c index ba46a72..13ad62d 100644 --- a/src/matrix.c +++ b/src/matrix.c @@ -1,5 +1,5 @@ -/* The same "header template" vector.h is used to generate the various +/* The same "header template" matrix.h is used to generate the various type specific functions. */ #define SUFFIX _bool @@ -172,7 +172,7 @@ matrix_nrows(PG_FUNCTION_ARGS) { pgGrB_Matrix *mat; GrB_Index count; mat = PGGRB_GETARG_MATRIX(0); - CHECKD(GrB_Matrix_nrows(&count, mat->M)); + CHECKD(GrB_Matrix_nrows(&count, mat->M), mat->M); return Int64GetDatum(count); } @@ -182,7 +182,7 @@ matrix_ncols(PG_FUNCTION_ARGS) { pgGrB_Matrix *mat; GrB_Index count; mat = PGGRB_GETARG_MATRIX(0); - CHECKD(GrB_Matrix_ncols(&count, mat->M)); + CHECKD(GrB_Matrix_ncols(&count, mat->M), mat->M); return Int64GetDatum(count); } @@ -192,7 +192,7 @@ matrix_nvals(PG_FUNCTION_ARGS) { pgGrB_Matrix *mat; GrB_Index count; mat = PGGRB_GETARG_MATRIX(0); - CHECKD(GrB_Matrix_nvals(&count, mat->M)); + CHECKD(GrB_Matrix_nvals(&count, mat->M), mat->M); return Int64GetDatum(count); } @@ -205,7 +205,7 @@ matrix_eq(PG_FUNCTION_ARGS) { A = PGGRB_GETARG_MATRIX(0); B = PGGRB_GETARG_MATRIX(1); - CHECKD(LAGraph_isequal(&result, A->M, B->M, NULL)); + CHECKD(LAGraph_isequal(&result, A->M, B->M, NULL), A->M); PG_RETURN_BOOL(result); } @@ -218,7 +218,7 @@ matrix_ne(PG_FUNCTION_ARGS) { A = PGGRB_GETARG_MATRIX(0); B = PGGRB_GETARG_MATRIX(1); - CHECKD(LAGraph_isequal(&result, A->M, B->M, NULL)); + CHECKD(LAGraph_isequal(&result, A->M, B->M, NULL), A->M); PG_RETURN_BOOL(!result); } @@ -448,17 +448,17 @@ matrix_reduce_vector(PG_FUNCTION_ARGS) { text_to_cstring(PG_GETARG_TEXT_PP(1)); if (semiring_name == NULL) { - CHECKD(GxB_Matrix_type(&type, A->M)); + CHECKD(GxB_Matrix_type(&type, A->M), A->M); semiring_name = DEFAULT_SEMIRING(type); } semiring = lookup_semiring(semiring_name); - CHECKD(GxB_Semiring_add(&monoid, semiring)); + CHECKD(GxB_Semiring_add(&monoid, semiring), semiring); - CHECKD(GrB_Matrix_ncols(&size, A->M)); + CHECKD(GrB_Matrix_ncols(&size, A->M), A->M); TYPE_APPLY(val, A->type, construct_empty_expanded_vector, size, CurrentMemoryContext); - CHECKD(GrB_reduce(val->V, NULL, monoid, A->M, NULL)); + CHECKD(GrB_reduce(val->V, NULL, monoid, A->M, NULL), A->M); PGGRB_RETURN_VECTOR(val); } @@ -480,12 +480,12 @@ matrix_transpose(PG_FUNCTION_ARGS) { } if (C == NULL) { - CHECKD(GrB_Matrix_nrows(&m, A->M)); - CHECKD(GrB_Matrix_ncols(&n, A->M)); - TYPE_APPLY(C, A->type, construct_empty_expanded_matrix, m, n, CurrentMemoryContext); + CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&n, A->M), A->M); + TYPE_APPLY(C, A->type, construct_empty_expanded_matrix, m, n, CurrentMemoryContext); } - CHECKD(GrB_transpose(C->M, mask? mask->M:NULL, NULL, A->M, desc)); + CHECKD(GrB_transpose(C->M, mask? mask->M:NULL, NULL, A->M, desc), A->M); PGGRB_RETURN_MATRIX(C); } @@ -499,7 +499,7 @@ matrix_assign_matrix(PG_FUNCTION_ARGS) { B = PGGRB_GETARG_MATRIX(1); mask = PG_ARGISNULL(2)? NULL : PGGRB_GETARG_MATRIX(2); - CHECKD(GrB_Matrix_nvals(&nvals, B->M)); + CHECKD(GrB_Matrix_nvals(&nvals, B->M), B->M); if (B != NULL) { TYPE_APPLY(nvals, B->type, extract_rowscols, B, &rows, &cols, nvals); @@ -513,7 +513,7 @@ matrix_assign_matrix(PG_FUNCTION_ARGS) { nvals, cols? cols : GrB_ALL, nvals, - NULL)); + NULL), A->M); PGGRB_RETURN_MATRIX(A); } @@ -573,17 +573,17 @@ matrix_xtract(PG_FUNCTION_ARGS) { C = PG_ARGISNULL(2) ? NULL : PGGRB_GETARG_MATRIX(2); GET_DESCRIPTOR(3, desc); - CHECKD(GrB_Matrix_nrows(&nrows, A->M)); - CHECKD(GrB_Matrix_ncols(&ncols, A->M)); + CHECKD(GrB_Matrix_nrows(&nrows, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&ncols, A->M), A->M); if (C == NULL) { TYPE_APPLY(C, A->type, construct_empty_expanded_matrix, nrows, ncols, CurrentMemoryContext); } - CHECKD(GrB_Matrix_nvals(&nvals, A->M)); + CHECKD(GrB_Matrix_nvals(&nvals, A->M), A->M); TYPE_APPLY(nvals, A->type, extract_rowscols, B, &rows, &cols, nvals); - CHECKD(GrB_Matrix_extract(C->M, NULL, NULL, A->M, rows, nrows, cols, ncols, NULL)); + CHECKD(GrB_Matrix_extract(C->M, NULL, NULL, A->M, rows, nrows, cols, ncols, NULL), A->M); PGGRB_RETURN_MATRIX(C); } @@ -646,169 +646,12 @@ matrix_mmread(PG_FUNCTION_ARGS) { elog(ERROR, "unable to open memstream for matrix_mmread"); LAGraph_mmread(&M, fp); - CHECKD(GrB_Matrix_nrows(&nrows, M)); - CHECKD(GrB_Matrix_ncols(&ncols, M)); - CHECKD(GxB_Matrix_type(&type, M)); + CHECKD(GrB_Matrix_nrows(&nrows, M), M); + CHECKD(GrB_Matrix_ncols(&ncols, M), M); + CHECKD(GxB_Matrix_type(&type, M), M); TYPE_APPLY(A, type, construct_empty_expanded_matrix, nrows, ncols, CurrentMemoryContext); - CHECKD(GrB_free(&A->M)); + CHECKD(GrB_free(&A->M), A->M); A->M = M; PGGRB_RETURN_MATRIX(A); } - -Datum -matrix_bfs(PG_FUNCTION_ARGS) { - pgGrB_Matrix *A, *AT; - pgGrB_Vector *R; - GrB_Vector V, P; - GrB_Index size, start; - GrB_Info info; - - A = PGGRB_GETARG_MATRIX(0); - start = PG_GETARG_INT64(1); - AT = PG_ARGISNULL(2)? NULL : PGGRB_GETARG_MATRIX(2); - - CHECKD(LAGraph_bfs_pushpull(&V, &P, A->M, AT? AT->M : NULL, start, 0, true)); - CHECKD(GrB_Matrix_nrows(&size, A->M)); - TYPE_APPLY(R, GrB_INT32, construct_empty_expanded_vector, size, CurrentMemoryContext); - CHECKD(GrB_free(&R->V)); - R->V = V; - PGGRB_RETURN_VECTOR(R); -} - -Datum -matrix_pagerank(PG_FUNCTION_ARGS) { - GrB_Info info; - FuncCallContext *funcctx; - TupleDesc tupdesc; - Datum result; - - Datum values[2]; - bool nulls[2] = {false, false}; - HeapTuple tuple; - GrB_Index nrows = 0; - pgGrB_Matrix *mat; - pgGrB_Matrix_PageRankState *state; - int iters; - LAGraph_PageRank *ranks = NULL; - - if (SRF_IS_FIRSTCALL()) { - MemoryContext oldcontext; - - funcctx = SRF_FIRSTCALL_INIT(); - oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - mat = PGGRB_GETARG_MATRIX(0); - - state = (pgGrB_Matrix_PageRankState*)palloc(sizeof(pgGrB_Matrix_PageRankState)); - CHECKD(GrB_Matrix_nrows(&nrows, mat->M)); - CHECKD(LAGraph_pagerank(&ranks, mat->M, 100, 0.0001, &iters)); - - state->ranks = ranks; - funcctx->max_calls = nrows; - funcctx->user_fctx = (void*)state; - - if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("function returning record called in context " - "that cannot accept type record"))); - BlessTupleDesc(tupdesc); - funcctx->tuple_desc = tupdesc; - - MemoryContextSwitchTo(oldcontext); - } - - funcctx = SRF_PERCALL_SETUP(); - state = (pgGrB_Matrix_PageRankState*)funcctx->user_fctx; - - if (funcctx->call_cntr < funcctx->max_calls) { - values[0] = Int64GetDatum(state->ranks[funcctx->call_cntr].page); - values[1] = Float8GetDatum(state->ranks[funcctx->call_cntr].pagerank); - - tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); - result = HeapTupleGetDatum(tuple); - SRF_RETURN_NEXT(funcctx, result); - } else { - SRF_RETURN_DONE(funcctx); - } -} - -/* Datum sssp_bf(PG_FUNCTION_ARGS) { */ -/* pgGrB_Matrix *A; */ -/* GrB_Vector pd, ppi, ph; */ -/* GrB_Index start, n; */ -/* GrB_Info info; */ -/* FuncCallContext *funcctx; */ -/* GrB_Index cnt, nrows; */ -/* TupleDesc tupdesc; */ -/* Datum result; */ -/* pgGrB_Matrix_SSSPState *state; */ -/* float8 distance; */ -/* int64 parent; */ -/* int64 hops; */ - -/* Datum values[4]; */ -/* bool nulls[4] = {false, false, false, false}; */ -/* HeapTuple tuple; */ - - -/* if (SRF_IS_FIRSTCALL()) { */ -/* MemoryContext oldcontext; */ - -/* funcctx = SRF_FIRSTCALL_INIT(); */ -/* oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); */ -/* A = PGGRB_GETARG_MATRIX(0); */ -/* start = PG_GETARG_INT64(1); */ - -/* state = (pgGrB_Matrix_SSSPState*)palloc(sizeof(pgGrB_Matrix_SSSPState)); */ - -/* CHECKD(GrB_Matrix_nrows(&n, A->M)); */ -/* for (GrB_Index i = 0; i < n; i++) { */ -/* CHECKD(GrB_Matrix_setElement_FP64 (A->M, 0, i, i)); */ -/* } */ - -/* CHECKD(LAGraph_BF_full(&pd, &ppi, &ph, A->M, start)); */ - -/* state->pd = pd; */ -/* state->ppi = ppi; */ -/* state->ph = ph; */ - -/* funcctx->max_calls = n; */ -/* funcctx->user_fctx = (void*)state; */ - -/* if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) */ -/* ereport(ERROR, */ -/* (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), */ -/* errmsg("function returning record called in context " */ -/* "that cannot accept type record"))); */ -/* BlessTupleDesc(tupdesc); */ -/* funcctx->tuple_desc = tupdesc; */ - -/* MemoryContextSwitchTo(oldcontext); */ -/* } */ - -/* funcctx = SRF_PERCALL_SETUP(); */ -/* state = (pgGrB_Matrix_SSSPState*)funcctx->user_fctx; */ - -/* cnt = funcctx->call_cntr; */ -/* if (cnt < funcctx->max_calls) { */ - -/* CHECKD(GrB_Vector_extractElement(&distance, state->pd, cnt)); */ -/* CHECKD(GrB_Vector_extractElement(&parent, state->ppi, cnt)); */ -/* CHECKD(GrB_Vector_extractElement(&hops, state->ph, cnt)); */ - -/* values[0] = Int64GetDatum(cnt); */ - -/* values[1] = distance == INFINITY? get_float8_infinity() : Float8GetDatum(distance); */ - -/* values[2] = Int64GetDatum(parent); */ -/* values[3] = Int64GetDatum(hops); */ - -/* tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); */ -/* result = HeapTupleGetDatum(tuple); */ -/* SRF_RETURN_NEXT(funcctx, result); */ -/* } else { */ -/* SRF_RETURN_DONE(funcctx); */ -/* } */ - -/* } */ diff --git a/src/matrix.h b/src/matrix.h index d538949..a384fb4 100644 --- a/src/matrix.h +++ b/src/matrix.h @@ -109,9 +109,9 @@ FN(matrix_get_flat_size)(ExpandedObjectHeader *eohptr) { if (A->flat_size) return A->flat_size; - CHECKD(GrB_Matrix_nrows(&nrows, A->M)); - CHECKD(GrB_Matrix_ncols(&ncols, A->M)); - CHECKD(GrB_Matrix_nvals(&nvals, A->M)); + CHECKD(GrB_Matrix_nrows(&nrows, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&ncols, A->M), A->M); + CHECKD(GrB_Matrix_nvals(&nvals, A->M), A->M); nbytes = PGGRB_MATRIX_OVERHEAD(); #ifdef IMPORT_EXPORT @@ -158,7 +158,7 @@ FN(matrix_flatten_into)(ExpandedObjectHeader *eohptr, &rows, &cols, &values, - NULL)); + NULL), A->M); if (nvals > 0) { memcpy(PGGRB_MATRIX_DATA(flat), @@ -176,16 +176,16 @@ FN(matrix_flatten_into)(ExpandedObjectHeader *eohptr, } flat->nonempty = nonempty; #else - CHECKV(GrB_Matrix_nrows(&nrows, A->M)); - CHECKV(GrB_Matrix_ncols(&ncols, A->M)); - CHECKV(GrB_Matrix_nvals(&nvals, A->M)); + CHECKV(GrB_Matrix_nrows(&nrows, A->M), A->M); + CHECKV(GrB_Matrix_ncols(&ncols, A->M), A->M); + CHECKV(GrB_Matrix_nvals(&nvals, A->M), A->M); rows = PGGRB_MATRIX_DATA(flat); CHECKV(GrB_Matrix_extractTuples(rows, rows + nvals, rows + nvals + nvals, &nvals, - A->M)); + A->M), A->M); #endif flat->type = GB_TYPE; @@ -267,7 +267,7 @@ FN(expand_flat_matrix)(pgGrB_FlatMatrix *flat, &cols, &vals, NULL - )); + ), A->M); if (A->M == NULL) { pfree(rows); pfree(cols); @@ -278,7 +278,7 @@ FN(expand_flat_matrix)(pgGrB_FlatMatrix *flat, CHECKD(GrB_Matrix_new(&A->M, type, nrows, - ncols)); + ncols), A->M); } #else @@ -286,7 +286,7 @@ FN(expand_flat_matrix)(pgGrB_FlatMatrix *flat, CHECKD(GrB_Matrix_new(&A->M, type, nrows, - ncols)); + ncols), A->M); if (nvals > 0) { /* Rows, cols, and vals are pointers into the vardata area */ @@ -299,7 +299,7 @@ FN(expand_flat_matrix)(pgGrB_FlatMatrix *flat, cols, vals, nvals, - GB_DUP)); + GB_DUP), A->M); } #endif @@ -368,7 +368,7 @@ FN(matrix_elements)(PG_FUNCTION_ARGS) { mat = PGGRB_GETARG_MATRIX(0); state = (FN(pgGrB_Matrix_ExtractState)*)palloc(sizeof(FN(pgGrB_Matrix_ExtractState))); - CHECKD(GrB_Matrix_nvals(&nvals, mat->M)); + CHECKD(GrB_Matrix_nvals(&nvals, mat->M), mat->M); state->rows = (GrB_Index*) palloc0(sizeof(GrB_Index) * nvals); state->cols = (GrB_Index*) palloc0(sizeof(GrB_Index) * nvals); @@ -378,7 +378,7 @@ FN(matrix_elements)(PG_FUNCTION_ARGS) { state->cols, state->vals, &nvals, - mat->M)); + mat->M), mat->M); state->mat = mat; funcctx->max_calls = nvals; funcctx->user_fctx = (void*)state; @@ -425,11 +425,11 @@ FN(matrix_ewise_mult)(pgGrB_Matrix *A, GrB_Index m, n; if (C == NULL) { - CHECKD(GrB_Matrix_nrows(&m, A->M)); - CHECKD(GrB_Matrix_ncols(&n, A->M)); + CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&n, A->M), A->M); C = FN(construct_empty_expanded_matrix)(m, n, CurrentMemoryContext); } - CHECKD(GrB_eWiseMult(C->M, mask ? mask->M : NULL, accum, binop, A->M, B->M, desc)); + CHECKD(GrB_eWiseMult(C->M, mask ? mask->M : NULL, accum, binop, A->M, B->M, desc), A->M); PGGRB_RETURN_MATRIX(C); } @@ -446,12 +446,12 @@ FN(matrix_ewise_add)(pgGrB_Matrix *A, GrB_Index m, n; if (C == NULL) { - CHECKD(GrB_Matrix_nrows(&m, A->M)); - CHECKD(GrB_Matrix_ncols(&n, A->M)); + CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&n, A->M), A->M); C = FN(construct_empty_expanded_matrix)(m, n, CurrentMemoryContext); } - CHECKD(GrB_eWiseAdd(C->M, mask ? mask->M : NULL, accum, binop, A->M, B->M, desc)); + CHECKD(GrB_eWiseAdd(C->M, mask ? mask->M : NULL, accum, binop, A->M, B->M, desc), A->M); PGGRB_RETURN_MATRIX(C); } @@ -467,11 +467,11 @@ FN(mxm)(pgGrB_Matrix *A, if (C == NULL) { GrB_Index m, n; - CHECKD(GrB_Matrix_nrows(&m, A->M)); - CHECKD(GrB_Matrix_ncols(&n, B->M)); + CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&n, B->M), A->M); C = FN(construct_empty_expanded_matrix)(m, n, CurrentMemoryContext); } - CHECKD(GrB_mxm(C->M, mask ? mask->M : NULL, binop, semiring, A->M, B->M, desc)); + CHECKD(GrB_mxm(C->M, mask ? mask->M : NULL, binop, semiring, A->M, B->M, desc), A->M); PGGRB_RETURN_MATRIX(C); } @@ -487,10 +487,10 @@ FN(mxv)(pgGrB_Matrix *A, GrB_Index size; if (C == NULL) { - CHECKD(GrB_Matrix_ncols(&size, A->M)); + CHECKD(GrB_Matrix_ncols(&size, A->M), A->M); C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); } - CHECKD(GrB_mxv(C->V, mask ? mask->V : NULL, binop, semiring, A->M, B->V, desc)); + CHECKD(GrB_mxv(C->V, mask ? mask->V : NULL, binop, semiring, A->M, B->V, desc), A->M); PGGRB_RETURN_VECTOR(C); } @@ -506,10 +506,10 @@ FN(vxm)(pgGrB_Vector *A, GrB_Index size; if (C == NULL) { - CHECKD(GrB_Vector_size(&size, A->V)); + CHECKD(GrB_Vector_size(&size, A->V), A->M); C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); } - CHECKD(GrB_vxm(C->V, mask ? mask->V : NULL, binop, semiring, A->V, B->M, desc)); + CHECKD(GrB_vxm(C->V, mask ? mask->V : NULL, binop, semiring, A->V, B->M, desc), A->M); PGGRB_RETURN_VECTOR(C); } @@ -607,7 +607,7 @@ FN(matrix)(PG_FUNCTION_ARGS) { col_indices, values, count, - GB_DUP)); + GB_DUP), A->M); PGGRB_RETURN_MATRIX(retval); } @@ -628,12 +628,12 @@ FN(matrix_reduce)(PG_FUNCTION_ARGS) { text_to_cstring(PG_GETARG_TEXT_PP(1)); if (semiring_name == NULL) { - CHECKD(GxB_Matrix_type(&type, A->M)); + CHECKD(GxB_Matrix_type(&type, A->M), A->M); semiring_name = DEFAULT_SEMIRING(type); } semiring = lookup_semiring(semiring_name); - CHECKD(GxB_Semiring_add(&monoid, semiring)); - CHECKD(GrB_reduce(&val, NULL, monoid, A->M, NULL)); + CHECKD(GxB_Semiring_add(&monoid, semiring), A->M); + CHECKD(GrB_reduce(&val, NULL, monoid, A->M, NULL), A->M); PG_RET(val); } @@ -652,7 +652,7 @@ GrB_Index FN(extract_rowscols)(pgGrB_Matrix *A, *cols, values, &nvals, - A->M)); + A->M), A->M); return nvals; } @@ -670,11 +670,11 @@ FN(matrix_assign)(PG_FUNCTION_ARGS) { mask = PG_ARGISNULL(3)? NULL : PGGRB_GETARG_MATRIX(3); if (B != NULL) { - CHECKD(GrB_Matrix_nvals(&nvals, B->M)); + CHECKD(GrB_Matrix_nvals(&nvals, B->M), A->M); nrows = ncols = nvals = FN(extract_rowscols)(B, &rows, &cols, nvals); } else { - CHECKD(GrB_Matrix_nrows(&nrows, A->M)); - CHECKD(GrB_Matrix_ncols(&ncols, A->M)); + CHECKD(GrB_Matrix_nrows(&nrows, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&ncols, A->M), A->M); } CHECKD(GrB_assign(A->M, @@ -685,7 +685,7 @@ FN(matrix_assign)(PG_FUNCTION_ARGS) { nrows, cols?cols:GrB_ALL, ncols, - NULL)); + NULL), A->M); PGGRB_RETURN_MATRIX(A); } @@ -702,13 +702,13 @@ FN(matrix_kron)(pgGrB_Matrix *A, if (C == NULL) { GrB_Index m, n, p, q; - CHECKD(GrB_Matrix_nrows(&m, A->M)); - CHECKD(GrB_Matrix_ncols(&n, A->M)); - CHECKD(GrB_Matrix_nrows(&p, B->M)); - CHECKD(GrB_Matrix_ncols(&q, B->M)); + CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&n, A->M), A->M); + CHECKD(GrB_Matrix_nrows(&p, B->M), B->M); + CHECKD(GrB_Matrix_ncols(&q, B->M), B->M); C = FN(construct_empty_expanded_matrix)(m*p, n*q, CurrentMemoryContext); } - CHECKD(GxB_kron(C->M, mask ? mask->M : NULL, accum, mulop, A->M, B->M, desc)); + CHECKD(GxB_kron(C->M, mask ? mask->M : NULL, accum, mulop, A->M, B->M, desc), A->M); PGGRB_RETURN_MATRIX(C); } @@ -744,9 +744,9 @@ FN(matrix_random)(PG_FUNCTION_ARGS) { make_skew_symmetric, make_hermitian, no_diagonal, - &seed)); + &seed), A->M); - CHECKD(GrB_free(&A->M)); + CHECKD(GrB_free(&A->M), A->M); A->M = M; PGGRB_RETURN_MATRIX(A); } @@ -763,7 +763,7 @@ FN(matrix_set_element)(PG_FUNCTION_ARGS) { col = PG_GETARG_INT64(2); val = PG_GET(3); - CHECKD(GrB_Matrix_setElement(A->M, val, row, col)); + CHECKD(GrB_Matrix_setElement(A->M, val, row, col), A->M); PGGRB_RETURN_MATRIX(A); } diff --git a/src/pggraphblas.c b/src/pggraphblas.c index 40ee0a7..a1c79a3 100644 --- a/src/pggraphblas.c +++ b/src/pggraphblas.c @@ -76,10 +76,12 @@ _PG_init(void) #endif if (! (info == GrB_SUCCESS || info == GrB_NO_VALUE)) { - elog(ERROR, "%s", GrB_error()); + const char *emsg; + GrB_error(&emsg, NULL); + elog(ERROR, "%s", emsg); return; } - + SEMIRING_GROUP(0, FIRST_); SEMIRING_GROUP(40, SECOND_); SEMIRING_GROUP(80, MIN_); diff --git a/src/pggraphblas.h b/src/pggraphblas.h index cea040d..f5d3fd0 100644 --- a/src/pggraphblas.h +++ b/src/pggraphblas.h @@ -1,8 +1,7 @@ #ifndef PGGRAPHBLAS_H #define PGGRAPHBLAS_H -#include "GraphBLAS.h" -#include "LAGraph.h" +#include "suitesparse/GraphBLAS.h" #include "postgres.h" #include "utils/builtins.h" #include "libpq/pqformat.h" @@ -96,22 +95,26 @@ /* GraphBLAS API checking macros */ -#define CHECKD(method) \ +#define CHECKD(method, obj) \ { \ info = method ; \ if (! (info == GrB_SUCCESS || info == GrB_NO_VALUE)) \ { \ - elog(ERROR, "%s", GrB_error()); \ - return (Datum) 0; \ + const char *emsg; \ + GrB_error(&emsg, obj); \ + elog(ERROR, "%s", emsg); \ + return (Datum) 0; \ } \ -} + } \ -#define CHECKV(method) \ +#define CHECKV(method, obj) \ { \ info = method ; \ if (! (info == GrB_SUCCESS || info == GrB_NO_VALUE)) \ { \ - elog(ERROR, "%s", GrB_error()); \ + const char *emsg; \ + GrB_error(&emsg, obj); \ + elog(ERROR, "%s", emsg); \ return; \ } \ } \ @@ -176,9 +179,9 @@ typedef struct pgGrB_Matrix { Size flat_size; } pgGrB_Matrix; -typedef struct pgGrB_Matrix_PageRankState { - LAGraph_PageRank *ranks; -} pgGrB_Matrix_PageRankState; +/* typedef struct pgGrB_Matrix_PageRankState { */ +/* LAGraph_PageRank *ranks; */ +/* } pgGrB_Matrix_PageRankState; */ typedef struct pgGrB_Matrix_SSSPState { GrB_Vector pd; @@ -244,7 +247,7 @@ PG_FUNCTION_INFO_V1(matrix_reduce_vector); PG_FUNCTION_INFO_V1(matrix_transpose); PG_FUNCTION_INFO_V1(matrix_assign_matrix); PG_FUNCTION_INFO_V1(matrix_bfs); -PG_FUNCTION_INFO_V1(matrix_pagerank); +//PG_FUNCTION_INFO_V1(matrix_pagerank); /* PG_FUNCTION_INFO_V1(sssp_bf); */ /* Vectors */ @@ -452,20 +455,20 @@ typedef struct pgGrB_UnaryOp { if (!PG_ARGISNULL(ARG)) { \ (desc_val) = text_to_cstring(PG_GETARG_TEXT_PP(ARG)); \ if (strcmp((desc_val), "default") == 0) { \ - CHECKD(GrB_Descriptor_set((DESC), GrB_##FIELD, GxB_DEFAULT)); \ + CHECKD(GrB_Descriptor_set((DESC), GrB_##FIELD, GxB_DEFAULT), DESC); \ } else if (strcmp((desc_val), "replace") == 0) { \ - CHECKD(GrB_Descriptor_set((DESC), GrB_##FIELD, GrB_##VAL)); \ + CHECKD(GrB_Descriptor_set((DESC), GrB_##FIELD, GrB_##VAL), DESC); \ } else if (strcmp((desc_val), "scmp") == 0) { \ - CHECKD(GrB_Descriptor_set((DESC), GrB_##FIELD, GrB_##VAL)); \ + CHECKD(GrB_Descriptor_set((DESC), GrB_##FIELD, GrB_##VAL), DESC); \ } else if (strcmp((desc_val), "tran") == 0) { \ - CHECKD(GrB_Descriptor_set((DESC), GrB_##FIELD, GrB_##VAL)); \ + CHECKD(GrB_Descriptor_set((DESC), GrB_##FIELD, GrB_##VAL), DESC); \ } else \ elog(ERROR, "unknown outp descriptor value %s", desc_val); \ } \ } while(0) #define GET_DESCRIPTOR(N, D) do { \ - CHECKD(GrB_Descriptor_new(&D)); \ + CHECKD(GrB_Descriptor_new(&D), D); \ GETARG_DESCRIPTOR_VAL(N, D, OUTP, REPLACE); \ GETARG_DESCRIPTOR_VAL(N+1, D, MASK, SCMP); \ GETARG_DESCRIPTOR_VAL(N+2, D, INP0, TRAN); \ diff --git a/src/type.c b/src/type.c index b479cc6..9e58e21 100644 --- a/src/type.c +++ b/src/type.c @@ -18,8 +18,8 @@ GrB_BinaryOp lookup_binop(char *name) { GrB_Type mxm_type(pgGrB_Matrix *left, pgGrB_Matrix *right) { GrB_Info info; GrB_Type atype, btype; - CHECKD(GxB_Matrix_type(&atype, left->M)); - CHECKD(GxB_Matrix_type(&btype, right->M)); + CHECKD(GxB_Matrix_type(&atype, left->M), left->M); + CHECKD(GxB_Matrix_type(&btype, right->M), right->M); RETURN_TYPECHCK2(atype, btype, FP64); RETURN_TYPECHCK2(atype, btype, FP32); RETURN_TYPECHCK2(atype, btype, INT64); @@ -32,8 +32,8 @@ GrB_Type mxm_type(pgGrB_Matrix *left, pgGrB_Matrix *right) { GrB_Type mxv_type(pgGrB_Matrix *left, pgGrB_Vector *right) { GrB_Info info; GrB_Type atype, btype; - CHECKD(GxB_Matrix_type(&atype, left->M)); - CHECKD(GxB_Vector_type(&btype, right->V)); + CHECKD(GxB_Matrix_type(&atype, left->M), left->M); + CHECKD(GxB_Vector_type(&btype, right->V), right->V); RETURN_TYPECHCK2(atype, btype, FP64); RETURN_TYPECHCK2(atype, btype, FP32); RETURN_TYPECHCK2(atype, btype, INT64); @@ -46,8 +46,8 @@ GrB_Type mxv_type(pgGrB_Matrix *left, pgGrB_Vector *right) { GrB_Type vxm_type(pgGrB_Vector *left, pgGrB_Matrix *right) { GrB_Info info; GrB_Type atype, btype; - CHECKD(GxB_Vector_type(&atype, left->V)); - CHECKD(GxB_Matrix_type(&btype, right->M)); + CHECKD(GxB_Vector_type(&atype, left->V), left->V); + CHECKD(GxB_Matrix_type(&btype, right->M), right->M); RETURN_TYPECHCK2(atype, btype, FP64); RETURN_TYPECHCK2(atype, btype, FP32); RETURN_TYPECHCK2(atype, btype, INT64); @@ -60,8 +60,8 @@ GrB_Type vxm_type(pgGrB_Vector *left, pgGrB_Matrix *right) { char* mxm_semiring(pgGrB_Matrix *left, pgGrB_Matrix *right) { GrB_Info info; GrB_Type atype, btype; - CHECKD(GxB_Matrix_type(&atype, left->M)); - CHECKD(GxB_Matrix_type(&btype, right->M)); + CHECKD(GxB_Matrix_type(&atype, left->M), left->M); + CHECKD(GxB_Matrix_type(&btype, right->M), right->M); RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, FP64); RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, FP32); RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT64); @@ -74,8 +74,8 @@ char* mxm_semiring(pgGrB_Matrix *left, pgGrB_Matrix *right) { char* mxv_semiring(pgGrB_Matrix *left, pgGrB_Vector *right) { GrB_Info info; GrB_Type atype, btype; - CHECKD(GxB_Matrix_type(&atype, left->M)); - CHECKD(GxB_Vector_type(&btype, right->V)); + CHECKD(GxB_Matrix_type(&atype, left->M), left->M); + CHECKD(GxB_Vector_type(&btype, right->V), right->V); RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, FP64); RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, FP32); RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT64); @@ -88,8 +88,8 @@ char* mxv_semiring(pgGrB_Matrix *left, pgGrB_Vector *right) { char* vxm_semiring(pgGrB_Vector *left, pgGrB_Matrix *right) { GrB_Info info; GrB_Type atype, btype; - CHECKD(GxB_Vector_type(&atype, left->V)); - CHECKD(GxB_Matrix_type(&btype, right->M)); + CHECKD(GxB_Vector_type(&atype, left->V), left->V); + CHECKD(GxB_Matrix_type(&btype, right->M), right->M); RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, FP64); RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, FP32); RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT64); @@ -103,14 +103,14 @@ char* vxm_semiring(pgGrB_Vector *left, pgGrB_Matrix *right) { char* matrix_times_binop(pgGrB_Matrix *left, pgGrB_Matrix *right) { GrB_Info info; GrB_Type type; - CHECKD(GxB_Matrix_type(&type, left->M)); + CHECKD(GxB_Matrix_type(&type, left->M), left->M); return DEFAULT_TIMES_BINOP(type); } char* matrix_plus_binop(pgGrB_Matrix *left, pgGrB_Matrix *right) { GrB_Info info; GrB_Type type; - CHECKD(GxB_Matrix_type(&type, left->M)); + CHECKD(GxB_Matrix_type(&type, left->M), left->M); return DEFAULT_PLUS_BINOP(type); } @@ -118,14 +118,14 @@ char* matrix_plus_binop(pgGrB_Matrix *left, pgGrB_Matrix *right) { char* vector_times_binop(pgGrB_Vector *left, pgGrB_Vector *right) { GrB_Info info; GrB_Type type; - CHECKD(GxB_Vector_type(&type, left->V)); + CHECKD(GxB_Vector_type(&type, left->V), left->V); return DEFAULT_TIMES_BINOP(type); } char* vector_plus_binop(pgGrB_Vector *left, pgGrB_Vector *right) { GrB_Info info; GrB_Type type; - CHECKD(GxB_Vector_type(&type, left->V)); + CHECKD(GxB_Vector_type(&type, left->V), left->V); return DEFAULT_PLUS_BINOP(type); } diff --git a/src/vector.c b/src/vector.c index da0d66a..dce7d90 100644 --- a/src/vector.c +++ b/src/vector.c @@ -269,7 +269,7 @@ vector_nvals(PG_FUNCTION_ARGS) { pgGrB_Vector *vec; GrB_Index nvals; vec = PGGRB_GETARG_VECTOR(0); - CHECKD(GrB_Vector_nvals(&nvals, vec->V)); + CHECKD(GrB_Vector_nvals(&nvals, vec->V), vec->V); return Int64GetDatum(nvals); } @@ -279,7 +279,7 @@ vector_size(PG_FUNCTION_ARGS) { pgGrB_Vector *vec; GrB_Index size; vec = PGGRB_GETARG_VECTOR(0); - CHECKD(GrB_Vector_size(&size, vec->V)); + CHECKD(GrB_Vector_size(&size, vec->V), vec->V); return Int64GetDatum(size); } @@ -293,7 +293,7 @@ vector_eq(PG_FUNCTION_ARGS) { A = PGGRB_GETARG_VECTOR(0); B = PGGRB_GETARG_VECTOR(1); - CHECKD(LAGraph_Vector_isequal(&result, A->V, B->V, NULL)); + CHECKD(LAGraph_Vector_isequal(&result, A->V, B->V, NULL), A->V); PG_RETURN_BOOL(result); } @@ -306,7 +306,7 @@ vector_ne(PG_FUNCTION_ARGS) { A = PGGRB_GETARG_VECTOR(0); B = PGGRB_GETARG_VECTOR(1); - CHECKD(LAGraph_Vector_isequal(&result, A->V, B->V, NULL)); + CHECKD(LAGraph_Vector_isequal(&result, A->V, B->V, NULL), A->V); PG_RETURN_BOOL(!result); } @@ -320,14 +320,14 @@ vector_xtract(PG_FUNCTION_ARGS) { B = PGGRB_GETARG_VECTOR(1); C = PG_ARGISNULL(2) ? NULL : PGGRB_GETARG_VECTOR(2); - CHECKD(GrB_Vector_size(&size, A->V)); + CHECKD(GrB_Vector_size(&size, A->V), A->V); if (C == NULL) { TYPE_APPLY(C, A->type, construct_empty_expanded_vector, size, CurrentMemoryContext); } TYPE_APPLY(indexes, A->type, extract_indexes, B, size); - CHECKD(GrB_Vector_extract(C->V, NULL, NULL, A->V, indexes, size, NULL)); + CHECKD(GrB_Vector_extract(C->V, NULL, NULL, A->V, indexes, size, NULL), A->V); PGGRB_RETURN_VECTOR(C); } diff --git a/src/vector.h b/src/vector.h index 6ab239f..fe2112d 100644 --- a/src/vector.h +++ b/src/vector.h @@ -70,8 +70,8 @@ FN(vector_get_flat_size)(ExpandedObjectHeader *eohptr) { if (A->flat_size) return A->flat_size; - CHECKD(GrB_Vector_size(&size, A->V)); - CHECKD(GrB_Vector_nvals(&nvals, A->V)); + CHECKD(GrB_Vector_size(&size, A->V), A->V); + CHECKD(GrB_Vector_nvals(&nvals, A->V), A->V); nbytes = PGGRB_VECTOR_OVERHEAD(); nbytes += size * sizeof(GrB_Index); @@ -89,27 +89,24 @@ FN(vector_flatten_into)(ExpandedObjectHeader *eohptr, GrB_Index *start, size, nvals; pgGrB_Vector *A = (pgGrB_Vector *) eohptr; pgGrB_FlatVector *flat = (pgGrB_FlatVector *) result; -#ifdef IMPORT_EXPORT void *values; GrB_Type type; -#endif Assert(A->ev_magic == vector_MAGIC); Assert(allocated_size == A->flat_size); memset(flat, 0, allocated_size); - CHECKV(GrB_Vector_nvals(&nvals, A->V)); - CHECKV(GrB_Vector_size(&size, A->V)); + CHECKV(GrB_Vector_nvals(&nvals, A->V), A->V); + CHECKV(GrB_Vector_size(&size, A->V), A->V); -#ifdef IMPORT_EXPORT - CHECKV(GxB_Vector_export(&A->V, + CHECKV(GxB_Vector_export_CSC(&A->V, &type, &size, &nvals, &start, &values, - NULL)); + NULL), A->V); if (nvals > 0) { memcpy(PGGRB_VECTOR_DATA(flat), start, nvals*sizeof(GrB_Index)); @@ -117,13 +114,6 @@ FN(vector_flatten_into)(ExpandedObjectHeader *eohptr, pfree(start); pfree(values); } -#else - start = PGGRB_VECTOR_DATA(flat); - CHECKV(GrB_Vector_extractTuples(start, - start + size, - &nvals, - A->V)); -#endif flat->size = size; flat->nvals = nvals; @@ -182,7 +172,7 @@ FN(expand_flat_vector)(pgGrB_FlatVector *flat, /* Initialize the new vector */ CHECKD(GrB_Vector_new(&A->V, type, - size)); + size), A->V); /* Create a context callback to free vector when context is cleared */ ctxcb = (MemoryContextCallback*)MemoryContextAlloc( @@ -199,7 +189,7 @@ FN(expand_flat_vector)(pgGrB_FlatVector *flat, indices, vals, nvals, - GB_DUP)); + GB_DUP), A->V); } A->type = type; @@ -301,7 +291,7 @@ FN(vector)(PG_FUNCTION_ARGS) { row_indices, values, vcount, - GB_DUP)); + GB_DUP), retval->V); PGGRB_RETURN_VECTOR(retval); } @@ -328,7 +318,7 @@ FN(vector_elements)(PG_FUNCTION_ARGS) { vec = (pgGrB_Vector *) PGGRB_GETARG_VECTOR(0); state = (FN(pgGrB_Vector_ExtractState)*)palloc(sizeof(FN(pgGrB_Vector_ExtractState))); - CHECKD(GrB_Vector_size(&size, vec->V)); + CHECKD(GrB_Vector_size(&size, vec->V), vec->V); state->indices = (GrB_Index*) palloc0(sizeof(GrB_Index) * size); state->vals = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * size); @@ -336,7 +326,7 @@ FN(vector_elements)(PG_FUNCTION_ARGS) { CHECKD(GrB_Vector_extractTuples(state->indices, state->vals, &size, - vec->V)); + vec->V), vec->V); state->vec = vec; funcctx->max_calls = size; funcctx->user_fctx = (void*)state; @@ -381,10 +371,10 @@ FN(vector_ewise_mult)(pgGrB_Vector *A, GrB_Index size; if (C == NULL) { - CHECKD(GrB_Vector_size(&size, A->V)); + CHECKD(GrB_Vector_size(&size, A->V), A->V); C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); } - CHECKD(GrB_eWiseMult(C->V, mask ? mask->V : NULL, accum, binop, A->V, B->V, desc)); + CHECKD(GrB_eWiseMult(C->V, mask ? mask->V : NULL, accum, binop, A->V, B->V, desc), C->V); PGGRB_RETURN_VECTOR(C); } @@ -400,10 +390,10 @@ FN(vector_ewise_add)(pgGrB_Vector *A, GrB_Index size; if (C == NULL) { - CHECKD(GrB_Vector_size(&size, A->V)); + CHECKD(GrB_Vector_size(&size, A->V), A->V); C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); } - CHECKD(GrB_eWiseAdd(C->V, mask ? mask->V : NULL, accum, GB_ADD, A->V, B->V, desc)); + CHECKD(GrB_eWiseAdd(C->V, mask ? mask->V : NULL, accum, GB_ADD, A->V, B->V, desc), C->V); PGGRB_RETURN_VECTOR(C); } @@ -419,7 +409,7 @@ GrB_Index *FN(extract_indexes)(pgGrB_Vector *A, CHECKD(GrB_Vector_extractTuples(row_indices, values, &size, - A->V)); + A->V), A->V); return row_indices; } @@ -436,8 +426,8 @@ FN(vector_reduce)(PG_FUNCTION_ARGS) { semiring_name = PG_ARGISNULL(1) ? NULL : text_to_cstring(PG_GETARG_TEXT_PP(1)); semiring = semiring_name ? lookup_semiring(semiring_name) : GB_RNG; - CHECKD(GxB_Semiring_add(&monoid, semiring)); - CHECKD(GrB_reduce(&val, NULL, monoid, A->V, NULL)); + CHECKD(GxB_Semiring_add(&monoid, semiring), semiring); + CHECKD(GrB_reduce(&val, NULL, monoid, A->V, NULL), A->V); PG_RET(val); } @@ -453,12 +443,12 @@ FN(vector_assign)(PG_FUNCTION_ARGS) { B = PG_ARGISNULL(2) ? NULL : PGGRB_GETARG_VECTOR(2); mask = PG_ARGISNULL(3)? NULL : PGGRB_GETARG_VECTOR(3); - CHECKD(GrB_Vector_size(&size, A->V)); + CHECKD(GrB_Vector_size(&size, A->V), A->V); if (B != NULL) indexes = FN(extract_indexes)(B, size); - CHECKD(GrB_assign(A->V, mask? mask->V: NULL, NULL, val, indexes ? indexes : GrB_ALL, size, NULL)); + CHECKD(GrB_assign(A->V, mask? mask->V: NULL, NULL, val, indexes ? indexes : GrB_ALL, size, NULL), A->V); PGGRB_RETURN_VECTOR(A); } @@ -473,7 +463,7 @@ FN(vector_set_element)(PG_FUNCTION_ARGS) { index = PG_GETARG_INT64(1); val = PG_GET(2); - CHECKD(GrB_Vector_setElement(A->V, val, index)); + CHECKD(GrB_Vector_setElement(A->V, val, index), A->V); PGGRB_RETURN_VECTOR(A); } From cdb2c5436f25c87f91f68e19aa688354e861ef38 Mon Sep 17 00:00:00 2001 From: Michel Pelletier Date: Wed, 7 Aug 2024 16:27:28 -0700 Subject: [PATCH 2/6] remove current serialization functionality moving toward GxB_serialize --- Makefile | 4 +- demo/bfs.sql | 38 +---- pggraphblas--0.0.1.sql | 121 --------------- src/LAGraph_pagerank.c | 345 ----------------------------------------- src/matrix.c | 52 +------ src/matrix.h | 169 +------------------- src/pggraphblas.c | 32 +--- src/pggraphblas.h | 30 +--- src/type.c | 1 - src/vector.c | 4 +- src/vector.h | 15 -- 11 files changed, 22 insertions(+), 789 deletions(-) delete mode 100644 src/LAGraph_pagerank.c diff --git a/Makefile b/Makefile index f932720..0e87a57 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,8 @@ DATA = $(wildcard *--*.sql) PGXS := $(shell $(PG_CONFIG) --pgxs) MODULE_big = pggraphblas OBJS = $(patsubst %.c,%.o,$(wildcard src/pggraphblas.c)) -SHLIB_LINK = -lgraphblas -llagraph -PG_CPPFLAGS = -O0 +SHLIB_LINK = -lgraphblas +PG_CPPFLAGS = -O0 -Wfatal-errors TESTS = $(wildcard test/sql/*.sql) REGRESS = $(patsubst test/sql/%.sql,%,$(TESTS)) diff --git a/demo/bfs.sql b/demo/bfs.sql index 7f5f7fe..e4e0a24 100644 --- a/demo/bfs.sql +++ b/demo/bfs.sql @@ -2,43 +2,7 @@ \ir fixtures.sql -drop function if exists bfs2; - -create function bfs2(tablename text, source bigint) returns vector as $$ -declare - A matrix; - n bigint; - v vector; - q vector; - level integer := 0; -- Start at level 1. - not_done bool := true; -- Flag to indicate still work to do. - -begin - execute format('select matrix(array_agg(i), array_agg(j), array_agg(true)) from %I', tablename) into A; - n := nrows(A); -- The number of result rows. - v := vector_integer(n); -- int32 result vector of vertex levels. - q := assign(vector_bool(n), false); -- bool mask of completed vertices. - - q := set_element(q, source, true); -- Set the source element to done. - - while not_done and level <= n loop -- While still work to do. - v := assign(v, level, mask=>q); -- Assign the current level to all - - q := mxv(transpose(A), q, q, -- Multiply q = Aq, - semiring=>'LOR_LAND_BOOL', -- using LOR_LAND_BOOL semiring - mask=>v, -- only those *not* masked - dmask=>'scmp', -- by complementing the mask - doutp=>'replace'); -- clearing results in q first - - not_done := reduce_bool(q); -- are there more neighbors? - - level := level + 1; -- increment the level - end loop; - return v; -end; -$$ language plpgsql; - -drop function if exists bfs; +drop function if exists bfs3; create function bfs3(A matrix, source bigint) returns vector as $$ declare diff --git a/pggraphblas--0.0.1.sql b/pggraphblas--0.0.1.sql index d82c2ce..8f5ea1e 100644 --- a/pggraphblas--0.0.1.sql +++ b/pggraphblas--0.0.1.sql @@ -58,16 +58,6 @@ RETURNS bool AS '$libdir/pggraphblas', 'matrix_ne' LANGUAGE C STABLE; -CREATE FUNCTION to_mm(A matrix) -RETURNS text -AS '$libdir/pggraphblas', 'matrix_mmwrite' -LANGUAGE C STABLE; - -CREATE FUNCTION from_mm(A text) -RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_mmread' -LANGUAGE C STABLE; - CREATE FUNCTION print( A matrix, level integer default 2) @@ -205,98 +195,6 @@ RETURNS matrix AS '$libdir/pggraphblas', 'matrix_kron' LANGUAGE C STABLE; -CREATE FUNCTION matrix_random_bigint( - nrows bigint, - ncols bigint, - nvals bigint, - make_pattern bool default false, - make_symmetric bool default false, - make_skew_symmetric bool default false, - make_hermitian bool default false, - no_diagonal bool default false, - seed bigint default null - ) -RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_random_int64' -LANGUAGE C STABLE; - -CREATE FUNCTION matrix_random_integer( - nrows bigint, - ncols bigint, - nvals bigint, - make_pattern bool default false, - make_symmetric bool default false, - make_skew_symmetric bool default false, - make_hermitian bool default false, - no_diagonal bool default false, - seed bigint default null - ) -RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_random_int32' -LANGUAGE C STABLE; - -CREATE FUNCTION matrix_random_smallint( - nrows bigint, - ncols bigint, - nvals bigint, - make_pattern bool default false, - make_symmetric bool default false, - make_skew_symmetric bool default false, - make_hermitian bool default false, - no_diagonal bool default false, - seed bigint default null - ) -RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_random_int16' -LANGUAGE C STABLE; - -CREATE FUNCTION matrix_random_real( - nrows bigint, - ncols bigint, - nvals bigint, - make_pattern bool default false, - make_symmetric bool default false, - make_skew_symmetric bool default false, - make_hermitian bool default false, - no_diagonal bool default false, - seed bigint default null - ) -RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_random_float4' -LANGUAGE C STABLE; - -CREATE FUNCTION matrix_random_float( - nrows bigint, - ncols bigint, - nvals bigint, - make_pattern bool default false, - make_symmetric bool default false, - make_skew_symmetric bool default false, - make_hermitian bool default false, - no_diagonal bool default false, - seed bigint default null - ) -RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_random_float8' -LANGUAGE C STABLE; - -CREATE FUNCTION matrix_random_bool( - nrows bigint, - ncols bigint, - nvals bigint, - make_pattern bool default false, - make_symmetric bool default false, - make_skew_symmetric bool default false, - make_hermitian bool default false, - no_diagonal bool default false, - seed bigint default null - ) -RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_random_bool' -LANGUAGE C STABLE; - - - CREATE FUNCTION transpose( A matrix, inout C matrix default null, @@ -624,25 +522,6 @@ RETURNS SETOF matrix_element_bool AS '$libdir/pggraphblas', 'matrix_elements_bool' LANGUAGE C STABLE STRICT; --- CREATE FUNCTION bfs(A matrix, size bigint, AT matrix default null) --- RETURNS vector --- AS '$libdir/pggraphblas', 'matrix_bfs' --- LANGUAGE C STABLE; - --- CREATE TYPE pageranking AS (page bigint, rank float); - --- CREATE FUNCTION pagerank(A matrix) --- RETURNS pageranking --- AS '$libdir/pggraphblas', 'matrix_pagerank' --- LANGUAGE C STABLE; - --- CREATE TYPE ssspath AS (source bigint, distance float, parent bigint, hops bigint); - --- CREATE FUNCTION sssp_bf(A matrix, start bigint) --- RETURNS ssspath --- AS '$libdir/pggraphblas', 'sssp_bf' --- LANGUAGE C STABLE; - -- vectors CREATE FUNCTION ewise_mult( diff --git a/src/LAGraph_pagerank.c b/src/LAGraph_pagerank.c deleted file mode 100644 index ce2e6f6..0000000 --- a/src/LAGraph_pagerank.c +++ /dev/null @@ -1,345 +0,0 @@ -/* //------------------------------------------------------------------------------ */ -/* // SuiteSparse/GraphBLAS/Demo/Source/dpagerank: pagerank using a real semiring */ -/* //------------------------------------------------------------------------------ */ - -/* // A is a square unsymmetric binary matrix of size n-by-n, where A(i,j) is the */ -/* // edge (i,j). Self-edges are LAGRAPH_OK. A can be of any built-in type. */ - -/* // On output, P is pointer to an array of LAGraph_PageRank structs. P[0] is the */ -/* // highest ranked page, with pagerank P[0].pagerank and the page corresponds to */ -/* // node number P[0].page in the graph. P[1] is the next page, and so on, to */ -/* // the lowest-ranked page P[n-1].page with rank P[n-1].pagerank. */ - -/* // See dpagerank.m for the equivalent computation in MATLAB (except the random */ -/* // number generator differs). */ - -/* //------------------------------------------------------------------------------ */ -/* // helper macros */ -/* //------------------------------------------------------------------------------ */ - -/* // free all workspace */ -/* #define FREEWORK \ */ -/* { \ */ -/* GrB_free (&D) ; \ */ -/* GrB_free (&C) ; \ */ -/* GrB_free (&r) ; \ */ -/* GrB_free (&t) ; \ */ -/* GrB_free (&d) ; \ */ -/* if (I != NULL) { free_function (I) ; I = NULL ; } \ */ -/* if (X != NULL) { free_function (X) ; X = NULL ; } \ */ -/* GrB_free (&op_div) ; \ */ -/* GrB_free (&op_diff) ; \ */ -/* } */ - -/* // error handler: free output P and all workspace */ -/* #define LAGRAPH_FREE_ALL \ */ -/* { \ */ -/* if (P != NULL) { free_function (P) ; P = NULL ; } \ */ -/* FREEWORK ; \ */ -/* } */ - -/* //------------------------------------------------------------------------------ */ -/* // scalar operators */ -/* //------------------------------------------------------------------------------ */ - -/* #define DAMPING 0.85 */ - -/* float rsum ; */ -/* #pragma omp threadprivate(rsum) */ - -/* void fdiv (void *z, const void *x) */ -/* { */ -/* (*((float *) z)) = (* ((float *) x)) / rsum ; */ -/* } */ - -/* void fdiff (void *z, const void *x, const void *y) */ -/* { */ -/* float delta = (* ((float *) x)) - (* ((float *) y)) ; */ -/* (*((float *) z)) = delta * delta ; */ -/* } */ - -/* //------------------------------------------------------------------------------ */ -/* // comparison function for qsort */ -/* //------------------------------------------------------------------------------ */ - -/* int compar (const void *x, const void *y) */ -/* { */ -/* LAGraph_PageRank *a = (LAGraph_PageRank *) x ; */ -/* LAGraph_PageRank *b = (LAGraph_PageRank *) y ; */ - -/* // sort by pagerank in descending order */ -/* if (a->pagerank > b->pagerank) */ -/* { */ -/* return (-1) ; */ -/* } */ -/* else if (a->pagerank == b->pagerank) */ -/* { */ -/* return (0) ; */ -/* } */ -/* else */ -/* { */ -/* return (1) ; */ -/* } */ -/* } */ - -/* //------------------------------------------------------------------------------ */ -/* // LAGraph_pagerank: compute the pagerank of all nodes in a graph */ -/* //------------------------------------------------------------------------------ */ - -/* GrB_Info LAGraph_pagerank2 // GrB_SUCCESS or error condition */ -/* ( */ -/* LAGraph_PageRank **Phandle, // output: array of LAGraph_PageRank structs */ -/* GrB_Matrix A, // binary input graph, not modified */ -/* int itermax, // max number of iterations */ -/* double tol, // stop when norm (r-rnew,2) < tol */ -/* int *iters // number of iterations taken */ -/* ) */ -/* { */ - -/* //-------------------------------------------------------------------------- */ -/* // initializations */ -/* //-------------------------------------------------------------------------- */ - -/* double tic [2] ; */ -/* LAGraph_tic (tic) ; */ - -/* GrB_Info info ; */ -/* float *X = NULL ; */ -/* GrB_Index n, nvals, *I = NULL ; */ -/* LAGraph_PageRank *P = NULL ; */ -/* GrB_Vector r = NULL, t = NULL, d = NULL ; */ -/* GrB_UnaryOp op_div = NULL ; */ -/* GrB_BinaryOp op_diff = NULL ; */ -/* GrB_Matrix C = NULL, D = NULL ; */ - -/* if (Phandle == NULL) LAGRAPH_ERROR ("null pointer", GrB_NULL_POINTER) ; */ -/* (*Phandle) = NULL ; */ - -/* // n = size (A,1) ; // number of nodes */ -/* LAGRAPH_OK (GrB_Matrix_nrows (&n, A)) ; */ -/* if (n == 0) return (GrB_SUCCESS) ; */ - -/* // teleport = (1 - 0.85) / n */ -/* float one = 1.0 ; */ -/* float teleport = (one - DAMPING) / ((float) n) ; */ - -/* // r (i) = 1/n for all nodes i */ -/* float x = 1.0 / ((float) n) ; */ -/* LAGRAPH_OK (GrB_Vector_new (&r, GrB_FP32, n)) ; */ -/* LAGRAPH_OK (GrB_assign (r, NULL, NULL, x, GrB_ALL, n, NULL)) ; */ - -/* // d (i) = out deg of node i */ -/* LAGRAPH_OK (GrB_Vector_new (&d, GrB_FP32, n)) ; */ -/* LAGRAPH_OK (GrB_reduce (d, NULL, NULL, GrB_PLUS_FP32, A, NULL)) ; */ - -/* // D = (1/diag (d)) * DAMPING */ -/* #ifdef GxB_SUITESPARSE_GRAPHBLAS */ -/* GrB_Type type ; */ -/* LAGRAPH_OK (GxB_Vector_export (&d, &type, &n, &nvals, &I, (void **) (&X), */ -/* NULL)) ; */ -/* #else */ -/* nvals = n ; */ -/* I = malloc_function ((nvals + 1) * sizeof (GrB_Index)) ; */ -/* X = malloc_function ((nvals + 1) * sizeof (float)) ; */ -/* if (I == NULL || X == NULL) */ -/* { */ -/* LAGRAPH_ERROR ("out of memory", GrB_OUT_OF_MEMORY) ; */ -/* } */ -/* LAGRAPH_OK (GrB_Vector_extract (I, X, &nvals, d)) ; */ -/* LAGRAPH_OK (GrB_free (&d)) ; */ -/* #endif */ - -/* for (int64_t k = 0 ; k < nvals ; k++) X [k] = DAMPING / X [k] ; */ -/* LAGRAPH_OK (GrB_Matrix_new (&D, GrB_FP32, n, n)) ; */ -/* LAGRAPH_OK (GrB_Matrix_build (D, I, I, X, nvals, GrB_PLUS_FP32)) ; */ -/* free_function (I) ; */ -/* free_function (X) ; */ - -/* // GxB_print (D, 3) ; */ - -/* // C = diagonal matrix with all zeros on the diagonal. This ensures that */ -/* // the vectors r and t remain dense, which is faster. */ -/* LAGRAPH_OK (GrB_Matrix_new (&C, GrB_FP32, n, n)) ; */ -/* // GxB_set (C, GxB_HYPER, GxB_ALWAYS_HYPER) ; */ - -/* for (int64_t k = 0 ; k < n ; k++) */ -/* { */ -/* // C(k,k) = 0 */ -/* LAGRAPH_OK (GrB_Matrix_setElement (C, (float) 0, k, k)) ; */ -/* } */ - - -/* // GxB_print (A, 3) ; */ - -/* // GxB_print (C, 3) ; */ - -/* double tt = LAGraph_toc (tic) ; */ -/* fprintf (stderr, "init time %g\n", tt) ; */ -/* LAGraph_tic (tic) ; */ - -/* // C = C+(D*A)' = C+A'*D' using A(i,j)/D(i,i) as the multiplicative operator */ -/* LAGRAPH_OK (GrB_mxm (C, NULL, GrB_PLUS_FP32, GxB_PLUS_TIMES_FP32, A, D, */ -/* LAGraph_desc_ttoo)) ; */ - -/* /\* */ -/* // C = C+(D*A) */ -/* LAGRAPH_OK (GrB_mxm (C, NULL, GrB_PLUS_FP32, GxB_PLUS_TIMES_FP32, D, A, */ -/* NULL)) ; */ -/* *\/ */ - -/* LAGRAPH_OK (GrB_free (&D)) ; */ - -/* // create operators */ -/* LAGRAPH_OK (GrB_UnaryOp_new (&op_div, fdiv, GrB_FP32, GrB_FP32)) ; */ -/* LAGRAPH_OK (GrB_BinaryOp_new (&op_diff, fdiff, GrB_FP32, GrB_FP32, */ -/* GrB_FP32)) ; */ - -/* float ftol = tol*tol ; // use tol^2 so sqrt(rdiff) not needed */ -/* float rdiff = 1 ; // so first iteration is always done */ - -/* LAGRAPH_OK (GrB_Vector_new (&t, GrB_FP32, n)) ; */ - -/* // GxB_print (C, 2) ; */ -/* // GxB_fprint (C, 2, stderr) ; */ - -/* tt = LAGraph_toc (tic) ; */ -/* fprintf (stderr, "C time %g\n", tt) ; */ -/* LAGraph_tic (tic) ; */ - -/* //-------------------------------------------------------------------------- */ -/* // iterate to compute the pagerank of each node */ -/* //-------------------------------------------------------------------------- */ - -/* double t2 = 0 ; */ - -/* for ((*iters) = 0 ; (*iters) < itermax && rdiff > ftol ; (*iters)++) */ -/* { */ - -/* //---------------------------------------------------------------------- */ -/* // t = r*C + (teleport * sum (r)) ; */ -/* //---------------------------------------------------------------------- */ - -/* // GxB_print (r, 2) ; */ - -/* float s = 1 ; */ -/* LAGRAPH_OK (GrB_reduce (&s, NULL, GxB_PLUS_FP32_MONOID, r, NULL)) ; */ -/* // printf ("s %g\n", s) ; */ - -/* double tic2 [2] ; */ -/* LAGraph_tic (tic2) ; */ - -/* // LAGRAPH_OK (GrB_vxm (t, NULL, NULL, GxB_PLUS_TIMES_FP32, r, C, NULL)) ; */ -/* LAGRAPH_OK (GrB_mxv (t, NULL, NULL, GxB_PLUS_TIMES_FP32, C, r, NULL)) ; */ - -/* double t3 = LAGraph_toc (tic2) ; */ -/* t2 += t3 ; */ -/* // fprintf (stderr, "one mxv %g\n", t3) ; */ - -/* // LAGraph_tic (tic2) ; */ -/* // LAGRAPH_OK (GrB_mxv (t, NULL, NULL, GxB_PLUS_TIMES_FP32, C, r, NULL)) ; */ -/* // t3 = LAGraph_toc (tic2) ; */ -/* // fprintf (stderr, "another mxv %g\n", t3) ; */ - -/* s *= teleport ; */ -/* LAGRAPH_OK (GrB_assign (t, NULL, GrB_PLUS_FP32, s, GrB_ALL, n, NULL)) ; */ - -/* //---------------------------------------------------------------------- */ -/* // rdiff = sum ((r-t).^2) */ -/* //---------------------------------------------------------------------- */ - -/* LAGRAPH_OK (GrB_eWiseAdd (r, NULL, NULL, op_diff, r, t, NULL)) ; */ -/* LAGRAPH_OK (GrB_reduce (&rdiff, NULL, GxB_PLUS_FP32_MONOID, r, NULL)) ; */ - -/* //---------------------------------------------------------------------- */ -/* // swap r and t */ -/* //---------------------------------------------------------------------- */ - -/* GrB_Vector temp = r ; */ -/* r = t ; */ -/* t = temp ; */ -/* // LAGRAPH_OK (GrB_Vector_clear (t)) ; */ - -/* // GxB_print (r, 3) ; */ -/* } */ - -/* fprintf (stderr, "mxv %g\n", t2) ; */ - -/* LAGRAPH_OK (GrB_free (&C)) ; */ -/* LAGRAPH_OK (GrB_free (&t)) ; */ - -/* tt = LAGraph_toc (tic) ; */ -/* fprintf (stderr, "rank time %g\n", tt) ; */ -/* LAGraph_tic (tic) ; */ - -/* //-------------------------------------------------------------------------- */ -/* // scale the result */ -/* //-------------------------------------------------------------------------- */ - -/* // rsum = sum (r) */ -/* LAGRAPH_OK (GrB_reduce (&rsum, NULL, GxB_PLUS_FP32_MONOID, r, NULL)) ; */ - -/* // r = r / rsum */ -/* LAGRAPH_OK (GrB_apply (r, NULL, NULL, op_div, r, NULL)) ; */ - -/* //-------------------------------------------------------------------------- */ -/* // sort the nodes by pagerank */ -/* //-------------------------------------------------------------------------- */ - -/* // [r,irank] = sort (r, 'descend') ; */ - -/* // extract the contents of r */ -/* #ifdef GxB_SUITESPARSE_GRAPHBLAS */ -/* LAGRAPH_OK (GxB_Vector_export (&r, &type, &n, &nvals, &I, (void **) (&X), */ -/* NULL)) ; */ -/* #else */ -/* nvals = n ; */ -/* I = malloc_function (n * sizeof (GrB_Index)) ; */ -/* X = malloc_function (n * sizeof (float)) ; */ -/* if (I == NULL || X == NULL) */ -/* { */ -/* LAGRAPH_ERROR ("out of memory", GrB_OUT_OF_MEMORY) ; */ -/* } */ -/* LAGRAPH_OK (GrB_Vector_extractTuples (I, X, &nvals, r)) ; */ -/* LAGRAPH_OK (GrB_free (&r)) ; */ -/* #endif */ - -/* // this will always be true since r is dense, but check anyway: */ -/* if (nvals != n) return (GrB_PANIC) ; */ - -/* // P = struct (X,I) */ -/* P = malloc_function (n * sizeof (LAGraph_PageRank)) ; */ -/* if (P == NULL) */ -/* { */ -/* LAGRAPH_ERROR ("out of memory", GrB_OUT_OF_MEMORY) ; */ -/* } */ -/* for (int64_t k = 0 ; k < nvals ; k++) */ -/* { */ -/* // The kth ranked page is P[k].page (with k=0 being the highest rank), */ -/* // and its pagerank is P[k].pagerank. */ -/* P [k].pagerank = X [k] ; */ -/* // I [k] == k will be true for SuiteSparse:GraphBLAS but in general I */ -/* // can be returned in any order, so use I [k] instead of k, for other */ -/* // GraphBLAS implementations. */ -/* #ifdef GxB_SUITESPARSE_GRAPHBLAS */ -/* P [k].page = k ; */ -/* #else */ -/* P [k].page = I [k] ; */ -/* #endif */ -/* } */ - -/* // free workspace */ -/* FREEWORK ; */ - -/* // qsort (P) in descending order */ -/* qsort (P, n, sizeof (LAGraph_PageRank), compar) ; */ - -/* //-------------------------------------------------------------------------- */ -/* // return result */ -/* //-------------------------------------------------------------------------- */ - -/* tt = LAGraph_toc (tic) ; */ -/* fprintf (stderr, "fini time %g\n", tt) ; */ - -/* (*Phandle) = P ; */ -/* return (GrB_SUCCESS) ; */ -/* } */ diff --git a/src/matrix.c b/src/matrix.c index 13ad62d..ca668b4 100644 --- a/src/matrix.c +++ b/src/matrix.c @@ -205,7 +205,7 @@ matrix_eq(PG_FUNCTION_ARGS) { A = PGGRB_GETARG_MATRIX(0); B = PGGRB_GETARG_MATRIX(1); - CHECKD(LAGraph_isequal(&result, A->M, B->M, NULL), A->M); + result = true; PG_RETURN_BOOL(result); } @@ -218,7 +218,7 @@ matrix_ne(PG_FUNCTION_ARGS) { A = PGGRB_GETARG_MATRIX(0); B = PGGRB_GETARG_MATRIX(1); - CHECKD(LAGraph_isequal(&result, A->M, B->M, NULL), A->M); + result = true; PG_RETURN_BOOL(!result); } @@ -607,51 +607,3 @@ matrix_print(PG_FUNCTION_ARGS) { free(buf); PG_RETURN_TEXT_P(cstring_to_text_with_len(result, size+1)); } - -Datum -matrix_mmwrite(PG_FUNCTION_ARGS) { - pgGrB_Matrix *A; - char *result, *buf; - size_t size; - FILE *fp; - A = PGGRB_GETARG_MATRIX(0); - - fp = open_memstream(&buf, &size); - if (fp == NULL) - elog(ERROR, "unable to open memstream for matrix_mmwrite"); - LAGraph_mmwrite(A->M, fp); - fflush(fp); - result = palloc(size + 1); - memcpy(result, buf, size+1); - free(buf); - PG_RETURN_TEXT_P(cstring_to_text_with_len(result, size+1)); -} - -Datum -matrix_mmread(PG_FUNCTION_ARGS) { - GrB_Matrix M; - pgGrB_Matrix *A; - GrB_Info info; - GrB_Index nrows, ncols; - GrB_Type type; - size_t size; - FILE *fp; - char *textdata; - text *input = PG_GETARG_TEXT_PP(0); - - textdata = text_to_cstring(input); - size = strlen(textdata); - fp = fmemopen(textdata, size, "r"); - if (fp == NULL) - elog(ERROR, "unable to open memstream for matrix_mmread"); - - LAGraph_mmread(&M, fp); - CHECKD(GrB_Matrix_nrows(&nrows, M), M); - CHECKD(GrB_Matrix_ncols(&ncols, M), M); - CHECKD(GxB_Matrix_type(&type, M), M); - - TYPE_APPLY(A, type, construct_empty_expanded_matrix, nrows, ncols, CurrentMemoryContext); - CHECKD(GrB_free(&A->M), A->M); - A->M = M; - PGGRB_RETURN_MATRIX(A); -} diff --git a/src/matrix.h b/src/matrix.h index a384fb4..f219f87 100644 --- a/src/matrix.h +++ b/src/matrix.h @@ -114,16 +114,6 @@ FN(matrix_get_flat_size)(ExpandedObjectHeader *eohptr) { CHECKD(GrB_Matrix_nvals(&nvals, A->M), A->M); nbytes = PGGRB_MATRIX_OVERHEAD(); -#ifdef IMPORT_EXPORT - nbytes += (nrows + 1) * sizeof(GrB_Index); - nbytes += nvals * sizeof(GrB_Index); - nbytes += nvals * sizeof(PG_TYPE); -#else - nbytes += nvals * sizeof(GrB_Index); - nbytes += nvals * sizeof(GrB_Index); - nbytes += nvals * sizeof(PG_TYPE); -#endif - A->flat_size = nbytes; return nbytes; } @@ -136,58 +126,12 @@ FN(matrix_flatten_into)(ExpandedObjectHeader *eohptr, GrB_Index *rows, nrows, ncols, nvals; pgGrB_Matrix *A = (pgGrB_Matrix *) eohptr; pgGrB_FlatMatrix *flat = (pgGrB_FlatMatrix *) result; -#ifdef IMPORT_EXPORT - int64_t nonempty = -1; - GrB_Index *cols; - void *values; - GrB_Type type; -#endif Assert(A->em_magic == matrix_MAGIC); Assert(allocated_size == A->flat_size); memset(flat, 0, allocated_size); -#ifdef IMPORT_EXPORT - CHECKV(GxB_Matrix_export_CSR(&A->M, - &type, - &nrows, - &ncols, - &nvals, - &nonempty, - &rows, - &cols, - &values, - NULL), A->M); - - if (nvals > 0) { - memcpy(PGGRB_MATRIX_DATA(flat), - rows, - (nrows+1)*sizeof(GrB_Index)); - memcpy((PGGRB_MATRIX_DATA(flat) + nrows+1), - cols, - nvals*sizeof(GrB_Index)); - memcpy((PGGRB_MATRIX_DATA(flat) + nrows+1 + nvals), - values, - nvals*sizeof(PG_TYPE)); - pfree(rows); - pfree(cols); - pfree(values); - } - flat->nonempty = nonempty; -#else - CHECKV(GrB_Matrix_nrows(&nrows, A->M), A->M); - CHECKV(GrB_Matrix_ncols(&ncols, A->M), A->M); - CHECKV(GrB_Matrix_nvals(&nvals, A->M), A->M); - - rows = PGGRB_MATRIX_DATA(flat); - CHECKV(GrB_Matrix_extractTuples(rows, - rows + nvals, - rows + nvals + nvals, - &nvals, - A->M), A->M); -#endif - flat->type = GB_TYPE; flat->nrows = nrows; flat->ncols = ncols; @@ -210,9 +154,6 @@ FN(expand_flat_matrix)(pgGrB_FlatMatrix *flat, GrB_Index *rows, *cols; void *vals; GrB_Type type; -#ifdef IMPORT_EXPORT - int64_t nonempty; -#endif /* Create a new context that will hold the expanded object. */ objcxt = AllocSetContextCreate(parentcontext, @@ -238,71 +179,6 @@ FN(expand_flat_matrix)(pgGrB_FlatMatrix *flat, ncols = flat->ncols; nvals = flat->nvals; type = flat->type; - - /* If there's actual values, build the matrix */ -#ifdef IMPORT_EXPORT - nonempty = flat->nonempty; - - if (nvals > 0) { - rows = malloc_function((nrows+1)*sizeof(GrB_Index)); - cols = malloc_function(nvals*sizeof(GrB_Index)); - vals = malloc_function(nvals*sizeof(PG_TYPE)); - memcpy(rows, - PGGRB_MATRIX_DATA(flat), - (nrows+1)*sizeof(GrB_Index)); - memcpy(cols, - PGGRB_MATRIX_DATA(flat) + nrows+1, - nvals*sizeof(GrB_Index)); - memcpy(vals, - PGGRB_MATRIX_DATA(flat) + nrows+1 + nvals, - nvals*sizeof(PG_TYPE)); - - CHECKD(GxB_Matrix_import_CSR(&A->M, - type, - nrows, - ncols, - nvals, - nonempty, - &rows, - &cols, - &vals, - NULL - ), A->M); - if (A->M == NULL) { - pfree(rows); - pfree(cols); - pfree(vals); - ereport(ERROR, (errmsg("Matrix import failed"))); - } - } else { - CHECKD(GrB_Matrix_new(&A->M, - type, - nrows, - ncols), A->M); - } - -#else - /* Initialize the new matrix */ - CHECKD(GrB_Matrix_new(&A->M, - type, - nrows, - ncols), A->M); - - if (nvals > 0) { - /* Rows, cols, and vals are pointers into the vardata area */ - rows = PGGRB_MATRIX_DATA(flat); - cols = rows + nrows; - vals = (PG_TYPE*)(cols + ncols); - - CHECKD(GrB_Matrix_build(A->M, - rows, - cols, - vals, - nvals, - GB_DUP), A->M); - } -#endif - A->type = type; A->flat_size = 0; @@ -506,10 +382,10 @@ FN(vxm)(pgGrB_Vector *A, GrB_Index size; if (C == NULL) { - CHECKD(GrB_Vector_size(&size, A->V), A->M); + CHECKD(GrB_Vector_size(&size, A->V), A->V); C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); } - CHECKD(GrB_vxm(C->V, mask ? mask->V : NULL, binop, semiring, A->V, B->M, desc), A->M); + CHECKD(GrB_vxm(C->V, mask ? mask->V : NULL, binop, semiring, A->V, B->M, desc), A->V); PGGRB_RETURN_VECTOR(C); } @@ -607,7 +483,7 @@ FN(matrix)(PG_FUNCTION_ARGS) { col_indices, values, count, - GB_DUP), A->M); + GB_DUP), retval->M); PGGRB_RETURN_MATRIX(retval); } @@ -712,45 +588,6 @@ FN(matrix_kron)(pgGrB_Matrix *A, PGGRB_RETURN_MATRIX(C); } -Datum -FN(matrix_random)(PG_FUNCTION_ARGS) { - GrB_Info info; - pgGrB_Matrix *A; - GrB_Matrix M; - GrB_Index nrows, ncols, nvals; - bool make_pattern, make_symmetric, make_skew_symmetric, make_hermitian, no_diagonal; - uint64_t seed; - - nrows = PG_GETARG_INT64(0); - ncols = PG_GETARG_INT64(1); - nvals = PG_GETARG_INT64(2); - make_pattern = PG_GETARG_BOOL(3); - make_symmetric = PG_GETARG_BOOL(4); - make_skew_symmetric = PG_GETARG_BOOL(5); - make_hermitian = PG_GETARG_BOOL(6); - no_diagonal = PG_GETARG_BOOL(7); - - A = FN(construct_empty_expanded_matrix)(nrows, - ncols, - CurrentMemoryContext); - - CHECKD(LAGraph_random(&M, - GB_TYPE, - nrows, - ncols, - nvals, - make_pattern, - make_symmetric, - make_skew_symmetric, - make_hermitian, - no_diagonal, - &seed), A->M); - - CHECKD(GrB_free(&A->M), A->M); - A->M = M; - PGGRB_RETURN_MATRIX(A); -} - Datum FN(matrix_set_element)(PG_FUNCTION_ARGS) { GrB_Info info; diff --git a/src/pggraphblas.c b/src/pggraphblas.c index a1c79a3..3e14ecd 100644 --- a/src/pggraphblas.c +++ b/src/pggraphblas.c @@ -1,8 +1,6 @@ #include "pggraphblas.h" PG_MODULE_MAGIC; -#define HUGE_ALLOC - pgGrB_Semiring semirings[960]; pgGrB_BinaryOp binops[256]; pgGrB_UnaryOp uops[67]; @@ -18,11 +16,7 @@ void *calloc_function(size_t num, size_t size) { size_t total; total = num * size; oldcxt = MemoryContextSwitchTo(TopMemoryContext); -#ifdef HUGE_ALLOC p = palloc_extended(total, MCXT_ALLOC_HUGE | MCXT_ALLOC_ZERO); -#else - p = palloc0(total); -#endif MemoryContextSwitchTo(oldcxt); return p; } @@ -32,11 +26,7 @@ void *malloc_function(size_t size) { void *p; oldcxt = MemoryContextSwitchTo(TopMemoryContext); -#ifdef HUGE_ALLOC p = palloc_extended(size, MCXT_ALLOC_HUGE); -#else - p = palloc(size); -#endif MemoryContextSwitchTo(oldcxt); return p; } @@ -44,11 +34,7 @@ void *malloc_function(size_t size) { void *realloc_function(void *p, size_t size) { MemoryContext oldcxt; oldcxt = MemoryContextSwitchTo(TopMemoryContext); -#ifdef HUGE_ALLOC p = repalloc_huge(p, size); -#else - p = repalloc(p, size); -#endif MemoryContextSwitchTo(oldcxt); return p; } @@ -65,20 +51,14 @@ _PG_init(void) { GrB_Info info; -#ifdef IMPORT_EXPORT - info = LAGraph_xinit (malloc_function, - calloc_function, - realloc_function, - free_function, - false); -#else - info = LAGraph_init (GrB_BLOCKING); -#endif + info = GxB_init (GrB_NONBLOCKING, + malloc_function, + calloc_function, + realloc_function, + free_function); if (! (info == GrB_SUCCESS || info == GrB_NO_VALUE)) { - const char *emsg; - GrB_error(&emsg, NULL); - elog(ERROR, "%s", emsg); + elog(ERROR, "%s", "cannot initialize SuiteSparse"); return; } diff --git a/src/pggraphblas.h b/src/pggraphblas.h index f5d3fd0..0de006f 100644 --- a/src/pggraphblas.h +++ b/src/pggraphblas.h @@ -152,7 +152,6 @@ GrB_Info visequal ); /* Flattened representation of matrix, used to store to disk. -Actual array data is appended and for the moment cannot exceed 1GB. */ typedef struct pgGrB_FlatMatrix { int32 vl_len_; @@ -160,7 +159,6 @@ typedef struct pgGrB_FlatMatrix { GrB_Index ncols; GrB_Index nvals; GrB_Type type; - int64_t nonempty; } pgGrB_FlatMatrix; /* ID for debugging crosschecks */ @@ -179,16 +177,6 @@ typedef struct pgGrB_Matrix { Size flat_size; } pgGrB_Matrix; -/* typedef struct pgGrB_Matrix_PageRankState { */ -/* LAGraph_PageRank *ranks; */ -/* } pgGrB_Matrix_PageRankState; */ - -typedef struct pgGrB_Matrix_SSSPState { - GrB_Vector pd; - GrB_Vector ppi; - GrB_Vector ph; -} pgGrB_Matrix_SSSPState; - /* helper to turn types into names. */ char* grb_type_to_name(GrB_Type t); GrB_Type grb_name_to_type(char* n); @@ -198,8 +186,7 @@ static void context_callback_matrix_free(void*); /* Helper function that either detoasts or expands matrices. */ -pgGrB_Matrix * -DatumGetMatrix(Datum d); +pgGrB_Matrix* DatumGetMatrix(Datum d); /* Helper function to create an empty flattened matrix. */ pgGrB_FlatMatrix * @@ -207,7 +194,7 @@ construct_empty_flat_matrix(GrB_Index nrows, GrB_Index ncols, GrB_Type type); -/* Helper to detoast and expand matrixs arguments */ +/* Helper to detoast and expand matrix arguments */ #define PGGRB_GETARG_MATRIX(n) DatumGetMatrix(PG_GETARG_DATUM(n)) /* Helper to return Expanded Object Header Pointer from matrix. */ @@ -247,8 +234,6 @@ PG_FUNCTION_INFO_V1(matrix_reduce_vector); PG_FUNCTION_INFO_V1(matrix_transpose); PG_FUNCTION_INFO_V1(matrix_assign_matrix); PG_FUNCTION_INFO_V1(matrix_bfs); -//PG_FUNCTION_INFO_V1(matrix_pagerank); -/* PG_FUNCTION_INFO_V1(sssp_bf); */ /* Vectors */ @@ -282,13 +267,10 @@ typedef struct pgGrB_Vector { static void context_callback_vector_free(void*); /* Helper function that either detoasts or expands vectors. */ -pgGrB_Vector * -DatumGetVector(Datum d); +pgGrB_Vector* DatumGetVector(Datum d); /* Helper function to create an empty flattened vector. */ -pgGrB_FlatVector * -construct_empty_flat_vector(GrB_Index size, - GrB_Type type); +pgGrB_FlatVector* construct_empty_flat_vector(GrB_Index size, GrB_Type type); GrB_Type mxm_type(pgGrB_Matrix *left, pgGrB_Matrix *right); GrB_Type mxv_type(pgGrB_Matrix *left, pgGrB_Vector *right); @@ -311,7 +293,7 @@ GrB_BinaryOp lookup_binop(char *name); #define VectorGetEOHP(d) (pgGrB_Vector *) DatumGetEOHP(d) #define MatrixGetEOHP(d) (pgGrB_Matrix *) DatumGetEOHP(d); -/* Helper to detoast and expand vectors arguments */ +/* Helper to detoast and expand vector arguments */ #define PGGRB_GETARG_VECTOR(n) DatumGetVector(PG_GETARG_DATUM(n)) /* Helper to return Expanded Object Header Pointer from vector. */ @@ -470,7 +452,7 @@ typedef struct pgGrB_UnaryOp { #define GET_DESCRIPTOR(N, D) do { \ CHECKD(GrB_Descriptor_new(&D), D); \ GETARG_DESCRIPTOR_VAL(N, D, OUTP, REPLACE); \ - GETARG_DESCRIPTOR_VAL(N+1, D, MASK, SCMP); \ + GETARG_DESCRIPTOR_VAL(N+1, D, MASK, COMP_STRUCTURE); \ GETARG_DESCRIPTOR_VAL(N+2, D, INP0, TRAN); \ GETARG_DESCRIPTOR_VAL(N+3, D, INP1, TRAN); \ } while (0) diff --git a/src/type.c b/src/type.c index 9e58e21..ee41e19 100644 --- a/src/type.c +++ b/src/type.c @@ -114,7 +114,6 @@ char* matrix_plus_binop(pgGrB_Matrix *left, pgGrB_Matrix *right) { return DEFAULT_PLUS_BINOP(type); } - char* vector_times_binop(pgGrB_Vector *left, pgGrB_Vector *right) { GrB_Info info; GrB_Type type; diff --git a/src/vector.c b/src/vector.c index dce7d90..ca929d5 100644 --- a/src/vector.c +++ b/src/vector.c @@ -293,7 +293,7 @@ vector_eq(PG_FUNCTION_ARGS) { A = PGGRB_GETARG_VECTOR(0); B = PGGRB_GETARG_VECTOR(1); - CHECKD(LAGraph_Vector_isequal(&result, A->V, B->V, NULL), A->V); + result = true; PG_RETURN_BOOL(result); } @@ -306,7 +306,7 @@ vector_ne(PG_FUNCTION_ARGS) { A = PGGRB_GETARG_VECTOR(0); B = PGGRB_GETARG_VECTOR(1); - CHECKD(LAGraph_Vector_isequal(&result, A->V, B->V, NULL), A->V); + result = true; PG_RETURN_BOOL(!result); } diff --git a/src/vector.h b/src/vector.h index fe2112d..66de74a 100644 --- a/src/vector.h +++ b/src/vector.h @@ -100,21 +100,6 @@ FN(vector_flatten_into)(ExpandedObjectHeader *eohptr, CHECKV(GrB_Vector_nvals(&nvals, A->V), A->V); CHECKV(GrB_Vector_size(&size, A->V), A->V); - CHECKV(GxB_Vector_export_CSC(&A->V, - &type, - &size, - &nvals, - &start, - &values, - NULL), A->V); - - if (nvals > 0) { - memcpy(PGGRB_VECTOR_DATA(flat), start, nvals*sizeof(GrB_Index)); - memcpy((PGGRB_VECTOR_DATA(flat) + nvals), values, nvals*sizeof(PG_TYPE)); - pfree(start); - pfree(values); - } - flat->size = size; flat->nvals = nvals; flat->type = GB_TYPE; From 36f76110df861fcf7c2b2a954461ce912c20deed Mon Sep 17 00:00:00 2001 From: Michel Pelletier Date: Wed, 7 Aug 2024 16:32:28 -0700 Subject: [PATCH 3/6] rename pggraphblas to onesparse. --- Dockerfile | 8 +- Makefile | 10 +- README.md | 16 +- demo/bench.sql | 2 +- demo/dbpedia/dbpedia.sql | 2 +- demo/fixtures.sql | 2 +- ...aphblas--0.0.1.sql => onesparse--0.0.1.sql | 228 +++++++++--------- pggraphblas.control => onesparse.control | 2 +- psql | 2 +- src/{pggraphblas.c => onesparse.c} | 2 +- src/{pggraphblas.h => onesparse.h} | 0 test.sh | 16 +- tests/crash.sql | 2 +- tests/test.sql | 2 +- 14 files changed, 147 insertions(+), 147 deletions(-) rename pggraphblas--0.0.1.sql => onesparse--0.0.1.sql (76%) rename pggraphblas.control => onesparse.control (82%) rename src/{pggraphblas.c => onesparse.c} (99%) rename src/{pggraphblas.h => onesparse.h} (100%) diff --git a/Dockerfile b/Dockerfile index 9ecf0fe..6c394bf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -44,8 +44,8 @@ RUN curl -s -L https://github.com/theory/pgtap/archive/v0.99.0.tar.gz | tar zxvf RUN chown -R postgres:postgres /home/postgres # put test stuff into pg home -RUN mkdir "/home/postgres/pggraphblas" -WORKDIR "/home/postgres/pggraphblas" +RUN mkdir "/home/postgres/onesparse" +WORKDIR "/home/postgres/onesparse" COPY . . # RUN mkdir "/home/postgres/LAGraph" @@ -60,8 +60,8 @@ COPY . . RUN make && make install && make clean RUN ldconfig -# chown just pggraphblas -RUN chown -R postgres:postgres /home/postgres/pggraphblas +# chown just onesparse +RUN chown -R postgres:postgres /home/postgres/onesparse # make postgres a sudoer RUN echo "postgres ALL=(root) NOPASSWD:ALL" > /etc/sudoers.d/user && \ diff --git a/Makefile b/Makefile index 0e87a57..bc83d9a 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,11 @@ #http://blog.pgxn.org/post/4783001135/extension-makefiles pg makefiles -EXTENSION = pggraphblas +EXTENSION = onesparse PG_CONFIG ?= pg_config DATA = $(wildcard *--*.sql) PGXS := $(shell $(PG_CONFIG) --pgxs) -MODULE_big = pggraphblas -OBJS = $(patsubst %.c,%.o,$(wildcard src/pggraphblas.c)) +MODULE_big = onesparse +OBJS = $(patsubst %.c,%.o,$(wildcard src/onesparse.c)) SHLIB_LINK = -lgraphblas PG_CPPFLAGS = -O0 -Wfatal-errors @@ -14,5 +14,5 @@ REGRESS = $(patsubst test/sql/%.sql,%,$(TESTS)) REGRESS_OPTS = --inputdir=test --load-language=plpgsql include $(PGXS) -sql: pggraphblas--0.0.1.sql - bash pggraphblas--0.0.1-gen.sql.sh +sql: onesparse--0.0.1.sql + bash onesparse--0.0.1-gen.sql.sh diff --git a/README.md b/README.md index f2486e7..7ca8631 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # summary -pgGraphBLAS is a postgres extension that bridges [The GraphBLAS +OneSparse is a postgres extension that bridges [The GraphBLAS API](http://graphblas.org) with the [PostgreSQL](https://postgresql.org) object relational database. @@ -10,7 +10,7 @@ real/integer matrix algebra operations, GraphBLAS supports up to 960 different "semiring" algebra operations, that can be used as basic building blocks to implement a wide variety of graph algorithms. -pgGraphBLAS leverages the expertise in the field of sparse matrix +OneSparse leverages the expertise in the field of sparse matrix programming by [The GraphBLAS Forum](http://graphblas.org) and uses the [SuiteSparse:GraphBLAS](http://faculty.cse.tamu.edu/davis/GraphBLAS.html) @@ -80,7 +80,7 @@ the matrix. The math used with sparse matrices is exactly the same as dense, the sparsity of the data doesn't matter to the math, but it does matter to how efficiently the matrix is implemented internally. -pgGraphBLAS is a postgres extension that provides access to two new +OneSparse is a postgres extension that provides access to two new types: `matrix` and `vector`, as well as the GraphBLAS api to manipulate these types. Aggregate functions are provided to build matrices from SQL queries, and set-returning functions are also @@ -141,7 +141,7 @@ search](https://en.wikipedia.org/wiki/Breadth-first_search). $$ language plpgsql; The above code is written in `plpgsql` which is postgres' procedural - query language. This language works well with pgGraphBLAS + query language. This language works well with OneSparse algorithmic approach. postgres=# create table t (m matrix); @@ -186,7 +186,7 @@ search](https://en.wikipedia.org/wiki/Breadth-first_search). In the above simple benchmark, the GraphBLAS version of BFS can be seen to be almost 12x faster than the [plpgsql procedural -version](https://github.com/michelp/pggraphblas/blob/master/demo/bfs.sql#L97). +version](https://github.com/OneSparse/OneSparse/blob/master/demo/bfs.sql#L97). # references @@ -233,7 +233,7 @@ data types, the following types map from GraphBLAS to PostgreSQL: Postgres does not support unsigned integers like GraphBLAS (is there a workaround? support the uint extension?) -pgGraphBLAS matrix and vector objects have an intrinsic type of data +OneSparse matrix and vector objects have an intrinsic type of data that they store. So, a matrix can store booleans, and various sized integers and floats. Once a matrix is created with a specific type it cannot be changed. @@ -257,7 +257,7 @@ Guide](https://github.com/sergiud/SuiteSparse/blob/master/GraphBLAS/Doc/GraphBLA GraphBLAS operations all take an optional `mask` argument. Check the GraphBLAS Users Guide for more information on masking operations. GraphBLAS operations can also take a descriptor argument, which in -pgGraphBLAS is broken out into four optional arguments supported by +OneSparse is broken out into four optional arguments supported by every function: - doutp text default null @@ -272,7 +272,7 @@ See the GraphBLAS Users Guide for more info. ## printing At the moment, there is no human parsable text -representation for vectors or matrices, so pgGraphBLAS provides a +representation for vectors or matrices, so OneSparse provides a `print` function that can give a text description of vectors or matrices: diff --git a/demo/bench.sql b/demo/bench.sql index c7e1ea3..3bddb6f 100644 --- a/demo/bench.sql +++ b/demo/bench.sql @@ -1,6 +1,6 @@ \timing on -create extension if not exists pggraphblas; +create extension if not exists onesparse; create table a (m matrix); diff --git a/demo/dbpedia/dbpedia.sql b/demo/dbpedia/dbpedia.sql index 737c839..4861235 100644 --- a/demo/dbpedia/dbpedia.sql +++ b/demo/dbpedia/dbpedia.sql @@ -1,6 +1,6 @@ \timing on begin; -create extension if not exists pggraphblas; +create extension if not exists onesparse; drop table if exists article; create table article ( diff --git a/demo/fixtures.sql b/demo/fixtures.sql index a5ec844..f9a394c 100644 --- a/demo/fixtures.sql +++ b/demo/fixtures.sql @@ -1,4 +1,4 @@ -create extension if not exists pggraphblas; +create extension if not exists onesparse; drop table if exists test; create table test ( diff --git a/pggraphblas--0.0.1.sql b/onesparse--0.0.1.sql similarity index 76% rename from pggraphblas--0.0.1.sql rename to onesparse--0.0.1.sql index 8f5ea1e..1cc01f1 100644 --- a/pggraphblas--0.0.1.sql +++ b/onesparse--0.0.1.sql @@ -1,16 +1,16 @@ -- complain if script is sourced in psql, rather than via CREATE EXTENSION -\echo Use "CREATE EXTENSION pggraphblas" to load this file. \quit +\echo Use "CREATE EXTENSION onesparse" to load this file. \quit CREATE TYPE vector; CREATE FUNCTION vector_in(cstring) RETURNS vector -AS '$libdir/pggraphblas', 'vector_in' +AS '$libdir/onesparse', 'vector_in' LANGUAGE C IMMUTABLE STRICT; CREATE FUNCTION vector_out(A vector) RETURNS cstring -AS '$libdir/pggraphblas', 'vector_out' +AS '$libdir/onesparse', 'vector_out' LANGUAGE C IMMUTABLE STRICT; CREATE TYPE vector ( @@ -25,51 +25,51 @@ CREATE TYPE matrix; CREATE FUNCTION matrix_in(cstring) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_in' +AS '$libdir/onesparse', 'matrix_in' LANGUAGE C IMMUTABLE STRICT; CREATE FUNCTION matrix_out(matrix) RETURNS cstring -AS '$libdir/pggraphblas', 'matrix_out' +AS '$libdir/onesparse', 'matrix_out' LANGUAGE C IMMUTABLE STRICT; CREATE FUNCTION nrows(matrix) RETURNS bigint -AS '$libdir/pggraphblas', 'matrix_nrows' +AS '$libdir/onesparse', 'matrix_nrows' LANGUAGE C STABLE; CREATE FUNCTION ncols(matrix) RETURNS bigint -AS '$libdir/pggraphblas', 'matrix_ncols' +AS '$libdir/onesparse', 'matrix_ncols' LANGUAGE C STABLE; CREATE FUNCTION nvals(matrix) RETURNS bigint -AS '$libdir/pggraphblas', 'matrix_nvals' +AS '$libdir/onesparse', 'matrix_nvals' LANGUAGE C STABLE; CREATE FUNCTION matrix_eq(A matrix, B matrix) RETURNS bool -AS '$libdir/pggraphblas', 'matrix_eq' +AS '$libdir/onesparse', 'matrix_eq' LANGUAGE C STABLE; CREATE FUNCTION matrix_ne(A matrix, B matrix) RETURNS bool -AS '$libdir/pggraphblas', 'matrix_ne' +AS '$libdir/onesparse', 'matrix_ne' LANGUAGE C STABLE; CREATE FUNCTION print( A matrix, level integer default 2) RETURNS text -AS '$libdir/pggraphblas', 'matrix_print' +AS '$libdir/onesparse', 'matrix_print' LANGUAGE C STABLE; CREATE FUNCTION print( A vector, level integer default 2) RETURNS text -AS '$libdir/pggraphblas', 'vector_print' +AS '$libdir/onesparse', 'vector_print' LANGUAGE C STABLE; CREATE TYPE matrix ( @@ -83,37 +83,37 @@ CREATE TYPE matrix ( CREATE FUNCTION matrix(bigint[], bigint[], bool[], bigint default null, bigint default null) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_bool' +AS '$libdir/onesparse', 'matrix_bool' LANGUAGE C STABLE; CREATE FUNCTION matrix(bigint[], bigint[], bigint[], bigint default null, bigint default null) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_int64' +AS '$libdir/onesparse', 'matrix_int64' LANGUAGE C STABLE; CREATE FUNCTION matrix(bigint[], bigint[], integer[], bigint default null, bigint default null) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_int32' +AS '$libdir/onesparse', 'matrix_int32' LANGUAGE C STABLE; CREATE FUNCTION matrix(bigint[], bigint[], smallint[], bigint default null, bigint default null) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_int16' +AS '$libdir/onesparse', 'matrix_int16' LANGUAGE C STABLE; CREATE FUNCTION matrix(bigint[], bigint[], real[], bigint default null, bigint default null) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_float4' +AS '$libdir/onesparse', 'matrix_float4' LANGUAGE C STABLE; CREATE FUNCTION matrix(bigint[], bigint[], float[], bigint default null, bigint default null) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_float8' +AS '$libdir/onesparse', 'matrix_float8' LANGUAGE C STABLE; -- matrix extract @@ -128,39 +128,39 @@ CREATE FUNCTION xtract( dinp1 text default null ) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_xtract' +AS '$libdir/onesparse', 'matrix_xtract' LANGUAGE C STABLE; -- empty matrix construction CREATE FUNCTION matrix_bool(nrows bigint, ncols bigint) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_bool' +AS '$libdir/onesparse', 'matrix_bool' LANGUAGE C STABLE STRICT; CREATE FUNCTION matrix_bigint(nrows bigint, ncols bigint) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_int64' +AS '$libdir/onesparse', 'matrix_int64' LANGUAGE C STABLE STRICT; CREATE FUNCTION matrix_integer(nrows bigint, ncols bigint) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_int32' +AS '$libdir/onesparse', 'matrix_int32' LANGUAGE C STABLE STRICT; CREATE FUNCTION matrix_smallint(nrows bigint, ncols bigint) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_int16' +AS '$libdir/onesparse', 'matrix_int16' LANGUAGE C STABLE STRICT; CREATE FUNCTION matrix_real(nrows bigint, ncols bigint) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_float4' +AS '$libdir/onesparse', 'matrix_float4' LANGUAGE C STABLE STRICT; CREATE FUNCTION matrix_float(nrows bigint, ncols bigint) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_float8' +AS '$libdir/onesparse', 'matrix_float8' LANGUAGE C STABLE STRICT; CREATE FUNCTION mxm( @@ -176,7 +176,7 @@ CREATE FUNCTION mxm( dinp1 text default null ) RETURNS matrix -AS '$libdir/pggraphblas', 'mxm' +AS '$libdir/onesparse', 'mxm' LANGUAGE C STABLE; CREATE FUNCTION kron( @@ -192,7 +192,7 @@ CREATE FUNCTION kron( dinp1 text default null ) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_kron' +AS '$libdir/onesparse', 'matrix_kron' LANGUAGE C STABLE; CREATE FUNCTION transpose( @@ -206,12 +206,12 @@ CREATE FUNCTION transpose( dinp1 text default null ) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_transpose' +AS '$libdir/onesparse', 'matrix_transpose' LANGUAGE C STABLE; CREATE FUNCTION mxm_op(A matrix, B matrix) RETURNS matrix -AS '$libdir/pggraphblas', 'mxm' +AS '$libdir/onesparse', 'mxm' LANGUAGE C STABLE STRICT; CREATE FUNCTION mxv( @@ -227,12 +227,12 @@ CREATE FUNCTION mxv( dinp1 text default null ) RETURNS vector -AS '$libdir/pggraphblas', 'mxv' +AS '$libdir/onesparse', 'mxv' LANGUAGE C STABLE; CREATE FUNCTION mxv_op(matrix, vector) RETURNS vector -AS '$libdir/pggraphblas', 'mxv' +AS '$libdir/onesparse', 'mxv' LANGUAGE C STABLE STRICT; CREATE FUNCTION vxm( @@ -248,12 +248,12 @@ CREATE FUNCTION vxm( dinp1 text default null ) RETURNS vector -AS '$libdir/pggraphblas', 'vxm' +AS '$libdir/onesparse', 'vxm' LANGUAGE C STABLE; CREATE FUNCTION vxm_op(vector, matrix) RETURNS vector -AS '$libdir/pggraphblas', 'vxm' +AS '$libdir/onesparse', 'vxm' LANGUAGE C STABLE STRICT; CREATE FUNCTION ewise_mult( @@ -270,7 +270,7 @@ CREATE FUNCTION ewise_mult( ) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_ewise_mult' +AS '$libdir/onesparse', 'matrix_ewise_mult' LANGUAGE C STABLE; CREATE FUNCTION ewise_add( @@ -287,56 +287,56 @@ CREATE FUNCTION ewise_add( ) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_ewise_add' +AS '$libdir/onesparse', 'matrix_ewise_add' LANGUAGE C STABLE; CREATE FUNCTION matrix_ewise_mult_op(A matrix, B matrix) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_ewise_mult' +AS '$libdir/onesparse', 'matrix_ewise_mult' LANGUAGE C STABLE STRICT; CREATE FUNCTION matrix_ewise_add_op(A matrix, B matrix) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_ewise_add' +AS '$libdir/onesparse', 'matrix_ewise_add' LANGUAGE C STABLE STRICT; -- matrix reduce to vector CREATE FUNCTION reduce(A matrix, semiring text default null) RETURNS vector -AS '$libdir/pggraphblas', 'matrix_reduce_vector' +AS '$libdir/onesparse', 'matrix_reduce_vector' LANGUAGE C STABLE; -- matrix reduce scalar CREATE FUNCTION reduce_bool(A matrix, semiring text default null) RETURNS bool -AS '$libdir/pggraphblas', 'matrix_reduce_bool' +AS '$libdir/onesparse', 'matrix_reduce_bool' LANGUAGE C STABLE; CREATE FUNCTION reduce_bigint(A matrix, semiring text default null) RETURNS bigint -AS '$libdir/pggraphblas', 'matrix_reduce_int64' +AS '$libdir/onesparse', 'matrix_reduce_int64' LANGUAGE C STABLE; CREATE FUNCTION reduce_integer(A matrix, semiring text default null) RETURNS integer -AS '$libdir/pggraphblas', 'matrix_reduce_int32' +AS '$libdir/onesparse', 'matrix_reduce_int32' LANGUAGE C STABLE; CREATE FUNCTION reduce_smallint(A matrix, semiring text default null) RETURNS smallint -AS '$libdir/pggraphblas', 'matrix_reduce_int16' +AS '$libdir/onesparse', 'matrix_reduce_int16' LANGUAGE C STABLE; CREATE FUNCTION reduce_real(A matrix, semiring text default null) RETURNS real -AS '$libdir/pggraphblas', 'matrix_reduce_float4' +AS '$libdir/onesparse', 'matrix_reduce_float4' LANGUAGE C STABLE; CREATE FUNCTION reduce_float(A matrix, semiring text default null) RETURNS float -AS '$libdir/pggraphblas', 'matrix_reduce_float8' +AS '$libdir/onesparse', 'matrix_reduce_float8' LANGUAGE C STABLE; -- matrix assign matrix @@ -346,7 +346,7 @@ CREATE FUNCTION assign( B matrix, mask matrix default null) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_assign_matrix' +AS '$libdir/onesparse', 'matrix_assign_matrix' LANGUAGE C STABLE; -- matrix assign scalar @@ -357,7 +357,7 @@ CREATE FUNCTION assign( C matrix default null, mask matrix default null) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_assign_bool' +AS '$libdir/onesparse', 'matrix_assign_bool' LANGUAGE C STABLE; CREATE FUNCTION assign( @@ -366,7 +366,7 @@ CREATE FUNCTION assign( C matrix default null, mask matrix default null) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_assign_int64' +AS '$libdir/onesparse', 'matrix_assign_int64' LANGUAGE C STABLE; CREATE FUNCTION assign( @@ -375,7 +375,7 @@ CREATE FUNCTION assign( C matrix default null, mask matrix default null) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_assign_int32' +AS '$libdir/onesparse', 'matrix_assign_int32' LANGUAGE C STABLE; CREATE FUNCTION assign( @@ -384,7 +384,7 @@ CREATE FUNCTION assign( C matrix default null, mask matrix default null) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_assign_int16' +AS '$libdir/onesparse', 'matrix_assign_int16' LANGUAGE C STABLE; CREATE FUNCTION assign( @@ -393,7 +393,7 @@ CREATE FUNCTION assign( C matrix default null, mask matrix default null) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_assign_float4' +AS '$libdir/onesparse', 'matrix_assign_float4' LANGUAGE C STABLE; CREATE FUNCTION assign( @@ -402,39 +402,39 @@ CREATE FUNCTION assign( C matrix default null, mask matrix default null) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_assign_float8' +AS '$libdir/onesparse', 'matrix_assign_float8' LANGUAGE C STABLE; -- matrix set element CREATE FUNCTION set_element(A matrix, i bigint, j bigint, value bool) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_set_element_bool' +AS '$libdir/onesparse', 'matrix_set_element_bool' LANGUAGE C STABLE STRICT; CREATE FUNCTION set_element(A matrix, i bigint, j bigint, value bigint) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_set_element_int64' +AS '$libdir/onesparse', 'matrix_set_element_int64' LANGUAGE C STABLE STRICT; CREATE FUNCTION set_element(A matrix, i bigint, j bigint, value integer) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_set_element_int32' +AS '$libdir/onesparse', 'matrix_set_element_int32' LANGUAGE C STABLE STRICT; CREATE FUNCTION set_element(A matrix, i bigint, j bigint, value smallint) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_set_element_int16' +AS '$libdir/onesparse', 'matrix_set_element_int16' LANGUAGE C STABLE STRICT; CREATE FUNCTION set_element(A matrix, i bigint, j bigint, value real) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_set_element_float4' +AS '$libdir/onesparse', 'matrix_set_element_float4' LANGUAGE C STABLE STRICT; CREATE FUNCTION set_element(A matrix, i bigint, j bigint, value float) RETURNS matrix -AS '$libdir/pggraphblas', 'matrix_set_element_float8' +AS '$libdir/onesparse', 'matrix_set_element_float8' LANGUAGE C STABLE STRICT; @@ -494,32 +494,32 @@ CREATE TYPE matrix_element_bool AS (i bigint, j bigint, value bool); CREATE FUNCTION elements_bigint(A matrix) RETURNS SETOF matrix_element_bigint -AS '$libdir/pggraphblas', 'matrix_elements_int64' +AS '$libdir/onesparse', 'matrix_elements_int64' LANGUAGE C STABLE STRICT; CREATE FUNCTION elements_integer(A matrix) RETURNS SETOF matrix_element_integer -AS '$libdir/pggraphblas', 'matrix_elements_int32' +AS '$libdir/onesparse', 'matrix_elements_int32' LANGUAGE C STABLE STRICT; CREATE FUNCTION elements_smallint(A matrix) RETURNS SETOF matrix_element_smallint -AS '$libdir/pggraphblas', 'matrix_elements_int16' +AS '$libdir/onesparse', 'matrix_elements_int16' LANGUAGE C STABLE STRICT; CREATE FUNCTION elements_float(A matrix) RETURNS SETOF matrix_element_float -AS '$libdir/pggraphblas', 'matrix_elements_float8' +AS '$libdir/onesparse', 'matrix_elements_float8' LANGUAGE C STABLE STRICT; CREATE FUNCTION elements_real(A matrix) RETURNS SETOF matrix_element_real -AS '$libdir/pggraphblas', 'matrix_elements_float4' +AS '$libdir/onesparse', 'matrix_elements_float4' LANGUAGE C STABLE STRICT; CREATE FUNCTION elements_bool(A matrix) RETURNS SETOF matrix_element_bool -AS '$libdir/pggraphblas', 'matrix_elements_bool' +AS '$libdir/onesparse', 'matrix_elements_bool' LANGUAGE C STABLE STRICT; -- vectors @@ -537,7 +537,7 @@ CREATE FUNCTION ewise_mult( dinp1 text default null ) RETURNS vector -AS '$libdir/pggraphblas', 'vector_ewise_mult' +AS '$libdir/onesparse', 'vector_ewise_mult' LANGUAGE C STABLE; CREATE FUNCTION ewise_add( @@ -553,37 +553,37 @@ CREATE FUNCTION ewise_add( dinp1 text default null ) RETURNS vector -AS '$libdir/pggraphblas', 'vector_ewise_add' +AS '$libdir/onesparse', 'vector_ewise_add' LANGUAGE C STABLE; CREATE FUNCTION vector_ewise_mult_op(A vector, B vector) RETURNS vector -AS '$libdir/pggraphblas', 'vector_ewise_mult' +AS '$libdir/onesparse', 'vector_ewise_mult' LANGUAGE C STABLE STRICT; CREATE FUNCTION vector_ewise_add_op(A vector, B vector) RETURNS vector -AS '$libdir/pggraphblas', 'vector_ewise_add' +AS '$libdir/onesparse', 'vector_ewise_add' LANGUAGE C STABLE STRICT; CREATE FUNCTION vector_eq(A vector, B vector) RETURNS bool -AS '$libdir/pggraphblas', 'vector_eq' +AS '$libdir/onesparse', 'vector_eq' LANGUAGE C STABLE; CREATE FUNCTION vector_ne(A vector, B vector) RETURNS bool -AS '$libdir/pggraphblas', 'vector_ne' +AS '$libdir/onesparse', 'vector_ne' LANGUAGE C STABLE; CREATE FUNCTION size(A vector) RETURNS bigint -AS '$libdir/pggraphblas', 'vector_size' +AS '$libdir/onesparse', 'vector_size' LANGUAGE C STABLE; CREATE FUNCTION nvals(A vector) RETURNS bigint -AS '$libdir/pggraphblas', 'vector_nvals' +AS '$libdir/onesparse', 'vector_nvals' LANGUAGE C STABLE; CREATE FUNCTION xtract( @@ -596,7 +596,7 @@ CREATE FUNCTION xtract( dinp1 text default null ) RETURNS vector -AS '$libdir/pggraphblas', 'vector_xtract' +AS '$libdir/onesparse', 'vector_xtract' LANGUAGE C STABLE; -- vector reduce @@ -605,42 +605,42 @@ CREATE FUNCTION reduce_bool( A vector, semiring text default null) RETURNS bool -AS '$libdir/pggraphblas', 'vector_reduce_bool' +AS '$libdir/onesparse', 'vector_reduce_bool' LANGUAGE C STABLE; CREATE FUNCTION reduce_bigint( A vector, semiring text default null) RETURNS bigint -AS '$libdir/pggraphblas', 'vector_reduce_int64' +AS '$libdir/onesparse', 'vector_reduce_int64' LANGUAGE C STABLE; CREATE FUNCTION reduce_integer( A vector, semiring text default null) RETURNS integer -AS '$libdir/pggraphblas', 'vector_reduce_int32' +AS '$libdir/onesparse', 'vector_reduce_int32' LANGUAGE C STABLE; CREATE FUNCTION reduce_smallint( A vector, semiring text default null) RETURNS smallint -AS '$libdir/pggraphblas', 'vector_reduce_int16' +AS '$libdir/onesparse', 'vector_reduce_int16' LANGUAGE C STABLE; CREATE FUNCTION reduce_real( A vector, semiring text default null) RETURNS real -AS '$libdir/pggraphblas', 'vector_reduce_float4' +AS '$libdir/onesparse', 'vector_reduce_float4' LANGUAGE C STABLE; CREATE FUNCTION reduce_float( A vector, semiring text default null) RETURNS float -AS '$libdir/pggraphblas', 'vector_reduce_float8' +AS '$libdir/onesparse', 'vector_reduce_float8' LANGUAGE C STABLE; -- vector assign @@ -651,7 +651,7 @@ CREATE FUNCTION assign( C vector default null, mask vector default null) RETURNS vector -AS '$libdir/pggraphblas', 'vector_assign_bool' +AS '$libdir/onesparse', 'vector_assign_bool' LANGUAGE C STABLE; CREATE FUNCTION assign( @@ -660,7 +660,7 @@ CREATE FUNCTION assign( C vector default null, mask vector default null) RETURNS vector -AS '$libdir/pggraphblas', 'vector_assign_int64' +AS '$libdir/onesparse', 'vector_assign_int64' LANGUAGE C STABLE; CREATE FUNCTION assign( @@ -669,7 +669,7 @@ CREATE FUNCTION assign( C vector default null, mask vector default null) RETURNS vector -AS '$libdir/pggraphblas', 'vector_assign_int32' +AS '$libdir/onesparse', 'vector_assign_int32' LANGUAGE C STABLE; CREATE FUNCTION assign( @@ -678,7 +678,7 @@ CREATE FUNCTION assign( C vector default null, mask vector default null) RETURNS vector -AS '$libdir/pggraphblas', 'vector_assign_int16' +AS '$libdir/onesparse', 'vector_assign_int16' LANGUAGE C STABLE; CREATE FUNCTION assign( @@ -687,7 +687,7 @@ CREATE FUNCTION assign( C vector default null, mask vector default null) RETURNS vector -AS '$libdir/pggraphblas', 'vector_assign_float4' +AS '$libdir/onesparse', 'vector_assign_float4' LANGUAGE C STABLE; CREATE FUNCTION assign( @@ -696,39 +696,39 @@ CREATE FUNCTION assign( C vector default null, mask vector default null) RETURNS vector -AS '$libdir/pggraphblas', 'vector_assign_float8' +AS '$libdir/onesparse', 'vector_assign_float8' LANGUAGE C STABLE; -- vector set element CREATE FUNCTION set_element(A vector, index bigint, value bool) RETURNS vector -AS '$libdir/pggraphblas', 'vector_set_element_bool' +AS '$libdir/onesparse', 'vector_set_element_bool' LANGUAGE C STABLE STRICT; CREATE FUNCTION set_element(A vector, index bigint, value bigint) RETURNS vector -AS '$libdir/pggraphblas', 'vector_set_element_int64' +AS '$libdir/onesparse', 'vector_set_element_int64' LANGUAGE C STABLE STRICT; CREATE FUNCTION set_element(A vector, index bigint, value integer) RETURNS vector -AS '$libdir/pggraphblas', 'vector_set_element_int32' +AS '$libdir/onesparse', 'vector_set_element_int32' LANGUAGE C STABLE STRICT; CREATE FUNCTION set_element(A vector, index bigint, value smallint) RETURNS vector -AS '$libdir/pggraphblas', 'vector_set_element_int16' +AS '$libdir/onesparse', 'vector_set_element_int16' LANGUAGE C STABLE STRICT; CREATE FUNCTION set_element(A vector, index bigint, value real) RETURNS vector -AS '$libdir/pggraphblas', 'vector_set_element_float4' +AS '$libdir/onesparse', 'vector_set_element_float4' LANGUAGE C STABLE STRICT; CREATE FUNCTION set_element(A vector, index bigint, value float) RETURNS vector -AS '$libdir/pggraphblas', 'vector_set_element_float8' +AS '$libdir/onesparse', 'vector_set_element_float8' LANGUAGE C STABLE STRICT; CREATE OPERATOR * ( @@ -761,42 +761,42 @@ CREATE OPERATOR <> ( CREATE FUNCTION vector(bigint[]) RETURNS vector -AS '$libdir/pggraphblas', 'vector_int64' +AS '$libdir/onesparse', 'vector_int64' LANGUAGE C; CREATE CAST (bigint[] AS vector) WITH FUNCTION vector(bigint[]) AS IMPLICIT; CREATE FUNCTION vector(integer[]) RETURNS vector -AS '$libdir/pggraphblas', 'vector_int32' +AS '$libdir/onesparse', 'vector_int32' LANGUAGE C; CREATE CAST (integer[] AS vector) WITH FUNCTION vector(integer[]) AS IMPLICIT; CREATE FUNCTION vector(smallint[]) RETURNS vector -AS '$libdir/pggraphblas', 'vector_int16' +AS '$libdir/onesparse', 'vector_int16' LANGUAGE C; CREATE CAST (smallint[] AS vector) WITH FUNCTION vector(smallint[]) AS IMPLICIT; CREATE FUNCTION vector(float[]) RETURNS vector -AS '$libdir/pggraphblas', 'vector_float8' +AS '$libdir/onesparse', 'vector_float8' LANGUAGE C; CREATE CAST (float[] AS vector) WITH FUNCTION vector(float[]) AS IMPLICIT; CREATE FUNCTION vector(real[]) RETURNS vector -AS '$libdir/pggraphblas', 'vector_float4' +AS '$libdir/onesparse', 'vector_float4' LANGUAGE C; CREATE CAST (real[] AS vector) WITH FUNCTION vector(real[]) AS IMPLICIT; CREATE FUNCTION vector(bool[]) RETURNS vector -AS '$libdir/pggraphblas', 'vector_bool' +AS '$libdir/onesparse', 'vector_bool' LANGUAGE C; CREATE CAST (bool[] AS vector) WITH FUNCTION vector(bool[]) AS IMPLICIT; @@ -805,64 +805,64 @@ CREATE CAST (bool[] AS vector) WITH FUNCTION vector(bool[]) AS IMPLICIT; CREATE FUNCTION vector_bigint(size bigint) RETURNS vector -AS '$libdir/pggraphblas', 'vector_empty_int64' +AS '$libdir/onesparse', 'vector_empty_int64' LANGUAGE C STRICT; CREATE FUNCTION vector_integer(size bigint) RETURNS vector -AS '$libdir/pggraphblas', 'vector_empty_int32' +AS '$libdir/onesparse', 'vector_empty_int32' LANGUAGE C STRICT; CREATE FUNCTION vector_smallint(size bigint) RETURNS vector -AS '$libdir/pggraphblas', 'vector_empty_int16' +AS '$libdir/onesparse', 'vector_empty_int16' LANGUAGE C STRICT; CREATE FUNCTION vector_float(size bigint) RETURNS vector -AS '$libdir/pggraphblas', 'vector_empty_float8' +AS '$libdir/onesparse', 'vector_empty_float8' LANGUAGE C STRICT; CREATE FUNCTION vector_real(size bigint) RETURNS vector -AS '$libdir/pggraphblas', 'vector_empty_float4' +AS '$libdir/onesparse', 'vector_empty_float4' LANGUAGE C STRICT; CREATE FUNCTION vector_bool(size bigint) RETURNS vector -AS '$libdir/pggraphblas', 'vector_empty_bool' +AS '$libdir/onesparse', 'vector_empty_bool' LANGUAGE C STRICT; -- sparse construction CREATE FUNCTION vector(bigint[], bigint[], bigint default null) RETURNS vector -AS '$libdir/pggraphblas', 'vector_int64' +AS '$libdir/onesparse', 'vector_int64' LANGUAGE C; CREATE FUNCTION vector(bigint[], integer[], bigint default null) RETURNS vector -AS '$libdir/pggraphblas', 'vector_int32' +AS '$libdir/onesparse', 'vector_int32' LANGUAGE C; CREATE FUNCTION vector(bigint[], smallint[], bigint default null) RETURNS vector -AS '$libdir/pggraphblas', 'vector_int16' +AS '$libdir/onesparse', 'vector_int16' LANGUAGE C; CREATE FUNCTION vector(bigint[], float[], bigint default null) RETURNS vector -AS '$libdir/pggraphblas', 'vector_float8' +AS '$libdir/onesparse', 'vector_float8' LANGUAGE C; CREATE FUNCTION vector(bigint[], real[], bigint default null) RETURNS vector -AS '$libdir/pggraphblas', 'vector_float4' +AS '$libdir/onesparse', 'vector_float4' LANGUAGE C; CREATE FUNCTION vector(bigint[], bool[], bigint default null) RETURNS vector -AS '$libdir/pggraphblas', 'vector_bool' +AS '$libdir/onesparse', 'vector_bool' LANGUAGE C; -- tuple formats for vector edges @@ -876,30 +876,30 @@ CREATE TYPE vector_element_bool AS (index bigint, value bool); CREATE FUNCTION elements_bigint(A vector) RETURNS SETOF vector_element_bigint -AS '$libdir/pggraphblas', 'vector_elements_int64' +AS '$libdir/onesparse', 'vector_elements_int64' LANGUAGE C STABLE STRICT; CREATE FUNCTION elements_integer(A vector) RETURNS SETOF vector_element_integer -AS '$libdir/pggraphblas', 'vector_elements_int32' +AS '$libdir/onesparse', 'vector_elements_int32' LANGUAGE C STABLE STRICT; CREATE FUNCTION elements_smallint(A vector) RETURNS SETOF vector_element_smallint -AS '$libdir/pggraphblas', 'vector_elements_int16' +AS '$libdir/onesparse', 'vector_elements_int16' LANGUAGE C STABLE STRICT; CREATE FUNCTION elements_float(A vector) RETURNS SETOF vector_element_float -AS '$libdir/pggraphblas', 'vector_elements_float8' +AS '$libdir/onesparse', 'vector_elements_float8' LANGUAGE C STABLE STRICT; CREATE FUNCTION elements_real(A vector) RETURNS SETOF vector_element_real -AS '$libdir/pggraphblas', 'vector_elements_float4' +AS '$libdir/onesparse', 'vector_elements_float4' LANGUAGE C STABLE STRICT; CREATE FUNCTION elements_bool(A vector) RETURNS SETOF vector_element_bool -AS '$libdir/pggraphblas', 'vector_elements_bool' +AS '$libdir/onesparse', 'vector_elements_bool' LANGUAGE C STABLE STRICT; diff --git a/pggraphblas.control b/onesparse.control similarity index 82% rename from pggraphblas.control rename to onesparse.control index 27d93fd..cbcb82b 100644 --- a/pggraphblas.control +++ b/onesparse.control @@ -1,4 +1,4 @@ -# pggraphblas extension +# onesparse extension comment = 'Postgres extension for SuiteSparse::GraphBLAS' default_version = '0.0.1' relocatable = true diff --git a/psql b/psql index 2fff2f0..846a5fa 100755 --- a/psql +++ b/psql @@ -1 +1 @@ -docker run -it pggraphblas/test psql -U postgres +docker run -it onesparse/test psql -U postgres diff --git a/src/pggraphblas.c b/src/onesparse.c similarity index 99% rename from src/pggraphblas.c rename to src/onesparse.c index 3e14ecd..ba0b749 100644 --- a/src/pggraphblas.c +++ b/src/onesparse.c @@ -1,4 +1,4 @@ -#include "pggraphblas.h" +#include "onesparse.h" PG_MODULE_MAGIC; pgGrB_Semiring semirings[960]; diff --git a/src/pggraphblas.h b/src/onesparse.h similarity index 100% rename from src/pggraphblas.h rename to src/onesparse.h diff --git a/test.sh b/test.sh index 4ab96e2..3ae04e7 100755 --- a/test.sh +++ b/test.sh @@ -1,21 +1,21 @@ #!/bin/bash -DB_HOST="pggraphblas-test-db" +DB_HOST="onesparse-test-db" DB_NAME="postgres" SU="postgres" EXEC="docker exec $DB_HOST" EXECIT="docker exec -it $DB_HOST" echo force rm previous container -docker rm -f pggraphblas-test +docker rm -f onesparse-test set -e echo building test image -docker build . -t pggraphblas/test +docker build . -t onesparse/test echo running test container -docker run -v $(pwd)/tests/:/tests -v $(pwd)/demo/:/demo -v --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -d --name "$DB_HOST" pggraphblas/test +docker run -v $(pwd)/tests/:/tests -v $(pwd)/demo/:/demo -v --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -d --name "$DB_HOST" onesparse/test $EXECIT pg_ctl start # $EXEC make clean @@ -34,12 +34,12 @@ done if [ $# -eq 0 ] then echo running tests - $EXEC tmux new-session -d -s pggraphblas - $EXECIT tmux attach-session -t pggraphblas + $EXEC tmux new-session -d -s onesparse + $EXECIT tmux attach-session -t onesparse else echo running repl - $EXEC tmux new-session -d -s pggraphblas $* - $EXECIT tmux attach-session -t pggraphblas + $EXEC tmux new-session -d -s onesparse $* + $EXECIT tmux attach-session -t onesparse fi echo destroying test container and image diff --git a/tests/crash.sql b/tests/crash.sql index af9bd93..e775a33 100644 --- a/tests/crash.sql +++ b/tests/crash.sql @@ -1,4 +1,4 @@ -create extension if not exists pggraphblas; +create extension if not exists onesparse; \ir gdb.sql \i /demo/fixtures.sql diff --git a/tests/test.sql b/tests/test.sql index 142d885..2b95482 100644 --- a/tests/test.sql +++ b/tests/test.sql @@ -9,6 +9,6 @@ -- \set QUIET 1 create extension if not exists pgtap; -create extension if not exists pggraphblas; +create extension if not exists onesparse; \ir init.sql From 600c1c83b02aae2e5f00881c38dcb180d970fc6a Mon Sep 17 00:00:00 2001 From: Michel Pelletier Date: Thu, 8 Aug 2024 21:23:10 -0700 Subject: [PATCH 4/6] refactor ops methods into separate header. --- Makefile | 2 +- onesparse.control | 3 +- src/matrix.c | 154 +++++++++--------- src/matrix.h | 397 +++------------------------------------------- src/matrix_ops.h | 346 ++++++++++++++++++++++++++++++++++++++++ src/onesparse.c | 6 +- src/onesparse.h | 77 +++++---- src/type.c | 24 +-- src/vector.c | 82 +++++----- src/vector.h | 275 +++----------------------------- src/vector_ops.h | 203 ++++++++++++++++++++++++ 11 files changed, 770 insertions(+), 799 deletions(-) create mode 100644 src/matrix_ops.h create mode 100644 src/vector_ops.h diff --git a/Makefile b/Makefile index bc83d9a..e4c7aa7 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ DATA = $(wildcard *--*.sql) PGXS := $(shell $(PG_CONFIG) --pgxs) MODULE_big = onesparse OBJS = $(patsubst %.c,%.o,$(wildcard src/onesparse.c)) -SHLIB_LINK = -lgraphblas +SHLIB_LINK = -lgraphblas -lpq PG_CPPFLAGS = -O0 -Wfatal-errors TESTS = $(wildcard test/sql/*.sql) diff --git a/onesparse.control b/onesparse.control index cbcb82b..8e1ef34 100644 --- a/onesparse.control +++ b/onesparse.control @@ -1,5 +1,6 @@ # onesparse extension comment = 'Postgres extension for SuiteSparse::GraphBLAS' default_version = '0.0.1' -relocatable = true +relocatable = false +schema = 'onesparse' requires = '' diff --git a/src/matrix.c b/src/matrix.c index ca668b4..abee3ed 100644 --- a/src/matrix.c +++ b/src/matrix.c @@ -96,19 +96,19 @@ /* MemoryContextCallback function to free matrices */ static void context_callback_matrix_free(void* m) { - pgGrB_Matrix *mat = (pgGrB_Matrix *) m; + OS_Matrix *mat = (OS_Matrix *) m; GrB_Matrix_free(&mat->M); } /* Construct an empty flat matrix. */ -pgGrB_FlatMatrix * +OS_FlatMatrix * construct_empty_flat_matrix(GrB_Index nrows, GrB_Index ncols, GrB_Type type) { - pgGrB_FlatMatrix *result; + OS_FlatMatrix *result; - result = (pgGrB_FlatMatrix *) palloc0(sizeof(pgGrB_FlatMatrix)); - SET_VARSIZE(result, sizeof(pgGrB_FlatMatrix)); + result = (OS_FlatMatrix *) palloc0(sizeof(OS_FlatMatrix)); + SET_VARSIZE(result, sizeof(OS_FlatMatrix)); result->nrows = ncols; result->ncols = nrows; result->nvals = 0; @@ -118,25 +118,25 @@ construct_empty_flat_matrix(GrB_Index nrows, /* Helper function to always expanded datum -This is used by PGGRB_GETARG_MATRIX */ -pgGrB_Matrix * +This is used by OS_GETARG_MATRIX */ +OS_Matrix * DatumGetMatrix(Datum d) { - pgGrB_Matrix *A; - pgGrB_FlatMatrix *flat; + OS_Matrix *A; + OS_FlatMatrix *flat; if (VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(d))) { A = MatrixGetEOHP(d); Assert(A->em_magic == matrix_MAGIC); return A; } - flat = (pgGrB_FlatMatrix*)PG_DETOAST_DATUM(d); + flat = (OS_FlatMatrix*)PG_DETOAST_DATUM(d); TYPE_APPLY(d, flat->type, expand_flat_matrix, flat, CurrentMemoryContext); return MatrixGetEOHP(d); } Datum matrix_in(PG_FUNCTION_ARGS) { - pgGrB_FlatMatrix *flat; + OS_FlatMatrix *flat; char *input; size_t len; int bc; @@ -156,7 +156,7 @@ matrix_out(PG_FUNCTION_ARGS) { Size size; char *rp, *result, *buf; - pgGrB_Matrix *A = PGGRB_GETARG_MATRIX(0); + OS_Matrix *A = OS_GETARG_MATRIX(0); size = EOH_get_flat_size(&A->hdr); buf = palloc(size); EOH_flatten_into(&A->hdr, buf, size); @@ -169,9 +169,9 @@ matrix_out(PG_FUNCTION_ARGS) Datum matrix_nrows(PG_FUNCTION_ARGS) { GrB_Info info; - pgGrB_Matrix *mat; + OS_Matrix *mat; GrB_Index count; - mat = PGGRB_GETARG_MATRIX(0); + mat = OS_GETARG_MATRIX(0); CHECKD(GrB_Matrix_nrows(&count, mat->M), mat->M); return Int64GetDatum(count); } @@ -179,9 +179,9 @@ matrix_nrows(PG_FUNCTION_ARGS) { Datum matrix_ncols(PG_FUNCTION_ARGS) { GrB_Info info; - pgGrB_Matrix *mat; + OS_Matrix *mat; GrB_Index count; - mat = PGGRB_GETARG_MATRIX(0); + mat = OS_GETARG_MATRIX(0); CHECKD(GrB_Matrix_ncols(&count, mat->M), mat->M); return Int64GetDatum(count); } @@ -189,9 +189,9 @@ matrix_ncols(PG_FUNCTION_ARGS) { Datum matrix_nvals(PG_FUNCTION_ARGS) { GrB_Info info; - pgGrB_Matrix *mat; + OS_Matrix *mat; GrB_Index count; - mat = PGGRB_GETARG_MATRIX(0); + mat = OS_GETARG_MATRIX(0); CHECKD(GrB_Matrix_nvals(&count, mat->M), mat->M); return Int64GetDatum(count); } @@ -199,11 +199,11 @@ matrix_nvals(PG_FUNCTION_ARGS) { Datum matrix_eq(PG_FUNCTION_ARGS) { GrB_Info info; - pgGrB_Matrix *A, *B; + OS_Matrix *A, *B; bool result; - A = PGGRB_GETARG_MATRIX(0); - B = PGGRB_GETARG_MATRIX(1); + A = OS_GETARG_MATRIX(0); + B = OS_GETARG_MATRIX(1); result = true; PG_RETURN_BOOL(result); @@ -212,11 +212,11 @@ matrix_eq(PG_FUNCTION_ARGS) { Datum matrix_ne(PG_FUNCTION_ARGS) { GrB_Info info; - pgGrB_Matrix *A, *B; + OS_Matrix *A, *B; bool result; - A = PGGRB_GETARG_MATRIX(0); - B = PGGRB_GETARG_MATRIX(1); + A = OS_GETARG_MATRIX(0); + B = OS_GETARG_MATRIX(1); result = true; PG_RETURN_BOOL(!result); @@ -224,22 +224,22 @@ matrix_ne(PG_FUNCTION_ARGS) { Datum matrix_ewise_mult(PG_FUNCTION_ARGS) { - pgGrB_Matrix *A, *B, *C = NULL, *mask = NULL; + OS_Matrix *A, *B, *C = NULL, *mask = NULL; Datum d; char *binop_name, *accum_name; GrB_BinaryOp binop = NULL, accum = NULL; GrB_Descriptor desc = NULL; GrB_Info info; - A = PGGRB_GETARG_MATRIX(0); - B = PGGRB_GETARG_MATRIX(1); + A = OS_GETARG_MATRIX(0); + B = OS_GETARG_MATRIX(1); binop_name = matrix_times_binop(A, B); accum_name = NULL; if (PG_NARGS() > 2) { - C = PG_ARGISNULL(2) ? NULL : PGGRB_GETARG_MATRIX(2); - mask = PG_ARGISNULL(3) ? NULL : PGGRB_GETARG_MATRIX(3); + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(2); + mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_MATRIX(3); binop_name = PG_ARGISNULL(4) ? binop_name : text_to_cstring(PG_GETARG_TEXT_PP(4)); accum_name = PG_ARGISNULL(5) ? @@ -260,22 +260,22 @@ matrix_ewise_mult(PG_FUNCTION_ARGS) { Datum matrix_ewise_add(PG_FUNCTION_ARGS) { - pgGrB_Matrix *A, *B, *C = NULL, *mask = NULL; + OS_Matrix *A, *B, *C = NULL, *mask = NULL; Datum d; char *binop_name, *accum_name; GrB_BinaryOp binop = NULL, accum = NULL; GrB_Descriptor desc = NULL; GrB_Info info; - A = PGGRB_GETARG_MATRIX(0); - B = PGGRB_GETARG_MATRIX(1); + A = OS_GETARG_MATRIX(0); + B = OS_GETARG_MATRIX(1); accum_name = NULL; binop_name = matrix_plus_binop(A, B); if (PG_NARGS() > 2) { - C = PG_ARGISNULL(2) ? NULL : PGGRB_GETARG_MATRIX(2); - mask = PG_ARGISNULL(3) ? NULL : PGGRB_GETARG_MATRIX(3); + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(2); + mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_MATRIX(3); binop_name = PG_ARGISNULL(4) ? binop_name : text_to_cstring(PG_GETARG_TEXT_PP(4)); accum_name = PG_ARGISNULL(5) ? @@ -297,7 +297,7 @@ matrix_ewise_add(PG_FUNCTION_ARGS) { Datum mxm(PG_FUNCTION_ARGS) { - pgGrB_Matrix *A, *B, *C = NULL, *mask = NULL; + OS_Matrix *A, *B, *C = NULL, *mask = NULL; GrB_Info info; GrB_Type type; Datum d; @@ -306,15 +306,15 @@ mxm(PG_FUNCTION_ARGS) { GrB_BinaryOp binop = NULL; GrB_Descriptor desc = NULL; - A = PGGRB_GETARG_MATRIX(0); - B = PGGRB_GETARG_MATRIX(1); + A = OS_GETARG_MATRIX(0); + B = OS_GETARG_MATRIX(1); semiring_name = mxm_semiring(A, B); binop_name = NULL; if (PG_NARGS() > 2) { - C = PG_ARGISNULL(2) ? NULL : PGGRB_GETARG_MATRIX(2); - mask = PG_ARGISNULL(3) ? NULL : PGGRB_GETARG_MATRIX(3); + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(2); + mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_MATRIX(3); semiring_name = PG_ARGISNULL(4) ? semiring_name : text_to_cstring(PG_GETARG_TEXT_PP(4)); @@ -346,8 +346,8 @@ mxm(PG_FUNCTION_ARGS) { Datum mxv(PG_FUNCTION_ARGS) { GrB_Info info; - pgGrB_Matrix *A; - pgGrB_Vector *B, *C = NULL, *mask = NULL; + OS_Matrix *A; + OS_Vector *B, *C = NULL, *mask = NULL; GrB_Type type; Datum d; char *semiring_name, *binop_name; @@ -355,15 +355,15 @@ mxv(PG_FUNCTION_ARGS) { GrB_BinaryOp binop = NULL; GrB_Descriptor desc = NULL; - A = PGGRB_GETARG_MATRIX(0); - B = PGGRB_GETARG_VECTOR(1); + A = OS_GETARG_MATRIX(0); + B = OS_GETARG_VECTOR(1); semiring_name = mxv_semiring(A, B); binop_name = NULL; if (PG_NARGS() > 2) { - C = PG_ARGISNULL(2) ? NULL : PGGRB_GETARG_VECTOR(2); - mask = PG_ARGISNULL(3) ? NULL : PGGRB_GETARG_VECTOR(3); + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_VECTOR(2); + mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_VECTOR(3); semiring_name = PG_ARGISNULL(4) ? semiring_name : text_to_cstring(PG_GETARG_TEXT_PP(4)); @@ -390,8 +390,8 @@ mxv(PG_FUNCTION_ARGS) { Datum vxm(PG_FUNCTION_ARGS) { - pgGrB_Matrix *B; - pgGrB_Vector *A, *C = NULL, *mask = NULL; + OS_Matrix *B; + OS_Vector *A, *C = NULL, *mask = NULL; GrB_Type type; GrB_Info info; Datum d; @@ -400,15 +400,15 @@ vxm(PG_FUNCTION_ARGS) { GrB_BinaryOp binop = NULL; GrB_Descriptor desc = NULL; - A = PGGRB_GETARG_VECTOR(0); - B = PGGRB_GETARG_MATRIX(1); + A = OS_GETARG_VECTOR(0); + B = OS_GETARG_MATRIX(1); semiring_name = vxm_semiring(A, B); binop_name = NULL; if (PG_NARGS() > 2) { - C = PG_ARGISNULL(2) ? NULL : PGGRB_GETARG_VECTOR(2); - mask = PG_ARGISNULL(3) ? NULL : PGGRB_GETARG_VECTOR(3); + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_VECTOR(2); + mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_VECTOR(3); semiring_name = PG_ARGISNULL(4) ? semiring_name : PG_GETARG_CSTRING(4); binop_name = PG_ARGISNULL(5) ? NULL : @@ -434,15 +434,15 @@ vxm(PG_FUNCTION_ARGS) { Datum matrix_reduce_vector(PG_FUNCTION_ARGS) { GrB_Info info; - pgGrB_Matrix *A; + OS_Matrix *A; GrB_Semiring semiring; GrB_Monoid monoid; char *semiring_name; - pgGrB_Vector *val; + OS_Vector *val; GrB_Index size; GrB_Type type; - A = PGGRB_GETARG_MATRIX(0); + A = OS_GETARG_MATRIX(0); semiring_name = PG_ARGISNULL(1)? NULL: text_to_cstring(PG_GETARG_TEXT_PP(1)); @@ -459,21 +459,21 @@ matrix_reduce_vector(PG_FUNCTION_ARGS) { TYPE_APPLY(val, A->type, construct_empty_expanded_vector, size, CurrentMemoryContext); CHECKD(GrB_reduce(val->V, NULL, monoid, A->M, NULL), A->M); - PGGRB_RETURN_VECTOR(val); + OS_RETURN_VECTOR(val); } Datum matrix_transpose(PG_FUNCTION_ARGS) { GrB_Info info; - pgGrB_Matrix *A, *C = NULL, *mask; + OS_Matrix *A, *C = NULL, *mask; GrB_Index m, n; GrB_Descriptor desc = NULL; - A = PGGRB_GETARG_MATRIX(0); + A = OS_GETARG_MATRIX(0); if (PG_NARGS() > 0) { - C = PG_ARGISNULL(1) ? NULL : PGGRB_GETARG_MATRIX(2); - mask = PG_ARGISNULL(2) ? NULL : PGGRB_GETARG_MATRIX(3); + C = PG_ARGISNULL(1) ? NULL : OS_GETARG_MATRIX(2); + mask = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(3); if (PG_NARGS() > 3) { GET_DESCRIPTOR(3, desc); } @@ -486,18 +486,18 @@ matrix_transpose(PG_FUNCTION_ARGS) { } CHECKD(GrB_transpose(C->M, mask? mask->M:NULL, NULL, A->M, desc), A->M); - PGGRB_RETURN_MATRIX(C); + OS_RETURN_MATRIX(C); } Datum matrix_assign_matrix(PG_FUNCTION_ARGS) { GrB_Info info; - pgGrB_Matrix *A, *B, *mask; + OS_Matrix *A, *B, *mask; GrB_Index nvals, *rows = NULL, *cols = NULL; - A = PGGRB_GETARG_MATRIX(0); - B = PGGRB_GETARG_MATRIX(1); - mask = PG_ARGISNULL(2)? NULL : PGGRB_GETARG_MATRIX(2); + A = OS_GETARG_MATRIX(0); + B = OS_GETARG_MATRIX(1); + mask = PG_ARGISNULL(2)? NULL : OS_GETARG_MATRIX(2); CHECKD(GrB_Matrix_nvals(&nvals, B->M), B->M); @@ -514,12 +514,12 @@ matrix_assign_matrix(PG_FUNCTION_ARGS) { cols? cols : GrB_ALL, nvals, NULL), A->M); - PGGRB_RETURN_MATRIX(A); + OS_RETURN_MATRIX(A); } Datum matrix_kron(PG_FUNCTION_ARGS) { - pgGrB_Matrix *A, *B, *C = NULL, *mask = NULL; + OS_Matrix *A, *B, *C = NULL, *mask = NULL; GrB_Info info; GrB_Type type; Datum d; @@ -527,14 +527,14 @@ matrix_kron(PG_FUNCTION_ARGS) { GrB_BinaryOp accum = NULL, mulop = NULL; GrB_Descriptor desc = NULL; - A = PGGRB_GETARG_MATRIX(0); - B = PGGRB_GETARG_MATRIX(1); + A = OS_GETARG_MATRIX(0); + B = OS_GETARG_MATRIX(1); accum_name = NULL; mulop_name = NULL; if (PG_NARGS() > 2) { - C = PG_ARGISNULL(2) ? NULL : PGGRB_GETARG_MATRIX(2); - mask = PG_ARGISNULL(3) ? NULL : PGGRB_GETARG_MATRIX(3); + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(2); + mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_MATRIX(3); accum_name = PG_ARGISNULL(4) ? NULL : text_to_cstring(PG_GETARG_TEXT_PP(4)); @@ -564,13 +564,13 @@ matrix_kron(PG_FUNCTION_ARGS) { Datum matrix_xtract(PG_FUNCTION_ARGS) { GrB_Info info; - pgGrB_Matrix *A, *B, *C = NULL; + OS_Matrix *A, *B, *C = NULL; GrB_Index nrows, ncols, nvals, *rows, *cols; GrB_Descriptor desc = NULL; - A = PGGRB_GETARG_MATRIX(0); - B = PGGRB_GETARG_MATRIX(1); - C = PG_ARGISNULL(2) ? NULL : PGGRB_GETARG_MATRIX(2); + A = OS_GETARG_MATRIX(0); + B = OS_GETARG_MATRIX(1); + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(2); GET_DESCRIPTOR(3, desc); CHECKD(GrB_Matrix_nrows(&nrows, A->M), A->M); @@ -584,17 +584,17 @@ matrix_xtract(PG_FUNCTION_ARGS) { TYPE_APPLY(nvals, A->type, extract_rowscols, B, &rows, &cols, nvals); CHECKD(GrB_Matrix_extract(C->M, NULL, NULL, A->M, rows, nrows, cols, ncols, NULL), A->M); - PGGRB_RETURN_MATRIX(C); + OS_RETURN_MATRIX(C); } Datum matrix_print(PG_FUNCTION_ARGS) { - pgGrB_Matrix *A; + OS_Matrix *A; char *result, *buf; size_t size; FILE *fp; int level; - A = PGGRB_GETARG_MATRIX(0); + A = OS_GETARG_MATRIX(0); level = PG_GETARG_INT32(1); fp = open_memstream(&buf, &size); diff --git a/src/matrix.h b/src/matrix.h index f219f87..3ecd0c1 100644 --- a/src/matrix.h +++ b/src/matrix.h @@ -3,12 +3,12 @@ /* Set Returning Function (matrix_elements) state for generating tuples from a matrix. */ -typedef struct FN(pgGrB_Matrix_ExtractState) { - pgGrB_Matrix *mat; +typedef struct FN(OS_Matrix_ExtractState) { + OS_Matrix *mat; GrB_Index *rows; GrB_Index *cols; PG_TYPE *vals; -} FN(pgGrB_Matrix_ExtractState); +} FN(OS_Matrix_ExtractState); /* Expanded Object Header "methods" for flattening matrices for storage */ static Size FN(matrix_get_flat_size)(ExpandedObjectHeader *eohptr); @@ -22,100 +22,31 @@ static const ExpandedObjectMethods FN(matrix_methods) = { /* Utility function that expands a flattened matrix datum. */ Datum -FN(expand_flat_matrix)(pgGrB_FlatMatrix *flat, +FN(expand_flat_matrix)(OS_FlatMatrix *flat, MemoryContext parentcontext); -GrB_Index FN(extract_rowscols)(pgGrB_Matrix *A, - GrB_Index **rows, - GrB_Index **cols, - GrB_Index nvals); - -pgGrB_Matrix * +OS_Matrix * FN(construct_empty_expanded_matrix)(GrB_Index nrows, GrB_Index ncols, MemoryContext parentcontext); -Datum FN(matrix_ewise_mult)(pgGrB_Matrix *A, - pgGrB_Matrix *B, - pgGrB_Matrix *C, - pgGrB_Matrix *mask, - GrB_BinaryOp binop, - GrB_BinaryOp accum, - GrB_Descriptor desc); - -Datum FN(matrix_ewise_add)(pgGrB_Matrix *A, - pgGrB_Matrix *B, - pgGrB_Matrix *C, - pgGrB_Matrix *mask, - GrB_BinaryOp binop, - GrB_BinaryOp accum, - GrB_Descriptor desc); - -Datum -FN(mxm)(pgGrB_Matrix *A, - pgGrB_Matrix *B, - pgGrB_Matrix *C, - pgGrB_Matrix *mask, - GrB_Semiring semiring, - GrB_BinaryOp binop, - GrB_Descriptor desc); - -Datum -FN(matrix_kron)(pgGrB_Matrix *A, - pgGrB_Matrix *B, - pgGrB_Matrix *C, - pgGrB_Matrix *mask, - GrB_BinaryOp accum, - GrB_BinaryOp mulop, - GrB_Descriptor desc); - -Datum -FN(mxv)(pgGrB_Matrix *A, - pgGrB_Vector *B, - pgGrB_Vector *C, - pgGrB_Vector *mask, - GrB_Semiring semiring, - GrB_BinaryOp binop, - GrB_Descriptor desc); - -Datum -FN(vxm)(pgGrB_Vector *A, - pgGrB_Matrix *B, - pgGrB_Vector *C, - pgGrB_Vector *mask, - GrB_Semiring semiring, - GrB_BinaryOp binop, - GrB_Descriptor desc); - PG_FUNCTION_INFO_V1(FN(matrix)); PG_FUNCTION_INFO_V1(FN(matrix_empty)); -PG_FUNCTION_INFO_V1(FN(matrix_elements)); -PG_FUNCTION_INFO_V1(FN(matrix_reduce)); -PG_FUNCTION_INFO_V1(FN(matrix_assign)); -PG_FUNCTION_INFO_V1(FN(matrix_random)); -PG_FUNCTION_INFO_V1(FN(matrix_set_element)); /* Compute size of storage needed for matrix */ static Size FN(matrix_get_flat_size)(ExpandedObjectHeader *eohptr) { GrB_Info info; - pgGrB_Matrix *A = (pgGrB_Matrix *) eohptr; - Size nbytes; - GrB_Index nrows, ncols, nvals; + OS_Matrix *A = (OS_Matrix *) eohptr; Assert(A->em_magic == matrix_MAGIC); if (A->flat_size) return A->flat_size; - CHECKD(GrB_Matrix_nrows(&nrows, A->M), A->M); - CHECKD(GrB_Matrix_ncols(&ncols, A->M), A->M); - CHECKD(GrB_Matrix_nvals(&nvals, A->M), A->M); - - nbytes = PGGRB_MATRIX_OVERHEAD(); - A->flat_size = nbytes; - return nbytes; + A->flat_size = OS_MATRIX_OVERHEAD(); + return A->flat_size; } /* Flatten matrix into allocated result buffer */ @@ -124,8 +55,8 @@ FN(matrix_flatten_into)(ExpandedObjectHeader *eohptr, void *result, Size allocated_size) { GrB_Info info; GrB_Index *rows, nrows, ncols, nvals; - pgGrB_Matrix *A = (pgGrB_Matrix *) eohptr; - pgGrB_FlatMatrix *flat = (pgGrB_FlatMatrix *) result; + OS_Matrix *A = (OS_Matrix *) eohptr; + OS_FlatMatrix *flat = (OS_FlatMatrix *) result; Assert(A->em_magic == matrix_MAGIC); Assert(allocated_size == A->flat_size); @@ -141,11 +72,11 @@ FN(matrix_flatten_into)(ExpandedObjectHeader *eohptr, /* Expand a flat matrix. */ Datum -FN(expand_flat_matrix)(pgGrB_FlatMatrix *flat, +FN(expand_flat_matrix)(OS_FlatMatrix *flat, MemoryContext parentcontext) { GrB_Info info; - pgGrB_Matrix *A; + OS_Matrix *A; MemoryContext objcxt, oldcxt; MemoryContextCallback *ctxcb; @@ -161,8 +92,8 @@ FN(expand_flat_matrix)(pgGrB_FlatMatrix *flat, ALLOCSET_DEFAULT_SIZES); /* Allocate a new expanded matrix */ - A = (pgGrB_Matrix*)MemoryContextAlloc(objcxt, - sizeof(pgGrB_Matrix)); + A = (OS_Matrix*)MemoryContextAlloc(objcxt, + sizeof(OS_Matrix)); /* Initialize the ExpandedObjectHeader member with flattening * methods and new object context */ @@ -192,25 +123,25 @@ FN(expand_flat_matrix)(pgGrB_FlatMatrix *flat, /* Switch back to old context */ MemoryContextSwitchTo(oldcxt); - PGGRB_RETURN_MATRIX(A); + OS_RETURN_MATRIX(A); } /* Construct an empty expanded matrix. */ -pgGrB_Matrix * +OS_Matrix * FN(construct_empty_expanded_matrix)(GrB_Index nrows, GrB_Index ncols, MemoryContext parentcontext) { - pgGrB_FlatMatrix *flat; + OS_FlatMatrix *flat; Datum d; flat = construct_empty_flat_matrix(nrows, ncols, GB_TYPE); d = FN(expand_flat_matrix)(flat, parentcontext); pfree(flat); - return (pgGrB_Matrix *) DatumGetEOHP(d); + return (OS_Matrix *) DatumGetEOHP(d); } Datum FN(matrix_empty)(PG_FUNCTION_ARGS) { - pgGrB_Matrix *retval; + OS_Matrix *retval; GrB_Index nrows, ncols; nrows = PG_GETARG_INT64(0); @@ -219,180 +150,14 @@ FN(matrix_empty)(PG_FUNCTION_ARGS) { retval = FN(construct_empty_expanded_matrix)(nrows, ncols, CurrentMemoryContext); - PGGRB_RETURN_MATRIX(retval); -} - -Datum -FN(matrix_elements)(PG_FUNCTION_ARGS) { - GrB_Info info; - FuncCallContext *funcctx; - TupleDesc tupdesc; - Datum result; - - Datum values[3]; - bool nulls[3] = {false, false, false}; - HeapTuple tuple; - GrB_Index nvals = 0; - pgGrB_Matrix *mat; - FN(pgGrB_Matrix_ExtractState) *state; - - if (SRF_IS_FIRSTCALL()) { - MemoryContext oldcontext; - - funcctx = SRF_FIRSTCALL_INIT(); - oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - mat = PGGRB_GETARG_MATRIX(0); - - state = (FN(pgGrB_Matrix_ExtractState)*)palloc(sizeof(FN(pgGrB_Matrix_ExtractState))); - CHECKD(GrB_Matrix_nvals(&nvals, mat->M), mat->M); - - state->rows = (GrB_Index*) palloc0(sizeof(GrB_Index) * nvals); - state->cols = (GrB_Index*) palloc0(sizeof(GrB_Index) * nvals); - state->vals = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * nvals); - - CHECKD(GrB_Matrix_extractTuples(state->rows, - state->cols, - state->vals, - &nvals, - mat->M), mat->M); - state->mat = mat; - funcctx->max_calls = nvals; - funcctx->user_fctx = (void*)state; - - /* One-time setup code appears here: */ - if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("function returning record called in context " - "that cannot accept type record"))); - BlessTupleDesc(tupdesc); - funcctx->tuple_desc = tupdesc; - - MemoryContextSwitchTo(oldcontext); - } - - funcctx = SRF_PERCALL_SETUP(); - state = (FN(pgGrB_Matrix_ExtractState)*)funcctx->user_fctx; - mat = state->mat; - - if (funcctx->call_cntr < funcctx->max_calls) { - values[0] = Int64GetDatum(state->rows[funcctx->call_cntr]); - values[1] = Int64GetDatum(state->cols[funcctx->call_cntr]); - values[2] = PG_TGD(state->vals[funcctx->call_cntr]); - - tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); - result = HeapTupleGetDatum(tuple); - SRF_RETURN_NEXT(funcctx, result); - } else { - SRF_RETURN_DONE(funcctx); - } + OS_RETURN_MATRIX(retval); } -Datum -FN(matrix_ewise_mult)(pgGrB_Matrix *A, - pgGrB_Matrix *B, - pgGrB_Matrix *C, - pgGrB_Matrix *mask, - GrB_BinaryOp binop, - GrB_BinaryOp accum, - GrB_Descriptor desc - ) { - GrB_Info info; - GrB_Index m, n; - - if (C == NULL) { - CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); - CHECKD(GrB_Matrix_ncols(&n, A->M), A->M); - C = FN(construct_empty_expanded_matrix)(m, n, CurrentMemoryContext); - } - CHECKD(GrB_eWiseMult(C->M, mask ? mask->M : NULL, accum, binop, A->M, B->M, desc), A->M); - PGGRB_RETURN_MATRIX(C); -} - -Datum -FN(matrix_ewise_add)(pgGrB_Matrix *A, - pgGrB_Matrix *B, - pgGrB_Matrix *C, - pgGrB_Matrix *mask, - GrB_BinaryOp binop, - GrB_BinaryOp accum, - GrB_Descriptor desc - ) { - GrB_Info info; - GrB_Index m, n; - - if (C == NULL) { - CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); - CHECKD(GrB_Matrix_ncols(&n, A->M), A->M); - C = FN(construct_empty_expanded_matrix)(m, n, CurrentMemoryContext); - } - - CHECKD(GrB_eWiseAdd(C->M, mask ? mask->M : NULL, accum, binop, A->M, B->M, desc), A->M); - PGGRB_RETURN_MATRIX(C); -} - -Datum -FN(mxm)(pgGrB_Matrix *A, - pgGrB_Matrix *B, - pgGrB_Matrix *C, - pgGrB_Matrix *mask, - GrB_Semiring semiring, - GrB_BinaryOp binop, - GrB_Descriptor desc) { - GrB_Info info; - - if (C == NULL) { - GrB_Index m, n; - CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); - CHECKD(GrB_Matrix_ncols(&n, B->M), A->M); - C = FN(construct_empty_expanded_matrix)(m, n, CurrentMemoryContext); - } - CHECKD(GrB_mxm(C->M, mask ? mask->M : NULL, binop, semiring, A->M, B->M, desc), A->M); - PGGRB_RETURN_MATRIX(C); -} - -Datum -FN(mxv)(pgGrB_Matrix *A, - pgGrB_Vector *B, - pgGrB_Vector *C, - pgGrB_Vector *mask, - GrB_Semiring semiring, - GrB_BinaryOp binop, - GrB_Descriptor desc) { - GrB_Info info; - GrB_Index size; - - if (C == NULL) { - CHECKD(GrB_Matrix_ncols(&size, A->M), A->M); - C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); - } - CHECKD(GrB_mxv(C->V, mask ? mask->V : NULL, binop, semiring, A->M, B->V, desc), A->M); - PGGRB_RETURN_VECTOR(C); -} - -Datum -FN(vxm)(pgGrB_Vector *A, - pgGrB_Matrix *B, - pgGrB_Vector *C, - pgGrB_Vector *mask, - GrB_Semiring semiring, - GrB_BinaryOp binop, - GrB_Descriptor desc) { - GrB_Info info; - GrB_Index size; - - if (C == NULL) { - CHECKD(GrB_Vector_size(&size, A->V), A->V); - C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); - } - CHECKD(GrB_vxm(C->V, mask ? mask->V : NULL, binop, semiring, A->V, B->M, desc), A->V); - PGGRB_RETURN_VECTOR(C); -} Datum FN(matrix)(PG_FUNCTION_ARGS) { GrB_Info info; - pgGrB_Matrix *retval; + OS_Matrix *retval; ArrayType *rows, *cols, *vals; int *idims, *jdims, *vdims; int i, count; @@ -410,7 +175,7 @@ FN(matrix)(PG_FUNCTION_ARGS) { retval = FN(construct_empty_expanded_matrix)(max_row_index, max_col_index, CurrentMemoryContext); - PGGRB_RETURN_MATRIX(retval); + OS_RETURN_MATRIX(retval); } rows = PG_GETARG_ARRAYTYPE_P(0); @@ -485,124 +250,10 @@ FN(matrix)(PG_FUNCTION_ARGS) { count, GB_DUP), retval->M); - PGGRB_RETURN_MATRIX(retval); + OS_RETURN_MATRIX(retval); } -Datum -FN(matrix_reduce)(PG_FUNCTION_ARGS) { - GrB_Info info; - GrB_Type type; - pgGrB_Matrix *A; - GrB_Semiring semiring; - GrB_Monoid monoid; - char *semiring_name; - PG_TYPE val; - - A = PGGRB_GETARG_MATRIX(0); - semiring_name = PG_ARGISNULL(1)? - NULL: - text_to_cstring(PG_GETARG_TEXT_PP(1)); - - if (semiring_name == NULL) { - CHECKD(GxB_Matrix_type(&type, A->M), A->M); - semiring_name = DEFAULT_SEMIRING(type); - } - semiring = lookup_semiring(semiring_name); - CHECKD(GxB_Semiring_add(&monoid, semiring), A->M); - CHECKD(GrB_reduce(&val, NULL, monoid, A->M, NULL), A->M); - PG_RET(val); -} - -GrB_Index FN(extract_rowscols)(pgGrB_Matrix *A, - GrB_Index **rows, - GrB_Index **cols, - GrB_Index nvals) { - PG_TYPE *values; - GrB_Info info; - - *rows = (GrB_Index*) palloc0(sizeof(GrB_Index) * nvals); - *cols = (GrB_Index*) palloc0(sizeof(GrB_Index) * nvals); - values = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * nvals); - - CHECKD(GrB_Matrix_extractTuples(*rows, - *cols, - values, - &nvals, - A->M), A->M); - return nvals; -} - -Datum -FN(matrix_assign)(PG_FUNCTION_ARGS) { - GrB_Info info; - pgGrB_Matrix *A, *B=NULL, *mask=NULL; - GrB_Index nrows, ncols, nvals; - GrB_Index *rows = NULL, *cols = NULL; - PG_TYPE val; - - A = PGGRB_GETARG_MATRIX(0); - val = PG_GET(1); - B = PG_ARGISNULL(2) ? NULL : PGGRB_GETARG_MATRIX(2); - mask = PG_ARGISNULL(3)? NULL : PGGRB_GETARG_MATRIX(3); - - if (B != NULL) { - CHECKD(GrB_Matrix_nvals(&nvals, B->M), A->M); - nrows = ncols = nvals = FN(extract_rowscols)(B, &rows, &cols, nvals); - } else { - CHECKD(GrB_Matrix_nrows(&nrows, A->M), A->M); - CHECKD(GrB_Matrix_ncols(&ncols, A->M), A->M); - } - - CHECKD(GrB_assign(A->M, - mask? mask->M: NULL, - NULL, - val, - rows?rows:GrB_ALL, - nrows, - cols?cols:GrB_ALL, - ncols, - NULL), A->M); - - PGGRB_RETURN_MATRIX(A); -} - -Datum -FN(matrix_kron)(pgGrB_Matrix *A, - pgGrB_Matrix *B, - pgGrB_Matrix *C, - pgGrB_Matrix *mask, - GrB_BinaryOp accum, - GrB_BinaryOp mulop, - GrB_Descriptor desc) { - GrB_Info info; - - if (C == NULL) { - GrB_Index m, n, p, q; - CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); - CHECKD(GrB_Matrix_ncols(&n, A->M), A->M); - CHECKD(GrB_Matrix_nrows(&p, B->M), B->M); - CHECKD(GrB_Matrix_ncols(&q, B->M), B->M); - C = FN(construct_empty_expanded_matrix)(m*p, n*q, CurrentMemoryContext); - } - CHECKD(GxB_kron(C->M, mask ? mask->M : NULL, accum, mulop, A->M, B->M, desc), A->M); - PGGRB_RETURN_MATRIX(C); -} - -Datum -FN(matrix_set_element)(PG_FUNCTION_ARGS) { - GrB_Info info; - pgGrB_Matrix *A; - GrB_Index row, col; - PG_TYPE val; - - A = PGGRB_GETARG_MATRIX(0); - row = PG_GETARG_INT64(1); - col = PG_GETARG_INT64(2); - val = PG_GET(3); - - CHECKD(GrB_Matrix_setElement(A->M, val, row, col), A->M); - PGGRB_RETURN_MATRIX(A); -} +#include "matrix_ops.h" #undef SUFFIX #undef PG_TYPE diff --git a/src/matrix_ops.h b/src/matrix_ops.h new file mode 100644 index 0000000..354a3b8 --- /dev/null +++ b/src/matrix_ops.h @@ -0,0 +1,346 @@ +GrB_Index FN(extract_rowscols)(OS_Matrix *A, + GrB_Index **rows, + GrB_Index **cols, + GrB_Index nvals); + +Datum FN(matrix_ewise_mult)(OS_Matrix *A, + OS_Matrix *B, + OS_Matrix *C, + OS_Matrix *mask, + GrB_BinaryOp binop, + GrB_BinaryOp accum, + GrB_Descriptor desc); + +Datum FN(matrix_ewise_add)(OS_Matrix *A, + OS_Matrix *B, + OS_Matrix *C, + OS_Matrix *mask, + GrB_BinaryOp binop, + GrB_BinaryOp accum, + GrB_Descriptor desc); + +Datum +FN(mxm)(OS_Matrix *A, + OS_Matrix *B, + OS_Matrix *C, + OS_Matrix *mask, + GrB_Semiring semiring, + GrB_BinaryOp binop, + GrB_Descriptor desc); + +Datum +FN(matrix_kron)(OS_Matrix *A, + OS_Matrix *B, + OS_Matrix *C, + OS_Matrix *mask, + GrB_BinaryOp accum, + GrB_BinaryOp mulop, + GrB_Descriptor desc); + +Datum +FN(mxv)(OS_Matrix *A, + OS_Vector *B, + OS_Vector *C, + OS_Vector *mask, + GrB_Semiring semiring, + GrB_BinaryOp binop, + GrB_Descriptor desc); + +Datum +FN(vxm)(OS_Vector *A, + OS_Matrix *B, + OS_Vector *C, + OS_Vector *mask, + GrB_Semiring semiring, + GrB_BinaryOp binop, + GrB_Descriptor desc); + + +PG_FUNCTION_INFO_V1(FN(matrix_elements)); +PG_FUNCTION_INFO_V1(FN(matrix_reduce)); +PG_FUNCTION_INFO_V1(FN(matrix_assign)); +PG_FUNCTION_INFO_V1(FN(matrix_random)); +PG_FUNCTION_INFO_V1(FN(matrix_set_element)); + +Datum +FN(matrix_elements)(PG_FUNCTION_ARGS) { + GrB_Info info; + FuncCallContext *funcctx; + TupleDesc tupdesc; + Datum result; + + Datum values[3]; + bool nulls[3] = {false, false, false}; + HeapTuple tuple; + GrB_Index nvals = 0; + OS_Matrix *mat; + FN(OS_Matrix_ExtractState) *state; + + if (SRF_IS_FIRSTCALL()) { + MemoryContext oldcontext; + + funcctx = SRF_FIRSTCALL_INIT(); + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + mat = OS_GETARG_MATRIX(0); + + state = (FN(OS_Matrix_ExtractState)*)palloc(sizeof(FN(OS_Matrix_ExtractState))); + CHECKD(GrB_Matrix_nvals(&nvals, mat->M), mat->M); + + state->rows = (GrB_Index*) palloc0(sizeof(GrB_Index) * nvals); + state->cols = (GrB_Index*) palloc0(sizeof(GrB_Index) * nvals); + state->vals = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * nvals); + + CHECKD(GrB_Matrix_extractTuples(state->rows, + state->cols, + state->vals, + &nvals, + mat->M), mat->M); + state->mat = mat; + funcctx->max_calls = nvals; + funcctx->user_fctx = (void*)state; + + /* One-time setup code appears here: */ + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("function returning record called in context " + "that cannot accept type record"))); + BlessTupleDesc(tupdesc); + funcctx->tuple_desc = tupdesc; + + MemoryContextSwitchTo(oldcontext); + } + + funcctx = SRF_PERCALL_SETUP(); + state = (FN(OS_Matrix_ExtractState)*)funcctx->user_fctx; + mat = state->mat; + + if (funcctx->call_cntr < funcctx->max_calls) { + values[0] = Int64GetDatum(state->rows[funcctx->call_cntr]); + values[1] = Int64GetDatum(state->cols[funcctx->call_cntr]); + values[2] = PG_TGD(state->vals[funcctx->call_cntr]); + + tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); + result = HeapTupleGetDatum(tuple); + SRF_RETURN_NEXT(funcctx, result); + } else { + SRF_RETURN_DONE(funcctx); + } +} + +Datum +FN(matrix_ewise_mult)(OS_Matrix *A, + OS_Matrix *B, + OS_Matrix *C, + OS_Matrix *mask, + GrB_BinaryOp binop, + GrB_BinaryOp accum, + GrB_Descriptor desc + ) { + GrB_Info info; + GrB_Index m, n; + + if (C == NULL) { + CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&n, A->M), A->M); + C = FN(construct_empty_expanded_matrix)(m, n, CurrentMemoryContext); + } + CHECKD(GrB_eWiseMult(C->M, mask ? mask->M : NULL, accum, binop, A->M, B->M, desc), A->M); + OS_RETURN_MATRIX(C); +} + +Datum +FN(matrix_ewise_add)(OS_Matrix *A, + OS_Matrix *B, + OS_Matrix *C, + OS_Matrix *mask, + GrB_BinaryOp binop, + GrB_BinaryOp accum, + GrB_Descriptor desc + ) { + GrB_Info info; + GrB_Index m, n; + + if (C == NULL) { + CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&n, A->M), A->M); + C = FN(construct_empty_expanded_matrix)(m, n, CurrentMemoryContext); + } + + CHECKD(GrB_eWiseAdd(C->M, mask ? mask->M : NULL, accum, binop, A->M, B->M, desc), A->M); + OS_RETURN_MATRIX(C); +} + +Datum +FN(mxm)(OS_Matrix *A, + OS_Matrix *B, + OS_Matrix *C, + OS_Matrix *mask, + GrB_Semiring semiring, + GrB_BinaryOp binop, + GrB_Descriptor desc) { + GrB_Info info; + + if (C == NULL) { + GrB_Index m, n; + CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&n, B->M), A->M); + C = FN(construct_empty_expanded_matrix)(m, n, CurrentMemoryContext); + } + CHECKD(GrB_mxm(C->M, mask ? mask->M : NULL, binop, semiring, A->M, B->M, desc), A->M); + OS_RETURN_MATRIX(C); +} + +Datum +FN(mxv)(OS_Matrix *A, + OS_Vector *B, + OS_Vector *C, + OS_Vector *mask, + GrB_Semiring semiring, + GrB_BinaryOp binop, + GrB_Descriptor desc) { + GrB_Info info; + GrB_Index size; + + if (C == NULL) { + CHECKD(GrB_Matrix_ncols(&size, A->M), A->M); + C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); + } + CHECKD(GrB_mxv(C->V, mask ? mask->V : NULL, binop, semiring, A->M, B->V, desc), A->M); + OS_RETURN_VECTOR(C); +} + +Datum +FN(vxm)(OS_Vector *A, + OS_Matrix *B, + OS_Vector *C, + OS_Vector *mask, + GrB_Semiring semiring, + GrB_BinaryOp binop, + GrB_Descriptor desc) { + GrB_Info info; + GrB_Index size; + + if (C == NULL) { + CHECKD(GrB_Vector_size(&size, A->V), A->V); + C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); + } + CHECKD(GrB_vxm(C->V, mask ? mask->V : NULL, binop, semiring, A->V, B->M, desc), A->V); + OS_RETURN_VECTOR(C); +} + +Datum +FN(matrix_reduce)(PG_FUNCTION_ARGS) { + GrB_Info info; + GrB_Type type; + OS_Matrix *A; + GrB_Semiring semiring; + GrB_Monoid monoid; + char *semiring_name; + PG_TYPE val; + + A = OS_GETARG_MATRIX(0); + semiring_name = PG_ARGISNULL(1)? + NULL: + text_to_cstring(PG_GETARG_TEXT_PP(1)); + + if (semiring_name == NULL) { + CHECKD(GxB_Matrix_type(&type, A->M), A->M); + semiring_name = DEFAULT_SEMIRING(type); + } + semiring = lookup_semiring(semiring_name); + CHECKD(GxB_Semiring_add(&monoid, semiring), A->M); + CHECKD(GrB_reduce(&val, NULL, monoid, A->M, NULL), A->M); + PG_RET(val); +} + +GrB_Index FN(extract_rowscols)(OS_Matrix *A, + GrB_Index **rows, + GrB_Index **cols, + GrB_Index nvals) { + PG_TYPE *values; + GrB_Info info; + + *rows = (GrB_Index*) palloc0(sizeof(GrB_Index) * nvals); + *cols = (GrB_Index*) palloc0(sizeof(GrB_Index) * nvals); + values = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * nvals); + + CHECKD(GrB_Matrix_extractTuples(*rows, + *cols, + values, + &nvals, + A->M), A->M); + return nvals; +} + +Datum +FN(matrix_assign)(PG_FUNCTION_ARGS) { + GrB_Info info; + OS_Matrix *A, *B=NULL, *mask=NULL; + GrB_Index nrows, ncols, nvals; + GrB_Index *rows = NULL, *cols = NULL; + PG_TYPE val; + + A = OS_GETARG_MATRIX(0); + val = PG_GET(1); + B = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(2); + mask = PG_ARGISNULL(3)? NULL : OS_GETARG_MATRIX(3); + + if (B != NULL) { + CHECKD(GrB_Matrix_nvals(&nvals, B->M), A->M); + nrows = ncols = nvals = FN(extract_rowscols)(B, &rows, &cols, nvals); + } else { + CHECKD(GrB_Matrix_nrows(&nrows, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&ncols, A->M), A->M); + } + + CHECKD(GrB_assign(A->M, + mask? mask->M: NULL, + NULL, + val, + rows?rows:GrB_ALL, + nrows, + cols?cols:GrB_ALL, + ncols, + NULL), A->M); + + OS_RETURN_MATRIX(A); +} + +Datum +FN(matrix_kron)(OS_Matrix *A, + OS_Matrix *B, + OS_Matrix *C, + OS_Matrix *mask, + GrB_BinaryOp accum, + GrB_BinaryOp mulop, + GrB_Descriptor desc) { + GrB_Info info; + + if (C == NULL) { + GrB_Index m, n, p, q; + CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&n, A->M), A->M); + CHECKD(GrB_Matrix_nrows(&p, B->M), B->M); + CHECKD(GrB_Matrix_ncols(&q, B->M), B->M); + C = FN(construct_empty_expanded_matrix)(m*p, n*q, CurrentMemoryContext); + } + CHECKD(GxB_kron(C->M, mask ? mask->M : NULL, accum, mulop, A->M, B->M, desc), A->M); + OS_RETURN_MATRIX(C); +} + +Datum +FN(matrix_set_element)(PG_FUNCTION_ARGS) { + GrB_Info info; + OS_Matrix *A; + GrB_Index row, col; + PG_TYPE val; + + A = OS_GETARG_MATRIX(0); + row = PG_GETARG_INT64(1); + col = PG_GETARG_INT64(2); + val = PG_GET(3); + + CHECKD(GrB_Matrix_setElement(A->M, val, row, col), A->M); + OS_RETURN_MATRIX(A); +} diff --git a/src/onesparse.c b/src/onesparse.c index ba0b749..c77d4a6 100644 --- a/src/onesparse.c +++ b/src/onesparse.c @@ -1,9 +1,9 @@ #include "onesparse.h" PG_MODULE_MAGIC; -pgGrB_Semiring semirings[960]; -pgGrB_BinaryOp binops[256]; -pgGrB_UnaryOp uops[67]; +OS_Semiring semirings[960]; +OS_BinaryOp binops[256]; +OS_UnaryOp uops[67]; MemoryContext gb_context; #include "type.c" diff --git a/src/onesparse.h b/src/onesparse.h index 0de006f..af4cdbe 100644 --- a/src/onesparse.h +++ b/src/onesparse.h @@ -14,6 +14,7 @@ #include "utils/lsyscache.h" #include "nodes/pg_list.h" #include "utils/varlena.h" +#include "libpq/libpq-fs.h" #define CCAT2(x, y) x ## y #define CCAT(x, y) CCAT2(x, y) @@ -153,13 +154,13 @@ GrB_Info visequal /* Flattened representation of matrix, used to store to disk. */ -typedef struct pgGrB_FlatMatrix { +typedef struct OS_FlatMatrix { int32 vl_len_; GrB_Index nrows; GrB_Index ncols; GrB_Index nvals; GrB_Type type; -} pgGrB_FlatMatrix; +} OS_FlatMatrix; /* ID for debugging crosschecks */ #define matrix_MAGIC 689276813 @@ -169,13 +170,13 @@ typedef struct pgGrB_FlatMatrix { When loaded from storage, the flattened representation is used to build the matrix with GrB_Matrix_build. */ -typedef struct pgGrB_Matrix { +typedef struct OS_Matrix { ExpandedObjectHeader hdr; int em_magic; GrB_Type type; GrB_Matrix M; Size flat_size; -} pgGrB_Matrix; +} OS_Matrix; /* helper to turn types into names. */ char* grb_type_to_name(GrB_Type t); @@ -186,25 +187,22 @@ static void context_callback_matrix_free(void*); /* Helper function that either detoasts or expands matrices. */ -pgGrB_Matrix* DatumGetMatrix(Datum d); +OS_Matrix* DatumGetMatrix(Datum d); /* Helper function to create an empty flattened matrix. */ -pgGrB_FlatMatrix * +OS_FlatMatrix * construct_empty_flat_matrix(GrB_Index nrows, GrB_Index ncols, GrB_Type type); /* Helper to detoast and expand matrix arguments */ -#define PGGRB_GETARG_MATRIX(n) DatumGetMatrix(PG_GETARG_DATUM(n)) +#define OS_GETARG_MATRIX(n) DatumGetMatrix(PG_GETARG_DATUM(n)) /* Helper to return Expanded Object Header Pointer from matrix. */ -#define PGGRB_RETURN_MATRIX(A) return EOHPGetRWDatum(&(A)->hdr) +#define OS_RETURN_MATRIX(A) return EOHPGetRWDatum(&(A)->hdr) /* Helper to compute flat matrix header size */ -#define PGGRB_MATRIX_OVERHEAD() MAXALIGN(sizeof(pgGrB_FlatMatrix)) - -/* pointer to beginning of matrix data. */ -#define PGGRB_MATRIX_DATA(a) ((GrB_Index *)(((char *) (a)) + PGGRB_MATRIX_OVERHEAD())) +#define OS_MATRIX_OVERHEAD() MAXALIGN(sizeof(OS_FlatMatrix)) /* Public API functions */ @@ -241,12 +239,12 @@ PG_FUNCTION_INFO_V1(matrix_bfs); Actual array data is appended and for the moment cannot exceed 1GB. */ -typedef struct pgGrB_FlatVector { +typedef struct OS_FlatVector { int32 vl_len_; GrB_Index size; GrB_Index nvals; GrB_Type type; -} pgGrB_FlatVector; +} OS_FlatVector; /* ID for debugging crosschecks */ #define vector_MAGIC 681276813 @@ -256,53 +254,52 @@ typedef struct pgGrB_FlatVector { When loaded from storage, the flattened representation is used to build the vector with GrB_Vector_build. */ -typedef struct pgGrB_Vector { +typedef struct OS_Vector { ExpandedObjectHeader hdr; int ev_magic; GrB_Type type; GrB_Vector V; Size flat_size; -} pgGrB_Vector; +} OS_Vector; static void context_callback_vector_free(void*); /* Helper function that either detoasts or expands vectors. */ -pgGrB_Vector* DatumGetVector(Datum d); +OS_Vector* DatumGetVector(Datum d); /* Helper function to create an empty flattened vector. */ -pgGrB_FlatVector* construct_empty_flat_vector(GrB_Index size, GrB_Type type); +OS_FlatVector* construct_empty_flat_vector(GrB_Index size, GrB_Type type); -GrB_Type mxm_type(pgGrB_Matrix *left, pgGrB_Matrix *right); -GrB_Type mxv_type(pgGrB_Matrix *left, pgGrB_Vector *right); -GrB_Type vxm_type(pgGrB_Vector *left, pgGrB_Matrix *right); +GrB_Type mxm_type(OS_Matrix *left, OS_Matrix *right); +GrB_Type mxv_type(OS_Matrix *left, OS_Vector *right); +GrB_Type vxm_type(OS_Vector *left, OS_Matrix *right); /* function to choose implicit semirings for overloaded operators */ -char* mxm_semiring(pgGrB_Matrix *left, pgGrB_Matrix *right); -char* mxv_semiring(pgGrB_Matrix *left, pgGrB_Vector *right); -char* vxm_semiring(pgGrB_Vector *left, pgGrB_Matrix *right); +char* mxm_semiring(OS_Matrix *left, OS_Matrix *right); +char* mxv_semiring(OS_Matrix *left, OS_Vector *right); +char* vxm_semiring(OS_Vector *left, OS_Matrix *right); -char* matrix_times_binop(pgGrB_Matrix *left, pgGrB_Matrix *right); -char* matrix_plus_binop(pgGrB_Matrix *left, pgGrB_Matrix *right); +char* matrix_times_binop(OS_Matrix *left, OS_Matrix *right); +char* matrix_plus_binop(OS_Matrix *left, OS_Matrix *right); -char* vector_times_binop(pgGrB_Vector *left, pgGrB_Vector *right); -char* vector_plus_binop(pgGrB_Vector *left, pgGrB_Vector *right); +char* vector_times_binop(OS_Vector *left, OS_Vector *right); +char* vector_plus_binop(OS_Vector *left, OS_Vector *right); GrB_Semiring lookup_semiring(char *name); GrB_BinaryOp lookup_binop(char *name); -#define VectorGetEOHP(d) (pgGrB_Vector *) DatumGetEOHP(d) -#define MatrixGetEOHP(d) (pgGrB_Matrix *) DatumGetEOHP(d); +#define VectorGetEOHP(d) (OS_Vector *) DatumGetEOHP(d) +#define MatrixGetEOHP(d) (OS_Matrix *) DatumGetEOHP(d); /* Helper to detoast and expand vector arguments */ -#define PGGRB_GETARG_VECTOR(n) DatumGetVector(PG_GETARG_DATUM(n)) +#define OS_GETARG_VECTOR(n) DatumGetVector(PG_GETARG_DATUM(n)) /* Helper to return Expanded Object Header Pointer from vector. */ -#define PGGRB_RETURN_VECTOR(A) return EOHPGetRWDatum(&(A)->hdr) +#define OS_RETURN_VECTOR(A) return EOHPGetRWDatum(&(A)->hdr) /* Helper to compute flat vector header size */ -#define PGGRB_VECTOR_OVERHEAD() MAXALIGN(sizeof(pgGrB_FlatVector)) +#define OS_VECTOR_OVERHEAD() MAXALIGN(sizeof(OS_FlatVector)) -#define PGGRB_VECTOR_DATA(a) ((GrB_Index *)(((char *) (a)) + PGGRB_VECTOR_OVERHEAD())) PG_FUNCTION_INFO_V1(vector_in); PG_FUNCTION_INFO_V1(vector_out); @@ -319,20 +316,20 @@ PG_FUNCTION_INFO_V1(vector_size); PG_FUNCTION_INFO_V1(vector_xtract); PG_FUNCTION_INFO_V1(vector_print); -typedef struct pgGrB_Semiring { +typedef struct OS_Semiring { char name[255]; GrB_Semiring R; -} pgGrB_Semiring; +} OS_Semiring; -typedef struct pgGrB_BinaryOp { +typedef struct OS_BinaryOp { char name[255]; GrB_BinaryOp B; -} pgGrB_BinaryOp; +} OS_BinaryOp; -typedef struct pgGrB_UnaryOp { +typedef struct OS_UnaryOp { char name[255]; GrB_UnaryOp U; -} pgGrB_UnaryOp; +} OS_UnaryOp; #define SEMIRING(N, PLS, TMS, TYP) do { \ strlcpy(semirings[(N)].name, #PLS #TMS #TYP, 255); \ diff --git a/src/type.c b/src/type.c index ee41e19..903682b 100644 --- a/src/type.c +++ b/src/type.c @@ -15,7 +15,7 @@ GrB_BinaryOp lookup_binop(char *name) { return NULL; } -GrB_Type mxm_type(pgGrB_Matrix *left, pgGrB_Matrix *right) { +GrB_Type mxm_type(OS_Matrix *left, OS_Matrix *right) { GrB_Info info; GrB_Type atype, btype; CHECKD(GxB_Matrix_type(&atype, left->M), left->M); @@ -29,7 +29,7 @@ GrB_Type mxm_type(pgGrB_Matrix *left, pgGrB_Matrix *right) { return NULL; } -GrB_Type mxv_type(pgGrB_Matrix *left, pgGrB_Vector *right) { +GrB_Type mxv_type(OS_Matrix *left, OS_Vector *right) { GrB_Info info; GrB_Type atype, btype; CHECKD(GxB_Matrix_type(&atype, left->M), left->M); @@ -43,7 +43,7 @@ GrB_Type mxv_type(pgGrB_Matrix *left, pgGrB_Vector *right) { return NULL; } -GrB_Type vxm_type(pgGrB_Vector *left, pgGrB_Matrix *right) { +GrB_Type vxm_type(OS_Vector *left, OS_Matrix *right) { GrB_Info info; GrB_Type atype, btype; CHECKD(GxB_Vector_type(&atype, left->V), left->V); @@ -57,7 +57,7 @@ GrB_Type vxm_type(pgGrB_Vector *left, pgGrB_Matrix *right) { return NULL; } -char* mxm_semiring(pgGrB_Matrix *left, pgGrB_Matrix *right) { +char* mxm_semiring(OS_Matrix *left, OS_Matrix *right) { GrB_Info info; GrB_Type atype, btype; CHECKD(GxB_Matrix_type(&atype, left->M), left->M); @@ -71,7 +71,7 @@ char* mxm_semiring(pgGrB_Matrix *left, pgGrB_Matrix *right) { return ""; } -char* mxv_semiring(pgGrB_Matrix *left, pgGrB_Vector *right) { +char* mxv_semiring(OS_Matrix *left, OS_Vector *right) { GrB_Info info; GrB_Type atype, btype; CHECKD(GxB_Matrix_type(&atype, left->M), left->M); @@ -85,7 +85,7 @@ char* mxv_semiring(pgGrB_Matrix *left, pgGrB_Vector *right) { return ""; } -char* vxm_semiring(pgGrB_Vector *left, pgGrB_Matrix *right) { +char* vxm_semiring(OS_Vector *left, OS_Matrix *right) { GrB_Info info; GrB_Type atype, btype; CHECKD(GxB_Vector_type(&atype, left->V), left->V); @@ -100,28 +100,28 @@ char* vxm_semiring(pgGrB_Vector *left, pgGrB_Matrix *right) { } -char* matrix_times_binop(pgGrB_Matrix *left, pgGrB_Matrix *right) { +char* matrix_times_binop(OS_Matrix *left, OS_Matrix *right) { GrB_Info info; GrB_Type type; CHECKD(GxB_Matrix_type(&type, left->M), left->M); return DEFAULT_TIMES_BINOP(type); } -char* matrix_plus_binop(pgGrB_Matrix *left, pgGrB_Matrix *right) { +char* matrix_plus_binop(OS_Matrix *left, OS_Matrix *right) { GrB_Info info; GrB_Type type; CHECKD(GxB_Matrix_type(&type, left->M), left->M); return DEFAULT_PLUS_BINOP(type); } -char* vector_times_binop(pgGrB_Vector *left, pgGrB_Vector *right) { +char* vector_times_binop(OS_Vector *left, OS_Vector *right) { GrB_Info info; GrB_Type type; CHECKD(GxB_Vector_type(&type, left->V), left->V); return DEFAULT_TIMES_BINOP(type); } -char* vector_plus_binop(pgGrB_Vector *left, pgGrB_Vector *right) { +char* vector_plus_binop(OS_Vector *left, OS_Vector *right) { GrB_Info info; GrB_Type type; CHECKD(GxB_Vector_type(&type, left->V), left->V); @@ -160,12 +160,12 @@ char* grb_type_to_name(GrB_Type t) { /* {"GxB_" #add #mul "INT32", GxB_ ## add ## mul ## INT32}, \ */ /* {"GxB_" #add #mul "INT64", GxB_ ## add ## mul ## INT64}, \ */ -/* struct pgGrB_Semiring */ +/* struct OS_Semiring */ /* { */ /* const char* name; */ /* GrB_Semiring semiring; */ /* } */ -/* pgGrB_Semiring[] = */ +/* OS_Semiring[] = */ /* { */ /* SEMIRING(PLUS_, TIMES_); */ /* {"setinel", NULL} */ diff --git a/src/vector.c b/src/vector.c index ca929d5..65f6ea7 100644 --- a/src/vector.c +++ b/src/vector.c @@ -117,17 +117,17 @@ /* MemoryContextCallback function to free matrices */ static void context_callback_vector_free(void* a) { - pgGrB_Vector *A = (pgGrB_Vector *) a; + OS_Vector *A = (OS_Vector *) a; GrB_Vector_free(&A->V); } /* Construct an empty flat vector. */ -pgGrB_FlatVector * +OS_FlatVector * construct_empty_flat_vector(GrB_Index size, GrB_Type type) { - pgGrB_FlatVector *result; + OS_FlatVector *result; - result = (pgGrB_FlatVector *) palloc0(sizeof(pgGrB_FlatVector)); - SET_VARSIZE(result, sizeof(pgGrB_FlatVector)); + result = (OS_FlatVector *) palloc0(sizeof(OS_FlatVector)); + SET_VARSIZE(result, sizeof(OS_FlatVector)); result->size = size; result->nvals = 0; result->type = type; @@ -136,18 +136,18 @@ construct_empty_flat_vector(GrB_Index size, GrB_Type type) { /* Helper function to always expanded datum -This is used by PGGRB_GETARG_VECTOR */ -pgGrB_Vector * +This is used by OS_GETARG_VECTOR */ +OS_Vector * DatumGetVector(Datum d) { - pgGrB_Vector *A; - pgGrB_FlatVector *flat; + OS_Vector *A; + OS_FlatVector *flat; if (VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(d))) { A = VectorGetEOHP(d); Assert(A->ev_magic == vector_MAGIC); return A; } - flat = (pgGrB_FlatVector*)PG_DETOAST_DATUM(d); + flat = (OS_FlatVector*)PG_DETOAST_DATUM(d); TYPE_APPLY(d, flat->type, expand_flat_vector, flat, CurrentMemoryContext); return VectorGetEOHP(d); } @@ -155,7 +155,7 @@ DatumGetVector(Datum d) { Datum vector_in(PG_FUNCTION_ARGS) { - pgGrB_FlatVector *flat; + OS_FlatVector *flat; char *input; size_t len; int bc; @@ -175,7 +175,7 @@ vector_out(PG_FUNCTION_ARGS) { Size size; char *rp, *result, *buf; - pgGrB_Vector *A = PGGRB_GETARG_VECTOR(0); + OS_Vector *A = OS_GETARG_VECTOR(0); size = EOH_get_flat_size(&A->hdr); buf = palloc(size); EOH_flatten_into(&A->hdr, buf, size); @@ -187,23 +187,23 @@ vector_out(PG_FUNCTION_ARGS) Datum vector_ewise_mult(PG_FUNCTION_ARGS) { - pgGrB_Vector *A, *B; - pgGrB_Vector *C = NULL, *mask = NULL; + OS_Vector *A, *B; + OS_Vector *C = NULL, *mask = NULL; Datum d; char *binop_name, *accum_name; GrB_BinaryOp binop = NULL, accum = NULL; GrB_Descriptor desc = NULL; GrB_Info info; - A = PGGRB_GETARG_VECTOR(0); - B = PGGRB_GETARG_VECTOR(1); + A = OS_GETARG_VECTOR(0); + B = OS_GETARG_VECTOR(1); accum_name = NULL; binop_name = vector_times_binop(A, B); if (PG_NARGS() > 2) { - C = PG_ARGISNULL(2) ? NULL : PGGRB_GETARG_VECTOR(2); - mask = PG_ARGISNULL(3) ? NULL : PGGRB_GETARG_VECTOR(3); + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_VECTOR(2); + mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_VECTOR(3); binop_name = PG_ARGISNULL(4) ? binop_name : text_to_cstring(PG_GETARG_TEXT_PP(4)); accum_name = PG_ARGISNULL(5) ? @@ -226,23 +226,23 @@ vector_ewise_mult(PG_FUNCTION_ARGS) { Datum vector_ewise_add(PG_FUNCTION_ARGS) { - pgGrB_Vector *A, *B; - pgGrB_Vector *C = NULL, *mask = NULL; + OS_Vector *A, *B; + OS_Vector *C = NULL, *mask = NULL; Datum d; char *binop_name, *accum_name; GrB_BinaryOp binop = NULL, accum = NULL; GrB_Descriptor desc = NULL; GrB_Info info; - A = PGGRB_GETARG_VECTOR(0); - B = PGGRB_GETARG_VECTOR(1); + A = OS_GETARG_VECTOR(0); + B = OS_GETARG_VECTOR(1); accum_name = NULL; binop_name = vector_times_binop(A, B); if (PG_NARGS() > 2) { - C = PG_ARGISNULL(2) ? NULL : PGGRB_GETARG_VECTOR(2); - mask = PG_ARGISNULL(3) ? NULL : PGGRB_GETARG_VECTOR(3); + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_VECTOR(2); + mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_VECTOR(3); binop_name = PG_ARGISNULL(4) ? binop_name : text_to_cstring(PG_GETARG_TEXT_PP(4)); accum_name = PG_ARGISNULL(5) ? @@ -266,9 +266,9 @@ vector_ewise_add(PG_FUNCTION_ARGS) { Datum vector_nvals(PG_FUNCTION_ARGS) { GrB_Info info; - pgGrB_Vector *vec; + OS_Vector *vec; GrB_Index nvals; - vec = PGGRB_GETARG_VECTOR(0); + vec = OS_GETARG_VECTOR(0); CHECKD(GrB_Vector_nvals(&nvals, vec->V), vec->V); return Int64GetDatum(nvals); } @@ -276,9 +276,9 @@ vector_nvals(PG_FUNCTION_ARGS) { Datum vector_size(PG_FUNCTION_ARGS) { GrB_Info info; - pgGrB_Vector *vec; + OS_Vector *vec; GrB_Index size; - vec = PGGRB_GETARG_VECTOR(0); + vec = OS_GETARG_VECTOR(0); CHECKD(GrB_Vector_size(&size, vec->V), vec->V); return Int64GetDatum(size); } @@ -287,11 +287,11 @@ vector_size(PG_FUNCTION_ARGS) { Datum vector_eq(PG_FUNCTION_ARGS) { GrB_Info info; - pgGrB_Vector *A, *B; + OS_Vector *A, *B; bool result; - A = PGGRB_GETARG_VECTOR(0); - B = PGGRB_GETARG_VECTOR(1); + A = OS_GETARG_VECTOR(0); + B = OS_GETARG_VECTOR(1); result = true; PG_RETURN_BOOL(result); @@ -300,11 +300,11 @@ vector_eq(PG_FUNCTION_ARGS) { Datum vector_ne(PG_FUNCTION_ARGS) { GrB_Info info; - pgGrB_Vector *A, *B; + OS_Vector *A, *B; bool result; - A = PGGRB_GETARG_VECTOR(0); - B = PGGRB_GETARG_VECTOR(1); + A = OS_GETARG_VECTOR(0); + B = OS_GETARG_VECTOR(1); result = true; PG_RETURN_BOOL(!result); @@ -313,12 +313,12 @@ vector_ne(PG_FUNCTION_ARGS) { Datum vector_xtract(PG_FUNCTION_ARGS) { GrB_Info info; - pgGrB_Vector *A, *B, *C = NULL; + OS_Vector *A, *B, *C = NULL; GrB_Index size, *indexes; - A = PGGRB_GETARG_VECTOR(0); - B = PGGRB_GETARG_VECTOR(1); - C = PG_ARGISNULL(2) ? NULL : PGGRB_GETARG_VECTOR(2); + A = OS_GETARG_VECTOR(0); + B = OS_GETARG_VECTOR(1); + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_VECTOR(2); CHECKD(GrB_Vector_size(&size, A->V), A->V); if (C == NULL) { @@ -328,17 +328,17 @@ vector_xtract(PG_FUNCTION_ARGS) { TYPE_APPLY(indexes, A->type, extract_indexes, B, size); CHECKD(GrB_Vector_extract(C->V, NULL, NULL, A->V, indexes, size, NULL), A->V); - PGGRB_RETURN_VECTOR(C); + OS_RETURN_VECTOR(C); } Datum vector_print(PG_FUNCTION_ARGS) { - pgGrB_Vector *A; + OS_Vector *A; char *result, *buf; size_t size; FILE *fp; int level; - A = PGGRB_GETARG_VECTOR(0); + A = OS_GETARG_VECTOR(0); level = PG_GETARG_INT32(1); fp = open_memstream(&buf, &size); diff --git a/src/vector.h b/src/vector.h index 66de74a..3576f0f 100644 --- a/src/vector.h +++ b/src/vector.h @@ -1,10 +1,10 @@ /* This is a "header template" see vector.c for specific instanciations */ -typedef struct FN(pgGrB_Vector_ExtractState) { - pgGrB_Vector *vec; +typedef struct FN(OS_Vector_ExtractState) { + OS_Vector *vec; GrB_Index *indices; PG_TYPE *vals; -} FN(pgGrB_Vector_ExtractState); +} FN(OS_Vector_ExtractState); /* Expanded Object Header "methods" for flattening vectors for storage */ static Size FN(vector_get_flat_size)(ExpandedObjectHeader *eohptr); @@ -18,51 +18,20 @@ static const ExpandedObjectMethods FN(vector_methods) = { /* Utility function that expands a flattened vector datum. */ Datum -FN(expand_flat_vector)(pgGrB_FlatVector *flat, +FN(expand_flat_vector)(OS_FlatVector *flat, MemoryContext parentcontext); /* Helper function that creates an expanded empty vector. */ -pgGrB_Vector * +OS_Vector * FN(construct_empty_expanded_vector)(GrB_Index size, MemoryContext parentcontext); -Datum FN(vector_out)(pgGrB_Vector *vec); -Datum FN(vector_ewise_mult)(pgGrB_Vector *A, - pgGrB_Vector *B, - pgGrB_Vector *C, - pgGrB_Vector *mask, - GrB_BinaryOp binop, - GrB_BinaryOp accum, - GrB_Descriptor desc); -Datum FN(vector_ewise_add)(pgGrB_Vector *A, - pgGrB_Vector *B, - pgGrB_Vector *C, - pgGrB_Vector *mask, - GrB_BinaryOp binop, - GrB_BinaryOp accum, - GrB_Descriptor desc); - -Datum FN(vector_eq)(pgGrB_Vector *A, - pgGrB_Vector *B); - -Datum FN(vector_ne)(pgGrB_Vector *A, - pgGrB_Vector *B); - -GrB_Index *FN(extract_indexes)(pgGrB_Vector *A, GrB_Index size); - -PG_FUNCTION_INFO_V1(FN(vector)); -PG_FUNCTION_INFO_V1(FN(vector_empty)); -PG_FUNCTION_INFO_V1(FN(vector_elements)); -PG_FUNCTION_INFO_V1(FN(vector_reduce)); -PG_FUNCTION_INFO_V1(FN(vector_assign)); -PG_FUNCTION_INFO_V1(FN(vector_set_element)); /* Compute size of storage needed for vector */ static Size FN(vector_get_flat_size)(ExpandedObjectHeader *eohptr) { GrB_Info info; - pgGrB_Vector *A = (pgGrB_Vector *) eohptr; - Size nbytes; + OS_Vector *A = (OS_Vector *) eohptr; GrB_Index size, nvals; Assert(A->ev_magic == vector_MAGIC); @@ -73,12 +42,8 @@ FN(vector_get_flat_size)(ExpandedObjectHeader *eohptr) { CHECKD(GrB_Vector_size(&size, A->V), A->V); CHECKD(GrB_Vector_nvals(&nvals, A->V), A->V); - nbytes = PGGRB_VECTOR_OVERHEAD(); - nbytes += size * sizeof(GrB_Index); - nbytes += nvals * sizeof(PG_TYPE); - - A->flat_size = nbytes; - return nbytes; + A->flat_size = OS_VECTOR_OVERHEAD(); + return A->flat_size; } /* Flatten vector into allocated result buffer */ @@ -86,11 +51,9 @@ static void FN(vector_flatten_into)(ExpandedObjectHeader *eohptr, void *result, Size allocated_size) { GrB_Info info; - GrB_Index *start, size, nvals; - pgGrB_Vector *A = (pgGrB_Vector *) eohptr; - pgGrB_FlatVector *flat = (pgGrB_FlatVector *) result; - void *values; - GrB_Type type; + GrB_Index size, nvals; + OS_Vector *A = (OS_Vector *) eohptr; + OS_FlatVector *flat = (OS_FlatVector *) result; Assert(A->ev_magic == vector_MAGIC); Assert(allocated_size == A->flat_size); @@ -109,18 +72,16 @@ FN(vector_flatten_into)(ExpandedObjectHeader *eohptr, /* Expand a flat vector. */ Datum -FN(expand_flat_vector)(pgGrB_FlatVector *flat, +FN(expand_flat_vector)(OS_FlatVector *flat, MemoryContext parentcontext) { GrB_Info info; - pgGrB_Vector *A; + OS_Vector *A; MemoryContext objcxt, oldcxt; MemoryContextCallback *ctxcb; GrB_Index size, nvals; - GrB_Index *indices; - PG_TYPE *vals; GrB_Type type; /* Create a new context that will hold the expanded object. */ @@ -130,9 +91,9 @@ FN(expand_flat_vector)(pgGrB_FlatVector *flat, ALLOCSET_DEFAULT_SIZES); /* Allocate a new expanded vector */ - A = (pgGrB_Vector*)MemoryContextAlloc( + A = (OS_Vector*)MemoryContextAlloc( objcxt, - sizeof(pgGrB_Vector)); + sizeof(OS_Vector)); /* Initialize the ExpandedObjectHeader member with flattening * methods and new object context */ @@ -149,16 +110,6 @@ FN(expand_flat_vector)(pgGrB_FlatVector *flat, nvals = flat->nvals; type = flat->type; - /* indices and vals are pointers into the vardata area */ - - indices = PGGRB_VECTOR_DATA(flat); - vals = (PG_TYPE*)(indices + size); - - /* Initialize the new vector */ - CHECKD(GrB_Vector_new(&A->V, - type, - size), A->V); - /* Create a context callback to free vector when context is cleared */ ctxcb = (MemoryContextCallback*)MemoryContextAlloc( objcxt, @@ -168,49 +119,40 @@ FN(expand_flat_vector)(pgGrB_FlatVector *flat, ctxcb->arg = A; MemoryContextRegisterResetCallback(objcxt, ctxcb); - /* If there's actual values, build the vector */ - if (nvals > 0) { - CHECKD(GrB_Vector_build(A->V, - indices, - vals, - nvals, - GB_DUP), A->V); - } - A->type = type; A->flat_size = 0; /* Switch back to old context */ MemoryContextSwitchTo(oldcxt); - PGGRB_RETURN_VECTOR(A); + OS_RETURN_VECTOR(A); } /* Construct an empty expanded vector. */ -pgGrB_Vector * +OS_Vector * FN(construct_empty_expanded_vector)(GrB_Index size, MemoryContext parentcontext) { - pgGrB_FlatVector *flat; + OS_FlatVector *flat; Datum d; flat = construct_empty_flat_vector(size, GB_TYPE); d = FN(expand_flat_vector)(flat, parentcontext); pfree(flat); - return (pgGrB_Vector *) DatumGetEOHP(d); + return (OS_Vector *) DatumGetEOHP(d); } Datum FN(vector_empty)(PG_FUNCTION_ARGS) { - pgGrB_Vector *retval; + OS_Vector *retval; GrB_Index max_index; max_index = PG_GETARG_INT64(0); retval = FN(construct_empty_expanded_vector)(max_index, CurrentMemoryContext); - PGGRB_RETURN_VECTOR(retval); + OS_RETURN_VECTOR(retval); } /* cast implementation function. */ Datum FN(vector)(PG_FUNCTION_ARGS) { GrB_Info info; - pgGrB_Vector *retval; + OS_Vector *retval; ArrayType *indexes, *vals; int *idims, *vdims; int i; @@ -278,179 +220,10 @@ FN(vector)(PG_FUNCTION_ARGS) { vcount, GB_DUP), retval->V); - PGGRB_RETURN_VECTOR(retval); + OS_RETURN_VECTOR(retval); } -Datum -FN(vector_elements)(PG_FUNCTION_ARGS) { - GrB_Info info; - FuncCallContext *funcctx; - TupleDesc tupdesc; - Datum result; - - Datum values[3]; - bool nulls[2] = {false, false}; - HeapTuple tuple; - GrB_Index size = 0; - pgGrB_Vector *vec; - FN(pgGrB_Vector_ExtractState) *state; - - if (SRF_IS_FIRSTCALL()) { - MemoryContext oldcontext; - - funcctx = SRF_FIRSTCALL_INIT(); - oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - vec = (pgGrB_Vector *) PGGRB_GETARG_VECTOR(0); - - state = (FN(pgGrB_Vector_ExtractState)*)palloc(sizeof(FN(pgGrB_Vector_ExtractState))); - CHECKD(GrB_Vector_size(&size, vec->V), vec->V); - - state->indices = (GrB_Index*) palloc0(sizeof(GrB_Index) * size); - state->vals = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * size); - - CHECKD(GrB_Vector_extractTuples(state->indices, - state->vals, - &size, - vec->V), vec->V); - state->vec = vec; - funcctx->max_calls = size; - funcctx->user_fctx = (void*)state; - - /* One-time setup code appears here: */ - if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("function returning record called in context " - "that cannot accept type record"))); - BlessTupleDesc(tupdesc); - funcctx->tuple_desc = tupdesc; - - MemoryContextSwitchTo(oldcontext); - } - - funcctx = SRF_PERCALL_SETUP(); - state = (FN(pgGrB_Vector_ExtractState)*)funcctx->user_fctx; - vec = state->vec; - - if (funcctx->call_cntr < funcctx->max_calls) { - values[0] = Int64GetDatum(state->indices[funcctx->call_cntr]); - values[1] = PG_TGD(state->vals[funcctx->call_cntr]); - - tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); - result = HeapTupleGetDatum(tuple); - SRF_RETURN_NEXT(funcctx, result); - } else { - SRF_RETURN_DONE(funcctx); - } -} - -Datum -FN(vector_ewise_mult)(pgGrB_Vector *A, - pgGrB_Vector *B, - pgGrB_Vector *C, - pgGrB_Vector *mask, - GrB_BinaryOp binop, - GrB_BinaryOp accum, - GrB_Descriptor desc) { - GrB_Info info; - GrB_Index size; - - if (C == NULL) { - CHECKD(GrB_Vector_size(&size, A->V), A->V); - C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); - } - CHECKD(GrB_eWiseMult(C->V, mask ? mask->V : NULL, accum, binop, A->V, B->V, desc), C->V); - PGGRB_RETURN_VECTOR(C); -} - -Datum -FN(vector_ewise_add)(pgGrB_Vector *A, - pgGrB_Vector *B, - pgGrB_Vector *C, - pgGrB_Vector *mask, - GrB_BinaryOp binop, - GrB_BinaryOp accum, - GrB_Descriptor desc) { - GrB_Info info; - GrB_Index size; - - if (C == NULL) { - CHECKD(GrB_Vector_size(&size, A->V), A->V); - C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); - } - CHECKD(GrB_eWiseAdd(C->V, mask ? mask->V : NULL, accum, GB_ADD, A->V, B->V, desc), C->V); - PGGRB_RETURN_VECTOR(C); -} - -GrB_Index *FN(extract_indexes)(pgGrB_Vector *A, - GrB_Index size) { - GrB_Index *row_indices; - PG_TYPE *values; - GrB_Info info; - - row_indices = (GrB_Index*) palloc0(sizeof(GrB_Index) * size); - values = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * size); - - CHECKD(GrB_Vector_extractTuples(row_indices, - values, - &size, - A->V), A->V); - return row_indices; -} - -Datum -FN(vector_reduce)(PG_FUNCTION_ARGS) { - GrB_Info info; - pgGrB_Vector *A; - GrB_Semiring semiring; - GrB_Monoid monoid; - char *semiring_name; - PG_TYPE val; - - A = PGGRB_GETARG_VECTOR(0); - semiring_name = PG_ARGISNULL(1) ? NULL : text_to_cstring(PG_GETARG_TEXT_PP(1)); - - semiring = semiring_name ? lookup_semiring(semiring_name) : GB_RNG; - CHECKD(GxB_Semiring_add(&monoid, semiring), semiring); - CHECKD(GrB_reduce(&val, NULL, monoid, A->V, NULL), A->V); - PG_RET(val); -} - -Datum -FN(vector_assign)(PG_FUNCTION_ARGS) { - GrB_Info info; - pgGrB_Vector *A, *B, *mask; - GrB_Index size, *indexes = NULL; - PG_TYPE val; - - A = PGGRB_GETARG_VECTOR(0); - val = PG_GET(1); - B = PG_ARGISNULL(2) ? NULL : PGGRB_GETARG_VECTOR(2); - mask = PG_ARGISNULL(3)? NULL : PGGRB_GETARG_VECTOR(3); - - CHECKD(GrB_Vector_size(&size, A->V), A->V); - - if (B != NULL) - indexes = FN(extract_indexes)(B, size); - - CHECKD(GrB_assign(A->V, mask? mask->V: NULL, NULL, val, indexes ? indexes : GrB_ALL, size, NULL), A->V); - PGGRB_RETURN_VECTOR(A); -} - -Datum -FN(vector_set_element)(PG_FUNCTION_ARGS) { - GrB_Info info; - pgGrB_Vector *A; - GrB_Index index; - PG_TYPE val; - - A = PGGRB_GETARG_VECTOR(0); - index = PG_GETARG_INT64(1); - val = PG_GET(2); - - CHECKD(GrB_Vector_setElement(A->V, val, index), A->V); - PGGRB_RETURN_VECTOR(A); -} +#include "vector_ops.h" #undef SUFFIX #undef PG_TYPE diff --git a/src/vector_ops.h b/src/vector_ops.h new file mode 100644 index 0000000..0792a36 --- /dev/null +++ b/src/vector_ops.h @@ -0,0 +1,203 @@ + + +Datum FN(vector_out)(OS_Vector *vec); +Datum FN(vector_ewise_mult)(OS_Vector *A, + OS_Vector *B, + OS_Vector *C, + OS_Vector *mask, + GrB_BinaryOp binop, + GrB_BinaryOp accum, + GrB_Descriptor desc); +Datum FN(vector_ewise_add)(OS_Vector *A, + OS_Vector *B, + OS_Vector *C, + OS_Vector *mask, + GrB_BinaryOp binop, + GrB_BinaryOp accum, + GrB_Descriptor desc); + +Datum FN(vector_eq)(OS_Vector *A, + OS_Vector *B); + +Datum FN(vector_ne)(OS_Vector *A, + OS_Vector *B); + +GrB_Index *FN(extract_indexes)(OS_Vector *A, GrB_Index size); + +PG_FUNCTION_INFO_V1(FN(vector)); +PG_FUNCTION_INFO_V1(FN(vector_empty)); +PG_FUNCTION_INFO_V1(FN(vector_elements)); +PG_FUNCTION_INFO_V1(FN(vector_reduce)); +PG_FUNCTION_INFO_V1(FN(vector_assign)); +PG_FUNCTION_INFO_V1(FN(vector_set_element)); + +Datum +FN(vector_elements)(PG_FUNCTION_ARGS) { + GrB_Info info; + FuncCallContext *funcctx; + TupleDesc tupdesc; + Datum result; + + Datum values[3]; + bool nulls[2] = {false, false}; + HeapTuple tuple; + GrB_Index size = 0; + OS_Vector *vec; + FN(OS_Vector_ExtractState) *state; + + if (SRF_IS_FIRSTCALL()) { + MemoryContext oldcontext; + + funcctx = SRF_FIRSTCALL_INIT(); + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + vec = (OS_Vector *) OS_GETARG_VECTOR(0); + + state = (FN(OS_Vector_ExtractState)*)palloc(sizeof(FN(OS_Vector_ExtractState))); + CHECKD(GrB_Vector_size(&size, vec->V), vec->V); + + state->indices = (GrB_Index*) palloc0(sizeof(GrB_Index) * size); + state->vals = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * size); + + CHECKD(GrB_Vector_extractTuples(state->indices, + state->vals, + &size, + vec->V), vec->V); + state->vec = vec; + funcctx->max_calls = size; + funcctx->user_fctx = (void*)state; + + /* One-time setup code appears here: */ + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("function returning record called in context " + "that cannot accept type record"))); + BlessTupleDesc(tupdesc); + funcctx->tuple_desc = tupdesc; + + MemoryContextSwitchTo(oldcontext); + } + + funcctx = SRF_PERCALL_SETUP(); + state = (FN(OS_Vector_ExtractState)*)funcctx->user_fctx; + vec = state->vec; + + if (funcctx->call_cntr < funcctx->max_calls) { + values[0] = Int64GetDatum(state->indices[funcctx->call_cntr]); + values[1] = PG_TGD(state->vals[funcctx->call_cntr]); + + tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); + result = HeapTupleGetDatum(tuple); + SRF_RETURN_NEXT(funcctx, result); + } else { + SRF_RETURN_DONE(funcctx); + } +} + +Datum +FN(vector_ewise_mult)(OS_Vector *A, + OS_Vector *B, + OS_Vector *C, + OS_Vector *mask, + GrB_BinaryOp binop, + GrB_BinaryOp accum, + GrB_Descriptor desc) { + GrB_Info info; + GrB_Index size; + + if (C == NULL) { + CHECKD(GrB_Vector_size(&size, A->V), A->V); + C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); + } + CHECKD(GrB_eWiseMult(C->V, mask ? mask->V : NULL, accum, binop, A->V, B->V, desc), C->V); + OS_RETURN_VECTOR(C); +} + +Datum +FN(vector_ewise_add)(OS_Vector *A, + OS_Vector *B, + OS_Vector *C, + OS_Vector *mask, + GrB_BinaryOp binop, + GrB_BinaryOp accum, + GrB_Descriptor desc) { + GrB_Info info; + GrB_Index size; + + if (C == NULL) { + CHECKD(GrB_Vector_size(&size, A->V), A->V); + C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); + } + CHECKD(GrB_eWiseAdd(C->V, mask ? mask->V : NULL, accum, GB_ADD, A->V, B->V, desc), C->V); + OS_RETURN_VECTOR(C); +} + +GrB_Index *FN(extract_indexes)(OS_Vector *A, + GrB_Index size) { + GrB_Index *row_indices; + PG_TYPE *values; + GrB_Info info; + + row_indices = (GrB_Index*) palloc0(sizeof(GrB_Index) * size); + values = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * size); + + CHECKD(GrB_Vector_extractTuples(row_indices, + values, + &size, + A->V), A->V); + return row_indices; +} + +Datum +FN(vector_reduce)(PG_FUNCTION_ARGS) { + GrB_Info info; + OS_Vector *A; + GrB_Semiring semiring; + GrB_Monoid monoid; + char *semiring_name; + PG_TYPE val; + + A = OS_GETARG_VECTOR(0); + semiring_name = PG_ARGISNULL(1) ? NULL : text_to_cstring(PG_GETARG_TEXT_PP(1)); + + semiring = semiring_name ? lookup_semiring(semiring_name) : GB_RNG; + CHECKD(GxB_Semiring_add(&monoid, semiring), semiring); + CHECKD(GrB_reduce(&val, NULL, monoid, A->V, NULL), A->V); + PG_RET(val); +} + +Datum +FN(vector_assign)(PG_FUNCTION_ARGS) { + GrB_Info info; + OS_Vector *A, *B, *mask; + GrB_Index size, *indexes = NULL; + PG_TYPE val; + + A = OS_GETARG_VECTOR(0); + val = PG_GET(1); + B = PG_ARGISNULL(2) ? NULL : OS_GETARG_VECTOR(2); + mask = PG_ARGISNULL(3)? NULL : OS_GETARG_VECTOR(3); + + CHECKD(GrB_Vector_size(&size, A->V), A->V); + + if (B != NULL) + indexes = FN(extract_indexes)(B, size); + + CHECKD(GrB_assign(A->V, mask? mask->V: NULL, NULL, val, indexes ? indexes : GrB_ALL, size, NULL), A->V); + OS_RETURN_VECTOR(A); +} + +Datum +FN(vector_set_element)(PG_FUNCTION_ARGS) { + GrB_Info info; + OS_Vector *A; + GrB_Index index; + PG_TYPE val; + + A = OS_GETARG_VECTOR(0); + index = PG_GETARG_INT64(1); + val = PG_GET(2); + + CHECKD(GrB_Vector_setElement(A->V, val, index), A->V); + OS_RETURN_VECTOR(A); +} From d99e56ad27599a4c4ac302aa290a2e3b58d209b0 Mon Sep 17 00:00:00 2001 From: Michel Pelletier Date: Fri, 9 Aug 2024 07:44:21 -0700 Subject: [PATCH 5/6] reformat to postgresql rules. --- src/matrix.c | 917 ++++++++++++++++++++++++----------------------- src/matrix.h | 413 ++++++++++----------- src/matrix_ops.h | 596 +++++++++++++++--------------- src/onesparse.c | 215 +++++------ src/onesparse.h | 550 ++++++++++++++-------------- src/type.c | 288 ++++++++------- src/vector.c | 408 +++++++++++---------- src/vector.h | 334 +++++++++-------- src/vector_ops.h | 335 +++++++++-------- 9 files changed, 2114 insertions(+), 1942 deletions(-) diff --git a/src/matrix.c b/src/matrix.c index abee3ed..ad94565 100644 --- a/src/matrix.c +++ b/src/matrix.c @@ -2,6 +2,19 @@ /* The same "header template" matrix.h is used to generate the various type specific functions. */ +#define SUFFIX _int64 // suffix for names +#define PG_TYPE int64 // postgres type +#define GB_TYPE GrB_INT64 // graphblas vector type +#define GB_DUP GrB_SECOND_INT64 // default duplicate index resolver +#define GB_MUL GrB_TIMES_INT64 // times bin op +#define GB_ADD GrB_PLUS_INT64 // times bin op +#define PG_GET PG_GETARG_INT64 // how to get value args +#define PG_RET PG_RETURN_INT64 +#define PG_DGT DatumGetInt64 // datum get type +#define PG_TGD Int64GetDatum // type get datum +#define PRINT_FMT(v) "%lu", v // printf fmt +#include "matrix.h" // "call" template + #define SUFFIX _bool #define PG_TYPE bool #define GB_TYPE GrB_BOOL @@ -54,19 +67,6 @@ #define PRINT_FMT(v) "%i", v #include "matrix.h" -#define SUFFIX _int64 // suffix for names -#define PG_TYPE int64 // postgres type -#define GB_TYPE GrB_INT64 // graphblas vector type -#define GB_DUP GrB_SECOND_INT64 // default duplicate index resolver -#define GB_MUL GrB_TIMES_INT64 // times bin op -#define GB_ADD GrB_PLUS_INT64 // times bin op -#define PG_GET PG_GETARG_INT64 // how to get value args -#define PG_RET PG_RETURN_INT64 -#define PG_DGT DatumGetInt64 // datum get type -#define PG_TGD Int64GetDatum // type get datum -#define PRINT_FMT(v) "%lu", v // printf fmt -#include "matrix.h" // "call" template - #define SUFFIX _float4 #define PG_TYPE float4 #define GB_TYPE GrB_FP32 @@ -95,515 +95,544 @@ /* MemoryContextCallback function to free matrices */ static void -context_callback_matrix_free(void* m) { - OS_Matrix *mat = (OS_Matrix *) m; - GrB_Matrix_free(&mat->M); +context_callback_matrix_free(void* m) +{ + OS_Matrix *mat = (OS_Matrix *) m; + GrB_Matrix_free(&mat->M); } /* Construct an empty flat matrix. */ OS_FlatMatrix * construct_empty_flat_matrix(GrB_Index nrows, - GrB_Index ncols, - GrB_Type type) { - OS_FlatMatrix *result; - - result = (OS_FlatMatrix *) palloc0(sizeof(OS_FlatMatrix)); - SET_VARSIZE(result, sizeof(OS_FlatMatrix)); - result->nrows = ncols; - result->ncols = nrows; - result->nvals = 0; - result->type = type; - return result; + GrB_Index ncols, + GrB_Type type) +{ + OS_FlatMatrix *result; + + result = (OS_FlatMatrix *) palloc0(sizeof(OS_FlatMatrix)); + SET_VARSIZE(result, sizeof(OS_FlatMatrix)); + result->nrows = ncols; + result->ncols = nrows; + result->nvals = 0; + result->type = type; + return result; } /* Helper function to always expanded datum -This is used by OS_GETARG_MATRIX */ + This is used by OS_GETARG_MATRIX */ OS_Matrix * -DatumGetMatrix(Datum d) { - OS_Matrix *A; - OS_FlatMatrix *flat; - - if (VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(d))) { - A = MatrixGetEOHP(d); - Assert(A->em_magic == matrix_MAGIC); - return A; - } - flat = (OS_FlatMatrix*)PG_DETOAST_DATUM(d); - TYPE_APPLY(d, flat->type, expand_flat_matrix, flat, CurrentMemoryContext); - return MatrixGetEOHP(d); +DatumGetMatrix(Datum d) +{ + OS_Matrix *A; + OS_FlatMatrix *flat; + + if (VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(d))) + { + A = MatrixGetEOHP(d); + Assert(A->em_magic == matrix_MAGIC); + return A; + } + flat = (OS_FlatMatrix*)PG_DETOAST_DATUM(d); + TYPE_APPLY(d, flat->type, expand_flat_matrix, flat, CurrentMemoryContext); + return MatrixGetEOHP(d); } Datum -matrix_in(PG_FUNCTION_ARGS) { - OS_FlatMatrix *flat; - char *input; - size_t len; - int bc; - Datum d; - - input = PG_GETARG_CSTRING(0); - len = strlen(input); - bc = (len) / 2 + VARHDRSZ; - flat = palloc(bc); - hex_decode(input, len, (char*)flat); - TYPE_APPLY(d, flat->type, expand_flat_matrix, flat, CurrentMemoryContext); - return d; +matrix_in(PG_FUNCTION_ARGS) +{ + OS_FlatMatrix *flat; + char *input; + size_t len; + int bc; + Datum d; + + input = PG_GETARG_CSTRING(0); + len = strlen(input); + bc = (len) / 2 + VARHDRSZ; + flat = palloc(bc); + hex_decode(input, len, (char*)flat); + TYPE_APPLY(d, flat->type, expand_flat_matrix, flat, CurrentMemoryContext); + return d; } Datum matrix_out(PG_FUNCTION_ARGS) { - Size size; - char *rp, *result, *buf; - OS_Matrix *A = OS_GETARG_MATRIX(0); - size = EOH_get_flat_size(&A->hdr); - buf = palloc(size); - EOH_flatten_into(&A->hdr, buf, size); - rp = result = palloc((size * 2) + 1); - rp += hex_encode(buf, size, rp); - *rp = '\0'; - PG_RETURN_CSTRING(result); + Size size; + char *rp, *result, *buf; + OS_Matrix *A = OS_GETARG_MATRIX(0); + size = EOH_get_flat_size(&A->hdr); + buf = palloc(size); + EOH_flatten_into(&A->hdr, buf, size); + rp = result = palloc((size * 2) + 1); + rp += hex_encode(buf, size, rp); + *rp = '\0'; + PG_RETURN_CSTRING(result); } Datum -matrix_nrows(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Matrix *mat; - GrB_Index count; - mat = OS_GETARG_MATRIX(0); - CHECKD(GrB_Matrix_nrows(&count, mat->M), mat->M); - return Int64GetDatum(count); +matrix_nrows(PG_FUNCTION_ARGS) +{ + GrB_Info info; + OS_Matrix *mat; + GrB_Index count; + mat = OS_GETARG_MATRIX(0); + CHECKD(GrB_Matrix_nrows(&count, mat->M), mat->M); + return Int64GetDatum(count); } Datum -matrix_ncols(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Matrix *mat; - GrB_Index count; - mat = OS_GETARG_MATRIX(0); - CHECKD(GrB_Matrix_ncols(&count, mat->M), mat->M); - return Int64GetDatum(count); +matrix_ncols(PG_FUNCTION_ARGS) +{ + GrB_Info info; + OS_Matrix *mat; + GrB_Index count; + mat = OS_GETARG_MATRIX(0); + CHECKD(GrB_Matrix_ncols(&count, mat->M), mat->M); + return Int64GetDatum(count); } Datum -matrix_nvals(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Matrix *mat; - GrB_Index count; - mat = OS_GETARG_MATRIX(0); - CHECKD(GrB_Matrix_nvals(&count, mat->M), mat->M); - return Int64GetDatum(count); +matrix_nvals(PG_FUNCTION_ARGS) +{ + GrB_Info info; + OS_Matrix *mat; + GrB_Index count; + mat = OS_GETARG_MATRIX(0); + CHECKD(GrB_Matrix_nvals(&count, mat->M), mat->M); + return Int64GetDatum(count); } Datum -matrix_eq(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Matrix *A, *B; - bool result; +matrix_eq(PG_FUNCTION_ARGS) +{ + GrB_Info info; + OS_Matrix *A, *B; + bool result; - A = OS_GETARG_MATRIX(0); - B = OS_GETARG_MATRIX(1); + A = OS_GETARG_MATRIX(0); + B = OS_GETARG_MATRIX(1); - result = true; - PG_RETURN_BOOL(result); + result = true; + PG_RETURN_BOOL(result); } Datum -matrix_ne(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Matrix *A, *B; - bool result; +matrix_ne(PG_FUNCTION_ARGS) +{ + GrB_Info info; + OS_Matrix *A, *B; + bool result; - A = OS_GETARG_MATRIX(0); - B = OS_GETARG_MATRIX(1); + A = OS_GETARG_MATRIX(0); + B = OS_GETARG_MATRIX(1); - result = true; - PG_RETURN_BOOL(!result); + result = true; + PG_RETURN_BOOL(!result); } Datum -matrix_ewise_mult(PG_FUNCTION_ARGS) { - OS_Matrix *A, *B, *C = NULL, *mask = NULL; - Datum d; - char *binop_name, *accum_name; - GrB_BinaryOp binop = NULL, accum = NULL; - GrB_Descriptor desc = NULL; - GrB_Info info; - - A = OS_GETARG_MATRIX(0); - B = OS_GETARG_MATRIX(1); - - binop_name = matrix_times_binop(A, B); - accum_name = NULL; - - if (PG_NARGS() > 2) { - C = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(2); - mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_MATRIX(3); - binop_name = PG_ARGISNULL(4) ? - binop_name : text_to_cstring(PG_GETARG_TEXT_PP(4)); - accum_name = PG_ARGISNULL(5) ? - accum_name : text_to_cstring(PG_GETARG_TEXT_PP(5)); - if (PG_NARGS() > 6) { - GET_DESCRIPTOR(6, desc); - } - } - binop = lookup_binop(binop_name); - if (binop == NULL) - elog(ERROR, "unknown binop name %s", binop_name); - if (accum_name != NULL) - accum = lookup_binop(accum_name); - - TYPE_APPLY(d, A->type, matrix_ewise_mult, A, B, C, mask, binop, accum, desc); - return d; +matrix_ewise_mult(PG_FUNCTION_ARGS) +{ + OS_Matrix *A, *B, *C = NULL, *mask = NULL; + Datum d; + char *binop_name, *accum_name; + GrB_BinaryOp binop = NULL, accum = NULL; + GrB_Descriptor desc = NULL; + GrB_Info info; + + A = OS_GETARG_MATRIX(0); + B = OS_GETARG_MATRIX(1); + + binop_name = matrix_times_binop(A, B); + accum_name = NULL; + + if (PG_NARGS() > 2) { + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(2); + mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_MATRIX(3); + binop_name = PG_ARGISNULL(4) ? + binop_name : text_to_cstring(PG_GETARG_TEXT_PP(4)); + accum_name = PG_ARGISNULL(5) ? + accum_name : text_to_cstring(PG_GETARG_TEXT_PP(5)); + if (PG_NARGS() > 6) { + GET_DESCRIPTOR(6, desc); + } + } + binop = lookup_binop(binop_name); + if (binop == NULL) + elog(ERROR, "unknown binop name %s", binop_name); + if (accum_name != NULL) + accum = lookup_binop(accum_name); + + TYPE_APPLY(d, A->type, matrix_ewise_mult, A, B, C, mask, binop, accum, desc); + return d; } Datum -matrix_ewise_add(PG_FUNCTION_ARGS) { - OS_Matrix *A, *B, *C = NULL, *mask = NULL; - Datum d; - char *binop_name, *accum_name; - GrB_BinaryOp binop = NULL, accum = NULL; - GrB_Descriptor desc = NULL; - GrB_Info info; - - A = OS_GETARG_MATRIX(0); - B = OS_GETARG_MATRIX(1); - - accum_name = NULL; - binop_name = matrix_plus_binop(A, B); - - if (PG_NARGS() > 2) { - C = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(2); - mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_MATRIX(3); - binop_name = PG_ARGISNULL(4) ? - binop_name : text_to_cstring(PG_GETARG_TEXT_PP(4)); - accum_name = PG_ARGISNULL(5) ? - accum_name : text_to_cstring(PG_GETARG_TEXT_PP(5)); - if (PG_NARGS() > 6) { - GET_DESCRIPTOR(6, desc); - } - } - - binop = lookup_binop(binop_name); - if (binop == NULL) - elog(ERROR, "unknown binop name %s", binop_name); - if (accum_name != NULL) - accum = lookup_binop(accum_name); - - TYPE_APPLY(d, A->type, matrix_ewise_add, A, B, C, mask, binop, accum, desc); - return d; +matrix_ewise_add(PG_FUNCTION_ARGS) +{ + OS_Matrix *A, *B, *C = NULL, *mask = NULL; + Datum d; + char *binop_name, *accum_name; + GrB_BinaryOp binop = NULL, accum = NULL; + GrB_Descriptor desc = NULL; + GrB_Info info; + + A = OS_GETARG_MATRIX(0); + B = OS_GETARG_MATRIX(1); + + accum_name = NULL; + binop_name = matrix_plus_binop(A, B); + + if (PG_NARGS() > 2) + { + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(2); + mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_MATRIX(3); + binop_name = PG_ARGISNULL(4) ? + binop_name : text_to_cstring(PG_GETARG_TEXT_PP(4)); + accum_name = PG_ARGISNULL(5) ? + accum_name : text_to_cstring(PG_GETARG_TEXT_PP(5)); + if (PG_NARGS() > 6) + { + GET_DESCRIPTOR(6, desc); + } + } + + binop = lookup_binop(binop_name); + if (binop == NULL) + elog(ERROR, "unknown binop name %s", binop_name); + if (accum_name != NULL) + accum = lookup_binop(accum_name); + + TYPE_APPLY(d, A->type, matrix_ewise_add, A, B, C, mask, binop, accum, desc); + return d; } Datum -mxm(PG_FUNCTION_ARGS) { - OS_Matrix *A, *B, *C = NULL, *mask = NULL; - GrB_Info info; - GrB_Type type; - Datum d; - char *semiring_name, *binop_name; - GrB_Semiring semiring; - GrB_BinaryOp binop = NULL; - GrB_Descriptor desc = NULL; - - A = OS_GETARG_MATRIX(0); - B = OS_GETARG_MATRIX(1); - - semiring_name = mxm_semiring(A, B); - binop_name = NULL; - - if (PG_NARGS() > 2) { - C = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(2); - mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_MATRIX(3); - semiring_name = PG_ARGISNULL(4) ? - semiring_name : - text_to_cstring(PG_GETARG_TEXT_PP(4)); - binop_name = PG_ARGISNULL(5) ? - NULL : - text_to_cstring(PG_GETARG_TEXT_PP(5)); - - if (PG_NARGS() > 6) { - GET_DESCRIPTOR(6, desc); - } - } - - semiring = lookup_semiring(semiring_name); - if (semiring == NULL) - elog(ERROR, "unknown semiring name %s", semiring_name); - - if (binop_name != NULL) - binop = lookup_binop(binop_name); - - if (semiring == NULL) - elog(ERROR, "unknown semiring name %s", semiring_name); - - type = mxm_type(A, B); - - TYPE_APPLY(d, type, mxm, A, B, C, mask, semiring, binop, desc); - return d; +mxm(PG_FUNCTION_ARGS) +{ + OS_Matrix *A, *B, *C = NULL, *mask = NULL; + GrB_Info info; + GrB_Type type; + Datum d; + char *semiring_name, *binop_name; + GrB_Semiring semiring; + GrB_BinaryOp binop = NULL; + GrB_Descriptor desc = NULL; + + A = OS_GETARG_MATRIX(0); + B = OS_GETARG_MATRIX(1); + + semiring_name = mxm_semiring(A, B); + binop_name = NULL; + + if (PG_NARGS() > 2) + { + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(2); + mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_MATRIX(3); + semiring_name = PG_ARGISNULL(4) ? + semiring_name : + text_to_cstring(PG_GETARG_TEXT_PP(4)); + binop_name = PG_ARGISNULL(5) ? + NULL : + text_to_cstring(PG_GETARG_TEXT_PP(5)); + + if (PG_NARGS() > 6) + { + GET_DESCRIPTOR(6, desc); + } + } + + semiring = lookup_semiring(semiring_name); + if (semiring == NULL) + elog(ERROR, "unknown semiring name %s", semiring_name); + + if (binop_name != NULL) + binop = lookup_binop(binop_name); + + if (semiring == NULL) + elog(ERROR, "unknown semiring name %s", semiring_name); + + type = mxm_type(A, B); + + TYPE_APPLY(d, type, mxm, A, B, C, mask, semiring, binop, desc); + return d; } Datum -mxv(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Matrix *A; - OS_Vector *B, *C = NULL, *mask = NULL; - GrB_Type type; - Datum d; - char *semiring_name, *binop_name; - GrB_Semiring semiring; - GrB_BinaryOp binop = NULL; - GrB_Descriptor desc = NULL; - - A = OS_GETARG_MATRIX(0); - B = OS_GETARG_VECTOR(1); - - semiring_name = mxv_semiring(A, B); - binop_name = NULL; - - if (PG_NARGS() > 2) { - C = PG_ARGISNULL(2) ? NULL : OS_GETARG_VECTOR(2); - mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_VECTOR(3); - semiring_name = PG_ARGISNULL(4) ? - semiring_name : - text_to_cstring(PG_GETARG_TEXT_PP(4)); - binop_name = PG_ARGISNULL(5) ? - NULL : - text_to_cstring(PG_GETARG_TEXT_PP(5)); - if (PG_NARGS() > 6) { - GET_DESCRIPTOR(6, desc); - } - } - - if (binop_name != NULL) - binop = lookup_binop(binop_name); - - semiring = lookup_semiring(semiring_name); - if (semiring == NULL) - elog(ERROR, "unknown semiring name %s", semiring_name); - - type = mxv_type(A, B); - - TYPE_APPLY(d, type, mxv, A, B, C, mask, semiring, binop, desc); - return d; +mxv(PG_FUNCTION_ARGS) +{ + GrB_Info info; + OS_Matrix *A; + OS_Vector *B, *C = NULL, *mask = NULL; + GrB_Type type; + Datum d; + char *semiring_name, *binop_name; + GrB_Semiring semiring; + GrB_BinaryOp binop = NULL; + GrB_Descriptor desc = NULL; + + A = OS_GETARG_MATRIX(0); + B = OS_GETARG_VECTOR(1); + + semiring_name = mxv_semiring(A, B); + binop_name = NULL; + + if (PG_NARGS() > 2) + { + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_VECTOR(2); + mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_VECTOR(3); + semiring_name = PG_ARGISNULL(4) ? + semiring_name : + text_to_cstring(PG_GETARG_TEXT_PP(4)); + binop_name = PG_ARGISNULL(5) ? + NULL : + text_to_cstring(PG_GETARG_TEXT_PP(5)); + if (PG_NARGS() > 6) { + GET_DESCRIPTOR(6, desc); + } + } + + if (binop_name != NULL) + binop = lookup_binop(binop_name); + + semiring = lookup_semiring(semiring_name); + if (semiring == NULL) + elog(ERROR, "unknown semiring name %s", semiring_name); + + type = mxv_type(A, B); + + TYPE_APPLY(d, type, mxv, A, B, C, mask, semiring, binop, desc); + return d; } Datum -vxm(PG_FUNCTION_ARGS) { - OS_Matrix *B; - OS_Vector *A, *C = NULL, *mask = NULL; - GrB_Type type; - GrB_Info info; - Datum d; - char *semiring_name, *binop_name; - GrB_Semiring semiring; - GrB_BinaryOp binop = NULL; - GrB_Descriptor desc = NULL; - - A = OS_GETARG_VECTOR(0); - B = OS_GETARG_MATRIX(1); - - semiring_name = vxm_semiring(A, B); - binop_name = NULL; - - if (PG_NARGS() > 2) { - C = PG_ARGISNULL(2) ? NULL : OS_GETARG_VECTOR(2); - mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_VECTOR(3); - semiring_name = PG_ARGISNULL(4) ? semiring_name : PG_GETARG_CSTRING(4); - binop_name = PG_ARGISNULL(5) ? - NULL : - text_to_cstring(PG_GETARG_TEXT_PP(5)); - if (PG_NARGS() > 6) { - GET_DESCRIPTOR(6, desc); - } - } - - if (binop_name != NULL) - binop = lookup_binop(binop_name); - - semiring = lookup_semiring(semiring_name); - if (semiring == NULL) - elog(ERROR, "unknown semiring name %s", semiring_name); - - type = vxm_type(A, B); - - TYPE_APPLY(d, type, vxm, A, B, C, mask, semiring, binop, desc); - return d; +vxm(PG_FUNCTION_ARGS) +{ + OS_Matrix *B; + OS_Vector *A, *C = NULL, *mask = NULL; + GrB_Type type; + GrB_Info info; + Datum d; + char *semiring_name, *binop_name; + GrB_Semiring semiring; + GrB_BinaryOp binop = NULL; + GrB_Descriptor desc = NULL; + + A = OS_GETARG_VECTOR(0); + B = OS_GETARG_MATRIX(1); + + semiring_name = vxm_semiring(A, B); + binop_name = NULL; + + if (PG_NARGS() > 2) + { + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_VECTOR(2); + mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_VECTOR(3); + semiring_name = PG_ARGISNULL(4) ? semiring_name : PG_GETARG_CSTRING(4); + binop_name = PG_ARGISNULL(5) ? + NULL : + text_to_cstring(PG_GETARG_TEXT_PP(5)); + if (PG_NARGS() > 6) + { + GET_DESCRIPTOR(6, desc); + } + } + + if (binop_name != NULL) + binop = lookup_binop(binop_name); + + semiring = lookup_semiring(semiring_name); + if (semiring == NULL) + elog(ERROR, "unknown semiring name %s", semiring_name); + + type = vxm_type(A, B); + + TYPE_APPLY(d, type, vxm, A, B, C, mask, semiring, binop, desc); + return d; } Datum -matrix_reduce_vector(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Matrix *A; - GrB_Semiring semiring; - GrB_Monoid monoid; - char *semiring_name; - OS_Vector *val; - GrB_Index size; - GrB_Type type; - - A = OS_GETARG_MATRIX(0); - semiring_name = PG_ARGISNULL(1)? - NULL: - text_to_cstring(PG_GETARG_TEXT_PP(1)); - - if (semiring_name == NULL) { - CHECKD(GxB_Matrix_type(&type, A->M), A->M); - semiring_name = DEFAULT_SEMIRING(type); - } - - semiring = lookup_semiring(semiring_name); - CHECKD(GxB_Semiring_add(&monoid, semiring), semiring); - - CHECKD(GrB_Matrix_ncols(&size, A->M), A->M); - TYPE_APPLY(val, A->type, construct_empty_expanded_vector, size, CurrentMemoryContext); - - CHECKD(GrB_reduce(val->V, NULL, monoid, A->M, NULL), A->M); - OS_RETURN_VECTOR(val); +matrix_reduce_vector(PG_FUNCTION_ARGS) +{ + GrB_Info info; + OS_Matrix *A; + GrB_Semiring semiring; + GrB_Monoid monoid; + char *semiring_name; + OS_Vector *val; + GrB_Index size; + GrB_Type type; + + A = OS_GETARG_MATRIX(0); + semiring_name = PG_ARGISNULL(1)? + NULL: + text_to_cstring(PG_GETARG_TEXT_PP(1)); + + if (semiring_name == NULL) + { + CHECKD(GxB_Matrix_type(&type, A->M), A->M); + semiring_name = DEFAULT_SEMIRING(type); + } + + semiring = lookup_semiring(semiring_name); + CHECKD(GxB_Semiring_add(&monoid, semiring), semiring); + + CHECKD(GrB_Matrix_ncols(&size, A->M), A->M); + TYPE_APPLY(val, A->type, construct_empty_expanded_vector, size, CurrentMemoryContext); + + CHECKD(GrB_reduce(val->V, NULL, monoid, A->M, NULL), A->M); + OS_RETURN_VECTOR(val); } Datum matrix_transpose(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Matrix *A, *C = NULL, *mask; - GrB_Index m, n; - GrB_Descriptor desc = NULL; - - A = OS_GETARG_MATRIX(0); - - if (PG_NARGS() > 0) { - C = PG_ARGISNULL(1) ? NULL : OS_GETARG_MATRIX(2); - mask = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(3); - if (PG_NARGS() > 3) { - GET_DESCRIPTOR(3, desc); - } - } - - if (C == NULL) { - CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); - CHECKD(GrB_Matrix_ncols(&n, A->M), A->M); - TYPE_APPLY(C, A->type, construct_empty_expanded_matrix, m, n, CurrentMemoryContext); - } - - CHECKD(GrB_transpose(C->M, mask? mask->M:NULL, NULL, A->M, desc), A->M); - OS_RETURN_MATRIX(C); + GrB_Info info; + OS_Matrix *A, *C = NULL, *mask; + GrB_Index m, n; + GrB_Descriptor desc = NULL; + + A = OS_GETARG_MATRIX(0); + + if (PG_NARGS() > 0) { + C = PG_ARGISNULL(1) ? NULL : OS_GETARG_MATRIX(2); + mask = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(3); + if (PG_NARGS() > 3) { + GET_DESCRIPTOR(3, desc); + } + } + + if (C == NULL) { + CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&n, A->M), A->M); + TYPE_APPLY(C, A->type, construct_empty_expanded_matrix, m, n, CurrentMemoryContext); + } + + CHECKD(GrB_transpose(C->M, mask? mask->M:NULL, NULL, A->M, desc), A->M); + OS_RETURN_MATRIX(C); } Datum matrix_assign_matrix(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Matrix *A, *B, *mask; - GrB_Index nvals, *rows = NULL, *cols = NULL; - - A = OS_GETARG_MATRIX(0); - B = OS_GETARG_MATRIX(1); - mask = PG_ARGISNULL(2)? NULL : OS_GETARG_MATRIX(2); - - CHECKD(GrB_Matrix_nvals(&nvals, B->M), B->M); - - if (B != NULL) { - TYPE_APPLY(nvals, B->type, extract_rowscols, B, &rows, &cols, nvals); - } - - CHECKD(GrB_assign(A->M, - mask? mask->M: NULL, - NULL, - B->M, - rows? rows : GrB_ALL, - nvals, - cols? cols : GrB_ALL, - nvals, - NULL), A->M); - OS_RETURN_MATRIX(A); + GrB_Info info; + OS_Matrix *A, *B, *mask; + GrB_Index nvals, *rows = NULL, *cols = NULL; + + A = OS_GETARG_MATRIX(0); + B = OS_GETARG_MATRIX(1); + mask = PG_ARGISNULL(2)? NULL : OS_GETARG_MATRIX(2); + + CHECKD(GrB_Matrix_nvals(&nvals, B->M), B->M); + + if (B != NULL) { + TYPE_APPLY(nvals, B->type, extract_rowscols, B, &rows, &cols, nvals); + } + + CHECKD(GrB_assign(A->M, + mask? mask->M: NULL, + NULL, + B->M, + rows? rows : GrB_ALL, + nvals, + cols? cols : GrB_ALL, + nvals, + NULL), A->M); + OS_RETURN_MATRIX(A); } Datum matrix_kron(PG_FUNCTION_ARGS) { - OS_Matrix *A, *B, *C = NULL, *mask = NULL; - GrB_Info info; - GrB_Type type; - Datum d; - char *accum_name, *mulop_name; - GrB_BinaryOp accum = NULL, mulop = NULL; - GrB_Descriptor desc = NULL; - - A = OS_GETARG_MATRIX(0); - B = OS_GETARG_MATRIX(1); - accum_name = NULL; - mulop_name = NULL; - - if (PG_NARGS() > 2) { - C = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(2); - mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_MATRIX(3); - accum_name = PG_ARGISNULL(4) ? - NULL : - text_to_cstring(PG_GETARG_TEXT_PP(4)); - mulop_name = PG_ARGISNULL(5) ? - NULL : - text_to_cstring(PG_GETARG_TEXT_PP(5)); - - if (PG_NARGS() > 6) { - GET_DESCRIPTOR(6, desc); - } - } - - if (accum_name != NULL) - accum = lookup_binop(accum_name); - - if (mulop_name == NULL) - mulop_name = matrix_times_binop(A, NULL); - - mulop = lookup_binop(mulop_name); - - type = mxm_type(A, B); - - TYPE_APPLY(d, type, matrix_kron, A, B, C, mask, accum, mulop, desc); - return d; + OS_Matrix *A, *B, *C = NULL, *mask = NULL; + GrB_Info info; + GrB_Type type; + Datum d; + char *accum_name, *mulop_name; + GrB_BinaryOp accum = NULL, mulop = NULL; + GrB_Descriptor desc = NULL; + + A = OS_GETARG_MATRIX(0); + B = OS_GETARG_MATRIX(1); + accum_name = NULL; + mulop_name = NULL; + + if (PG_NARGS() > 2) { + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(2); + mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_MATRIX(3); + accum_name = PG_ARGISNULL(4) ? + NULL : + text_to_cstring(PG_GETARG_TEXT_PP(4)); + mulop_name = PG_ARGISNULL(5) ? + NULL : + text_to_cstring(PG_GETARG_TEXT_PP(5)); + + if (PG_NARGS() > 6) { + GET_DESCRIPTOR(6, desc); + } + } + + if (accum_name != NULL) + accum = lookup_binop(accum_name); + + if (mulop_name == NULL) + mulop_name = matrix_times_binop(A, NULL); + + mulop = lookup_binop(mulop_name); + + type = mxm_type(A, B); + + TYPE_APPLY(d, type, matrix_kron, A, B, C, mask, accum, mulop, desc); + return d; } Datum matrix_xtract(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Matrix *A, *B, *C = NULL; - GrB_Index nrows, ncols, nvals, *rows, *cols; - GrB_Descriptor desc = NULL; + GrB_Info info; + OS_Matrix *A, *B, *C = NULL; + GrB_Index nrows, ncols, nvals, *rows, *cols; + GrB_Descriptor desc = NULL; - A = OS_GETARG_MATRIX(0); - B = OS_GETARG_MATRIX(1); - C = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(2); - GET_DESCRIPTOR(3, desc); + A = OS_GETARG_MATRIX(0); + B = OS_GETARG_MATRIX(1); + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(2); + GET_DESCRIPTOR(3, desc); - CHECKD(GrB_Matrix_nrows(&nrows, A->M), A->M); - CHECKD(GrB_Matrix_ncols(&ncols, A->M), A->M); + CHECKD(GrB_Matrix_nrows(&nrows, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&ncols, A->M), A->M); - if (C == NULL) { - TYPE_APPLY(C, A->type, construct_empty_expanded_matrix, nrows, ncols, CurrentMemoryContext); - } + if (C == NULL) { + TYPE_APPLY(C, A->type, construct_empty_expanded_matrix, nrows, ncols, CurrentMemoryContext); + } - CHECKD(GrB_Matrix_nvals(&nvals, A->M), A->M); - TYPE_APPLY(nvals, A->type, extract_rowscols, B, &rows, &cols, nvals); + CHECKD(GrB_Matrix_nvals(&nvals, A->M), A->M); + TYPE_APPLY(nvals, A->type, extract_rowscols, B, &rows, &cols, nvals); - CHECKD(GrB_Matrix_extract(C->M, NULL, NULL, A->M, rows, nrows, cols, ncols, NULL), A->M); - OS_RETURN_MATRIX(C); + CHECKD(GrB_Matrix_extract(C->M, NULL, NULL, A->M, rows, nrows, cols, ncols, NULL), A->M); + OS_RETURN_MATRIX(C); } Datum matrix_print(PG_FUNCTION_ARGS) { - OS_Matrix *A; - char *result, *buf; - size_t size; - FILE *fp; - int level; - A = OS_GETARG_MATRIX(0); - level = PG_GETARG_INT32(1); - - fp = open_memstream(&buf, &size); - if (fp == NULL) - elog(ERROR, "unable to open memstream for matrix_print"); - GxB_fprint(A->M, level, fp); - fflush(fp); - result = palloc(size + 1); - memcpy(result, buf, size+1); - free(buf); - PG_RETURN_TEXT_P(cstring_to_text_with_len(result, size+1)); + OS_Matrix *A; + char *result, *buf; + size_t size; + FILE *fp; + int level; + A = OS_GETARG_MATRIX(0); + level = PG_GETARG_INT32(1); + + fp = open_memstream(&buf, &size); + if (fp == NULL) + elog(ERROR, "unable to open memstream for matrix_print"); + GxB_fprint(A->M, level, fp); + fflush(fp); + result = palloc(size + 1); + memcpy(result, buf, size+1); + free(buf); + PG_RETURN_TEXT_P(cstring_to_text_with_len(result, size+1)); } + +/* Local Variables: */ +/* mode: c */ +/* c-file-style: "postgresql" */ +/* End: */ diff --git a/src/matrix.h b/src/matrix.h index 3ecd0c1..6a9394c 100644 --- a/src/matrix.h +++ b/src/matrix.h @@ -2,33 +2,35 @@ /* Set Returning Function (matrix_elements) state for generating tuples from a matrix. - */ -typedef struct FN(OS_Matrix_ExtractState) { - OS_Matrix *mat; - GrB_Index *rows; - GrB_Index *cols; - PG_TYPE *vals; +*/ +typedef struct FN(OS_Matrix_ExtractState) +{ + OS_Matrix *mat; + GrB_Index *rows; + GrB_Index *cols; + PG_TYPE *vals; } FN(OS_Matrix_ExtractState); /* Expanded Object Header "methods" for flattening matrices for storage */ static Size FN(matrix_get_flat_size)(ExpandedObjectHeader *eohptr); static void FN(matrix_flatten_into)(ExpandedObjectHeader *eohptr, - void *result, Size allocated_size); + void *result, Size allocated_size); -static const ExpandedObjectMethods FN(matrix_methods) = { - FN(matrix_get_flat_size), - FN(matrix_flatten_into) +static const ExpandedObjectMethods FN(matrix_methods) = +{ + FN(matrix_get_flat_size), + FN(matrix_flatten_into) }; /* Utility function that expands a flattened matrix datum. */ Datum FN(expand_flat_matrix)(OS_FlatMatrix *flat, - MemoryContext parentcontext); + MemoryContext parentcontext); OS_Matrix * FN(construct_empty_expanded_matrix)(GrB_Index nrows, - GrB_Index ncols, - MemoryContext parentcontext); + GrB_Index ncols, + MemoryContext parentcontext); PG_FUNCTION_INFO_V1(FN(matrix)); @@ -36,221 +38,227 @@ PG_FUNCTION_INFO_V1(FN(matrix_empty)); /* Compute size of storage needed for matrix */ static Size -FN(matrix_get_flat_size)(ExpandedObjectHeader *eohptr) { - GrB_Info info; - OS_Matrix *A = (OS_Matrix *) eohptr; +FN(matrix_get_flat_size)(ExpandedObjectHeader *eohptr) +{ + GrB_Info info; + OS_Matrix *A = (OS_Matrix *) eohptr; - Assert(A->em_magic == matrix_MAGIC); + Assert(A->em_magic == matrix_MAGIC); - if (A->flat_size) - return A->flat_size; + if (A->flat_size) + return A->flat_size; - A->flat_size = OS_MATRIX_OVERHEAD(); - return A->flat_size; + A->flat_size = OS_MATRIX_OVERHEAD(); + return A->flat_size; } /* Flatten matrix into allocated result buffer */ static void FN(matrix_flatten_into)(ExpandedObjectHeader *eohptr, - void *result, Size allocated_size) { - GrB_Info info; - GrB_Index *rows, nrows, ncols, nvals; - OS_Matrix *A = (OS_Matrix *) eohptr; - OS_FlatMatrix *flat = (OS_FlatMatrix *) result; - - Assert(A->em_magic == matrix_MAGIC); - Assert(allocated_size == A->flat_size); - - memset(flat, 0, allocated_size); - - flat->type = GB_TYPE; - flat->nrows = nrows; - flat->ncols = ncols; - flat->nvals = nvals; - SET_VARSIZE(flat, allocated_size); + void *result, Size allocated_size) +{ + GrB_Info info; + GrB_Index *rows, nrows, ncols, nvals; + OS_Matrix *A = (OS_Matrix *) eohptr; + OS_FlatMatrix *flat = (OS_FlatMatrix *) result; + + Assert(A->em_magic == matrix_MAGIC); + Assert(allocated_size == A->flat_size); + + memset(flat, 0, allocated_size); + + flat->type = GB_TYPE; + flat->nrows = nrows; + flat->ncols = ncols; + flat->nvals = nvals; + SET_VARSIZE(flat, allocated_size); } /* Expand a flat matrix. */ Datum FN(expand_flat_matrix)(OS_FlatMatrix *flat, - MemoryContext parentcontext) { - GrB_Info info; - - OS_Matrix *A; - - MemoryContext objcxt, oldcxt; - MemoryContextCallback *ctxcb; - - GrB_Index ncols, nrows, nvals; - GrB_Index *rows, *cols; - void *vals; - GrB_Type type; - - /* Create a new context that will hold the expanded object. */ - objcxt = AllocSetContextCreate(parentcontext, - "expanded matrix", - ALLOCSET_DEFAULT_SIZES); - - /* Allocate a new expanded matrix */ - A = (OS_Matrix*)MemoryContextAlloc(objcxt, - sizeof(OS_Matrix)); - - /* Initialize the ExpandedObjectHeader member with flattening - * methods and new object context */ - EOH_init_header(&A->hdr, &FN(matrix_methods), objcxt); - - /* Used for debugging checks */ - A->em_magic = matrix_MAGIC; - - /* Switch to new object context */ - oldcxt = MemoryContextSwitchTo(objcxt); - - /* Get dimensional information from flat */ - nrows = flat->nrows; - ncols = flat->ncols; - nvals = flat->nvals; - type = flat->type; - A->type = type; - A->flat_size = 0; - - /* Create a context callback to free matrix when context is cleared */ - ctxcb = MemoryContextAlloc(objcxt, - sizeof(MemoryContextCallback)); - - ctxcb->func = context_callback_matrix_free; - ctxcb->arg = A; - MemoryContextRegisterResetCallback(objcxt, ctxcb); - - /* Switch back to old context */ - MemoryContextSwitchTo(oldcxt); - OS_RETURN_MATRIX(A); + MemoryContext parentcontext) +{ + GrB_Info info; + + OS_Matrix *A; + + MemoryContext objcxt, oldcxt; + MemoryContextCallback *ctxcb; + + GrB_Index ncols, nrows, nvals; + GrB_Index *rows, *cols; + void *vals; + GrB_Type type; + + /* Create a new context that will hold the expanded object. */ + objcxt = AllocSetContextCreate(parentcontext, + "expanded matrix", + ALLOCSET_DEFAULT_SIZES); + + /* Allocate a new expanded matrix */ + A = (OS_Matrix*)MemoryContextAlloc(objcxt, + sizeof(OS_Matrix)); + + /* Initialize the ExpandedObjectHeader member with flattening + * methods and new object context */ + EOH_init_header(&A->hdr, &FN(matrix_methods), objcxt); + + /* Used for debugging checks */ + A->em_magic = matrix_MAGIC; + + /* Switch to new object context */ + oldcxt = MemoryContextSwitchTo(objcxt); + + /* Get dimensional information from flat */ + nrows = flat->nrows; + ncols = flat->ncols; + nvals = flat->nvals; + type = flat->type; + A->type = type; + A->flat_size = 0; + + /* Create a context callback to free matrix when context is cleared */ + ctxcb = MemoryContextAlloc(objcxt, + sizeof(MemoryContextCallback)); + + ctxcb->func = context_callback_matrix_free; + ctxcb->arg = A; + MemoryContextRegisterResetCallback(objcxt, ctxcb); + + /* Switch back to old context */ + MemoryContextSwitchTo(oldcxt); + OS_RETURN_MATRIX(A); } /* Construct an empty expanded matrix. */ OS_Matrix * FN(construct_empty_expanded_matrix)(GrB_Index nrows, - GrB_Index ncols, - MemoryContext parentcontext) { - OS_FlatMatrix *flat; - Datum d; - flat = construct_empty_flat_matrix(nrows, ncols, GB_TYPE); - d = FN(expand_flat_matrix)(flat, parentcontext); - pfree(flat); - return (OS_Matrix *) DatumGetEOHP(d); + GrB_Index ncols, + MemoryContext parentcontext) +{ + OS_FlatMatrix *flat; + Datum d; + flat = construct_empty_flat_matrix(nrows, ncols, GB_TYPE); + d = FN(expand_flat_matrix)(flat, parentcontext); + pfree(flat); + return (OS_Matrix *) DatumGetEOHP(d); } Datum -FN(matrix_empty)(PG_FUNCTION_ARGS) { - OS_Matrix *retval; - GrB_Index nrows, ncols; - - nrows = PG_GETARG_INT64(0); - ncols = PG_GETARG_INT64(1); - - retval = FN(construct_empty_expanded_matrix)(nrows, - ncols, - CurrentMemoryContext); - OS_RETURN_MATRIX(retval); +FN(matrix_empty)(PG_FUNCTION_ARGS) +{ + OS_Matrix *retval; + GrB_Index nrows, ncols; + + nrows = PG_GETARG_INT64(0); + ncols = PG_GETARG_INT64(1); + + retval = FN(construct_empty_expanded_matrix)(nrows, + ncols, + CurrentMemoryContext); + OS_RETURN_MATRIX(retval); } Datum -FN(matrix)(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Matrix *retval; - ArrayType *rows, *cols, *vals; - int *idims, *jdims, *vdims; - int i, count; - - GrB_Index *row_indices, *col_indices; - GrB_Index max_row_index, max_col_index; - PG_TYPE *values; - ArrayIterator array_iterator; - Datum value; - bool isnull; - - if (PG_NARGS() == 2) { - max_row_index = PG_GETARG_INT64(0); - max_col_index = PG_GETARG_INT64(1); - retval = FN(construct_empty_expanded_matrix)(max_row_index, - max_col_index, - CurrentMemoryContext); - OS_RETURN_MATRIX(retval); - } - - rows = PG_GETARG_ARRAYTYPE_P(0); - cols = PG_GETARG_ARRAYTYPE_P(1); - vals = PG_GETARG_ARRAYTYPE_P(2); - - if (ARR_HASNULL(rows) || ARR_HASNULL(cols) || ARR_HASNULL(vals)) - ereport(ERROR, (errmsg("Matrix values may not be null"))); - - idims = ARR_DIMS(rows); - jdims = ARR_DIMS(cols); - vdims = ARR_DIMS(vals); - - if (!PG_ARGISNULL(3)) - max_row_index = PG_GETARG_INT64(3); - else - max_row_index = idims[0]; - - if (!PG_ARGISNULL(4)) - max_col_index = PG_GETARG_INT64(4); - else - max_col_index = jdims[0]; - - count = vdims[0]; - - if ((idims[0] != jdims[0]) || (jdims[0] != vdims[0])) - ereport(ERROR, (errmsg("Row, column, and value arrays must be same size."))); - - row_indices = (GrB_Index*) palloc0(sizeof(GrB_Index) * max_row_index); - col_indices = (GrB_Index*) palloc0(sizeof(GrB_Index) * max_col_index); - values = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * count); - - i = 0; - array_iterator = array_create_iterator(rows, 0, NULL); - while (array_iterate(array_iterator, &value, &isnull)) +FN(matrix)(PG_FUNCTION_ARGS) +{ + GrB_Info info; + OS_Matrix *retval; + ArrayType *rows, *cols, *vals; + int *idims, *jdims, *vdims; + int i, count; + + GrB_Index *row_indices, *col_indices; + GrB_Index max_row_index, max_col_index; + PG_TYPE *values; + ArrayIterator array_iterator; + Datum value; + bool isnull; + + if (PG_NARGS() == 2) { + max_row_index = PG_GETARG_INT64(0); + max_col_index = PG_GETARG_INT64(1); + retval = FN(construct_empty_expanded_matrix)(max_row_index, + max_col_index, + CurrentMemoryContext); + OS_RETURN_MATRIX(retval); + } + + rows = PG_GETARG_ARRAYTYPE_P(0); + cols = PG_GETARG_ARRAYTYPE_P(1); + vals = PG_GETARG_ARRAYTYPE_P(2); + + if (ARR_HASNULL(rows) || ARR_HASNULL(cols) || ARR_HASNULL(vals)) + ereport(ERROR, (errmsg("Matrix values may not be null"))); + + idims = ARR_DIMS(rows); + jdims = ARR_DIMS(cols); + vdims = ARR_DIMS(vals); + + if (!PG_ARGISNULL(3)) + max_row_index = PG_GETARG_INT64(3); + else + max_row_index = idims[0]; + + if (!PG_ARGISNULL(4)) + max_col_index = PG_GETARG_INT64(4); + else + max_col_index = jdims[0]; + + count = vdims[0]; + + if ((idims[0] != jdims[0]) || (jdims[0] != vdims[0])) + ereport(ERROR, (errmsg("Row, column, and value arrays must be same size."))); + + row_indices = (GrB_Index*) palloc0(sizeof(GrB_Index) * max_row_index); + col_indices = (GrB_Index*) palloc0(sizeof(GrB_Index) * max_col_index); + values = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * count); + + i = 0; + array_iterator = array_create_iterator(rows, 0, NULL); + while (array_iterate(array_iterator, &value, &isnull)) { - row_indices[i] = DatumGetInt64(value); - if (row_indices[i] > max_row_index) - max_row_index = row_indices[i] + 1; - i++; - } - array_free_iterator(array_iterator); - - i = 0; - array_iterator = array_create_iterator(cols, 0, NULL); - while (array_iterate(array_iterator, &value, &isnull)) + row_indices[i] = DatumGetInt64(value); + if (row_indices[i] > max_row_index) + max_row_index = row_indices[i] + 1; + i++; + } + array_free_iterator(array_iterator); + + i = 0; + array_iterator = array_create_iterator(cols, 0, NULL); + while (array_iterate(array_iterator, &value, &isnull)) { - col_indices[i] = DatumGetInt64(value); - if (col_indices[i] > max_col_index) - max_col_index = col_indices[i] + 1; - i++; - } - array_free_iterator(array_iterator); - - i = 0; - array_iterator = array_create_iterator(vals, 0, NULL); - while (array_iterate(array_iterator, &value, &isnull)) + col_indices[i] = DatumGetInt64(value); + if (col_indices[i] > max_col_index) + max_col_index = col_indices[i] + 1; + i++; + } + array_free_iterator(array_iterator); + + i = 0; + array_iterator = array_create_iterator(vals, 0, NULL); + while (array_iterate(array_iterator, &value, &isnull)) { - values[i] = PG_DGT(value); - i++; - } - array_free_iterator(array_iterator); - - retval = FN(construct_empty_expanded_matrix)(max_row_index, - max_col_index, - CurrentMemoryContext); - - CHECKD(GrB_Matrix_build(retval->M, - row_indices, - col_indices, - values, - count, - GB_DUP), retval->M); - - OS_RETURN_MATRIX(retval); + values[i] = PG_DGT(value); + i++; + } + array_free_iterator(array_iterator); + + retval = FN(construct_empty_expanded_matrix)(max_row_index, + max_col_index, + CurrentMemoryContext); + + CHECKD(GrB_Matrix_build(retval->M, + row_indices, + col_indices, + values, + count, + GB_DUP), retval->M); + + OS_RETURN_MATRIX(retval); } #include "matrix_ops.h" @@ -266,3 +274,8 @@ FN(matrix)(PG_FUNCTION_ARGS) { #undef PG_DGT #undef PG_TGD #undef PRINT_FMT + +/* Local Variables: */ +/* mode: c */ +/* c-file-style: "postgresql" */ +/* End: */ diff --git a/src/matrix_ops.h b/src/matrix_ops.h index 354a3b8..1be1af4 100644 --- a/src/matrix_ops.h +++ b/src/matrix_ops.h @@ -1,59 +1,59 @@ GrB_Index FN(extract_rowscols)(OS_Matrix *A, - GrB_Index **rows, - GrB_Index **cols, - GrB_Index nvals); + GrB_Index **rows, + GrB_Index **cols, + GrB_Index nvals); Datum FN(matrix_ewise_mult)(OS_Matrix *A, - OS_Matrix *B, - OS_Matrix *C, - OS_Matrix *mask, - GrB_BinaryOp binop, - GrB_BinaryOp accum, - GrB_Descriptor desc); + OS_Matrix *B, + OS_Matrix *C, + OS_Matrix *mask, + GrB_BinaryOp binop, + GrB_BinaryOp accum, + GrB_Descriptor desc); Datum FN(matrix_ewise_add)(OS_Matrix *A, - OS_Matrix *B, - OS_Matrix *C, - OS_Matrix *mask, - GrB_BinaryOp binop, - GrB_BinaryOp accum, - GrB_Descriptor desc); + OS_Matrix *B, + OS_Matrix *C, + OS_Matrix *mask, + GrB_BinaryOp binop, + GrB_BinaryOp accum, + GrB_Descriptor desc); Datum FN(mxm)(OS_Matrix *A, - OS_Matrix *B, - OS_Matrix *C, - OS_Matrix *mask, - GrB_Semiring semiring, - GrB_BinaryOp binop, - GrB_Descriptor desc); + OS_Matrix *B, + OS_Matrix *C, + OS_Matrix *mask, + GrB_Semiring semiring, + GrB_BinaryOp binop, + GrB_Descriptor desc); Datum FN(matrix_kron)(OS_Matrix *A, - OS_Matrix *B, - OS_Matrix *C, - OS_Matrix *mask, - GrB_BinaryOp accum, - GrB_BinaryOp mulop, - GrB_Descriptor desc); + OS_Matrix *B, + OS_Matrix *C, + OS_Matrix *mask, + GrB_BinaryOp accum, + GrB_BinaryOp mulop, + GrB_Descriptor desc); Datum FN(mxv)(OS_Matrix *A, - OS_Vector *B, - OS_Vector *C, - OS_Vector *mask, - GrB_Semiring semiring, - GrB_BinaryOp binop, - GrB_Descriptor desc); + OS_Vector *B, + OS_Vector *C, + OS_Vector *mask, + GrB_Semiring semiring, + GrB_BinaryOp binop, + GrB_Descriptor desc); Datum FN(vxm)(OS_Vector *A, - OS_Matrix *B, - OS_Vector *C, - OS_Vector *mask, - GrB_Semiring semiring, - GrB_BinaryOp binop, - GrB_Descriptor desc); + OS_Matrix *B, + OS_Vector *C, + OS_Vector *mask, + GrB_Semiring semiring, + GrB_BinaryOp binop, + GrB_Descriptor desc); PG_FUNCTION_INFO_V1(FN(matrix_elements)); @@ -63,284 +63,314 @@ PG_FUNCTION_INFO_V1(FN(matrix_random)); PG_FUNCTION_INFO_V1(FN(matrix_set_element)); Datum -FN(matrix_elements)(PG_FUNCTION_ARGS) { - GrB_Info info; - FuncCallContext *funcctx; - TupleDesc tupdesc; - Datum result; - - Datum values[3]; - bool nulls[3] = {false, false, false}; - HeapTuple tuple; - GrB_Index nvals = 0; - OS_Matrix *mat; - FN(OS_Matrix_ExtractState) *state; - - if (SRF_IS_FIRSTCALL()) { - MemoryContext oldcontext; - - funcctx = SRF_FIRSTCALL_INIT(); - oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - mat = OS_GETARG_MATRIX(0); - - state = (FN(OS_Matrix_ExtractState)*)palloc(sizeof(FN(OS_Matrix_ExtractState))); - CHECKD(GrB_Matrix_nvals(&nvals, mat->M), mat->M); - - state->rows = (GrB_Index*) palloc0(sizeof(GrB_Index) * nvals); - state->cols = (GrB_Index*) palloc0(sizeof(GrB_Index) * nvals); - state->vals = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * nvals); - - CHECKD(GrB_Matrix_extractTuples(state->rows, - state->cols, - state->vals, - &nvals, - mat->M), mat->M); - state->mat = mat; - funcctx->max_calls = nvals; - funcctx->user_fctx = (void*)state; - - /* One-time setup code appears here: */ - if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("function returning record called in context " - "that cannot accept type record"))); - BlessTupleDesc(tupdesc); - funcctx->tuple_desc = tupdesc; - - MemoryContextSwitchTo(oldcontext); - } - - funcctx = SRF_PERCALL_SETUP(); - state = (FN(OS_Matrix_ExtractState)*)funcctx->user_fctx; - mat = state->mat; - - if (funcctx->call_cntr < funcctx->max_calls) { - values[0] = Int64GetDatum(state->rows[funcctx->call_cntr]); - values[1] = Int64GetDatum(state->cols[funcctx->call_cntr]); - values[2] = PG_TGD(state->vals[funcctx->call_cntr]); - - tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); - result = HeapTupleGetDatum(tuple); - SRF_RETURN_NEXT(funcctx, result); - } else { - SRF_RETURN_DONE(funcctx); - } +FN(matrix_elements)(PG_FUNCTION_ARGS) +{ + GrB_Info info; + FuncCallContext *funcctx; + TupleDesc tupdesc; + Datum result; + + Datum values[3]; + bool nulls[3] = {false, false, false}; + HeapTuple tuple; + GrB_Index nvals = 0; + OS_Matrix *mat; + FN(OS_Matrix_ExtractState) *state; + + if (SRF_IS_FIRSTCALL()) + { + MemoryContext oldcontext; + + funcctx = SRF_FIRSTCALL_INIT(); + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + mat = OS_GETARG_MATRIX(0); + + state = (FN(OS_Matrix_ExtractState)*)palloc(sizeof(FN(OS_Matrix_ExtractState))); + CHECKD(GrB_Matrix_nvals(&nvals, mat->M), mat->M); + + state->rows = (GrB_Index*) palloc0(sizeof(GrB_Index) * nvals); + state->cols = (GrB_Index*) palloc0(sizeof(GrB_Index) * nvals); + state->vals = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * nvals); + + CHECKD(GrB_Matrix_extractTuples(state->rows, + state->cols, + state->vals, + &nvals, + mat->M), mat->M); + state->mat = mat; + funcctx->max_calls = nvals; + funcctx->user_fctx = (void*)state; + + /* One-time setup code appears here: */ + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("function returning record called in context " + "that cannot accept type record"))); + BlessTupleDesc(tupdesc); + funcctx->tuple_desc = tupdesc; + + MemoryContextSwitchTo(oldcontext); + } + + funcctx = SRF_PERCALL_SETUP(); + state = (FN(OS_Matrix_ExtractState)*)funcctx->user_fctx; + mat = state->mat; + + if (funcctx->call_cntr < funcctx->max_calls) + { + values[0] = Int64GetDatum(state->rows[funcctx->call_cntr]); + values[1] = Int64GetDatum(state->cols[funcctx->call_cntr]); + values[2] = PG_TGD(state->vals[funcctx->call_cntr]); + + tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); + result = HeapTupleGetDatum(tuple); + SRF_RETURN_NEXT(funcctx, result); + } + else + { + SRF_RETURN_DONE(funcctx); + } } Datum FN(matrix_ewise_mult)(OS_Matrix *A, - OS_Matrix *B, - OS_Matrix *C, - OS_Matrix *mask, - GrB_BinaryOp binop, - GrB_BinaryOp accum, - GrB_Descriptor desc - ) { - GrB_Info info; - GrB_Index m, n; - - if (C == NULL) { - CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); - CHECKD(GrB_Matrix_ncols(&n, A->M), A->M); - C = FN(construct_empty_expanded_matrix)(m, n, CurrentMemoryContext); - } - CHECKD(GrB_eWiseMult(C->M, mask ? mask->M : NULL, accum, binop, A->M, B->M, desc), A->M); - OS_RETURN_MATRIX(C); + OS_Matrix *B, + OS_Matrix *C, + OS_Matrix *mask, + GrB_BinaryOp binop, + GrB_BinaryOp accum, + GrB_Descriptor desc + ) +{ + GrB_Info info; + GrB_Index m, n; + + if (C == NULL) + { + CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&n, A->M), A->M); + C = FN(construct_empty_expanded_matrix)(m, n, CurrentMemoryContext); + } + CHECKD(GrB_eWiseMult(C->M, mask ? mask->M : NULL, accum, binop, A->M, B->M, desc), A->M); + OS_RETURN_MATRIX(C); } Datum FN(matrix_ewise_add)(OS_Matrix *A, - OS_Matrix *B, - OS_Matrix *C, - OS_Matrix *mask, - GrB_BinaryOp binop, - GrB_BinaryOp accum, - GrB_Descriptor desc - ) { - GrB_Info info; - GrB_Index m, n; - - if (C == NULL) { - CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); - CHECKD(GrB_Matrix_ncols(&n, A->M), A->M); - C = FN(construct_empty_expanded_matrix)(m, n, CurrentMemoryContext); - } - - CHECKD(GrB_eWiseAdd(C->M, mask ? mask->M : NULL, accum, binop, A->M, B->M, desc), A->M); - OS_RETURN_MATRIX(C); + OS_Matrix *B, + OS_Matrix *C, + OS_Matrix *mask, + GrB_BinaryOp binop, + GrB_BinaryOp accum, + GrB_Descriptor desc + ) +{ + GrB_Info info; + GrB_Index m, n; + + if (C == NULL) + { + CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&n, A->M), A->M); + C = FN(construct_empty_expanded_matrix)(m, n, CurrentMemoryContext); + } + + CHECKD(GrB_eWiseAdd(C->M, mask ? mask->M : NULL, accum, binop, A->M, B->M, desc), A->M); + OS_RETURN_MATRIX(C); } Datum FN(mxm)(OS_Matrix *A, - OS_Matrix *B, - OS_Matrix *C, - OS_Matrix *mask, - GrB_Semiring semiring, - GrB_BinaryOp binop, - GrB_Descriptor desc) { - GrB_Info info; - - if (C == NULL) { - GrB_Index m, n; - CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); - CHECKD(GrB_Matrix_ncols(&n, B->M), A->M); - C = FN(construct_empty_expanded_matrix)(m, n, CurrentMemoryContext); - } - CHECKD(GrB_mxm(C->M, mask ? mask->M : NULL, binop, semiring, A->M, B->M, desc), A->M); - OS_RETURN_MATRIX(C); + OS_Matrix *B, + OS_Matrix *C, + OS_Matrix *mask, + GrB_Semiring semiring, + GrB_BinaryOp binop, + GrB_Descriptor desc) +{ + GrB_Info info; + + if (C == NULL) + { + GrB_Index m, n; + CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&n, B->M), A->M); + C = FN(construct_empty_expanded_matrix)(m, n, CurrentMemoryContext); + } + CHECKD(GrB_mxm(C->M, mask ? mask->M : NULL, binop, semiring, A->M, B->M, desc), A->M); + OS_RETURN_MATRIX(C); } Datum FN(mxv)(OS_Matrix *A, - OS_Vector *B, - OS_Vector *C, - OS_Vector *mask, - GrB_Semiring semiring, - GrB_BinaryOp binop, - GrB_Descriptor desc) { - GrB_Info info; - GrB_Index size; - - if (C == NULL) { - CHECKD(GrB_Matrix_ncols(&size, A->M), A->M); - C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); - } - CHECKD(GrB_mxv(C->V, mask ? mask->V : NULL, binop, semiring, A->M, B->V, desc), A->M); - OS_RETURN_VECTOR(C); + OS_Vector *B, + OS_Vector *C, + OS_Vector *mask, + GrB_Semiring semiring, + GrB_BinaryOp binop, + GrB_Descriptor desc) +{ + GrB_Info info; + GrB_Index size; + + if (C == NULL) + { + CHECKD(GrB_Matrix_ncols(&size, A->M), A->M); + C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); + } + CHECKD(GrB_mxv(C->V, mask ? mask->V : NULL, binop, semiring, A->M, B->V, desc), A->M); + OS_RETURN_VECTOR(C); } Datum FN(vxm)(OS_Vector *A, - OS_Matrix *B, - OS_Vector *C, - OS_Vector *mask, - GrB_Semiring semiring, - GrB_BinaryOp binop, - GrB_Descriptor desc) { - GrB_Info info; - GrB_Index size; - - if (C == NULL) { - CHECKD(GrB_Vector_size(&size, A->V), A->V); - C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); - } - CHECKD(GrB_vxm(C->V, mask ? mask->V : NULL, binop, semiring, A->V, B->M, desc), A->V); - OS_RETURN_VECTOR(C); + OS_Matrix *B, + OS_Vector *C, + OS_Vector *mask, + GrB_Semiring semiring, + GrB_BinaryOp binop, + GrB_Descriptor desc) +{ + GrB_Info info; + GrB_Index size; + + if (C == NULL) + { + CHECKD(GrB_Vector_size(&size, A->V), A->V); + C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); + } + CHECKD(GrB_vxm(C->V, mask ? mask->V : NULL, binop, semiring, A->V, B->M, desc), A->V); + OS_RETURN_VECTOR(C); } Datum -FN(matrix_reduce)(PG_FUNCTION_ARGS) { - GrB_Info info; - GrB_Type type; - OS_Matrix *A; - GrB_Semiring semiring; - GrB_Monoid monoid; - char *semiring_name; - PG_TYPE val; - - A = OS_GETARG_MATRIX(0); - semiring_name = PG_ARGISNULL(1)? - NULL: - text_to_cstring(PG_GETARG_TEXT_PP(1)); - - if (semiring_name == NULL) { - CHECKD(GxB_Matrix_type(&type, A->M), A->M); - semiring_name = DEFAULT_SEMIRING(type); - } - semiring = lookup_semiring(semiring_name); - CHECKD(GxB_Semiring_add(&monoid, semiring), A->M); - CHECKD(GrB_reduce(&val, NULL, monoid, A->M, NULL), A->M); - PG_RET(val); +FN(matrix_reduce)(PG_FUNCTION_ARGS) +{ + GrB_Info info; + GrB_Type type; + OS_Matrix *A; + GrB_Semiring semiring; + GrB_Monoid monoid; + char *semiring_name; + PG_TYPE val; + + A = OS_GETARG_MATRIX(0); + semiring_name = PG_ARGISNULL(1)? + NULL: + text_to_cstring(PG_GETARG_TEXT_PP(1)); + + if (semiring_name == NULL) + { + CHECKD(GxB_Matrix_type(&type, A->M), A->M); + semiring_name = DEFAULT_SEMIRING(type); + } + semiring = lookup_semiring(semiring_name); + CHECKD(GxB_Semiring_add(&monoid, semiring), A->M); + CHECKD(GrB_reduce(&val, NULL, monoid, A->M, NULL), A->M); + PG_RET(val); } GrB_Index FN(extract_rowscols)(OS_Matrix *A, - GrB_Index **rows, - GrB_Index **cols, - GrB_Index nvals) { - PG_TYPE *values; - GrB_Info info; - - *rows = (GrB_Index*) palloc0(sizeof(GrB_Index) * nvals); - *cols = (GrB_Index*) palloc0(sizeof(GrB_Index) * nvals); - values = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * nvals); - - CHECKD(GrB_Matrix_extractTuples(*rows, - *cols, - values, - &nvals, - A->M), A->M); - return nvals; + GrB_Index **rows, + GrB_Index **cols, + GrB_Index nvals) +{ + PG_TYPE *values; + GrB_Info info; + + *rows = (GrB_Index*) palloc0(sizeof(GrB_Index) * nvals); + *cols = (GrB_Index*) palloc0(sizeof(GrB_Index) * nvals); + values = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * nvals); + + CHECKD(GrB_Matrix_extractTuples(*rows, + *cols, + values, + &nvals, + A->M), A->M); + return nvals; } Datum -FN(matrix_assign)(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Matrix *A, *B=NULL, *mask=NULL; - GrB_Index nrows, ncols, nvals; - GrB_Index *rows = NULL, *cols = NULL; - PG_TYPE val; - - A = OS_GETARG_MATRIX(0); - val = PG_GET(1); - B = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(2); - mask = PG_ARGISNULL(3)? NULL : OS_GETARG_MATRIX(3); - - if (B != NULL) { - CHECKD(GrB_Matrix_nvals(&nvals, B->M), A->M); - nrows = ncols = nvals = FN(extract_rowscols)(B, &rows, &cols, nvals); - } else { - CHECKD(GrB_Matrix_nrows(&nrows, A->M), A->M); - CHECKD(GrB_Matrix_ncols(&ncols, A->M), A->M); - } - - CHECKD(GrB_assign(A->M, - mask? mask->M: NULL, - NULL, - val, - rows?rows:GrB_ALL, - nrows, - cols?cols:GrB_ALL, - ncols, - NULL), A->M); - - OS_RETURN_MATRIX(A); +FN(matrix_assign)(PG_FUNCTION_ARGS) +{ + GrB_Info info; + OS_Matrix *A, *B=NULL, *mask=NULL; + GrB_Index nrows, ncols, nvals; + GrB_Index *rows = NULL, *cols = NULL; + PG_TYPE val; + + A = OS_GETARG_MATRIX(0); + val = PG_GET(1); + B = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(2); + mask = PG_ARGISNULL(3)? NULL : OS_GETARG_MATRIX(3); + + if (B != NULL) + { + CHECKD(GrB_Matrix_nvals(&nvals, B->M), A->M); + nrows = ncols = nvals = FN(extract_rowscols)(B, &rows, &cols, nvals); + } + else + { + CHECKD(GrB_Matrix_nrows(&nrows, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&ncols, A->M), A->M); + } + + CHECKD(GrB_assign(A->M, + mask? mask->M: NULL, + NULL, + val, + rows?rows:GrB_ALL, + nrows, + cols?cols:GrB_ALL, + ncols, + NULL), A->M); + + OS_RETURN_MATRIX(A); } Datum FN(matrix_kron)(OS_Matrix *A, - OS_Matrix *B, - OS_Matrix *C, - OS_Matrix *mask, - GrB_BinaryOp accum, - GrB_BinaryOp mulop, - GrB_Descriptor desc) { - GrB_Info info; - - if (C == NULL) { - GrB_Index m, n, p, q; - CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); - CHECKD(GrB_Matrix_ncols(&n, A->M), A->M); - CHECKD(GrB_Matrix_nrows(&p, B->M), B->M); - CHECKD(GrB_Matrix_ncols(&q, B->M), B->M); - C = FN(construct_empty_expanded_matrix)(m*p, n*q, CurrentMemoryContext); - } - CHECKD(GxB_kron(C->M, mask ? mask->M : NULL, accum, mulop, A->M, B->M, desc), A->M); - OS_RETURN_MATRIX(C); + OS_Matrix *B, + OS_Matrix *C, + OS_Matrix *mask, + GrB_BinaryOp accum, + GrB_BinaryOp mulop, + GrB_Descriptor desc) +{ + GrB_Info info; + + if (C == NULL) + { + GrB_Index m, n, p, q; + CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); + CHECKD(GrB_Matrix_ncols(&n, A->M), A->M); + CHECKD(GrB_Matrix_nrows(&p, B->M), B->M); + CHECKD(GrB_Matrix_ncols(&q, B->M), B->M); + C = FN(construct_empty_expanded_matrix)(m*p, n*q, CurrentMemoryContext); + } + CHECKD(GxB_kron(C->M, mask ? mask->M : NULL, accum, mulop, A->M, B->M, desc), A->M); + OS_RETURN_MATRIX(C); } Datum -FN(matrix_set_element)(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Matrix *A; - GrB_Index row, col; - PG_TYPE val; - - A = OS_GETARG_MATRIX(0); - row = PG_GETARG_INT64(1); - col = PG_GETARG_INT64(2); - val = PG_GET(3); - - CHECKD(GrB_Matrix_setElement(A->M, val, row, col), A->M); - OS_RETURN_MATRIX(A); +FN(matrix_set_element)(PG_FUNCTION_ARGS) +{ + GrB_Info info; + OS_Matrix *A; + GrB_Index row, col; + PG_TYPE val; + + A = OS_GETARG_MATRIX(0); + row = PG_GETARG_INT64(1); + col = PG_GETARG_INT64(2); + val = PG_GET(3); + + CHECKD(GrB_Matrix_setElement(A->M, val, row, col), A->M); + OS_RETURN_MATRIX(A); } + +/* Local Variables: */ +/* mode: c */ +/* c-file-style: "postgresql" */ +/* End: */ diff --git a/src/onesparse.c b/src/onesparse.c index c77d4a6..c4a104c 100644 --- a/src/onesparse.c +++ b/src/onesparse.c @@ -10,119 +10,128 @@ MemoryContext gb_context; #include "vector.c" #include "matrix.c" -void *calloc_function(size_t num, size_t size) { - MemoryContext oldcxt; - void *p; - size_t total; - total = num * size; - oldcxt = MemoryContextSwitchTo(TopMemoryContext); - p = palloc_extended(total, MCXT_ALLOC_HUGE | MCXT_ALLOC_ZERO); - MemoryContextSwitchTo(oldcxt); - return p; +void *calloc_function(size_t num, size_t size) +{ + MemoryContext oldcxt; + void *p; + size_t total; + total = num * size; + oldcxt = MemoryContextSwitchTo(TopMemoryContext); + p = palloc_extended(total, MCXT_ALLOC_HUGE | MCXT_ALLOC_ZERO); + MemoryContextSwitchTo(oldcxt); + return p; } -void *malloc_function(size_t size) { - MemoryContext oldcxt; - void *p; - oldcxt = MemoryContextSwitchTo(TopMemoryContext); +void *malloc_function(size_t size) +{ + MemoryContext oldcxt; + void *p; + oldcxt = MemoryContextSwitchTo(TopMemoryContext); - p = palloc_extended(size, MCXT_ALLOC_HUGE); - MemoryContextSwitchTo(oldcxt); - return p; + p = palloc_extended(size, MCXT_ALLOC_HUGE); + MemoryContextSwitchTo(oldcxt); + return p; } -void *realloc_function(void *p, size_t size) { - MemoryContext oldcxt; - oldcxt = MemoryContextSwitchTo(TopMemoryContext); - p = repalloc_huge(p, size); - MemoryContextSwitchTo(oldcxt); - return p; +void *realloc_function(void *p, size_t size) +{ + MemoryContext oldcxt; + oldcxt = MemoryContextSwitchTo(TopMemoryContext); + p = repalloc_huge(p, size); + MemoryContextSwitchTo(oldcxt); + return p; } -void free_function(void *p) { - // MemoryContext oldcxt; - // oldcxt = MemoryContextSwitchTo(TopMemoryContext); - pfree(p); - // MemoryContextSwitchTo(oldcxt); +void free_function(void *p) +{ + // MemoryContext oldcxt; + // oldcxt = MemoryContextSwitchTo(TopMemoryContext); + pfree(p); + // MemoryContextSwitchTo(oldcxt); } void _PG_init(void) { - GrB_Info info; - - info = GxB_init (GrB_NONBLOCKING, - malloc_function, - calloc_function, - realloc_function, - free_function); - - if (! (info == GrB_SUCCESS || info == GrB_NO_VALUE)) { - elog(ERROR, "%s", "cannot initialize SuiteSparse"); - return; - } - - SEMIRING_GROUP(0, FIRST_); - SEMIRING_GROUP(40, SECOND_); - SEMIRING_GROUP(80, MIN_); - SEMIRING_GROUP(120, MAX_); - SEMIRING_GROUP(160, PLUS_); - SEMIRING_GROUP(200, MINUS_); - SEMIRING_GROUP(240, TIMES_); - SEMIRING_GROUP(280, DIV_); - SEMIRING_GROUP(320, ISEQ_); - SEMIRING_GROUP(360, ISNE_); - SEMIRING_GROUP(400, ISGT_); - SEMIRING_GROUP(440, ISLT_); - SEMIRING_GROUP(480, ISGE_); - SEMIRING_GROUP(520, ISLE_); - SEMIRING_GROUP(560, LOR_); - SEMIRING_GROUP(600, LAND_); - SEMIRING_GROUP(640, LXOR_); - SEMIRING_BOOL_GROUP(680, EQ_); - SEMIRING_BOOL_GROUP(720, NE_); - SEMIRING_BOOL_GROUP(760, GT_); - SEMIRING_BOOL_GROUP(800, LT_); - SEMIRING_BOOL_GROUP(840, GE_); - SEMIRING_BOOL_GROUP(880, LE_); - SEMIRING_PURE_BOOL_GROUP(920); - - BINOP_TYPES(0, GrB_, FIRST_); - BINOP_TYPES(11, GrB_, SECOND_); - BINOP_TYPES(22, GrB_, MIN_); - BINOP_TYPES(33, GrB_, MAX_); - BINOP_TYPES(44, GrB_, PLUS_); - BINOP_TYPES(55, GrB_, MINUS_); - BINOP_TYPES(66, GrB_, TIMES_); - BINOP_TYPES(77, GrB_, DIV_); - - BINOP_TYPES(88, GxB_, ISEQ_); - BINOP_TYPES(99, GxB_, ISNE_); - BINOP_TYPES(110, GxB_, ISGT_); - BINOP_TYPES(121, GxB_, ISLT_); - BINOP_TYPES(132, GxB_, ISGE_); - BINOP_TYPES(143, GxB_, ISLE_); - - BINOP_TYPES(154, GrB_, EQ_); - BINOP_TYPES(165, GrB_, NE_); - BINOP_TYPES(176, GrB_, GT_); - BINOP_TYPES(187, GrB_, LT_); - BINOP_TYPES(198, GrB_, GE_); - BINOP_TYPES(209, GrB_, LE_); - - BINOP_TYPES(220, GxB_, LOR_); - BINOP_TYPES(231, GxB_, LAND_); - BINOP_TYPES(242, GxB_, LXOR_); - - BINOP(254, GrB_, LOR,); - BINOP(255, GrB_, LAND,); - BINOP(256, GrB_, LXOR,); - - UOP_TYPES(0, GrB_, IDENTITY_); - UOP_TYPES(11, GrB_, AINV_); - UOP_TYPES(22, GrB_, MINV_); - UOP_TYPES(33, GxB_, LNOT_); - UOP_TYPES(44, GxB_, ONE_); - UOP_TYPES(55, GxB_, ABS_); - UOP(67, GrB_, LNOT,); + GrB_Info info; + + info = GxB_init (GrB_NONBLOCKING, + malloc_function, + calloc_function, + realloc_function, + free_function); + + if (! (info == GrB_SUCCESS || info == GrB_NO_VALUE)) { + elog(ERROR, "%s", "cannot initialize SuiteSparse"); + return; + } + + SEMIRING_GROUP(0, FIRST_); + SEMIRING_GROUP(40, SECOND_); + SEMIRING_GROUP(80, MIN_); + SEMIRING_GROUP(120, MAX_); + SEMIRING_GROUP(160, PLUS_); + SEMIRING_GROUP(200, MINUS_); + SEMIRING_GROUP(240, TIMES_); + SEMIRING_GROUP(280, DIV_); + SEMIRING_GROUP(320, ISEQ_); + SEMIRING_GROUP(360, ISNE_); + SEMIRING_GROUP(400, ISGT_); + SEMIRING_GROUP(440, ISLT_); + SEMIRING_GROUP(480, ISGE_); + SEMIRING_GROUP(520, ISLE_); + SEMIRING_GROUP(560, LOR_); + SEMIRING_GROUP(600, LAND_); + SEMIRING_GROUP(640, LXOR_); + SEMIRING_BOOL_GROUP(680, EQ_); + SEMIRING_BOOL_GROUP(720, NE_); + SEMIRING_BOOL_GROUP(760, GT_); + SEMIRING_BOOL_GROUP(800, LT_); + SEMIRING_BOOL_GROUP(840, GE_); + SEMIRING_BOOL_GROUP(880, LE_); + SEMIRING_PURE_BOOL_GROUP(920); + + BINOP_TYPES(0, GrB_, FIRST_); + BINOP_TYPES(11, GrB_, SECOND_); + BINOP_TYPES(22, GrB_, MIN_); + BINOP_TYPES(33, GrB_, MAX_); + BINOP_TYPES(44, GrB_, PLUS_); + BINOP_TYPES(55, GrB_, MINUS_); + BINOP_TYPES(66, GrB_, TIMES_); + BINOP_TYPES(77, GrB_, DIV_); + + BINOP_TYPES(88, GxB_, ISEQ_); + BINOP_TYPES(99, GxB_, ISNE_); + BINOP_TYPES(110, GxB_, ISGT_); + BINOP_TYPES(121, GxB_, ISLT_); + BINOP_TYPES(132, GxB_, ISGE_); + BINOP_TYPES(143, GxB_, ISLE_); + + BINOP_TYPES(154, GrB_, EQ_); + BINOP_TYPES(165, GrB_, NE_); + BINOP_TYPES(176, GrB_, GT_); + BINOP_TYPES(187, GrB_, LT_); + BINOP_TYPES(198, GrB_, GE_); + BINOP_TYPES(209, GrB_, LE_); + + BINOP_TYPES(220, GxB_, LOR_); + BINOP_TYPES(231, GxB_, LAND_); + BINOP_TYPES(242, GxB_, LXOR_); + + BINOP(254, GrB_, LOR,); + BINOP(255, GrB_, LAND,); + BINOP(256, GrB_, LXOR,); + + UOP_TYPES(0, GrB_, IDENTITY_); + UOP_TYPES(11, GrB_, AINV_); + UOP_TYPES(22, GrB_, MINV_); + UOP_TYPES(33, GxB_, LNOT_); + UOP_TYPES(44, GxB_, ONE_); + UOP_TYPES(55, GxB_, ABS_); + UOP(67, GrB_, LNOT,); } + +/* Local Variables: */ +/* mode: c */ +/* c-file-style: "postgresql" */ +/* End: */ diff --git a/src/onesparse.h b/src/onesparse.h index af4cdbe..28ac2c7 100644 --- a/src/onesparse.h +++ b/src/onesparse.h @@ -20,75 +20,75 @@ #define CCAT(x, y) CCAT2(x, y) #define FN(x) CCAT(x, SUFFIX) -#define TYPE_APPLY(D, T, F, ...) do { \ - if ((T) == GrB_INT64) \ - D = F ## _int64(__VA_ARGS__); \ - else if ((T) == GrB_INT32) \ - D = F ## _int32(__VA_ARGS__); \ - else if ((T) == GrB_INT16) \ - D = F ## _int16(__VA_ARGS__); \ - else if ((T) == GrB_INT8) \ - D = F ## _int8(__VA_ARGS__); \ - else if ((T) == GrB_BOOL) \ - D = F ## _bool(__VA_ARGS__); \ - else if ((T) == GrB_FP64) \ - D = F ## _float8(__VA_ARGS__); \ - else if((T) == GrB_FP32) \ - D = F ## _float4(__VA_ARGS__); \ - else \ - elog(ERROR, "unsupported type"); \ - } while(0) - -#define DEFAULT_SEMIRING(T) \ - (T) == GrB_INT64? \ - "PLUS_TIMES_INT64" : \ - (T) == GrB_INT32? \ - "PLUS_TIMES_INT32" : \ - (T) == GrB_INT16? \ - "PLUS_TIMES_INT16" : \ - (T) == GrB_INT8? \ - "PLUS_TIMES_INT8" : \ - (T) == GrB_BOOL? \ - "LOR_LAND_BOOL" : \ - (T) == GrB_FP64? \ - "PLUS_TIMES_FP64" : \ - (T) == GrB_FP32? \ - "PLUS_TIMES_FP32" : \ - "unknown" - -#define DEFAULT_TIMES_BINOP(T) \ - (T) == GrB_INT64? \ - "TIMES_INT64" : \ - (T) == GrB_INT32? \ - "TIMES_INT32" : \ - (T) == GrB_INT16? \ - "TIMES_INT16" : \ - (T) == GrB_INT8? \ - "TIMES_INT8" : \ - (T) == GrB_BOOL? \ - "TIMES_BOOL" : \ - (T) == GrB_FP64? \ - "TIMES_FP64" : \ - (T) == GrB_FP32? \ - "TIMES_FP32" : \ - "unknown" - -#define DEFAULT_PLUS_BINOP(T) \ - (T) == GrB_INT64? \ - "PLUS_INT64" : \ - (T) == GrB_INT32? \ - "PLUS_INT32" : \ - (T) == GrB_INT16? \ - "PLUS_INT16" : \ - (T) == GrB_INT8? \ - "PLUS_INT8" : \ - (T) == GrB_BOOL? \ - "PLUS_BOOL" : \ - (T) == GrB_FP64? \ - "PLUS_FP64" : \ - (T) == GrB_FP32? \ - "PLUS_FP32" : \ - "unknown" +#define TYPE_APPLY(D, T, F, ...) do { \ + if ((T) == GrB_INT64) \ + D = F ## _int64(__VA_ARGS__); \ + else if ((T) == GrB_INT32) \ + D = F ## _int32(__VA_ARGS__); \ + else if ((T) == GrB_INT16) \ + D = F ## _int16(__VA_ARGS__); \ + else if ((T) == GrB_INT8) \ + D = F ## _int8(__VA_ARGS__); \ + else if ((T) == GrB_BOOL) \ + D = F ## _bool(__VA_ARGS__); \ + else if ((T) == GrB_FP64) \ + D = F ## _float8(__VA_ARGS__); \ + else if((T) == GrB_FP32) \ + D = F ## _float4(__VA_ARGS__); \ + else \ + elog(ERROR, "unsupported type"); \ + } while(0) + +#define DEFAULT_SEMIRING(T) \ + (T) == GrB_INT64? \ + "PLUS_TIMES_INT64" : \ + (T) == GrB_INT32? \ + "PLUS_TIMES_INT32" : \ + (T) == GrB_INT16? \ + "PLUS_TIMES_INT16" : \ + (T) == GrB_INT8? \ + "PLUS_TIMES_INT8" : \ + (T) == GrB_BOOL? \ + "LOR_LAND_BOOL" : \ + (T) == GrB_FP64? \ + "PLUS_TIMES_FP64" : \ + (T) == GrB_FP32? \ + "PLUS_TIMES_FP32" : \ + "unknown" + +#define DEFAULT_TIMES_BINOP(T) \ + (T) == GrB_INT64? \ + "TIMES_INT64" : \ + (T) == GrB_INT32? \ + "TIMES_INT32" : \ + (T) == GrB_INT16? \ + "TIMES_INT16" : \ + (T) == GrB_INT8? \ + "TIMES_INT8" : \ + (T) == GrB_BOOL? \ + "TIMES_BOOL" : \ + (T) == GrB_FP64? \ + "TIMES_FP64" : \ + (T) == GrB_FP32? \ + "TIMES_FP32" : \ + "unknown" + +#define DEFAULT_PLUS_BINOP(T) \ + (T) == GrB_INT64? \ + "PLUS_INT64" : \ + (T) == GrB_INT32? \ + "PLUS_INT32" : \ + (T) == GrB_INT16? \ + "PLUS_INT16" : \ + (T) == GrB_INT8? \ + "PLUS_INT8" : \ + (T) == GrB_BOOL? \ + "PLUS_BOOL" : \ + (T) == GrB_FP64? \ + "PLUS_FP64" : \ + (T) == GrB_FP32? \ + "PLUS_FP32" : \ + "unknown" /* dumb debug helper */ #define elogn(s) elog(NOTICE, "%s", (s)) @@ -96,70 +96,72 @@ /* GraphBLAS API checking macros */ -#define CHECKD(method, obj) \ - { \ - info = method ; \ - if (! (info == GrB_SUCCESS || info == GrB_NO_VALUE)) \ - { \ - const char *emsg; \ - GrB_error(&emsg, obj); \ - elog(ERROR, "%s", emsg); \ - return (Datum) 0; \ - } \ - } \ - -#define CHECKV(method, obj) \ -{ \ - info = method ; \ - if (! (info == GrB_SUCCESS || info == GrB_NO_VALUE)) \ - { \ - const char *emsg; \ - GrB_error(&emsg, obj); \ - elog(ERROR, "%s", emsg); \ - return; \ - } \ -} \ +#define CHECKD(method, obj) \ + { \ + info = method ; \ + if (! (info == GrB_SUCCESS || info == GrB_NO_VALUE)) \ + { \ + const char *emsg; \ + GrB_error(&emsg, obj); \ + elog(ERROR, "%s", emsg); \ + return (Datum) 0; \ + } \ + } \ + +#define CHECKV(method, obj) \ + { \ + info = method ; \ + if (! (info == GrB_SUCCESS || info == GrB_NO_VALUE)) \ + { \ + const char *emsg; \ + GrB_error(&emsg, obj); \ + elog(ERROR, "%s", emsg); \ + return; \ + } \ + } \ GrB_Info isequal_type ( - bool *result, - GrB_Matrix A, - GrB_Matrix B, - GrB_BinaryOp op + bool *result, + GrB_Matrix A, + GrB_Matrix B, + GrB_BinaryOp op ); GrB_Info isequal ( - bool *result, - GrB_Matrix A, - GrB_Matrix B, - GrB_BinaryOp userop + bool *result, + GrB_Matrix A, + GrB_Matrix B, + GrB_BinaryOp userop ); GrB_Info visequal_type ( - bool *result, - GrB_Vector A, - GrB_Vector B, - GrB_BinaryOp op + bool *result, + GrB_Vector A, + GrB_Vector B, + GrB_BinaryOp op ); GrB_Info visequal ( - bool *result, - GrB_Vector A, - GrB_Vector B, - GrB_BinaryOp userop + bool *result, + GrB_Vector A, + GrB_Vector B, + GrB_BinaryOp userop ); /* Flattened representation of matrix, used to store to disk. -*/ -typedef struct OS_FlatMatrix { - int32 vl_len_; - GrB_Index nrows; - GrB_Index ncols; - GrB_Index nvals; - GrB_Type type; + */ +typedef struct OS_FlatMatrix +{ + int32 vl_len_; + GrB_Index nrows; + GrB_Index ncols; + GrB_Index nvals; + GrB_Type type; + Oid lobjId; } OS_FlatMatrix; /* ID for debugging crosschecks */ @@ -167,15 +169,17 @@ typedef struct OS_FlatMatrix { /* Expanded representation of matrix. -When loaded from storage, the flattened representation is used to -build the matrix with GrB_Matrix_build. + When loaded from storage, the flattened representation is used to + build the matrix with GrB_Matrix_build. */ -typedef struct OS_Matrix { - ExpandedObjectHeader hdr; - int em_magic; - GrB_Type type; - GrB_Matrix M; - Size flat_size; +typedef struct OS_Matrix +{ + ExpandedObjectHeader hdr; + int em_magic; + GrB_Type type; + GrB_Matrix M; + Oid lobjId; + Size flat_size; } OS_Matrix; /* helper to turn types into names. */ @@ -192,8 +196,8 @@ OS_Matrix* DatumGetMatrix(Datum d); /* Helper function to create an empty flattened matrix. */ OS_FlatMatrix * construct_empty_flat_matrix(GrB_Index nrows, - GrB_Index ncols, - GrB_Type type); + GrB_Index ncols, + GrB_Type type); /* Helper to detoast and expand matrix arguments */ #define OS_GETARG_MATRIX(n) DatumGetMatrix(PG_GETARG_DATUM(n)) @@ -237,13 +241,14 @@ PG_FUNCTION_INFO_V1(matrix_bfs); /* Flattened representation of vector, used to store to disk. -Actual array data is appended and for the moment cannot exceed 1GB. + Actual array data is appended and for the moment cannot exceed 1GB. */ -typedef struct OS_FlatVector { - int32 vl_len_; - GrB_Index size; - GrB_Index nvals; - GrB_Type type; +typedef struct OS_FlatVector +{ + int32 vl_len_; + GrB_Index size; + GrB_Index nvals; + GrB_Type type; } OS_FlatVector; /* ID for debugging crosschecks */ @@ -251,15 +256,16 @@ typedef struct OS_FlatVector { /* Expanded representation of vector. -When loaded from storage, the flattened representation is used to -build the vector with GrB_Vector_build. + When loaded from storage, the flattened representation is used to + build the vector with GrB_Vector_build. */ -typedef struct OS_Vector { - ExpandedObjectHeader hdr; - int ev_magic; - GrB_Type type; - GrB_Vector V; - Size flat_size; +typedef struct OS_Vector +{ + ExpandedObjectHeader hdr; + int ev_magic; + GrB_Type type; + GrB_Vector V; + Size flat_size; } OS_Vector; static void context_callback_vector_free(void*); @@ -316,143 +322,146 @@ PG_FUNCTION_INFO_V1(vector_size); PG_FUNCTION_INFO_V1(vector_xtract); PG_FUNCTION_INFO_V1(vector_print); -typedef struct OS_Semiring { - char name[255]; - GrB_Semiring R; +typedef struct OS_Semiring +{ + char name[255]; + GrB_Semiring R; } OS_Semiring; -typedef struct OS_BinaryOp { - char name[255]; - GrB_BinaryOp B; +typedef struct OS_BinaryOp +{ + char name[255]; + GrB_BinaryOp B; } OS_BinaryOp; -typedef struct OS_UnaryOp { - char name[255]; - GrB_UnaryOp U; +typedef struct OS_UnaryOp +{ + char name[255]; + GrB_UnaryOp U; } OS_UnaryOp; -#define SEMIRING(N, PLS, TMS, TYP) do { \ - strlcpy(semirings[(N)].name, #PLS #TMS #TYP, 255); \ - semirings[(N)].R = GxB_ ## PLS ## TMS ## TYP; \ - } while (0) - -#define SEMIRING_TYPES(N, PLS, TMS) do { \ - SEMIRING (N, PLS, TMS, INT8); \ - SEMIRING(N+1, PLS, TMS, UINT8); \ - SEMIRING(N+2, PLS, TMS, INT16); \ - SEMIRING(N+3, PLS, TMS, UINT16); \ - SEMIRING(N+4, PLS, TMS, INT32); \ - SEMIRING(N+5, PLS, TMS, UINT32); \ - SEMIRING(N+6, PLS, TMS, INT64); \ - SEMIRING(N+7, PLS, TMS, UINT64); \ - SEMIRING(N+8, PLS, TMS, FP32); \ - SEMIRING(N+9, PLS, TMS, FP64); \ - } while(0) - -#define SEMIRING_PURE_BOOL(N, PLS) do { \ - SEMIRING(N, PLS, FIRST_, BOOL); \ - SEMIRING(N+1, PLS, SECOND_, BOOL); \ - SEMIRING(N+2, PLS, LOR_, BOOL); \ - SEMIRING(N+3, PLS, LAND_, BOOL); \ - SEMIRING(N+4, PLS, LXOR_, BOOL); \ - SEMIRING(N+5, PLS, EQ_, BOOL); \ - SEMIRING(N+6, PLS, GT_, BOOL); \ - SEMIRING(N+7, PLS, LT_, BOOL); \ - SEMIRING(N+8, PLS, GE_, BOOL); \ - SEMIRING(N+9, PLS, LE_, BOOL); \ - } while(0) - -#define SEMIRING_GROUP(N, TMS) do { \ - SEMIRING_TYPES((N), MIN_, TMS); \ - SEMIRING_TYPES((N)+10, MAX_, TMS); \ - SEMIRING_TYPES((N)+20, PLUS_, TMS); \ - SEMIRING_TYPES((N)+30, TIMES_, TMS); \ - } while(0) - -#define SEMIRING_BOOL_GROUP(N, TMS) do { \ - SEMIRING_TYPES((N), LOR_, TMS); \ - SEMIRING_TYPES((N)+10, LAND_, TMS); \ - SEMIRING_TYPES((N)+20, LXOR_, TMS); \ - SEMIRING_TYPES((N)+30, EQ_, TMS); \ - } while(0) - -#define SEMIRING_PURE_BOOL_GROUP(N) do { \ - SEMIRING_PURE_BOOL((N), LOR_); \ - SEMIRING_PURE_BOOL((N)+10, LAND_); \ - SEMIRING_PURE_BOOL((N)+20, LXOR_); \ - SEMIRING_PURE_BOOL((N)+30, EQ_); \ - } while(0) - -#define BINOP(N, PRE, OP, TYP) do { \ - strlcpy(binops[(N)].name, #OP #TYP, 255); \ - binops[(N)].B = PRE ## OP ## TYP; \ - } while (0) - -#define BINOP_TYPES(N, PRE, OP) do { \ - BINOP (N, PRE, OP, INT8); \ - BINOP(N+1, PRE, OP, UINT8); \ - BINOP(N+2, PRE, OP, INT16); \ - BINOP(N+3, PRE, OP, UINT16); \ - BINOP(N+4, PRE, OP, INT32); \ - BINOP(N+5, PRE, OP, UINT32); \ - BINOP(N+6, PRE, OP, INT64); \ - BINOP(N+7, PRE, OP, UINT64); \ - BINOP(N+8, PRE, OP, FP32); \ - BINOP(N+9, PRE, OP, FP64); \ - BINOP (N+10, PRE, OP, BOOL); \ - } while(0) - - -#define UOP(N, PRE, OP, TYP) do { \ - strlcpy(uops[(N)].name, #OP #TYP, 255); \ - uops[(N)].U = PRE ## OP ## TYP; \ - } while (0) - -#define UOP_TYPES(N, PRE, OP) do { \ - UOP (N, PRE, OP, INT8); \ - UOP(N+1, PRE, OP, UINT8); \ - UOP(N+2, PRE, OP, INT16); \ - UOP(N+3, PRE, OP, UINT16); \ - UOP(N+4, PRE, OP, INT32); \ - UOP(N+5, PRE, OP, UINT32); \ - UOP(N+6, PRE, OP, INT64); \ - UOP(N+7, PRE, OP, UINT64); \ - UOP(N+8, PRE, OP, FP32); \ - UOP(N+9, PRE, OP, FP64); \ - } while(0) - -#define RETURN_TYPECHCK1(A, B, OP, TYP) \ - if ((A) == GrB_##TYP || (B) == GrB_##TYP) \ - return #OP "_" #TYP - -#define RETURN_TYPECHCK2(A, B, TYP) \ - if ((A) == GrB_##TYP || (B) == GrB_##TYP) \ - return GrB_##TYP +#define SEMIRING(N, PLS, TMS, TYP) do { \ + strlcpy(semirings[(N)].name, #PLS #TMS #TYP, 255); \ + semirings[(N)].R = GxB_ ## PLS ## TMS ## TYP; \ + } while (0) + +#define SEMIRING_TYPES(N, PLS, TMS) do { \ + SEMIRING (N, PLS, TMS, INT8); \ + SEMIRING(N+1, PLS, TMS, UINT8); \ + SEMIRING(N+2, PLS, TMS, INT16); \ + SEMIRING(N+3, PLS, TMS, UINT16); \ + SEMIRING(N+4, PLS, TMS, INT32); \ + SEMIRING(N+5, PLS, TMS, UINT32); \ + SEMIRING(N+6, PLS, TMS, INT64); \ + SEMIRING(N+7, PLS, TMS, UINT64); \ + SEMIRING(N+8, PLS, TMS, FP32); \ + SEMIRING(N+9, PLS, TMS, FP64); \ + } while(0) + +#define SEMIRING_PURE_BOOL(N, PLS) do { \ + SEMIRING(N, PLS, FIRST_, BOOL); \ + SEMIRING(N+1, PLS, SECOND_, BOOL); \ + SEMIRING(N+2, PLS, LOR_, BOOL); \ + SEMIRING(N+3, PLS, LAND_, BOOL); \ + SEMIRING(N+4, PLS, LXOR_, BOOL); \ + SEMIRING(N+5, PLS, EQ_, BOOL); \ + SEMIRING(N+6, PLS, GT_, BOOL); \ + SEMIRING(N+7, PLS, LT_, BOOL); \ + SEMIRING(N+8, PLS, GE_, BOOL); \ + SEMIRING(N+9, PLS, LE_, BOOL); \ + } while(0) + +#define SEMIRING_GROUP(N, TMS) do { \ + SEMIRING_TYPES((N), MIN_, TMS); \ + SEMIRING_TYPES((N)+10, MAX_, TMS); \ + SEMIRING_TYPES((N)+20, PLUS_, TMS); \ + SEMIRING_TYPES((N)+30, TIMES_, TMS); \ + } while(0) + +#define SEMIRING_BOOL_GROUP(N, TMS) do { \ + SEMIRING_TYPES((N), LOR_, TMS); \ + SEMIRING_TYPES((N)+10, LAND_, TMS); \ + SEMIRING_TYPES((N)+20, LXOR_, TMS); \ + SEMIRING_TYPES((N)+30, EQ_, TMS); \ + } while(0) + +#define SEMIRING_PURE_BOOL_GROUP(N) do { \ + SEMIRING_PURE_BOOL((N), LOR_); \ + SEMIRING_PURE_BOOL((N)+10, LAND_); \ + SEMIRING_PURE_BOOL((N)+20, LXOR_); \ + SEMIRING_PURE_BOOL((N)+30, EQ_); \ + } while(0) + +#define BINOP(N, PRE, OP, TYP) do { \ + strlcpy(binops[(N)].name, #OP #TYP, 255); \ + binops[(N)].B = PRE ## OP ## TYP; \ + } while (0) + +#define BINOP_TYPES(N, PRE, OP) do { \ + BINOP (N, PRE, OP, INT8); \ + BINOP(N+1, PRE, OP, UINT8); \ + BINOP(N+2, PRE, OP, INT16); \ + BINOP(N+3, PRE, OP, UINT16); \ + BINOP(N+4, PRE, OP, INT32); \ + BINOP(N+5, PRE, OP, UINT32); \ + BINOP(N+6, PRE, OP, INT64); \ + BINOP(N+7, PRE, OP, UINT64); \ + BINOP(N+8, PRE, OP, FP32); \ + BINOP(N+9, PRE, OP, FP64); \ + BINOP (N+10, PRE, OP, BOOL); \ + } while(0) + + +#define UOP(N, PRE, OP, TYP) do { \ + strlcpy(uops[(N)].name, #OP #TYP, 255); \ + uops[(N)].U = PRE ## OP ## TYP; \ + } while (0) + +#define UOP_TYPES(N, PRE, OP) do { \ + UOP (N, PRE, OP, INT8); \ + UOP(N+1, PRE, OP, UINT8); \ + UOP(N+2, PRE, OP, INT16); \ + UOP(N+3, PRE, OP, UINT16); \ + UOP(N+4, PRE, OP, INT32); \ + UOP(N+5, PRE, OP, UINT32); \ + UOP(N+6, PRE, OP, INT64); \ + UOP(N+7, PRE, OP, UINT64); \ + UOP(N+8, PRE, OP, FP32); \ + UOP(N+9, PRE, OP, FP64); \ + } while(0) + +#define RETURN_TYPECHCK1(A, B, OP, TYP) \ + if ((A) == GrB_##TYP || (B) == GrB_##TYP) \ + return #OP "_" #TYP + +#define RETURN_TYPECHCK2(A, B, TYP) \ + if ((A) == GrB_##TYP || (B) == GrB_##TYP) \ + return GrB_##TYP #define GETARG_DESCRIPTOR_VAL(ARG, DESC, FIELD, VAL) do { \ - char *desc_val; \ - if (!PG_ARGISNULL(ARG)) { \ - (desc_val) = text_to_cstring(PG_GETARG_TEXT_PP(ARG)); \ - if (strcmp((desc_val), "default") == 0) { \ - CHECKD(GrB_Descriptor_set((DESC), GrB_##FIELD, GxB_DEFAULT), DESC); \ - } else if (strcmp((desc_val), "replace") == 0) { \ - CHECKD(GrB_Descriptor_set((DESC), GrB_##FIELD, GrB_##VAL), DESC); \ - } else if (strcmp((desc_val), "scmp") == 0) { \ - CHECKD(GrB_Descriptor_set((DESC), GrB_##FIELD, GrB_##VAL), DESC); \ - } else if (strcmp((desc_val), "tran") == 0) { \ - CHECKD(GrB_Descriptor_set((DESC), GrB_##FIELD, GrB_##VAL), DESC); \ - } else \ - elog(ERROR, "unknown outp descriptor value %s", desc_val); \ - } \ - } while(0) - -#define GET_DESCRIPTOR(N, D) do { \ - CHECKD(GrB_Descriptor_new(&D), D); \ - GETARG_DESCRIPTOR_VAL(N, D, OUTP, REPLACE); \ - GETARG_DESCRIPTOR_VAL(N+1, D, MASK, COMP_STRUCTURE); \ - GETARG_DESCRIPTOR_VAL(N+2, D, INP0, TRAN); \ - GETARG_DESCRIPTOR_VAL(N+3, D, INP1, TRAN); \ - } while (0) + char *desc_val; \ + if (!PG_ARGISNULL(ARG)) { \ + (desc_val) = text_to_cstring(PG_GETARG_TEXT_PP(ARG)); \ + if (strcmp((desc_val), "default") == 0) { \ + CHECKD(GrB_Descriptor_set((DESC), GrB_##FIELD, GxB_DEFAULT), DESC); \ + } else if (strcmp((desc_val), "replace") == 0) { \ + CHECKD(GrB_Descriptor_set((DESC), GrB_##FIELD, GrB_##VAL), DESC); \ + } else if (strcmp((desc_val), "scmp") == 0) { \ + CHECKD(GrB_Descriptor_set((DESC), GrB_##FIELD, GrB_##VAL), DESC); \ + } else if (strcmp((desc_val), "tran") == 0) { \ + CHECKD(GrB_Descriptor_set((DESC), GrB_##FIELD, GrB_##VAL), DESC); \ + } else \ + elog(ERROR, "unknown outp descriptor value %s", desc_val); \ + } \ + } while(0) + +#define GET_DESCRIPTOR(N, D) do { \ + CHECKD(GrB_Descriptor_new(&D), D); \ + GETARG_DESCRIPTOR_VAL(N, D, OUTP, REPLACE); \ + GETARG_DESCRIPTOR_VAL(N+1, D, MASK, COMP_STRUCTURE); \ + GETARG_DESCRIPTOR_VAL(N+2, D, INP0, TRAN); \ + GETARG_DESCRIPTOR_VAL(N+3, D, INP1, TRAN); \ + } while (0) void _PG_init(void); @@ -464,3 +473,8 @@ void free_function(void*); #define IMPORT_EXPORT // Use import export #endif /* PGGRAPHBLAS_H */ + +/* Local Variables: */ +/* mode: c */ +/* c-file-style: "postgresql" */ +/* End: */ diff --git a/src/type.c b/src/type.c index 903682b..aa5c991 100644 --- a/src/type.c +++ b/src/type.c @@ -1,172 +1,192 @@ -GrB_Semiring lookup_semiring(char *name) { - for (int i = 0; i < 960; i++) { - if (strcasecmp(semirings[i].name, name) == 0) - return semirings[i].R; - } - return NULL; +GrB_Semiring lookup_semiring(char *name) +{ + for (int i = 0; i < 960; i++) + { + if (strcasecmp(semirings[i].name, name) == 0) + return semirings[i].R; + } + return NULL; } -GrB_BinaryOp lookup_binop(char *name) { - for (int i = 0; i < 256; i++) { - if (strcasecmp(binops[i].name, name) == 0) - return binops[i].B; - } - return NULL; +GrB_BinaryOp lookup_binop(char *name) +{ + for (int i = 0; i < 256; i++) + { + if (strcasecmp(binops[i].name, name) == 0) + return binops[i].B; + } + return NULL; } -GrB_Type mxm_type(OS_Matrix *left, OS_Matrix *right) { - GrB_Info info; - GrB_Type atype, btype; - CHECKD(GxB_Matrix_type(&atype, left->M), left->M); - CHECKD(GxB_Matrix_type(&btype, right->M), right->M); - RETURN_TYPECHCK2(atype, btype, FP64); - RETURN_TYPECHCK2(atype, btype, FP32); - RETURN_TYPECHCK2(atype, btype, INT64); - RETURN_TYPECHCK2(atype, btype, INT32); - RETURN_TYPECHCK2(atype, btype, INT16); - RETURN_TYPECHCK2(atype, btype, BOOL); - return NULL; +GrB_Type mxm_type(OS_Matrix *left, OS_Matrix *right) +{ + GrB_Info info; + GrB_Type atype, btype; + CHECKD(GxB_Matrix_type(&atype, left->M), left->M); + CHECKD(GxB_Matrix_type(&btype, right->M), right->M); + RETURN_TYPECHCK2(atype, btype, FP64); + RETURN_TYPECHCK2(atype, btype, FP32); + RETURN_TYPECHCK2(atype, btype, INT64); + RETURN_TYPECHCK2(atype, btype, INT32); + RETURN_TYPECHCK2(atype, btype, INT16); + RETURN_TYPECHCK2(atype, btype, BOOL); + return NULL; } -GrB_Type mxv_type(OS_Matrix *left, OS_Vector *right) { - GrB_Info info; - GrB_Type atype, btype; - CHECKD(GxB_Matrix_type(&atype, left->M), left->M); - CHECKD(GxB_Vector_type(&btype, right->V), right->V); - RETURN_TYPECHCK2(atype, btype, FP64); - RETURN_TYPECHCK2(atype, btype, FP32); - RETURN_TYPECHCK2(atype, btype, INT64); - RETURN_TYPECHCK2(atype, btype, INT32); - RETURN_TYPECHCK2(atype, btype, INT16); - RETURN_TYPECHCK2(atype, btype, BOOL); - return NULL; +GrB_Type mxv_type(OS_Matrix *left, OS_Vector *right) +{ + GrB_Info info; + GrB_Type atype, btype; + CHECKD(GxB_Matrix_type(&atype, left->M), left->M); + CHECKD(GxB_Vector_type(&btype, right->V), right->V); + RETURN_TYPECHCK2(atype, btype, FP64); + RETURN_TYPECHCK2(atype, btype, FP32); + RETURN_TYPECHCK2(atype, btype, INT64); + RETURN_TYPECHCK2(atype, btype, INT32); + RETURN_TYPECHCK2(atype, btype, INT16); + RETURN_TYPECHCK2(atype, btype, BOOL); + return NULL; } -GrB_Type vxm_type(OS_Vector *left, OS_Matrix *right) { - GrB_Info info; - GrB_Type atype, btype; - CHECKD(GxB_Vector_type(&atype, left->V), left->V); - CHECKD(GxB_Matrix_type(&btype, right->M), right->M); - RETURN_TYPECHCK2(atype, btype, FP64); - RETURN_TYPECHCK2(atype, btype, FP32); - RETURN_TYPECHCK2(atype, btype, INT64); - RETURN_TYPECHCK2(atype, btype, INT32); - RETURN_TYPECHCK2(atype, btype, INT16); - RETURN_TYPECHCK2(atype, btype, BOOL); - return NULL; +GrB_Type vxm_type(OS_Vector *left, OS_Matrix *right) +{ + GrB_Info info; + GrB_Type atype, btype; + CHECKD(GxB_Vector_type(&atype, left->V), left->V); + CHECKD(GxB_Matrix_type(&btype, right->M), right->M); + RETURN_TYPECHCK2(atype, btype, FP64); + RETURN_TYPECHCK2(atype, btype, FP32); + RETURN_TYPECHCK2(atype, btype, INT64); + RETURN_TYPECHCK2(atype, btype, INT32); + RETURN_TYPECHCK2(atype, btype, INT16); + RETURN_TYPECHCK2(atype, btype, BOOL); + return NULL; } -char* mxm_semiring(OS_Matrix *left, OS_Matrix *right) { - GrB_Info info; - GrB_Type atype, btype; - CHECKD(GxB_Matrix_type(&atype, left->M), left->M); - CHECKD(GxB_Matrix_type(&btype, right->M), right->M); - RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, FP64); - RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, FP32); - RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT64); - RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT32); - RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT16); - RETURN_TYPECHCK1(atype, btype, LOR_LAND, BOOL); - return ""; +char* mxm_semiring(OS_Matrix *left, OS_Matrix *right) +{ + GrB_Info info; + GrB_Type atype, btype; + CHECKD(GxB_Matrix_type(&atype, left->M), left->M); + CHECKD(GxB_Matrix_type(&btype, right->M), right->M); + RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, FP64); + RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, FP32); + RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT64); + RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT32); + RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT16); + RETURN_TYPECHCK1(atype, btype, LOR_LAND, BOOL); + return ""; } -char* mxv_semiring(OS_Matrix *left, OS_Vector *right) { - GrB_Info info; - GrB_Type atype, btype; - CHECKD(GxB_Matrix_type(&atype, left->M), left->M); - CHECKD(GxB_Vector_type(&btype, right->V), right->V); - RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, FP64); - RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, FP32); - RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT64); - RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT32); - RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT16); - RETURN_TYPECHCK1(atype, btype, LOR_LAND, BOOL); - return ""; +char* mxv_semiring(OS_Matrix *left, OS_Vector *right) +{ + GrB_Info info; + GrB_Type atype, btype; + CHECKD(GxB_Matrix_type(&atype, left->M), left->M); + CHECKD(GxB_Vector_type(&btype, right->V), right->V); + RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, FP64); + RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, FP32); + RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT64); + RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT32); + RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT16); + RETURN_TYPECHCK1(atype, btype, LOR_LAND, BOOL); + return ""; } -char* vxm_semiring(OS_Vector *left, OS_Matrix *right) { - GrB_Info info; - GrB_Type atype, btype; - CHECKD(GxB_Vector_type(&atype, left->V), left->V); - CHECKD(GxB_Matrix_type(&btype, right->M), right->M); - RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, FP64); - RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, FP32); - RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT64); - RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT32); - RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT16); - RETURN_TYPECHCK1(atype, btype, LOR_LAND, BOOL); - return ""; +char* vxm_semiring(OS_Vector *left, OS_Matrix *right) +{ + GrB_Info info; + GrB_Type atype, btype; + CHECKD(GxB_Vector_type(&atype, left->V), left->V); + CHECKD(GxB_Matrix_type(&btype, right->M), right->M); + RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, FP64); + RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, FP32); + RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT64); + RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT32); + RETURN_TYPECHCK1(atype, btype, PLUS_TIMES, INT16); + RETURN_TYPECHCK1(atype, btype, LOR_LAND, BOOL); + return ""; } -char* matrix_times_binop(OS_Matrix *left, OS_Matrix *right) { - GrB_Info info; - GrB_Type type; - CHECKD(GxB_Matrix_type(&type, left->M), left->M); - return DEFAULT_TIMES_BINOP(type); +char* matrix_times_binop(OS_Matrix *left, OS_Matrix *right) +{ + GrB_Info info; + GrB_Type type; + CHECKD(GxB_Matrix_type(&type, left->M), left->M); + return DEFAULT_TIMES_BINOP(type); } -char* matrix_plus_binop(OS_Matrix *left, OS_Matrix *right) { - GrB_Info info; - GrB_Type type; - CHECKD(GxB_Matrix_type(&type, left->M), left->M); - return DEFAULT_PLUS_BINOP(type); +char* matrix_plus_binop(OS_Matrix *left, OS_Matrix *right) +{ + GrB_Info info; + GrB_Type type; + CHECKD(GxB_Matrix_type(&type, left->M), left->M); + return DEFAULT_PLUS_BINOP(type); } -char* vector_times_binop(OS_Vector *left, OS_Vector *right) { - GrB_Info info; - GrB_Type type; - CHECKD(GxB_Vector_type(&type, left->V), left->V); - return DEFAULT_TIMES_BINOP(type); +char* vector_times_binop(OS_Vector *left, OS_Vector *right) +{ + GrB_Info info; + GrB_Type type; + CHECKD(GxB_Vector_type(&type, left->V), left->V); + return DEFAULT_TIMES_BINOP(type); } -char* vector_plus_binop(OS_Vector *left, OS_Vector *right) { - GrB_Info info; - GrB_Type type; - CHECKD(GxB_Vector_type(&type, left->V), left->V); - return DEFAULT_PLUS_BINOP(type); +char* vector_plus_binop(OS_Vector *left, OS_Vector *right) +{ + GrB_Info info; + GrB_Type type; + CHECKD(GxB_Vector_type(&type, left->V), left->V); + return DEFAULT_PLUS_BINOP(type); } -char* grb_type_to_name(GrB_Type t) { - if ( t == GrB_BOOL ) - return "bool"; - if ( t == GrB_INT8 ) - return "char"; - if ( t == GrB_UINT8 ) - return "uchar"; - if ( t == GrB_INT16 ) - return "smallint"; - if ( t == GrB_UINT16 ) - return "usmallint"; - if ( t == GrB_INT32 ) - return "integer"; - if ( t == GrB_UINT32 ) - return "uinteger"; - if ( t == GrB_INT64 ) - return "bigint"; - if ( t == GrB_UINT64 ) - return "ubigint"; - if ( t == GrB_FP32 ) - return "real"; - if ( t == GrB_FP64 ) - return "float"; - return "unknown"; +char* grb_type_to_name(GrB_Type t) +{ + if ( t == GrB_BOOL ) + return "bool"; + if ( t == GrB_INT8 ) + return "char"; + if ( t == GrB_UINT8 ) + return "uchar"; + if ( t == GrB_INT16 ) + return "smallint"; + if ( t == GrB_UINT16 ) + return "usmallint"; + if ( t == GrB_INT32 ) + return "integer"; + if ( t == GrB_UINT32 ) + return "uinteger"; + if ( t == GrB_INT64 ) + return "bigint"; + if ( t == GrB_UINT64 ) + return "ubigint"; + if ( t == GrB_FP32 ) + return "real"; + if ( t == GrB_FP64 ) + return "float"; + return "unknown"; } /* #define SEMIRING(add, mul) \ */ -/* {"GxB_" #add #mul "INT8", GxB_ ## add ## mul ## INT8}, \ */ -/* {"GxB_" #add #mul "INT16", GxB_ ## add ## mul ## INT16}, \ */ -/* {"GxB_" #add #mul "INT32", GxB_ ## add ## mul ## INT32}, \ */ -/* {"GxB_" #add #mul "INT64", GxB_ ## add ## mul ## INT64}, \ */ +/* {"GxB_" #add #mul "INT8", GxB_ ## add ## mul ## INT8}, \ */ +/* {"GxB_" #add #mul "INT16", GxB_ ## add ## mul ## INT16}, \ */ +/* {"GxB_" #add #mul "INT32", GxB_ ## add ## mul ## INT32}, \ */ +/* {"GxB_" #add #mul "INT64", GxB_ ## add ## mul ## INT64}, \ */ /* struct OS_Semiring */ /* { */ -/* const char* name; */ -/* GrB_Semiring semiring; */ +/* const char* name; */ +/* GrB_Semiring semiring; */ /* } */ /* OS_Semiring[] = */ /* { */ /* SEMIRING(PLUS_, TIMES_); */ /* {"setinel", NULL} */ /* }; */ + +/* Local Variables: */ +/* mode: c */ +/* c-file-style: "postgresql" */ +/* End: */ diff --git a/src/vector.c b/src/vector.c index 65f6ea7..a636462 100644 --- a/src/vector.c +++ b/src/vector.c @@ -66,21 +66,21 @@ #define PRINT_FMT(v) "%i", v #include "vector.h" -#define SUFFIX _int64 // suffix for names -#define PG_TYPE int64 // postgres type -#define GB_TYPE GrB_INT64 // graphblas vector type -#define GB_DUP GrB_SECOND_INT64 // default duplicate index resolver -#define GB_MUL GrB_TIMES_INT64 // times bin op -#define GB_ADD GrB_PLUS_INT64 // times bin op -#define GB_EQ GxB_ISEQ_INT64 // equality operator +#define SUFFIX _int64 // suffix for names +#define PG_TYPE int64 // postgres type +#define GB_TYPE GrB_INT64 // graphblas vector type +#define GB_DUP GrB_SECOND_INT64 // default duplicate index resolver +#define GB_MUL GrB_TIMES_INT64 // times bin op +#define GB_ADD GrB_PLUS_INT64 // times bin op +#define GB_EQ GxB_ISEQ_INT64 // equality operator #define GB_NE GxB_ISNE_INT64 #define GB_RNG GxB_PLUS_TIMES_INT64 -#define PG_GET PG_GETARG_INT64 // how to get value args +#define PG_GET PG_GETARG_INT64 // how to get value args #define PG_RET PG_RETURN_INT64 -#define PG_DGT DatumGetInt64 // datum get type -#define PG_TGD Int64GetDatum // type get datum -#define PRINT_FMT(v) "%lu", v // printf fmt -#include "vector.h" // "call" template +#define PG_DGT DatumGetInt64 // datum get type +#define PG_TGD Int64GetDatum // type get datum +#define PRINT_FMT(v) "%lu", v // printf fmt +#include "vector.h" // "call" template #define SUFFIX _float4 #define PG_TYPE float4 @@ -116,238 +116,260 @@ /* MemoryContextCallback function to free matrices */ static void -context_callback_vector_free(void* a) { - OS_Vector *A = (OS_Vector *) a; - GrB_Vector_free(&A->V); +context_callback_vector_free(void* a) +{ + OS_Vector *A = (OS_Vector *) a; + GrB_Vector_free(&A->V); } /* Construct an empty flat vector. */ OS_FlatVector * -construct_empty_flat_vector(GrB_Index size, GrB_Type type) { - OS_FlatVector *result; - - result = (OS_FlatVector *) palloc0(sizeof(OS_FlatVector)); - SET_VARSIZE(result, sizeof(OS_FlatVector)); - result->size = size; - result->nvals = 0; - result->type = type; - return result; +construct_empty_flat_vector(GrB_Index size, GrB_Type type) +{ + OS_FlatVector *result; + + result = (OS_FlatVector *) palloc0(sizeof(OS_FlatVector)); + SET_VARSIZE(result, sizeof(OS_FlatVector)); + result->size = size; + result->nvals = 0; + result->type = type; + return result; } /* Helper function to always expanded datum -This is used by OS_GETARG_VECTOR */ + This is used by OS_GETARG_VECTOR */ OS_Vector * -DatumGetVector(Datum d) { - OS_Vector *A; - OS_FlatVector *flat; - - if (VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(d))) { - A = VectorGetEOHP(d); - Assert(A->ev_magic == vector_MAGIC); - return A; - } - flat = (OS_FlatVector*)PG_DETOAST_DATUM(d); - TYPE_APPLY(d, flat->type, expand_flat_vector, flat, CurrentMemoryContext); - return VectorGetEOHP(d); +DatumGetVector(Datum d) +{ + OS_Vector *A; + OS_FlatVector *flat; + + if (VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(d))) + { + A = VectorGetEOHP(d); + Assert(A->ev_magic == vector_MAGIC); + return A; + } + flat = (OS_FlatVector*)PG_DETOAST_DATUM(d); + TYPE_APPLY(d, flat->type, expand_flat_vector, flat, CurrentMemoryContext); + return VectorGetEOHP(d); } Datum vector_in(PG_FUNCTION_ARGS) { - OS_FlatVector *flat; - char *input; - size_t len; - int bc; - Datum d; - - input = PG_GETARG_CSTRING(0); - len = strlen(input); - bc = (len) / 2 + VARHDRSZ; - flat = palloc(bc); - hex_decode(input, len, (char*)flat); - TYPE_APPLY(d, flat->type, expand_flat_vector, flat, CurrentMemoryContext); - return d; + OS_FlatVector *flat; + char *input; + size_t len; + int bc; + Datum d; + + input = PG_GETARG_CSTRING(0); + len = strlen(input); + bc = (len) / 2 + VARHDRSZ; + flat = palloc(bc); + hex_decode(input, len, (char*)flat); + TYPE_APPLY(d, flat->type, expand_flat_vector, flat, CurrentMemoryContext); + return d; } Datum vector_out(PG_FUNCTION_ARGS) { - Size size; - char *rp, *result, *buf; - OS_Vector *A = OS_GETARG_VECTOR(0); - size = EOH_get_flat_size(&A->hdr); - buf = palloc(size); - EOH_flatten_into(&A->hdr, buf, size); - rp = result = palloc((size * 2) + 1); - rp += hex_encode(buf, size, rp); - *rp = '\0'; - PG_RETURN_CSTRING(result); + Size size; + char *rp, *result, *buf; + OS_Vector *A = OS_GETARG_VECTOR(0); + size = EOH_get_flat_size(&A->hdr); + buf = palloc(size); + EOH_flatten_into(&A->hdr, buf, size); + rp = result = palloc((size * 2) + 1); + rp += hex_encode(buf, size, rp); + *rp = '\0'; + PG_RETURN_CSTRING(result); } Datum -vector_ewise_mult(PG_FUNCTION_ARGS) { - OS_Vector *A, *B; - OS_Vector *C = NULL, *mask = NULL; - Datum d; - char *binop_name, *accum_name; - GrB_BinaryOp binop = NULL, accum = NULL; - GrB_Descriptor desc = NULL; - GrB_Info info; - - A = OS_GETARG_VECTOR(0); - B = OS_GETARG_VECTOR(1); - - accum_name = NULL; - binop_name = vector_times_binop(A, B); - - if (PG_NARGS() > 2) { - C = PG_ARGISNULL(2) ? NULL : OS_GETARG_VECTOR(2); - mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_VECTOR(3); - binop_name = PG_ARGISNULL(4) ? - binop_name : text_to_cstring(PG_GETARG_TEXT_PP(4)); - accum_name = PG_ARGISNULL(5) ? - accum_name : text_to_cstring(PG_GETARG_TEXT_PP(5)); - if (PG_NARGS() > 6) { - GET_DESCRIPTOR(6, desc); - } - } - - binop = lookup_binop(binop_name); - if (binop == NULL) - elog(ERROR, "unknown binop name %s", binop_name); - if (accum_name != NULL) - accum = lookup_binop(accum_name); - - - TYPE_APPLY(d, A->type, vector_ewise_mult, A, B, C, mask, binop, accum, desc); - return d; +vector_ewise_mult(PG_FUNCTION_ARGS) +{ + OS_Vector *A, *B; + OS_Vector *C = NULL, *mask = NULL; + Datum d; + char *binop_name, *accum_name; + GrB_BinaryOp binop = NULL, accum = NULL; + GrB_Descriptor desc = NULL; + GrB_Info info; + + A = OS_GETARG_VECTOR(0); + B = OS_GETARG_VECTOR(1); + + accum_name = NULL; + binop_name = vector_times_binop(A, B); + + if (PG_NARGS() > 2) + { + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_VECTOR(2); + mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_VECTOR(3); + binop_name = PG_ARGISNULL(4) ? + binop_name : text_to_cstring(PG_GETARG_TEXT_PP(4)); + accum_name = PG_ARGISNULL(5) ? + accum_name : text_to_cstring(PG_GETARG_TEXT_PP(5)); + if (PG_NARGS() > 6) + { + GET_DESCRIPTOR(6, desc); + } + } + + binop = lookup_binop(binop_name); + if (binop == NULL) + elog(ERROR, "unknown binop name %s", binop_name); + if (accum_name != NULL) + accum = lookup_binop(accum_name); + + + TYPE_APPLY(d, A->type, vector_ewise_mult, A, B, C, mask, binop, accum, desc); + return d; } Datum -vector_ewise_add(PG_FUNCTION_ARGS) { - OS_Vector *A, *B; - OS_Vector *C = NULL, *mask = NULL; - Datum d; - char *binop_name, *accum_name; - GrB_BinaryOp binop = NULL, accum = NULL; - GrB_Descriptor desc = NULL; - GrB_Info info; - - A = OS_GETARG_VECTOR(0); - B = OS_GETARG_VECTOR(1); - - accum_name = NULL; - binop_name = vector_times_binop(A, B); - - if (PG_NARGS() > 2) { - C = PG_ARGISNULL(2) ? NULL : OS_GETARG_VECTOR(2); - mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_VECTOR(3); - binop_name = PG_ARGISNULL(4) ? - binop_name : text_to_cstring(PG_GETARG_TEXT_PP(4)); - accum_name = PG_ARGISNULL(5) ? - accum_name : text_to_cstring(PG_GETARG_TEXT_PP(5)); - if (PG_NARGS() > 6) { - GET_DESCRIPTOR(6, desc); - } - } - - binop = lookup_binop(binop_name); - if (binop == NULL) - elog(ERROR, "unknown binop name %s", binop_name); - if (accum_name != NULL) - accum = lookup_binop(accum_name); - - - TYPE_APPLY(d, A->type, vector_ewise_add, A, B, C, mask, binop, accum, desc); - return d; +vector_ewise_add(PG_FUNCTION_ARGS) +{ + OS_Vector *A, *B; + OS_Vector *C = NULL, *mask = NULL; + Datum d; + char *binop_name, *accum_name; + GrB_BinaryOp binop = NULL, accum = NULL; + GrB_Descriptor desc = NULL; + GrB_Info info; + + A = OS_GETARG_VECTOR(0); + B = OS_GETARG_VECTOR(1); + + accum_name = NULL; + binop_name = vector_times_binop(A, B); + + if (PG_NARGS() > 2) + { + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_VECTOR(2); + mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_VECTOR(3); + binop_name = PG_ARGISNULL(4) ? + binop_name : text_to_cstring(PG_GETARG_TEXT_PP(4)); + accum_name = PG_ARGISNULL(5) ? + accum_name : text_to_cstring(PG_GETARG_TEXT_PP(5)); + if (PG_NARGS() > 6) + { + GET_DESCRIPTOR(6, desc); + } + } + + binop = lookup_binop(binop_name); + if (binop == NULL) + elog(ERROR, "unknown binop name %s", binop_name); + if (accum_name != NULL) + accum = lookup_binop(accum_name); + + + TYPE_APPLY(d, A->type, vector_ewise_add, A, B, C, mask, binop, accum, desc); + return d; } Datum -vector_nvals(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Vector *vec; - GrB_Index nvals; - vec = OS_GETARG_VECTOR(0); - CHECKD(GrB_Vector_nvals(&nvals, vec->V), vec->V); - return Int64GetDatum(nvals); +vector_nvals(PG_FUNCTION_ARGS) +{ + GrB_Info info; + OS_Vector *vec; + GrB_Index nvals; + vec = OS_GETARG_VECTOR(0); + CHECKD(GrB_Vector_nvals(&nvals, vec->V), vec->V); + return Int64GetDatum(nvals); } Datum -vector_size(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Vector *vec; - GrB_Index size; - vec = OS_GETARG_VECTOR(0); - CHECKD(GrB_Vector_size(&size, vec->V), vec->V); - return Int64GetDatum(size); +vector_size(PG_FUNCTION_ARGS) +{ + GrB_Info info; + OS_Vector *vec; + GrB_Index size; + vec = OS_GETARG_VECTOR(0); + CHECKD(GrB_Vector_size(&size, vec->V), vec->V); + return Int64GetDatum(size); } Datum -vector_eq(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Vector *A, *B; - bool result; +vector_eq(PG_FUNCTION_ARGS) +{ + GrB_Info info; + OS_Vector *A, *B; + bool result; - A = OS_GETARG_VECTOR(0); - B = OS_GETARG_VECTOR(1); + A = OS_GETARG_VECTOR(0); + B = OS_GETARG_VECTOR(1); - result = true; - PG_RETURN_BOOL(result); + result = true; + PG_RETURN_BOOL(result); } Datum -vector_ne(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Vector *A, *B; - bool result; +vector_ne(PG_FUNCTION_ARGS) +{ + GrB_Info info; + OS_Vector *A, *B; + bool result; - A = OS_GETARG_VECTOR(0); - B = OS_GETARG_VECTOR(1); + A = OS_GETARG_VECTOR(0); + B = OS_GETARG_VECTOR(1); - result = true; - PG_RETURN_BOOL(!result); + result = true; + PG_RETURN_BOOL(!result); } Datum -vector_xtract(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Vector *A, *B, *C = NULL; - GrB_Index size, *indexes; +vector_xtract(PG_FUNCTION_ARGS) +{ + GrB_Info info; + OS_Vector *A, *B, *C = NULL; + GrB_Index size, *indexes; - A = OS_GETARG_VECTOR(0); - B = OS_GETARG_VECTOR(1); - C = PG_ARGISNULL(2) ? NULL : OS_GETARG_VECTOR(2); + A = OS_GETARG_VECTOR(0); + B = OS_GETARG_VECTOR(1); + C = PG_ARGISNULL(2) ? NULL : OS_GETARG_VECTOR(2); - CHECKD(GrB_Vector_size(&size, A->V), A->V); - if (C == NULL) { - TYPE_APPLY(C, A->type, construct_empty_expanded_vector, size, CurrentMemoryContext); - } + CHECKD(GrB_Vector_size(&size, A->V), A->V); + if (C == NULL) + { + TYPE_APPLY(C, A->type, construct_empty_expanded_vector, size, CurrentMemoryContext); + } - TYPE_APPLY(indexes, A->type, extract_indexes, B, size); + TYPE_APPLY(indexes, A->type, extract_indexes, B, size); - CHECKD(GrB_Vector_extract(C->V, NULL, NULL, A->V, indexes, size, NULL), A->V); - OS_RETURN_VECTOR(C); + CHECKD(GrB_Vector_extract(C->V, NULL, NULL, A->V, indexes, size, NULL), A->V); + OS_RETURN_VECTOR(C); } Datum -vector_print(PG_FUNCTION_ARGS) { - OS_Vector *A; - char *result, *buf; - size_t size; - FILE *fp; - int level; - A = OS_GETARG_VECTOR(0); - level = PG_GETARG_INT32(1); +vector_print(PG_FUNCTION_ARGS) +{ + OS_Vector *A; + char *result, *buf; + size_t size; + FILE *fp; + int level; + A = OS_GETARG_VECTOR(0); + level = PG_GETARG_INT32(1); - fp = open_memstream(&buf, &size); - if (fp == NULL) - elog(ERROR, "unable to open memstream for vector_print"); - GxB_fprint(A->V, level, fp); - fflush(fp); - result = palloc(size + 1); - memcpy(result, buf, size+1); - free(buf); - PG_RETURN_TEXT_P(cstring_to_text_with_len(result, size+1)); + fp = open_memstream(&buf, &size); + if (fp == NULL) + elog(ERROR, "unable to open memstream for vector_print"); + GxB_fprint(A->V, level, fp); + fflush(fp); + result = palloc(size + 1); + memcpy(result, buf, size+1); + free(buf); + PG_RETURN_TEXT_P(cstring_to_text_with_len(result, size+1)); } + +/* Local Variables: */ +/* mode: c */ +/* c-file-style: "postgresql" */ +/* End: */ diff --git a/src/vector.h b/src/vector.h index 3576f0f..fd7efe8 100644 --- a/src/vector.h +++ b/src/vector.h @@ -1,226 +1,239 @@ /* This is a "header template" see vector.c for specific instanciations */ -typedef struct FN(OS_Vector_ExtractState) { - OS_Vector *vec; - GrB_Index *indices; - PG_TYPE *vals; +typedef struct FN(OS_Vector_ExtractState) +{ + OS_Vector *vec; + GrB_Index *indices; + PG_TYPE *vals; } FN(OS_Vector_ExtractState); /* Expanded Object Header "methods" for flattening vectors for storage */ static Size FN(vector_get_flat_size)(ExpandedObjectHeader *eohptr); static void FN(vector_flatten_into)(ExpandedObjectHeader *eohptr, - void *result, Size allocated_size); + void *result, Size allocated_size); -static const ExpandedObjectMethods FN(vector_methods) = { - FN(vector_get_flat_size), - FN(vector_flatten_into) +static const ExpandedObjectMethods FN(vector_methods) = +{ + FN(vector_get_flat_size), + FN(vector_flatten_into) }; /* Utility function that expands a flattened vector datum. */ Datum FN(expand_flat_vector)(OS_FlatVector *flat, - MemoryContext parentcontext); + MemoryContext parentcontext); /* Helper function that creates an expanded empty vector. */ OS_Vector * FN(construct_empty_expanded_vector)(GrB_Index size, - MemoryContext parentcontext); + MemoryContext parentcontext); /* Compute size of storage needed for vector */ static Size -FN(vector_get_flat_size)(ExpandedObjectHeader *eohptr) { - GrB_Info info; - OS_Vector *A = (OS_Vector *) eohptr; - GrB_Index size, nvals; +FN(vector_get_flat_size)(ExpandedObjectHeader *eohptr) +{ + GrB_Info info; + OS_Vector *A = (OS_Vector *) eohptr; + GrB_Index size, nvals; - Assert(A->ev_magic == vector_MAGIC); + Assert(A->ev_magic == vector_MAGIC); - if (A->flat_size) - return A->flat_size; + if (A->flat_size) + return A->flat_size; - CHECKD(GrB_Vector_size(&size, A->V), A->V); - CHECKD(GrB_Vector_nvals(&nvals, A->V), A->V); + CHECKD(GrB_Vector_size(&size, A->V), A->V); + CHECKD(GrB_Vector_nvals(&nvals, A->V), A->V); - A->flat_size = OS_VECTOR_OVERHEAD(); - return A->flat_size; + A->flat_size = OS_VECTOR_OVERHEAD(); + return A->flat_size; } /* Flatten vector into allocated result buffer */ static void FN(vector_flatten_into)(ExpandedObjectHeader *eohptr, - void *result, Size allocated_size) { - GrB_Info info; - GrB_Index size, nvals; - OS_Vector *A = (OS_Vector *) eohptr; - OS_FlatVector *flat = (OS_FlatVector *) result; + void *result, Size allocated_size) +{ + GrB_Info info; + GrB_Index size, nvals; + OS_Vector *A = (OS_Vector *) eohptr; + OS_FlatVector *flat = (OS_FlatVector *) result; - Assert(A->ev_magic == vector_MAGIC); - Assert(allocated_size == A->flat_size); + Assert(A->ev_magic == vector_MAGIC); + Assert(allocated_size == A->flat_size); - memset(flat, 0, allocated_size); + memset(flat, 0, allocated_size); - CHECKV(GrB_Vector_nvals(&nvals, A->V), A->V); - CHECKV(GrB_Vector_size(&size, A->V), A->V); + CHECKV(GrB_Vector_nvals(&nvals, A->V), A->V); + CHECKV(GrB_Vector_size(&size, A->V), A->V); - flat->size = size; - flat->nvals = nvals; - flat->type = GB_TYPE; + flat->size = size; + flat->nvals = nvals; + flat->type = GB_TYPE; - SET_VARSIZE(flat, allocated_size); + SET_VARSIZE(flat, allocated_size); } /* Expand a flat vector. */ Datum FN(expand_flat_vector)(OS_FlatVector *flat, - MemoryContext parentcontext) { - GrB_Info info; + MemoryContext parentcontext) +{ + GrB_Info info; - OS_Vector *A; + OS_Vector *A; - MemoryContext objcxt, oldcxt; - MemoryContextCallback *ctxcb; + MemoryContext objcxt, oldcxt; + MemoryContextCallback *ctxcb; - GrB_Index size, nvals; - GrB_Type type; + GrB_Index size, nvals; + GrB_Type type; - /* Create a new context that will hold the expanded object. */ - objcxt = AllocSetContextCreate( - parentcontext, - "expanded vector", - ALLOCSET_DEFAULT_SIZES); + /* Create a new context that will hold the expanded object. */ + objcxt = AllocSetContextCreate( + parentcontext, + "expanded vector", + ALLOCSET_DEFAULT_SIZES); - /* Allocate a new expanded vector */ - A = (OS_Vector*)MemoryContextAlloc( - objcxt, - sizeof(OS_Vector)); + /* Allocate a new expanded vector */ + A = (OS_Vector*)MemoryContextAlloc( + objcxt, + sizeof(OS_Vector)); - /* Initialize the ExpandedObjectHeader member with flattening - * methods and new object context */ - EOH_init_header(&A->hdr, &FN(vector_methods), objcxt); + /* Initialize the ExpandedObjectHeader member with flattening + * methods and new object context */ + EOH_init_header(&A->hdr, &FN(vector_methods), objcxt); - /* Used for debugging checks */ - A->ev_magic = vector_MAGIC; + /* Used for debugging checks */ + A->ev_magic = vector_MAGIC; - /* Switch to new object context */ - oldcxt = MemoryContextSwitchTo(objcxt); + /* Switch to new object context */ + oldcxt = MemoryContextSwitchTo(objcxt); - /* Get dimensional information from flat */ - size = flat->size; - nvals = flat->nvals; - type = flat->type; + /* Get dimensional information from flat */ + size = flat->size; + nvals = flat->nvals; + type = flat->type; - /* Create a context callback to free vector when context is cleared */ - ctxcb = (MemoryContextCallback*)MemoryContextAlloc( - objcxt, - sizeof(MemoryContextCallback)); + /* Create a context callback to free vector when context is cleared */ + ctxcb = (MemoryContextCallback*)MemoryContextAlloc( + objcxt, + sizeof(MemoryContextCallback)); - ctxcb->func = context_callback_vector_free; - ctxcb->arg = A; - MemoryContextRegisterResetCallback(objcxt, ctxcb); + ctxcb->func = context_callback_vector_free; + ctxcb->arg = A; + MemoryContextRegisterResetCallback(objcxt, ctxcb); - A->type = type; - A->flat_size = 0; + A->type = type; + A->flat_size = 0; - /* Switch back to old context */ - MemoryContextSwitchTo(oldcxt); - OS_RETURN_VECTOR(A); + /* Switch back to old context */ + MemoryContextSwitchTo(oldcxt); + OS_RETURN_VECTOR(A); } /* Construct an empty expanded vector. */ OS_Vector * FN(construct_empty_expanded_vector)(GrB_Index size, - MemoryContext parentcontext) { - OS_FlatVector *flat; - Datum d; - flat = construct_empty_flat_vector(size, GB_TYPE); - d = FN(expand_flat_vector)(flat, parentcontext); - pfree(flat); - return (OS_Vector *) DatumGetEOHP(d); + MemoryContext parentcontext) +{ + OS_FlatVector *flat; + Datum d; + flat = construct_empty_flat_vector(size, GB_TYPE); + d = FN(expand_flat_vector)(flat, parentcontext); + pfree(flat); + return (OS_Vector *) DatumGetEOHP(d); } Datum -FN(vector_empty)(PG_FUNCTION_ARGS) { - OS_Vector *retval; - GrB_Index max_index; - max_index = PG_GETARG_INT64(0); - retval = FN(construct_empty_expanded_vector)(max_index, CurrentMemoryContext); - OS_RETURN_VECTOR(retval); - } +FN(vector_empty)(PG_FUNCTION_ARGS) +{ + OS_Vector *retval; + GrB_Index max_index; + max_index = PG_GETARG_INT64(0); + retval = FN(construct_empty_expanded_vector)(max_index, CurrentMemoryContext); + OS_RETURN_VECTOR(retval); +} /* cast implementation function. */ Datum -FN(vector)(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Vector *retval; - ArrayType *indexes, *vals; - int *idims, *vdims; - int i; - GrB_Index vcount, size; - - GrB_Index *row_indices; - PG_TYPE *values; - ArrayIterator array_iterator; - Datum value; - bool isnull; - - if (PG_NARGS() == 1) { - indexes = NULL; - vals = PG_GETARG_ARRAYTYPE_P(0); - if (ARR_HASNULL(vals)) - ereport(ERROR, (errmsg("Value array may not contain NULLs"))); - vdims = ARR_DIMS(vals); - } else { - indexes = PG_GETARG_ARRAYTYPE_P(0); - vals = PG_GETARG_ARRAYTYPE_P(1); - if (ARR_HASNULL(vals) || ARR_HASNULL(indexes)) - ereport(ERROR, (errmsg("Neither value or indexc arrays may not contain NULLs"))); - - idims = ARR_DIMS(indexes); - vdims = ARR_DIMS(vals); - - if (idims[0] != vdims[0]) - ereport(ERROR, (errmsg("Index and Value arrays must be same size."))); - } - - size = vcount = vdims[0]; - - if (PG_NARGS() > 2 && !PG_ARGISNULL(2)) - size = PG_GETARG_INT64(2); - - row_indices = (GrB_Index*) palloc0(sizeof(GrB_Index) * vcount); - values = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * vcount); - - i = 0; - array_iterator = array_create_iterator(vals, 0, NULL); - while (array_iterate(array_iterator, &value, &isnull)) +FN(vector)(PG_FUNCTION_ARGS) +{ + GrB_Info info; + OS_Vector *retval; + ArrayType *indexes, *vals; + int *idims, *vdims; + int i; + GrB_Index vcount, size; + + GrB_Index *row_indices; + PG_TYPE *values; + ArrayIterator array_iterator; + Datum value; + bool isnull; + + if (PG_NARGS() == 1) + { + indexes = NULL; + vals = PG_GETARG_ARRAYTYPE_P(0); + if (ARR_HASNULL(vals)) + ereport(ERROR, (errmsg("Value array may not contain NULLs"))); + vdims = ARR_DIMS(vals); + } + else { - if (indexes == NULL) - row_indices[i] = i; - values[i] = PG_DGT(value); - i++; - } - - i = 0; - if (indexes != NULL) { - array_iterator = array_create_iterator(indexes, 0, NULL); - while (array_iterate(array_iterator, &value, &isnull)) { - row_indices[i] = DatumGetInt64(value); - if (row_indices[i] > size) - size = row_indices[i] + 1; - i++; - } - } - - retval = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); - - CHECKD(GrB_Vector_build(retval->V, - row_indices, - values, - vcount, - GB_DUP), retval->V); - - OS_RETURN_VECTOR(retval); + indexes = PG_GETARG_ARRAYTYPE_P(0); + vals = PG_GETARG_ARRAYTYPE_P(1); + if (ARR_HASNULL(vals) || ARR_HASNULL(indexes)) + ereport(ERROR, (errmsg("Neither value or indexc arrays may not contain NULLs"))); + + idims = ARR_DIMS(indexes); + vdims = ARR_DIMS(vals); + + if (idims[0] != vdims[0]) + ereport(ERROR, (errmsg("Index and Value arrays must be same size."))); + } + + size = vcount = vdims[0]; + + if (PG_NARGS() > 2 && !PG_ARGISNULL(2)) + size = PG_GETARG_INT64(2); + + row_indices = (GrB_Index*) palloc0(sizeof(GrB_Index) * vcount); + values = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * vcount); + + i = 0; + array_iterator = array_create_iterator(vals, 0, NULL); + while (array_iterate(array_iterator, &value, &isnull)) + { + if (indexes == NULL) + row_indices[i] = i; + values[i] = PG_DGT(value); + i++; + } + + i = 0; + if (indexes != NULL) + { + array_iterator = array_create_iterator(indexes, 0, NULL); + while (array_iterate(array_iterator, &value, &isnull)) + { + row_indices[i] = DatumGetInt64(value); + if (row_indices[i] > size) + size = row_indices[i] + 1; + i++; + } + } + + retval = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); + + CHECKD(GrB_Vector_build(retval->V, + row_indices, + values, + vcount, + GB_DUP), retval->V); + + OS_RETURN_VECTOR(retval); } #include "vector_ops.h" @@ -239,3 +252,8 @@ FN(vector)(PG_FUNCTION_ARGS) { #undef PG_DGT #undef PG_TGD #undef PRINT_FMT + +/* Local Variables: */ +/* mode: c */ +/* c-file-style: "postgresql" */ +/* End: */ diff --git a/src/vector_ops.h b/src/vector_ops.h index 0792a36..1447e79 100644 --- a/src/vector_ops.h +++ b/src/vector_ops.h @@ -1,26 +1,25 @@ - Datum FN(vector_out)(OS_Vector *vec); Datum FN(vector_ewise_mult)(OS_Vector *A, - OS_Vector *B, - OS_Vector *C, - OS_Vector *mask, - GrB_BinaryOp binop, - GrB_BinaryOp accum, - GrB_Descriptor desc); + OS_Vector *B, + OS_Vector *C, + OS_Vector *mask, + GrB_BinaryOp binop, + GrB_BinaryOp accum, + GrB_Descriptor desc); Datum FN(vector_ewise_add)(OS_Vector *A, - OS_Vector *B, - OS_Vector *C, - OS_Vector *mask, - GrB_BinaryOp binop, - GrB_BinaryOp accum, - GrB_Descriptor desc); + OS_Vector *B, + OS_Vector *C, + OS_Vector *mask, + GrB_BinaryOp binop, + GrB_BinaryOp accum, + GrB_Descriptor desc); Datum FN(vector_eq)(OS_Vector *A, - OS_Vector *B); + OS_Vector *B); Datum FN(vector_ne)(OS_Vector *A, - OS_Vector *B); + OS_Vector *B); GrB_Index *FN(extract_indexes)(OS_Vector *A, GrB_Index size); @@ -32,172 +31,190 @@ PG_FUNCTION_INFO_V1(FN(vector_assign)); PG_FUNCTION_INFO_V1(FN(vector_set_element)); Datum -FN(vector_elements)(PG_FUNCTION_ARGS) { - GrB_Info info; - FuncCallContext *funcctx; - TupleDesc tupdesc; - Datum result; - - Datum values[3]; - bool nulls[2] = {false, false}; - HeapTuple tuple; - GrB_Index size = 0; - OS_Vector *vec; - FN(OS_Vector_ExtractState) *state; - - if (SRF_IS_FIRSTCALL()) { - MemoryContext oldcontext; - - funcctx = SRF_FIRSTCALL_INIT(); - oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - vec = (OS_Vector *) OS_GETARG_VECTOR(0); - - state = (FN(OS_Vector_ExtractState)*)palloc(sizeof(FN(OS_Vector_ExtractState))); - CHECKD(GrB_Vector_size(&size, vec->V), vec->V); - - state->indices = (GrB_Index*) palloc0(sizeof(GrB_Index) * size); - state->vals = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * size); - - CHECKD(GrB_Vector_extractTuples(state->indices, - state->vals, - &size, - vec->V), vec->V); - state->vec = vec; - funcctx->max_calls = size; - funcctx->user_fctx = (void*)state; - - /* One-time setup code appears here: */ - if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("function returning record called in context " - "that cannot accept type record"))); - BlessTupleDesc(tupdesc); - funcctx->tuple_desc = tupdesc; - - MemoryContextSwitchTo(oldcontext); - } - - funcctx = SRF_PERCALL_SETUP(); - state = (FN(OS_Vector_ExtractState)*)funcctx->user_fctx; - vec = state->vec; - - if (funcctx->call_cntr < funcctx->max_calls) { - values[0] = Int64GetDatum(state->indices[funcctx->call_cntr]); - values[1] = PG_TGD(state->vals[funcctx->call_cntr]); - - tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); - result = HeapTupleGetDatum(tuple); - SRF_RETURN_NEXT(funcctx, result); - } else { - SRF_RETURN_DONE(funcctx); - } +FN(vector_elements)(PG_FUNCTION_ARGS) +{ + GrB_Info info; + FuncCallContext *funcctx; + TupleDesc tupdesc; + Datum result; + + Datum values[3]; + bool nulls[2] = {false, false}; + HeapTuple tuple; + GrB_Index size = 0; + OS_Vector *vec; + FN(OS_Vector_ExtractState) *state; + + if (SRF_IS_FIRSTCALL()) + { + MemoryContext oldcontext; + + funcctx = SRF_FIRSTCALL_INIT(); + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + vec = (OS_Vector *) OS_GETARG_VECTOR(0); + + state = (FN(OS_Vector_ExtractState)*)palloc(sizeof(FN(OS_Vector_ExtractState))); + CHECKD(GrB_Vector_size(&size, vec->V), vec->V); + + state->indices = (GrB_Index*) palloc0(sizeof(GrB_Index) * size); + state->vals = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * size); + + CHECKD(GrB_Vector_extractTuples(state->indices, + state->vals, + &size, + vec->V), vec->V); + state->vec = vec; + funcctx->max_calls = size; + funcctx->user_fctx = (void*)state; + + /* One-time setup code appears here: */ + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("function returning record called in context " + "that cannot accept type record"))); + BlessTupleDesc(tupdesc); + funcctx->tuple_desc = tupdesc; + + MemoryContextSwitchTo(oldcontext); + } + + funcctx = SRF_PERCALL_SETUP(); + state = (FN(OS_Vector_ExtractState)*)funcctx->user_fctx; + vec = state->vec; + + if (funcctx->call_cntr < funcctx->max_calls) + { + values[0] = Int64GetDatum(state->indices[funcctx->call_cntr]); + values[1] = PG_TGD(state->vals[funcctx->call_cntr]); + + tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); + result = HeapTupleGetDatum(tuple); + SRF_RETURN_NEXT(funcctx, result); + } + else + { + SRF_RETURN_DONE(funcctx); + } } Datum FN(vector_ewise_mult)(OS_Vector *A, - OS_Vector *B, - OS_Vector *C, - OS_Vector *mask, - GrB_BinaryOp binop, - GrB_BinaryOp accum, - GrB_Descriptor desc) { - GrB_Info info; - GrB_Index size; - - if (C == NULL) { - CHECKD(GrB_Vector_size(&size, A->V), A->V); - C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); - } - CHECKD(GrB_eWiseMult(C->V, mask ? mask->V : NULL, accum, binop, A->V, B->V, desc), C->V); - OS_RETURN_VECTOR(C); + OS_Vector *B, + OS_Vector *C, + OS_Vector *mask, + GrB_BinaryOp binop, + GrB_BinaryOp accum, + GrB_Descriptor desc) +{ + GrB_Info info; + GrB_Index size; + + if (C == NULL) + { + CHECKD(GrB_Vector_size(&size, A->V), A->V); + C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); + } + CHECKD(GrB_eWiseMult(C->V, mask ? mask->V : NULL, accum, binop, A->V, B->V, desc), C->V); + OS_RETURN_VECTOR(C); } Datum FN(vector_ewise_add)(OS_Vector *A, - OS_Vector *B, - OS_Vector *C, - OS_Vector *mask, - GrB_BinaryOp binop, - GrB_BinaryOp accum, - GrB_Descriptor desc) { - GrB_Info info; - GrB_Index size; - - if (C == NULL) { - CHECKD(GrB_Vector_size(&size, A->V), A->V); - C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); - } - CHECKD(GrB_eWiseAdd(C->V, mask ? mask->V : NULL, accum, GB_ADD, A->V, B->V, desc), C->V); - OS_RETURN_VECTOR(C); + OS_Vector *B, + OS_Vector *C, + OS_Vector *mask, + GrB_BinaryOp binop, + GrB_BinaryOp accum, + GrB_Descriptor desc) +{ + GrB_Info info; + GrB_Index size; + + if (C == NULL) + { + CHECKD(GrB_Vector_size(&size, A->V), A->V); + C = FN(construct_empty_expanded_vector)(size, CurrentMemoryContext); + } + CHECKD(GrB_eWiseAdd(C->V, mask ? mask->V : NULL, accum, GB_ADD, A->V, B->V, desc), C->V); + OS_RETURN_VECTOR(C); } GrB_Index *FN(extract_indexes)(OS_Vector *A, - GrB_Index size) { - GrB_Index *row_indices; - PG_TYPE *values; - GrB_Info info; - - row_indices = (GrB_Index*) palloc0(sizeof(GrB_Index) * size); - values = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * size); - - CHECKD(GrB_Vector_extractTuples(row_indices, - values, - &size, - A->V), A->V); - return row_indices; + GrB_Index size) +{ + GrB_Index *row_indices; + PG_TYPE *values; + GrB_Info info; + + row_indices = (GrB_Index*) palloc0(sizeof(GrB_Index) * size); + values = (PG_TYPE*) palloc0(sizeof(PG_TYPE) * size); + + CHECKD(GrB_Vector_extractTuples(row_indices, + values, + &size, + A->V), A->V); + return row_indices; } Datum -FN(vector_reduce)(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Vector *A; - GrB_Semiring semiring; - GrB_Monoid monoid; - char *semiring_name; - PG_TYPE val; - - A = OS_GETARG_VECTOR(0); - semiring_name = PG_ARGISNULL(1) ? NULL : text_to_cstring(PG_GETARG_TEXT_PP(1)); - - semiring = semiring_name ? lookup_semiring(semiring_name) : GB_RNG; - CHECKD(GxB_Semiring_add(&monoid, semiring), semiring); - CHECKD(GrB_reduce(&val, NULL, monoid, A->V, NULL), A->V); - PG_RET(val); +FN(vector_reduce)(PG_FUNCTION_ARGS) +{ + GrB_Info info; + OS_Vector *A; + GrB_Semiring semiring; + GrB_Monoid monoid; + char *semiring_name; + PG_TYPE val; + + A = OS_GETARG_VECTOR(0); + semiring_name = PG_ARGISNULL(1) ? NULL : text_to_cstring(PG_GETARG_TEXT_PP(1)); + + semiring = semiring_name ? lookup_semiring(semiring_name) : GB_RNG; + CHECKD(GxB_Semiring_add(&monoid, semiring), semiring); + CHECKD(GrB_reduce(&val, NULL, monoid, A->V, NULL), A->V); + PG_RET(val); } Datum -FN(vector_assign)(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Vector *A, *B, *mask; - GrB_Index size, *indexes = NULL; - PG_TYPE val; +FN(vector_assign)(PG_FUNCTION_ARGS) +{ + GrB_Info info; + OS_Vector *A, *B, *mask; + GrB_Index size, *indexes = NULL; + PG_TYPE val; - A = OS_GETARG_VECTOR(0); - val = PG_GET(1); - B = PG_ARGISNULL(2) ? NULL : OS_GETARG_VECTOR(2); - mask = PG_ARGISNULL(3)? NULL : OS_GETARG_VECTOR(3); + A = OS_GETARG_VECTOR(0); + val = PG_GET(1); + B = PG_ARGISNULL(2) ? NULL : OS_GETARG_VECTOR(2); + mask = PG_ARGISNULL(3)? NULL : OS_GETARG_VECTOR(3); - CHECKD(GrB_Vector_size(&size, A->V), A->V); + CHECKD(GrB_Vector_size(&size, A->V), A->V); - if (B != NULL) - indexes = FN(extract_indexes)(B, size); + if (B != NULL) + indexes = FN(extract_indexes)(B, size); - CHECKD(GrB_assign(A->V, mask? mask->V: NULL, NULL, val, indexes ? indexes : GrB_ALL, size, NULL), A->V); - OS_RETURN_VECTOR(A); + CHECKD(GrB_assign(A->V, mask? mask->V: NULL, NULL, val, indexes ? indexes : GrB_ALL, size, NULL), A->V); + OS_RETURN_VECTOR(A); } Datum -FN(vector_set_element)(PG_FUNCTION_ARGS) { - GrB_Info info; - OS_Vector *A; - GrB_Index index; - PG_TYPE val; - - A = OS_GETARG_VECTOR(0); - index = PG_GETARG_INT64(1); - val = PG_GET(2); - - CHECKD(GrB_Vector_setElement(A->V, val, index), A->V); - OS_RETURN_VECTOR(A); +FN(vector_set_element)(PG_FUNCTION_ARGS) +{ + GrB_Info info; + OS_Vector *A; + GrB_Index index; + PG_TYPE val; + + A = OS_GETARG_VECTOR(0); + index = PG_GETARG_INT64(1); + val = PG_GET(2); + + CHECKD(GrB_Vector_setElement(A->V, val, index), A->V); + OS_RETURN_VECTOR(A); } + +/* Local Variables: */ +/* mode: c */ +/* c-file-style: "postgresql" */ +/* End: */ From 1fda894e612fd7d7d301a56b307d8a9a5a1fae9c Mon Sep 17 00:00:00 2001 From: Michel Pelletier Date: Fri, 9 Aug 2024 07:48:30 -0700 Subject: [PATCH 6/6] reformat to postgresql rules. --- src/matrix.c | 36 ++++++++++++++---------------------- src/vector.c | 6 ------ 2 files changed, 14 insertions(+), 28 deletions(-) diff --git a/src/matrix.c b/src/matrix.c index ad94565..e9428ba 100644 --- a/src/matrix.c +++ b/src/matrix.c @@ -248,16 +248,16 @@ matrix_ewise_mult(PG_FUNCTION_ARGS) binop_name = matrix_times_binop(A, B); accum_name = NULL; - if (PG_NARGS() > 2) { + if (PG_NARGS() > 2) + { C = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(2); mask = PG_ARGISNULL(3) ? NULL : OS_GETARG_MATRIX(3); binop_name = PG_ARGISNULL(4) ? binop_name : text_to_cstring(PG_GETARG_TEXT_PP(4)); accum_name = PG_ARGISNULL(5) ? accum_name : text_to_cstring(PG_GETARG_TEXT_PP(5)); - if (PG_NARGS() > 6) { + if (PG_NARGS() > 6) GET_DESCRIPTOR(6, desc); - } } binop = lookup_binop(binop_name); if (binop == NULL) @@ -294,9 +294,7 @@ matrix_ewise_add(PG_FUNCTION_ARGS) accum_name = PG_ARGISNULL(5) ? accum_name : text_to_cstring(PG_GETARG_TEXT_PP(5)); if (PG_NARGS() > 6) - { GET_DESCRIPTOR(6, desc); - } } binop = lookup_binop(binop_name); @@ -339,9 +337,7 @@ mxm(PG_FUNCTION_ARGS) text_to_cstring(PG_GETARG_TEXT_PP(5)); if (PG_NARGS() > 6) - { GET_DESCRIPTOR(6, desc); - } } semiring = lookup_semiring(semiring_name); @@ -389,9 +385,8 @@ mxv(PG_FUNCTION_ARGS) binop_name = PG_ARGISNULL(5) ? NULL : text_to_cstring(PG_GETARG_TEXT_PP(5)); - if (PG_NARGS() > 6) { + if (PG_NARGS() > 6) GET_DESCRIPTOR(6, desc); - } } if (binop_name != NULL) @@ -435,9 +430,7 @@ vxm(PG_FUNCTION_ARGS) NULL : text_to_cstring(PG_GETARG_TEXT_PP(5)); if (PG_NARGS() > 6) - { GET_DESCRIPTOR(6, desc); - } } if (binop_name != NULL) @@ -495,15 +488,16 @@ matrix_transpose(PG_FUNCTION_ARGS) { A = OS_GETARG_MATRIX(0); - if (PG_NARGS() > 0) { + if (PG_NARGS() > 0) + { C = PG_ARGISNULL(1) ? NULL : OS_GETARG_MATRIX(2); mask = PG_ARGISNULL(2) ? NULL : OS_GETARG_MATRIX(3); - if (PG_NARGS() > 3) { + if (PG_NARGS() > 3) GET_DESCRIPTOR(3, desc); - } } - if (C == NULL) { + if (C == NULL) + { CHECKD(GrB_Matrix_nrows(&m, A->M), A->M); CHECKD(GrB_Matrix_ncols(&n, A->M), A->M); TYPE_APPLY(C, A->type, construct_empty_expanded_matrix, m, n, CurrentMemoryContext); @@ -514,7 +508,8 @@ matrix_transpose(PG_FUNCTION_ARGS) { } Datum -matrix_assign_matrix(PG_FUNCTION_ARGS) { +matrix_assign_matrix(PG_FUNCTION_ARGS) +{ GrB_Info info; OS_Matrix *A, *B, *mask; GrB_Index nvals, *rows = NULL, *cols = NULL; @@ -525,9 +520,8 @@ matrix_assign_matrix(PG_FUNCTION_ARGS) { CHECKD(GrB_Matrix_nvals(&nvals, B->M), B->M); - if (B != NULL) { + if (B != NULL) TYPE_APPLY(nvals, B->type, extract_rowscols, B, &rows, &cols, nvals); - } CHECKD(GrB_assign(A->M, mask? mask->M: NULL, @@ -566,9 +560,8 @@ matrix_kron(PG_FUNCTION_ARGS) { NULL : text_to_cstring(PG_GETARG_TEXT_PP(5)); - if (PG_NARGS() > 6) { + if (PG_NARGS() > 6) GET_DESCRIPTOR(6, desc); - } } if (accum_name != NULL) @@ -600,9 +593,8 @@ matrix_xtract(PG_FUNCTION_ARGS) { CHECKD(GrB_Matrix_nrows(&nrows, A->M), A->M); CHECKD(GrB_Matrix_ncols(&ncols, A->M), A->M); - if (C == NULL) { + if (C == NULL) TYPE_APPLY(C, A->type, construct_empty_expanded_matrix, nrows, ncols, CurrentMemoryContext); - } CHECKD(GrB_Matrix_nvals(&nvals, A->M), A->M); TYPE_APPLY(nvals, A->type, extract_rowscols, B, &rows, &cols, nvals); diff --git a/src/vector.c b/src/vector.c index a636462..b93cf40 100644 --- a/src/vector.c +++ b/src/vector.c @@ -215,9 +215,7 @@ vector_ewise_mult(PG_FUNCTION_ARGS) accum_name = PG_ARGISNULL(5) ? accum_name : text_to_cstring(PG_GETARG_TEXT_PP(5)); if (PG_NARGS() > 6) - { GET_DESCRIPTOR(6, desc); - } } binop = lookup_binop(binop_name); @@ -257,9 +255,7 @@ vector_ewise_add(PG_FUNCTION_ARGS) accum_name = PG_ARGISNULL(5) ? accum_name : text_to_cstring(PG_GETARG_TEXT_PP(5)); if (PG_NARGS() > 6) - { GET_DESCRIPTOR(6, desc); - } } binop = lookup_binop(binop_name); @@ -337,9 +333,7 @@ vector_xtract(PG_FUNCTION_ARGS) CHECKD(GrB_Vector_size(&size, A->V), A->V); if (C == NULL) - { TYPE_APPLY(C, A->type, construct_empty_expanded_vector, size, CurrentMemoryContext); - } TYPE_APPLY(indexes, A->type, extract_indexes, B, size);