void load_all(const char* name) { bvgraph g = {0}; bvgraph_load(&g, name, strlen(name), 0); bvgraph_iterator git; int rval = bvgraph_nonzero_iterator(&g, &git); if (rval){ printf("Construct nonzero iterator failed. Stop.\n"); return; } ALL_PAIR = malloc(sizeof(int)*2*(int)g.m); for (; bvgraph_iterator_valid(&git); bvgraph_iterator_next(&git)) { int64_t*links = NULL; uint64_t d = 0; bvgraph_iterator_outedges(&git, &links, &d); int64_t i = 0; for (i=0; i<d; ++i) { ALL_PAIR[PAIR_SIZE].from = git.curr; ALL_PAIR[PAIR_SIZE].to = links[i]; PAIR_SIZE++; } } bvgraph_iterator_free(&git); }
void iteration(const char* name){ bvgraph g = {0}; bvgraph_load(&g, name, strlen(name), 0); bvgraph_iterator git; int rval = bvgraph_nonzero_iterator(&g, &git); if (rval){ printf("Construct nonzero iterator failed. Stop.\n"); return; } for (; bvgraph_iterator_valid(&git); bvgraph_iterator_next(&git)) { int64_t *links = NULL; uint64_t d = 0; bvgraph_iterator_outedges(&git, &links, &d); printf("node %"PRId64" has degree %"PRId64"\n", git.curr, d); int64_t i = 0; for (i=0; i<d; ++i) { printf("node %"PRId64" links to node %"PRId64"\n", git.curr, links[i]); } } bvgraph_iterator_free(&git); }
/** Compute a matrix vector product with a substochastic bvgraph structure * * y = y + alpha*P'*x where P = D^{-1} A for the adjacency matrix A given * by a bvgraph structure. * * @param g the bvgraph * @param x the right hand vector, * @param y the output vector y = y + alpha*P'*x * @param alpha the value of alpha to adjust the mutliplication by * @param sum_aPtx the value e^T (alpha*P'*x) * @return non-zero on error */ int mult(omptransbvgraph *tg, double *x, double *y, const double alpha, double *sum_aPtx) { bvgraph_parallel_iterators *pits = tg->pits; int rval=0, j, n=pits->g->n; double sum0=0, sum1=0, *id=tg->id; #pragma omp parallel shared(x,y,pits,sum0,sum1,id) \ reduction(|:rval) num_threads(pits->niters) { int *links, tid, nsteps; unsigned int i, d; double sumy0, sumy1, t, z; bvgraph_iterator iter; tid = omp_get_thread_num(); rval = bvgraph_parallel_iterator(pits, tid, &iter, &nsteps); sumy0=0.0; sumy1=0.0; if (rval == 0) { for (; bvgraph_iterator_valid(&iter) && nsteps; bvgraph_iterator_next(&iter), nsteps--) { double yi=0.0; bvgraph_iterator_outedges(&iter, &links, &d); for (i = 0; i < d; i++) { yi += x[links[i]]*id[links[i]]; } yi *= alpha; CSUM2(yi,sumy0,sumy1,t,z); y[iter.curr]=yi; } bvgraph_iterator_free(&iter); #pragma omp critical { CSUM2(FCSUM2(sumy0,sumy1),sum0,sum1,t,z) } } else { if (BVGRAPH_VERBOSE) { fprintf(stderr,"bvgraph_omp_transmult failed on thread %3i\n", tid); } } }
/** * Load a graph file but using a set of externally provided buffers * for the data. This might be useful in the case that you want to managed * memory for the graph independently of this function. * * To maintain the graph, only the bvgraph structure, and the two * external ararys: gmemory and offsets are required. Consequently, * a bvgraph structure can always be patched together out of these * functions. * * One common way of using this function would be to first * load a graph on the disk (bvgraph_load(...,offset_step=-1)) * and then call bvgraph_required_memory with an alternative * offset step. * * @param[in] g a newly created bvgraph structure * @param[in] filename the base filename for a set of bvgraph files, * so filename.graph and filename.properties must exist. * @param[in] offset_step controls how many offsets are loaded, * if offset_step = -1, then the graph file isn't loaded into memory * if offset_step = 0, then the graph file is loaded, but no offsets * no other values are supported at the moment. * @param[in] gmemory an arry of size gmemsize for the graph * (if NULL, then this parameter is treated as internal memory) * @param[in] gmemsize the size of the gmemory block * @param[in] offsets an array of offsets * (if NULL, then this parameter is treated as internal memory) * @param[in] offsetssize the number of offsets * @return 0 if successful; * bvgraph_load_error_filename_too_long - indicates the filename was too long */ int bvgraph_load_external(bvgraph *g, const char *filename, unsigned int filenamelen, int offset_step, unsigned char *gmemory, size_t gmemsize, unsigned long long* offsets, int offsetssize) { int rval = 0; assert(offset_step == 0 || offset_step == -1 || offset_step == 1); if (filenamelen > BVGRAPH_MAX_FILENAME_SIZE-1) { return bvgraph_load_error_filename_too_long; } memset(g,0,sizeof(bvgraph)); strncpy(g->filename, filename, filenamelen); g->filename[filenamelen] = '\0'; g->filenamelen = filenamelen; g->offset_step = offset_step; set_defaults(g); rval = parse_properties(g); // check for any errors if (rval != 0) { return rval; } // continue processing if (offset_step >= 0) { if (offset_step == 0 || offset_step == 1) { //modified 082911 // in this case, we ust load the graph // file into memory // first get the filesize unsigned long long graphfilesize; char *gfilename = strappend(g->filename, g->filenamelen, ".graph", 6); rval = fsize(gfilename, &graphfilesize); free(gfilename); if (rval) { return bvgraph_call_io_error; } if (gmemory != NULL) { // they want to use their own memory, make sure // they allocated enough! if (gmemsize < graphfilesize) { return bvgraph_load_error_buffer_too_small; } g->memory = gmemory; g->memory_size = gmemsize; g->memory_external = 1; } else { // we have to allocate the memory ourselves g->memory_size = (size_t)graphfilesize; g->memory = malloc(sizeof(unsigned char)*g->memory_size); if (!g->memory) { return bvgraph_call_out_of_memory; } g->memory_external = 0; } // now read the file gfilename = strappend(g->filename, g->filenamelen, ".graph", 6); { size_t bytesread = 0; FILE *gfile = fopen(gfilename, "rb"); free(gfilename); if (!gfile) { return bvgraph_call_io_error; } bytesread = fread(g->memory, 1, g->memory_size, gfile); if (bytesread != graphfilesize) { return bvgraph_call_io_error; } fclose(gfile); } // we now have the graph in memory! if (offset_step == 1) { //modified 082911 // now read the file char *ofilename = strappend(g->filename, g->filenamelen, ".offsets", 8); bitfile bf; long long off = 0; int64_t i; FILE *ofile = fopen(ofilename, "rb"); if (offsets != NULL) { g->offsets = offsets; g->offsets_external = 1; } else { // we have to allocate the memory ourselves g->offsets = (unsigned long long*) malloc(sizeof(unsigned long long)*g->n); g->offsets_external = 0; } if (ofile) { rval = bitfile_open(ofile, &bf); if (rval) { return bvgraph_call_io_error; } for (i = 0; i < g->n; i++){ off = read_offset(g, &bf) + off; g->offsets[i] = off; } } else { // need to build the offsets bvgraph_iterator git; int rval = bvgraph_nonzero_iterator(g, &git); if (rval) { return rval; } g->offsets[0] = 0; for (; bvgraph_iterator_valid(&git); bvgraph_iterator_next(&git)) { if (git.curr+1 < g->n) { g->offsets[git.curr+1] = bitfile_tell(&git.bf); } } bvgraph_iterator_free(&git); } } } } else { g->memory_size = 0; } // presently the othercases are not supported, so we don't have to // worry about them! return (0); }
int main(int argc, char **argv) { bvgraph graph = {0}; bvgraph *g = &graph; char *filename; int filenamelen; int rval; int i; if (argc < 2) { fprintf(stderr, "Usage: bvgraph_test bvgraph_basename\n"); return (-1); } filename = argv[1]; filenamelen = (int)strlen(filename); rval = bvgraph_load(g, filename, filenamelen, -1); if (rval) { perror("error with initial load!"); } { size_t memrequired; bvgraph_required_memory(g, 0, &memrequired, NULL); printf("the graph %s requires %i bytes to load into memory\n", filename, memrequired); } bvgraph_close(g); rval = bvgraph_load(g, filename, filenamelen, 0); if (rval) { perror("error with full load!"); } { bvgraph_iterator iter; int *links; unsigned int d; // initialize a vector of column sums int *colsum = malloc(sizeof(int)*g->n); int *colsum2 = malloc(sizeof(int)*g->n); int rep; memset(colsum, 0, sizeof(int)*g->n); for (bvgraph_nonzero_iterator(g, &iter); bvgraph_iterator_valid(&iter); bvgraph_iterator_next(&iter)) { bvgraph_iterator_outedges(&iter, &links, &d); for (i = 0; i < d; i++) { colsum[links[i]]++; } } bvgraph_iterator_free(&iter); for (rep = 0; rep < 10000; rep++) { memset(colsum2, 0, sizeof(int)*g->n); for (bvgraph_nonzero_iterator(g, &iter); bvgraph_iterator_valid(&iter); bvgraph_iterator_next(&iter)) { bvgraph_iterator_outedges(&iter, &links, &d); for (i = 0; i < d; i++) { colsum2[links[i]]++; } } bvgraph_iterator_free(&iter); for (i=0; i < g->n; i++) { if (colsum2[i] != colsum[i]) { fprintf(stderr, "error, column sum of column %i is not correct (%i =? %i)", i, colsum[i], colsum2[i]); perror("colsum error!"); } } } free(colsum); free(colsum2); } bvgraph_close(g); for (i = 0; i < 10000000; i++) { rval = bvgraph_load(g, filename, filenamelen, 0); bvgraph_close(g); } }