28 #include <sys/types.h> 37 #define READBUFSIZ 1048576 48 char *dirname = (
char *)p;
52 DIR *dir = opendir(dirname);
54 for (
struct dirent *dp = readdir(dir); dp != NULL; dp = readdir(dir)) {
55 assert(strlen(dp->d_name) > 0);
56 if (dp->d_name[0] ==
'.') {
64 char **files = (
char **)malloc(
sizeof(
char *) * (size_t)file_cnt);
65 dir = opendir(dirname);
68 for (
struct dirent *dp = readdir(dir); dp != NULL; dp = readdir(dir)) {
69 assert(strlen(dp->d_name) > 0);
70 if (dp->d_name[0] ==
'.') {
73 files[fidx] = (
char *)malloc(
sizeof(
char) * PATHLEN);
74 snprintf(files[fidx], PATHLEN,
"%s/%s", dirname, dp->d_name);
80 for (
int i = 0; i < file_cnt; i++) {
81 char *first = files[i];
82 char *second = files[(i + 1) % file_cnt];
83 size_t first_len = strlen(first);
84 size_t second_len = strlen(second);
85 long vlen = (long)first_len + (
long)second_len + 2;
86 char *val = (
char *)malloc(
sizeof(
char) * (size_t)vlen);
87 strncpy(val, first, first_len);
88 val[first_len] =
'\0';
89 strncpy(&val[first_len + 1], second, second_len);
91 struct kmr_kv_box nkv = { .klen =
sizeof(long),
92 .vlen = (
int)(vlen * (long)
sizeof(
char)),
100 for (
int i = 0; i < file_cnt; i++) {
115 double time_diff = 0.0;
116 char *filename = (
char *)kv.v.p;
117 for (
char *pp = filename + 1; pp < kv.v.p + kv.vlen; pp++) {
120 char buf[READBUFSIZ];
121 double t1 = MPI_Wtime();
122 FILE *fp = fopen(filename,
"r");
126 siz = fread(buf,
sizeof(
char), READBUFSIZ, fp);
129 double t2 = MPI_Wtime();
130 time_diff += t2 - t1;
136 struct kmr_kv_box nkv = { .klen =
sizeof(long),
137 .vlen =
sizeof(
double),
148 summarize(
const struct kmr_kv_box kv[],
const long n,
152 for (
long i = 0; i < n; i++) {
153 printf(
"%f\n", kv[i].v.d);
156 double avg = sum / (double)n;
157 printf(
"Average read time: %f\n", avg);
167 check_directory(
const char *path)
170 int ret = stat(path, &s);
174 if (S_ISDIR(s.st_mode)) {
184 fprintf(stderr,
"Specify a directory.\n\n");
185 fprintf(stderr,
"Usage: ./a.out [-s] DIRECTORY\n");
186 fprintf(stderr,
" -s : perform shuffle to distribute files.\n");
192 main(
int argc,
char **argv)
196 char *dirname = NULL;
198 MPI_Init(&argc, &argv);
199 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
200 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
202 if (!(argc == 2 || argc == 3)) {
206 }
else if (argc == 2) {
208 if (!check_directory(dirname)) {
213 }
else if (argc == 3) {
214 int ret = strcmp(argv[1],
"-s");
219 if (!check_directory(dirname)) {
232 kmr_map_once(kvs_infiles, (
void *)dirname, kmr_noopt, 1, read_files);
244 kmr_map(kvs_targets, kvs_times, NULL, kmr_noopt, benchmark);
249 kmr_reduce(kvs_all_times, NULL, NULL, kmr_noopt, summarize);
Key-Value Stream (abstract).
#define kmr_reduce(KVI, KVO, ARG, OPT, R)
Reduces key-value pairs.
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_assign_file(KMR_KVS *kvi, KMR_KVS *kvo, struct kmr_option opt)
Assigns files to ranks based on data locality.
#define kmr_map(KVI, KVO, ARG, OPT, M)
Maps simply.
Handy Copy of a Key-Value Field.
int kmr_fin(void)
Clears the environment.
#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).