-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathclustering.cpp
140 lines (115 loc) · 3.34 KB
/
clustering.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
#include <iostream>
#include <map>
#include <Python.h>
extern "C" {
#include "config.h"
#include "clustering.h"
}
typedef std::map<u32, u32> ClusterResult;
using namespace std;
u8 clustering_worker(string, u32, ClusterResult &);
PyObject *moduleName = NULL;
PyObject *pModule = NULL;
PyObject *pv = NULL;
void clustering_queue(u32 n_clusters)
{
ClusterResult cr;
u8 succeed = clustering_worker("/home/binzhang/fuzz/test/libpng/bitmaps", n_clusters, cr);
if (!succeed) {
printf("Clustering failed!\n");
return;
}
FILE *f_cluster = fopen("/tmp/clustering.res", "w");
if (!f_cluster) {
printf("Cannot open clutering file!\n");
return;
}
auto it = cr.begin(), end = cr.end();
for (; it != end; it++) {
char map[128];
memset(map, 0, 128);
sprintf(map, "%u:%d\n", it->first, it->second);
fwrite(map, sizeof(u8), strlen(map), f_cluster);
}
fclose(f_cluster);
}
void init_python_env()
{
u8 verbose = 0;
#if 0
verbose = 1;
#endif
Py_Initialize();
string path = "./bitmap_clustering";
string chdir_cmd = string("sys.path.append(\"") + path + "\")";
const char* cstr_cmd = chdir_cmd.c_str();
PyRun_SimpleString("import sys");
PyRun_SimpleString("import os");
PyRun_SimpleString(cstr_cmd);
// Disable python's output
PyRun_SimpleString("fnull = open('/dev/null','a')");
PyRun_SimpleString("sys.stdout = fnull");
PyRun_SimpleString("sys.stderr = fnull");
moduleName = PyString_FromString("clustering_worker");
pModule = PyImport_Import(moduleName);
if (!pModule)
{
cout << "[ERROR] Python get module failed." << endl;
exit(0);
}
if (verbose)
cout << "[INFO] Python get module succeed." << endl;
pv = PyObject_GetAttrString(pModule, "read_and_clustering");
if (!(pv) || !PyCallable_Check(pv))
{
cout << "[ERROR] Can't find funftion (read_and_clustering)" << endl;
exit(0);
}
cout << "[INFO] Get function (read_and_clustering) succeed." << endl;
}
void fini_python_env()
{
Py_INCREF(pv);
Py_INCREF(moduleName);
Py_INCREF(pModule);
Py_Finalize();
}
/* Real worker, return 1 if succeed. */
u8 clustering_worker(string bitmapDir, u32 nClusters, ClusterResult & cr)
{
u8 verbose = 0;
#if 1
verbose = 1;
#endif
static u8 init_flag = 0;
if (!init_flag) {
init_flag += 1;
init_python_env();
atexit(fini_python_env);
}
assert(pv);
PyObject* args = PyTuple_New(2);
PyObject* arg1 = PyString_FromString(bitmapDir.c_str());
PyObject* arg2 = PyInt_FromLong(nClusters);
PyTuple_SetItem(args, 0, arg1);
PyTuple_SetItem(args, 1, arg2);
PyObject* pRet = PyObject_CallObject(pv, args);
/*
* Python function `clustering` returns a map {cksum: belongs_to},
* then we can collect it to a map in c++.
*/
if (pRet)
{
PyObject *pCksum, *pBelongsTo;
Py_ssize_t pos = 0;
while (PyDict_Next(pRet, &pos, &pCksum, &pBelongsTo)) {
string str_cksum = PyString_AsString(pCksum);
u32 cksum = atoi(str_cksum.c_str());
u32 belongs_to = PyInt_AsLong(pBelongsTo);
cr.insert(std::make_pair(cksum, belongs_to));
Py_DECREF(pCksum);
Py_DECREF(pBelongsTo);
}
}
return 1;
}