1 //------------------------------------------------------------------------------
2 // GraphBLAS/Demo/Program/reduce_demo: reduce a matrix to a scalar
3 //------------------------------------------------------------------------------
4 
5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved.
6 // SPDX-License-Identifier: Apache-2.0
7 
8 //------------------------------------------------------------------------------
9 
10 #include "GraphBLAS.h"
11 #if defined ( _OPENMP )
12 #include <omp.h>
13 #endif
14 
15 // #define N 65536
16    #define N 16384
17 
main(void)18 int main (void)
19 {
20 
21     #if defined ( _OPENMP )
22     double t0 = omp_get_wtime ( ) ;
23     #endif
24 
25     // start GraphBLAS
26     GrB_init (GrB_NONBLOCKING) ;
27     int nthreads ;
28     GxB_Global_Option_get (GxB_GLOBAL_NTHREADS, &nthreads) ;
29     printf ("demo: reduce a matrix to a scalar, nthreads: %d\n", nthreads) ;
30 
31     int nthreads_max ;
32     GxB_Global_Option_get (GxB_GLOBAL_NTHREADS, &nthreads_max) ;
33     printf ("# of threads: %d\n", nthreads_max) ;
34 
35     #if defined ( _OPENMP )
36     t0 = omp_get_wtime ( ) - t0 ;
37     printf ("GPU warmup time: %g\n", t0) ;
38     t0 = omp_get_wtime ( ) ;
39     #endif
40 
41     GrB_Index nrows = N ;
42     GrB_Index ncols = N ;
43     GrB_Matrix A ;
44     GrB_Matrix_new (&A, GrB_INT64, nrows, ncols) ;
45 
46     GrB_Index *I = (GrB_Index *) malloc (nrows * ncols * sizeof (GrB_Index)) ;
47     GrB_Index *J = (GrB_Index *) malloc (nrows * ncols * sizeof (GrB_Index)) ;
48     int64_t   *X = (int64_t   *) malloc (nrows * ncols * sizeof (int64_t)) ;
49 
50     int64_t k ;
51     #pragma omp parallel for num_threads(nthreads_max) schedule(static)
52     for (k = 0 ; k < N*N ; k++)
53     {
54         // k = i * N + j ;
55         int64_t i = k / N ;
56         int64_t j = k % N ;
57         // int x = (int) (rand ( ) & 0xFF) ;
58         int x = (int) (k & 0xFF) ;
59         I [k] = i ;
60         J [k] = j ;
61         X [k] = x ;
62     }
63 
64     GrB_Index nvals = N*N ;
65     GrB_Matrix_build_INT64 (A, I, J, X, nvals, GrB_PLUS_INT64) ;
66 
67     free (I) ;
68     free (J) ;
69     free (X) ;
70 
71     #if defined ( _OPENMP )
72     t0 = omp_get_wtime ( ) - t0 ;
73     printf ("time to create matrix: %g\n", t0) ;
74     #endif
75 
76     GrB_Index result ;
77 
78     double t1 ;
79 
80     printf ("\nreduce to a scalar:\n") ;
81 
82     for (int nthreads = 1 ; nthreads <= nthreads_max ; nthreads++)
83     {
84         GxB_Global_Option_set (GxB_GLOBAL_NTHREADS, nthreads) ;
85         #if defined ( _OPENMP )
86         double t = omp_get_wtime ( ) ;
87         #endif
88         GrB_Matrix_reduce_UINT64 (&result, NULL, GrB_PLUS_MONOID_INT64,
89             A, NULL) ;
90         #if defined ( _OPENMP )
91         t = omp_get_wtime ( ) - t ;
92         if (nthreads == 1) t1 = t ;
93         printf ("nthreads %3d time: %12.6f speedup %8.2f\n",
94             nthreads, t, t1/t) ;
95         #endif
96     }
97 
98     printf ("result %" PRId64 "\n", result) ;
99 
100     // free everyting
101     GrB_Matrix_free (&A) ;
102     GrB_finalize ( ) ;
103 }
104 
105