2 #include "caffe2/core/init.h" 3 #include "caffe2/core/operator.h" 4 #include "caffe2/core/tensor.h" 5 #include "caffe2/core/timer.h" 6 #include "caffe2/utils/proto_utils.h" 8 #define TEST_REAL_DATA 0 14 #define POPULATE_DATA(_n, _s, _l) do {\ 15 Blob* _blob = ws.CreateBlob((_n));\ 16 auto* _tensor = _blob->GetMutable<TensorCPU>();\ 17 _tensor->Resize((_s));\ 18 memcpy(_tensor->mutable_data<float>(), data_##_l, _tensor->nbytes());\ 22 #define POPULATE_DATA(_n, _s, _l) do {\ 23 Blob* _blob = ws.CreateBlob((_n));\ 24 auto* _tensor = _blob->GetMutable<TensorCPU>();\ 25 _tensor->Resize((_s));\ 26 memset(_tensor->mutable_data<float>(), 1, _tensor->nbytes());\ 37 void AddConstInput(
const vector<TIndex>& shape,
42 CPUContext context(option);
43 Blob* blob = ws->CreateBlob(name);
44 auto* tensor = blob->GetMutable<TensorCPU>();
45 tensor->Resize(shape);
46 math::Set<float, CPUContext>(tensor->size(), value,
47 tensor->mutable_data<
float>(),
51 void AddNoiseInput(
const vector<TIndex>& shape,
55 CPUContext context(option);
56 Blob* blob = ws->CreateBlob(name);
57 auto* tensor = blob->GetMutable<TensorCPU>();
58 tensor->Resize(shape);
60 math::RandGaussian<float, CPUContext>(
63 tensor->mutable_data<
float>(),
68 float snpe_run(
int iters, Workspace& ws) {
73 POPULATE_DATA(
"X_snpe", (caffe2::vector<caffe2::TIndex>{H, W, C}), hwc);
76 def.set_name(
"snpe_test");
78 def.add_input(
"X_snpe");
79 def.add_output(
"snpeout");
80 std::ostringstream model_buffer;
81 std::ifstream file(
"/data/local/tmp/squeeze_net.dlc", std::ios::in|std::ios::binary);
82 CAFFE_ENFORCE(file.is_open(),
"Couldn't open test model.");
83 model_buffer << file.rdbuf();
84 CAFFE_ENFORCE(model_buffer.str().length() > 0,
"Couldn't load model into string.");
85 def.add_arg()->CopyFrom(MakeArgument(
"model_buffer", model_buffer.str()));
87 unique_ptr<OperatorBase> op(CreateOperator(def, &ws));
91 for (
auto i = 0; i < iters; ++i) {
94 return timer.MicroSeconds();
97 float caffe2_run(
int iters, Workspace& ws) {
106 ReadProtoFromBinaryFile(
"/data/local/tmp/squeeze_init_net.pb", &init_net);
107 ReadProtoFromBinaryFile(
"/data/local/tmp/squeeze_predict_net.pb", &predict_net);
108 ws.RunNetOnce(init_net);
109 POPULATE_DATA(
"data", (caffe2::vector<caffe2::TIndex>{N, C, H, W}), chw);
110 predict_net.set_name(
"SqueezeNet");
111 ws.CreateNet(predict_net);
116 for (
auto i = 0; i < iters; ++i) {
117 ws.RunNet(
"SqueezeNet");
119 float us = timer.MicroSeconds();
121 OperatorDef copy_def;
122 copy_def.set_type(
"Copy");
123 copy_def.set_name(
"Copy");
124 copy_def.add_input(
"softmaxout");
125 copy_def.add_output(
"caffe2out");
126 unique_ptr<OperatorBase> copy_op(CreateOperator(copy_def, &ws));
133 int main(
int argc,
char** argv) {
138 std::cout <<
"Testing caffe2...";
139 float t_caffe2 = caffe2::caffe2_run(iters, ws);
140 std::cout <<
"done!\nTesting snpe...";
141 float t_snpe = caffe2::snpe_run(iters, ws);
142 std::cout <<
"done!\n";
149 CAFFE_ENFORCE(snpe_tensor.size() == caffe2_tensor.size(),
"Outputs are not the same!\n");
151 float total_diff = 0;
152 float KL_divergence = 0;
153 float JS_divergence = 0;
157 for (
auto i = 0; i < snpe_tensor.size(); ++i) {
158 auto Q = caffe2_tensor.data<
float>()[i];
159 auto P = snpe_tensor.data<
float>()[i];
164 auto diff = fabs(P - Q);
165 auto avg = P + Q / 2;
167 KL_divergence += P * log(P / Q);
168 JS_divergence += 0.5 * P * log(P / Q) + 0.5 * Q * log(Q / P);
171 if (diff / avg > 0.10 && avg > 0.01) {
172 std::cout <<
"Diff: " << diff <<
" (" << P <<
" vs " << Q <<
")\n";
176 float avg_diff = total_diff;
177 printf(
"Average difference is %f%%\n", avg_diff * 100);
178 printf(
"JS Divergence is %f\n", JS_divergence);
179 printf(
"KL Divergence is %f\n", KL_divergence);
180 printf(
"Predicted %d with %f%% confidence\n", max_index, max * 100);
182 printf (
"Caffe2: %f microseconds.\n", t_caffe2);
183 printf (
"SNPE: %f microseconds.\n", t_snpe);
184 printf (
"SNPE impl %fx faster\n", t_caffe2/t_snpe);
Blob is a general container that hosts a typed pointer.
bool GlobalInit(int *pargc, char ***pargv)
Initialize the global environment of caffe2.
Workspace is a class that holds all the related objects created during runtime: (1) all blobs...
const Blob * GetBlob(const string &name) const
Gets the blob with the given name as a const pointer.
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
const T & Get() const
Gets the const reference of the stored object.