diff --git a/src/common/log.h b/src/common/log.h index d964d9c1b39a7e72e3d757ef2be0737fd1d25f94..d574818f865ab6b2af748a5b3162b589f396a564 100644 --- a/src/common/log.h +++ b/src/common/log.h @@ -85,18 +85,18 @@ struct Print { private: void print(LogLevel level) { - buffer_ << std::endl; + // buffer_ << std::endl; if (level == kLOG_ERROR) { - std::cerr << buffer_.str(); + std::cerr << buffer_.str() << std::endl; } else { - std::cout << buffer_.str(); + std::cout << buffer_.str() << std::endl; } } std::ostringstream buffer_; }; struct ToLog { - ToLog(LogLevel level = kLOG_DEBUG, const std::string &info = "") + explicit ToLog(LogLevel level = kLOG_DEBUG, const std::string &info = "") : level_(level) { unsigned blanks = (unsigned)(level > kLOG_DEBUG ? (level - kLOG_DEBUG) * 4 : 1); @@ -175,11 +175,8 @@ struct Print { friend struct ToLog; template Print &operator<<(T const &value) { - Print p = Print(); - return p; + return *this; } - - private: }; struct ToLog { diff --git a/src/common/types.cpp b/src/common/types.cpp index d1a1a55a89f69a8d6f195e548b864af8d5bd4e64..7edfde6f857daad252fc8ef6174417e4f639d093 100644 --- a/src/common/types.cpp +++ b/src/common/types.cpp @@ -77,6 +77,12 @@ const char *G_OP_TYPE_CAST = "cast"; const char *G_OP_TYPE_LOG = "log"; const char *G_OP_TYPE_LOD_RESET = "lod_reset"; const char *G_OP_TYPE_LESS_THAN = "less_than"; +const char *G_OP_TYPE_LOGICAL_AND = "logical_and"; +const char *G_OP_TYPE_LOGICAL_OR = "logical_or"; +const char *G_OP_TYPE_LOGICAL_NOT = "logical_not"; +const char *G_OP_TYPE_LOGICAL_XOR = "logical_xor"; +const char *G_OP_TYPE_WRITE_TO_ARRAY = "write_to_array"; +const char *G_OP_TYPE_READ_FROM_ARRAY = "read_from_array"; const char *G_OP_TYPE_QUANTIZE = "quantize"; const char *G_OP_TYPE_DEQUANTIZE = "dequantize"; @@ -181,5 +187,11 @@ std::unordered_map< {G_OP_TYPE_NORM, {{"X"}, {"Out", "Norm"}}}, {G_OP_TYPE_LOG, {{"X"}, {"Out"}}}, {G_OP_TYPE_LOD_RESET, {{"X", "Y"}, {"Out"}}}, - {G_OP_TYPE_LESS_THAN, {{"X", "Y"}, {"Out"}}}}; + {G_OP_TYPE_LESS_THAN, {{"X", "Y"}, {"Out"}}}, + {G_OP_TYPE_LOGICAL_AND, {{"X", "Y"}, {"Out"}}}, + {G_OP_TYPE_LOGICAL_OR, {{"X", "Y"}, {"Out"}}}, + {G_OP_TYPE_LOGICAL_XOR, {{"X", "Y"}, {"Out"}}}, + {G_OP_TYPE_LOGICAL_NOT, {{"X"}, {"Out"}}}, + {G_OP_TYPE_WRITE_TO_ARRAY, {{"X", "I"}, {"Out"}}}, + {G_OP_TYPE_READ_FROM_ARRAY, {{"X", "I"}, {"Out"}}}}; } // namespace paddle_mobile diff --git a/src/common/types.h b/src/common/types.h index 7e7046dea9e6ebd32380c9ad3f34daabe43dd23d..31d8020d4d3a715683f08f0d27e5463f7865abcc 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -131,9 +131,12 @@ extern const char *G_OP_TYPE_FUSION_CONV_BN_ADD_RELU; extern const char *G_OP_TYPE_FUSION_DWCONV_BN_RELU; extern const char *G_OP_TYPE_FUSION_CONV_BN_RELU; +extern const char *G_OP_TYPE_GRU; +extern const char *G_OP_TYPE_GRU_UNIT; extern const char *G_OP_TYPE_LRN; extern const char *G_OP_TYPE_MUL; extern const char *G_OP_TYPE_MULTICLASS_NMS; +extern const char *G_OP_TYPE_NORM; extern const char *G_OP_TYPE_POOL2D; extern const char *G_OP_TYPE_PRIOR_BOX; extern const char *G_OP_TYPE_RELU; @@ -163,6 +166,12 @@ extern const char *G_OP_TYPE_CAST; extern const char *G_OP_TYPE_LOG; extern const char *G_OP_TYPE_LOD_RESET; extern const char *G_OP_TYPE_LESS_THAN; +extern const char *G_OP_TYPE_LOGICAL_AND; +extern const char *G_OP_TYPE_LOGICAL_OR; +extern const char *G_OP_TYPE_LOGICAL_NOT; +extern const char *G_OP_TYPE_LOGICAL_XOR; +extern const char *G_OP_TYPE_WRITE_TO_ARRAY; +extern const char *G_OP_TYPE_READ_FROM_ARRAY; extern const char *G_OP_TYPE_QUANTIZE; extern const char *G_OP_TYPE_DEQUANTIZE; diff --git a/src/framework/attribute.h b/src/framework/attribute.h index a21e0a4ec321dbfe08f87160cc2f0c159594920d..3bc9284bfa6873b9c3f97071b2f96677937c4206 100644 --- a/src/framework/attribute.h +++ b/src/framework/attribute.h @@ -90,6 +90,10 @@ class Attribute { attr.Set(attr_desc->l); break; } + case PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__BLOCK: { + attr.Set(attr_desc->block_idx); + break; + } default: PADDLE_MOBILE_THROW_EXCEPTION("attr type not support"); } diff --git a/src/framework/executor.cpp b/src/framework/executor.cpp index db48534097118f930759ceda6b6e75cb82dcf930..e5b3fadfed0fffb703f8a18a59d3d5e8f4777fa4 100644 --- a/src/framework/executor.cpp +++ b/src/framework/executor.cpp @@ -65,6 +65,7 @@ Executor::Executor(const Program &program, for (int j = 0; j < ops.size(); ++j) { std::shared_ptr op_desc = ops[j]; DLOG << "create op: " << op_desc->Type(); + auto op_handler = OpRegistry::CreateOp( op_desc->Type(), op_desc->GetInputs(), op_desc->GetOutputs(), op_desc->GetAttrMap(), program_.scope); diff --git a/src/framework/load_ops.h b/src/framework/load_ops.h index 1caefe5ae77c9f4328d4d99af9e0b5c3b408d921..eadef7d6688291af2b44c686d78ba6b950abbbba 100644 --- a/src/framework/load_ops.h +++ b/src/framework/load_ops.h @@ -168,6 +168,9 @@ LOAD_FUSION_MATCHER(fusion_conv_bn_relu); #ifdef GRU_OP LOAD_OP1(gru, CPU); #endif +#ifdef GRU_UNIT_OP +LOAD_OP1(gru_unit, CPU); +#endif #ifdef FUSION_CONVADDBN_OP LOAD_OP2(fusion_conv_add_bn, CPU, FPGA); LOAD_FUSION_MATCHER(fusion_conv_add_bn); @@ -189,6 +192,9 @@ LOAD_OP1(crf_decoding, CPU); #ifdef MUL_OP LOAD_OP2(mul, CPU, MALI_GPU); #endif +#ifdef NORM_OP +LOAD_OP1(norm, CPU); +#endif #ifdef RELU_OP LOAD_OP2(relu, CPU, MALI_GPU); LOAD_OP1(relu6, CPU); @@ -279,3 +285,24 @@ LOAD_OP1(lod_reset, CPU); #ifdef LESS_THAN_OP LOAD_OP1(less_than, CPU); #endif +#ifdef LOGICAL_AND_OP +LOAD_OP1(logical_and, CPU); +#endif +#ifdef LOGICAL_OR_OP +LOAD_OP1(logical_or, CPU); +#endif +#ifdef LOGICAL_NOT_OP +LOAD_OP1(logical_not, CPU); +#endif +#ifdef LOGICAL_XOR_OP +LOAD_OP1(logical_xor, CPU); +#endif +#ifdef WHILE_OP +LOAD_OP1(while, CPU); +#endif +#ifdef WRITE_TO_ARRAY_OP +LOAD_OP1(write_to_array, CPU); +#endif +#ifdef READ_FROM_ARRAY_OP +LOAD_OP1(read_from_array, CPU); +#endif diff --git a/src/framework/lod_tensor.h b/src/framework/lod_tensor.h index bd956c866844760a69a89755c3202f264c962bc3..8c35a48f5fa2f13aeb2474eaf6e369dab09ee6d7 100644 --- a/src/framework/lod_tensor.h +++ b/src/framework/lod_tensor.h @@ -176,6 +176,8 @@ LoDTensor LodExpand(const LoDTensor &source, const LoD &lod, size_t level) { return tensor; } +using LoDTensorArray = std::vector; + // Get the absolute offset of a lod[start_level][start_idx:end_idx] and // relative length of details for every levels(i.e., [start_level: ]). // diff --git a/src/framework/program/op_desc.cpp b/src/framework/program/op_desc.cpp index c8cbe3b608cc0b7e4e57b318756389bc89a3dec0..318dd643bbc1d34cf1ab9bc97218caddd8c8d528 100644 --- a/src/framework/program/op_desc.cpp +++ b/src/framework/program/op_desc.cpp @@ -41,9 +41,7 @@ OpDesc::OpDesc(PaddleMobile__Framework__Proto__OpDesc *desc) { for (int k = 0; k < desc->n_attrs; ++k) { PaddleMobile__Framework__Proto__OpDesc__Attr *attr = desc->attrs[k]; std::string attr_name(attr->name); - if (attr->type != PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__BLOCK) { - attrs_[attr_name] = Attribute::GetAttrValue(attr); - } + attrs_[attr_name] = Attribute::GetAttrValue(attr); } } diff --git a/src/io/ios_io/PaddleMobileCPU.h b/src/io/ios_io/PaddleMobileCPU.h index d38da70247beb0e91b6c69d3c7a1c8bb407c128e..69e8b894d7b16eefa36259b479902e6185e5a36e 100644 --- a/src/io/ios_io/PaddleMobileCPU.h +++ b/src/io/ios_io/PaddleMobileCPU.h @@ -44,6 +44,11 @@ */ @property (assign, nonatomic) BOOL optimize; +/** + @b 是否预测时初始化内存,用于处理可变输入 + */ +@property (assign, nonatomic) BOOL loadWhenPredict; + @end @interface PaddleMobileCPU : NSObject diff --git a/src/io/ios_io/PaddleMobileCPU.mm b/src/io/ios_io/PaddleMobileCPU.mm index de801292e225da4f1d21886bdc919c2a2fdcdd7c..7103dce16b4eeed8b2e63c93f5dbf4b122f06a84 100644 --- a/src/io/ios_io/PaddleMobileCPU.mm +++ b/src/io/ios_io/PaddleMobileCPU.mm @@ -73,6 +73,8 @@ static std::mutex shared_mutex; - (instancetype)initWithConfig:(PaddleMobileCPUConfig *)config { if (self = [super init]) { + paddle_mobile::PaddleMobileConfigInternal configInternal; + configInternal.load_when_predict = config.loadWhenPredict; pam_ = new paddle_mobile::PaddleMobile(); _config = config; } diff --git a/src/io/jni/PML.java b/src/io/jni/PML.java index 9cbea253ff54ca82cb5059ea096d5a436018119a..cfacf46135ce25ed73b0bbcfa94cbdc62f74e799 100644 --- a/src/io/jni/PML.java +++ b/src/io/jni/PML.java @@ -7,15 +7,7 @@ public class PML { * @param modelDir model dir * @return isloadsuccess */ - public static native boolean load(String modelDir); - - /** - * load seperated model - * - * @param modelDir model dir - * @return isloadsuccess - */ - public static native boolean loadnlp(String modelDir); + public static native boolean load(String modelDir, Boolean lodMode); /** * load combined model @@ -24,7 +16,7 @@ public class PML { * @param paramPath param file path * @return isloadsuccess */ - public static native boolean loadCombined(String modelPath, String paramPath); + public static native boolean loadCombined(String modelPath, String paramPath, Boolean lodMode); /** * load model and qualified params @@ -32,7 +24,7 @@ public class PML { * @param modelDir qualified model dir * @return isloadsuccess */ - public static native boolean loadQualified(String modelDir); + public static native boolean loadQualified(String modelDir, Boolean lodMode); /** * load model and qualified combined params @@ -41,7 +33,7 @@ public class PML { * @param paramPath qualified param path * @return isloadsuccess */ - public static native boolean loadCombinedQualified(String modelPath, String paramPath); + public static native boolean loadCombinedQualified(String modelPath, String paramPath, Boolean lodMode); /** * predict image @@ -52,9 +44,12 @@ public class PML { */ public static native float[] predictImage(float[] buf, int[] ddims); - public static native float[] predictYuv(byte[] buf, int imgWidth, int imgHeight, int[] ddims, float[] meanValues); + // predict with variable length input + // support only one input and one output currently + public static native float[] predictLod(float[] buf); + /** * clear model data */ @@ -66,6 +61,4 @@ public class PML { * @param threadCount threadCount */ public static native void setThread(int threadCount); - - } diff --git a/src/io/jni/paddle_mobile_jni.cpp b/src/io/jni/paddle_mobile_jni.cpp index 79283070034a4b0a2720cdfb7e68412041163053..12c0a6cbca1721578efe175d8c108e30de18be7d 100644 --- a/src/io/jni/paddle_mobile_jni.cpp +++ b/src/io/jni/paddle_mobile_jni.cpp @@ -39,7 +39,7 @@ using framework::Tensor; using paddle_mobile::CPU; using std::string; -extern const char *ANDROID_LOG_TAG = +const char *ANDROID_LOG_TAG = "paddle_mobile LOG built on " __DATE__ " " __TIME__; paddle_mobile::PaddleMobile paddle_mobile; static std::mutex shared_mutex; @@ -55,51 +55,31 @@ string jstring2cppstring(JNIEnv *env, jstring jstr) { JNIEXPORT jboolean JNICALL Java_com_baidu_paddle_PML_load(JNIEnv *env, jclass thiz, - jstring modelPath) { + jstring modelPath, + jboolean lodMode) { std::lock_guard lock(shared_mutex); ANDROIDLOGI("load invoked"); bool optimize = true; bool isLoadOk = false; - #ifdef ENABLE_EXCEPTION try { isLoadOk = getPaddleMobileInstance()->Load( - jstring2cppstring(env, modelPath), optimize); + jstring2cppstring(env, modelPath), optimize, false, 1, + static_cast(lodMode)); } catch (paddle_mobile::PaddleMobileException &e) { ANDROIDLOGE("jni got an PaddleMobileException! ", e.what()); isLoadOk = false; } #else isLoadOk = getPaddleMobileInstance()->Load(jstring2cppstring(env, modelPath), - optimize); -#endif - return static_cast(isLoadOk); -} - -JNIEXPORT jboolean JNICALL -Java_com_baidu_paddle_PML_loadnlp(JNIEnv *env, jclass thiz, jstring modelPath) { - std::lock_guard lock(shared_mutex); - ANDROIDLOGI("load invoked"); - bool optimize = true; - bool isLoadOk = false; - -#ifdef ENABLE_EXCEPTION - try { - isLoadOk = getPaddleMobileInstance()->Load( - jstring2cppstring(env, modelPath), optimize, false, 1, true); - } catch (paddle_mobile::PaddleMobileException &e) { - ANDROIDLOGE("jni got an PaddleMobileException! ", e.what()); - isLoadOk = false; - } -#else - isLoadOk = getPaddleMobileInstance()->Load(jstring2cppstring(env, modelPath), - optimize, false, 1, true); + optimize, false, 1, + static_cast(lodMode)); #endif return static_cast(isLoadOk); } JNIEXPORT jboolean JNICALL Java_com_baidu_paddle_PML_loadQualified( - JNIEnv *env, jclass thiz, jstring modelPath) { + JNIEnv *env, jclass thiz, jstring modelPath, jboolean lodMode) { std::lock_guard lock(shared_mutex); ANDROIDLOGI("loadQualified invoked"); @@ -110,21 +90,24 @@ JNIEXPORT jboolean JNICALL Java_com_baidu_paddle_PML_loadQualified( #ifdef ENABLE_EXCEPTION try { isLoadOk = getPaddleMobileInstance()->Load( - jstring2cppstring(env, modelPath), optimize, qualified); + jstring2cppstring(env, modelPath), optimize, qualified, 1, + static_cast(lodMode)); } catch (paddle_mobile::PaddleMobileException &e) { ANDROIDLOGE("jni got an PaddleMobileException! ", e.what()); isLoadOk = false; } #else isLoadOk = getPaddleMobileInstance()->Load(jstring2cppstring(env, modelPath), - optimize, qualified); + optimize, qualified, 1, + static_cast(lodMode)); #endif return static_cast(isLoadOk); } JNIEXPORT jboolean JNICALL Java_com_baidu_paddle_PML_loadCombined( - JNIEnv *env, jclass thiz, jstring modelPath, jstring paramPath) { + JNIEnv *env, jclass thiz, jstring modelPath, jstring paramPath, + jboolean lodMode) { std::lock_guard lock(shared_mutex); ANDROIDLOGI("loadCombined invoked"); bool optimize = true; @@ -134,21 +117,22 @@ JNIEXPORT jboolean JNICALL Java_com_baidu_paddle_PML_loadCombined( try { isLoadOk = getPaddleMobileInstance()->Load( jstring2cppstring(env, modelPath), jstring2cppstring(env, paramPath), - optimize); + optimize, false, 1, static_cast(lodMode)); } catch (paddle_mobile::PaddleMobileException &e) { ANDROIDLOGE("jni got an PaddleMobileException! ", e.what()); isLoadOk = false; } #else - isLoadOk = getPaddleMobileInstance()->Load(jstring2cppstring(env, modelPath), - jstring2cppstring(env, paramPath), - optimize); + isLoadOk = getPaddleMobileInstance()->Load( + jstring2cppstring(env, modelPath), jstring2cppstring(env, paramPath), + optimize, false, 1, static_cast(lodMode)); #endif return static_cast(isLoadOk); } JNIEXPORT jboolean JNICALL Java_com_baidu_paddle_PML_loadCombinedQualified( - JNIEnv *env, jclass thiz, jstring modelPath, jstring paramPath) { + JNIEnv *env, jclass thiz, jstring modelPath, jstring paramPath, + jboolean lodMode) { std::lock_guard lock(shared_mutex); ANDROIDLOGI("loadCombinedQualified invoked"); bool optimize = true; @@ -159,15 +143,15 @@ JNIEXPORT jboolean JNICALL Java_com_baidu_paddle_PML_loadCombinedQualified( try { isLoadOk = getPaddleMobileInstance()->Load( jstring2cppstring(env, modelPath), jstring2cppstring(env, paramPath), - optimize, qualified); + optimize, qualified, 1, static_cast(lodMode)); } catch (paddle_mobile::PaddleMobileException &e) { ANDROIDLOGE("jni got an PaddleMobileException! ", e.what()); isLoadOk = false; } #else - isLoadOk = getPaddleMobileInstance()->Load(jstring2cppstring(env, modelPath), - jstring2cppstring(env, paramPath), - optimize, qualified); + isLoadOk = getPaddleMobileInstance()->Load( + jstring2cppstring(env, modelPath), jstring2cppstring(env, paramPath), + optimize, qualified, 1, static_cast(lodMode)); #endif return static_cast(isLoadOk); } diff --git a/src/io/jni/paddle_mobile_jni.h b/src/io/jni/paddle_mobile_jni.h index 158d64d4517b69761b26fc18f2e0943798174014..a2825f96fef122c4270b4b83bb202e2e03c2d7ba 100644 --- a/src/io/jni/paddle_mobile_jni.h +++ b/src/io/jni/paddle_mobile_jni.h @@ -26,24 +26,27 @@ namespace jni { */ JNIEXPORT jboolean JNICALL Java_com_baidu_paddle_PML_load(JNIEnv *env, jclass thiz, - jstring modelPath); + jstring modelPath, + jboolean lodMode); /** * load separated qualified model for android */ JNIEXPORT jboolean JNICALL Java_com_baidu_paddle_PML_loadQualified( - JNIEnv *env, jclass thiz, jstring modelPath); + JNIEnv *env, jclass thiz, jstring modelPath, jboolean lodMode); /** * load combined model for android */ JNIEXPORT jboolean JNICALL Java_com_baidu_paddle_PML_loadCombined( - JNIEnv *env, jclass thiz, jstring modelPath, jstring paramPath); + JNIEnv *env, jclass thiz, jstring modelPath, jstring paramPath, + jboolean lodMode); /** * load combined qualified model for android */ JNIEXPORT jboolean JNICALL Java_com_baidu_paddle_PML_loadCombinedQualified( - JNIEnv *env, jclass thiz, jstring modelPath, jstring paramPath); + JNIEnv *env, jclass thiz, jstring modelPath, jstring paramPath, + jboolean lodMode); /** * object detection for anroid @@ -61,8 +64,8 @@ JNIEXPORT jfloatArray JNICALL Java_com_baidu_paddle_PML_predictYuv( /** * object detection for anroid */ -JNIEXPORT jfloatArray JNICALL -Java_com_baidu_paddle_PML_predict(JNIEnv *env, jclass thiz, jfloatArray buf); +JNIEXPORT jlongArray JNICALL +Java_com_baidu_paddle_PML_predictLod(JNIEnv *env, jclass thiz, jlongArray buf); /** * setThreadCount for multithread diff --git a/src/operators/controlflow/tensor_array_read_write_op.cpp b/src/operators/controlflow/tensor_array_read_write_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0ea8ac01c65f974988a4fd42d8902cce6b888dc5 --- /dev/null +++ b/src/operators/controlflow/tensor_array_read_write_op.cpp @@ -0,0 +1,43 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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 "operators/controlflow/tensor_array_read_write_op.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef WRITE_TO_ARRAY_OP +template +void WriteToArrayOp::InferShape() const {} +#endif // WRITE_TO_ARRAY_OP + +#ifdef READ_FROM_ARRAY_OP +template +void ReadFromArrayOp::InferShape() const {} +#endif // READ_FROM_ARRAY_OP + +} // namespace operators +} // namespace paddle_mobile + +namespace ops = paddle_mobile::operators; + +#ifdef PADDLE_MOBILE_CPU +#ifdef WRITE_TO_ARRAY_OP +REGISTER_OPERATOR_CPU(write_to_array, ops::WriteToArrayOp); +#endif // WRITE_TO_ARRAY_OP + +#ifdef READ_FROM_ARRAY_OP +REGISTER_OPERATOR_CPU(read_from_array, ops::ReadFromArrayOp); +#endif // READ_FROM_ARRAY_OP +#endif diff --git a/src/operators/controlflow/tensor_array_read_write_op.h b/src/operators/controlflow/tensor_array_read_write_op.h new file mode 100644 index 0000000000000000000000000000000000000000..21d3ca10ef58780891f20e60d1f19ae0dcc39a23 --- /dev/null +++ b/src/operators/controlflow/tensor_array_read_write_op.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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. */ + +#pragma once + +#include +#include "framework/operator.h" +#include "operators/kernel/tensor_array_read_write_kernel.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef WRITE_TO_ARRAY_OP +DECLARE_OPERATOR(WriteToArray, WriteToArrayParam, WriteToArrayKernel); +#endif // WRITE_TO_ARRAY_OP + +#ifdef READ_FROM_ARRAY_OP +DECLARE_OPERATOR(ReadFromArray, ReadFromArrayParam, ReadFromArrayKernel); +#endif // WRITE_TO_ARRAY_OP + +} // namespace operators +} // namespace paddle_mobile diff --git a/src/operators/controlflow/while_op.cpp b/src/operators/controlflow/while_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..06eb7c570999237310a5d6f9c40f678281385cf8 --- /dev/null +++ b/src/operators/controlflow/while_op.cpp @@ -0,0 +1,36 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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 "operators/controlflow/while_op.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef WHILE_OP +template +void WhileOp::InferShape() const { + // TODO(hjchen2) +} +#endif // WHILE_OP + +} // namespace operators +} // namespace paddle_mobile + +namespace ops = paddle_mobile::operators; + +#ifdef PADDLE_MOBILE_CPU +#ifdef WHILE_OP +REGISTER_OPERATOR_CPU(while, ops::WhileOp); +#endif // WHILE_OP +#endif diff --git a/src/operators/controlflow/while_op.h b/src/operators/controlflow/while_op.h new file mode 100644 index 0000000000000000000000000000000000000000..6f753a08ef6268120085ef250719a4a9b5a04e8d --- /dev/null +++ b/src/operators/controlflow/while_op.h @@ -0,0 +1,30 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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. */ + +#pragma once + +#include +#include "framework/operator.h" +#include "operators/kernel/while_kernel.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef WHILE_OP +DECLARE_OPERATOR(While, WhileParam, WhileKernel); +#endif // WHILE_OP + +} // namespace operators +} // namespace paddle_mobile diff --git a/src/operators/kernel/arm/conv_add_bn_relu_kernel.cpp b/src/operators/kernel/arm/conv_add_bn_relu_kernel.cpp index 3380cf5b56ba4ffd9f97b2921d9f2abeb6b125a7..1e67f9cc607a6d51abf31ee95e95bff5b051c781 100644 --- a/src/operators/kernel/arm/conv_add_bn_relu_kernel.cpp +++ b/src/operators/kernel/arm/conv_add_bn_relu_kernel.cpp @@ -15,7 +15,7 @@ limitations under the License. */ #ifdef FUSION_CONVADDBNRELU_OP #include "operators/kernel/conv_add_bn_relu_kernel.h" -#include +#include #include "operators/kernel/central-arm-func/conv_add_bn_relu_arm_func.h" namespace paddle_mobile { diff --git a/src/operators/kernel/arm/conv_bn_add_relu_kernel.cpp b/src/operators/kernel/arm/conv_bn_add_relu_kernel.cpp index a0f21dd6126ed81cf5e96f99bd0f8ed5211f96a4..17c9fbd315451af7391ddf0b219fc7f6b7ff22e0 100644 --- a/src/operators/kernel/arm/conv_bn_add_relu_kernel.cpp +++ b/src/operators/kernel/arm/conv_bn_add_relu_kernel.cpp @@ -15,6 +15,7 @@ limitations under the License. */ #ifdef FUSION_CONVBNADDRELU_OP #include "operators/kernel/conv_bn_add_relu_kernel.h" +#include #include "operators/kernel/central-arm-func/conv_bn_add_relu_arm_func.h" namespace paddle_mobile { diff --git a/src/operators/kernel/arm/conv_bn_relu_kernel.cpp b/src/operators/kernel/arm/conv_bn_relu_kernel.cpp index d8acb8d2083b732da026a9bff19c2d7732568597..44c7f463f4cc6e24c5de696b0750e683e6b8b09c 100644 --- a/src/operators/kernel/arm/conv_bn_relu_kernel.cpp +++ b/src/operators/kernel/arm/conv_bn_relu_kernel.cpp @@ -15,6 +15,7 @@ limitations under the License. */ #ifdef FUSION_CONVBNRELU_OP #include "operators/kernel/conv_bn_relu_kernel.h" +#include #include "operators/kernel/central-arm-func/conv_bn_relu_arm_func.h" namespace paddle_mobile { diff --git a/src/operators/kernel/arm/dwconv_bn_relu_kernel.cpp b/src/operators/kernel/arm/dwconv_bn_relu_kernel.cpp index f92d9a273467bf15d9d7fad43237af5385d3d54e..60d35302942ec398597c5e02157581c19fe0547c 100644 --- a/src/operators/kernel/arm/dwconv_bn_relu_kernel.cpp +++ b/src/operators/kernel/arm/dwconv_bn_relu_kernel.cpp @@ -15,6 +15,7 @@ limitations under the License. */ #ifdef FUSION_DWCONVBNRELU_OP #include "operators/kernel/dwconv_bn_relu_kernel.h" +#include #include "operators/kernel/central-arm-func/dwconv_bn_relu_arm_func.h" namespace paddle_mobile { diff --git a/src/operators/kernel/arm/logical_kernel.cpp b/src/operators/kernel/arm/logical_kernel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3cffcf5c691fde551ad01f42757da8eaae98833e --- /dev/null +++ b/src/operators/kernel/arm/logical_kernel.cpp @@ -0,0 +1,125 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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 "operators/kernel/logical_kernel.h" + +namespace paddle_mobile { +namespace operators { + +template +struct LogicalAndFunctor { + bool operator()(const T& a, const T& b) const { return a && b; } +}; + +template +struct LogicalOrFunctor { + bool operator()(const T& a, const T& b) const { return a || b; } +}; + +template +struct LogicalNotFunctor { + bool operator()(const T& a) const { return !a; } +}; + +template +struct LogicalXorFunctor { + bool operator()(const T& a, const T& b) const { + return (a || b) && !(a && b); + } +}; + +template +void UnaryLogicalCompute(const Tensor* inputX, Tensor* output) { + Functor func; + std::transform(inputX->data(), inputX->data() + inputX->numel(), + output->data(), func); +} + +template +void BinaryLogicalCompute(const Tensor* inputX, const Tensor* inputY, + Tensor* output) { + Functor func; + std::transform(inputX->data(), inputX->data() + inputX->numel(), + inputY->data(), output->data(), func); +} + +#ifdef LOGICAL_AND_OP +template <> +bool LogicalAndKernel::Init(LogicalBinaryParam* param) { + return true; +} + +template <> +void LogicalAndKernel::Compute( + const LogicalBinaryParam& param) { + auto* inputX = param.InputX(); + auto* inputY = param.InputY(); + auto* out = param.Out(); + out->mutable_data(); + BinaryLogicalCompute>(inputX, inputY, out); +} +#endif + +#ifdef LOGICAL_OR_OP +template <> +bool LogicalOrKernel::Init(LogicalBinaryParam* param) { + return true; +} + +template <> +void LogicalOrKernel::Compute( + const LogicalBinaryParam& param) { + auto* inputX = param.InputX(); + auto* inputY = param.InputY(); + auto* out = param.Out(); + out->mutable_data(); + BinaryLogicalCompute>(inputX, inputY, out); +} +#endif + +#ifdef LOGICAL_NOT_OP +template <> +bool LogicalNotKernel::Init(LogicalUnaryParam* param) { + return true; +} + +template <> +void LogicalNotKernel::Compute( + const LogicalUnaryParam& param) { + auto* inputX = param.InputX(); + auto* out = param.Out(); + out->mutable_data(); + UnaryLogicalCompute>(inputX, out); +} +#endif + +#ifdef LOGICAL_XOR_OP +template <> +bool LogicalXorKernel::Init(LogicalBinaryParam* param) { + return true; +} + +template <> +void LogicalXorKernel::Compute( + const LogicalBinaryParam& param) { + auto* inputX = param.InputX(); + auto* inputY = param.InputY(); + auto* out = param.Out(); + out->mutable_data(); + BinaryLogicalCompute>(inputX, inputY, out); +} +#endif + +} // namespace operators +} // namespace paddle_mobile diff --git a/src/operators/kernel/arm/quantize_kernel.cpp b/src/operators/kernel/arm/quantize_kernel.cpp index 97ffa05c86f15fe6cd7ca18ffef867ad92a61bde..c8af30a65590ef6dd3592da8709b94cba1ee60c6 100644 --- a/src/operators/kernel/arm/quantize_kernel.cpp +++ b/src/operators/kernel/arm/quantize_kernel.cpp @@ -167,7 +167,7 @@ float find_abs_max(const Tensor *input) { max_abs = vmaxvq_f32(__max); #endif for (size_t i = 0; i < remain; ++i) { - max_abs = std::max(max_abs, std::abs(x[i])); + max_abs = std::max(max_abs, fabs(x[i])); } return max_abs; } diff --git a/src/operators/kernel/arm/tensor_array_read_write_kernel.cpp b/src/operators/kernel/arm/tensor_array_read_write_kernel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5d6b86c34c963808e72a05db08940db97b0212b9 --- /dev/null +++ b/src/operators/kernel/arm/tensor_array_read_write_kernel.cpp @@ -0,0 +1,58 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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 "operators/kernel/tensor_array_read_write_kernel.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef WRITE_TO_ARRAY_OP +template <> +bool WriteToArrayKernel::Init(WriteToArrayParam *param) { + return true; +} + +template <> +void WriteToArrayKernel::Compute( + const WriteToArrayParam ¶m) { + int64_t offset = param.index_->data()[0]; + if (offset >= param.output_->size()) { + param.output_->resize(offset); + } + framework::LoDTensor *out_tensor = &(param.output_->at(offset)); + out_tensor->set_lod(param.input_->lod()); + if (param.input_->memory_size() > 0) { + TensorCopy(*(param.input_), out_tensor); + } +} +#endif // WRITE_TO_ARRAY_OP + +#ifdef READ_FROM_ARRAY_OP +template <> +bool ReadFromArrayKernel::Init(ReadFromArrayParam *param) { + return true; +} + +template <> +void ReadFromArrayKernel::Compute( + const ReadFromArrayParam ¶m) { + int64_t offset = param.index_->data()[0]; + if (offset < param.input_->size()) { + TensorCopy(param.input_->at(offset), param.output_); + } +} +#endif // READ_FROM_ARRAY_OP + +} // namespace operators +} // namespace paddle_mobile diff --git a/src/operators/kernel/arm/while_kernel.cpp b/src/operators/kernel/arm/while_kernel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f27a897ffcadbb1ade759f324766ccbfb8dd49d5 --- /dev/null +++ b/src/operators/kernel/arm/while_kernel.cpp @@ -0,0 +1,33 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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 "operators/kernel/while_kernel.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef WHILE_OP +template <> +bool WhileKernel::Init(WhileParam *param) { + return true; +} + +template <> +void WhileKernel::Compute(const WhileParam ¶m) { + // TODO(hjchen2) +} +#endif // WHILE_OP + +} // namespace operators +} // namespace paddle_mobile diff --git a/src/operators/kernel/central-arm-func/gru_unit_arm_func.h b/src/operators/kernel/central-arm-func/gru_unit_arm_func.h index 3897d6a308484f942f4a0cbb03957a37f3b7ab4c..603592505d2a2bcb9d6557e2a2369d5e8625a764 100644 --- a/src/operators/kernel/central-arm-func/gru_unit_arm_func.h +++ b/src/operators/kernel/central-arm-func/gru_unit_arm_func.h @@ -21,6 +21,7 @@ limitations under the License. */ #include "operators/math/gemm.h" #include "operators/math/math_function.h" #include "operators/op_param.h" + namespace paddle_mobile { namespace operators { diff --git a/src/operators/kernel/cl/batchnorm_kernel.cpp b/src/operators/kernel/cl/batchnorm_kernel.cpp index 590e8c5cb028ab4acd3a94df28c5c10dd477d51f..ce57e8dc2e1504e0e3a1fe957bded6de5312d5fa 100644 --- a/src/operators/kernel/cl/batchnorm_kernel.cpp +++ b/src/operators/kernel/cl/batchnorm_kernel.cpp @@ -15,6 +15,7 @@ limitations under the License. */ #ifdef BATCHNORM_OP #include "operators/kernel/batchnorm_kernel.h" +#include namespace paddle_mobile { namespace operators { 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 33172e4f0343f1bb26e34f6c7d3b009629b60430..3d1e167613a15e470b160fc5864ab11d4a01a81f 100644 --- a/src/operators/kernel/cl/conv_add_bn_relu_kernel.cpp +++ b/src/operators/kernel/cl/conv_add_bn_relu_kernel.cpp @@ -15,6 +15,7 @@ limitations under the License. */ #ifdef FUSION_CONVADDBNRELU_OP #include "operators/kernel/conv_add_bn_relu_kernel.h" +#include #include "framework/cl/cl_image.h" #include "framework/cl/cl_tool.h" diff --git a/src/operators/kernel/cl/conv_bn_add_relu_kernel.cpp b/src/operators/kernel/cl/conv_bn_add_relu_kernel.cpp index 4b7352a679afcb1137421040117e9d85d9589e61..b0a7f36ffb612d42b081ffd10c22f2ebc730db7c 100644 --- a/src/operators/kernel/cl/conv_bn_add_relu_kernel.cpp +++ b/src/operators/kernel/cl/conv_bn_add_relu_kernel.cpp @@ -15,6 +15,7 @@ limitations under the License. */ #ifdef FUSION_CONVBNADDRELU_OP #include "operators/kernel/conv_bn_add_relu_kernel.h" +#include namespace paddle_mobile { namespace operators { diff --git a/src/operators/kernel/cl/conv_bn_relu_kernel.cpp b/src/operators/kernel/cl/conv_bn_relu_kernel.cpp index 945f84358ff2f5a61ece0c8f96d39b3c10c01c1e..12a01e28a7c5dce9150104576a62200e01c4267f 100644 --- a/src/operators/kernel/cl/conv_bn_relu_kernel.cpp +++ b/src/operators/kernel/cl/conv_bn_relu_kernel.cpp @@ -15,6 +15,7 @@ limitations under the License. */ #ifdef FUSION_CONVBNRELU_OP #include "operators/kernel/conv_bn_relu_kernel.h" +#include namespace paddle_mobile { namespace operators { diff --git a/src/operators/kernel/cl/dwconv_bn_relu_kernel.cpp b/src/operators/kernel/cl/dwconv_bn_relu_kernel.cpp index 31cb654d75c9c83e132a52d740b0b2db1c3a2ccf..03362a8d9f73fc18b13b546eabcd92d51663a65d 100644 --- a/src/operators/kernel/cl/dwconv_bn_relu_kernel.cpp +++ b/src/operators/kernel/cl/dwconv_bn_relu_kernel.cpp @@ -15,6 +15,7 @@ limitations under the License. */ #ifdef FUSION_DWCONVBNRELU_OP #include "operators/kernel/dwconv_bn_relu_kernel.h" +#include namespace paddle_mobile { namespace operators { diff --git a/src/operators/kernel/cl/relu_kernel.cpp b/src/operators/kernel/cl/relu_kernel.cpp index c3acfe442201a9be59c6f0a0a536cf9aea68c4a2..dcd1275e3cf2fc7a226f32371e81b7b1ba91b9d2 100644 --- a/src/operators/kernel/cl/relu_kernel.cpp +++ b/src/operators/kernel/cl/relu_kernel.cpp @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. */ #ifdef RELU_OP -#include "operators/kernel/relu_kernel.h" +#include "operators/kernel/activation_kernel.h" namespace paddle_mobile { namespace operators { diff --git a/src/operators/kernel/fpga/V1/conv_add_bn_kernel.cpp b/src/operators/kernel/fpga/V1/conv_add_bn_kernel.cpp old mode 100755 new mode 100644 index 5d7e180f01aea4c6357d4638f73fbe51b8c18c17..30ff3155a47c813f303dc59191edd8b60e6d8ce3 --- a/src/operators/kernel/fpga/V1/conv_add_bn_kernel.cpp +++ b/src/operators/kernel/fpga/V1/conv_add_bn_kernel.cpp @@ -15,7 +15,8 @@ limitations under the License. */ #ifdef FUSION_CONVADDBN_OP #include "operators/kernel/conv_add_bn_kernel.h" -#include +#include + namespace paddle_mobile { namespace operators { diff --git a/src/operators/kernel/fpga/V1/conv_add_bn_relu_kernel.cpp b/src/operators/kernel/fpga/V1/conv_add_bn_relu_kernel.cpp index 567b42ef08b7047225013ac48eb95262a353082a..7f720323253fff53f7d1bb92f8bfeec77bf0da14 100644 --- a/src/operators/kernel/fpga/V1/conv_add_bn_relu_kernel.cpp +++ b/src/operators/kernel/fpga/V1/conv_add_bn_relu_kernel.cpp @@ -15,7 +15,7 @@ limitations under the License. */ #ifdef FUSION_CONVADDBNRELU_OP #include "operators/kernel/conv_add_bn_relu_kernel.h" -#include +#include namespace paddle_mobile { namespace operators { diff --git a/src/operators/kernel/fpga/V1/conv_bn_kernel.cpp b/src/operators/kernel/fpga/V1/conv_bn_kernel.cpp old mode 100755 new mode 100644 diff --git a/src/operators/kernel/fpga/V1/conv_bn_relu_kernel.cpp b/src/operators/kernel/fpga/V1/conv_bn_relu_kernel.cpp old mode 100755 new mode 100644 diff --git a/src/operators/kernel/fpga/V2/conv_add_bn_kernel.cpp b/src/operators/kernel/fpga/V2/conv_add_bn_kernel.cpp index 82cb872055aed84d28c798e413b86478de6ca0a6..a529a9871966485f46f5e3435fd24ddcbf3cfb07 100644 --- a/src/operators/kernel/fpga/V2/conv_add_bn_kernel.cpp +++ b/src/operators/kernel/fpga/V2/conv_add_bn_kernel.cpp @@ -15,6 +15,7 @@ limitations under the License. */ #ifdef FUSION_CONVADDBN_OP #include "operators/kernel/conv_add_bn_kernel.h" +#include namespace paddle_mobile { namespace operators { diff --git a/src/operators/kernel/fpga/V2/conv_add_bn_relu_kernel.cpp b/src/operators/kernel/fpga/V2/conv_add_bn_relu_kernel.cpp index 266ebe012e0db3ef3b2ac21f81f4436d143ece59..c9cf04fe6773ee3d194945ad5a69154a9c7a07bf 100644 --- a/src/operators/kernel/fpga/V2/conv_add_bn_relu_kernel.cpp +++ b/src/operators/kernel/fpga/V2/conv_add_bn_relu_kernel.cpp @@ -15,6 +15,7 @@ limitations under the License. */ #ifdef FUSION_CONVADDBNRELU_OP #include "operators/kernel/conv_add_bn_relu_kernel.h" +#include namespace paddle_mobile { namespace operators { diff --git a/src/operators/kernel/fpga/V2/conv_bn_kernel.cpp b/src/operators/kernel/fpga/V2/conv_bn_kernel.cpp index cb32c0fe040b9c55de660269fbfc3598ea9722bf..77b6a9a5356270a75723b56f342c133360f44ed6 100644 --- a/src/operators/kernel/fpga/V2/conv_bn_kernel.cpp +++ b/src/operators/kernel/fpga/V2/conv_bn_kernel.cpp @@ -15,6 +15,7 @@ limitations under the License. */ #ifdef FUSION_CONVBN_OP #include "operators/kernel/conv_bn_kernel.h" +#include namespace paddle_mobile { namespace operators { diff --git a/src/operators/kernel/fpga/V2/conv_bn_relu_kernel.cpp b/src/operators/kernel/fpga/V2/conv_bn_relu_kernel.cpp index 918b65bd347811f9a2cc6b1182c54d9f39a9082e..c20dfb8911a8fdd32e3097a21deb56f37db11d28 100644 --- a/src/operators/kernel/fpga/V2/conv_bn_relu_kernel.cpp +++ b/src/operators/kernel/fpga/V2/conv_bn_relu_kernel.cpp @@ -15,6 +15,7 @@ limitations under the License. */ #ifdef FUSION_CONVBNRELU_OP #include "operators/kernel/conv_bn_relu_kernel.h" +#include #include "fpga/V2/filter.h" namespace paddle_mobile { diff --git a/src/operators/kernel/logical_kernel.h b/src/operators/kernel/logical_kernel.h new file mode 100644 index 0000000000000000000000000000000000000000..8c49669fa8f276b28e4d3b50db16937f766f70a1 --- /dev/null +++ b/src/operators/kernel/logical_kernel.h @@ -0,0 +1,40 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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. */ + +#pragma once + +#include "framework/operator.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef LOGICAL_AND_OP +DECLARE_KERNEL(LogicalAnd, LogicalBinaryParam); +#endif + +#ifdef LOGICAL_OR_OP +DECLARE_KERNEL(LogicalOr, LogicalBinaryParam); +#endif + +#ifdef LOGICAL_NOT_OP +DECLARE_KERNEL(LogicalNot, LogicalUnaryParam); +#endif + +#ifdef LOGICAL_XOR_OP +DECLARE_KERNEL(LogicalXor, LogicalBinaryParam); +#endif + +} // namespace operators +} // namespace paddle_mobile diff --git a/src/operators/kernel/tensor_array_read_write_kernel.h b/src/operators/kernel/tensor_array_read_write_kernel.h new file mode 100644 index 0000000000000000000000000000000000000000..8b666c0b40e79bde9c2f101e69f4e5b58aa32d45 --- /dev/null +++ b/src/operators/kernel/tensor_array_read_write_kernel.h @@ -0,0 +1,32 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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. */ + +#pragma once + +#include "framework/operator.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef WRITE_TO_ARRAY_OP +DECLARE_KERNEL(WriteToArray, WriteToArrayParam); +#endif // WRITE_TO_ARRAY_OP + +#ifdef READ_FROM_ARRAY_OP +DECLARE_KERNEL(ReadFromArray, ReadFromArrayParam); +#endif // READ_FROM_ARRAY_OP + +} // namespace operators +} // namespace paddle_mobile diff --git a/src/operators/kernel/while_kernel.h b/src/operators/kernel/while_kernel.h new file mode 100644 index 0000000000000000000000000000000000000000..72b0f5f7388f10551d91491b605d57de2fd7271e --- /dev/null +++ b/src/operators/kernel/while_kernel.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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. */ + +#pragma once + +#include "framework/operator.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef WHILE_OP +template +class WhileParam : public OpParam { + public: + WhileParam(const VariableNameMap &inputs, const VariableNameMap &outputs, + const AttributeMap &attrs, const Scope &scope) + : inputs_(inputs), outputs_(outputs), scope_(scope) { + cond_ = + OpParam::GetVarValue("Condition", inputs, scope); + sub_block_ = OpParam::GetAttr("sub_block", attrs); + } + + public: + framework::LoDTensor *cond_; + int sub_block_; + const VariableNameMap inputs_; + const VariableNameMap outputs_; + const Scope scope_; +}; + +DECLARE_KERNEL(While, WhileParam); +#endif // WHILE_OP + +} // namespace operators +} // namespace paddle_mobile diff --git a/src/operators/logical_op.cpp b/src/operators/logical_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6478516be088960be8f91e106c21129c8de774f5 --- /dev/null +++ b/src/operators/logical_op.cpp @@ -0,0 +1,69 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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 "operators/logical_op.h" + +namespace paddle_mobile { +namespace operators { + +#define DEFINE_LOGICAL_INFERSHAPE(OpName) \ + template \ + void OpName##Op::InferShape() const { \ + const auto &input_dims = this->param_.InputX()->dims(); \ + this->param_.Out()->Resize(input_dims); \ + } + +#ifdef LOGICAL_AND_OP +DEFINE_LOGICAL_INFERSHAPE(LogicalAnd); +#endif // TLOGICAL_AND_OP + +#ifdef LOGICAL_OR_OP +DEFINE_LOGICAL_INFERSHAPE(LogicalOr); +#endif // TLOGICAL_OR_OP + +#ifdef LOGICAL_NOT_OP +DEFINE_LOGICAL_INFERSHAPE(LogicalNot); +#endif // LOGICAL_NOT_OP + +#ifdef LOGICAL_XOR_OP +DEFINE_LOGICAL_INFERSHAPE(LogicalXor); +#endif // TLOGICAL_XOR_OP + +} // namespace operators +} // namespace paddle_mobile + +namespace ops = paddle_mobile::operators; +#ifdef LOGICAL_AND_OP +#ifdef PADDLE_MOBILE_CPU +REGISTER_OPERATOR_CPU(logical_and, ops::LogicalAndOp); +#endif +#endif // LOGICAL_AND_OP + +#ifdef LOGICAL_OR_OP +#ifdef PADDLE_MOBILE_CPU +REGISTER_OPERATOR_CPU(logical_or, ops::LogicalOrOp); +#endif +#endif // LOGICAL_OR_OP + +#ifdef LOGICAL_NOT_OP +#ifdef PADDLE_MOBILE_CPU +REGISTER_OPERATOR_CPU(logical_not, ops::LogicalNotOp); +#endif +#endif // LOGICAL_NOT_OP + +#ifdef LOGICAL_XOR_OP +#ifdef PADDLE_MOBILE_CPU +REGISTER_OPERATOR_CPU(logical_xor, ops::LogicalXorOp); +#endif +#endif // LOGICAL_XOR_OP diff --git a/src/operators/logical_op.h b/src/operators/logical_op.h new file mode 100644 index 0000000000000000000000000000000000000000..a3cd2fb605f3f081e06eee740d9c47873a29ca97 --- /dev/null +++ b/src/operators/logical_op.h @@ -0,0 +1,42 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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. */ + +#pragma once + +#include +#include "framework/operator.h" +#include "operators/kernel/logical_kernel.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +#ifdef LOGICAL_AND_OP +DECLARE_OPERATOR(LogicalAnd, LogicalBinaryParam, LogicalAndKernel); +#endif + +#ifdef LOGICAL_OR_OP +DECLARE_OPERATOR(LogicalOr, LogicalBinaryParam, LogicalOrKernel); +#endif + +#ifdef LOGICAL_NOT_OP +DECLARE_OPERATOR(LogicalNot, LogicalUnaryParam, LogicalNotKernel); +#endif + +#ifdef LOGICAL_XOR_OP +DECLARE_OPERATOR(LogicalXor, LogicalBinaryParam, LogicalXorKernel); +#endif + +} // namespace operators +} // namespace paddle_mobile diff --git a/src/operators/math/gemm.h b/src/operators/math/gemm.h index 99c68de7c34cf6300625cbc1cee3c2b388ffb517..b6af1c838d337fb84aae58e1531ab0acb07f7bea 100644 --- a/src/operators/math/gemm.h +++ b/src/operators/math/gemm.h @@ -13,6 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. */ #pragma once +#include #include #include "common/log.h" #include "memory/t_malloc.h" diff --git a/src/operators/math/quantize.h b/src/operators/math/quantize.h index 9f9e91330cd9645eb1fbc2fd01192eda4ef0fc7a..9f6b2437f53868341586efdf04b2c8a2a66dac4a 100644 --- a/src/operators/math/quantize.h +++ b/src/operators/math/quantize.h @@ -40,8 +40,8 @@ template <> inline int8_t Round(const float &x) { float v = std::round(x); int32_t q = static_cast(v); - if (std::abs(std::abs(q - v) - 0.5) <= 0) { - if (std::abs(q) % 2 != 0) { + if (fabs(fabs(q - v) - 0.5) <= 0) { + if (abs(q) % 2 != 0) { q = q + ((q > 0) ? -1 : 1); } } diff --git a/src/operators/op_param.h b/src/operators/op_param.h index 60f760c2024359c3fcfebf383e29afed33c51bcb..bcf6b6e32a38dd379869492fe50644327ce3edad 100644 --- a/src/operators/op_param.h +++ b/src/operators/op_param.h @@ -2949,5 +2949,112 @@ class CompareParam : public OpParam { }; #endif // LESS_THAN_OP +#if defined(LOGICAL_AND_OP) || defined(LOGICAL_OR_OP) || defined(LOGICAL_XOR_OP) +template +class LogicalBinaryParam : public OpParam { + typedef typename DtypeTensorTrait::gtype GType; + typedef typename DtypeTensorTrait::rtype RType; + + public: + LogicalBinaryParam(const VariableNameMap &inputs, + const VariableNameMap &outputs, const AttributeMap &attrs, + const Scope &scope) { + input_x_ = InputXFrom(inputs, scope); + input_y_ = InputYFrom(inputs, scope); + output_ = OutFrom(outputs, scope); + } + + const GType *InputX() const { return input_x_; } + const GType *InputY() const { return input_y_; } + GType *Out() const { return output_; } + + public: + GType *input_x_; + GType *input_y_; + GType *output_; +}; +#endif // LOGICAL_AND_OP LOGICAL_OR_OP LOGICAL_XOR_OP + +#ifdef LOGICAL_NOT_OP +template +class LogicalUnaryParam : public OpParam { + typedef typename DtypeTensorTrait::gtype GType; + typedef typename DtypeTensorTrait::rtype RType; + + public: + LogicalUnaryParam(const VariableNameMap &inputs, + const VariableNameMap &outputs, const AttributeMap &attrs, + const Scope &scope) { + input_x_ = InputXFrom(inputs, scope); + output_ = OutFrom(outputs, scope); + } + + const GType *InputX() const { return input_x_; } + GType *Out() const { return output_; } + + public: + GType *input_x_; + GType *output_; +}; +#endif // LOGICAL_NOT_OP + +// #ifdef WHILE_OP +// template +// class WhileParam : public OpParam { +// public: +// WhileParam(const VariableNameMap &inputs, +// const VariableNameMap &outputs, const AttributeMap &attrs, +// const Scope &scope) { +// cond_ = OpParam::GetVarValue("Condition", inputs, +// scope); block_desc_ = OpParam::GetAttr("sub_block", attrs); +// } +// +// public: +// framework::LoDTensor *cond_; +// const framework::BlockDesc *block_desc_; +// }; +// #endif // WHILE_OP + +#ifdef WRITE_TO_ARRAY_OP +template +class WriteToArrayParam : public OpParam { + public: + WriteToArrayParam(const VariableNameMap &inputs, + const VariableNameMap &outputs, const AttributeMap &attrs, + const Scope &scope) { + input_ = OpParam::GetVarValue("X", inputs, scope); + index_ = OpParam::GetVarValue("I", inputs, scope); + output_ = + OpParam::GetVarValue("Out", outputs, scope); + } + + public: + framework::LoDTensor *input_; + framework::LoDTensor *index_; + framework::LoDTensorArray *output_; +}; +#endif + +#ifdef READ_FROM_ARRAY_OP +template +class ReadFromArrayParam : public OpParam { + public: + ReadFromArrayParam(const VariableNameMap &inputs, + const VariableNameMap &outputs, const AttributeMap &attrs, + const Scope &scope) { + input_ = + OpParam::GetVarValue("X", inputs, scope); + index_ = OpParam::GetVarValue("I", inputs, scope); + output_ = OpParam::GetVarValue("Out", outputs, scope); + } + + public: + framework::LoDTensorArray *input_; + framework::LoDTensor *index_; + framework::LoDTensor *output_; +}; +#endif + } // namespace operators } // namespace paddle_mobile diff --git a/src/operators/reshape_op.cpp b/src/operators/reshape_op.cpp old mode 100755 new mode 100644 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 75ad5348aa0743c081e2df3a59c190fa4c9a64f9..23634f33fe01dbfbc994f48a522c30c966fc7087 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -30,6 +30,10 @@ if (CON GREATER -1) target_link_libraries(test-mobilenet-combine paddle-mobile) set(FOUND_MATCH ON) + # gen test + ADD_EXECUTABLE(test-mobilenetgpu net/test_mobilenet_GPU.cpp test_helper.h test_include.h) + target_link_libraries(test-mobilenetgpu paddle-mobile) + endif () list(FIND NET "yolo" CON) @@ -417,4 +421,20 @@ if (NOT FOUND_MATCH) ADD_EXECUTABLE(test-vgg16ssd net/test_vgg16ssd.cpp test_helper.h test_include.h) target_link_libraries(test-vgg16ssd paddle-mobile) + # gen test + ADD_EXECUTABLE(test-logical-and-op operators/test_logical_and_op.cpp test_helper.h test_include.h) + target_link_libraries(test-logical-and-op paddle-mobile) + + # gen test + ADD_EXECUTABLE(test-logical-or-op operators/test_logical_or_op.cpp test_helper.h test_include.h) + target_link_libraries(test-logical-or-op paddle-mobile) + + # gen test + ADD_EXECUTABLE(test-logical-not-op operators/test_logical_not_op.cpp test_helper.h test_include.h) + target_link_libraries(test-logical-not-op paddle-mobile) + + # gen test + ADD_EXECUTABLE(test-logical-xor-op operators/test_logical_xor_op.cpp test_helper.h test_include.h) + target_link_libraries(test-logical-xor-op paddle-mobile) + endif () diff --git a/test/net/test_mobilenet_GPU.cpp b/test/net/test_mobilenet_GPU.cpp index e410baf77616584995f1e3687b47ca0af337a231..22ff12f592834efeab1566c2bd4fbd3b5c00dc26 100644 --- a/test/net/test_mobilenet_GPU.cpp +++ b/test/net/test_mobilenet_GPU.cpp @@ -25,11 +25,11 @@ int main() { paddle_mobile.SetCLPath("/data/local/tmp/bin"); #endif - auto isok = - paddle_mobile.Load(std::string(g_mobilenet_mul) + "/model", - std::string(g_mobilenet_mul) + "/params", true); + // auto isok = + // paddle_mobile.Load(std::string(g_mobilenet_mul) + "/model", + // std::string(g_mobilenet_mul) + "/params", true); - // auto isok = paddle_mobile.Load(std::string(g_mobilenet_mul), true); + auto isok = paddle_mobile.Load(std::string(g_mobilenet), true); if (isok) { auto time2 = paddle_mobile::time(); std::cout << "load cost :" << paddle_mobile::time_diff(time1, time2) << "ms" diff --git a/test/operators/test_logical_and_op.cpp b/test/operators/test_logical_and_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..216513cf3d7f64c865bf0931abe6a9dad2d2582d --- /dev/null +++ b/test/operators/test_logical_and_op.cpp @@ -0,0 +1,84 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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 "../test_include.h" +#include "operators/logical_op.h" + +namespace paddle_mobile { + +void LogicalAnd(const framework::Tensor *inputX, + const framework::Tensor *inputY, framework::Tensor *output) { + auto x_data = inputX->data(); + auto y_data = inputY->data(); + auto output_data = output->data(); + for (int i = 0; i < inputX->numel(); ++i) { + *output_data = *x_data && *y_data; + x_data++; + y_data++; + output_data++; + } +} + +int TestLogicalAndOp(const std::vector input_shape) { + framework::DDim input_dims = framework::make_ddim(input_shape); + VariableNameMap inputs; + VariableNameMap outputs; + auto scope = std::make_shared(); + inputs["X"] = std::vector({"inputX"}); + inputs["Y"] = std::vector({"inputY"}); + outputs["Out"] = std::vector({"output"}); + + auto x_var = scope.get()->Var("inputX"); + auto x = x_var->template GetMutable(); + SetupTensor(x, input_dims, 0, 1); + + auto y_var = scope.get()->Var("inputY"); + auto y = y_var->template GetMutable(); + SetupTensor(y, input_dims, 0, 1); + + auto output_var = scope.get()->Var("output"); + framework::AttributeMap attrs; + + auto *op = new operators::LogicalAndOp("logical_and", inputs, + outputs, attrs, scope); + + op->InferShape(); + op->Init(); + op->Run(); + + auto output = output_var->template Get(); + framework::Tensor output_cmp; + bool *output_cmp_data = output_cmp.mutable_data(output->dims()); + LogicalAnd(x, y, &output_cmp); + + const bool *output_data = output->data(); + for (int i = 0; i < output->numel(); ++i) { + if (output_data[i] != output_cmp_data[i]) { + LOG(kLOG_INFO) << "output_data[" << i << "] = " << output_data[i] + << ", output_cmp_data[" << i + << "] = " << output_cmp_data[i]; + delete op; + exit(1); + } + } +} +} // namespace paddle_mobile + +int main() { + paddle_mobile::TestLogicalAndOp({1, 1, 2, 3}); + paddle_mobile::TestLogicalAndOp({1, 3, 11, 12}); + paddle_mobile::TestLogicalAndOp({1, 16, 32, 32}); + DLOG << "test logical_and op pass."; + return 0; +} diff --git a/test/operators/test_logical_not_op.cpp b/test/operators/test_logical_not_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..55d48f79b72a05a74b6d13e4095f25ddfb4e8cbd --- /dev/null +++ b/test/operators/test_logical_not_op.cpp @@ -0,0 +1,76 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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 "../test_include.h" +#include "operators/logical_op.h" + +namespace paddle_mobile { + +void LogicalNot(const framework::Tensor *inputX, framework::Tensor *output) { + auto x_data = inputX->data(); + auto output_data = output->data(); + for (int i = 0; i < inputX->numel(); ++i) { + *output_data = !*x_data; + x_data++; + output_data++; + } +} + +int TestLogicalNotOp(const std::vector input_shape) { + framework::DDim input_dims = framework::make_ddim(input_shape); + VariableNameMap inputs; + VariableNameMap outputs; + auto scope = std::make_shared(); + inputs["X"] = std::vector({"inputX"}); + outputs["Out"] = std::vector({"output"}); + + auto x_var = scope.get()->Var("inputX"); + auto x = x_var->template GetMutable(); + SetupTensor(x, input_dims, 0, 1); + + auto output_var = scope.get()->Var("output"); + framework::AttributeMap attrs; + + auto *op = new operators::LogicalNotOp("logical_not", inputs, + outputs, attrs, scope); + + op->InferShape(); + op->Init(); + op->Run(); + + auto output = output_var->template Get(); + framework::Tensor output_cmp; + bool *output_cmp_data = output_cmp.mutable_data(output->dims()); + LogicalNot(x, &output_cmp); + + const bool *output_data = output->data(); + for (int i = 0; i < output->numel(); ++i) { + if (output_data[i] != output_cmp_data[i]) { + LOG(kLOG_INFO) << "output_data[" << i << "] = " << output_data[i] + << ", output_cmp_data[" << i + << "] = " << output_cmp_data[i]; + delete op; + exit(1); + } + } +} +} // namespace paddle_mobile + +int main() { + paddle_mobile::TestLogicalNotOp({1, 1, 2, 3}); + paddle_mobile::TestLogicalNotOp({1, 3, 11, 12}); + paddle_mobile::TestLogicalNotOp({1, 16, 32, 32}); + DLOG << "test logical_not op pass."; + return 0; +} diff --git a/test/operators/test_logical_or_op.cpp b/test/operators/test_logical_or_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..593ee35e696ebc392496846d8beb244210d1ec88 --- /dev/null +++ b/test/operators/test_logical_or_op.cpp @@ -0,0 +1,84 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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 "../test_include.h" +#include "operators/logical_op.h" + +namespace paddle_mobile { + +void LogicalOr(const framework::Tensor *inputX, const framework::Tensor *inputY, + framework::Tensor *output) { + auto x_data = inputX->data(); + auto y_data = inputY->data(); + auto output_data = output->data(); + for (int i = 0; i < inputX->numel(); ++i) { + *output_data = *x_data || *y_data; + x_data++; + y_data++; + output_data++; + } +} + +int TestLogicalOrOp(const std::vector input_shape) { + framework::DDim input_dims = framework::make_ddim(input_shape); + VariableNameMap inputs; + VariableNameMap outputs; + auto scope = std::make_shared(); + inputs["X"] = std::vector({"inputX"}); + inputs["Y"] = std::vector({"inputY"}); + outputs["Out"] = std::vector({"output"}); + + auto x_var = scope.get()->Var("inputX"); + auto x = x_var->template GetMutable(); + SetupTensor(x, input_dims, 0, 1); + + auto y_var = scope.get()->Var("inputY"); + auto y = y_var->template GetMutable(); + SetupTensor(y, input_dims, 0, 1); + + auto output_var = scope.get()->Var("output"); + framework::AttributeMap attrs; + + auto *op = new operators::LogicalOrOp("logical_or", inputs, + outputs, attrs, scope); + + op->InferShape(); + op->Init(); + op->Run(); + + auto output = output_var->template Get(); + framework::Tensor output_cmp; + bool *output_cmp_data = output_cmp.mutable_data(output->dims()); + LogicalOr(x, y, &output_cmp); + + const bool *output_data = output->data(); + for (int i = 0; i < output->numel(); ++i) { + if (output_data[i] != output_cmp_data[i]) { + LOG(kLOG_INFO) << "output_data[" << i << "] = " << output_data[i] + << ", output_cmp_data[" << i + << "] = " << output_cmp_data[i]; + delete op; + exit(1); + } + } +} +} // namespace paddle_mobile + +int main() { + paddle_mobile::TestLogicalOrOp({1, 1, 2, 3}); + paddle_mobile::TestLogicalOrOp({1, 3, 11, 12}); + paddle_mobile::TestLogicalOrOp({1, 16, 32, 32}); + DLOG << "test logical_or op pass."; + return 0; +} diff --git a/test/operators/test_logical_xor_op.cpp b/test/operators/test_logical_xor_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b4ca4c826727a6493ce785f4fab97a4dfa809557 --- /dev/null +++ b/test/operators/test_logical_xor_op.cpp @@ -0,0 +1,86 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +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 "../test_include.h" +#include "operators/logical_op.h" + +namespace paddle_mobile { + +void LogicalXor(const framework::Tensor *inputX, + const framework::Tensor *inputY, framework::Tensor *output) { + auto x_data = inputX->data(); + auto y_data = inputY->data(); + auto output_data = output->data(); + for (int i = 0; i < inputX->numel(); ++i) { + bool x = *x_data; + bool y = *y_data; + *output_data = (x || y) && !(x && y); + x_data++; + y_data++; + output_data++; + } +} + +int TestLogicalXorOp(const std::vector input_shape) { + framework::DDim input_dims = framework::make_ddim(input_shape); + VariableNameMap inputs; + VariableNameMap outputs; + auto scope = std::make_shared(); + inputs["X"] = std::vector({"inputX"}); + inputs["Y"] = std::vector({"inputY"}); + outputs["Out"] = std::vector({"output"}); + + auto x_var = scope.get()->Var("inputX"); + auto x = x_var->template GetMutable(); + SetupTensor(x, input_dims, 0, 1); + + auto y_var = scope.get()->Var("inputY"); + auto y = y_var->template GetMutable(); + SetupTensor(y, input_dims, 0, 1); + + auto output_var = scope.get()->Var("output"); + framework::AttributeMap attrs; + + auto *op = new operators::LogicalXorOp("logical_xor", inputs, + outputs, attrs, scope); + + op->InferShape(); + op->Init(); + op->Run(); + + auto output = output_var->template Get(); + framework::Tensor output_cmp; + bool *output_cmp_data = output_cmp.mutable_data(output->dims()); + LogicalXor(x, y, &output_cmp); + + const bool *output_data = output->data(); + for (int i = 0; i < output->numel(); ++i) { + if (output_data[i] != output_cmp_data[i]) { + LOG(kLOG_INFO) << "output_data[" << i << "] = " << output_data[i] + << ", output_cmp_data[" << i + << "] = " << output_cmp_data[i]; + delete op; + exit(1); + } + } +} +} // namespace paddle_mobile + +int main() { + paddle_mobile::TestLogicalXorOp({1, 1, 2, 3}); + paddle_mobile::TestLogicalXorOp({1, 3, 11, 12}); + paddle_mobile::TestLogicalXorOp({1, 16, 32, 32}); + DLOG << "test logical_xor op pass."; + return 0; +} diff --git a/test/test_helper.h b/test/test_helper.h index a760fa7ff05a528be9109b6589c625cce208e9c7..652283494f48b1cc1c1b87a791a5111bd9386fd4 100644 --- a/test/test_helper.h +++ b/test/test_helper.h @@ -83,6 +83,26 @@ void SetupTensor(paddle_mobile::framework::Tensor *input, } } +template <> +void SetupTensor(paddle_mobile::framework::Tensor *input, + paddle_mobile::framework::DDim dims, bool lower, + bool upper) { + static unsigned int seed = 100; + std::mt19937 rng(seed++); + std::uniform_real_distribution uniform_dist(0, 1); + + bool *input_ptr = input->mutable_data(dims); + if (lower == upper) { + for (int i = 0; i < input->numel(); ++i) { + input_ptr[i] = lower; + } + } else { + for (int i = 0; i < input->numel(); ++i) { + input_ptr[i] = uniform_dist(rng) > 0.5; + } + } +} + template T *CreateInput(Tensor *input, DDim dims, T low, T up) { SetupTensor(input, dims, static_cast(low), static_cast(up)); diff --git a/tools/ci_build.sh b/tools/ci_build.sh index 3697f01063af1844bc7721f77cb31f370069d419..f21bcdc67e6f73f61e0b33558672ac61fdf0fb22 100755 --- a/tools/ci_build.sh +++ b/tools/ci_build.sh @@ -26,6 +26,7 @@ function print_usage() { ${BLUE}ios${NONE}: run build for apple ios platform ${BLUE}linux_armv7${NONE}: run build for linux armv7 platform ${BLUE}linux_armv8${NONE}: run build for linux armv8 platform + ${BLUE}fpga${NONE}: run build for fpga platform " echo "\n${RED}Network${NONE}: optional, for deep compressing the framework size ${BLUE}googlenet${NONE}: build only googlenet support @@ -146,6 +147,7 @@ function build_ios_armv8_cpu_only() { -DIOS_PLATFORM=OS \ -DIOS_ARCH="${IOS_ARCH}" \ -DIS_IOS=true \ + -DUSE_OPENMP=OFF \ -DGPU_MALI=OFF \ -DGPU_CL=OFF \ -DFPGA=OFF @@ -163,6 +165,7 @@ function build_ios_armv8_gpu() { -DIOS_PLATFORM=OS \ -DIOS_ARCH="${IOS_ARCH}" \ -DIS_IOS=true \ + -DUSE_OPENMP=OFF \ -DGPU_MALI=OFF \ -DGPU_CL=ON \ -DFPGA=OFF @@ -217,11 +220,19 @@ function build_ios() { } function build_linux_armv7() { - check_ndk build_linux_armv7_cpu_only # build_linux_armv7_gpu } +function build_linux_fpga() { + cd .. + image=`docker images paddle-mobile:dev | grep 'paddle-mobile'` + if [[ "x"$image == "x" ]]; then + docker build -t paddle-mobile:dev - < Dockerfile + fi + docker run --rm -v `pwd`:/workspace paddle-mobile:dev bash /workspace/tools/docker_build_fpga.sh +} + function main() { local CMD=$1 init @@ -238,6 +249,9 @@ function main() { linux_armv7) build_linux_armv7 ;; + fpga) + build_linux_fpga + ;; *) print_usage exit 0 diff --git a/tools/docker_build_fpga.sh b/tools/docker_build_fpga.sh new file mode 100644 index 0000000000000000000000000000000000000000..0927c328dd41b87f77adf19d514703e7bcafbce8 --- /dev/null +++ b/tools/docker_build_fpga.sh @@ -0,0 +1,6 @@ +apt-get update +apt-get install -y gcc g++ cmake + +cd /workspace && mkdir build +cd build && cmake .. -DCPU=OFF -DFPGA=ON && make -j4 + diff --git a/tools/op.cmake b/tools/op.cmake index b14dfdacf6051d6edc57934cc25841f346e9d0df..65afb07054e107dfc29d27c7ce547f926b318df0 100644 --- a/tools/op.cmake +++ b/tools/op.cmake @@ -281,6 +281,13 @@ if(NOT FOUND_MATCH) set(TANH_OP ON) set(LOD_RESET_OP ON) set(LESS_THAN_OP ON) + set(LOGICAL_AND_OP ON) + set(LOGICAL_OR_OP ON) + set(LOGICAL_NOT_OP ON) + set(LOGICAL_XOR_OP ON) + set(WHILE_OP ON) + set(WRITE_TO_ARRAY_OP ON) + set(READ_FROM_ARRAY_OP ON) endif() # option(BATCHNORM_OP "" ON) @@ -530,6 +537,18 @@ endif() if (LESS_THAN_OP) add_definitions(-DLESS_THAN_OP) endif() +if (LOGICAL_AND_OP) + add_definitions(-DLOGICAL_AND_OP) +endif() +if (LOGICAL_OR_OP) + add_definitions(-DLOGICAL_OR_OP) +endif() +if (LOGICAL_NOT_OP) + add_definitions(-DLOGICAL_NOT_OP) +endif() +if (LOGICAL_XOR_OP) + add_definitions(-DLOGICAL_XOR_OP) +endif() if (TANH_OP) add_definitions(-DTANH_OP) @@ -543,3 +562,13 @@ endif() if (FUSION_DECONVADDRELU_OP) add_definitions(-DFUSION_DECONVADDRELU_OP) endif() + +if (WHILE_OP) + add_definitions(-DWHILE_OP) +endif() +if (WRITE_TO_ARRAY_OP) + add_definitions(-DWRITE_TO_ARRAY_OP) +endif() +if (READ_FROM_ARRAY_OP) + add_definitions(-DREAD_FROM_ARRAY_OP) +endif()