Skip to content

Commit e6f09cc

Browse files
authored
Merge pull request #6 from GraphBLAS/add-benchmarks
Add benchmarks checking Binsparse performance
2 parents 293228b + 7ced41c commit e6f09cc

File tree

11 files changed

+401
-22
lines changed

11 files changed

+401
-22
lines changed

examples/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ add_example(mtx2bsp)
1111
add_example(bsp2mtx)
1212
add_example(check_equivalence)
1313
add_example(bsp-ls)
14+
add_example(benchmark_read)
15+
add_example(benchmark_write)

examples/benchmark_read.c

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#include <binsparse/binsparse.h>
2+
#include <stdlib.h>
3+
#include <time.h>
4+
5+
double gettime() {
6+
struct timespec time;
7+
clock_gettime(CLOCK_MONOTONIC, &time);
8+
return ((double) time.tv_sec) + ((double) 1e-9) * time.tv_nsec;
9+
}
10+
11+
int compar(const void* a, const void* b) {
12+
double x = *((const double*) a);
13+
double y = *((const double*) b);
14+
15+
double diff = x - y;
16+
17+
if (diff > 0) {
18+
return 1;
19+
} else if (diff < 0) {
20+
return -1;
21+
} else {
22+
return 0;
23+
}
24+
}
25+
26+
double compute_variance(double* x, size_t n) {
27+
double sum = 0;
28+
29+
for (size_t i = 0; i < n; i++) {
30+
sum += x[i];
31+
}
32+
33+
double mean = sum / n;
34+
35+
double sum_of_squares = 0;
36+
for (size_t i = 0; i < n; i++) {
37+
sum_of_squares += (x[i] - mean) * (x[i] - mean);
38+
}
39+
40+
return sum_of_squares / (n - 1);
41+
}
42+
43+
void flush_cache() {
44+
#ifdef __APPLE__
45+
system("bash -c \"sync && sudo purge\"");
46+
#elif __linux__
47+
system("bash -c \"sync\" && sudo echo 3 > /proc/sys/vm/drop_caches");
48+
#else
49+
static_assert(false);
50+
#endif
51+
}
52+
53+
int main(int argc, char** argv) {
54+
if (argc < 2) {
55+
fprintf(stderr, "usage: ./benchmark_read [file_name.h5]\n");
56+
return 1;
57+
}
58+
59+
char* file_name = argv[1];
60+
61+
printf("Opening %s\n", file_name);
62+
63+
const int num_trials = 10;
64+
65+
double durations[num_trials];
66+
67+
size_t nbytes = 0;
68+
69+
for (size_t i = 0; i < num_trials; i++) {
70+
flush_cache();
71+
double begin = gettime();
72+
bsp_matrix_t mat = bsp_read_matrix(file_name, NULL);
73+
double end = gettime();
74+
durations[i] = end - begin;
75+
nbytes = bsp_matrix_nbytes(mat);
76+
bsp_destroy_matrix_t(mat);
77+
}
78+
79+
printf("[");
80+
for (size_t i = 0; i < num_trials; i++) {
81+
printf("%lf", durations[i]);
82+
if (i + 1 < num_trials) {
83+
printf(", ");
84+
}
85+
}
86+
printf("]\n");
87+
88+
qsort(durations, num_trials, sizeof(double), compar);
89+
90+
double variance = compute_variance(durations, num_trials);
91+
92+
printf("Read file in %lf seconds\n", durations[num_trials / 2]);
93+
94+
printf("Variance is %lf seconds, standard devication is %lf seconds\n",
95+
variance, sqrt(variance));
96+
97+
double gbytes = ((double) nbytes) / 1024 / 1024 / 1024;
98+
double gbytes_s = gbytes / durations[num_trials / 2];
99+
100+
printf("Achieved %lf GiB/s\n", gbytes_s);
101+
102+
printf("[");
103+
for (size_t i = 0; i < num_trials; i++) {
104+
printf("%lf", durations[i]);
105+
if (i + 1 < num_trials) {
106+
printf(", ");
107+
}
108+
}
109+
printf("]\n");
110+
111+
return 0;
112+
}

examples/benchmark_write.c

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
#include <binsparse/binsparse.h>
2+
#include <stdlib.h>
3+
#include <time.h>
4+
5+
double gettime() {
6+
struct timespec time;
7+
clock_gettime(CLOCK_MONOTONIC, &time);
8+
return ((double) time.tv_sec) + ((double) 1e-9) * time.tv_nsec;
9+
}
10+
11+
int compar(const void* a, const void* b) {
12+
double x = *((const double*) a);
13+
double y = *((const double*) b);
14+
15+
double diff = x - y;
16+
17+
if (diff > 0) {
18+
return 1;
19+
} else if (diff < 0) {
20+
return -1;
21+
} else {
22+
return 0;
23+
}
24+
}
25+
26+
double compute_variance(double* x, size_t n) {
27+
double sum = 0;
28+
29+
for (size_t i = 0; i < n; i++) {
30+
sum += x[i];
31+
}
32+
33+
double mean = sum / n;
34+
35+
double sum_of_squares = 0;
36+
for (size_t i = 0; i < n; i++) {
37+
sum_of_squares += (x[i] - mean) * (x[i] - mean);
38+
}
39+
40+
return sum_of_squares / (n - 1);
41+
}
42+
43+
void flush_cache() {
44+
#ifdef __APPLE__
45+
system("bash -c \"sync && sudo purge\"");
46+
#elif __linux__
47+
system("bash -c \"sync\" && sudo echo 3 > /proc/sys/vm/drop_caches");
48+
#else
49+
static_assert(false);
50+
#endif
51+
}
52+
53+
void flush_writes() {
54+
#ifdef __APPLE__
55+
system("bash -c \"sync\"");
56+
#elif __linux__
57+
system("bash -c \"sync\"");
58+
#else
59+
static_assert(false);
60+
#endif
61+
}
62+
63+
void delete_file(char* file_name) {
64+
char command[2048];
65+
snprintf(command, 2047, "rm %s", file_name);
66+
system(command);
67+
}
68+
69+
int main(int argc, char** argv) {
70+
if (argc < 2) {
71+
fprintf(stderr, "usage: ./benchmark_read [file_name.h5] [optional: "
72+
"compression_level]\n");
73+
return 1;
74+
}
75+
76+
char* file_name = argv[1];
77+
78+
int compression_level = 0;
79+
80+
if (argc >= 3) {
81+
compression_level = atoi(argv[2]);
82+
}
83+
84+
printf("Opening %s\n", file_name);
85+
86+
const int num_trials = 10;
87+
88+
double durations[num_trials];
89+
90+
bsp_matrix_t mat = bsp_read_matrix(file_name, NULL);
91+
size_t nbytes = bsp_matrix_nbytes(mat);
92+
93+
char output_filename[2048];
94+
strncpy(output_filename, "benchmark_write_file_n.h5", 2047);
95+
96+
for (size_t i = 0; i < num_trials; i++) {
97+
flush_cache();
98+
output_filename[21] = '0' + i;
99+
printf("Writing to file %s\n", output_filename);
100+
101+
double begin = gettime();
102+
bsp_write_matrix(output_filename, mat, NULL, NULL, compression_level);
103+
flush_writes();
104+
double end = gettime();
105+
durations[i] = end - begin;
106+
delete_file(output_filename);
107+
}
108+
109+
printf("[");
110+
for (size_t i = 0; i < num_trials; i++) {
111+
printf("%lf", durations[i]);
112+
if (i + 1 < num_trials) {
113+
printf(", ");
114+
}
115+
}
116+
printf("]\n");
117+
118+
qsort(durations, num_trials, sizeof(double), compar);
119+
120+
double variance = compute_variance(durations, num_trials);
121+
122+
printf("Wrote file in %lf seconds\n", durations[num_trials / 2]);
123+
124+
printf("Variance is %lf seconds, standard devication is %lf seconds\n",
125+
variance, sqrt(variance));
126+
127+
double gbytes = ((double) nbytes) / 1024 / 1024 / 1024;
128+
double gbytes_s = gbytes / durations[num_trials / 2];
129+
130+
printf("Achieved %lf GiB/s\n", gbytes_s);
131+
132+
printf("[");
133+
for (size_t i = 0; i < num_trials; i++) {
134+
printf("%lf", durations[i]);
135+
if (i + 1 < num_trials) {
136+
printf(", ");
137+
}
138+
}
139+
printf("]\n");
140+
141+
return 0;
142+
}

examples/mtx2bsp.c

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
#include <binsparse/binsparse.h>
22
#include <stdio.h>
33

4+
#include <time.h>
5+
6+
double gettime() {
7+
struct timespec time;
8+
clock_gettime(CLOCK_MONOTONIC, &time);
9+
return ((double) time.tv_sec) + ((double) 1e-9) * time.tv_nsec;
10+
}
11+
412
int main(int argc, char** argv) {
513

614
if (argc < 3) {
715
printf("usage: ./mtx2bsp [input.mtx] [output.bsp.h5]:[optional: group] "
8-
"[optional: format]\n");
16+
"[optional: format] [optional: compression level 0-9]\n");
917
printf("\n");
1018
printf("Description: Convert a Matrix Market file to a Binsparse HDF5 "
1119
"file.\n");
@@ -29,6 +37,13 @@ int main(int argc, char** argv) {
2937
"example: ./mtx2bsp chesapeake.mtx chesapeake.bsp.h5:chesapeake CSR\n");
3038
printf(" - Same as previous example, but matrix will use CSR "
3139
"format.\n");
40+
printf("example: ./mtx2bsp chesapeake.mtx chesapeake.bsp.h5:chesapeake CSR "
41+
"5\n");
42+
printf(" - Same as previous example, but will use GZip compression "
43+
"level 5.\n");
44+
printf(" 0 is no compression, 1-9 correspond to GZip compression "
45+
"levels.\n");
46+
printf(" Default is 9.\n");
3247
return 1;
3348
}
3449

@@ -49,6 +64,12 @@ int main(int argc, char** argv) {
4964
format_name = argv[3];
5065
}
5166

67+
int compression_level = 9;
68+
69+
if (argc >= 5) {
70+
compression_level = atoi(argv[4]);
71+
}
72+
5273
char* input_file_extension = bsp_get_file_extension(input_fname);
5374
char* output_file_extension = bsp_get_file_extension(output_fname);
5475

@@ -90,32 +111,57 @@ int main(int argc, char** argv) {
90111
printf("File has very long comments, not printing.\n");
91112
}
92113

114+
printf("Printing with compression level %d.\n", compression_level);
115+
93116
cJSON* user_json = cJSON_CreateObject();
94117

95118
assert(user_json != NULL);
96119

97120
cJSON_AddStringToObject(user_json, "comment", m.comments);
98121

99122
printf(" === Reading file... ===\n");
123+
double begin = gettime();
100124
bsp_matrix_t matrix = bsp_mmread(input_fname);
125+
double end = gettime();
101126
printf(" === Done reading. ===\n");
102127

128+
double duration = end - begin;
129+
printf("%lf seconds reading Matrix Market file...\n", duration);
130+
103131
if (perform_suitesparse_declamping) {
132+
begin = gettime();
104133
bsp_matrix_declamp_values(matrix);
134+
end = gettime();
135+
duration = end - begin;
136+
printf("%lf seconds declamping...\n", duration);
105137
}
106138

139+
begin = gettime();
107140
matrix = bsp_matrix_minimize_values(matrix);
141+
end = gettime();
142+
duration = end - begin;
143+
printf("%lf seconds minimizing values...\n", duration);
108144

109145
if (format != BSP_COOR) {
146+
begin = gettime();
110147
bsp_matrix_t converted_matrix = bsp_convert_matrix(matrix, format);
111148
bsp_destroy_matrix_t(matrix);
112149
matrix = converted_matrix;
150+
end = gettime();
151+
duration = end - begin;
152+
printf("%lf seconds converting to %s format...\n", duration,
153+
bsp_get_matrix_format_string(format));
113154
}
114155

115156
bsp_print_matrix_info(matrix);
116157

117158
printf(" === Writing to %s... ===\n", output_fname);
118-
bsp_write_matrix(output_fname, matrix, group_name, user_json);
159+
begin = gettime();
160+
bsp_write_matrix(output_fname, matrix, group_name, user_json,
161+
compression_level);
162+
end = gettime();
163+
duration = end - begin;
164+
printf("%lf seconds writing Binsparse file...\n", duration);
119165
printf(" === Done writing. ===\n");
120166

121167
bsp_destroy_matrix_t(matrix);

examples/simple_matrix_write.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ int main(int argc, char** argv) {
1515
printf("%d, %d: %f\n", rowind[i], colind[i], values[i]);
1616
}
1717

18-
bsp_write_matrix("test.hdf5", mat, NULL, NULL);
18+
bsp_write_matrix("test.hdf5", mat, NULL, NULL, 9);
1919

2020
return 0;
2121
}

examples/simple_write.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ int main(int argc, char** argv) {
1313
bsp_array_write(array, i, i);
1414
}
1515

16-
bsp_write_array(f, "test", array);
16+
bsp_write_array(f, "test", array, 0);
1717

1818
H5Fclose(f);
1919
bsp_destroy_array_t(array);

0 commit comments

Comments
 (0)