Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build mobile inference library for minimum size #4509

Merged
merged 9 commits into from
Oct 9, 2017
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,18 @@ if(ANDROID OR IOS)
"Disable MKLDNN when cross-compiling for Android and iOS" FORCE)
set(WITH_MKLML OFF CACHE STRING
"Disable MKLML package when cross-compiling for Android and iOS" FORCE)

# Compile PaddlePaddle mobile inference library
if (NOT WITH_C_API)
set(WITH_C_API ON CACHE STRING
"Always compile the C_API when cross-compiling for Android and iOS" FORCE)
endif()
set(MOBILE_INFERENCE ON)
add_definitions(-DPADDLE_MOBILE_INFERENCE)

# TODO: Need Open the WITH_TESTING
set(WITH_TESTING OFF CACHE STRING "Disable TESTING when cross-compiling
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to not set WITH_TESTING to OFF, because it is useful to check the linking error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that the WITH_TESTING switch needs to be opened, but this PR will lead to some test program compiler failure, so I turn off the WITH_TESTING for temporarily.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

for Android and iOS" FORCE)
endif()

set(THIRD_PARTY_PATH "${CMAKE_BINARY_DIR}/third_party" CACHE STRING
Expand Down Expand Up @@ -160,9 +172,11 @@ endif(USE_NNPACK)

add_subdirectory(proto)

# "add_subdirectory(go)" should be placed after the following loine,
# because it depends on paddle/optimizer.
add_subdirectory(paddle/optimizer)
if(NOT MOBILE_INFERENCE)
# "add_subdirectory(go)" should be placed after the following loine,
# because it depends on paddle/optimizer.
add_subdirectory(paddle/optimizer)
endif()

# "add_subdirectory(paddle)" and "add_subdirectory(python)" should be
# placed after this block, because they depends on it.
Expand Down
56 changes: 37 additions & 19 deletions cmake/util.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -73,25 +73,43 @@ function(link_paddle_exe TARGET_NAME)
generate_rdma_links()
endif()

target_circle_link_libraries(${TARGET_NAME}
ARCHIVE_START
paddle_gserver
paddle_function
ARCHIVE_END
paddle_pserver
paddle_trainer_lib
paddle_network
paddle_math
paddle_utils
paddle_parameter
paddle_proto
paddle_cuda
paddle_optimizer
${EXTERNAL_LIBS}
${CMAKE_THREAD_LIBS_INIT}
${CMAKE_DL_LIBS}
${RDMA_LD_FLAGS}
${RDMA_LIBS})
if(MOBILE_INFERENCE)
target_circle_link_libraries(${TARGET_NAME}
ARCHIVE_START
paddle_gserver
paddle_function
ARCHIVE_END
paddle_math
paddle_utils
paddle_parameter
paddle_proto
paddle_cuda
${EXTERNAL_LIBS}
${CMAKE_THREAD_LIBS_INIT}
${CMAKE_DL_LIBS}
${RDMA_LD_FLAGS}
${RDMA_LIBS})
else()
target_circle_link_libraries(${TARGET_NAME}
ARCHIVE_START
paddle_gserver
paddle_function
ARCHIVE_END
paddle_pserver
paddle_trainer_lib
paddle_network
paddle_math
paddle_utils
paddle_parameter
paddle_proto
paddle_cuda
paddle_optimizer
${EXTERNAL_LIBS}
${CMAKE_THREAD_LIBS_INIT}
${CMAKE_DL_LIBS}
${RDMA_LD_FLAGS}
${RDMA_LIBS})
endif()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can use a new variable to specify which modules need to link, like:

if(MOBILE_INFERENCE)
    set(PADDLE_LIBS
        paddle_math
        paddle_utils
        paddle_parameter
        paddle_proto
        paddle_cuda
        )
else()
    set(PADDLE_LIBS
        paddle_pserver
        paddle_trainer_lib
        paddle_network
        paddle_math
        paddle_utils
        paddle_parameter
        paddle_proto
        paddle_cuda
        paddle_optimizer         
        )
endif()
target_circle_link_libraries(${TARGET_NAME}
        ARCHIVE_START
        paddle_gserver
        paddle_function
        ARCHIVE_END
        ${PADDLE_LIBS}
        ${EXTERNAL_LIBS}
        ${CMAKE_THREAD_LIBS_INIT}
        ${CMAKE_DL_LIBS}
        ${RDMA_LD_FLAGS}
        ${RDMA_LIBS})
 endif()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will fix this commit in the next pr.


if(ANDROID)
target_link_libraries(${TARGET_NAME} log)
Expand Down
41 changes: 23 additions & 18 deletions paddle/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
add_subdirectory(cuda)
add_subdirectory(function)
add_subdirectory(utils)
add_subdirectory(testing)
add_subdirectory(math)
add_subdirectory(parameter)
add_subdirectory(gserver)
add_subdirectory(pserver)
add_subdirectory(trainer)
add_subdirectory(scripts)
add_subdirectory(string)

if(Boost_FOUND)
add_subdirectory(memory)
add_subdirectory(platform)
add_subdirectory(framework)
add_subdirectory(operators)
add_subdirectory(pybind)
endif()
add_subdirectory(parameter)
add_subdirectory(testing)

if(WITH_C_API)
if(MOBILE_INFERENCE)
add_subdirectory(capi)
endif()
else()
add_subdirectory(pserver)
add_subdirectory(trainer)
add_subdirectory(string)
add_subdirectory(scripts)

if(WITH_C_API)
add_subdirectory(capi)
endif()

if(Boost_FOUND)
add_subdirectory(memory)
add_subdirectory(platform)
add_subdirectory(framework)
add_subdirectory(operators)
add_subdirectory(pybind)
endif()

if(WITH_SWIG_PY)
add_subdirectory(api)
if(WITH_SWIG_PY)
add_subdirectory(api)
endif()
endif()
4 changes: 1 addition & 3 deletions paddle/capi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ set(PADDLE_CAPI_INFER_LIBS
paddle_cuda
paddle_function
paddle_gserver
paddle_proto
paddle_pserver
paddle_network)
paddle_proto)

cc_library(paddle_capi_whole DEPS paddle_capi ${PADDLE_CAPI_INFER_LIBS})

Expand Down
30 changes: 30 additions & 0 deletions paddle/gserver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,36 @@ if(NOT WITH_PYTHON)
dataproviders/PyDataProvider.h)
endif()

if(MOBILE_INFERENCE)
# Remove evaluators
list(REMOVE_ITEM GSERVER_SOURCES
layers/ValidationLayer.cpp
evaluators/Evaluator.cpp
evaluators/DetectionMAPEvaluator.cpp
evaluators/CTCErrorEvaluator.cpp
evaluators/ChunkEvaluator.cpp)

# Remove dataproviders
list(REMOVE_ITEM GSERVER_SOURCES
dataproviders/DataProvider.cpp
dataproviders/MultiDataProvider.cpp
dataproviders/ProtoDataProvider.cpp
dataproviders/PyDataProvider2.cpp
dataproviders/PyDataProvider.cpp)

# Remove useless gradientmachines
list(REMOVE_ITEM GSERVER_SOURCES
gradientmachines/MultiNetwork.cpp
gradientmachines/RecurrentGradientMachine.cpp
gradientmachines/ParallelNeuralNetwork.cpp
gradientmachines/GradientMachineMode.cpp
gradientmachines/MultiGradientMachine.cpp)

# Remove useless layers
list(REMOVE_ITEM GSERVER_SOURCES
layers/RecurrentLayerGroup.cpp)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure whether layers/RecurrentLayerGroup.cpp can be removed.
And cost layers can be removed too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For RecurrentLayerGroup.cpp, first remove Evaluator, then remove the RecurrentGradientMachine which depends on Evaluator, and last remove 'RecurrentLayerGroup' which depends on 'RecurrentGradientMachine'.

For cost layers, can be considered in the next PR.

endif()

if(WITH_GPU)
cuda_add_library(paddle_gserver ${GSERVER_SOURCES})
else()
Expand Down
13 changes: 11 additions & 2 deletions paddle/gserver/gradientmachines/GradientMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,32 @@ limitations under the License. */
#include <fstream>
#include "paddle/utils/Logging.h"

#include "NeuralNetwork.h"
#include "hl_gpu.h"

#ifndef PADDLE_MOBILE_INFERENCE
#include "GradientMachineMode.h"
#include "MultiGradientMachine.h"
#include "MultiNetwork.h"
#include "NeuralNetwork.h"
#include "ParallelNeuralNetwork.h"
#include "hl_gpu.h"
#endif

namespace paddle {

GradientMachine* GradientMachine::create(
const ModelConfig& config,
int mode,
const std::vector<ParameterType>& parameterTypes) {
#ifndef PADDLE_MOBILE_INFERENCE
if (auto gm = IGradientMachineMode::tryCreateGradientMachine(mode, config)) {
return gm;
}
if (FLAGS_trainer_count > 1) {
return new MultiGradientMachine(config, FLAGS_use_gpu);
}
#endif
if (FLAGS_trainer_count == 1) { // single
#ifndef PADDLE_MOBILE_INFERENCE
NeuralNetwork* nn;
if (config.type() == "multi_nn") {
/* multi submodel calculate, thread(s) will be initialized inside */
Expand All @@ -48,6 +54,9 @@ GradientMachine* GradientMachine::create(
/* single thread calculate */
nn = NeuralNetwork::create(config);
}
#else
NeuralNetwork* nn = NeuralNetwork::create(config);
#endif
ParamInitCallback testParamInitCb = [](int paramId, Parameter* para) {
para->enableType(PARAMETER_VALUE);
};
Expand Down
7 changes: 6 additions & 1 deletion paddle/gserver/gradientmachines/GradientMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@ limitations under the License. */
#include "ModelConfig.pb.h"
#include "TrainerConfig.pb.h"
#include "paddle/gserver/dataproviders/DataProvider.h"
#include "paddle/gserver/evaluators/Evaluator.h"
#include "paddle/gserver/layers/Layer.h"
#include "paddle/math/Matrix.h"
#include "paddle/parameter/Parameter.h"
#include "paddle/parameter/ParameterUpdaterBase.h"
#include "paddle/utils/Thread.h"

#ifndef PADDLE_MOBILE_INFERENCE
#include "paddle/gserver/evaluators/Evaluator.h"
#endif

namespace paddle {
/**
* @brief A gradient machine is capable of calculating some outputs given
Expand Down Expand Up @@ -147,6 +150,7 @@ class GradientMachine {

virtual void onPassEnd() = 0;

#ifndef PADDLE_MOBILE_INFERENCE
/**
* Create an evaluator which can be used for eval()
*/
Expand All @@ -156,6 +160,7 @@ class GradientMachine {
* evaluate using the given evaluator
*/
virtual void eval(Evaluator* evaluator) const = 0;
#endif

std::vector<ParameterPtr>& getParameters() { return parameters_; }

Expand Down
18 changes: 14 additions & 4 deletions paddle/gserver/gradientmachines/NeuralNetwork.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ limitations under the License. */

#include "paddle/utils/Util.h"

#include "NeuralNetwork.h"
#include "hl_gpu.h"
#include "paddle/gserver/layers/AgentLayer.h"
#include "paddle/utils/CustomStackTrace.h"
#include "paddle/utils/Logging.h"
#include "paddle/utils/Stat.h"

#ifndef PADDLE_MOBILE_INFERENCE
#include "MultiNetwork.h"
#include "NeuralNetwork.h"
#include "RecurrentGradientMachine.h"
#include "hl_gpu.h"
#include "paddle/gserver/layers/AgentLayer.h"
#include "paddle/utils/Stat.h"
#endif

namespace paddle {
void parameterInitNN(int paramId,
Expand Down Expand Up @@ -54,13 +56,17 @@ void parameterInitNN(int paramId,
}

NeuralNetwork* NeuralNetwork::create(const ModelConfig& config) {
#ifndef PADDLE_MOBILE_INFERENCE
if (config.type() == "recurrent_nn") {
return newNeuralNetwork("root");
} else if (config.type() == "multi_nn") {
return new MultiNetwork("root");
} else {
return newNeuralNetwork();
}
#else
return new NeuralNetwork();
#endif
}

std::map<std::string, bool> NeuralNetwork::dllInitMap;
Expand Down Expand Up @@ -304,6 +310,8 @@ void NeuralNetwork::onPassEnd() {
}
}

#ifndef PADDLE_MOBILE_INFERENCE

class CombinedEvaluator : public Evaluator {
public:
void addEvaluator(std::unique_ptr<Evaluator>&& evaluator) {
Expand Down Expand Up @@ -466,6 +474,8 @@ Evaluator* NeuralNetwork::makeEvaluator() const {

void NeuralNetwork::eval(Evaluator* evaluator) const { evaluator->eval(*this); }

#endif

void NeuralNetwork::setOutputGrad(const std::vector<Argument>& args) {
CHECK_GE(outputLayers_.size(), args.size());
for (size_t i = 0; i < args.size(); ++i) {
Expand Down
3 changes: 3 additions & 0 deletions paddle/gserver/gradientmachines/NeuralNetwork.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,12 @@ class NeuralNetwork : public GradientMachine {

virtual void onPassEnd();

#ifndef PADDLE_MOBILE_INFERENCE
virtual Evaluator* makeEvaluator() const;

virtual void eval(Evaluator* evaluator) const;
#endif

virtual void resetState();
virtual void setOutputGrad(const std::vector<Argument>& args);

Expand Down
2 changes: 2 additions & 0 deletions paddle/gserver/layers/Layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,12 @@ LayerPtr Layer::create(const LayerConfig& config) {
return LayerPtr(new MultiClassCrossEntropy(config));
else if (type == "rank-cost")
return LayerPtr(new RankingCost(config));
#ifndef PADDLE_MOBILE_INFERENCE
else if (type == "auc-validation")
return LayerPtr(new AucValidation(config));
else if (type == "pnpair-validation")
return LayerPtr(new PnpairValidation(config));
#endif

return LayerPtr(registrar_.createByType(config.type(), config));
}
Expand Down