38 #include "cmapreduce.h" 45 int cull(
const struct kmr_kv_box kv[],
const long n,
47 void output(
char *,
int,
char *,
int,
int *,
void *,
void *);
48 void nonzero(
char *,
int,
char *,
int,
int *,
void *,
void *);
49 void degree(
char *,
int,
char *,
int,
int *,
void *,
void *);
50 void histo(
char *,
int,
char *,
int,
int *,
void *,
void *);
51 int ncompare(
char *,
int,
char *,
int);
52 void stats(uint64_t,
char *,
int,
char *,
int,
void *,
void *);
58 double a, b, c, d, fraction;
71 int main(
int argc,
char **argv)
75 MPI_Init_thread(&argc, &argv, MPI_THREAD_SERIALIZED, &thlv);
76 MPI_Comm_rank(MPI_COMM_WORLD, &me);
77 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
82 if (argc != 9 && argc != 10) {
83 if (me == 0) printf(
"Syntax: rmat N Nz a b c d frac seed {outfile}\n");
84 MPI_Abort(MPI_COMM_WORLD, 1);
88 rmat.nlevels = atoi(argv[1]);
89 rmat.nnonzero = atoi(argv[2]);
90 rmat.a = atof(argv[3]);
91 rmat.b = atof(argv[4]);
92 rmat.c = atof(argv[5]);
93 rmat.d = atof(argv[6]);
94 rmat.fraction = atof(argv[7]);
95 int seed = atoi(argv[8]);
97 int n = (int)(strlen(argv[9]) + 1);
98 rmat.outfile = malloc(
sizeof(
char) * (
size_t)n);
99 strcpy(rmat.outfile, argv[9]);
104 if (rmat.a + rmat.b + rmat.c + rmat.d != 1.0) {
105 if (me == 0) printf(
"ERROR: a,b,c,d must sum to 1\n");
106 MPI_Abort(MPI_COMM_WORLD, 1);
109 if (rmat.fraction >= 1.0) {
110 if (me == 0) printf(
"ERROR: fraction must be < 1\n");
111 MPI_Abort(MPI_COMM_WORLD, 1);
115 rmat.order = (1 << rmat.nlevels);
124 struct kmr_option keepopen = {.keep_open = 1};
126 MPI_Barrier(MPI_COMM_WORLD);
127 double tstart = MPI_Wtime();
132 int ntotal = (1 << rmat.nlevels) * rmat.nnonzero;
133 int nremain = ntotal;
134 while (nremain > 0) {
136 rmat.ngenerate = nremain/nprocs;
137 if (me < (nremain % nprocs))
153 nremain = (ntotal - (int)nunique);
157 MPI_Barrier(MPI_COMM_WORLD);
158 double tstop = MPI_Wtime();
165 sprintf(fname,
"%s.%d", rmat.outfile, me);
166 rmat.fp = fopen(fname,
"w");
167 if (rmat.fp == NULL) {
168 printf(
"ERROR: Could not open output file\n");
169 MPI_Abort(MPI_COMM_WORLD, 1);
171 void *mr2 = MR_copy(mr);
172 MR_reduce(mr2, &output, &rmat);
181 printf(
"%d rows in matrix\n", rmat.order);
182 printf(
"%d nonzeroes in matrix\n", ntotal);
185 MR_reduce(mr, &nonzero, NULL);
186 MR_collate(mr, NULL);
187 MR_reduce(mr, °ree, NULL);
188 MR_collate(mr, NULL);
189 MR_reduce(mr, &histo, NULL);
191 MR_sort_keys(mr, &ncompare);
193 MR_map_mr(mr, mr, &stats, &total);
194 if (me == 0) printf(
"%d rows with 0 nonzeroes\n", rmat.order-total);
198 printf(
"%g secs to generate matrix on %d procs in %d iterations\n",
199 tstop-tstart, nprocs, niterate);
224 int nlevels = rmat->nlevels;
225 int order = rmat->order;
226 int ngenerate = rmat->ngenerate;
231 double fraction = rmat->fraction;
233 int i, j, ilevel, delta, m;
234 double a1, b1, c1, d1, total, rn;
237 for (m = 0; m < ngenerate; m++) {
239 a1 = a; b1 = b; c1 = c; d1 = d;
242 for (ilevel = 0; ilevel < nlevels; ilevel++) {
246 }
else if (rn < a1+b1) {
248 }
else if (rn < a1+b1+c1) {
256 if (fraction > 0.0) {
257 a1 += a1*fraction * (drand48() - 0.5);
258 b1 += b1*fraction * (drand48() - 0.5);
259 c1 += c1*fraction * (drand48() - 0.5);
260 d1 += d1*fraction * (drand48() - 0.5);
273 .k.p = (
char *)&edge,
290 int cull(
const struct kmr_kv_box kv[],
const long n,
306 void output(
char *key,
int keybytes,
char *multivalue,
307 int nvalues,
int *valuebytes,
void *kv,
void *ptr)
311 fprintf(rmat->fp,
"%d %d 1\n", edge->vi+1, edge->vj+1);
320 void nonzero(
char *key,
int keybytes,
char *multivalue,
321 int nvalues,
int *valuebytes,
void *kv,
void *ptr)
333 void degree(
char *key,
int keybytes,
char *multivalue,
334 int nvalues,
int *valuebytes,
void *kv,
void *ptr)
345 void histo(
char *key,
int keybytes,
char *multivalue,
346 int nvalues,
int *valuebytes,
void *kv,
void *ptr)
356 int ncompare(
char *p1,
int len1,
char *p2,
int len2)
358 int i1 = *(
int *) p1;
359 int i2 = *(
int *) p2;
372 void stats(uint64_t itask,
char *key,
int keybytes,
char *value,
373 int valuebytes,
void *kv,
void *ptr)
375 int *total = (
int *) ptr;
376 int nnz = *(
int *) key;
377 int ncount = *(
int *) value;
379 printf(
"%d rows with %d nonzeroes\n",ncount,nnz);
Key-Value Stream (abstract).
#define kmr_reduce(KVI, KVO, ARG, OPT, R)
Reduces key-value pairs.
Options to Mapping, Shuffling, and Reduction.
int kmr_add_kv(KMR_KVS *kvs, const struct kmr_kv_box kv)
Adds a key-value pair.
int kmr_map_once(KMR_KVS *kvo, void *arg, struct kmr_option opt, _Bool rank_zero_only, kmr_mapfn_t m)
Maps once.
#define kmr_create_kvs(MR, KF, VF)
Makes a new key-value stream (of type KMR_KVS) with the specified field datatypes.
int kmr_shuffle(KMR_KVS *kvi, KMR_KVS *kvo, struct kmr_option opt)
Shuffles key-value pairs to the appropriate destination ranks.
int kmr_free_kvs(KMR_KVS *kvs)
Releases a key-value stream (type KMR_KVS).
Handy Copy of a Key-Value Field.
int kmr_fin(void)
Clears the environment.
int kmr_get_element_count(KMR_KVS *kvs, long *v)
Gets the total number of key-value pairs.
#define kmr_init()
Sets up the environment.
int kmr_free_context(KMR *mr)
Releases a context created with kmr_create_context().
KMR * kmr_create_context(const MPI_Comm comm, const MPI_Info conf, const char *name)
Makes a new KMR context (a context has type KMR).