/* produces the egoent of the stinger vertex ID given in JSON form */ string_t * egonet_to_json(stinger_t * S, int64_t vtx) { string_t vertices, edges; string_init_from_cstr(&vertices, "\"vertices\" : [ \n"); string_init_from_cstr(&edges, "\"edges\" : [ \n"); char vtx_str[1UL<<20UL]; FILE * vtx_file = fmemopen(vtx_str, sizeof(vtx_str), "w"); char edge_str[1UL<<20UL]; int edge_added = 0; stinger_vertex_to_json_with_type_strings(stinger_vertices_get(S), stinger_vtype_names_get(S), stinger_physmap_get(S), vtx, vtx_file, 2); fflush(vtx_file); string_append_cstr(&vertices, vtx_str); fseek(vtx_file, 0, SEEK_SET); int_hm_seq_t * neighbors = int_hm_seq_new(stinger_outdegree_get(S, vtx) + stinger_indegree_get(S, vtx)); int64_t which = 1; STINGER_FORALL_EDGES_OF_VTX_BEGIN(S, vtx) { int64_t source = int_hm_seq_get(neighbors, STINGER_EDGE_DEST); if(INT_HT_SEQ_EMPTY == source) { source = which++; int_hm_seq_insert(neighbors, STINGER_EDGE_DEST, source); fprintf(vtx_file, ",\n"); stinger_vertex_to_json_with_type_strings(stinger_vertices_get(S), stinger_vtype_names_get(S), stinger_physmap_get(S), STINGER_EDGE_DEST, vtx_file, 2); fputc('\0',vtx_file); fflush(vtx_file); string_append_cstr(&vertices, vtx_str); fseek(vtx_file, 0, SEEK_SET); } char * etype = stinger_etype_names_lookup_name(S, STINGER_EDGE_TYPE); const char prepend_str [] = ",\n"; if (STINGER_IS_OUT_EDGE) { if(!edge_added) { edge_added = 1; if(etype) { sprintf(edge_str, "{ \"type\" : \"%s\", \"src\" : %ld, \"dest\" : %ld, \"weight\" : %ld, \"time1\" : %ld, \"time2\" : %ld, \"source\" : %ld, \"target\": %ld }", etype, STINGER_EDGE_SOURCE, STINGER_EDGE_DEST, STINGER_EDGE_WEIGHT, STINGER_EDGE_TIME_FIRST, STINGER_EDGE_TIME_RECENT, (long int) 0, source); } else { sprintf(edge_str, "{ \"type\" : \"%ld\", \"src\" : %ld, \"dest\" : %ld, \"weight\" : %ld, \"time1\" : %ld, \"time2\" : %ld, \"source\" : %ld, \"target\": %ld }", STINGER_EDGE_TYPE, STINGER_EDGE_SOURCE, STINGER_EDGE_DEST, STINGER_EDGE_WEIGHT, STINGER_EDGE_TIME_FIRST, STINGER_EDGE_TIME_RECENT, (long int) 0, source); } } else { if(etype) { sprintf(edge_str, ",\n{ \"type\" : \"%s\", \"src\" : %ld, \"dest\" : %ld, \"weight\" : %ld, \"time1\" : %ld, \"time2\" : %ld, \"source\" : %ld, \"target\": %ld }", etype, STINGER_EDGE_SOURCE, STINGER_EDGE_DEST, STINGER_EDGE_WEIGHT, STINGER_EDGE_TIME_FIRST, STINGER_EDGE_TIME_RECENT, (long int) 0, source); } else { sprintf(edge_str, ",\n{ \"type\" : \"%ld\", \"src\" : %ld, \"dest\" : %ld, \"weight\" : %ld, \"time1\" : %ld, \"time2\" : %ld, \"source\" : %ld, \"target\": %ld }", STINGER_EDGE_TYPE, STINGER_EDGE_SOURCE, STINGER_EDGE_DEST, STINGER_EDGE_WEIGHT, STINGER_EDGE_TIME_FIRST, STINGER_EDGE_TIME_RECENT, (long int) 0, source); } } string_append_cstr(&edges, edge_str); } uint64_t dest = STINGER_EDGE_DEST; STINGER_FORALL_OUT_EDGES_OF_VTX_BEGIN(S, dest) { int64_t target = int_hm_seq_get(neighbors, STINGER_EDGE_DEST); if(INT_HT_SEQ_EMPTY != target) { char * etype = stinger_etype_names_lookup_name(S, STINGER_EDGE_TYPE); if(etype) { sprintf(edge_str, ",\n{ \"type\" : \"%s\", \"src\" : %ld, \"dest\" : %ld, \"weight\" : %ld, \"time1\" : %ld, \"time2\" : %ld, \"source\" : %ld, \"target\": %ld }", etype, STINGER_EDGE_SOURCE, STINGER_EDGE_DEST, STINGER_EDGE_WEIGHT, STINGER_EDGE_TIME_FIRST, STINGER_EDGE_TIME_RECENT, source, target); } else { sprintf(edge_str, ",\n{ \"type\" : \"%ld\", \"src\" : %ld, \"dest\" : %ld, \"weight\" : %ld, \"time1\" : %ld, \"time2\" : %ld, \"source\" : %ld, \"target\": %ld }", STINGER_EDGE_TYPE, STINGER_EDGE_SOURCE, STINGER_EDGE_DEST, STINGER_EDGE_WEIGHT, STINGER_EDGE_TIME_FIRST, STINGER_EDGE_TIME_RECENT, source, target); } string_append_cstr(&edges, edge_str); } } STINGER_FORALL_OUT_EDGES_OF_VTX_END();
int main(int argc, char *argv[]) { /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Setup and register algorithm with the server * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ char name[1024]; char type_str[1024]; int type_specified = 0; int directed = 0; double epsilon = EPSILON_DEFAULT; double dampingfactor = DAMPINGFACTOR_DEFAULT; int64_t maxiter = MAXITER_DEFAULT; int opt = 0; while(-1 != (opt = getopt(argc, argv, "t:e:f:i:d?h"))) { switch(opt) { case 't': { sprintf(name, "pagerank_%s", optarg); strcpy(type_str,optarg); type_specified = 1; } break; case 'd': { directed = 1; } break; case 'e': { epsilon = atof(optarg); } break; case 'f': { dampingfactor = atof(optarg); } break; case 'i': { maxiter = atol(optarg); } break; default: printf("Unknown option '%c'\n", opt); case '?': case 'h': { printf( "PageRank\n" "==================================\n" "\n" " -t <str> Specify an edge type to run page rank over\n" " -d Use a PageRank that is safe on directed graphs\n" " -e Set PageRank Epsilon (default: %0.1e)\n" " -f Set PageRank Damping Factor (default: %lf)\n" " -i Set PageRank Max Iterations (default: %ld)\n" "\n",EPSILON_DEFAULT,DAMPINGFACTOR_DEFAULT,MAXITER_DEFAULT); return(opt); } } } stinger_registered_alg * alg = stinger_register_alg( .name=type_specified ? name : "pagerank", .data_per_vertex=sizeof(double), .data_description="d pagerank", .host="localhost", ); if(!alg) { LOG_E("Registering algorithm failed. Exiting"); return -1; } double * pr = (double *)alg->alg_data; OMP("omp parallel for") for(uint64_t v = 0; v < alg->stinger->max_nv; v++) { pr[v] = 1 / ((double)alg->stinger->max_nv); } double * tmp_pr = (double *)xcalloc(alg->stinger->max_nv, sizeof(double)); double time; init_timer(); /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Initial static computation * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ stinger_alg_begin_init(alg); { int64_t type = -1; if(type_specified) { type = stinger_etype_names_lookup_type(alg->stinger, type_str); } if(type_specified && type > -1) { if (directed) { page_rank_type_directed(alg->stinger, stinger_mapping_nv(alg->stinger), pr, tmp_pr, epsilon, dampingfactor, maxiter, type); } else { page_rank_type(alg->stinger, stinger_mapping_nv(alg->stinger), pr, tmp_pr, epsilon, dampingfactor, maxiter, type); } } else if (!type_specified) { if (directed) { page_rank_directed(alg->stinger, stinger_mapping_nv(alg->stinger), pr, tmp_pr, epsilon, dampingfactor, maxiter); } else { page_rank(alg->stinger, stinger_mapping_nv(alg->stinger), pr, tmp_pr, epsilon, dampingfactor, maxiter); } } } stinger_alg_end_init(alg); /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Streaming Phase * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ while(alg->enabled) { /* Pre processing */ if(stinger_alg_begin_pre(alg)) { /* nothing to do */ time = timer(); stinger_alg_end_pre(alg); time = timer() - time; LOG_I_A("Pre time : %20.15e", time); } /* Post processing */ time = timer(); if(stinger_alg_begin_post(alg)) { int64_t type = -1; if(type_specified) { type = stinger_etype_names_lookup_type(alg->stinger, type_str); if(type > -1) { if (directed) { page_rank_type_directed(alg->stinger, stinger_mapping_nv(alg->stinger), pr, tmp_pr, epsilon, dampingfactor, maxiter, type); } else { page_rank_type(alg->stinger, stinger_mapping_nv(alg->stinger), pr, tmp_pr, epsilon, dampingfactor, maxiter, type); } } else { LOG_W_A("TYPE DOES NOT EXIST %s", type_str); LOG_W("Existing types:"); // TODO: Don't go through the loop if LOG_W isn't enabled for(int64_t t = 0; t < stinger_etype_names_count(alg->stinger); t++) { LOG_W_A(" > %ld %s", (long) t, stinger_etype_names_lookup_name(alg->stinger, t)); } } } else { if (directed) { page_rank_directed(alg->stinger, stinger_mapping_nv(alg->stinger), pr, tmp_pr, epsilon, dampingfactor, maxiter); } else { page_rank(alg->stinger, stinger_mapping_nv(alg->stinger), pr, tmp_pr, epsilon, dampingfactor, maxiter); } } stinger_alg_end_post(alg); } time = timer() - time; LOG_I_A("Post time : %20.15e", time); } LOG_I("Algorithm complete... shutting down"); free(tmp_pr); }