diff --git a/CMakeLists.txt b/CMakeLists.txt index d76ac16aacd9a3c4aa666960a17cf1cc1988c752..a80c50067e06d4317d89fcfcca96e14837e4d09d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ option(USE_OPENMP "openmp support" OFF) project(paddle-mobile) option(DEBUGING "enable debug mode" ON) -option(USE_EXCEPTION "use std exception" OFF) +option(USE_EXCEPTION "use std exception" ON) option(LOG_PROFILE "log profile" OFF) # select the platform to build option(CPU "armv7 with neon" OFF) diff --git a/src/framework/cl/cl_engine.h b/src/framework/cl/cl_engine.h index ee671a1ff276b6597535a0f0bf20b02c46bf5eac..930e511957dc1cd1a2ca588e39d89c19d372bf19 100644 --- a/src/framework/cl/cl_engine.h +++ b/src/framework/cl/cl_engine.h @@ -52,7 +52,7 @@ class CLEngine { cl_context context, std::string file_name) { FILE *file = fopen(file_name.c_str(), "rb"); PADDLE_MOBILE_ENFORCE(file != nullptr, "can't open file: %s ", - filename.c_str()); + file_name.c_str()); fseek(file, 0, SEEK_END); int64_t size = ftell(file); PADDLE_MOBILE_ENFORCE(size > 0, "size is too small"); diff --git a/src/framework/cl/cl_half.cpp b/src/framework/cl/cl_half.cpp index 6554815c68dce8649adc9b78b696c226c00d1c3d..d511b950dc787e83439094ae8d9be76af817b4b0 100644 --- a/src/framework/cl/cl_half.cpp +++ b/src/framework/cl/cl_half.cpp @@ -488,7 +488,7 @@ static const uint8_t shifttable[512] = { 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0d}; half_t float2half(float f) { - uint32_t v = *reinterpret_cast(&f); + uint32_t v = *reinterpret_cast(&f); return basetable[(v >> 23) & 0x1ff] + ((v & 0x007fffff) >> shifttable[(v >> 23) & 0x1ff]); } @@ -496,5 +496,17 @@ half_t float2half(float f) { float half2float(half_t h) { uint32_t v = mantissatable[offsettable[h >> 10] + (h & 0x3ff)] + exponenttable[h >> 10]; - return *reinterpret_cast(&v); + return *reinterpret_cast(&v); +} + +void FloatArray2HalfArray(float *f_array, half_t *h_array, int count) { + for (int i = 0; i < count; ++i) { + h_array[i] = float2half(f_array[i]); + } +} + +void HalfArray2FloatArray(half_t *h_array, float *f_array, int count) { + for (int i = 0; i < count; ++i) { + f_array[i] = float2half(h_array[i]); + } } diff --git a/src/framework/cl/cl_half.h b/src/framework/cl/cl_half.h index 23ef236d72b1842620302bdef9eb0ab4a0a67e38..ee6e2c7621af2749c520e5a3b242a099c0c28f0e 100644 --- a/src/framework/cl/cl_half.h +++ b/src/framework/cl/cl_half.h @@ -18,4 +18,9 @@ limitations under the License. */ typedef uint16_t half_t; half_t float2half(float f); + float half2float(half_t h); + +void FloatArray2HalfArray(float *f_array, half_t *h_array, int count); + +void HalfArray2FloatArray(half_t *h_array, float *f_array, int count); diff --git a/src/framework/cl/cl_helper.h b/src/framework/cl/cl_helper.h index e611a209238070420d15caa456c426b7b3650b79..8ebbcc911a558e3acbc5f54914300ca8226f0b0a 100644 --- a/src/framework/cl/cl_helper.h +++ b/src/framework/cl/cl_helper.h @@ -18,6 +18,7 @@ limitations under the License. */ #include #include +#include "common/log.h" #include "framework/cl/cl_deleter.h" #include "framework/cl/cl_image.h" #include "framework/cl/cl_scope.h" @@ -32,11 +33,16 @@ class CLHelper { explicit CLHelper(CLScope *scope) : scope_(scope) {} void AddKernel(const std::string &kernel_name, const std::string &file_name) { + DLOG << " begin add kernel "; auto kernel = scope_->GetKernel(kernel_name, file_name); + DLOG << " add kernel ing "; kernels.emplace_back(std::move(kernel)); } - cl_kernel KernelAt(const int index) { return kernels[index].get(); } + cl_kernel KernelAt(const int index) { + DLOG << " kernel count: " << kernels.size(); + return kernels[index].get(); + } cl_command_queue CLCommandQueue() { return scope_->CommandQueue(); } diff --git a/src/framework/cl/cl_image.h b/src/framework/cl/cl_image.h index 7c80078ed6909c719e0e064dda8b6b41cd18cf69..d971ad2c9bd847190fcea76b92b5ae9a38fe75ef 100644 --- a/src/framework/cl/cl_image.h +++ b/src/framework/cl/cl_image.h @@ -17,7 +17,9 @@ limitations under the License. */ #include #include "CL/cl.h" + #include "framework/cl/cl_half.h" +#include "framework/cl/cl_tool.h" #include "framework/ddim.h" #include "framework/tensor.h" @@ -59,6 +61,7 @@ class CLImage { PADDLE_MOBILE_THROW_EXCEPTION( " empty image tensor data shouldn't have value"); } + DLOG << " init empty image "; InitCLImage(context, nullptr, dim); initialized_ = true; } @@ -98,7 +101,8 @@ class CLImage { T *data() const { if (initialized_) { PADDLE_MOBILE_THROW_EXCEPTION( - " cl image has initialized, tensor data has been deleted "); + " cl image has initialized, tensor data has been deleted, can't use " + "tensor data"); } return reinterpret_cast(tensor_data_); } @@ -115,6 +119,7 @@ class CLImage { private: void InitCLImage(cl_context context, float *tensor_data, const DDim &dim) { + DLOG << " tensor dim: " << dim; cl_image_format cf = {.image_channel_order = CL_RGBA, .image_channel_data_type = CL_HALF_FLOAT}; // NCHW -> [W * (C+3)/4, H * N] @@ -132,29 +137,23 @@ class CLImage { tensor_data_[i] = 0; } } - size_t N, C, H, W; - if (tensor_dims_.size() == 4) { - N = tensor_dims_[0]; - if (N < 0) { - N = 1; - } - C = tensor_dims_[1]; - H = tensor_dims_[2]; - W = tensor_dims_[3]; - width_of_one_block_ = W; - height_of_one_block_ = H; + size_t new_dims[] = {1, 1, 1, 1}; - } else if (tensor_dims_.size() == 1) { - N = 1; - C = tensor_dims_[0]; - H = 1; - W = 1; - - width_of_one_block_ = W; - height_of_one_block_ = H; + for (int j = 0; j < dim.size(); ++j) { + new_dims[4 - dim.size() + j] = dim[j]; } + size_t N, C, H, W; + + N = new_dims[0]; + C = new_dims[1]; + H = new_dims[2]; + W = new_dims[3]; + + width_of_one_block_ = W; + height_of_one_block_ = H; + size_t width = W * ((C + 3) / 4); size_t height = H * N; @@ -193,9 +192,12 @@ class CLImage { } } cl_int err; + DLOG << " image width: " << width; + DLOG << " image height: " << height; cl_image_ = clCreateImage2D( - context, // cl_context context - CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, // cl_mem_flags flags + context, // cl_context context + CL_MEM_READ_WRITE | + (imageData ? CL_MEM_COPY_HOST_PTR : 0), // cl_mem_flags flags &cf, // const cl_image_format *image_format width, // size_t image_width height, // size_t image_height @@ -205,6 +207,7 @@ class CLImage { if (err != CL_SUCCESS) { // TODO(HaiPeng): error handling + CL_CHECK_ERRORS(err); PADDLE_MOBILE_THROW_EXCEPTION(" create image 2d error "); } } @@ -222,9 +225,15 @@ class CLImage { cl_context context_; }; -void TensorToCLImage(Tensor *tensor, CLImage *image,cl_command_queue commandQueue); +void TensorToCLImage(Tensor *tensor, CLImage *image, + cl_command_queue commandQueue); + +void CLImageToTensor(CLImage *image, Tensor *tensor, + cl_command_queue commandQueue); -void CLImageToTensor(CLImage *image, Tensor *tensor,cl_command_queue commandQueue); +#ifdef PADDLE_MOBILE_DEBUG +Print &operator<<(Print &printer, const CLImage &image); +#endif } // namespace framework } // namespace paddle_mobile diff --git a/src/framework/cl/cl_scope.h b/src/framework/cl/cl_scope.h index 24757db138a2dc62d82ffe837b939f50bcbfe0f1..2b2ad8367fdfeeb0ca6943ed18ea21e570596413 100644 --- a/src/framework/cl/cl_scope.h +++ b/src/framework/cl/cl_scope.h @@ -40,8 +40,11 @@ class CLScope { std::unique_ptr<_cl_kernel, CLKernelDeleter> GetKernel( const std::string &kernel_name, const std::string &file_name) { auto program = Program(file_name); + DLOG << " get program ~ "; std::unique_ptr<_cl_kernel, CLKernelDeleter> kernel( - clCreateKernel(program, kernel_name.c_str(), NULL)); + clCreateKernel(program, kernel_name.c_str(), &status_)); + CL_CHECK_ERRORS(status_); + DLOG << " create kernel ~ "; return std::move(kernel); } @@ -58,11 +61,12 @@ class CLScope { status_ = clBuildProgram(program.get(), 0, 0, "-cl-fast-relaxed-math", 0, 0); + CL_CHECK_ERRORS(status_); programs_[file_name] = std::move(program); - return program.get(); + return programs_[file_name].get(); } private: diff --git a/src/framework/executor.cpp b/src/framework/executor.cpp index 274a6a1d82bc1a8b939226a01d74f7b1172c81cd..f542cfeae315bd0dc1d89d5eb7c44cfaf52b4704 100644 --- a/src/framework/executor.cpp +++ b/src/framework/executor.cpp @@ -37,6 +37,8 @@ limitations under the License. */ #include "framework/cl/cl_image.h" #endif +int debug_to = 2; + namespace paddle_mobile { namespace framework { @@ -85,7 +87,7 @@ Executor::Executor(const framework::Program p, int batch_size, for (int i = 0; i < blocks.size(); ++i) { std::shared_ptr block_desc = blocks[i]; std::vector> ops = block_desc->Ops(); - for (int j = 0; j < ops.size(); ++j) { + for (int j = 0; j < debug_to; ++j) { std::shared_ptr op = ops[j]; DLOG << "create op: " << j << " " << op->Type(); auto op_base = framework::OpRegistry::CreateOp( @@ -414,7 +416,7 @@ std::shared_ptr Executor::Predict( } } #else - for (int i = 0; i < ops.size(); i++) { + for (int i = 0; i < debug_to; i++) { #ifdef PADDLE_MOBILE_PROFILE struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); @@ -428,6 +430,11 @@ std::shared_ptr Executor::Predict( #endif } #endif + + DLOG << " predict return nullptr"; + + return nullptr; + auto last_op = ops.rbegin(); auto output_map = (*last_op)->Outputs(); std::vector out_keys = (*last_op)->GetOutKeys(); @@ -647,13 +654,18 @@ std::vector::Ptype> Executor::Predict( const std::vector &input, const std::vector &dims) { framework::Tensor tensor(input, framework::make_ddim(dims)); std::shared_ptr output_tensor = Predict(tensor, 0); - Executor::Ptype *output_ptr = - output_tensor->data::Ptype>(); - std::vector::Ptype> result_vector; - for (int j = 0; j < output_tensor->numel(); ++j) { - result_vector.push_back(output_ptr[j]); + if (output_tensor != nullptr) { + Executor::Ptype *output_ptr = + output_tensor->data::Ptype>(); + std::vector::Ptype> result_vector; + for (int j = 0; j < output_tensor->numel(); ++j) { + result_vector.push_back(output_ptr[j]); + } + return result_vector; + } else { + DLOG << "return empty vector"; + return {}; } - return result_vector; } #ifdef PADDLE_MOBILE_FPGA diff --git a/src/framework/operator.cpp b/src/framework/operator.cpp index 68ce52114cedd4267ef7fa40f9043bc4363bda9f..1bfac97c8bed8fea68b7d24b495ef6f4a2009340 100644 --- a/src/framework/operator.cpp +++ b/src/framework/operator.cpp @@ -57,7 +57,10 @@ void OperatorBase::CheckAllInputOutputSet() const {} template void OperatorBase::Run() { + DLOG << " begin run " << type_; RunImpl(); + DLOG << " end run " << type_; + return; #ifdef PADDLE_MOBILE_DEBUG DLOG << "-------------" << type_ << "----------------------------"; vector input_keys = GetInputKeys(); @@ -100,8 +103,9 @@ void OperatorBase::Run() { #ifdef PADDLE_MOBILE_CL if (type_ == "fetch") { Tensor *tensor = vari->template GetMutable(); - if (tensor) + if (tensor) { DLOG << type_ << " output- " << key << "=" << tensor->dims(); + } } else { CLImage *cl_image = vari->template GetMutable(); // cl_command_queue commandQueue = diff --git a/src/operators/kernel/cl/cl_kernel/conv_kernel.cl b/src/operators/kernel/cl/cl_kernel/conv_kernel.cl index 2a5c823295c7562361433414cf35be81d2fbf00c..fa718a7326d8fcdd5fff614f8c67632c9badec3e 100644 --- a/src/operators/kernel/cl/cl_kernel/conv_kernel.cl +++ b/src/operators/kernel/cl/cl_kernel/conv_kernel.cl @@ -12,4 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -#include "conv_kernel.inc.cl" +//#include "conv_kernel.inc.cl" + +__kernel void conv_3x3() {} \ No newline at end of file diff --git a/src/operators/kernel/cl/conv_add_bn_relu_kernel.cpp b/src/operators/kernel/cl/conv_add_bn_relu_kernel.cpp index 29b13b6abc3943ff23ce3f5a98962ecb4d9c2d7a..f24b2d6f932955533c9e71148d64ad69f33d9d9f 100644 --- a/src/operators/kernel/cl/conv_add_bn_relu_kernel.cpp +++ b/src/operators/kernel/cl/conv_add_bn_relu_kernel.cpp @@ -24,9 +24,16 @@ namespace operators { template <> bool ConvAddBNReluKernel::Init( FusionConvAddBNReluParam *param) { + PADDLE_MOBILE_ENFORCE( + param->Filter()->dims()[2] == param->Filter()->dims()[3] && + param->Paddings()[0] == param->Paddings()[1], + "need equal"); + + param->Filter()->InitCLImage(cl_helper_.CLContext()); + param->Bias()->InitCLImage(cl_helper_.CLContext()); + // const CL *mean = param->InputMean(); const framework::CLImage *mean = param->InputMean(); - const framework::CLImage *variance = param->InputVariance(); const framework::CLImage *scale = param->InputScale(); const framework::CLImage *bias = param->InputBias(); @@ -52,9 +59,6 @@ bool ConvAddBNReluKernel::Init( new_bias_ptr[i] = bias_ptr[i] - mean_ptr[i] * inv_std_ptr[i] * scale_ptr[i]; } - delete[](new_scale_ptr); - delete[](new_bias_ptr); - framework::CLImage *new_scale = new framework::CLImage(); new_scale->SetTensorData(new_scale_ptr, variance->dims()); @@ -68,6 +72,9 @@ bool ConvAddBNReluKernel::Init( param->SetNewScale(new_scale); param->SetNewBias(new_bias); + delete[](new_scale_ptr); + delete[](new_bias_ptr); + PADDLE_MOBILE_ENFORCE( param->Filter()->dims()[2] == param->Filter()->dims()[3] && param->Paddings()[0] == param->Paddings()[1], diff --git a/src/operators/kernel/cl/conv_add_kernel.cpp b/src/operators/kernel/cl/conv_add_kernel.cpp index b5fd82c47a9af4fc383cfe276d08dfb365b6bff3..ac36e70ed793ee000602114eb690780235b7d858 100644 --- a/src/operators/kernel/cl/conv_add_kernel.cpp +++ b/src/operators/kernel/cl/conv_add_kernel.cpp @@ -25,6 +25,9 @@ bool ConvAddKernel::Init(FusionConvAddParam *param) { param->Filter()->dims()[2] == param->Filter()->dims()[3] && param->Paddings()[0] == param->Paddings()[1], "need equal"); + param->Filter()->InitCLImage(cl_helper_.CLContext()); + param->Bias()->InitCLImage(cl_helper_.CLContext()); + int offset = static_cast(param->Filter()->dims()[2]) / 2 - static_cast(param->Paddings()[1]); param->SetOffset(offset); diff --git a/src/operators/kernel/cl/conv_kernel.cpp b/src/operators/kernel/cl/conv_kernel.cpp index d31553b60ef2827e9e818443e49a4be148305cf4..232579098a23e49a62662b461430829a32d0117c 100644 --- a/src/operators/kernel/cl/conv_kernel.cpp +++ b/src/operators/kernel/cl/conv_kernel.cpp @@ -26,18 +26,32 @@ bool ConvKernel::Init(ConvParam *param) { param->Paddings()[0] == param->Paddings()[1], "need equal"); + param->Filter()->InitCLImage(cl_helper_.CLContext()); + int offset = static_cast(param->Filter()->dims()[2]) / 2 - static_cast(param->Paddings()[1]); param->SetOffset(offset); + DLOG << " init helper: " << &cl_helper_; + DLOG << " conv kernel add kernel ~ "; + DLOG << " width of one block: " << param->Filter()->WidthOfOneBlock(); + DLOG << " height of one block: " << param->Filter()->HeightOfOneBlock(); + DLOG << " filter dims: " << param->Filter()->dims(); + if (param->Filter()->WidthOfOneBlock() == 1 && param->Filter()->HeightOfOneBlock() == 1) { - this->cl_helper_.AddKernel("conv_1x1", "conv_add_bn_relu_kernel.cl"); + DLOG << " here1 "; + this->cl_helper_.AddKernel("conv_1x1", "conv_kernel.cl"); + } else if (param->Filter()->dims()[1] == 1) { - this->cl_helper_.AddKernel("depth_conv_3x3", "conv_add_bn_relu_kernel.cl"); + DLOG << " here2 "; + this->cl_helper_.AddKernel("depth_conv_3x3", "conv_kernel.cl"); + } else if (param->Filter()->WidthOfOneBlock() == 3 && param->Filter()->HeightOfOneBlock() == 3) { - this->cl_helper_.AddKernel("conv_3x3", "conv_add_bn_relu_kernel.cl"); + DLOG << " here3 "; + this->cl_helper_.AddKernel("conv_3x3", "conv_kernel.cl"); + } else { PADDLE_MOBILE_THROW_EXCEPTION(" not support "); } @@ -47,14 +61,27 @@ bool ConvKernel::Init(ConvParam *param) { template <> void ConvKernel::Compute(const ConvParam ¶m) { + DLOG << " Compute helper: " << &cl_helper_; + DLOG << " begin compute "; auto kernel = this->cl_helper_.KernelAt(0); + DLOG << " get work size "; auto default_work_size = this->cl_helper_.DefaultWorkSize(*param.Output()); + DLOG << " end work size "; int c_block = default_work_size[0]; int w = default_work_size[1]; int nh = default_work_size[2]; auto input = param.Input()->GetCLImage(); + + DLOG << " get Input "; + auto filter = param.Filter()->GetCLImage(); + + DLOG << " get Filter "; + auto output = param.Output(); + + DLOG << " get Output "; + int stride = param.Strides()[0]; int offset = param.Offset(); int input_c = param.Input()->CBlock(); @@ -64,6 +91,8 @@ void ConvKernel::Compute(const ConvParam ¶m) { cl_int status; + DLOG << " begin set kernel arg "; + status = clSetKernelArg(kernel, 0, sizeof(int), &c_block); status = clSetKernelArg(kernel, 1, sizeof(int), &w); status = clSetKernelArg(kernel, 2, sizeof(int), &nh); @@ -77,12 +106,18 @@ void ConvKernel::Compute(const ConvParam ¶m) { status = clSetKernelArg(kernel, 10, sizeof(int), &input_width); status = clSetKernelArg(kernel, 11, sizeof(int), &input_height); + DLOG << " end set kernel arg "; + CL_CHECK_ERRORS(status); + DLOG << " begin enqueue "; + status = clEnqueueNDRangeKernel(this->cl_helper_.CLCommandQueue(), kernel, 3, NULL, default_work_size.data(), NULL, 0, NULL, NULL); + DLOG << " end enqueue "; + CL_CHECK_ERRORS(status); } diff --git a/src/operators/kernel/cl/depthwise_conv_kernel.cpp b/src/operators/kernel/cl/depthwise_conv_kernel.cpp index 99b5a714d6e2d5d6951b800f8f2cdc56c9241e79..dcb95b4c6a9c42ff8c08f83611fc89aebc6efdfa 100644 --- a/src/operators/kernel/cl/depthwise_conv_kernel.cpp +++ b/src/operators/kernel/cl/depthwise_conv_kernel.cpp @@ -27,6 +27,7 @@ bool DepthwiseConvKernel::Init(ConvParam *param) { param->Filter()->dims()[2] == param->Filter()->dims()[3] && param->Paddings()[0] == param->Paddings()[1], "need equal"); + param->Filter()->InitCLImage(cl_helper_.CLContext()); int offset = static_cast(param->Filter()->dims()[2]) / 2 - static_cast(param->Paddings()[1]); param->SetOffset(offset); diff --git a/src/operators/op_param.h b/src/operators/op_param.h index bd80bc8805a857d858c2d4c0d14c417677c2880f..5be3e6a6a8ec8f4c0dca046b5bee0fd5f60456b8 100644 --- a/src/operators/op_param.h +++ b/src/operators/op_param.h @@ -948,6 +948,7 @@ class FetchParam : public OpParam { input_x_ = InputXFrom(inputs, scope); out_ = OutFrom(outputs, scope); } + const RType *InputX() const { return input_x_; } Tensor *Out() const { return out_; } diff --git a/test/net/test_mobilenet_GPU.cpp b/test/net/test_mobilenet_GPU.cpp index 70983e2b1504fb078dce61a45c5c47a96201bc2d..f69334daf2f24bdd4b41ee58e7236051d1459809 100644 --- a/test/net/test_mobilenet_GPU.cpp +++ b/test/net/test_mobilenet_GPU.cpp @@ -34,23 +34,24 @@ int main() { GetInput(g_test_image_1x3x224x224_banana, &input, dims); auto vec_result = paddle_mobile.Predict(input, dims); - std::vector::iterator biggest = - std::max_element(std::begin(vec_result), std::end(vec_result)); - std::cout << " Max element is " << *biggest << " at position " - << std::distance(std::begin(vec_result), biggest) << std::endl; - - // 预热十次 - for (int i = 0; i < 10; ++i) { - auto vec_result = paddle_mobile.Predict(input, dims); - } - auto time3 = paddle_mobile::time(); - for (int i = 0; i < 10; ++i) { - auto vec_result = paddle_mobile.Predict(input, dims); - } - DLOG << vec_result; - auto time4 = paddle_mobile::time(); - std::cout << "predict cost :" << paddle_mobile::time_diff(time3, time4) / 10 - << "ms" << std::endl; + // std::vector::iterator biggest = + // std::max_element(std::begin(vec_result), std::end(vec_result)); + // std::cout << " Max element is " << *biggest << " at position " + // << std::distance(std::begin(vec_result), biggest) << + // std::endl; + + // for (int i = 0; i < 10; ++i) { + // auto vec_result = paddle_mobile.Predict(input, dims); + // } + // auto time3 = paddle_mobile::time(); + // for (int i = 0; i < 10; ++i) { + // auto vec_result = paddle_mobile.Predict(input, dims); + // } + // DLOG << vec_result; + // auto time4 = paddle_mobile::time(); + // std::cout << "predict cost :" << paddle_mobile::time_diff(time3, + // time4) / 10 << "ms" + // << std::endl; } std::cout << "如果结果Nan请查看: test/images/g_test_image_1x3x224x224_banana " diff --git a/tools/web-exporter/CMakeLists.txt b/tools/web-exporter/CMakeLists.txt deleted file mode 100644 index e9cddecd6794fd047a2d0e79719373adbe7f5959..0000000000000000000000000000000000000000 --- a/tools/web-exporter/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -cmake_minimum_required(VERSION 3.6) - -project(web-exporter) - -set(CMAKE_CXX_STANDARD 11) - -file(GLOB PADDLE_MOBILE_CPP_FILES - "../../src/common/*.c" - "../../src/common/*.cpp" - "../../src/memory/*.cpp" - "../../src/framework/*.c" - "../../src/framework/*.cpp" - "../../src/framework/program/*.cpp" - "../../src/framework/program/program-optimize/*.cpp" -) -file(GLOB EXPORT_CPP_FILES "*.cpp") - -add_executable(web-exporter ${PADDLE_MOBILE_CPP_FILES} ${EXPORT_CPP_FILES}) -target_include_directories(web-exporter PRIVATE "../../src") -target_link_libraries(web-exporter) \ No newline at end of file diff --git a/tools/web-exporter/export-nodejs.cpp b/tools/web-exporter/export-nodejs.cpp deleted file mode 100644 index 023d9e5874e5871cdeb4e2b568c63c69436dee6e..0000000000000000000000000000000000000000 --- a/tools/web-exporter/export-nodejs.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "export.h" - -inline std::string indent(int i) { - return std::string(i, ' '); -} -void export_nodejs(ProgramPtr program, ScopePtr scope, std::ostream & os) { - os << "module.exports.program = {\n"; - os << indent(2) << var2str("blocks") << ": [\n"; - for (const auto& block: program->Blocks()) { - os << indent(4) << "{\n"; - os << indent(6) << var2str("vars") << ": {\n"; - for (const auto& var: block->Vars()) { - const auto& dim = var->Tensor_desc().Dims(); - os << indent(8) << var2str(var->Name()) << ": {\n"; - os << indent(10) << var2str("dim") << ": " << var2str(dim) << ",\n"; - os << indent(10) << var2str("persistable") << ": " << var2str(var->Persistable()) << "\n"; - os << indent(8) << "},\n"; - } - os << indent(6) << "},\n"; - os << indent(6) << var2str("ops") << ": [\n"; - for (const auto& op: block->Ops()) { - os << indent(8) << "{\n"; - os << indent(10) << var2str("type") << ": " << var2str(op->Type()) << ",\n"; - os << indent(10) << var2str("inputs") << ": {\n"; - for (const auto& kv: op->GetInputs()) { - os << indent(12) << var2str(kv.first) << ": " << var2str(kv.second) << ",\n"; - } - os << indent(10) << "},\n"; - - os << indent(10) << var2str("outputs") << ": {\n"; - for (const auto& kv: op->GetInputs()) { - os << indent(12) << var2str(kv.first) << ": " << var2str(kv.second) << ",\n"; - } - os << indent(10) << "},\n"; - - os << indent(10) << var2str("attrs") << ": {\n"; - for (const auto& kv: op->GetAttrMap()) { - os << indent(12) << var2str(kv.first) << ": "; - os << decltype(kv.second)::ApplyVistor(VarVisitor(), kv.second) << ",\n"; - } - os << indent(10) << "},\n"; - os << indent(8) << "},\n"; - } - os << indent(6) << "],\n"; - os << indent(4) << "},\n"; - } - os << indent(2) << "]\n"; - os << "}\n"; -} diff --git a/tools/web-exporter/export-scope.cpp b/tools/web-exporter/export-scope.cpp deleted file mode 100644 index d5c2492ac74129fce25eb56dc9fc870e66f2dccc..0000000000000000000000000000000000000000 --- a/tools/web-exporter/export-scope.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include "export.h" - -void export_scope(ProgramPtr program, ScopePtr scope, const std::string & dirname) { - for (const auto& block: program->Blocks()) { - for (const auto& var: block->Vars()) { - if (var->Name() == "feed" || var->Name() == "fetch") { - continue; - } - if (var->Persistable()) { - auto* v = scope->FindVar(var->Name()); - assert(v != nullptr); - int count = 1; - for (auto n: var->Tensor_desc().Dims()) { - count *= n; - } - - auto* tensor = v->GetMutable(); - const float * p = tensor->mutable_data(); - - std::string para_file_name = dirname + '/' + var->Name(); - FILE *para_file = fopen(para_file_name.c_str(), "w"); - assert(p != nullptr); - fwrite(p, sizeof(float), count, para_file); - fclose(para_file); - // std::cout << "==> " << var->Name() << " " << count << "\n"; - // for (int i = 0; i < count; i++) { - // std::cout << p[i] << ", "; - // } - // std::cout << "\n"; - } - } - } -} diff --git a/tools/web-exporter/export.cpp b/tools/web-exporter/export.cpp deleted file mode 100644 index 1f7c678b69e6af9b4f6694489304b85853bf6215..0000000000000000000000000000000000000000 --- a/tools/web-exporter/export.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "export.h" -#include -#include - -class FakeExecutor : public paddle_mobile::framework::Executor { -public: - FakeExecutor(const paddle_mobile::framework::Program p) { - program_ = p; - batch_size_ = 1; - use_optimize_ = true; - loddable_ = false; - if (use_optimize_) { - to_predict_program_ = program_.optimizeProgram; - } else { - to_predict_program_ = program_.originProgram; - } - auto *variable_ptr = program_.scope->Var("batch_size"); - variable_ptr[0].SetValue(1); - if (program_.combined) { - InitCombineMemory(); - } else { - InitMemory(); - } - } -}; - -int main(int argc, char** argv) { - if (argc != 3) { - std::cout << "Usage: " << argv[0] << " \n"; - return -1; - } - std::string model_dir = argv[1]; - std::string model_path = model_dir + "/model"; - std::string para_path = model_dir + "/params"; - - std::string out_dir = argv[2]; - std::string out_model_js = out_dir + "/model.js"; - std::string out_para_dir = out_dir + "/paras"; - mkdir(out_dir.c_str(), S_IRWXU|S_IRWXG|S_IRWXO); - mkdir(out_para_dir.c_str(), S_IRWXU|S_IRWXG|S_IRWXO); - - std::cout << "loading " << model_path << " & " << para_path << "\n"; - paddle_mobile::framework::Loader<> loader; - auto program = loader.Load(model_path, para_path, true); - FakeExecutor executor(program); - auto optimizedProgram = program.optimizeProgram; - export_scope(optimizedProgram, program.scope, out_para_dir); - std::ofstream fs(out_model_js.c_str()); - export_nodejs(optimizedProgram, program.scope, fs); - fs.close(); - return 0; -} diff --git a/tools/web-exporter/export.h b/tools/web-exporter/export.h deleted file mode 100644 index d9db3b31dfa490b4404baccd6336df456cc84755..0000000000000000000000000000000000000000 --- a/tools/web-exporter/export.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "framework/loader.h" -#include "framework/executor.h" -#include "framework/scope.h" -#include "framework/program/program_desc.h" - -// using paddle_mobile::framework::ProgramDesc; -// using paddle_mobile::framework::Scope; - -using ProgramPtr = std::shared_ptr; -using ScopePtr = std::shared_ptr; - -void export_nodejs(ProgramPtr program, ScopePtr scope, std::ostream & os = std::cout); -void export_scope(ProgramPtr program, ScopePtr scope, const std::string & dirname = "."); - - -template -inline std::string var2str(const T & v) { - return std::to_string(v); -} - -template <> -inline std::string var2str(const std::string & v) { - return "\"" + v + "\""; -} - -inline std::string var2str(const char* v) { - return var2str(v); -} - -inline std::string var2str(const bool v) { - return v ? "true" : "false"; -} - -template -std::string var2str(const std::vector & v) { - std::string r = "["; - auto s = v.size(); - for (int i = 0; i < s; i++) { - if (i) r += ", "; - r += var2str(v[i]); - } - return r + "]"; -} - -struct VarVisitor { - using type_t = decltype(var2str(0)); - - template - type_t operator()(const T & v) { - return var2str(v); - } -}; \ No newline at end of file