Skip to content

Commit fcda222

Browse files
authored
Use CLI11 parser for all native benchmarks (#4)
This PR attempts to resolve some inconsistencies in argument parsing in native benchmarks, and uses CLI11 parser globally for native benchmarks. It also refactors distances, linear/ridge regression, and kmeans benchmarks to use some common code for consistency. * Add CLI11 header to repo * Combine cosine and correlation distances into one file * Use CLI11 in distances, linear/ridge regression, kmeans benches * Pass around results of benchmarks for verification if needed (as NumericTablePtr or ResultPtr or std::tuple) * General refactoring of benches converted to use CLI11 for easier readability
1 parent 2bb768e commit fcda222

16 files changed

+5214
-562
lines changed

Makefile

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,16 @@ native: data
3737
@echo "# Compiling native benchmarks"
3838
$(MAKE) -C native
3939
@echo "# Running native benchmarks"
40-
native/bin/cosine $(BATCH) $(HOST) native cosine_distances \
41-
$(NUM_THREADS) double $(DISTANCES_SIZE)
42-
native/bin/correlation $(BATCH) $(HOST) native correlation_distances \
43-
$(NUM_THREADS) double $(DISTANCES_SIZE)
44-
native/bin/ridge $(BATCH) $(HOST) native ridge \
45-
$(NUM_THREADS) double $(REGRESSION_SIZE)
46-
native/bin/linear $(BATCH) $(HOST) native linear \
47-
$(NUM_THREADS) double $(REGRESSION_SIZE)
48-
native/bin/kmeans $(BATCH) $(HOST) native kmeans \
49-
$(NUM_THREADS) double $(KMEANS_SIZE) $(DATA_DIR) $(MULTIPLIER)
40+
native/bin/distances --batch "$(BATCH)" --arch "$(HOST)" \
41+
--num-threads "$(NUM_THREADS)" --size "$(DISTANCES_SIZE)"
42+
native/bin/ridge --batch "$(BATCH)" --arch "$(HOST)" \
43+
--num-threads "$(NUM_THREADS)" --size "$(REGRESSION_SIZE)"
44+
native/bin/linear --batch "$(BATCH)" --arch "$(HOST)" \
45+
--num-threads "$(NUM_THREADS)" --size "$(REGRESSION_SIZE)"
46+
native/bin/kmeans --batch "$(BATCH)" --arch "$(HOST)" \
47+
--num-threads "$(NUM_THREADS)" --data-multiplier "$(MULTIPLIER)" \
48+
--filex $(KMEANS_DATA) --filei $(basename $(KMEANS_DATA)).init.npy \
49+
--filet $(basename $(KMEANS_DATA)).tol.npy
5050
native/bin/two_class_svm \
5151
--fileX data/two/X-$(SVM_SAMPLES)x$(SVM_FEATURES).npy \
5252
--fileY data/two/y-$(SVM_SAMPLES)x$(SVM_FEATURES).npy \

native/CLI11

Submodule CLI11 deleted from 899100c

native/Makefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
#
33
# SPDX-License-Identifier: MIT
44

5-
BENCHMARKS += correlation cosine kmeans linear ridge \
5+
BENCHMARKS += distances kmeans linear ridge pca \
66
two_class_svm multi_class_svm log_reg_lbfgs \
77
decision_forest_regr decision_forest_clsf
88
CXXSRCS = $(addsuffix _bench.cpp,$(BENCHMARKS))
99

1010
CXX = icc
11-
CXXFLAGS += -m64 -fPIC -fp-model strict -O3 -g -fomit-frame-pointer \
11+
CXXFLAGS += -m64 -fPIC -fp-model strict -O3 -fomit-frame-pointer \
1212
-xSSE4.2 -axCORE-AVX2,COMMON-AVX512
13-
CXXFLAGS += -std=c++14
13+
CXXFLAGS += -std=c++14 -g
1414
LDFLAGS += -ldaal_core -ldaal_thread -Wl,-rpath,$(CONDA_PREFIX)/lib
15-
CXXINCLUDE += CLI11/include
15+
CXXINCLUDE += include
1616

1717
ifneq ($(CONDA_PREFIX),)
1818
LDFLAGS += -L"$(CONDA_PREFIX)/lib"

native/common.hpp

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
#pragma once
2+
3+
#include <string>
4+
#include <vector>
5+
#include <iostream>
6+
#include <chrono>
7+
8+
#include "CLI11.hpp"
9+
#include "daal.h"
10+
11+
namespace dm = daal::data_management;
12+
namespace ds = daal::services;
13+
namespace da = daal::algorithms;
14+
15+
/*
16+
* Parse a size argument as given to the command-line options.
17+
* This consists of each element of the size, delimited by
18+
* a 'x' or ','.
19+
*
20+
* Parameters
21+
* ----------
22+
* in : std::string
23+
* String to parse
24+
* size : std::vector<int> &size
25+
* Vector to which we should output size values
26+
*/
27+
void parse_size(std::string in, std::vector<int> &size) {
28+
29+
std::stringstream tmp(in);
30+
int i;
31+
32+
while (tmp >> i) {
33+
size.push_back(i);
34+
char c = tmp.peek();
35+
if (c == 'x' || c == ',')
36+
tmp.ignore();
37+
}
38+
39+
}
40+
41+
42+
/*
43+
* Terminate the program with an error message if the number of dimensions
44+
* in the given size vector does not match the expected number of dimensions.
45+
*
46+
* Parameters
47+
* ----------
48+
* size : std::vector<int> &size
49+
* Vector to check
50+
* expected : int
51+
* Number of dimensions we expect
52+
*/
53+
void check_dims(std::vector<int> &size, int expected) {
54+
55+
if (size.size() != expected) {
56+
std::cerr << "error: expected " << expected << " dimensions in size "
57+
<< "but got " << size.size();
58+
std::exit(1);
59+
}
60+
61+
}
62+
63+
64+
/*
65+
* Try to set DAAL's number of threads to the given number of threads,
66+
* and returns the actual number of threads DAAL will use.
67+
*
68+
* Parameters
69+
* ----------
70+
* num_threads : int
71+
* Number of threads we ask DAAL to use
72+
*
73+
* Returns
74+
* -------
75+
* int
76+
* Number of threads DAAL says it will use
77+
*/
78+
int set_threads(int num_threads) {
79+
80+
if (num_threads > 0)
81+
ds::Environment::getInstance()->setNumberOfThreads(num_threads);
82+
83+
return ds::Environment::getInstance()->getNumberOfThreads();
84+
85+
}
86+
87+
88+
/*
89+
* Time the given function for the specified number of repetitions,
90+
* returning a pair of a vector of durations and the LAST result.
91+
*/
92+
template <typename T>
93+
std::pair<std::vector<std::chrono::duration<double>>, T>
94+
time_vec(std::function<T()> func, int reps) {
95+
96+
std::vector<std::chrono::duration<double>> vec;
97+
T result;
98+
for (int i = 0; i < reps; i++) {
99+
auto t0 = std::chrono::high_resolution_clock::now();
100+
result = func();
101+
auto t1 = std::chrono::high_resolution_clock::now();
102+
vec.push_back(t1 - t0);
103+
}
104+
return std::make_pair(vec, result);
105+
106+
}
107+
108+
109+
/*
110+
* Time the given function for the specified number of repetitions,
111+
* returning a pair of the minimum duration and the LAST result.
112+
*/
113+
template <typename T>
114+
std::pair<double, T> time_min(std::function<T()> func, int reps) {
115+
116+
auto pair = time_vec(func, reps);
117+
auto times = pair.first;
118+
double time = std::min_element(times.begin(), times.end())->count();
119+
120+
return std::make_pair(time, pair.second);
121+
122+
}
123+
124+
125+
/*
126+
* Create a DAAL HomogenNumericTable from an array in memory.
127+
*/
128+
template <typename T>
129+
dm::NumericTablePtr make_table(T *data, size_t rows, size_t cols) {
130+
131+
return dm::HomogenNumericTable<T>::create(data, cols, rows);
132+
133+
}
134+
135+
136+
/*
137+
* Generate an array of random numbers.
138+
*/
139+
double *gen_random(size_t n) {
140+
141+
double *x = new double[n];
142+
for (size_t i = 0; i < n; i++)
143+
x[i] = (double) rand() / RAND_MAX;
144+
return x;
145+
146+
}
147+
148+
149+
void add_common_args(CLI::App &app,
150+
std::string &batch, std::string &arch,
151+
std::string &prefix, int &num_threads,
152+
bool &header, bool &verbose) {
153+
154+
batch = "?";
155+
app.add_option("-b,--batch", batch, "Batch ID, for bookkeeping");
156+
157+
arch = "?";
158+
app.add_option("-a,--arch", arch, "Machine architecture, for bookkeeping");
159+
160+
prefix = "Native-C";
161+
app.add_option("-p,--prefix", prefix, "Prefix string, for bookkeeping");
162+
163+
num_threads = 0;
164+
app.add_option("-n,--num-threads", num_threads, "Number of threads for DAAL to use", true);
165+
166+
header = false;
167+
app.add_flag("--header", header, "Output CSV header");
168+
169+
verbose = false;
170+
app.add_flag("--verbose", header, "Output extra debug messages");
171+
172+
}
173+
174+

native/correlation_bench.cpp

Lines changed: 0 additions & 104 deletions
This file was deleted.

0 commit comments

Comments
 (0)