forked from hxim/paq8px
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPredictor.cpp
114 lines (109 loc) · 3.26 KB
/
Predictor.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
#include "Predictor.hpp"
Predictor::Predictor(Shared* const sh) : shared(sh), models(sh), contextModel(sh, models), sse(sh), pr(2048) {
shared->reset();
//initiate pre-training
if((shared->options & OPTION_TRAINTXT) != 0U ) {
trainText("english.dic", 3);
trainText("english.exp", 1);
}
if((shared->options & OPTION_TRAINEXE) != 0U ) {
trainExe();
}
}
auto Predictor::p() -> int {
// predict
pr = contextModel.p();
// SSE Stage
pr = sse.p(pr);
return pr;
}
void Predictor::update(uint8_t y) {
// update global context: y, pos, bitPosition, c0, c4, c8, buf
shared->update(y);
shared->State.misses = shared->State.misses<<1 | static_cast<uint64_t>((pr >> 11U) != y);
}
void Predictor::trainText(const char *const dictionary, int iterations) {
NormalModel &normalModel = models.normalModel();
WordModel &wordModel = models.wordModel();
DummyMixer mDummy(shared,
NormalModel::MIXERINPUTS + WordModel::MIXERINPUTS,
NormalModel::MIXERCONTEXTS + WordModel::MIXERCONTEXTS,
NormalModel::MIXERCONTEXTSETS + WordModel::MIXERCONTEXTSETS);
shared->State.blockType = TEXT;
INJECT_SHARED_pos
INJECT_SHARED_blockPos
assert(pos == 0 && blockPos == 0);
FileDisk f;
printf("Pre-training models with text...");
OpenFromMyFolder::anotherFile(&f, dictionary);
int c = 0;
int trainingByteCount = 0;
while( iterations-- > 0 ) {
f.setpos(0);
c = SPACE;
trainingByteCount = 0;
do {
trainingByteCount++;
uint8_t c1 = c == NEW_LINE ? SPACE : c;
if( c != CARRIAGE_RETURN ) {
for( int bpos = 0; bpos < 8; bpos++ ) {
normalModel.mix(mDummy); //update (train) model
#ifndef DISABLE_TEXTMODEL
wordModel.mix(mDummy); //update (train) model
#endif
mDummy.p();
int y = (c1 >> (7 - bpos)) & 1U;
shared->update(y);
}
}
// emulate a space before and after each word/expression
// reset models in between
if( c == NEW_LINE ) {
normalModel.reset();
#ifndef DISABLE_TEXTMODEL
wordModel.reset();
#endif
for( int bpos = 0; bpos < 8; bpos++ ) {
normalModel.mix(mDummy); //update (train) model
#ifndef DISABLE_TEXTMODEL
wordModel.mix(mDummy); //update (train) model
#endif
mDummy.p();
int y = (c1 >> (7 - bpos)) & 1U;
shared->update(y);
}
}
} while((c = f.getchar()) != EOF);
}
normalModel.reset();
#ifndef DISABLE_TEXTMODEL
wordModel.reset();
#endif
shared->reset();
printf(" done [%s, %d bytes]\n", dictionary, trainingByteCount);
f.close();
}
void Predictor::trainExe() {
ExeModel &exeModel = models.exeModel();
DummyMixer dummyM(shared, ExeModel::MIXERINPUTS, ExeModel::MIXERCONTEXTS, ExeModel::MIXERCONTEXTSETS);
INJECT_SHARED_pos
INJECT_SHARED_blockPos
assert(pos == 0 && blockPos == 0);
FileDisk f;
printf("Pre-training x86/x64 model...");
OpenFromMyFolder::myself(&f);
int c = 0;
int trainingByteCount = 0;
do {
trainingByteCount++;
for( uint32_t bpos = 0; bpos < 8; bpos++ ) {
exeModel.mix(dummyM); //update (train) model
dummyM.p();
int y = (c >> (7 - bpos)) & 1U;
shared->update(y);
}
} while((c = f.getchar()) != EOF);
printf(" done [%d bytes]\n", trainingByteCount);
f.close();
shared->reset();
}