-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjump.cpp
174 lines (148 loc) · 4.91 KB
/
jump.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#include "jump_matrix.h"
#include <thread>
#include <memory>
#include <sstream>
#include <optional>
#include <filesystem>
using namespace std;
void wait()
{
std::cout << "press a key...";
char c;
std::cin >> c;
}
enum GenType { undef, mt, sfmt };
template <GenType>
struct GenTraits;
template <>
struct GenTraits<mt>
{
typedef MT19937Matrix matrix_t;
static const size_t power2 = 0;
};
template <>
struct GenTraits<sfmt>
{
typedef SFMT19937Matrix matrix_t;
static const size_t power2 = 2;
};
template <typename Matrix>
void square(const Matrix& src, Matrix& dst, std::vector<typename Matrix::buffer_t>& buffers)
{
auto start = std::chrono::system_clock::now();
dst.square(src, buffers);
auto end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = end - start;
std::cout << "done in: " << std::fixed << std::setprecision(2) << elapsed_seconds.count() << "s" << std::endl;
}
const std::string extension = ".bits";
std::string mkFileName(const std::string& path, size_t n)
{
std::ostringstream os;
os << path << "F" << std::setw(5) << std::setfill('0') << n << extension;
return os.str();
}
void usage()
{
std::cerr
<< "Invalid command line arguments\n"
<< "Example:\n"
<< "jump -g generator [-j nthreads] [-p filepath] [-f savefrequency] [-s stopindex]\n"
<< " nthreads defaults to 1\n"
<< " filepath defaults to ./\n"
<< " savefrequency defaults to 100\n"
<< " generator must be one of {mt, sfmt}"
<< " stopindex: stops after saving the matrix with power >= stopIndex\n";
std::exit(-1);
}
template <GenType gen>
void run(const std::string& filepath, size_t nThreads, size_t saveFrequency, size_t stopIndex)
{
typename GenTraits<gen>::matrix_t f[2];
size_t lastComputed = GenTraits<gen>::power2;
for (const auto& entry : std::filesystem::directory_iterator(filepath)) {
if (std::filesystem::is_regular_file(entry) && entry.path().has_extension() && entry.path().extension().string() == extension) {
std::string s = entry.path().filename().string();
s = s.substr(1, s.length() - 1 - extension.length());
size_t n = atoi(s.c_str());
if (n > lastComputed)
lastComputed = n;
}
}
if (lastComputed == GenTraits<gen>::power2) {
std::cout << "initializing from base matrix: F^(2^" << GenTraits<gen>::power2 << ")\n";
}
else {
std::string fn = mkFileName(filepath, lastComputed);
std::cout << "initializing F^(2 ^ " << lastComputed << ") from file " << fn << "\n";
std::ifstream is(fn, ios::binary);
f[lastComputed % 2].fromBin(is);
}
std::cout << " ";
f[lastComputed % 2].printSparsity();
std::vector<typename GenTraits<gen>::matrix_t::buffer_t> buffers(nThreads);
for (size_t i = lastComputed + 1; i <= 19937 && (lastComputed < stopIndex); ++i) {
std::cout << "computing F^(2^" << i << ")\n";
size_t in = (i + 1) % 2;
size_t out = (i) % 2;
f[out].resetZero();
square(f[in], f[out], buffers);
std::cout << " ";
f[out].printSparsity();
if ((i % saveFrequency) == 0 || i > 19930) {
std::string fn = mkFileName(filepath, i);
std::cout << " saving file: " << fn << " ... ";
std::ofstream of(fn, ios::binary);
f[out].toBin(of);
of.close();
std::cout << "saved\n";
lastComputed = i;
}
}
}
int main(int argc, const char** argv)
{
// parse command line arguments
size_t nThreads = std::thread::hardware_concurrency();
std::string filepath = "./dat/";
std::string gentype;
size_t saveFrequency = 100;
size_t stopIndex = std::numeric_limits<size_t>::max();
if (argc % 2 == 0)
usage();
for (int i = 1; i < argc; i += 2) {
string key(argv[i]);
const char* value = argv[i + 1];
if (key == "-j") {
nThreads = atoi(value);
}
else if (key == "-p") {
filepath = value;
if (filepath.back() != '/')
filepath.push_back('/');
}
else if (key == "-g") {
gentype = value;
}
else if (key == "-f") {
saveFrequency = atoi(value);
}
else if (key == "-s") {
stopIndex = atoi(value);
}
else
usage();
}
std::cout << "nThreads = " << nThreads << "\n";
std::cout << "filepath = " << filepath << "\n";
std::cout << "savefrequency = " << saveFrequency << "\n";
std::cout << "generator = " << gentype << "\n";
std::cout << "stopindex = " << stopIndex << "\n";
if (gentype == "mt")
run<mt>(filepath, nThreads, saveFrequency, stopIndex);
if (gentype == "sfmt")
run<sfmt>(filepath, nThreads, saveFrequency, stopIndex);
else
usage();
return 0;
}