├── .gitignore ├── GraphBLAS_API_C_1.2.0.pdf ├── LICENSE ├── README.md ├── graph_blas_HPEC19.pdf ├── include ├── GraphBLAS.h ├── LAGraph.h └── tutorial_utils.h ├── lib ├── libgraphblas.so ├── libgraphblas.so.3 ├── libgraphblas.so.3.0.1 ├── libgraphblasOSX.dylib ├── liblagraph.a ├── liblagraph.so ├── liblagraph.so.0 ├── liblagraph.so.0.1.0 └── liblagraphOSX.a └── src ├── .DS_Store ├── AnalyzeGraph.c ├── BuildGraph.c ├── Challenge_problems ├── Makefile ├── betweenness_centrality.c ├── maximal_independent_set.c ├── page_rank.c └── triangle_count.c ├── Data ├── CreateCoauthorGraph.ipynb ├── all_hpec_records_cleaned_normalized_authors_indexed.tsv ├── author_normalization_table_reversed_indexed.tsv ├── hpec_coauthor_edgelist.tsv ├── hpec_coauthors.mtx ├── hpec_coauthors.tsv ├── ldbc-wcc-example.mtx ├── query_author_by_author_id.py ├── query_author_id_by_name.py ├── query_papers_by_author_id.py └── tree-example.mtx ├── Makefile ├── Solutions ├── AnalyzeGraph_final.c ├── BuildAdjMatIndVec.c ├── BuildAdjMatTuple.c ├── HPEC19_index.txt ├── Makefile ├── bfs_level.c ├── connected_components.c ├── matvec.c ├── matvecTrans.c ├── matvecTransIter.c ├── matvecTransIterLevels.c ├── matvecTransIterVisited.c └── matvecTransIterVisitedExitFlag.c ├── make.def └── read_mtx.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | *.o 3 | *~ 4 | #*# 5 | -------------------------------------------------------------------------------- /GraphBLAS_API_C_1.2.0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tgmattso/GraphBLAS/f8fdc81fe54493fae79e4d84d3dfd55bd6d753aa/GraphBLAS_API_C_1.2.0.pdf -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GraphBLAS Tutorial 2 | 3 | Copyright 2018 Carnegie Mellon University and Intel Corporation. 4 | All Rights Reserved. 5 | 6 | BSD (SEI) 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | 1. Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | 2. Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | 3. Products derived from this software may not include “Carnegie Mellon 19 | University,” "SEI”, “Software Engineering Institute", "Intel", and/or 20 | "Intel Corporation" in the name of such derived product, nor shall 21 | “Carnegie Mellon University,” "SEI”, “Software Engineering Institute", 22 | "Intel", and/or "Intel Corporation" be used to endorse or promote products 23 | derived from this software without prior written permission. For written 24 | permission, please contact permission@sei.cmu.edu. 25 | 26 | ACKNOWLEDGMENTS AND DISCLAIMERS: 27 | 28 | This material is based upon work funded and supported by the United States 29 | Department of Defense under Contract No. FA8702-15-D-0002 with Carnegie Mellon 30 | University for the operation of the Software Engineering Institute, a 31 | federally funded research and development center. 32 | 33 | THIS MATERIAL WAS PREPARED AS AN ACCOUNT OF WORK SPONSORED BY AN AGENCY OF THE 34 | UNITED STATES GOVERNMENT. NEITHER THE UNITED STATES GOVERNMENT NOR THE UNITED 35 | STATES DEPARTMENT OF DEFENSE, NOR CARNEGIE MELLON UNIVERSITY, NOR INTEL 36 | CORPORATION, NOR ANY OF THEIR EMPLOYEES, NOR ANY JURISDICTION OR ORGANIZATION 37 | THAT HAS COOPERATED IN THE DEVELOPMENT OF THESE MATERIALS, MAKES ANY WARRANTY, 38 | EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL LIABILITY OR RESPONSIBILITY FOR THE 39 | ACCURACY, COMPLETENESS, OR USEFULNESS OR ANY INFORMATION, APPARATUS, PRODUCT, 40 | SOFTWARE, OR PROCESS DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT INFRINGE 41 | PRIVATELY OWNED RIGHTS. 42 | 43 | Reference herein to any specific commercial product, process, or service by 44 | trade name, trademark, manufacturer, or otherwise does not necessarily 45 | constitute or imply its endorsement, recommendation, or favoring by the United 46 | States Government or any agency thereof, or Carnegie Mellon University, or 47 | Intel Corporation. The views and opinions of authors expressed herein do not 48 | necessarily state or reflect those of the United States Government or any 49 | agency thereof. 50 | 51 | DM18-1037 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repository holds the materials needed for our hands-on GraphBLAS tutorial. 2 | 3 | Clone the repo and test that everything works by going into the src directory 4 | 5 | cd src 6 | 7 | And then build our basic graph program 8 | 9 | make 10 | 11 | You can run this by typing 12 | 13 | ./BuildGraph.exe 14 | 15 | We include in this repo pre-built versions of the SuiteSparse library for 16 | OSX and for Linux. I'm sorry if you use Windows. The creators of this tutorial 17 | do not have Windows systems so we could not build/text the tutorial on Windows. 18 | 19 | You can go to the SuiteSparse web site 20 | 21 | http://faculty.cse.tamu.edu/davis/suitesparse.html 22 | 23 | And download the source and build for you won system if our prebuild OSX and Linux 24 | versions do not cover your own system. Reverse engineering our makefile for a 25 | windows or other non-Linux like system should be straightforward. The software 26 | dependencies are by design quite simple. Just build the code, link the suiteSparse 27 | libries, and reference the suiteSparse and our own tutorial-include-file. 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /graph_blas_HPEC19.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tgmattso/GraphBLAS/f8fdc81fe54493fae79e4d84d3dfd55bd6d753aa/graph_blas_HPEC19.pdf -------------------------------------------------------------------------------- /include/LAGraph.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // LAGraph.h: include file for user applications that use LAGraph 3 | //------------------------------------------------------------------------------ 4 | 5 | /* 6 | LAGraph: graph algorithms based on GraphBLAS 7 | 8 | Copyright 2019 LAGraph Contributors. 9 | 10 | (see Contributors.txt for a full list of Contributors; see 11 | ContributionInstructions.txt for information on how you can Contribute to 12 | this project). 13 | 14 | All Rights Reserved. 15 | 16 | NO WARRANTY. THIS MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. THE LAGRAPH 17 | CONTRIBUTORS MAKE NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, 18 | AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR 19 | PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF 20 | THE MATERIAL. THE CONTRIBUTORS DO NOT MAKE ANY WARRANTY OF ANY KIND WITH 21 | RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT. 22 | 23 | Released under a BSD license, please see the LICENSE file distributed with 24 | this Software or contact permission@sei.cmu.edu for full terms. 25 | 26 | Created, in part, with funding and support from the United States 27 | Government. (see Acknowledgments.txt file). 28 | 29 | This program includes and/or can make use of certain third party source 30 | code, object code, documentation and other files ("Third Party Software"). 31 | See LICENSE file for more details. 32 | 33 | */ 34 | 35 | //------------------------------------------------------------------------------ 36 | 37 | // TODO: add more comments to this file. 38 | 39 | //------------------------------------------------------------------------------ 40 | // include files and global #defines 41 | //------------------------------------------------------------------------------ 42 | 43 | #ifndef LAGRAPH_INCLUDE 44 | #define LAGRAPH_INCLUDE 45 | 46 | #include "GraphBLAS.h" 47 | #include 48 | #include 49 | 50 | // "I" is defined by , but is used in LAGraph and GraphBLAS to 51 | // denote a list of row indices; remove it here. 52 | #undef I 53 | 54 | #include 55 | 56 | #if defined ( __linux__ ) 57 | #include 58 | #endif 59 | 60 | #if defined ( _OPENMP ) 61 | #include 62 | #endif 63 | 64 | #if defined ( __MACH__ ) 65 | #include 66 | #include 67 | #endif 68 | 69 | #if defined __INTEL_COMPILER 70 | // disable icc warnings 71 | // 161: unrecognized pragma 72 | #pragma warning (disable: 161) 73 | #endif 74 | 75 | #define LAGRAPH_RAND_MAX 32767 76 | 77 | // suitable for integers, and non-NaN floating point: 78 | #define LAGRAPH_MAX(x,y) (((x) > (y)) ? (x) : (y)) 79 | #define LAGRAPH_MIN(x,y) (((x) < (y)) ? (x) : (y)) 80 | 81 | // free a block of memory and set the pointer to NULL 82 | #define LAGRAPH_FREE(p) \ 83 | { \ 84 | LAGraph_free (p) ; \ 85 | p = NULL ; \ 86 | } 87 | 88 | //------------------------------------------------------------------------------ 89 | // LAGRAPH_OK: call LAGraph or GraphBLAS and check the result 90 | //------------------------------------------------------------------------------ 91 | 92 | // To use LAGRAPH_OK, the #include'ing file must declare a scalar GrB_Info 93 | // info, and must define LAGRAPH_FREE_ALL as a macro that frees all workspace 94 | // if an error occurs. The method can be a GrB_Info scalar as well, so that 95 | // LAGRAPH_OK(info) works. The function that uses this macro must return 96 | // GrB_Info, or int. 97 | 98 | #define LAGRAPH_ERROR(message,info) \ 99 | { \ 100 | fprintf (stderr, "LAGraph error: %s\n[%d]\n%s\nFile: %s Line: %d\n", \ 101 | message, info, GrB_error ( ), __FILE__, __LINE__) ; \ 102 | LAGRAPH_FREE_ALL ; \ 103 | return (info) ; \ 104 | } 105 | 106 | #define LAGRAPH_OK(method) \ 107 | { \ 108 | info = method ; \ 109 | if (! (info == GrB_SUCCESS || info == GrB_NO_VALUE)) \ 110 | { \ 111 | LAGRAPH_ERROR ("", info) ; \ 112 | } \ 113 | } 114 | 115 | //------------------------------------------------------------------------------ 116 | // LAGraph_Context: 117 | //------------------------------------------------------------------------------ 118 | 119 | // All LAGraph functions will use a Context for global parameters, error 120 | // status, and the like. So far, the parameter is only for LAGraph_random. 121 | 122 | typedef struct 123 | { 124 | int nthreads ; // # of threads to use. If <= 0, use defaults 125 | // (from omp_get_max_threads) 126 | 127 | // TODO more can go here, like info, the GrB_error() results, etc. 128 | } 129 | LAGraph_Context ; 130 | 131 | //------------------------------------------------------------------------------ 132 | // global objects 133 | //------------------------------------------------------------------------------ 134 | 135 | // LAGraph_Complex is a GrB_Type containing the ANSI C11 double complex 136 | // type. This is required so that any arbitrary Matrix Market format 137 | // can be read into GraphBLAS. 138 | extern GrB_Type LAGraph_Complex ; 139 | 140 | extern GrB_BinaryOp 141 | 142 | // binary operators to test for symmetry, skew-symmetry 143 | // and Hermitian property 144 | LAGraph_EQ_Complex , 145 | LAGraph_SKEW_INT8 , 146 | LAGraph_SKEW_INT16 , 147 | LAGraph_SKEW_INT32 , 148 | LAGraph_SKEW_INT64 , 149 | LAGraph_SKEW_FP32 , 150 | LAGraph_SKEW_FP64 , 151 | LAGraph_SKEW_Complex , 152 | LAGraph_Hermitian , 153 | LAGraph_LOR_UINT32 ; 154 | 155 | extern GrB_UnaryOp 156 | 157 | // unary operators to check if the entry is equal to 1 158 | LAGraph_ISONE_INT8 , 159 | LAGraph_ISONE_INT16 , 160 | LAGraph_ISONE_INT32 , 161 | LAGraph_ISONE_INT64 , 162 | LAGraph_ISONE_UINT8 , 163 | LAGraph_ISONE_UINT16 , 164 | LAGraph_ISONE_UINT32 , 165 | LAGraph_ISONE_UINT64 , 166 | LAGraph_ISONE_FP32 , 167 | LAGraph_ISONE_FP64 , 168 | LAGraph_ISONE_Complex , 169 | 170 | // unary operators to check if the entry is equal to 2 171 | LAGraph_ISTWO_UINT32 , 172 | 173 | // unary operators that decrement by 1 174 | LAGraph_DECR_INT32 , 175 | LAGraph_DECR_INT64 , 176 | 177 | // unary operators for lcc 178 | LAGraph_COMB_DIR_FP64 , 179 | LAGraph_COMB_UNDIR_FP64 , 180 | 181 | // unary ops to check if greater than zero 182 | LAGraph_GT0_FP32 , 183 | LAGraph_GT0_FP64 , 184 | 185 | // unary YMAX ops for DNN 186 | LAGraph_YMAX_FP32 , 187 | LAGraph_YMAX_FP64 , 188 | 189 | // unary operators that return 1 190 | LAGraph_ONE_UINT32 , 191 | LAGraph_ONE_FP64 , 192 | LAGraph_TRUE_BOOL , 193 | LAGraph_TRUE_BOOL_Complex ; 194 | 195 | // monoids and semirings 196 | extern GrB_Monoid 197 | 198 | LAGraph_PLUS_INT64_MONOID , 199 | LAGraph_MAX_INT32_MONOID , 200 | LAGraph_LAND_MONOID , 201 | LAGraph_LOR_MONOID , 202 | LAGraph_MIN_INT32_MONOID , 203 | LAGraph_MIN_INT64_MONOID , 204 | LAGraph_PLUS_UINT32_MONOID , 205 | LAGraph_PLUS_FP32_MONOID , 206 | LAGraph_PLUS_FP64_MONOID ; 207 | 208 | extern GrB_Semiring 209 | 210 | LAGraph_LOR_LAND_BOOL , 211 | LAGraph_LOR_SECOND_BOOL , 212 | LAGraph_LOR_FIRST_BOOL , 213 | LAGraph_MIN_SECOND_INT32 , 214 | LAGraph_MIN_FIRST_INT32 , 215 | LAGraph_MIN_SECOND_INT64 , 216 | LAGraph_MIN_FIRST_INT64 , 217 | LAGraph_PLUS_TIMES_UINT32 , 218 | LAGraph_PLUS_TIMES_FP64 , 219 | LAGraph_PLUS_PLUS_FP64 , 220 | LAGraph_PLUS_TIMES_FP32 , 221 | LAGraph_PLUS_PLUS_FP32 ; 222 | 223 | // all 16 descriptors 224 | // syntax: 4 characters define the following. 'o' is the default: 225 | // 1: o or t: A transpose 226 | // 2: o or t: B transpose 227 | // 3: o or c: complemented mask 228 | // 4: o or r: replace 229 | extern GrB_Descriptor 230 | 231 | LAGraph_desc_oooo , // default (NULL) 232 | LAGraph_desc_ooor , // replace 233 | LAGraph_desc_ooco , // compl mask 234 | LAGraph_desc_oocr , // compl mask, replace 235 | 236 | LAGraph_desc_tooo , // A' 237 | LAGraph_desc_toor , // A', replace 238 | LAGraph_desc_toco , // A', compl mask 239 | LAGraph_desc_tocr , // A', compl mask, replace 240 | 241 | LAGraph_desc_otoo , // B' 242 | LAGraph_desc_otor , // B', replace 243 | LAGraph_desc_otco , // B', compl mask 244 | LAGraph_desc_otcr , // B', compl mask, replace 245 | 246 | LAGraph_desc_ttoo , // A', B' 247 | LAGraph_desc_ttor , // A', B', replace 248 | LAGraph_desc_ttco , // A', B', compl mask 249 | LAGraph_desc_ttcr ; // A', B', compl mask, replace 250 | 251 | #if defined ( GxB_SUITESPARSE_GRAPHBLAS ) \ 252 | && GxB_IMPLEMENTATION >= GxB_VERSION (3,0,1) 253 | // requires SuiteSparse:GraphBLAS v3.0.1 or later 254 | extern GxB_SelectOp LAGraph_support ; 255 | #endif 256 | 257 | //------------------------------------------------------------------------------ 258 | // memory management functions 259 | //------------------------------------------------------------------------------ 260 | 261 | // use the ANSI C functions by default (or mx* functions if the #ifdef 262 | // above redefines them). See Source/Utility/LAGraph_malloc.c. 263 | 264 | extern void * (* LAGraph_malloc_function ) (size_t) ; 265 | extern void * (* LAGraph_calloc_function ) (size_t, size_t) ; 266 | extern void * (* LAGraph_realloc_function ) (void *, size_t) ; 267 | extern void (* LAGraph_free_function ) (void *) ; 268 | extern bool LAGraph_malloc_is_thread_safe ; 269 | 270 | //------------------------------------------------------------------------------ 271 | // user-callable utility functions 272 | //------------------------------------------------------------------------------ 273 | 274 | typedef void (*LAGraph_binary_function) (void *, const void *, const void *) ; 275 | 276 | GrB_Info LAGraph_init ( ) ; // start LAGraph 277 | 278 | GrB_Info LAGraph_xinit // start LAGraph (alternative method) 279 | ( 280 | // pointers to memory management functions 281 | void * (* user_malloc_function ) (size_t), 282 | void * (* user_calloc_function ) (size_t, size_t), 283 | void * (* user_realloc_function ) (void *, size_t), 284 | void (* user_free_function ) (void *), 285 | bool user_malloc_is_thread_safe 286 | ) ; 287 | 288 | GrB_Info LAGraph_finalize ( ) ; // end LAGraph 289 | 290 | GrB_Info LAGraph_mmread 291 | ( 292 | GrB_Matrix *A, // handle of matrix to create 293 | FILE *f // file to read from, already open 294 | ) ; 295 | 296 | GrB_Info LAGraph_mmwrite 297 | ( 298 | GrB_Matrix A, // matrix to write to the file 299 | FILE *f // file to write it to 300 | // TODO , FILE *fcomments // optional file with extra comments 301 | ) ; 302 | 303 | GrB_Info LAGraph_tsvread // returns GrB_SUCCESS if successful 304 | ( 305 | GrB_Matrix *Chandle, // C, created on output 306 | FILE *f, // file to read from (already open) 307 | GrB_Type type, // the type of C to create 308 | GrB_Index nrows, // C is nrows-by-ncols 309 | GrB_Index ncols 310 | ) ; 311 | 312 | GrB_Info LAGraph_ispattern // return GrB_SUCCESS if successful 313 | ( 314 | bool *result, // true if A is all one, false otherwise 315 | GrB_Matrix A, 316 | GrB_UnaryOp userop // for A with arbitrary user-defined type. 317 | // Ignored if A and B are of built-in types or 318 | // LAGraph_Complex. 319 | ) ; 320 | 321 | GrB_Info LAGraph_pattern // return GrB_SUCCESS if successful 322 | ( 323 | GrB_Matrix *C, // a boolean matrix with the pattern of A 324 | GrB_Matrix A 325 | ) ; 326 | 327 | GrB_Info LAGraph_isequal // return GrB_SUCCESS if successful 328 | ( 329 | bool *result, // true if A == B, false if A != B or error 330 | GrB_Matrix A, 331 | GrB_Matrix B, 332 | GrB_BinaryOp userop // for A and B with arbitrary user-defined types. 333 | // Ignored if A and B are of built-in types or 334 | // LAGraph_Complex. 335 | ) ; 336 | 337 | GrB_Info LAGraph_Vector_isequal // return GrB_SUCCESS if successful 338 | ( 339 | bool *result, // true if A == B, false if A != B or error 340 | GrB_Vector A, 341 | GrB_Vector B, 342 | GrB_BinaryOp userop // for A and B with arbitrary user-defined types. 343 | // Ignored if A and B are of built-in types or 344 | // LAGraph_Complex. 345 | ) ; 346 | 347 | GrB_Info LAGraph_isall // return GrB_SUCCESS if successful 348 | ( 349 | bool *result, // true if A == B, false if A != B or error 350 | GrB_Matrix A, 351 | GrB_Matrix B, 352 | GrB_BinaryOp op // GrB_EQ_, for the type of A and B, 353 | // to check for equality. Or use any desired 354 | // operator. The operator should return GrB_BOOL. 355 | ) ; 356 | 357 | GrB_Info LAGraph_Vector_isall // return GrB_SUCCESS if successful 358 | ( 359 | bool *result, // true if A == B, false if A != B or error 360 | GrB_Vector A, 361 | GrB_Vector B, 362 | GrB_BinaryOp op // GrB_EQ_, for the type of A and B, 363 | // to check for equality. Or use any desired 364 | // operator. The operator should return GrB_BOOL. 365 | ) ; 366 | 367 | uint64_t LAGraph_rand (uint64_t *seed) ; 368 | 369 | uint64_t LAGraph_rand64 (uint64_t *seed) ; 370 | 371 | double LAGraph_randx (uint64_t *seed) ; 372 | 373 | GrB_Info LAGraph_random // create a random matrix 374 | ( 375 | GrB_Matrix *A, // handle of matrix to create 376 | GrB_Type type, // built-in type, or LAGraph_Complex 377 | GrB_Index nrows, // number of rows 378 | GrB_Index ncols, // number of columns 379 | GrB_Index nvals, // number of values 380 | bool make_pattern, // if true, A is a pattern 381 | bool make_symmetric, // if true, A is symmetric 382 | bool make_skew_symmetric, // if true, A is skew-symmetric 383 | bool make_hermitian, // if trur, A is hermitian 384 | bool no_diagonal, // if true, A has no entries on the diagonal 385 | uint64_t *seed // random number seed; modified on return 386 | ) ; 387 | 388 | GrB_Info LAGraph_alloc_global ( ) ; 389 | 390 | GrB_Info LAGraph_free_global ( ) ; 391 | 392 | void *LAGraph_malloc // wrapper for malloc 393 | ( 394 | size_t nitems, // number of items 395 | size_t size_of_item // size of each item 396 | ) ; 397 | 398 | void LAGraph_free // wrapper for free 399 | ( 400 | void *p 401 | ) ; 402 | 403 | void LAGraph_tic // gets current time in seconds and nanoseconds 404 | ( 405 | double tic [2] // tic [0]: seconds, tic [1]: nanoseconds 406 | ) ; 407 | 408 | double LAGraph_toc // returns time since last LAGraph_tic 409 | ( 410 | const double tic [2] // tic from last call to LAGraph_tic 411 | ) ; 412 | 413 | GrB_Info LAGraph_prune_diag // remove all entries from the diagonal 414 | ( 415 | GrB_Matrix A 416 | ) ; 417 | 418 | GrB_Info LAGraph_Vector_to_dense 419 | ( 420 | GrB_Vector *vdense, // output vector 421 | GrB_Vector v, // input vector 422 | void *id // pointer to value to fill vdense with 423 | ) ; 424 | 425 | int LAGraph_set_nthreads // returns # threads set, 0 if nothing done 426 | ( 427 | int nthreads 428 | ) ; 429 | 430 | int LAGraph_get_nthreads // returns # threads to use, 1 if unknown 431 | ( 432 | void 433 | ) ; 434 | 435 | GrB_Info LAGraph_grread // read a matrix from a binary file 436 | ( 437 | GrB_Matrix *G, // handle of matrix to create 438 | uint64_t *G_version, // the version in the file 439 | const char *filename, // name of file to open 440 | GrB_Type gtype // type of matrix to read 441 | ) ; 442 | 443 | //------------------------------------------------------------------------------ 444 | // user-callable algorithms 445 | //------------------------------------------------------------------------------ 446 | 447 | GrB_Info LAGraph_bfs_pushpull // push-pull BFS, or push-only if AT = NULL 448 | ( 449 | GrB_Vector *v_output, // v(i) is the BFS level of node i in the graph 450 | GrB_Vector *pi_output, // pi(i) is the parent of node i in the graph. 451 | // if NULL, the parent is not computed 452 | GrB_Matrix A, // input graph, treated as if boolean in semiring 453 | GrB_Matrix AT, // transpose of A (optional; push-only if NULL) 454 | int64_t s, // starting node of the BFS (s < 0: whole graph) 455 | int64_t max_level, // optional limit of # levels to search 456 | bool vsparse // if true, v is expected to be very sparse 457 | ) ; 458 | 459 | GrB_Info LAGraph_bfs_simple // push-only BFS 460 | ( 461 | GrB_Vector *v_output, // v(i) is the BFS level of node i in the graph 462 | const GrB_Matrix A, // input graph, treated as if boolean in semiring 463 | GrB_Index s // starting node of the BFS 464 | ) ; 465 | 466 | GrB_Info LAGraph_lacc ( 467 | GrB_Matrix A, 468 | GrB_Vector *result 469 | ) ; 470 | 471 | // LAGraph_pagerank computes an array of structs for its result 472 | typedef struct 473 | { 474 | double pagerank ; // the pagerank of a node 475 | GrB_Index page ; // the node number itself 476 | } 477 | LAGraph_PageRank ; 478 | 479 | GrB_Info LAGraph_pagerank // GrB_SUCCESS or error condition 480 | ( 481 | LAGraph_PageRank **Phandle, // output: array of LAGraph_PageRank structs 482 | GrB_Matrix A, // binary input graph, not modified 483 | int itermax, // max number of iterations 484 | double tol, // stop when norm (r-rnew,2) < tol 485 | int *iters // number of iterations taken 486 | ) ; 487 | 488 | GrB_Info LAGraph_pagerank2 489 | ( 490 | GrB_Vector *result, 491 | GrB_Matrix A, 492 | double damping_factor, 493 | unsigned long iteration_num 494 | ) ; 495 | 496 | GrB_Info LAGraph_tricount // count # of triangles 497 | ( 498 | int64_t *ntri, // # of triangles 499 | const int method, // 0 to 5, see above 500 | const GrB_Matrix A, // adjacency matrix for methods 0, 1, and 2 501 | const GrB_Matrix E, // edge incidence matrix for method 0 502 | const GrB_Matrix L, // L=tril(A) for methods 2, 4, and 4 503 | const GrB_Matrix U, // U=triu(A) for methods 2, 3, and 5 504 | double t [2] // t [0]: multiply time, t [1]: reduce time 505 | ) ; 506 | 507 | GrB_Info LAGraph_ktruss // compute the k-truss of a graph 508 | ( 509 | GrB_Matrix *Chandle, // output k-truss subgraph, C 510 | const GrB_Matrix A, // input adjacency matrix, A, not modified 511 | const uint32_t k, // find the k-truss, where k >= 3 512 | int32_t *nsteps // # of steps taken (ignored if NULL) 513 | ) ; 514 | 515 | GrB_Info LAGraph_allktruss // compute all k-trusses of a graph 516 | ( 517 | GrB_Matrix *Cset, // size n, output k-truss subgraphs (optional) 518 | GrB_Matrix A, // input adjacency matrix, A, not modified 519 | // output statistics 520 | int64_t *kmax, // smallest k where k-truss is empty 521 | int64_t *ntris, // size n, ntris [k] is #triangles in k-truss 522 | int64_t *nedges, // size n, nedges [k] is #edges in k-truss 523 | int64_t *nstepss // size n, nstepss [k] is #steps for k-truss 524 | ) ; 525 | 526 | GrB_Info LAGraph_BF_full 527 | ( 528 | GrB_Vector *pd, //the pointer to the vector of distance 529 | GrB_Vector *ppi, //the pointer to the vector of parent 530 | GrB_Vector *ph, //the pointer to the vector of hops 531 | const GrB_Matrix A, //matrix for the graph 532 | const GrB_Index s //given index of the source 533 | ) ; 534 | 535 | GrB_Info LAGraph_BF_basic 536 | ( 537 | GrB_Vector *pd, //the pointer to the vector of distance 538 | const GrB_Matrix A, //matrix for the graph 539 | const GrB_Index s //given index of the source 540 | ) ; 541 | 542 | GrB_Info LAGraph_lcc // compute lcc for all nodes in A 543 | ( 544 | GrB_Vector *LCC_handle, // output vector 545 | const GrB_Matrix A, // input matrix 546 | bool symmetric, // if true, the matrix is symmetric 547 | bool sanitize, // if true, ensure A is binary 548 | double t [2] // t [0] = sanitize time, t [1] = lcc time, 549 | // in seconds 550 | ) ; 551 | 552 | GrB_Info LAGraph_dnn // returns GrB_SUCCESS if successful 553 | ( 554 | // output 555 | GrB_Matrix *Yhandle, // Y, created on output 556 | // input: not modified 557 | GrB_Matrix *W, // W [0..nlayers-1], each nneurons-by-nneurons 558 | GrB_Matrix *Bias, // Bias [0..nlayers-1], diagonal nneurons-by-nneurons 559 | int nlayers, // # of layers 560 | GrB_Matrix Y0 // input features: nfeatures-by-nneurons 561 | ) ; 562 | 563 | #endif 564 | -------------------------------------------------------------------------------- /include/tutorial_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the GraphBLAS Tutorial materials, 3 | * Copyright (c) 2018 Carnegie Mellon University and Intel Corporation. 4 | * All Rights Reserved 5 | * 6 | * THIS SOFTWARE IS PROVIDED "AS IS," WITH NO WARRANTIES WHATSOEVER. CARNEGIE 7 | * MELLON UNIVERSITY AND INTEL CORPORATION EXPRESSLY DISCLAIMS TO THE FULLEST 8 | * EXTENT PERMITTED BY LAW ALL EXPRESS, IMPLIED, AND STATUTORY WARRANTIES, 9 | * INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS 10 | * FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF PROPRIETARY RIGHTS. 11 | * 12 | * Released under a BSD (SEI)-style license, please see LICENSE.txt for 13 | * full terms. 14 | * 15 | * DM18-xxx 16 | * 17 | * Authors: Scott McMillan, Timothy G. Mattson 18 | */ 19 | 20 | /** 21 | * @file tutorial_utils.h 22 | * 23 | * @brief Useful routines to use and test various algorithms. 24 | * 25 | * @todo Move implementation to a C file 26 | */ 27 | 28 | #ifndef TUTORIAL_UTILS_H 29 | #define TUTORIAL_UTILS_H 30 | 31 | #include 32 | 33 | //**************************************************************************** 34 | // pretty print a vector 35 | void pretty_print_vector_BOOL(GrB_Vector vec, char const *label) 36 | { 37 | GrB_Index N; 38 | GrB_Vector_size(&N, vec); 39 | 40 | bool val; 41 | GrB_Info ret_val; 42 | 43 | printf("Vector: %s =\n", label); 44 | 45 | printf("["); 46 | for (GrB_Index idx = 0; idx < N; ++idx) 47 | { 48 | ret_val = GrB_Vector_extractElement_BOOL(&val, vec, idx); 49 | if (GrB_SUCCESS == ret_val) 50 | { 51 | if (idx == 0) 52 | { 53 | printf("%3d", (int)val); 54 | } 55 | else 56 | { 57 | printf(", %3d", (int)val); 58 | } 59 | } 60 | else if (GrB_NO_VALUE == ret_val) 61 | { 62 | if (idx == 0) 63 | { 64 | printf(" -"); 65 | } 66 | else 67 | { 68 | printf(", -"); 69 | } 70 | } 71 | else 72 | { 73 | if (idx == 0) 74 | { 75 | printf(" ERR"); 76 | } 77 | else 78 | { 79 | printf(", ERR"); 80 | } 81 | } 82 | } 83 | printf("]\n"); 84 | 85 | } 86 | 87 | //**************************************************************************** 88 | // pretty print a vector 89 | void pretty_print_vector_UINT64(GrB_Vector vec, char const *label) 90 | { 91 | GrB_Index N; 92 | GrB_Vector_size(&N, vec); 93 | 94 | GrB_Index val; 95 | GrB_Info ret_val; 96 | 97 | printf("Vector: %s =\n", label); 98 | 99 | printf("["); 100 | for (GrB_Index idx = 0; idx < N; ++idx) 101 | { 102 | ret_val = GrB_Vector_extractElement_UINT64(&val, vec, idx); 103 | if (GrB_SUCCESS == ret_val) 104 | { 105 | if (idx == 0) 106 | { 107 | printf("%3ld", (long)val); 108 | } 109 | else 110 | { 111 | printf(", %3ld", (long)val); 112 | } 113 | } 114 | else if (GrB_NO_VALUE == ret_val) 115 | { 116 | if (idx == 0) 117 | { 118 | printf(" -"); 119 | } 120 | else 121 | { 122 | printf(", -"); 123 | } 124 | } 125 | else 126 | { 127 | if (idx == 0) 128 | { 129 | printf(" ERR"); 130 | } 131 | else 132 | { 133 | printf(", ERR"); 134 | } 135 | } 136 | } 137 | printf("]\n"); 138 | 139 | } 140 | 141 | //**************************************************************************** 142 | // pretty print a vector 143 | void pretty_print_vector_FP64(GrB_Vector vec, char const *label) 144 | { 145 | GrB_Index N; 146 | GrB_Vector_size(&N, vec); 147 | 148 | double val; 149 | GrB_Info ret_val; 150 | 151 | printf("Vector: %s =\n", label); 152 | 153 | printf("["); 154 | for (GrB_Index idx = 0; idx < N; ++idx) 155 | { 156 | ret_val = GrB_Vector_extractElement_FP64(&val, vec, idx); 157 | if (GrB_SUCCESS == ret_val) 158 | { 159 | if (idx == 0) 160 | { 161 | printf("%lf", (double)val); 162 | } 163 | else 164 | { 165 | printf(", %lf", (double)val); 166 | } 167 | } 168 | else if (GrB_NO_VALUE == ret_val) 169 | { 170 | if (idx == 0) 171 | { 172 | printf(" -"); 173 | } 174 | else 175 | { 176 | printf(", -"); 177 | } 178 | } 179 | else 180 | { 181 | if (idx == 0) 182 | { 183 | printf(" ERR"); 184 | } 185 | else 186 | { 187 | printf(", ERR"); 188 | } 189 | } 190 | } 191 | printf("]\n"); 192 | 193 | } 194 | 195 | //**************************************************************************** 196 | // pretty print a matrix 197 | void pretty_print_matrix_BOOL(GrB_Matrix mat, char const *label) 198 | { 199 | GrB_Index M,N; 200 | GrB_Matrix_nrows(&M, mat); 201 | GrB_Matrix_ncols(&N, mat); 202 | 203 | bool val; 204 | GrB_Info ret_val; 205 | 206 | printf("Matrix: %s =\n", label); 207 | for (GrB_Index row = 0; row < M; ++row) 208 | { 209 | printf("["); 210 | for (GrB_Index col = 0; col < N; ++col) 211 | { 212 | ret_val = GrB_Matrix_extractElement_BOOL(&val, mat, row, col); 213 | if (GrB_SUCCESS == ret_val) 214 | { 215 | if (col == 0) 216 | { 217 | printf("%3d", (int)val); 218 | } 219 | else 220 | { 221 | printf(", %3d", (int)val); 222 | } 223 | } 224 | else if (GrB_NO_VALUE == ret_val) 225 | { 226 | if (col == 0) 227 | { 228 | printf(" -"); 229 | } 230 | else 231 | { 232 | printf(", -"); 233 | } 234 | } 235 | else 236 | { 237 | if (col == 0) 238 | { 239 | printf(" ERR"); 240 | } 241 | else 242 | { 243 | printf(", ERR"); 244 | } 245 | } 246 | } 247 | printf("]\n"); 248 | } 249 | } 250 | 251 | //**************************************************************************** 252 | // pretty print a matrix 253 | void pretty_print_matrix_UINT64(GrB_Matrix mat, char const *label) 254 | { 255 | GrB_Index M,N; 256 | GrB_Matrix_nrows(&M, mat); 257 | GrB_Matrix_ncols(&N, mat); 258 | 259 | GrB_Index val; 260 | GrB_Info ret_val; 261 | 262 | printf("Matrix: %s =\n", label); 263 | for (GrB_Index row = 0; row < M; ++row) 264 | { 265 | printf("["); 266 | for (GrB_Index col = 0; col < N; ++col) 267 | { 268 | ret_val = GrB_Matrix_extractElement_UINT64(&val, mat, row, col); 269 | if (GrB_SUCCESS == ret_val) 270 | { 271 | if (col == 0) 272 | { 273 | printf("%3ld", (long)val); 274 | } 275 | else 276 | { 277 | printf(", %3ld", (long)val); 278 | } 279 | } 280 | else if (GrB_NO_VALUE == ret_val) 281 | { 282 | if (col == 0) 283 | { 284 | printf(" -"); 285 | } 286 | else 287 | { 288 | printf(", -"); 289 | } 290 | } 291 | else 292 | { 293 | if (col == 0) 294 | { 295 | printf(" ERR"); 296 | } 297 | else 298 | { 299 | printf(", ERR"); 300 | } 301 | } 302 | } 303 | printf("]\n"); 304 | } 305 | } 306 | 307 | //**************************************************************************** 308 | // pretty print a matrix 309 | void pretty_print_matrix_FP64(GrB_Matrix mat, char const *label) 310 | { 311 | GrB_Index M,N; 312 | GrB_Matrix_nrows(&M, mat); 313 | GrB_Matrix_ncols(&N, mat); 314 | 315 | double val; 316 | GrB_Info ret_val; 317 | 318 | printf("Matrix: %s =\n", label); 319 | for (GrB_Index row = 0; row < M; ++row) 320 | { 321 | printf("["); 322 | for (GrB_Index col = 0; col < N; ++col) 323 | { 324 | ret_val = GrB_Matrix_extractElement_FP64(&val, mat, row, col); 325 | if (GrB_SUCCESS == ret_val) 326 | { 327 | if (col == 0) 328 | { 329 | printf("%3lf", (double)val); 330 | } 331 | else 332 | { 333 | printf(", %3lf", (double)val); 334 | } 335 | } 336 | else if (GrB_NO_VALUE == ret_val) 337 | { 338 | if (col == 0) 339 | { 340 | printf(" -"); 341 | } 342 | else 343 | { 344 | printf(", -"); 345 | } 346 | } 347 | else 348 | { 349 | if (col == 0) 350 | { 351 | printf(" ERR"); 352 | } 353 | else 354 | { 355 | printf(", ERR"); 356 | } 357 | } 358 | } 359 | printf("]\n"); 360 | } 361 | } 362 | 363 | #endif 364 | -------------------------------------------------------------------------------- /lib/libgraphblas.so: -------------------------------------------------------------------------------- 1 | libgraphblas.so.3 -------------------------------------------------------------------------------- /lib/libgraphblas.so.3: -------------------------------------------------------------------------------- 1 | libgraphblas.so.3.0.1 -------------------------------------------------------------------------------- /lib/libgraphblas.so.3.0.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tgmattso/GraphBLAS/f8fdc81fe54493fae79e4d84d3dfd55bd6d753aa/lib/libgraphblas.so.3.0.1 -------------------------------------------------------------------------------- /lib/libgraphblasOSX.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tgmattso/GraphBLAS/f8fdc81fe54493fae79e4d84d3dfd55bd6d753aa/lib/libgraphblasOSX.dylib -------------------------------------------------------------------------------- /lib/liblagraph.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tgmattso/GraphBLAS/f8fdc81fe54493fae79e4d84d3dfd55bd6d753aa/lib/liblagraph.a -------------------------------------------------------------------------------- /lib/liblagraph.so: -------------------------------------------------------------------------------- 1 | liblagraph.so.0 -------------------------------------------------------------------------------- /lib/liblagraph.so.0: -------------------------------------------------------------------------------- 1 | liblagraph.so.0.1.0 -------------------------------------------------------------------------------- /lib/liblagraph.so.0.1.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tgmattso/GraphBLAS/f8fdc81fe54493fae79e4d84d3dfd55bd6d753aa/lib/liblagraph.so.0.1.0 -------------------------------------------------------------------------------- /lib/liblagraphOSX.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tgmattso/GraphBLAS/f8fdc81fe54493fae79e4d84d3dfd55bd6d753aa/lib/liblagraphOSX.a -------------------------------------------------------------------------------- /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tgmattso/GraphBLAS/f8fdc81fe54493fae79e4d84d3dfd55bd6d753aa/src/.DS_Store -------------------------------------------------------------------------------- /src/AnalyzeGraph.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 xxx. 3 | 4 | All Rights Reserved. 5 | 6 | NO WARRANTY. THIS MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. THE LAGRAPH 7 | CONTRIBUTORS MAKE NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, 8 | AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR 9 | PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF 10 | THE MATERIAL. THE CONTRIBUTORS DO NOT MAKE ANY WARRANTY OF ANY KIND WITH 11 | RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT. 12 | 13 | Released under a BSD license, please see the LICENSE file distributed with 14 | this Software or contact permission@sei.cmu.edu for full terms. 15 | 16 | Created, in part, with funding and support from the United States 17 | Government. (see Acknowledgments.txt file). 18 | 19 | This program includes and/or can make use of certain third party source 20 | code, object code, documentation and other files ("Third Party Software"). 21 | See LICENSE file for more details. 22 | 23 | */ 24 | 25 | //------------------------------------------------------------------------------ 26 | 27 | // Contributed by Scott McMillan/CMU, Tim Mattson/Intel 28 | 29 | // Run the following from the src directory: 30 | // 31 | // ./LoadGraph.exe Data/hpec_coauthors.mtx 32 | 33 | #include 34 | #include 35 | #include "GraphBLAS.h" 36 | #include "LAGraph.h" 37 | #include "tutorial_utils.h" 38 | 39 | // HACK: To expose convenience function from LACC_GraphBLAS.c in LAGraph 40 | GrB_Info CountCC(GrB_Vector parents, GrB_Index* countcc); 41 | 42 | //------------------------------------------------------------------------------ 43 | // Find all elements containing a given value (G_target_id) 44 | GrB_Index G_target_id = 0; 45 | 46 | void eq_target(void *z, const void *x) 47 | { 48 | (*(bool*)z) = (bool)((*(GrB_Index*)x) == G_target_id); 49 | } 50 | 51 | //------------------------------------------------------------------------------ 52 | // main: 53 | //------------------------------------------------------------------------------ 54 | int main (int argc, char **argv) 55 | { 56 | if (argc < 2) 57 | { 58 | fprintf(stderr, "Error\nUsage: %s \n", argv[0]); 59 | return 1; 60 | } 61 | 62 | // Call LAGraph_init() instead of GrB_init(GrB_BLOCKING) 63 | LAGraph_init(); 64 | 65 | double tic[2], t; // for timing 66 | 67 | //------------------------------------------------------------------ 68 | printf("*** Step 1: loading input graph: %s\n", argv[1]); 69 | GrB_Matrix A = NULL; 70 | FILE *fd = fopen(argv[1], "r"); 71 | 72 | LAGraph_tic (tic); 73 | if (GrB_SUCCESS != LAGraph_mmread(&A, fd)) 74 | { 75 | fprintf(stderr, "ERROR: Failed to load graph: %s\n", argv[1]); 76 | exit(-1); 77 | } 78 | t = LAGraph_toc(tic); 79 | if (fd != NULL) fclose(fd); 80 | printf("*** Step 1: Elapsed time: %g sec\n", t); 81 | 82 | //------------------------------------------------------------------ 83 | printf("*** Step 2: compute some basic statistics\n"); 84 | GrB_Index num_rows, num_cols, num_vals; 85 | GrB_Matrix_nrows(&num_rows, A); 86 | GrB_Matrix_ncols(&num_cols, A); 87 | GrB_Matrix_nvals(&num_vals, A); 88 | assert(num_rows == num_cols); 89 | 90 | // Compute node with the maximum some of outgoing edge weights 91 | // (author w/ most coauthor/paper combos) via row reduction of the 92 | // weighted adjacency matrix 93 | GrB_Vector degree; 94 | GrB_Vector_new(°ree, GrB_UINT64, num_rows); 95 | LAGraph_tic (tic); 96 | GrB_reduce(degree, GrB_NULL, GrB_NULL, GrB_PLUS_UINT64, A, GrB_NULL); 97 | 98 | uint64_t max_degree = 0; 99 | GrB_reduce(&max_degree, GrB_NULL, GxB_MAX_UINT64_MONOID, degree, GrB_NULL); 100 | 101 | uint64_t min_degree = UINT64_MAX; 102 | GrB_reduce(&min_degree, GrB_NULL, GxB_MIN_UINT64_MONOID, degree, GrB_NULL); 103 | 104 | t = LAGraph_toc(tic); 105 | printf("*** Step 2: Elapsed time: %g sec\n", t); 106 | printf("Num nodes: %ld\n", (unsigned long)num_rows); 107 | printf("Num edges: %ld\n", (unsigned long)num_vals); 108 | printf("Avg degree: %lf\n", ((double)num_vals)/((double)num_rows)); 109 | printf("Max degree: %ld\n", (unsigned long)max_degree); 110 | printf("Min degree: %ld\n", (unsigned long)min_degree); 111 | 112 | GrB_Index target_index = 0; 113 | for (GrB_Index ix = 0; ix < num_rows; ++ix) 114 | { 115 | GrB_Index val = 0; 116 | if (GrB_NO_VALUE != GrB_Vector_extractElement(&val, degree, ix)) 117 | { 118 | if (val == max_degree) 119 | { 120 | // This is the author with the most coauthor/paper combos at HPEC 121 | target_index = ix; 122 | printf("Node with max degree (target ID): %ld\n", (unsigned long)target_index); 123 | } 124 | } 125 | } 126 | 127 | //============================================================ 128 | printf("*** Step 3: Running LAGraph's connected components (LACC) algorithm.\n"); 129 | GrB_Vector components = NULL; 130 | GrB_Index num_components = 0; 131 | 132 | LAGraph_tic (tic); 133 | 134 | //============================================================ 135 | // Replace this step with code produced in the tutorial 136 | //============================================================ 137 | LAGraph_lacc(A, &components); 138 | CountCC(components, &num_components); // compute number of components 139 | //============================================================ 140 | 141 | t = LAGraph_toc(tic); 142 | printf ("*** Step 3: Elapsed time: %g sec\n", t); 143 | 144 | printf("Number of connected components: %ld\n", (unsigned long)num_components); 145 | 146 | //pretty_print_vector_UINT64(components, "Connected components"); 147 | 148 | GrB_Index cluster_num = 666; 149 | GrB_Vector_extractElement(&cluster_num, components, target_index); 150 | printf("ID for component containing target ID %ld: %ld\n", 151 | (unsigned long)target_index, (unsigned long)cluster_num); 152 | 153 | //=========================================================== 154 | printf("*** Step 4: Find all the nodes from the target ID's cluster.\n"); 155 | LAGraph_tic(tic); 156 | G_target_id = cluster_num; 157 | GrB_UnaryOp target_eq = NULL; 158 | GrB_UnaryOp_new(&target_eq, &eq_target, GrB_BOOL, GrB_UINT64); 159 | 160 | GrB_Vector cluster_mask; 161 | GrB_Vector_new(&cluster_mask, GrB_BOOL, num_rows); 162 | 163 | // Find all elements belonging to cluster labeled cluster_num 164 | GrB_apply(cluster_mask, GrB_NULL, GrB_NULL, 165 | target_eq, components, GrB_NULL); 166 | 167 | GrB_Index nc; 168 | GrB_Vector_nvals(&nc, cluster_mask); 169 | 170 | // remove all elements that have 'stored false' 171 | GrB_Descriptor desc; 172 | GrB_Descriptor_new(&desc); 173 | GrB_Descriptor_set(desc, GrB_OUTP, GrB_REPLACE); 174 | 175 | GrB_apply(cluster_mask, cluster_mask, GrB_NULL, 176 | GrB_IDENTITY_BOOL, cluster_mask, desc); 177 | 178 | GrB_Vector_nvals(&nc, cluster_mask); 179 | 180 | // get number of elements in the mask and extract the indices 181 | GrB_Index component_size; 182 | GrB_Vector_nvals(&component_size, cluster_mask); 183 | GrB_Index *cluster_indices = malloc(component_size*sizeof(GrB_Index)); 184 | bool *vals = malloc(component_size*sizeof(bool)); 185 | 186 | GrB_Vector_extractTuples(cluster_indices, vals, 187 | &component_size, cluster_mask); 188 | t = LAGraph_toc(tic); 189 | printf("*** Step 4: Elapsed time: %g sec\n", t); 190 | 191 | printf("Cluster mask nvals (after masking): %ld\n", (unsigned long)nc); 192 | printf("Component size: %ld\n", (unsigned long)component_size); 193 | 194 | //=========================================================== 195 | printf("*** Step 5: extract and perform PageRank on the target component.\n"); 196 | LAGraph_tic (tic); 197 | GrB_Matrix A_comp; 198 | GrB_Matrix_new(&A_comp, GrB_UINT64, component_size, component_size); 199 | GrB_extract(A_comp, GrB_NULL, GrB_NULL, A, 200 | cluster_indices, component_size, 201 | cluster_indices, component_size, 202 | GrB_NULL); 203 | 204 | GrB_Vector pr; 205 | double max_rank = 0.0, min_rank = 9999999999.9; 206 | GrB_Index max_rank_id, min_rank_id; 207 | LAGraph_pagerank2(&pr, A_comp, 0.85, 100); 208 | t = LAGraph_toc(tic); 209 | printf("*** Step 5: Elapsed time: %g sec\n", t); 210 | 211 | //printf("ID:\tRank\n"); 212 | for (GrB_Index ix = 0; ix < component_size; ++ix) 213 | { 214 | double rank=-1.; 215 | GrB_Vector_extractElement(&rank, pr, ix); 216 | //printf("%ld\t%lf\n", cluster_indices[ix], rank); 217 | if (rank > max_rank) 218 | { 219 | max_rank = rank; 220 | max_rank_id = cluster_indices[ix]; 221 | } 222 | if (rank < min_rank) 223 | { 224 | min_rank = rank; 225 | min_rank_id = cluster_indices[ix]; 226 | } 227 | } 228 | 229 | printf("Author with the highest rank: %ld (%lf)\n", 230 | (unsigned long)max_rank_id, max_rank); 231 | printf("Author with the smallest rank: %ld (%lf)\n", 232 | (unsigned long)min_rank_id, min_rank); 233 | 234 | GrB_Index count = 0; 235 | double threshold = 0.25*max_rank; 236 | printf("Authors with rank > %lf:\n", threshold); 237 | printf("ID:\tRank\n"); 238 | for (GrB_Index ix = 0; ix < component_size; ++ix) 239 | { 240 | double rank=-1.; 241 | GrB_Vector_extractElement(&rank, pr, ix); 242 | if (rank > threshold) 243 | { 244 | printf("%ld\t%lf\n", (unsigned long)cluster_indices[ix], rank); 245 | ++count; 246 | } 247 | } 248 | 249 | printf("Num authors with rank > %lf: %ld\n", threshold, (unsigned long)count); 250 | 251 | //=========================================================== 252 | GrB_free(&A_comp); 253 | GrB_free(&desc); 254 | GrB_free(&cluster_mask); 255 | GrB_free(&target_eq); 256 | GrB_free(°ree); 257 | GrB_free(&components); 258 | GrB_free(&A); 259 | 260 | free(cluster_indices); 261 | free(vals); 262 | 263 | // Call instead of GrB_finalize(); 264 | LAGraph_finalize(); 265 | return (GrB_SUCCESS); 266 | } 267 | -------------------------------------------------------------------------------- /src/BuildGraph.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the GraphBLAS Tutorial materials, 3 | * Copyright (c) 2018 Carnegie Mellon University and Intel Corporation. 4 | * All Rights Reserved 5 | * 6 | * THIS SOFTWARE IS PROVIDED "AS IS," WITH NO WARRANTIES WHATSOEVER. CARNEGIE 7 | * MELLON UNIVERSITY AND INTEL CORPORATION EXPRESSLY DISCLAIMS TO THE FULLEST 8 | * EXTENT PERMITTED BY LAW ALL EXPRESS, IMPLIED, AND STATUTORY WARRANTIES, 9 | * INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS 10 | * FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF PROPRIETARY RIGHTS. 11 | * 12 | * Released under a BSD (SEI)-style license, please see LICENSE.txt for 13 | * full terms. 14 | * 15 | * DM18-1037 16 | * 17 | * Authors: Scott McMillan, Timothy G. Mattson 18 | */ 19 | 20 | /** 21 | * @file BuildGraph.c 22 | * 23 | * @brief Build an adjacency matrix and verify our toolchain works 24 | * 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include "tutorial_utils.h" 31 | 32 | //**************************************************************************** 33 | int main(int argc, char** argv) 34 | { 35 | GrB_Index const NUM_NODES = 3; 36 | GrB_Matrix graph; 37 | 38 | // Initialize a GraphBLAS context 39 | GrB_init(GrB_BLOCKING); 40 | 41 | GrB_Matrix_new(&graph, GrB_UINT64, NUM_NODES, NUM_NODES); 42 | 43 | GrB_Matrix_setElement(graph, 4, 1, 2); // set 1,2 element to 4 44 | 45 | pretty_print_matrix_UINT64(graph, "GRAPH"); 46 | 47 | GrB_Index nvals; 48 | GrB_Matrix_nvals(&nvals, graph); 49 | assert(nvals == 1); 50 | 51 | // Cleanup 52 | GrB_free(&graph); 53 | GrB_finalize(); 54 | } 55 | -------------------------------------------------------------------------------- /src/Challenge_problems/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of the GraphBLAS tutorial materials, 3 | # Copyright (c) 2018 Carnegie Mellon University and Intel Corporation. 4 | # 5 | # THIS SOFTWARE IS PROVIDED "AS IS," WITH NO WARRANTIES WHATSOEVER. CARNEGIE 6 | # MELLON UNIVERSITY AND INTEL CORPORATION EXPRESSLY DISCLAIMS TO THE FULLEST 7 | # EXTENT PERMITTED BY LAW ALL EXPRESS, IMPLIED, AND STATUTORY WARRANTIES, 8 | # INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS 9 | # FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF PROPRIETARY RIGHTS. 10 | # 11 | # Released under a BSD (SEI)-style license, please see LICENSE.txt for 12 | # full terms. 13 | # 14 | # Authors: Scott McMillan, Timothy G. Mattson 15 | # 16 | 17 | # Project root not used yet 18 | PROJECT_ROOT = some_path_to/HPEC18_tutorial/code 19 | 20 | INCDIR = ../../include 21 | LIBDIR = ../../lib 22 | 23 | include ../make.def 24 | 25 | SOURCES = betweenness_centrality.c maximal_independent_set.c \ 26 | triangle_count.c page_rank.c 27 | 28 | OBJECTS = $(SOURCES:.c=.o) 29 | TARGETS = $(SOURCES:.c=.exe) 30 | DSYM = $(SOURCES:.c=.exe.dSYM) 31 | HEADERS = $(wildcard $(INCDIR)/*.h) 32 | PCHS = $(HEADERS:=.gch) 33 | 34 | .PHONY : all clean 35 | 36 | all : $(TARGETS) 37 | 38 | %.s : %.c $(HEADERS) 39 | $(CC) -S $(CCFLAGS) $< 40 | 41 | %.o : %.c $(HEADERS) 42 | $(CC) -c $(CCFLAGS) $< 43 | 44 | %.exe : %.o 45 | $(CC) $^ -o $@ $(LIB) 46 | 47 | clean : 48 | /bin/rm -rf a.out $(TARGETS) $(OBJECTS) $(PCHS) $(DSYM) *~ 49 | 50 | 51 | squeaky : clean 52 | /bin/rm -f $(SOURCES:%.c=%.d) 53 | 54 | .SECONDARY : $(OBJECTS) 55 | 56 | -include $(SOURCES:%.c=%.d) 57 | 58 | -------------------------------------------------------------------------------- /src/Challenge_problems/betweenness_centrality.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the GraphBLAS Tutorial materials, 3 | * Copyright (c) 2018 Carnegie Mellon University and Intel Corporation. 4 | * All Rights Reserved 5 | * 6 | * THIS SOFTWARE IS PROVIDED "AS IS," WITH NO WARRANTIES WHATSOEVER. CARNEGIE 7 | * MELLON UNIVERSITY AND INTEL CORPORATION EXPRESSLY DISCLAIMS TO THE FULLEST 8 | * EXTENT PERMITTED BY LAW ALL EXPRESS, IMPLIED, AND STATUTORY WARRANTIES, 9 | * INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS 10 | * FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF PROPRIETARY RIGHTS. 11 | * 12 | * Released under a BSD (SEI)-style license, please see LICENSE.txt for 13 | * full terms. 14 | * 15 | * DM18-xxx 16 | * 17 | * Authors: Scott McMillan, Timothy G. Mattson 18 | */ 19 | 20 | /** 21 | * @file betweenness_centrality.c 22 | * 23 | * @brief Two implementations of the betweenness centrality algorithm using 24 | * the GraphBLAS C API. One for single source contribution and one for 25 | * batch contribution. 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include "tutorial_utils.h" 34 | 35 | //**************************************************************************** 36 | /* 37 | * Given a boolean n x n adjacency matrix A and a source vertex s, 38 | * compute the BC-metric vector delta, which should be empty on input. 39 | */ 40 | GrB_Info BC(GrB_Vector *delta, GrB_Matrix A, GrB_Index s) 41 | { 42 | GrB_Index n; 43 | GrB_Matrix_nrows(&n,A); // n = # of vertices in graph 44 | 45 | GrB_Vector_new(delta,GrB_FP32,n); // Vector delta(n) 46 | 47 | GrB_Matrix sigma; // Matrix sigma(n,n) 48 | GrB_Matrix_new(&sigma,GrB_INT32,n,n); // sigma[d,k] = #shortest paths to node k at level d 49 | 50 | GrB_Vector q; 51 | GrB_Vector_new(&q, GrB_INT32, n); // Vector q(n) of path counts 52 | GrB_Vector_setElement(q,1,s); // q[s] = 1 53 | 54 | GrB_Vector p; // Vector p(n) shortest path counts so far 55 | GrB_Vector_dup(&p, q); // p = q 56 | 57 | GrB_Monoid Int32Add; // Monoid 58 | GrB_Monoid_new(&Int32Add,GrB_PLUS_INT32,0); 59 | GrB_Semiring Int32AddMul; // Semiring 60 | GrB_Semiring_new(&Int32AddMul,Int32Add,GrB_TIMES_INT32); 61 | 62 | GrB_Descriptor desc; // Descriptor for vxm 63 | GrB_Descriptor_new(&desc); 64 | GrB_Descriptor_set(desc,GrB_MASK,GrB_SCMP); // structural complement of the mask 65 | GrB_Descriptor_set(desc,GrB_OUTP,GrB_REPLACE);// clear the output before assignment 66 | 67 | GrB_Descriptor tr1; // Transpose 1st input argument 68 | GrB_Descriptor_new(&tr1); 69 | GrB_Descriptor_set(tr1,GrB_INP0,GrB_TRAN); // structural complement of the mask 70 | 71 | GrB_vxm(q,p,GrB_NULL,Int32AddMul,q,A,desc); // get the first set of out neighbors 72 | 73 | /* 74 | * BFS phase 75 | */ 76 | int32_t d = 0; // BFS level number 77 | int32_t sum = 0; // sum == 0 when BFS phase is complete 78 | do { 79 | GrB_assign(sigma,GrB_NULL,GrB_NULL,q,d,GrB_ALL,n,GrB_NULL); // sigma[d,:] = q 80 | GrB_eWiseAdd(p,GrB_NULL,GrB_NULL,Int32AddMul,p,q,GrB_NULL); // accumulate path counts on this level 81 | GrB_vxm(q,p,GrB_NULL,Int32AddMul,q,A,desc); // q = # paths to nodes reachable 82 | // from current level 83 | GrB_reduce(&sum,GrB_NULL,Int32Add,q,GrB_NULL); // sum path counts at this level 84 | ++d; 85 | } while (sum); 86 | 87 | /* 88 | * BC computation phase 89 | * (t1,t2,t3,t4) are temporary vectors 90 | */ 91 | GrB_Monoid FP32Add; // Monoid 92 | GrB_Monoid_new(&FP32Add,GrB_PLUS_FP32,0.0f); 93 | 94 | GrB_Monoid FP32Mul; // Monoid 95 | GrB_Monoid_new(&FP32Mul,GrB_TIMES_FP32,1.0f); 96 | 97 | GrB_Semiring FP32AddMul; // Semiring 98 | GrB_Semiring_new(&FP32AddMul,FP32Add,GrB_TIMES_FP32); 99 | 100 | GrB_Vector t1; GrB_Vector_new(&t1,GrB_FP32,n); 101 | GrB_Vector t2; GrB_Vector_new(&t2,GrB_FP32,n); 102 | GrB_Vector t3; GrB_Vector_new(&t3,GrB_FP32,n); 103 | GrB_Vector t4; GrB_Vector_new(&t4,GrB_FP32,n); 104 | for(int i=d-1; i>0; i--) 105 | { 106 | GrB_assign(t1,GrB_NULL,GrB_NULL,1.0f,GrB_ALL,n,GrB_NULL); // t1 = 1+delta 107 | GrB_eWiseAdd(t1,GrB_NULL,GrB_NULL,FP32Add,t1,*delta,GrB_NULL); 108 | GrB_extract(t2,GrB_NULL,GrB_NULL,sigma,GrB_ALL,n,i,tr1); // t2 = sigma[i,:] 109 | GrB_eWiseMult(t2,GrB_NULL,GrB_NULL,GrB_DIV_FP32,t1,t2,GrB_NULL); // t2 = (1+delta)/sigma[i,:] 110 | GrB_mxv(t3,GrB_NULL,GrB_NULL,FP32AddMul,A,t2,GrB_NULL); // add contributions made by 111 | // successors of a node 112 | GrB_extract(t4,GrB_NULL,GrB_NULL,sigma,GrB_ALL,n,i-1,tr1); // t4 = sigma[i-1,:] 113 | GrB_eWiseMult(t4,GrB_NULL,GrB_NULL,FP32Mul,t4,t3,GrB_NULL); // t4 = sigma[i-1,:]*t3 114 | GrB_eWiseAdd(*delta,GrB_NULL,GrB_NULL,FP32Add,*delta,t4,GrB_NULL); // accumulate into delta 115 | } 116 | 117 | GrB_free(&sigma); 118 | GrB_free(&q); GrB_free(&p); 119 | GrB_free(&Int32AddMul); GrB_free(&Int32Add); GrB_free(&FP32AddMul); 120 | GrB_free(&FP32Add); GrB_free(&FP32Mul); 121 | GrB_free(&desc); 122 | GrB_free(&t1); GrB_free(&t2); GrB_free(&t3); GrB_free(&t4); 123 | 124 | return GrB_SUCCESS; 125 | } 126 | 127 | //**************************************************************************** 128 | // Compute partial BC metric for a subset of source vertices, s, in graph A 129 | GrB_Info BC_update(GrB_Vector *delta, GrB_Matrix A, GrB_Index *s, GrB_Index nsver) 130 | { 131 | GrB_Index n; 132 | GrB_Matrix_nrows(&n, A); // n = # of vertices in graph 133 | GrB_Vector_new(delta,GrB_FP32,n); // Vector delta(n) 134 | 135 | GrB_Monoid Int32Add; // Monoid 136 | GrB_Monoid_new(&Int32Add,GrB_PLUS_INT32,0); 137 | GrB_Semiring Int32AddMul; // Semiring 138 | GrB_Semiring_new(&Int32AddMul,Int32Add,GrB_TIMES_INT32); 139 | 140 | // Descriptor for BFS phase mxm 141 | GrB_Descriptor desc_tsr; 142 | GrB_Descriptor_new(&desc_tsr); 143 | GrB_Descriptor_set(desc_tsr,GrB_INP0,GrB_TRAN); // transpose the adjacency matrix 144 | GrB_Descriptor_set(desc_tsr,GrB_MASK,GrB_SCMP); // complement the mask 145 | GrB_Descriptor_set(desc_tsr,GrB_OUTP,GrB_REPLACE); // clear output before result is stored 146 | 147 | // index and value arrays needed to build numsp 148 | GrB_Index *i_nsver = (GrB_Index*)malloc(sizeof(GrB_Index)*nsver); 149 | int32_t *ones = (int32_t*) malloc(sizeof(int32_t)*nsver); 150 | for(int i=0; i = A' +.* f (update frontier) 186 | GrB_Matrix_nvals(&nvals,frontier); // number of nodes in frontier at this level 187 | d++; 188 | } while (nvals); 189 | 190 | GrB_Monoid FP32Add; // Monoid 191 | GrB_Monoid_new(&FP32Add,GrB_PLUS_FP32,0.0f); 192 | GrB_Monoid FP32Mul; // Monoid 193 | GrB_Monoid_new(&FP32Mul,GrB_TIMES_FP32,1.0f); 194 | GrB_Semiring FP32AddMul; // Semiring 195 | GrB_Semiring_new(&FP32AddMul,FP32Add,GrB_TIMES_FP32); 196 | 197 | // nspinv: the inverse of the number of shortest paths for each node and starting vertex. |\label{line:nspinv}| 198 | GrB_Matrix nspinv; 199 | GrB_Matrix_new(&nspinv,GrB_FP32,n,nsver); 200 | GrB_apply(nspinv,GrB_NULL,GrB_NULL, 201 | GrB_MINV_FP32,numsp,GrB_NULL); // nspinv = 1./numsp 202 | 203 | // bcu: BC updates for each vertex for each starting vertex in s 204 | GrB_Matrix bcu; 205 | GrB_Matrix_new(&bcu,GrB_FP32,n,nsver); 206 | GrB_assign(bcu,GrB_NULL,GrB_NULL, 207 | 1.0f,GrB_ALL,n, GrB_ALL,nsver,GrB_NULL); // filled with 1 to avoid sparsity issues 208 | 209 | // Descriptor used in the tally phase 210 | GrB_Descriptor desc_r; 211 | GrB_Descriptor_new(&desc_r); 212 | GrB_Descriptor_set(desc_r,GrB_OUTP,GrB_REPLACE); // clear output before result is stored 213 | 214 | GrB_Matrix w; // temporary workspace matrix 215 | GrB_Matrix_new(&w,GrB_FP32,n,nsver); 216 | 217 | // -------------------- Tally phase (backward sweep) -------------------- 218 | for (int i=d-1; i>0; i--) { 219 | GrB_eWiseMult(w,sigmas[i],GrB_NULL, 220 | FP32Mul,bcu,nspinv,desc_r); // w=(1 ./ nsp).*bcu 221 | 222 | // add contributions by successors and mask with that BFS level's frontier 223 | GrB_mxm(w,sigmas[i-1],GrB_NULL, 224 | FP32AddMul,A,w,desc_r); // w = (A +.* w) 225 | GrB_eWiseMult(bcu,GrB_NULL,GrB_PLUS_FP32, 226 | FP32Mul,w,numsp,GrB_NULL); // bcu += w .* numsp 227 | } 228 | 229 | // subtract "nsver" from every entry in delta (account for 1 extra value per bcu element) 230 | GrB_assign(*delta,GrB_NULL,GrB_NULL, 231 | -(float)nsver,GrB_ALL,n,GrB_NULL); // fill with -nsver 232 | GrB_reduce(*delta,GrB_NULL,GrB_PLUS_FP32, 233 | GrB_PLUS_FP32,bcu,GrB_NULL); // add all updates to -nsver 234 | 235 | // Release resources 236 | for(int i=0; i 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include "tutorial_utils.h" 32 | 33 | // Assign a random number to each element scaled by the inverse of the node's degree. 34 | // This will increase the probability that low degree nodes are selected and larger 35 | // sets are selected. 36 | void setRandom(void *out, const void *in) 37 | { 38 | uint32_t degree = *(uint32_t*)in; 39 | double rnd = (double)random()/((double)RAND_MAX); 40 | *(float*)out = (0.0001f + rnd/(1. + 2.*degree)); // add 1 to prevent divide by zero 41 | } 42 | 43 | /* 44 | * A variant of Luby's randomized algorithm [Luby 1985]. 45 | * 46 | * Given a numeric n x n adjacency matrix A of an unwieghted and undirected graph (where 47 | * the value true represents an edge), compute a maximal set of independent vertices and 48 | * return it in a boolean n-vector, 'iset' where set[i] == true implies vertex i is a member 49 | * of the set (the iset vector should be uninitialized on input.) 50 | */ 51 | GrB_Info MIS(GrB_Vector *iset, const GrB_Matrix A) 52 | { 53 | GrB_Index n; 54 | GrB_Matrix_nrows(&n,A); // n = # of rows of A 55 | 56 | GrB_Vector prob; // holds random probabilities for each node 57 | GrB_Vector neighbor_max; // holds value of max neighbor probability 58 | GrB_Vector new_members; // holds set of new members to iset 59 | GrB_Vector new_neighbors; // holds set of new neighbors to new iset mbrs. 60 | GrB_Vector candidates; // candidate members to iset 61 | 62 | GrB_Vector_new(&prob,GrB_FP32,n); 63 | GrB_Vector_new(&neighbor_max,GrB_FP32,n); 64 | GrB_Vector_new(&new_members,GrB_BOOL,n); 65 | GrB_Vector_new(&new_neighbors,GrB_BOOL,n); 66 | GrB_Vector_new(&candidates,GrB_BOOL,n); 67 | GrB_Vector_new(iset,GrB_BOOL,n); // Initialize independent set vector, bool 68 | 69 | GrB_Monoid Max; 70 | GrB_Monoid_new(&Max,GrB_MAX_FP32,0.0f); 71 | 72 | GrB_Semiring maxSelect2nd; // Max/Select2nd "semiring" 73 | GrB_Semiring_new(&maxSelect2nd,Max,GrB_SECOND_FP32); 74 | 75 | GrB_Monoid Lor; 76 | GrB_Monoid_new(&Lor,GrB_LOR,(bool)false); 77 | 78 | GrB_Semiring Boolean; // Boolean semiring 79 | GrB_Semiring_new(&Boolean,Lor,GrB_LAND); 80 | 81 | // replace 82 | GrB_Descriptor r_desc; 83 | GrB_Descriptor_new(&r_desc); 84 | GrB_Descriptor_set(r_desc,GrB_OUTP,GrB_REPLACE); 85 | 86 | // replace + structural complement of mask 87 | GrB_Descriptor sr_desc; 88 | GrB_Descriptor_new(&sr_desc); 89 | GrB_Descriptor_set(sr_desc,GrB_MASK,GrB_SCMP); 90 | GrB_Descriptor_set(sr_desc,GrB_OUTP,GrB_REPLACE); 91 | 92 | GrB_UnaryOp set_random; 93 | GrB_UnaryOp_new(&set_random,setRandom,GrB_FP32,GrB_UINT32); 94 | 95 | // compute the degree of each vertex. 96 | GrB_Vector degrees; 97 | GrB_Vector_new(°rees,GrB_FP64,n); 98 | GrB_reduce(degrees,GrB_NULL,GrB_NULL,GrB_PLUS_FP64,A,GrB_NULL); 99 | 100 | // Isolated vertices are not candidates: candidates[degrees != 0] = true 101 | GrB_assign(candidates,degrees,GrB_NULL,true,GrB_ALL,n,GrB_NULL); 102 | 103 | // add all singletons to iset: iset[degree == 0] = 1 104 | GrB_assign(*iset,degrees,GrB_NULL,true,GrB_ALL,n,sr_desc) ; 105 | 106 | // Iterate while there are candidates to check. 107 | GrB_Index nvals; 108 | GrB_Vector_nvals(&nvals, candidates); 109 | while (nvals > 0) { 110 | // compute a random probability scaled by inverse of degree 111 | GrB_apply(prob,candidates,GrB_NULL,set_random,degrees,r_desc); 112 | 113 | // compute the max probability of all neighbors 114 | GrB_mxv(neighbor_max,candidates,GrB_NULL,maxSelect2nd,A,prob,r_desc); 115 | 116 | // select vertex if its probability is larger than all its active neighbors, 117 | // and apply a "masked no-op" to remove stored falses 118 | GrB_eWiseAdd(new_members,GrB_NULL,GrB_NULL,GrB_GT_FP64,prob,neighbor_max,GrB_NULL); 119 | GrB_apply(new_members,new_members,GrB_NULL,GrB_IDENTITY_BOOL,new_members,r_desc); 120 | 121 | // add new members to independent set. 122 | GrB_eWiseAdd(*iset,GrB_NULL,GrB_NULL,GrB_LOR,*iset,new_members,GrB_NULL); 123 | 124 | // remove new members from set of candidates c = c & !new 125 | GrB_eWiseMult(candidates,new_members,GrB_NULL, 126 | GrB_LAND,candidates,candidates,sr_desc); 127 | 128 | GrB_Vector_nvals(&nvals, candidates); 129 | if (nvals == 0) { break; } // early exit condition 130 | 131 | // Neighbors of new members can also be removed from candidates 132 | GrB_mxv(new_neighbors,candidates,GrB_NULL,Boolean,A,new_members,GrB_NULL); 133 | GrB_eWiseMult(candidates,new_neighbors,GrB_NULL, 134 | GrB_LAND,candidates,candidates,sr_desc); 135 | 136 | GrB_Vector_nvals(&nvals, candidates); 137 | } 138 | 139 | GrB_free(&neighbor_max); // free all objects "new'ed" 140 | GrB_free(&new_members); 141 | GrB_free(&new_neighbors); 142 | GrB_free(&prob); 143 | GrB_free(&candidates); 144 | GrB_free(&maxSelect2nd); 145 | GrB_free(&Boolean); 146 | GrB_free(&Max); 147 | GrB_free(&Lor); 148 | GrB_free(&sr_desc); 149 | GrB_free(&r_desc); 150 | GrB_free(&set_random); 151 | GrB_free(°rees); 152 | 153 | return GrB_SUCCESS; 154 | } 155 | 156 | //**************************************************************************** 157 | int main(int argc, char **argv) 158 | { 159 | #if 1 160 | // Logo graph undirected (symmetricized) 161 | GrB_Index const NUM_NODES = 7; 162 | GrB_Index const NUM_EDGES = 20; 163 | GrB_Index row_indices[] = {0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 6}; 164 | GrB_Index col_indices[] = {1, 3, 0, 4, 6, 3, 5, 6, 0, 2, 6, 1, 5, 6, 2, 4, 1, 2, 3, 4}; 165 | bool values[] = {true, true, true, true, true, true, true, true, true, true, 166 | true, true, true, true, true, true, true, true, true, true}; 167 | #else 168 | // Karate club graph 169 | GrB_Index const NUM_NODES = 34; 170 | GrB_Index const NUM_EDGES = 156; 171 | GrB_Index row_indices[] = { 172 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 173 | 1,1,1,1,1,1,1,1,1, 174 | 2,2,2,2,2,2,2,2,2,2, 175 | 3,3,3,3,3,3, 176 | 4,4,4, 177 | 5,5,5,5, 178 | 6,6,6,6, 179 | 7,7,7,7, 180 | 8,8,8,8,8, 181 | 9,9, 182 | 10,10,10, 183 | 11, 184 | 12,12, 185 | 13,13,13,13,13, 186 | 14,14, 187 | 15,15, 188 | 16,16, 189 | 17,17, 190 | 18,18, 191 | 19,19,19, 192 | 20,20, 193 | 21,21, 194 | 22,22, 195 | 23,23,23,23,23, 196 | 24,24,24, 197 | 25,25,25, 198 | 26,26, 199 | 27,27,27,27, 200 | 28,28,28, 201 | 29,29,29,29, 202 | 30,30,30,30, 203 | 31,31,31,31,31,31, 204 | 32,32,32,32,32,32,32,32,32,32,32,32, 205 | 33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33}; 206 | 207 | GrB_Index col_indices[] = { 208 | 1,2,3,4,5,6,7,8,10,11,12,13,17,19,21,31, 209 | 0,2,3,7,13,17,19,21,30, 210 | 0,1,3,7,8,9,13,27,28,32, 211 | 0,1,2,7,12,13, 212 | 0,6,10, 213 | 0,6,10,16, 214 | 0,4,5,16, 215 | 0,1,2,3, 216 | 0,2,30,32,33, 217 | 2,33, 218 | 0,4,5, 219 | 0, 220 | 0,3, 221 | 0,1,2,3,33, 222 | 32,33, 223 | 32,33, 224 | 5,6, 225 | 0,1, 226 | 32,33, 227 | 0,1,33, 228 | 32,33, 229 | 0,1, 230 | 32,33, 231 | 25,27,29,32,33, 232 | 25,27,31, 233 | 23,24,31, 234 | 29,33, 235 | 2,23,24,33, 236 | 2,31,33, 237 | 23,26,32,33, 238 | 1,8,32,33, 239 | 0,24,25,28,32,33, 240 | 2,8,14,15,18,20,22,23,29,30,31,33, 241 | 8,9,13,14,15,18,19,20,22,23,26,27,28,29,30,31,32}; 242 | 243 | bool values[156]; 244 | for (size_t ix = 0; ix < NUM_EDGES; ++ix) 245 | { 246 | values[ix] = true; 247 | } 248 | #endif 249 | 250 | GrB_Matrix graph; 251 | 252 | // Initialize a GraphBLAS context 253 | GrB_init(GrB_BLOCKING); 254 | 255 | GrB_Matrix_new(&graph, GrB_BOOL, NUM_NODES, NUM_NODES); 256 | GrB_Matrix_build(graph, row_indices, col_indices, (bool*)values, NUM_EDGES, 257 | GrB_LOR); 258 | 259 | pretty_print_matrix_FP64(graph, "GRAPH"); 260 | 261 | unsigned int const NUM_ITERS = 100; 262 | GrB_Index set_sizes = 0; 263 | GrB_Vector iset; 264 | GrB_Index set_indices[NUM_NODES]; 265 | bool set_vals[NUM_NODES]; 266 | for (unsigned int iter = 0; iter < NUM_ITERS; ++iter) 267 | { 268 | srandom(iter); // set a new random seed 269 | MIS(&iset, graph); 270 | GrB_Index nvals; 271 | GrB_Vector_nvals(&nvals, iset); 272 | set_sizes += nvals; 273 | fprintf(stdout, "%d: size = %ld: ", iter, nvals); 274 | GrB_Vector_extractTuples(set_indices, set_vals, &nvals, iset); 275 | for (GrB_Index ix = 0; ix < nvals; ++ix) 276 | fprintf(stdout, " %ld", set_indices[ix]); 277 | fprintf(stdout, "\n"); 278 | GrB_free(&iset); 279 | } 280 | fprintf(stdout, "Average set size = %lf\n", (double)set_sizes/(double)NUM_ITERS); 281 | 282 | // Cleanup 283 | GrB_free(&graph); 284 | GrB_finalize(); 285 | 286 | return GrB_SUCCESS; 287 | } 288 | -------------------------------------------------------------------------------- /src/Challenge_problems/page_rank.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the GraphBLAS Tutorial materials, 3 | * Copyright (c) 2018 Carnegie Mellon University and Intel Corporation. 4 | * All Rights Reserved 5 | * 6 | * THIS SOFTWARE IS PROVIDED "AS IS," WITH NO WARRANTIES WHATSOEVER. CARNEGIE 7 | * MELLON UNIVERSITY AND INTEL CORPORATION EXPRESSLY DISCLAIMS TO THE FULLEST 8 | * EXTENT PERMITTED BY LAW ALL EXPRESS, IMPLIED, AND STATUTORY WARRANTIES, 9 | * INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS 10 | * FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF PROPRIETARY RIGHTS. 11 | * 12 | * Released under a BSD (SEI)-style license, please see LICENSE.txt for 13 | * full terms. 14 | * 15 | * DM18-xxx 16 | * 17 | * Authors: Scott McMillan, Timothy G. Mattson 18 | */ 19 | 20 | /** 21 | * @file page_rank.c 22 | * 23 | * @brief A PageRank implementation using GraphBLAS C API. Adapted from the 24 | * GraphBLAS Template Library (GBTL) Version 2.0 license. 25 | */ 26 | 27 | #include 28 | #include 29 | #include "tutorial_utils.h" 30 | 31 | //**************************************************************************** 32 | double G_damping_factor; 33 | void times_damping_factor(void *out, void const *in) 34 | { 35 | *(double*)out = G_damping_factor * (*((double*)in)); 36 | } 37 | 38 | //**************************************************************************** 39 | double G_scaled_teleport; 40 | void plus_scaled_teleport(void *out, void const *in) 41 | { 42 | *(double*)out = G_scaled_teleport + (*((double*)in)); 43 | } 44 | 45 | //**************************************************************************** 46 | /** 47 | * @brief Compute the page rank for each node in a graph. 48 | * 49 | * Need more documentation 50 | * 51 | * @note Because of the random component of this algorithm, the MIS 52 | * calculated across various calls to mis may vary. 53 | * 54 | * @note This only works with floating point scalars. 55 | * 56 | * @param[in] graph NxN adjacency matrix (of doubles) of graph to 57 | * compute the page rank. The structural zero needs 58 | * to be '0' and edges are indicated by '1.0' 59 | * to support use of the Arithmetic FP64 semiring. 60 | * @param[out] page_rank N-vector (double) of page ranks (_new already called) 61 | * @param[in] damping_factor The constant to ensure stability in cyclic 62 | * graphs (often 0.85) 63 | * @param[in] threshold The sum of squared errors termination 64 | * threshold. 65 | * @param[in] max_iters The maximum number of iterations to perform (if 66 | * threshold is not met). 67 | * 68 | */ 69 | GrB_Info page_rank(GrB_Matrix const graph, 70 | GrB_Vector ranks, 71 | double damping_factor, 72 | double threshold, 73 | unsigned int max_iters) 74 | { 75 | GrB_Index rows, cols, num_nodes; 76 | GrB_Matrix_nrows(&rows, graph); 77 | GrB_Matrix_ncols(&cols, graph); 78 | GrB_Vector_size(&num_nodes, ranks); 79 | 80 | if ((rows != cols) || (num_nodes != rows)) 81 | { 82 | return GrB_DIMENSION_MISMATCH; 83 | } 84 | 85 | // Compute the scaled graph matrix, M, by normalizing the edge 86 | // weights of the graph by the vertices' out-degrees (num_nodes) 87 | GrB_Matrix M; 88 | GrB_Matrix_dup(&M, graph); 89 | 90 | GrB_Vector w; 91 | GrB_Vector_new(&w, GrB_FP64, num_nodes); 92 | GrB_reduce(w, GrB_NULL, GrB_NULL, GrB_PLUS_FP64, M, GrB_NULL); 93 | GrB_apply(w, GrB_NULL, GrB_NULL, GrB_MINV_FP64, w, GrB_NULL); 94 | 95 | GrB_Index num_vals; 96 | GrB_Vector_nvals(&num_vals, w); 97 | 98 | GrB_Index *indices = malloc(num_vals*sizeof(GrB_Index)); 99 | double *values = malloc(num_vals*sizeof(double)); 100 | 101 | GrB_Vector_extractTuples(indices, values, &num_vals, w); 102 | 103 | //populate diagonal: 104 | GrB_Matrix Mdiag; 105 | GrB_Matrix_new(&Mdiag, GrB_FP64, num_nodes, num_nodes); 106 | GrB_Matrix_build(Mdiag, indices, indices, values, num_vals, GrB_PLUS_FP64); 107 | 108 | //Perform matrix multiply to scale rows 109 | GrB_mxm(M, GrB_NULL, GrB_NULL, GxB_PLUS_TIMES_FP64, Mdiag, M, GrB_NULL); 110 | 111 | pretty_print_matrix_FP64(M, "Normalized Graph"); 112 | 113 | // scale the normalized edge weights by the damping factor 114 | G_damping_factor = damping_factor; 115 | GrB_UnaryOp multiply_damping_factor; 116 | GrB_UnaryOp_new(&multiply_damping_factor, times_damping_factor, 117 | GrB_FP64, GrB_FP64); 118 | GrB_apply(M, GrB_NULL, GrB_NULL, multiply_damping_factor, 119 | M, GrB_NULL); 120 | 121 | pretty_print_matrix_FP64(M, "Scaled Graph"); 122 | G_scaled_teleport = (1.0 - damping_factor) / ((double)num_nodes); 123 | GrB_UnaryOp add_scaled_teleport; 124 | GrB_UnaryOp_new(&add_scaled_teleport, plus_scaled_teleport, 125 | GrB_FP64, GrB_FP64); 126 | 127 | // Initialize all page ranks to 1/N 128 | GrB_assign(ranks, GrB_NULL, GrB_NULL, 1.0/((double)num_nodes), 129 | GrB_ALL, num_nodes, GrB_NULL); 130 | 131 | GrB_Vector new_rank, delta; 132 | GrB_Vector_new(&new_rank, GrB_FP64, num_nodes); 133 | GrB_Vector_new(&delta, GrB_FP64, num_nodes); 134 | for (GrB_Index i = 0; i < max_iters; ++i) 135 | { 136 | fprintf(stdout, "============= ITERATION %ld ============\n", i); 137 | pretty_print_vector_FP64(ranks, "rank"); 138 | 139 | // Compute the new rank: [1 x N] := [1 x N][N x N] 140 | GrB_vxm(new_rank, GrB_NULL, GrB_NULL, GxB_PLUS_TIMES_FP64, 141 | ranks, M, GrB_NULL); 142 | pretty_print_vector_FP64(new_rank, "step 1:"); 143 | 144 | // [1 x N][N x 1] = [1 x 1] = always (1 - damping_factor) 145 | // rank*(m + scaling_mat*teleport): [1 x 1][1 x N] + [1 x N] = [1 x N] 146 | // use apply to add "scaled teleport": 147 | GrB_apply(new_rank, GrB_NULL, GrB_NULL, add_scaled_teleport, 148 | new_rank, GrB_NULL); 149 | pretty_print_vector_FP64(new_rank, "new_rank"); 150 | 151 | // Test for convergence - compute squared error 152 | /// @todo should be mean squared error. (divide r2/N) 153 | double squared_error; 154 | GrB_eWiseAdd(delta, GrB_NULL, GrB_NULL, GrB_MINUS_FP64, 155 | ranks, new_rank, GrB_NULL); 156 | GrB_eWiseMult(delta, GrB_NULL, GrB_NULL, GrB_TIMES_FP64, 157 | delta, delta, GrB_NULL); 158 | GrB_reduce(&squared_error, GrB_NULL, GxB_PLUS_FP64_MONOID, 159 | delta, GrB_NULL); 160 | 161 | fprintf(stdout, "Squared error = %lf\n", squared_error); 162 | 163 | //copy new page rank vector 164 | GrB_assign(ranks, GrB_NULL, GrB_NULL, new_rank, 165 | GrB_ALL, num_nodes, GrB_NULL); 166 | 167 | // check mean-squared error 168 | if (squared_error/((double)num_nodes) < threshold) 169 | { 170 | break; 171 | } 172 | } 173 | 174 | // for any elements missing from page rank vector we need to set 175 | // to scaled teleport. 176 | //GrB_assign(new_rank, GrB_NULL, GrB_NULL, 177 | // (1.0 - damping_factor) / ((double)num_nodes), 178 | // GrB_ALL, GrB_NULL); 179 | //GrB_eWiseAdd(ranks, ranks, GrB_NULL, GrB_PLUS_FP64, 180 | // ranks, new_rank, desc_c); 181 | 182 | free(indices); 183 | free(values); 184 | GrB_free(&delta); 185 | GrB_free(&new_rank); 186 | GrB_free(&add_scaled_teleport); 187 | GrB_free(&multiply_damping_factor); 188 | GrB_free(&M); 189 | GrB_free(&Mdiag); 190 | GrB_free(&w); 191 | 192 | return GrB_SUCCESS; 193 | } 194 | 195 | //**************************************************************************** 196 | int main(int argc, char **argv) 197 | { 198 | #if 1 199 | // Logo graph 200 | GrB_Index const NUM_NODES = 7; 201 | GrB_Index const NUM_EDGES = 12; 202 | GrB_Index row_indices[] = {0, 0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 6}; 203 | GrB_Index col_indices[] = {1, 3, 4, 6, 5, 0, 2, 5, 2, 2, 3, 4}; 204 | double values[] = {1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.}; 205 | #else 206 | // Karate club graph 207 | GrB_Index const NUM_NODES = 34; 208 | GrB_Index const NUM_EDGES = 156; 209 | GrB_Index row_indices[] = { 210 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 211 | 1,1,1,1,1,1,1,1,1, 212 | 2,2,2,2,2,2,2,2,2,2, 213 | 3,3,3,3,3,3, 214 | 4,4,4, 215 | 5,5,5,5, 216 | 6,6,6,6, 217 | 7,7,7,7, 218 | 8,8,8,8,8, 219 | 9,9, 220 | 10,10,10, 221 | 11, 222 | 12,12, 223 | 13,13,13,13,13, 224 | 14,14, 225 | 15,15, 226 | 16,16, 227 | 17,17, 228 | 18,18, 229 | 19,19,19, 230 | 20,20, 231 | 21,21, 232 | 22,22, 233 | 23,23,23,23,23, 234 | 24,24,24, 235 | 25,25,25, 236 | 26,26, 237 | 27,27,27,27, 238 | 28,28,28, 239 | 29,29,29,29, 240 | 30,30,30,30, 241 | 31,31,31,31,31,31, 242 | 32,32,32,32,32,32,32,32,32,32,32,32, 243 | 33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33}; 244 | 245 | GrB_Index col_indices[] = { 246 | 1,2,3,4,5,6,7,8,10,11,12,13,17,19,21,31, 247 | 0,2,3,7,13,17,19,21,30, 248 | 0,1,3,7,8,9,13,27,28,32, 249 | 0,1,2,7,12,13, 250 | 0,6,10, 251 | 0,6,10,16, 252 | 0,4,5,16, 253 | 0,1,2,3, 254 | 0,2,30,32,33, 255 | 2,33, 256 | 0,4,5, 257 | 0, 258 | 0,3, 259 | 0,1,2,3,33, 260 | 32,33, 261 | 32,33, 262 | 5,6, 263 | 0,1, 264 | 32,33, 265 | 0,1,33, 266 | 32,33, 267 | 0,1, 268 | 32,33, 269 | 25,27,29,32,33, 270 | 25,27,31, 271 | 23,24,31, 272 | 29,33, 273 | 2,23,24,33, 274 | 2,31,33, 275 | 23,26,32,33, 276 | 1,8,32,33, 277 | 0,24,25,28,32,33, 278 | 2,8,14,15,18,20,22,23,29,30,31,33, 279 | 8,9,13,14,15,18,19,20,22,23,26,27,28,29,30,31,32}; 280 | 281 | double values[156]; 282 | for (size_t ix = 0; ix < NUM_EDGES; ++ix) 283 | { 284 | values[ix] = 1.0; 285 | } 286 | #endif 287 | 288 | GrB_Matrix graph; 289 | GrB_Vector ranks; 290 | 291 | // Initialize a GraphBLAS context 292 | GrB_init(GrB_BLOCKING); 293 | 294 | GrB_Matrix_new(&graph, GrB_FP64, NUM_NODES, NUM_NODES); 295 | GrB_Vector_new(&ranks, GrB_FP64, NUM_NODES); 296 | GrB_Matrix_build(graph, row_indices, col_indices, (double*)values, NUM_EDGES, 297 | GrB_LOR); 298 | 299 | pretty_print_matrix_FP64(graph, "GRAPH"); 300 | page_rank(graph, ranks, 0.85, 1.e-5, 100); 301 | 302 | pretty_print_vector_FP64(ranks, "Page Rank"); 303 | 304 | // Cleanup 305 | GrB_free(&ranks); 306 | GrB_free(&graph); 307 | GrB_finalize(); 308 | 309 | return GrB_SUCCESS; 310 | } 311 | -------------------------------------------------------------------------------- /src/Challenge_problems/triangle_count.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the GraphBLAS Tutorial materials, 3 | * Copyright (c) 2018 Carnegie Mellon University and Intel Corporation. 4 | * All Rights Reserved 5 | * 6 | * THIS SOFTWARE IS PROVIDED "AS IS," WITH NO WARRANTIES WHATSOEVER. CARNEGIE 7 | * MELLON UNIVERSITY AND INTEL CORPORATION EXPRESSLY DISCLAIMS TO THE FULLEST 8 | * EXTENT PERMITTED BY LAW ALL EXPRESS, IMPLIED, AND STATUTORY WARRANTIES, 9 | * INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS 10 | * FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF PROPRIETARY RIGHTS. 11 | * 12 | * Released under a BSD (SEI)-style license, please see LICENSE.txt for 13 | * full terms. 14 | * 15 | * DM18-xxx 16 | * 17 | * Authors: Scott McMillan, Timothy G. Mattson 18 | */ 19 | 20 | /** 21 | * @file triangle_count.c 22 | * 23 | * @brief A triangle counting implementation using GraphBLAS C API. 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include "tutorial_utils.h" 32 | 33 | //**************************************************************************** 34 | /* 35 | * Given, L, the lower triangular portion of n x n adjacency matrix A (of and 36 | * undirected graph), computes the number of triangles in the graph. 37 | */ 38 | uint64_t triangle_count(GrB_Matrix L) // L: NxN, lower-triangular, bool 39 | { 40 | GrB_Index n; 41 | GrB_Matrix_nrows(&n, L); // n = # of vertices 42 | 43 | GrB_Matrix C; 44 | GrB_Matrix_new(&C, GrB_UINT64, n, n); 45 | 46 | GrB_Monoid UInt64Plus; // integer plus monoid 47 | GrB_Monoid_new(&UInt64Plus,GrB_PLUS_UINT64,(uint64_t)0ul); 48 | 49 | GrB_Semiring UInt64Arithmetic; // integer arithmetic semiring 50 | GrB_Semiring_new(&UInt64Arithmetic,UInt64Plus,GrB_TIMES_UINT64); 51 | 52 | GrB_Descriptor desc_tb; // Descriptor for mxm 53 | GrB_Descriptor_new(&desc_tb); 54 | GrB_Descriptor_set(desc_tb,GrB_INP1,GrB_TRAN); // transpose the second matrix 55 | 56 | GrB_mxm(C, L, GrB_NULL, UInt64Arithmetic, L, L, desc_tb); // C = L *.+ L' 57 | 58 | uint64_t count; 59 | GrB_reduce(&count, GrB_NULL, UInt64Plus, C, GrB_NULL); // 1-norm of C 60 | 61 | GrB_free(&C); // C matrix no longer needed 62 | GrB_free(&UInt64Arithmetic); // Semiring no longer needed 63 | GrB_free(&UInt64Plus); // Monoid no longer needed 64 | GrB_free(&desc_tb); // descriptor no longer needed 65 | 66 | return count; 67 | } 68 | 69 | #if 0 70 | //**************************************************************************** 71 | // Logo graph 72 | int main(int argc, char **argv) 73 | { 74 | GrB_Index const NUM_NODES = 7; 75 | GrB_Index const NUM_EDGES = 12; 76 | GrB_Index row_indices[] = {0, 0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 6}; 77 | GrB_Index col_indices[] = {1, 3, 4, 6, 5, 0, 2, 5, 2, 2, 3, 4}; 78 | 79 | GrB_Matrix L; 80 | uint64_t num_triangles = 0; 81 | 82 | // Initialize a GraphBLAS context 83 | GrB_init(GrB_BLOCKING); 84 | 85 | GrB_Matrix_new(&L, GrB_BOOL, NUM_NODES, NUM_NODES); 86 | // turn the directed graph into an undirected graph and only set lower 87 | // triangular portion 88 | for (GrB_Index ix = 0; ix < NUM_EDGES; ++ix) 89 | { 90 | if (row_indices[ix] > col_indices[ix]) 91 | GrB_Matrix_setElement(L, true, row_indices[ix], col_indices[ix]); 92 | else 93 | GrB_Matrix_setElement(L, true, col_indices[ix], row_indices[ix]); 94 | } 95 | 96 | num_triangles = triangle_count(L); 97 | fprintf(stdout, "Number of triangles = %ld\n", (long int)num_triangles); 98 | 99 | return 0; 100 | } 101 | #endif 102 | 103 | //**************************************************************************** 104 | // Karate club graph 105 | int main(int argc, char **argv) 106 | { 107 | GrB_Index const NUM_NODES = 34; 108 | GrB_Index const NUM_EDGES = 156; 109 | GrB_Index row_indices[] = { 110 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 111 | 1,1,1,1,1,1,1,1,1, 112 | 2,2,2,2,2,2,2,2,2,2, 113 | 3,3,3,3,3,3, 114 | 4,4,4, 115 | 5,5,5,5, 116 | 6,6,6,6, 117 | 7,7,7,7, 118 | 8,8,8,8,8, 119 | 9,9, 120 | 10,10,10, 121 | 11, 122 | 12,12, 123 | 13,13,13,13,13, 124 | 14,14, 125 | 15,15, 126 | 16,16, 127 | 17,17, 128 | 18,18, 129 | 19,19,19, 130 | 20,20, 131 | 21,21, 132 | 22,22, 133 | 23,23,23,23,23, 134 | 24,24,24, 135 | 25,25,25, 136 | 26,26, 137 | 27,27,27,27, 138 | 28,28,28, 139 | 29,29,29,29, 140 | 30,30,30,30, 141 | 31,31,31,31,31,31, 142 | 32,32,32,32,32,32,32,32,32,32,32,32, 143 | 33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33}; 144 | 145 | GrB_Index col_indices[] = { 146 | 1,2,3,4,5,6,7,8,10,11,12,13,17,19,21,31, 147 | 0,2,3,7,13,17,19,21,30, 148 | 0,1,3,7,8,9,13,27,28,32, 149 | 0,1,2,7,12,13, 150 | 0,6,10, 151 | 0,6,10,16, 152 | 0,4,5,16, 153 | 0,1,2,3, 154 | 0,2,30,32,33, 155 | 2,33, 156 | 0,4,5, 157 | 0, 158 | 0,3, 159 | 0,1,2,3,33, 160 | 32,33, 161 | 32,33, 162 | 5,6, 163 | 0,1, 164 | 32,33, 165 | 0,1,33, 166 | 32,33, 167 | 0,1, 168 | 32,33, 169 | 25,27,29,32,33, 170 | 25,27,31, 171 | 23,24,31, 172 | 29,33, 173 | 2,23,24,33, 174 | 2,31,33, 175 | 23,26,32,33, 176 | 1,8,32,33, 177 | 0,24,25,28,32,33, 178 | 2,8,14,15,18,20,22,23,29,30,31,33, 179 | 8,9,13,14,15,18,19,20,22,23,26,27,28,29,30,31,32}; 180 | 181 | GrB_Matrix L; 182 | uint64_t num_triangles = 0; 183 | 184 | // Initialize a GraphBLAS context 185 | GrB_init(GrB_BLOCKING); 186 | 187 | GrB_Matrix_new(&L, GrB_BOOL, NUM_NODES, NUM_NODES); 188 | // turn a directed graph into an undirected graph and only set lower 189 | // triangular portion 190 | for (GrB_Index ix = 0; ix < NUM_EDGES; ++ix) 191 | { 192 | if (row_indices[ix] > col_indices[ix]) 193 | GrB_Matrix_setElement(L, true, row_indices[ix], col_indices[ix]); 194 | else 195 | GrB_Matrix_setElement(L, true, col_indices[ix], row_indices[ix]); 196 | } 197 | 198 | num_triangles = triangle_count(L); 199 | fprintf(stdout, "Number of triangles = %ld\n", (long int)num_triangles); 200 | 201 | return 0; 202 | } 203 | -------------------------------------------------------------------------------- /src/Data/CreateCoauthorGraph.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 4, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import csv\n", 10 | "import re\n", 11 | "import os, sys" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 5, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "# Author Fields: 0-based index, Normalized name, List of raw variants of the name\n", 21 | "author_pathname = \"author_normalization_table_reversed_indexed.tsv\"\n", 22 | "\n", 23 | "# Document Fields: 0-based index, Title, auth1/aff1|auth2/aff2|... year txt_pathname url\n", 24 | "document_pathname = \"all_hpec_records_cleaned_normalized_authors_indexed.tsv\"\n", 25 | "\n", 26 | "# Coauthor Graph fields: author1-index, author2-index, document-index1[|document-index2]*\n", 27 | "coauthor_graph_pathname = \"hpec_coauthors.tsv\"\n", 28 | "\n", 29 | "# Coauthor Graph in Matrix market formate where edge value is number of document-indices\"\n", 30 | "coauthor_graph_mtx_pathname = \"hpec_coauthors.mtx\"" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 7, 36 | "metadata": { 37 | "scrolled": true 38 | }, 39 | "outputs": [ 40 | { 41 | "name": "stdout", 42 | "output_type": "stream", 43 | "text": [ 44 | "Number of author entries: 1747\n", 45 | "Number of coauthor edges: 10072\n" 46 | ] 47 | } 48 | ], 49 | "source": [ 50 | "# Create the lookup table\n", 51 | "author_lookup = {} # key = full name, value = author_index\n", 52 | "\n", 53 | "# Read in the author index table\n", 54 | "with open(author_pathname, 'r') as infile:\n", 55 | " reader = csv.reader(infile, delimiter='\\t')\n", 56 | " line_number = 0\n", 57 | " for row in reader:\n", 58 | " line_number = line_number + 1\n", 59 | " if (len(row) != 3):\n", 60 | " print(\"ERROR: wrong number of fields in line \",line_number,\", record=\",row)\n", 61 | " continue\n", 62 | " \n", 63 | " (author_index, full_name, name_variants) = row\n", 64 | "\n", 65 | " if (full_name in author_lookup):\n", 66 | " print(\"ERROR: duplicate key (full name) in line \",line_number,\", name =\",full_name)\n", 67 | " else:\n", 68 | " author_lookup[full_name] = int(author_index)\n", 69 | "\n", 70 | "num_nodes = len(author_lookup.keys())\n", 71 | "print(\"Number of author entries: \", len(author_lookup.keys()))\n", 72 | "\n", 73 | "edge_list = {} # key = (auth1_index, auth2_index), value = (list of document indices)\n", 74 | "\n", 75 | "with open(document_pathname, 'r') as infile:\n", 76 | " line_number = 0\n", 77 | " reader = csv.reader(infile, delimiter='\\t')\n", 78 | " #outfile = open(output_pathname, 'w')\n", 79 | " #writer = csv.writer(outfile, delimiter='\\t')\n", 80 | " for row in reader:\n", 81 | " line_number = line_number + 1\n", 82 | " if (len(row) != 6):\n", 83 | " print(\"ERROR: bad record length in line \",line_number)\n", 84 | " else:\n", 85 | " (document_index, title, authors, pub_year, txt_filepath, url) = row\n", 86 | " doc_index = int(document_index)\n", 87 | " \n", 88 | " author_index_list = []\n", 89 | " alist = authors.split(\"|\")\n", 90 | " for author in alist:\n", 91 | " (full_name,affiliation) = author.split(\"/\")\n", 92 | " if (full_name not in author_lookup):\n", 93 | " print(\"ERROR: '\",full_name,\"' not found in lookup table, line = \",line_number)\n", 94 | " else:\n", 95 | " author_index_list.append(int(author_lookup[full_name]))\n", 96 | " #create bidirectional pairs of all possible author indices\n", 97 | " for idx1 in range(len(author_index_list)):\n", 98 | " for idx2 in range(len(author_index_list)):\n", 99 | " if (idx1 != idx2):\n", 100 | " auth_idx1 = author_index_list[idx1]\n", 101 | " auth_idx2 = author_index_list[idx2]\n", 102 | " if (auth_idx1 == auth_idx2):\n", 103 | " print(\"WARNING: skipping duplicate author entries, line = \", line_number,\n", 104 | " \", author index = \", auth_idx1)\n", 105 | " else:\n", 106 | " if ((auth_idx1,auth_idx2) in edge_list):\n", 107 | " edge_list[(auth_idx1, auth_idx2)].append(str(doc_index))\n", 108 | " else:\n", 109 | " edge_list[(auth_idx1, auth_idx2)] = [str(doc_index)]\n", 110 | "\n", 111 | "num_edges = len(edge_list.keys()) \n", 112 | "print(\"Number of coauthor edges: \", len(edge_list.keys()))\n", 113 | "\n", 114 | "outfile = open(coauthor_graph_pathname, 'w')\n", 115 | "mtx_outfile = open(coauthor_graph_mtx_pathname, 'w')\n", 116 | "mtx_outfile.write(\"%%MatrixMarket matrix coordinate integer\\n\")\n", 117 | " \n", 118 | "writer = csv.writer(outfile, delimiter='\\t')\n", 119 | "mtx_writer = csv.writer(mtx_outfile, delimiter=' ')\n", 120 | "mtx_writer.writerow((num_nodes, num_nodes, num_edges))\n", 121 | "\n", 122 | "for (key,value) in sorted(edge_list.items()):\n", 123 | " #print(key, \":\", edge_list[key])\n", 124 | " writer.writerow((key[0], key[1], \"|\".join(edge_list[key])))\n", 125 | " mtx_writer.writerow((key[0], key[1], len(edge_list[key])))\n", 126 | "\n", 127 | "outfile.close()\n", 128 | "mtx_outfile.close()\n" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": null, 134 | "metadata": { 135 | "scrolled": false 136 | }, 137 | "outputs": [], 138 | "source": [] 139 | } 140 | ], 141 | "metadata": { 142 | "kernelspec": { 143 | "display_name": "Python 3", 144 | "language": "python", 145 | "name": "python3" 146 | }, 147 | "language_info": { 148 | "codemirror_mode": { 149 | "name": "ipython", 150 | "version": 3 151 | }, 152 | "file_extension": ".py", 153 | "mimetype": "text/x-python", 154 | "name": "python", 155 | "nbconvert_exporter": "python", 156 | "pygments_lexer": "ipython3", 157 | "version": "3.5.2" 158 | } 159 | }, 160 | "nbformat": 4, 161 | "nbformat_minor": 2 162 | } 163 | -------------------------------------------------------------------------------- /src/Data/ldbc-wcc-example.mtx: -------------------------------------------------------------------------------- 1 | %%MatrixMarket matrix coordinate integer symmetric 2 | 10 10 15 3 | 3 1 1 4 | 5 1 1 5 | 8 1 1 6 | 4 2 1 7 | 5 2 1 8 | 10 2 1 9 | 5 3 1 10 | 6 3 1 11 | 8 3 1 12 | 10 3 1 13 | 5 4 1 14 | 6 4 1 15 | 7 4 1 16 | 9 4 1 17 | 8 5 1 18 | -------------------------------------------------------------------------------- /src/Data/query_author_by_author_id.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import sys 5 | import csv 6 | 7 | if __name__ == "__main__": 8 | if len(sys.argv) != 2: 9 | print("Usage:", sys.argv[0], " ") 10 | exit(1) 11 | 12 | author_id = int(sys.argv[1]) 13 | author_name = "" 14 | 15 | # find the all possible names of the author 16 | author_table = "author_normalization_table_reversed_indexed.tsv" 17 | with open(author_table, 'r') as infile: 18 | author_reader = csv.reader(infile, delimiter="\t") 19 | for row in author_reader: 20 | if (author_id == int(row[0])): 21 | print(row[0] + '\t' + row[1]) 22 | exit(0) 23 | 24 | 25 | print("Error: Author ID %d not found" % author_id) 26 | -------------------------------------------------------------------------------- /src/Data/query_author_id_by_name.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import sys 5 | import csv 6 | 7 | if __name__ == "__main__": 8 | if len(sys.argv) != 2: 9 | print("Usage:", sys.argv[0], " ") 10 | exit(1) 11 | 12 | count = 0 13 | author_query = sys.argv[1].lower() 14 | author_name = "" 15 | 16 | # find the all possible names of the author 17 | author_table = "author_normalization_table_reversed_indexed.tsv" 18 | with open(author_table, 'r') as infile: 19 | author_reader = csv.reader(infile, delimiter="\t") 20 | for row in author_reader: 21 | if (author_query in row[1].lower()): 22 | print(row[0] + '\t' + row[1]) 23 | count += 1 24 | 25 | print("Found", count, "records.") 26 | -------------------------------------------------------------------------------- /src/Data/query_papers_by_author_id.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import sys 5 | import csv 6 | 7 | if __name__ == "__main__": 8 | if len(sys.argv) != 2: 9 | print("Usage:", sys.argv[0], " ") 10 | exit(1) 11 | 12 | author_id = int(sys.argv[1]) 13 | author_name = "" 14 | 15 | # find the name of the author 16 | author_table = "author_normalization_table_reversed_indexed.tsv" 17 | with open(author_table, 'r') as infile: 18 | author_reader = csv.reader(infile, delimiter="\t") 19 | for row in author_reader: 20 | if (int(row[0]) == author_id): 21 | author_name = row[1] 22 | print("Searching for papers by:", author_name) 23 | break 24 | 25 | if (author_name == ""): 26 | print("Error: Invalid author ID:", author_id) 27 | exit(2) 28 | 29 | count = 0 30 | paper_table = "all_hpec_records_cleaned_normalized_authors_indexed.tsv" 31 | with open(paper_table, 'r') as infile: 32 | paper_reader = csv.reader(infile, delimiter="\t") 33 | for row in paper_reader: 34 | author_list = row[2].split("|") 35 | for author_affiliation in author_list: 36 | author, affiliation = author_affiliation.split("/") 37 | if (author == author_name): 38 | print("Paper ID:", row[0]) 39 | print("Year:", row[3]) 40 | print("Title: \"" + row[1] + "\"") 41 | print("Authors:\n" + "\n".join(row[2].split('|'))) 42 | 43 | print(" ") 44 | count += 1 45 | break 46 | 47 | print("Found", count, "papers.") 48 | -------------------------------------------------------------------------------- /src/Data/tree-example.mtx: -------------------------------------------------------------------------------- 1 | %%MatrixMarket matrix coordinate integer symmetric 2 | 6 6 5 3 | 3 1 1 4 | 4 2 1 5 | 5 3 1 6 | 5 4 1 7 | 6 4 1 8 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of the GraphBLAS tutorial materials, 3 | # Copyright (c) 2018 Carnegie Mellon University and Intel Corporation. 4 | # 5 | # THIS SOFTWARE IS PROVIDED "AS IS," WITH NO WARRANTIES WHATSOEVER. CARNEGIE 6 | # MELLON UNIVERSITY AND INTEL CORPORATION EXPRESSLY DISCLAIMS TO THE FULLEST 7 | # EXTENT PERMITTED BY LAW ALL EXPRESS, IMPLIED, AND STATUTORY WARRANTIES, 8 | # INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS 9 | # FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF PROPRIETARY RIGHTS. 10 | # 11 | # Released under a BSD (SEI)-style license, please see LICENSE.txt for 12 | # full terms. 13 | # 14 | # Authors: Scott McMillan, Timothy G. Mattson 15 | # 16 | 17 | PROJECT_ROOT = ${CURDIR}/.. 18 | 19 | INCDIR = $(PROJECT_ROOT)/include 20 | LIBDIR = $(PROJECT_ROOT)/lib 21 | 22 | include make.def 23 | 24 | SOURCES = BuildGraph.c AnalyzeGraph.c 25 | 26 | OBJECTS = $(SOURCES:.c=.o) 27 | TARGETS = $(SOURCES:.c=.exe) 28 | DSYM = $(SOURCES:.c=.exe.dSYM) 29 | HEADERS = $(wildcard $(INCDIR)/*.h) 30 | PCHS = $(HEADERS:=.gch) 31 | 32 | .PHONY : all clean 33 | 34 | all : $(TARGETS) 35 | 36 | %.s : %.c $(HEADERS) 37 | $(CC) -S $(CCFLAGS) $< 38 | 39 | %.o : %.c $(HEADERS) 40 | $(CC) -c $(CCFLAGS) $< 41 | 42 | %.exe : %.o 43 | $(CC) $^ -o $@ $(LIB) 44 | 45 | clean : 46 | /bin/rm -rf a.out $(TARGETS) $(OBJECTS) $(PCHS) $(DSYM) *~ 47 | 48 | 49 | squeaky : clean 50 | /bin/rm -f $(SOURCES:%.c=%.d) 51 | 52 | 53 | .SECONDARY : $(OBJECTS) 54 | 55 | -include $(SOURCES:%.c=%.d) 56 | -------------------------------------------------------------------------------- /src/Solutions/AnalyzeGraph_final.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 xxx. 3 | 4 | All Rights Reserved. 5 | 6 | NO WARRANTY. THIS MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. THE LAGRAPH 7 | CONTRIBUTORS MAKE NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, 8 | AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR 9 | PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF 10 | THE MATERIAL. THE CONTRIBUTORS DO NOT MAKE ANY WARRANTY OF ANY KIND WITH 11 | RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT. 12 | 13 | Released under a BSD license, please see the LICENSE file distributed with 14 | this Software or contact permission@sei.cmu.edu for full terms. 15 | 16 | Created, in part, with funding and support from the United States 17 | Government. (see Acknowledgments.txt file). 18 | 19 | This program includes and/or can make use of certain third party source 20 | code, object code, documentation and other files ("Third Party Software"). 21 | See LICENSE file for more details. 22 | 23 | */ 24 | 25 | //------------------------------------------------------------------------------ 26 | 27 | // Contributed by Scott McMillan/CMU, Tim Mattson/Intel 28 | 29 | // Run the following from the src directory: 30 | // 31 | // ./AnalyzeGraph.exe Data/hpec_coauthors.mtx 32 | 33 | #include 34 | #include 35 | #include "GraphBLAS.h" 36 | #include "LAGraph.h" 37 | #include "tutorial_utils.h" 38 | 39 | // From LACC_GraphBLAS.c in LAGraph 40 | GrB_Info CountCC(GrB_Vector parents, GrB_Index* countcc); 41 | 42 | //------------------------------------------------------------------------------ 43 | // Find all elements containing a given value (G_target_id) 44 | GrB_Index G_target_id = 0; 45 | 46 | void eq_target(void *z, const void *x) 47 | { 48 | (*(bool*)z) = (bool)((*(GrB_Index*)x) == G_target_id); 49 | } 50 | 51 | //------------------------------------------------------------------------------ 52 | // BFS visited: (from matvecTransIterVisitedExitFlag.c) 53 | //------------------------------------------------------------------------------ 54 | GrB_Info BFS(GrB_Matrix const A, // weighted adjacency matrix (positive) 55 | GrB_Index src_node, // root node for BFS 56 | GrB_Vector v) // vector of BOOL 57 | { 58 | GrB_Index num_nodes; 59 | GrB_Matrix_nrows(&num_nodes, A); 60 | GrB_Vector w; 61 | GrB_Vector_new(&w, GrB_BOOL, num_nodes); // wavefront 62 | GrB_Vector_setElement(w, true, src_node); 63 | 64 | GrB_Descriptor desc; // Descriptor for vxm: replace+scmp+trans 65 | GrB_Descriptor_new(&desc); 66 | GrB_Descriptor_set(desc, GrB_INP0, GrB_TRAN); 67 | GrB_Descriptor_set(desc, GrB_MASK, GrB_SCMP); 68 | GrB_Descriptor_set(desc, GrB_OUTP, GrB_REPLACE); 69 | 70 | // traverse to neighbors of a frontier iteratively starting with src_node 71 | GrB_Index nvals = 0; 72 | 73 | do 74 | { 75 | //GrB_eWiseAdd(v, GrB_NULL, GrB_NULL, GrB_LOR, v, w, GrB_NULL); 76 | GrB_assign(v, w, GrB_NULL, true, GrB_ALL, num_nodes, GrB_NULL); 77 | GrB_mxv(w, v, GrB_NULL, GxB_LOR_LAND_BOOL, A, w, desc); 78 | GrB_Vector_nvals(&nvals, w); 79 | } while (nvals > 0); 80 | 81 | GrB_free(&w); 82 | GrB_free(&desc); 83 | return GrB_SUCCESS; 84 | } 85 | 86 | //------------------------------------------------------------------------------ 87 | // connected_components: 88 | //------------------------------------------------------------------------------ 89 | GrB_Info ConnectedComponents(GrB_Matrix const A, 90 | GrB_Vector *components, 91 | GrB_Index *num_components) 92 | { 93 | GrB_Index n; 94 | GrB_Matrix_nrows(&n, A); 95 | GrB_Vector_new(components, GrB_UINT64, n); 96 | 97 | GrB_Vector v; 98 | GrB_Vector_new(&v, GrB_BOOL, n); // visited list 99 | 100 | *num_components = 0; 101 | GrB_Index max_component_num = 0; 102 | GrB_Index max_component_size = 0; 103 | 104 | for (GrB_Index src_node = 0; src_node < n; ++src_node) 105 | { 106 | GrB_Index c_num; 107 | if (GrB_NO_VALUE == GrB_Vector_extractElement(&c_num, *components, src_node)) 108 | { 109 | // Traverse as far as you can go from src_node marking all visited nodes 110 | BFS(A, src_node, v); 111 | 112 | // Merge visited list into components (give component source node name) 113 | // components[v] = src_node 114 | GrB_assign(*components, v, GrB_NULL, src_node, GrB_ALL, n, GrB_NULL); 115 | ++(*num_components); 116 | 117 | // Just for curiousity...not needed... 118 | GrB_Index component_size; 119 | GrB_Vector_nvals(&component_size, v); 120 | //printf("Component %ld: num nodes = %ld\n", src_node, component_size); 121 | if (component_size > max_component_size) 122 | { 123 | max_component_size = component_size; 124 | max_component_num = src_node; 125 | } 126 | 127 | GrB_Vector_clear(v); 128 | } 129 | } 130 | 131 | printf("Largest component #%ld (size = %ld)\n", max_component_num, max_component_size); 132 | GrB_free(&v); 133 | return GrB_SUCCESS; 134 | } 135 | 136 | //------------------------------------------------------------------------------ 137 | // main: 138 | //------------------------------------------------------------------------------ 139 | int main (int argc, char **argv) 140 | { 141 | if (argc < 2) 142 | { 143 | fprintf(stderr, "Error\nUsage: %s \n", argv[0]); 144 | return 1; 145 | } 146 | 147 | // Call LAGraph_init() instead of GrB_init(GrB_BLOCKING) 148 | LAGraph_init(); 149 | 150 | double tic[2], t; 151 | 152 | //------------------------------------------------------------------ 153 | printf("*** Step 1: loading input graph: %s\n", argv[1]); 154 | GrB_Matrix A = NULL; 155 | FILE *fd = fopen(argv[1], "r"); 156 | 157 | LAGraph_tic (tic); 158 | if (GrB_SUCCESS != LAGraph_mmread(&A, fd)) 159 | { 160 | fprintf(stderr, "ERROR: Failed to load graph: %s\n", argv[1]); 161 | exit(-1); 162 | } 163 | t = LAGraph_toc(tic); 164 | if (fd != NULL) fclose(fd); 165 | printf("*** Step 1: Elapsed time: %g sec\n", t); 166 | 167 | //------------------------------------------------------------------ 168 | printf("*** Step 2: compute some basic statistics\n"); 169 | GrB_Index num_rows, num_cols, num_vals; 170 | GrB_Matrix_nrows(&num_rows, A); 171 | GrB_Matrix_ncols(&num_cols, A); 172 | GrB_Matrix_nvals(&num_vals, A); 173 | assert(num_rows == num_cols); 174 | 175 | // Compute node with the maximum some of outgoing edge weights 176 | // (author w/ most coauthor/paper combos) via row reduction of the 177 | // weighted adjacency matrix 178 | GrB_Vector degree; 179 | GrB_Vector_new(°ree, GrB_UINT64, num_rows); 180 | LAGraph_tic (tic); 181 | GrB_reduce(degree, GrB_NULL, GrB_NULL, GrB_PLUS_UINT64, A, GrB_NULL); 182 | 183 | uint64_t max_degree = 0; 184 | GrB_reduce(&max_degree, GrB_NULL, GxB_MAX_UINT64_MONOID, degree, GrB_NULL); 185 | 186 | uint64_t min_degree = UINT64_MAX; 187 | GrB_reduce(&min_degree, GrB_NULL, GxB_MIN_UINT64_MONOID, degree, GrB_NULL); 188 | 189 | t = LAGraph_toc(tic); 190 | printf("*** Step 2: Elapsed time: %g sec\n", t); 191 | printf("Num nodes: %ld\n", num_rows); 192 | printf("Num edges: %ld\n", num_vals); 193 | printf("Avg degree: %lf\n", ((double)num_vals)/((double)num_rows)); 194 | printf("Max degree: %ld\n", max_degree); 195 | printf("Min degree: %ld\n", min_degree); 196 | 197 | GrB_Index target_index = 0; 198 | for (GrB_Index ix = 0; ix < num_rows; ++ix) 199 | { 200 | GrB_Index val = 0; 201 | if (GrB_NO_VALUE != GrB_Vector_extractElement(&val, degree, ix)) 202 | { 203 | if (val == max_degree) 204 | { 205 | // This is the author with the most coauthor/paper combos at HPEC 206 | target_index = ix; 207 | printf("Node with max degree (target ID): %ld\n", target_index); 208 | } 209 | } 210 | } 211 | 212 | //============================================================ 213 | //============================================================ 214 | // Replace this step with code produced in the tutorial 215 | //============================================================ 216 | //============================================================ 217 | printf("*** Step 3: Running Tutorial connected components algorithm.\n"); 218 | GrB_Vector components = NULL; 219 | GrB_Index num_components = 0; 220 | 221 | LAGraph_tic (tic); 222 | ConnectedComponents(A, &components, &num_components); 223 | t = LAGraph_toc(tic) ; 224 | printf ("*** Step 3: Elapsed time: %g sec\n", t); 225 | 226 | printf("Number of connected components: %ld\n", num_components); 227 | 228 | //pretty_print_vector_UINT64(components, "Connected components"); 229 | 230 | GrB_Index cluster_num = 666; 231 | GrB_Vector_extractElement(&cluster_num, components, target_index); 232 | printf("ID for component containing target ID %ld: %ld\n", 233 | target_index, cluster_num); 234 | 235 | //=========================================================== 236 | printf("*** Step 4: Find all the nodes from the target ID's cluster.\n"); 237 | LAGraph_tic(tic); 238 | G_target_id = cluster_num; 239 | GrB_UnaryOp target_eq = NULL; 240 | GrB_UnaryOp_new(&target_eq, &eq_target, GrB_BOOL, GrB_UINT64); 241 | 242 | GrB_Vector cluster_mask; 243 | GrB_Vector_new(&cluster_mask, GrB_BOOL, num_rows); 244 | 245 | // Find all elements belonging to cluster labeled cluster_num 246 | GrB_apply(cluster_mask, GrB_NULL, GrB_NULL, 247 | target_eq, components, GrB_NULL); 248 | 249 | GrB_Index nc; 250 | GrB_Vector_nvals(&nc, cluster_mask); 251 | 252 | // remove all elements that have 'stored false' 253 | GrB_Descriptor desc; 254 | GrB_Descriptor_new(&desc); 255 | GrB_Descriptor_set(desc, GrB_OUTP, GrB_REPLACE); 256 | 257 | GrB_apply(cluster_mask, cluster_mask, GrB_NULL, 258 | GrB_IDENTITY_BOOL, cluster_mask, desc); 259 | 260 | GrB_Vector_nvals(&nc, cluster_mask); 261 | 262 | // get number of elements in the mask and extract the indices 263 | GrB_Index component_size; 264 | GrB_Vector_nvals(&component_size, cluster_mask); 265 | GrB_Index *cluster_indices = malloc(component_size*sizeof(GrB_Index)); 266 | bool *vals = malloc(component_size*sizeof(bool)); 267 | 268 | GrB_Vector_extractTuples(cluster_indices, vals, 269 | &component_size, cluster_mask); 270 | t = LAGraph_toc(tic); 271 | printf("*** Step 4: Elapsed time: %g sec\n", t); 272 | 273 | printf("Cluster mask nvals (after masking): %ld\n", nc); 274 | printf("Component size: %ld\n", component_size); 275 | 276 | //=========================================================== 277 | printf("*** Step 5: extract and perform PageRank on the target component.\n"); 278 | LAGraph_tic (tic); 279 | GrB_Matrix A_comp; 280 | GrB_Matrix_new(&A_comp, GrB_UINT64, component_size, component_size); 281 | GrB_extract(A_comp, GrB_NULL, GrB_NULL, A, 282 | cluster_indices, component_size, 283 | cluster_indices, component_size, 284 | GrB_NULL); 285 | 286 | GrB_Vector pr; 287 | double max_rank = 0.0, min_rank = 9999999999.9; 288 | GrB_Index max_rank_id, min_rank_id; 289 | LAGraph_pagerank2(&pr, A_comp, 0.85, 100); 290 | t = LAGraph_toc(tic); 291 | printf("*** Step 5: Elapsed time: %g sec\n", t); 292 | 293 | //printf("ID:\tRank\n"); 294 | for (GrB_Index ix = 0; ix < component_size; ++ix) 295 | { 296 | double rank=-1.; 297 | GrB_Vector_extractElement(&rank, pr, ix); 298 | //printf("%ld\t%lf\n", cluster_indices[ix], rank); 299 | if (rank > max_rank) 300 | { 301 | max_rank = rank; 302 | max_rank_id = cluster_indices[ix]; 303 | } 304 | if (rank < min_rank) 305 | { 306 | min_rank = rank; 307 | min_rank_id = cluster_indices[ix]; 308 | } 309 | } 310 | 311 | printf("Author with the highest rank: %ld (%lf)\n", max_rank_id, max_rank); 312 | printf("Author with the smallest rank: %ld (%lf)\n", min_rank_id, min_rank); 313 | 314 | GrB_Index count = 0; 315 | double threshold = 0.25*max_rank; 316 | printf("Authors with rank > %lf:\n", threshold); 317 | printf("ID:\tRank\n"); 318 | for (GrB_Index ix = 0; ix < component_size; ++ix) 319 | { 320 | double rank=-1.; 321 | GrB_Vector_extractElement(&rank, pr, ix); 322 | if (rank > threshold) 323 | { 324 | printf("%ld\t%lf\n", cluster_indices[ix], rank); 325 | ++count; 326 | } 327 | } 328 | 329 | printf("Num authors with rank > %lf: %ld\n", threshold, count); 330 | 331 | //=========================================================== 332 | GrB_free(&A_comp); 333 | GrB_free(&desc); 334 | GrB_free(&cluster_mask); 335 | GrB_free(&target_eq); 336 | GrB_free(°ree); 337 | GrB_free(&components); 338 | GrB_free(&A); 339 | 340 | free(cluster_indices); 341 | free(vals); 342 | 343 | // Call instead of GrB_finalize(); 344 | LAGraph_finalize(); 345 | return (GrB_SUCCESS) ; 346 | } 347 | -------------------------------------------------------------------------------- /src/Solutions/BuildAdjMatIndVec.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the GraphBLAS Tutorial materials, 3 | * Copyright (c) 2018 Carnegie Mellon University and Intel Corporation. 4 | * All Rights Reserved 5 | * 6 | * THIS SOFTWARE IS PROVIDED "AS IS," WITH NO WARRANTIES WHATSOEVER. CARNEGIE 7 | * MELLON UNIVERSITY AND INTEL CORPORATION EXPRESSLY DISCLAIMS TO THE FULLEST 8 | * EXTENT PERMITTED BY LAW ALL EXPRESS, IMPLIED, AND STATUTORY WARRANTIES, 9 | * INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS 10 | * FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF PROPRIETARY RIGHTS. 11 | * 12 | * Released under a BSD (SEI)-style license, please see LICENSE.txt for 13 | * full terms. 14 | * 15 | * DM18-xxx 16 | * 17 | * Authors: Scott McMillan, Timothy G. Mattson 18 | */ 19 | 20 | /** 21 | * @file BuildAdjMatIndVec.c 22 | * 23 | * @brief Build a GraphBLAS adjacency matrix for the logo graph and 24 | * make sure it is correct. 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include "tutorial_utils.h" 31 | 32 | //**************************************************************************** 33 | int main(int argc, char** argv) 34 | { 35 | GrB_Index const NUM_NODES = 7; 36 | GrB_Index const NUM_EDGES = 12; 37 | 38 | // numbering nodes starts at node "0" 39 | GrB_Index row_indices[] = {0, 0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 6}; 40 | GrB_Index col_indices[] = {1, 3, 4, 6, 5, 0, 2, 5, 2, 2, 3, 4}; 41 | bool values[] = {true, true, true, true, true, true, 42 | true, true, true, true, true, true}; 43 | GrB_Matrix graph; 44 | 45 | // Initialize GraphBLAS context 46 | GrB_init(GrB_BLOCKING); 47 | 48 | GrB_Matrix_new(&graph, GrB_BOOL, NUM_NODES, NUM_NODES); 49 | 50 | // GrB_LOR is a binary op to resolve duplications ambiguities 51 | GrB_Matrix_build(graph, row_indices, col_indices, (bool*)values, NUM_EDGES, 52 | GrB_LOR); 53 | 54 | // Provided in hpec_utils.h 55 | pretty_print_matrix_UINT64(graph, "GRAPH"); 56 | 57 | // Check results 58 | bool error_found = false; 59 | 60 | GrB_Index nvals; 61 | GrB_Matrix_nvals(&nvals, graph); 62 | printf("Number of edges: %ld\n", (long)nvals); 63 | 64 | if (nvals != NUM_EDGES) 65 | { 66 | fprintf(stderr, "ERROR: wrong number of edges (!= %ld): %ld\n", 67 | (long)NUM_EDGES, (long)nvals); 68 | error_found = true; 69 | } 70 | for (size_t idx = 0; idx < NUM_EDGES; ++idx) 71 | { 72 | bool val; 73 | 74 | if (GrB_Matrix_extractElement(&val, graph, 75 | row_indices[idx], col_indices[idx])) 76 | { 77 | fprintf(stderr, "ERROR: missing element at: (%ld, %ld)\n", 78 | (long)row_indices[idx], (long)col_indices[idx]); 79 | error_found = true; 80 | } 81 | else 82 | { 83 | if (val != values[idx]) 84 | { 85 | fprintf(stderr, "ERROR: wrong value stored at: (%ld, %ld)\n", 86 | (long)row_indices[idx], (long)col_indices[idx]); 87 | error_found = true; 88 | } 89 | } 90 | } 91 | 92 | if (!error_found) 93 | { 94 | fprintf(stderr, "All tests passed.\n"); 95 | } 96 | 97 | // Cleanup 98 | GrB_free(&graph); 99 | GrB_finalize(); 100 | } 101 | -------------------------------------------------------------------------------- /src/Solutions/BuildAdjMatTuple.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the GraphBLAS Tutorial materials, 3 | * Copyright (c) 2018 Carnegie Mellon University and Intel Corporation. 4 | * All Rights Reserved 5 | * 6 | * THIS SOFTWARE IS PROVIDED "AS IS," WITH NO WARRANTIES WHATSOEVER. CARNEGIE 7 | * MELLON UNIVERSITY AND INTEL CORPORATION EXPRESSLY DISCLAIMS TO THE FULLEST 8 | * EXTENT PERMITTED BY LAW ALL EXPRESS, IMPLIED, AND STATUTORY WARRANTIES, 9 | * INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS 10 | * FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF PROPRIETARY RIGHTS. 11 | * 12 | * Released under a BSD (SEI)-style license, please see LICENSE.txt for 13 | * full terms. 14 | * 15 | * DM18-xxx 16 | * 17 | * Authors: Scott McMillan, Timothy G. Mattson 18 | */ 19 | 20 | /** 21 | * @file BuildAdjMatTuple.c 22 | * 23 | * @brief Build an adjacency matrix tuple by tuple 24 | * 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include "tutorial_utils.h" 31 | 32 | //**************************************************************************** 33 | int main(int argc, char** argv) 34 | { 35 | GrB_Index const NUM_NODES = 3; 36 | GrB_Matrix graph; 37 | 38 | // initialize GraphBLAS context 39 | GrB_init(GrB_BLOCKING); 40 | 41 | GrB_Matrix_new(&graph, GrB_UINT64, NUM_NODES, NUM_NODES); 42 | 43 | GrB_Matrix_setElement(graph, 4, 1, 2); 44 | GrB_Matrix_setElement(graph, 4, 2, 1); 45 | GrB_Matrix_setElement(graph, 2, 0, 1); 46 | GrB_Matrix_setElement(graph, 2, 1, 0); 47 | 48 | pretty_print_matrix_UINT64(graph, "GRAPH"); 49 | 50 | GrB_Index nvals; 51 | GrB_Matrix_nvals(&nvals, graph); 52 | assert(nvals == 4); // verify that we see the number of edges I set 53 | 54 | // Cleanup 55 | GrB_free(&graph); 56 | GrB_finalize(); 57 | } 58 | -------------------------------------------------------------------------------- /src/Solutions/HPEC19_index.txt: -------------------------------------------------------------------------------- 1 | Ex# Filename 2 | 1 ../BuildGraph.c GrB_init()/GrB_finalize(), GrB_Matrix_new()/GrB_free() 3 | 1 ../AnalyzeGraph.c LAGraph 4 | 2 BuildAdjMatTuple.c GrB_Matrix_setElement() 5 | 3 BuildAdjMatIndVec.c GrB_Matrix_build() 6 | 4 matvec.c GrB_mxv() 7 | 5 matvecTrans.c GrB_Descriptor, transpose 8 | 6 GrB_Semiring 9 | 7 matvecTransIter.c Iterative mxv to visit neighbors (fixed iteration) 10 | 8 matvecTransIterVisited.c Build visited lists 11 | 9 matvecTransIterVisitedExitFlag.c Mask/scmp, frontier 12 | X connected_components.c iterative BFS 13 | 14 | -------------------------------------------------------------------------------- /src/Solutions/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of the GraphBLAS tutorial materials, 3 | # Copyright (c) 2018 Carnegie Mellon University and Intel Corporation. 4 | # 5 | # THIS SOFTWARE IS PROVIDED "AS IS," WITH NO WARRANTIES WHATSOEVER. CARNEGIE 6 | # MELLON UNIVERSITY AND INTEL CORPORATION EXPRESSLY DISCLAIMS TO THE FULLEST 7 | # EXTENT PERMITTED BY LAW ALL EXPRESS, IMPLIED, AND STATUTORY WARRANTIES, 8 | # INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS 9 | # FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF PROPRIETARY RIGHTS. 10 | # 11 | # Released under a BSD (SEI)-style license, please see LICENSE.txt for 12 | # full terms. 13 | # 14 | # Authors: Scott McMillan, Timothy G. Mattson 15 | # 16 | 17 | PROJECT_ROOT = ${CURDIR}/../.. 18 | 19 | INCDIR = $(PROJECT_ROOT)/include 20 | LIBDIR = $(PROJECT_ROOT)/lib 21 | 22 | include ../make.def 23 | 24 | SOURCES = BuildAdjMatTuple.c \ 25 | BuildAdjMatIndVec.c \ 26 | matvec.c \ 27 | matvecTrans.c \ 28 | matvecTransIter.c \ 29 | matvecTransIterVisited.c \ 30 | matvecTransIterVisitedExitFlag.c \ 31 | matvecTransIterLevels.c \ 32 | bfs_level.c \ 33 | connected_components.c \ 34 | AnalyzeGraph_final.c 35 | 36 | OBJECTS = $(SOURCES:.c=.o) 37 | TARGETS = $(SOURCES:.c=.exe) 38 | DSYM = $(SOURCES:.c=.exe.dSYM) 39 | HEADERS = $(wildcard $(INCDIR)/*.h) 40 | PCHS = $(HEADERS:=.gch) 41 | 42 | .PHONY : all clean 43 | 44 | all : $(TARGETS) 45 | 46 | %.s : %.c $(HEADERS) 47 | $(CC) -S $(CCFLAGS) $< 48 | 49 | %.o : %.c $(HEADERS) 50 | $(CC) -c $(CCFLAGS) $< 51 | 52 | %.exe : %.o 53 | $(CC) $^ -o $@ $(LIB) 54 | 55 | clean : 56 | /bin/rm -rf a.out $(TARGETS) $(OBJECTS) $(PCHS) $(DSYM) *~ 57 | 58 | 59 | squeaky : clean 60 | /bin/rm -f $(SOURCES:%.c=%.d) 61 | 62 | .SECONDARY : $(OBJECTS) 63 | 64 | -include $(SOURCES:%.c=%.d) 65 | -------------------------------------------------------------------------------- /src/Solutions/bfs_level.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the GraphBLAS Tutorial materials, 3 | * Copyright (c) 2018 Carnegie Mellon University and Intel Corporation. 4 | * All Rights Reserved 5 | * 6 | * THIS SOFTWARE IS PROVIDED "AS IS," WITH NO WARRANTIES WHATSOEVER. CARNEGIE 7 | * MELLON UNIVERSITY AND INTEL CORPORATION EXPRESSLY DISCLAIMS TO THE FULLEST 8 | * EXTENT PERMITTED BY LAW ALL EXPRESS, IMPLIED, AND STATUTORY WARRANTIES, 9 | * INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS 10 | * FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF PROPRIETARY RIGHTS. 11 | * 12 | * Released under a BSD (SEI)-style license, please see LICENSE.txt for 13 | * full terms. 14 | * 15 | * DM18-xxx 16 | * 17 | * Authors: Scott McMillan, Timothy G. Mattson 18 | */ 19 | 20 | /** 21 | * @file bfs_level.c 22 | * 23 | * @brief A level BFS implementation using GraphBLAS C API. 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include "tutorial_utils.h" 32 | 33 | /* 34 | * Given a boolean n x n adjacency matrix, A, and a source vertex, src, 35 | * performs a BFS traversal of the graph and sets levels[i] to the level in 36 | * which vertex i is visited (levels[src] == 1). If i is not reacheable from 37 | * s, then levels[i] = 0. (Vector v should be empty/uninitialized on input.) 38 | */ 39 | GrB_Info bfs_level(GrB_Vector *levels, GrB_Matrix A, GrB_Index src) 40 | { 41 | GrB_Index n; 42 | GrB_Matrix_nrows(&n, A); // n = # of rows of A 43 | 44 | GrB_Vector_new(levels, GrB_INT32, n); // Vector levels(n) 45 | 46 | GrB_Vector w; // wavefront vertices visited in each level 47 | GrB_Vector_new(&w, GrB_BOOL, n); // Vector w(n) 48 | GrB_Vector_setElement(w, (bool)true, src); // w[src] = true, false elsewhere 49 | 50 | GrB_Monoid Lor; // Logical-or monoid 51 | GrB_Monoid_new(&Lor, GrB_LOR, (bool)false); 52 | 53 | GrB_Semiring Boolean; // Boolean semiring 54 | GrB_Semiring_new(&Boolean, Lor, GrB_LAND); 55 | 56 | GrB_Descriptor desc; // Descriptor for vxm: replace+scmp 57 | GrB_Descriptor_new(&desc); 58 | GrB_Descriptor_set(desc, GrB_MASK, GrB_SCMP); 59 | GrB_Descriptor_set(desc, GrB_OUTP, GrB_REPLACE); 60 | 61 | /* 62 | * BFS traversal and label the vertices. 63 | */ 64 | int32_t level = 0; // level in BFS traversal 65 | GrB_Index nvals = 0; // nvals == 0 when no successor found 66 | do { 67 | ++level; // next level (start with 1) 68 | GrB_assign(*levels, w, GrB_NULL, 69 | level, GrB_ALL, n, GrB_NULL); // levels[w] = d 70 | GrB_vxm(w, *levels, GrB_NULL, Boolean, 71 | w, A, desc); // w[!levels] = w ||.&& A ; finds all the 72 | 73 | GrB_Vector_nvals(&nvals, w); 74 | } while (nvals); // if there is no successor in w, we are done. 75 | 76 | GrB_free(&w); // Cleanup 77 | GrB_free(&Lor); 78 | GrB_free(&Boolean); 79 | GrB_free(&desc); 80 | 81 | return GrB_SUCCESS; 82 | } 83 | 84 | //**************************************************************************** 85 | // Logo graph 86 | int main(int argc, char **argv) 87 | { 88 | GrB_Index const NUM_NODES = 7; 89 | GrB_Index const NUM_EDGES = 12; 90 | GrB_Index row_indices[] = {0, 0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 6}; 91 | GrB_Index col_indices[] = {1, 3, 4, 6, 5, 0, 2, 5, 2, 2, 3, 4}; 92 | bool values[] = {true, true, true, true, true, true, 93 | true, true, true, true, true, true}; 94 | GrB_Matrix graph; 95 | GrB_Vector levels; 96 | 97 | // Initialize a GraphBLAS context 98 | GrB_init(GrB_BLOCKING); 99 | 100 | GrB_Matrix_new(&graph, GrB_BOOL, NUM_NODES, NUM_NODES); 101 | GrB_Matrix_build(graph, row_indices, col_indices, (bool*)values, NUM_EDGES, 102 | GrB_LOR); 103 | 104 | pretty_print_matrix_UINT64(graph, "GRAPH"); 105 | 106 | GrB_Index const SRC_NODE = 1; 107 | bfs_level(&levels, graph, SRC_NODE); 108 | 109 | pretty_print_vector_UINT64(levels, "level vector (src == 1)"); 110 | 111 | // Cleanup 112 | GrB_free(&levels); 113 | GrB_free(&graph); 114 | GrB_finalize(); 115 | 116 | return GrB_SUCCESS; 117 | } 118 | -------------------------------------------------------------------------------- /src/Solutions/connected_components.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the GraphBLAS Tutorial materials, 3 | * Copyright (c) 2018 Carnegie Mellon University and Intel Corporation. 4 | * All Rights Reserved 5 | * 6 | * THIS SOFTWARE IS PROVIDED "AS IS," WITH NO WARRANTIES WHATSOEVER. CARNEGIE 7 | * MELLON UNIVERSITY AND INTEL CORPORATION EXPRESSLY DISCLAIMS TO THE FULLEST 8 | * EXTENT PERMITTED BY LAW ALL EXPRESS, IMPLIED, AND STATUTORY WARRANTIES, 9 | * INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS 10 | * FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF PROPRIETARY RIGHTS. 11 | * 12 | * Released under a BSD (SEI)-style license, please see LICENSE.txt for 13 | * full terms. 14 | * 15 | * DM18-xxx 16 | * 17 | * Authors: Scott McMillan, Timothy G. Mattson 18 | */ 19 | 20 | /** 21 | * @file matvecTransIterExitFlag_v2.c 22 | * 23 | * @brief Code to hop to neighbors of a set of vertices iteratively and exit 24 | * when the frontier becomes empty. 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include "tutorial_utils.h" 31 | 32 | //**************************************************************************** 33 | GrB_Info BFS(GrB_Matrix const graph, 34 | GrB_Index src_node, 35 | GrB_Vector v) 36 | { 37 | GrB_Index num_nodes; 38 | GrB_Matrix_nrows(&num_nodes, graph); 39 | GrB_Vector w; 40 | GrB_Vector_new(&w, GrB_BOOL, num_nodes); 41 | GrB_Vector_setElement(w, true, src_node); 42 | 43 | GrB_Descriptor desc; // Descriptor for vxm: replace+scmp+trans 44 | GrB_Descriptor_new(&desc); 45 | GrB_Descriptor_set(desc, GrB_INP0, GrB_TRAN); 46 | GrB_Descriptor_set(desc, GrB_MASK, GrB_SCMP); 47 | GrB_Descriptor_set(desc, GrB_OUTP, GrB_REPLACE); 48 | 49 | // traverse to neighbors of a frontier iteratively starting with src_node 50 | GrB_Index nvals = 0; 51 | 52 | do 53 | { 54 | //GrB_eWiseAdd(v, GrB_NULL, GrB_NULL, GrB_LOR, v, w, GrB_NULL); 55 | GrB_assign(v, w, GrB_NULL, true, GrB_ALL, num_nodes, GrB_NULL); 56 | GrB_mxv(w, v, GrB_NULL, GxB_LOR_LAND_BOOL, graph, w, desc); 57 | GrB_Vector_nvals(&nvals, w); 58 | } while (nvals > 0); 59 | 60 | GrB_free(&w); 61 | GrB_free(&desc); 62 | return GrB_SUCCESS; 63 | } 64 | 65 | //**************************************************************************** 66 | int main(int argc, char** argv) 67 | { 68 | GrB_init(GrB_BLOCKING); 69 | 70 | GrB_Index const NUM_NODES = 9; 71 | GrB_Index const NUM_EDGES = 18; 72 | GrB_Index row_indices[] = {0, 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 8}; 73 | GrB_Index col_indices[] = {1, 4, 8, 0, 8, 6, 5, 7, 0, 8, 3, 7, 2, 3, 5, 0, 1, 4}; 74 | uint64_t values[] = {1, 2, 1, 1, 3, 4, 1, 2, 2, 5, 1, 2, 4, 2, 2, 1, 3, 5}; 75 | GrB_Matrix graph; 76 | 77 | GrB_Matrix_new(&graph, GrB_UINT64, NUM_NODES, NUM_NODES); 78 | GrB_Matrix_build(graph, row_indices, col_indices, values, 79 | NUM_EDGES, GrB_PLUS_UINT64); 80 | 81 | pretty_print_matrix_UINT64(graph, "GRAPH"); 82 | 83 | // ------------------ connected components algorithm ------------------ 84 | GrB_Index tmp = 0, num_ccs = 0; 85 | GrB_Vector cc_ids, visited; 86 | GrB_Vector_new(&cc_ids, GrB_UINT64, NUM_NODES); 87 | GrB_Vector_new(&visited, GrB_BOOL, NUM_NODES); 88 | 89 | // Build a vector to select a source node and another 90 | // vector to hold the mxv result. 91 | for (GrB_Index src = 0; src < NUM_NODES; ++src) 92 | { 93 | if (GrB_NO_VALUE == 94 | GrB_Vector_extractElement(&tmp, cc_ids, src)) 95 | { 96 | printf ("Processing node %ld\n", src); 97 | // Traverse from src_node marking all visited nodes 98 | BFS(graph, src, visited); 99 | 100 | // Merge visited list into cc_ids (use source node as ID) 101 | // cc_ids[visited] = src 102 | GrB_assign(cc_ids, visited, GrB_NULL, 103 | src, GrB_ALL, NUM_NODES, GrB_NULL); 104 | ++num_ccs; 105 | } 106 | else 107 | printf ("Skipping node %ld\n", src); 108 | GrB_Vector_clear(visited); 109 | } 110 | 111 | printf("Number of connected components: %ld\n", (unsigned long)num_ccs); 112 | pretty_print_vector_UINT64(cc_ids, "CC IDs"); 113 | 114 | // Cleanup 115 | GrB_free(&graph); 116 | GrB_free(&visited); 117 | GrB_free(&cc_ids); 118 | GrB_finalize(); 119 | } 120 | -------------------------------------------------------------------------------- /src/Solutions/matvec.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the GraphBLAS Tutorial materials, 3 | * Copyright (c) 2018 Carnegie Mellon University and Intel Corporation. 4 | * All Rights Reserved 5 | * 6 | * THIS SOFTWARE IS PROVIDED "AS IS," WITH NO WARRANTIES WHATSOEVER. CARNEGIE 7 | * MELLON UNIVERSITY AND INTEL CORPORATION EXPRESSLY DISCLAIMS TO THE FULLEST 8 | * EXTENT PERMITTED BY LAW ALL EXPRESS, IMPLIED, AND STATUTORY WARRANTIES, 9 | * INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS 10 | * FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF PROPRIETARY RIGHTS. 11 | * 12 | * Released under a BSD (SEI)-style license, please see LICENSE.txt for 13 | * full terms. 14 | * 15 | * DM18-xxx 16 | * 17 | * Authors: Scott McMillan, Timothy G. Mattson 18 | */ 19 | 20 | /** 21 | * @file matvec.c 22 | * 23 | * @brief Code to find sources of a vertex; 24 | * 25 | */ 26 | 27 | #include 28 | #include 29 | #include "tutorial_utils.h" 30 | 31 | //**************************************************************************** 32 | int main(int argc, char** argv) 33 | { 34 | GrB_Index const NUM_NODES = 7; 35 | GrB_Index const NUM_EDGES = 12; 36 | GrB_Index row_indices[] = {0, 0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 6}; 37 | GrB_Index col_indices[] = {1, 3, 4, 6, 5, 0, 2, 5, 2, 2, 3, 4}; 38 | bool values[] = {true, true, true, true, true, true, 39 | true, true, true, true, true, true}; 40 | 41 | // Initialize a GraphBLAS context 42 | GrB_init(GrB_BLOCKING); 43 | 44 | GrB_Matrix graph; 45 | GrB_Matrix_new(&graph, GrB_BOOL, NUM_NODES, NUM_NODES); 46 | GrB_Matrix_build(graph, row_indices, col_indices, (bool*)values, NUM_EDGES, 47 | GrB_LOR); 48 | 49 | pretty_print_matrix_UINT64(graph, "GRAPH"); 50 | 51 | // Build a vector to select a single node in the graph (vec) 52 | // and a vector to hold the result of our operation (result) 53 | GrB_Index const NODE = 2; 54 | GrB_Vector vec, result; 55 | GrB_Vector_new(&vec, GrB_BOOL, NUM_NODES); 56 | GrB_Vector_new(&result, GrB_BOOL, NUM_NODES); 57 | GrB_Vector_setElement(vec, true, NODE); 58 | 59 | // find source vertices to NODE 60 | 61 | pretty_print_vector_UINT64(vec, "Target node"); 62 | GrB_mxv(result, GrB_NULL, GrB_NULL, 63 | GxB_LOR_LAND_BOOL, graph, vec, GrB_NULL); 64 | pretty_print_vector_UINT64(result, "sources"); 65 | 66 | // Check results 67 | { 68 | bool error_found = false; 69 | GrB_Index nvals; 70 | GrB_Vector_nvals(&nvals, result); 71 | if (nvals != 3) 72 | { 73 | fprintf(stderr, "ERROR: wrong number of sources (!= 2): %ld\n", 74 | (long)nvals); 75 | error_found = true; 76 | } 77 | 78 | bool val; 79 | 80 | if (GrB_Vector_extractElement(&val, result, 3UL)) 81 | { 82 | fprintf(stderr, "ERROR: missing source 3.\n"); 83 | error_found = true; 84 | } 85 | if (GrB_Vector_extractElement(&val, result, 5UL)) 86 | { 87 | fprintf(stderr, "ERROR: missing source 5.\n"); 88 | error_found = true; 89 | } 90 | if (GrB_Vector_extractElement(&val, result, 6UL)) 91 | { 92 | fprintf(stderr, "ERROR: missing source 6.\n"); 93 | error_found = true; 94 | } 95 | 96 | if (!error_found) 97 | { 98 | fprintf(stderr, "GrB_mxv test passed.\n"); 99 | } 100 | } 101 | 102 | // Cleanup 103 | GrB_free(&graph); 104 | GrB_free(&vec); 105 | GrB_free(&result); 106 | GrB_finalize(); 107 | } 108 | -------------------------------------------------------------------------------- /src/Solutions/matvecTrans.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the GraphBLAS Tutorial materials, 3 | * Copyright (c) 2018 Carnegie Mellon University and Intel Corporation. 4 | * All Rights Reserved 5 | * 6 | * THIS SOFTWARE IS PROVIDED "AS IS," WITH NO WARRANTIES WHATSOEVER. CARNEGIE 7 | * MELLON UNIVERSITY AND INTEL CORPORATION EXPRESSLY DISCLAIMS TO THE FULLEST 8 | * EXTENT PERMITTED BY LAW ALL EXPRESS, IMPLIED, AND STATUTORY WARRANTIES, 9 | * INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS 10 | * FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF PROPRIETARY RIGHTS. 11 | * 12 | * Released under a BSD (SEI)-style license, please see LICENSE.txt for 13 | * full terms. 14 | * 15 | * DM18-xxx 16 | * 17 | * Authors: Scott McMillan, Timothy G. Mattson 18 | */ 19 | 20 | /** 21 | * @file matvecTrans.c 22 | * 23 | * @brief Code to find neighbors of a vertex 24 | * 25 | */ 26 | 27 | #include 28 | #include 29 | #include "tutorial_utils.h" 30 | 31 | //**************************************************************************** 32 | int main(int argc, char** argv) 33 | { 34 | GrB_Index const NUM_NODES = 7; 35 | GrB_Index const NUM_EDGES = 12; 36 | GrB_Index row_indices[] = {0, 0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 6}; 37 | GrB_Index col_indices[] = {1, 3, 4, 6, 5, 0, 2, 5, 2, 2, 3, 4}; 38 | bool values[] = {true, true, true, true, true, true, 39 | true, true, true, true, true, true}; 40 | 41 | // Initialize a GraphBLAS context 42 | GrB_init(GrB_BLOCKING); 43 | 44 | GrB_Matrix graph; 45 | GrB_Matrix_new(&graph, GrB_BOOL, NUM_NODES, NUM_NODES); 46 | GrB_Matrix_build(graph, row_indices, col_indices, (bool*)values, NUM_EDGES, 47 | GrB_LOR); 48 | 49 | pretty_print_matrix_UINT64(graph, "GRAPH"); 50 | 51 | // Build a vector to select a source node and another 52 | // vector to hold the mxv result. 53 | GrB_Index const SRC_NODE = 6; 54 | GrB_Vector vec, result; 55 | GrB_Vector_new(&vec, GrB_BOOL, NUM_NODES); 56 | GrB_Vector_new(&result, GrB_BOOL, NUM_NODES); 57 | GrB_Vector_setElement(vec, true, SRC_NODE); 58 | 59 | // Build the descriptor to transpose the first input arg (INP0) 60 | GrB_Descriptor desc; 61 | GrB_Descriptor_new(&desc); 62 | GrB_Descriptor_set(desc, GrB_INP0, GrB_TRAN); 63 | 64 | // find neighbors of SRC_NODE 65 | 66 | pretty_print_vector_UINT64(vec, "source node"); 67 | GrB_mxv(result, GrB_NULL, GrB_NULL, 68 | GxB_LOR_LAND_BOOL, graph, vec, desc); 69 | pretty_print_vector_UINT64(result, "neighbors"); 70 | 71 | // Check results 72 | { 73 | bool error_found = false; 74 | GrB_Index nvals; 75 | GrB_Vector_nvals(&nvals, result); 76 | if (nvals != 3) 77 | { 78 | fprintf(stderr, "ERROR: wrong number of neighbors (!= 3): %ld\n", 79 | (long)nvals); 80 | error_found = true; 81 | } 82 | 83 | bool val; 84 | 85 | if (GrB_Vector_extractElement(&val, result, 2UL)) 86 | { 87 | fprintf(stderr, "ERROR: missing neighbor 2.\n"); 88 | error_found = true; 89 | } 90 | if (GrB_Vector_extractElement(&val, result, 3UL)) 91 | { 92 | fprintf(stderr, "ERROR: missing neighbor 3.\n"); 93 | error_found = true; 94 | } 95 | if (GrB_Vector_extractElement(&val, result, 4UL)) 96 | { 97 | fprintf(stderr, "ERROR: missing neighbor 4.\n"); 98 | error_found = true; 99 | } 100 | 101 | if (!error_found) 102 | { 103 | fprintf(stderr, "neighbor test passed.\n"); 104 | } 105 | } 106 | 107 | 108 | // Cleanup 109 | GrB_free(&graph); 110 | GrB_free(&vec); 111 | GrB_free(&result); 112 | GrB_free(&desc); 113 | GrB_finalize(); 114 | } 115 | -------------------------------------------------------------------------------- /src/Solutions/matvecTransIter.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the GraphBLAS Tutorial materials, 3 | * Copyright (c) 2018 Carnegie Mellon University and Intel Corporation. 4 | * All Rights Reserved 5 | * 6 | * THIS SOFTWARE IS PROVIDED "AS IS," WITH NO WARRANTIES WHATSOEVER. CARNEGIE 7 | * MELLON UNIVERSITY AND INTEL CORPORATION EXPRESSLY DISCLAIMS TO THE FULLEST 8 | * EXTENT PERMITTED BY LAW ALL EXPRESS, IMPLIED, AND STATUTORY WARRANTIES, 9 | * INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS 10 | * FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF PROPRIETARY RIGHTS. 11 | * 12 | * Released under a BSD (SEI)-style license, please see LICENSE.txt for 13 | * full terms. 14 | * 15 | * DM18-xxx 16 | * 17 | * Authors: Scott McMillan, Timothy G. Mattson 18 | */ 19 | 20 | /** 21 | * @file matvecTransIter.c 22 | * 23 | * @brief Code to hop to neighbors of a set of vertices iteratively 24 | * 25 | */ 26 | 27 | #include 28 | #include 29 | #include "tutorial_utils.h" 30 | 31 | //**************************************************************************** 32 | int main(int argc, char** argv) 33 | { 34 | GrB_Index const NUM_NODES = 7; 35 | GrB_Index const NUM_EDGES = 12; 36 | GrB_Index row_indices[] = {0, 0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 6}; 37 | GrB_Index col_indices[] = {1, 3, 4, 6, 5, 0, 2, 5, 2, 2, 3, 4}; 38 | bool values[] = {true, true, true, true, true, true, 39 | true, true, true, true, true, true}; 40 | 41 | // Initialize a GraphBLAS context 42 | GrB_init(GrB_BLOCKING); 43 | 44 | GrB_Matrix graph; 45 | GrB_Matrix_new(&graph, GrB_BOOL, NUM_NODES, NUM_NODES); 46 | GrB_Matrix_build(graph, row_indices, col_indices, (bool*)values, NUM_EDGES, 47 | GrB_LOR); 48 | 49 | pretty_print_matrix_UINT64(graph, "GRAPH"); 50 | 51 | // Build a vector to select a source node and another 52 | // vector to hold the mxv result. 53 | GrB_Index const SRC_NODE = 0; 54 | GrB_Vector w; 55 | GrB_Vector_new(&w, GrB_BOOL, NUM_NODES); 56 | GrB_Vector_setElement(w, true, SRC_NODE); 57 | 58 | // Build the transpose (INP0) descriptor 59 | GrB_Descriptor desc; 60 | GrB_Descriptor_new(&desc); 61 | GrB_Descriptor_set(desc, GrB_INP0, GrB_TRAN); 62 | 63 | pretty_print_vector_UINT64(w, "wavefront(src)"); 64 | 65 | // traverse to neighbors of a w iteratively starting with SRC_NODE 66 | for (unsigned int iter = 0; iter < NUM_NODES; ++iter) 67 | { 68 | GrB_mxv(w, GrB_NULL, GrB_NULL, 69 | GxB_LOR_LAND_BOOL, graph, w, desc); 70 | pretty_print_vector_UINT64(w, "wavefront"); 71 | } 72 | 73 | // Cleanup 74 | GrB_free(&graph); 75 | GrB_free(&w); 76 | GrB_free(&desc); 77 | GrB_finalize(); 78 | } 79 | -------------------------------------------------------------------------------- /src/Solutions/matvecTransIterLevels.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the GraphBLAS Tutorial materials, 3 | * Copyright (c) 2018 Carnegie Mellon University and Intel Corporation. 4 | * All Rights Reserved 5 | * 6 | * THIS SOFTWARE IS PROVIDED "AS IS," WITH NO WARRANTIES WHATSOEVER. CARNEGIE 7 | * MELLON UNIVERSITY AND INTEL CORPORATION EXPRESSLY DISCLAIMS TO THE FULLEST 8 | * EXTENT PERMITTED BY LAW ALL EXPRESS, IMPLIED, AND STATUTORY WARRANTIES, 9 | * INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS 10 | * FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF PROPRIETARY RIGHTS. 11 | * 12 | * Released under a BSD (SEI)-style license, please see LICENSE.txt for 13 | * full terms. 14 | * 15 | * DM18-xxx 16 | * 17 | * Authors: Scott McMillan, Timothy G. Mattson 18 | */ 19 | 20 | /** 21 | * @file matvecTransIterLevels_v2.c 22 | * 23 | * @brief Code to hop to neighbors of a set of vertices iteratively and exit 24 | * when the frontier becomes empty. Set the level of each vertex when 25 | * encountered (source node at level = 1). 26 | * 27 | */ 28 | 29 | #include 30 | #include 31 | #include "tutorial_utils.h" 32 | 33 | //**************************************************************************** 34 | int main(int argc, char** argv) 35 | { 36 | GrB_Index const NUM_NODES = 7; 37 | GrB_Index const NUM_EDGES = 12; 38 | GrB_Index row_indices[] = {0, 0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 6}; 39 | GrB_Index col_indices[] = {1, 3, 4, 6, 5, 0, 2, 5, 2, 2, 3, 4}; 40 | bool values[] = {true, true, true, true, true, true, 41 | true, true, true, true, true, true}; 42 | GrB_Matrix graph; 43 | 44 | GrB_Matrix_new(&graph, GrB_BOOL, NUM_NODES, NUM_NODES); 45 | GrB_Matrix_build(graph, row_indices, col_indices, (bool*)values, NUM_EDGES, 46 | GrB_LOR); 47 | 48 | pretty_print_matrix_UINT64(graph, "GRAPH"); 49 | 50 | // Build a vector to select a source node and another 51 | // vector to hold the mxv result. 52 | GrB_Index const SRC_NODE = 0; 53 | GrB_Vector w, levels; 54 | GrB_Vector_new(&w, GrB_BOOL, NUM_NODES); 55 | GrB_Vector_new(&levels, GrB_UINT64, NUM_NODES); 56 | GrB_Vector_setElement(w, true, SRC_NODE); 57 | 58 | // Build the transpose/scmp/replace descriptor 59 | GrB_Descriptor desc; 60 | GrB_Descriptor_new(&desc); 61 | GrB_Descriptor_set(desc, GrB_MASK, GrB_SCMP); 62 | GrB_Descriptor_set(desc, GrB_INP0, GrB_TRAN); 63 | GrB_Descriptor_set(desc, GrB_OUTP, GrB_REPLACE); 64 | 65 | pretty_print_vector_UINT64(w, "wavefront(src)"); 66 | 67 | // traverse to neighbors of a frontier iteratively starting with SRC_NODE 68 | int64_t level = 0; 69 | GrB_Index nvals = 0; 70 | 71 | do 72 | { 73 | ++level; 74 | GrB_assign(levels, w, GrB_NULL, 75 | level, GrB_ALL, NUM_NODES, GrB_NULL); 76 | pretty_print_vector_UINT64(levels, "levels"); 77 | 78 | GrB_mxv(w, levels, GrB_NULL, 79 | GxB_LOR_LAND_BOOL, graph, w, desc); 80 | pretty_print_vector_UINT64(w, "wavefront"); 81 | 82 | GrB_Vector_nvals(&nvals, w); 83 | } while (nvals > 0); 84 | 85 | // Cleanup 86 | GrB_free(&graph); 87 | GrB_free(&w); 88 | GrB_free(&levels); 89 | GrB_free(&desc); 90 | GrB_finalize(); 91 | } 92 | -------------------------------------------------------------------------------- /src/Solutions/matvecTransIterVisited.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the GraphBLAS Tutorial materials, 3 | * Copyright (c) 2018 Carnegie Mellon University and Intel Corporation. 4 | * All Rights Reserved 5 | * 6 | * THIS SOFTWARE IS PROVIDED "AS IS," WITH NO WARRANTIES WHATSOEVER. CARNEGIE 7 | * MELLON UNIVERSITY AND INTEL CORPORATION EXPRESSLY DISCLAIMS TO THE FULLEST 8 | * EXTENT PERMITTED BY LAW ALL EXPRESS, IMPLIED, AND STATUTORY WARRANTIES, 9 | * INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS 10 | * FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF PROPRIETARY RIGHTS. 11 | * 12 | * Released under a BSD (SEI)-style license, please see LICENSE.txt for 13 | * full terms. 14 | * 15 | * DM18-xxx 16 | * 17 | * Authors: Scott McMillan, Timothy G. Mattson 18 | */ 19 | 20 | /** 21 | * @file matvecTransIter.c 22 | * 23 | * @brief Code to hop to neighbors of a set of vertices iteratively 24 | * 25 | */ 26 | 27 | #include 28 | #include 29 | #include "tutorial_utils.h" 30 | 31 | //**************************************************************************** 32 | int main(int argc, char** argv) 33 | { 34 | GrB_Index const NUM_NODES = 7; 35 | GrB_Index const NUM_EDGES = 12; 36 | GrB_Index row_indices[] = {0, 0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 6}; 37 | GrB_Index col_indices[] = {1, 3, 4, 6, 5, 0, 2, 5, 2, 2, 3, 4}; 38 | bool values[] = {true, true, true, true, true, true, 39 | true, true, true, true, true, true}; 40 | GrB_Matrix graph; 41 | 42 | GrB_Matrix_new(&graph, GrB_BOOL, NUM_NODES, NUM_NODES); 43 | GrB_Matrix_build(graph, row_indices, col_indices, (bool*)values, NUM_EDGES, 44 | GrB_LOR); 45 | 46 | pretty_print_matrix_UINT64(graph, "GRAPH"); 47 | 48 | // Build a vector to select a source node and another 49 | // vector to hold the mxv result. 50 | GrB_Index const SRC_NODE = 0; 51 | GrB_Vector w, v; 52 | GrB_Vector_new(&w, GrB_BOOL, NUM_NODES); 53 | GrB_Vector_new(&v, GrB_BOOL, NUM_NODES); 54 | GrB_Vector_setElement(w, true, SRC_NODE); 55 | 56 | // Build the transpose descriptor 57 | GrB_Descriptor desc; 58 | GrB_Descriptor_new(&desc); 59 | GrB_Descriptor_set(desc, GrB_INP0, GrB_TRAN); 60 | 61 | pretty_print_vector_UINT64(w, "wavefront(src)"); 62 | 63 | // traverse to neighbors of a frontier iteratively starting with SRC_NODE 64 | for (unsigned int iter = 0; iter < NUM_NODES; ++iter) 65 | { 66 | GrB_eWiseAdd(v, GrB_NULL, GrB_NULL, 67 | GrB_LOR, v, w, GrB_NULL); 68 | pretty_print_vector_UINT64(v, "visited"); 69 | 70 | GrB_mxv(w, GrB_NULL, GrB_NULL, 71 | GxB_LOR_LAND_BOOL, graph, w, desc); 72 | pretty_print_vector_UINT64(w, "wavefront"); 73 | } 74 | 75 | // Cleanup 76 | GrB_free(&graph); 77 | GrB_free(&w); 78 | GrB_free(&v); 79 | GrB_free(&desc); 80 | GrB_finalize(); 81 | } 82 | -------------------------------------------------------------------------------- /src/Solutions/matvecTransIterVisitedExitFlag.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the GraphBLAS Tutorial materials, 3 | * Copyright (c) 2018 Carnegie Mellon University and Intel Corporation. 4 | * All Rights Reserved 5 | * 6 | * THIS SOFTWARE IS PROVIDED "AS IS," WITH NO WARRANTIES WHATSOEVER. CARNEGIE 7 | * MELLON UNIVERSITY AND INTEL CORPORATION EXPRESSLY DISCLAIMS TO THE FULLEST 8 | * EXTENT PERMITTED BY LAW ALL EXPRESS, IMPLIED, AND STATUTORY WARRANTIES, 9 | * INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS 10 | * FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF PROPRIETARY RIGHTS. 11 | * 12 | * Released under a BSD (SEI)-style license, please see LICENSE.txt for 13 | * full terms. 14 | * 15 | * DM18-xxx 16 | * 17 | * Authors: Scott McMillan, Timothy G. Mattson 18 | */ 19 | 20 | /** 21 | * @file matvecTransIterExitFlag_v2.c 22 | * 23 | * @brief Code to hop to neighbors of a set of vertices iteratively and exit 24 | * when the frontier becomes empty. 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include "tutorial_utils.h" 31 | 32 | //**************************************************************************** 33 | int main(int argc, char** argv) 34 | { 35 | GrB_Index const NUM_NODES = 7; 36 | GrB_Index const NUM_EDGES = 12; 37 | GrB_Index row_indices[] = {0, 0, 1, 1, 2, 3, 3, 4, 5, 6, 6, 6}; 38 | GrB_Index col_indices[] = {1, 3, 4, 6, 5, 0, 2, 5, 2, 2, 3, 4}; 39 | bool values[] = {true, true, true, true, true, true, 40 | true, true, true, true, true, true}; 41 | GrB_Matrix graph; 42 | 43 | GrB_Matrix_new(&graph, GrB_BOOL, NUM_NODES, NUM_NODES); 44 | GrB_Matrix_build(graph, row_indices, col_indices, (bool*)values, NUM_EDGES, 45 | GrB_LOR); 46 | 47 | pretty_print_matrix_UINT64(graph, "GRAPH"); 48 | 49 | // Build a vector to select a source node and another 50 | // vector to hold the mxv result. 51 | GrB_Index const SRC_NODE = 0; 52 | GrB_Vector w, v; 53 | GrB_Vector_new(&w, GrB_BOOL, NUM_NODES); 54 | GrB_Vector_new(&v, GrB_BOOL, NUM_NODES); 55 | GrB_Vector_setElement(w, true, SRC_NODE); 56 | 57 | // Build the transpose/scmp/replace descriptor 58 | GrB_Descriptor desc; 59 | GrB_Descriptor_new(&desc); 60 | GrB_Descriptor_set(desc, GrB_INP0, GrB_TRAN); 61 | GrB_Descriptor_set(desc, GrB_MASK, GrB_SCMP); 62 | GrB_Descriptor_set(desc, GrB_OUTP, GrB_REPLACE); 63 | 64 | pretty_print_vector_UINT64(w, "wavefront(src)"); 65 | 66 | // traverse to neighbors of a frontier iteratively starting with SRC_NODE 67 | GrB_Index nvals = 0; 68 | 69 | do 70 | { 71 | GrB_eWiseAdd(v, GrB_NULL, GrB_NULL, GrB_LOR, v, w, GrB_NULL); 72 | pretty_print_vector_UINT64(v, "visited"); 73 | 74 | GrB_mxv(w, v, GrB_NULL, GxB_LOR_LAND_BOOL, graph, w, desc); 75 | pretty_print_vector_UINT64(w, "wavefront"); 76 | 77 | GrB_Vector_nvals(&nvals, w); 78 | } while (nvals > 0); 79 | 80 | // Cleanup 81 | GrB_free(&graph); 82 | GrB_free(&w); 83 | GrB_free(&v); 84 | GrB_free(&desc); 85 | GrB_finalize(); 86 | } 87 | -------------------------------------------------------------------------------- /src/make.def: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of the GraphBLAS tutorial materials, 3 | # Copyright (c) 2018 Carnegie Mellon University and Intel Corporation. 4 | # 5 | # THIS SOFTWARE IS PROVIDED "AS IS," WITH NO WARRANTIES WHATSOEVER. CARNEGIE 6 | # MELLON UNIVERSITY AND INTEL CORPORATION EXPRESSLY DISCLAIMS TO THE FULLEST 7 | # EXTENT PERMITTED BY LAW ALL EXPRESS, IMPLIED, AND STATUTORY WARRANTIES, 8 | # INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY, FITNESS 9 | # FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF PROPRIETARY RIGHTS. 10 | # 11 | # Released under a BSD (SEI)-style license, please see LICENSE.txt for 12 | # full terms. 13 | # 14 | # Authors: Scott McMillan, Timothy G. Mattson 15 | # 16 | 17 | PLATFORM := $(shell uname -s) 18 | 19 | CC = UNKNOW_PLATFORM 20 | 21 | ifeq ($(PLATFORM),Linux) 22 | CC = gcc -std=c11 -fopenmp 23 | OPTS = -g 24 | #OPTS = -Ofast -march=native -DNDEBUG 25 | #OPTS = -g -fsanitize=address 26 | WFLAGS = -Wall 27 | DEFS = 28 | INCLUDE = -I$(INCDIR) 29 | LIB = -llagraph -lgraphblas -lm -Wl,-rpath,$(LIBDIR) -L$(LIBDIR) 30 | endif 31 | 32 | ifeq ($(PLATFORM),Darwin) 33 | CC = gcc-9 -std=c11 -fopenmp 34 | OPTS = -g 35 | WFLAGS = -Wall 36 | DEFS = 37 | INCLUDE = -I$(INCDIR) 38 | LIB = -llagraphOSX -lgraphblasOSX -lm -Wl,-rpath,$(LIBDIR) -L$(LIBDIR) 39 | endif 40 | 41 | CCFLAGS = $(OPTS) $(WFLAGS) $(DEFS) $(INCLUDE) 42 | -------------------------------------------------------------------------------- /src/read_mtx.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 xxx. 3 | 4 | All Rights Reserved. 5 | 6 | NO WARRANTY. THIS MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. THE LAGRAPH 7 | CONTRIBUTORS MAKE NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, 8 | AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR 9 | PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF 10 | THE MATERIAL. THE CONTRIBUTORS DO NOT MAKE ANY WARRANTY OF ANY KIND WITH 11 | RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT. 12 | 13 | Released under a BSD license, please see the LICENSE file distributed with 14 | this Software or contact permission@sei.cmu.edu for full terms. 15 | 16 | Created, in part, with funding and support from the United States 17 | Government. (see Acknowledgments.txt file). 18 | 19 | This program includes and/or can make use of certain third party source 20 | code, object code, documentation and other files ("Third Party Software"). 21 | See LICENSE file for more details. 22 | 23 | */ 24 | 25 | //------------------------------------------------------------------------------ 26 | 27 | // Contributed by Scott McMillan/CMU, Tim Mattson/Intel 28 | 29 | #include 30 | #include "LAGraph.h" 31 | 32 | #define OK(method) \ 33 | { \ 34 | GrB_Info this_info = method ; \ 35 | if (! (this_info == GrB_SUCCESS || this_info == GrB_NO_VALUE)) \ 36 | { \ 37 | printf ("GrB failure: [%d] %s\n", this_info, GrB_error ( )) ; \ 38 | return (this_info) ; \ 39 | } \ 40 | } 41 | 42 | //------------------------------------------------------------------------------ 43 | // read_mtx main: 44 | //------------------------------------------------------------------------------ 45 | int main (int argc, char **argv) 46 | { 47 | if (argc < 2) 48 | { 49 | fprintf(stderr, "Error\nUsage: %s \n", argv[0]); 50 | return 1; 51 | } 52 | 53 | #if defined ( GxB_SUITESPARSE_GRAPHBLAS ) 54 | printf ("testing LAGraph_xinit (requires SuiteSparse:GraphBLAS)\n") ; 55 | LAGraph_xinit (malloc, calloc, realloc, free, true) ; 56 | #else 57 | printf ("LAGraph_init\n") ; 58 | LAGraph_init ( ) ; 59 | #endif 60 | 61 | #define NTYPES 12 62 | GrB_Type types [NTYPES] = { GrB_BOOL, 63 | GrB_INT8, GrB_INT16, GrB_INT32, GrB_INT64, 64 | GrB_UINT8, GrB_UINT16, GrB_UINT32, GrB_UINT64, 65 | GrB_FP32, GrB_FP64, LAGraph_Complex }; 66 | 67 | char *typenames [NTYPES] = { "bool", 68 | "int8", "int16", "int32", "int64", 69 | "uint8", "uint16", "uint32", "uint64", 70 | "float", "double", "complex" }; 71 | 72 | 73 | printf("reading input graph: %s\n", argv[1]); 74 | GrB_Matrix A = NULL; 75 | FILE *fd = fopen(argv[1], "r"); 76 | 77 | double tic[2], t; 78 | LAGraph_tic (tic); 79 | OK (LAGraph_mmread (&A, fd); ) 80 | t = LAGraph_toc(tic) ; 81 | if (fd != NULL) fclose(fd); 82 | printf ("time taken: %g sec\n", t) ; 83 | 84 | GrB_Index num_rows, num_cols, num_vals; 85 | GrB_Matrix_nrows(&num_rows, A); 86 | GrB_Matrix_ncols(&num_cols, A); 87 | GrB_Matrix_nvals(&num_vals, A); 88 | printf ("nrows/ncols/nvals = %ld/%ld/%ld\n", num_rows, num_cols, num_vals); 89 | 90 | GrB_Vector degree; 91 | GrB_Vector_new(°ree, GrB_UINT64, num_rows); 92 | GrB_reduce(degree, GrB_NULL, GrB_NULL, GrB_PLUS_UINT64, A, GrB_NULL); 93 | 94 | GrB_Index max_val, max_index; 95 | for (GrB_Index ix = 0; ix < num_rows; ++ix) 96 | { 97 | GrB_Index val; 98 | if (GrB_NO_VALUE != GrB_Vector_extractElement(&val, degree, ix)) 99 | { 100 | if (val > max_val) 101 | { 102 | max_val = val; 103 | max_index = ix; 104 | } 105 | } 106 | } 107 | 108 | printf("Author with the most coauthor/paper combos: %ld (count: %ld)\n", max_index, max_val); 109 | 110 | GrB_free(&A); 111 | LAGraph_finalize ( ) ; 112 | return (GrB_SUCCESS) ; 113 | } 114 | --------------------------------------------------------------------------------