Skip to content

Commit

Permalink
feat: chain uses dto end to end
Browse files Browse the repository at this point in the history
Improved performances (0 copy, no expensive structured data conversion)
Can only be used when linking to deepdetect for now
  • Loading branch information
Bycob authored and mergify[bot] committed Sep 20, 2021
1 parent 3770baf commit 5efbf28
Show file tree
Hide file tree
Showing 21 changed files with 853 additions and 172 deletions.
19 changes: 13 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ OPTION(USE_JSON_API "build internal JSON API" ON)
OPTION(USE_HTTP_SERVER "build cppnet-lib version of http JSON API " OFF)
OPTION(USE_HTTP_SERVER_OATPP "build oatpp version of http JSON API" ON)

# user set variables
set(USE_OPENCV_VERSION CACHE STRING "OpenCV Version used by DeepDetect")

# Get the current working branch
execute_process(
COMMAND git rev-parse --abbrev-ref HEAD
Expand Down Expand Up @@ -569,12 +572,16 @@ if (USE_TF)
endif() # USE_TF

# OpenCV
find_package(OpenCV 3 QUIET COMPONENTS core imgproc highgui imgcodecs)
if (NOT OpenCV_FOUND)
find_package(OpenCV 4 QUIET COMPONENTS core imgproc highgui imgcodecs)
endif()
if (NOT OpenCV_FOUND)
find_package(OpenCV 2 REQUIRED COMPONENTS core imgproc highgui imgcodecs)
if (USE_OPENCV_VERSION STREQUAL "")
find_package(OpenCV 3 QUIET COMPONENTS core imgproc highgui imgcodecs)
if (NOT OpenCV_FOUND)
find_package(OpenCV 4 QUIET COMPONENTS core imgproc highgui imgcodecs)
endif()
if (NOT OpenCV_FOUND)
find_package(OpenCV 2 REQUIRED COMPONENTS core imgproc highgui imgcodecs)
endif()
else()
find_package(OpenCV ${USE_OPENCV_VERSION} REQUIRED COMPONENTS core imgproc highgui imgcodecs)
endif()
set(OPENCV_VERSION ${OpenCV_VERSION_MAJOR})
include_directories(${OpenCV_INCLUDE_DIRS})
Expand Down
19 changes: 4 additions & 15 deletions src/backends/dlib/dlib_actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,12 @@ namespace dd
std::vector<std::string> bbox_ids;

// check for action parameters
double bratio = 0.25;
int chip_size = 150;
if (_params.has("padding_ratio"))
{
bratio = _params.get("padding_ratio").get<double>(); // e.g. 0.055
}
if (_params.has("chip_size"))
{
chip_size = _params.get("chip_size").get<int>(); // in pixels
}
double bratio
= _params->padding_ratio != nullptr ? _params->padding_ratio : 0.25;
int chip_size = _params->chip_size;
std::vector<APIData> cvad;

bool save_crops = false;
if (_params.has("save_crops"))
{
save_crops = _params.get("save_crops").get<bool>();
}
bool save_crops = _params->save_crops;

// iterate image batch
for (size_t i = 0; i < vad.size(); i++)
Expand Down
5 changes: 3 additions & 2 deletions src/backends/dlib/dlib_actions.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ namespace dd
class DlibAlignCropAction : public ChainAction
{
public:
DlibAlignCropAction(const APIData &adc, const std::string &action_id,
DlibAlignCropAction(oatpp::Object<DTO::ChainCall> call_dto,
const std::string &action_id,
const std::string &action_type,
const std::shared_ptr<spdlog::logger> chain_logger)
: ChainAction(adc, action_id, action_type, chain_logger)
: ChainAction(call_dto, action_id, action_type, chain_logger)
{
}

Expand Down
8 changes: 4 additions & 4 deletions src/backends/tensorrt/tensorrtinputconns.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,15 @@ namespace dd
}
}

void ImgTensorRTInputFileConn::transform(const APIData &ad)
void ImgTensorRTInputFileConn::transform(
oatpp::Object<DTO::ServicePredict> input_dto)
{

if (ad.has("has_mean_file"))
if (input_dto->has_mean_file)
_logger->warn("mean file cannot be used with tensorRT backend");

try
{
ImgInputFileConn::transform(ad);
ImgInputFileConn::transform(input_dto);
}
catch (const std::exception &e)
{
Expand Down
2 changes: 1 addition & 1 deletion src/backends/tensorrt/tensorrtinputconns.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ namespace dd
ImgInputFileConn::init(ad);
}

void transform(const APIData &ad);
void transform(oatpp::Object<DTO::ServicePredict> input_dto);

std::string _meanfname = "mean.binaryproto";
std::string _correspname = "corresp.txt";
Expand Down
61 changes: 43 additions & 18 deletions src/backends/tensorrt/tensorrtlib.cc
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,35 @@ namespace dd
_net_mutex); // no concurrent calls since the net is not
// re-instantiated

auto predict_dto = ad.createSharedDTO<DTO::ServicePredict>();
oatpp::Object<DTO::ServicePredict> predict_dto;
// XXX: until everything is DTO, we consider the two cases:
// - either ad embeds a DTO, so we just have to retrieve it
// - or it's an APIData that must be converted to DTO
if (ad.has("dto"))
{
// cast to ServicePredict...
auto any = ad.get("dto").get<oatpp::Any>();
predict_dto = oatpp::Object<DTO::ServicePredict>(
std::static_pointer_cast<typename DTO::ServicePredict>(any->ptr));
}
else
{
predict_dto = ad.createSharedDTO<DTO::ServicePredict>();

if (ad.has("chain") && ad.get("chain").get<bool>())
predict_dto->_chain = true;
if (ad.has("data_raw_img"))
predict_dto->_data_raw_img
= ad.get("data_raw_img").get<std::vector<cv::Mat>>();
if (ad.has("ids"))
predict_dto->_ids = ad.get("ids").get<std::vector<std::string>>();
if (ad.has("meta_uris"))
predict_dto->_meta_uris
= ad.get("meta_uris").get<std::vector<std::string>>();
if (ad.has("index_uris"))
predict_dto->_index_uris
= ad.get("index_uris").get<std::vector<std::string>>();
}

if (predict_dto->parameters->mllib->gpuid->_ids.size() == 0)
throw MLLibBadParamException("empty gpuid vector");
Expand All @@ -438,17 +466,16 @@ namespace dd
= predict_dto->parameters->mllib->extract_layer->std_str();
}

// detect architecture
cudaDeviceProp prop;
cudaGetDeviceProperties(&prop, _gpuid);
std::string arch = std::to_string(prop.major) + std::to_string(prop.minor);
if (_first_predict)
this->_logger->info("GPU {} architecture = compute_{}", _gpuid, arch);

TInputConnectorStrategy inputc(this->_inputc);

if (!_TRTContextReady)
{
// detect architecture
cudaDeviceProp prop;
cudaGetDeviceProperties(&prop, _gpuid);
_arch = std::to_string(prop.major) + std::to_string(prop.minor);
this->_logger->info("GPU {} architecture = compute_{}", _gpuid, _arch);

_bbox = output_params->bbox;
_regression = output_params->regression;
_ctc = output_params->ctc;
Expand Down Expand Up @@ -512,7 +539,7 @@ namespace dd
+ std::to_string(bs));
}
std::ifstream file(this->_mlmodel._repo + "/" + _engineFileName
+ "_arch" + arch + "_bs"
+ "_arch" + _arch + "_bs"
+ std::to_string(bs),
std::ios::binary);
if (file.good())
Expand Down Expand Up @@ -562,7 +589,7 @@ namespace dd
if (_writeEngine)
{
std::ofstream p(this->_mlmodel._repo + "/" + _engineFileName
+ "_arch" + arch + "_bs"
+ "_arch" + _arch + "_bs"
+ std::to_string(_max_batch_size),
std::ios::binary);
nvinfer1::IHostMemory *trtModelStream = _engine->serialize();
Expand Down Expand Up @@ -674,13 +701,11 @@ namespace dd
}
}

APIData cad = ad;

TOutputConnectorStrategy tout(this->_outputc);
this->_stats.transform_start();
try
{
inputc.transform(cad);
inputc.transform(predict_dto);
}
catch (...)
{
Expand Down Expand Up @@ -994,20 +1019,20 @@ namespace dd
out.add("regression", true);
out.add("roi", false);
out.add("multibox_rois", false);
tout.finalize(ad.getobj("parameters").getobj("output"),
out, // TODO; to output_params DTO
tout.finalize(predict_dto->parameters->output,
out, // TODO; to output DTO
static_cast<MLModel *>(&this->_mlmodel));
}
else
{
UnsupervisedOutput unsupo;
unsupo.set_results(std::move(unsup_results));
unsupo.finalize(ad.getobj("parameters").getobj("output"),
out, // TODO: to output_params DTO
unsupo.finalize(predict_dto->parameters->output,
out, // TODO: to output DTO
static_cast<MLModel *>(&this->_mlmodel));
}

if (ad.has("chain") && ad.get("chain").get<bool>())
if (predict_dto->_chain)
{
if (typeid(inputc) == typeid(ImgTensorRTInputFileConn))
{
Expand Down
1 change: 1 addition & 0 deletions src/backends/tensorrt/tensorrtlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ namespace dd
std::string _engineFileName = "TRTengine";
bool _readEngine = true;
bool _writeEngine = true;
std::string _arch;
int _gpuid = 0;

//!< The TensorRT engine used to run the network
Expand Down
16 changes: 9 additions & 7 deletions src/backends/torch/torchdataset.cc
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,15 @@ namespace dd
float w_ratio = static_cast<float>(width) / bgr.cols;
float h_ratio = static_cast<float>(height) / bgr.rows;
cv::resize(bgr, bgr, cv::Size(width, height), 0, 0, cv::INTER_CUBIC);
for (int bb = 0; bb < (int)targett[0].size(0); ++bb)
{
targett[0][bb][0] *= w_ratio;
targett[0][bb][1] *= h_ratio;
targett[0][bb][2] *= w_ratio;
targett[0][bb][3] *= h_ratio;
}

if (_bbox)
for (int bb = 0; bb < (int)targett[0].size(0); ++bb)
{
targett[0][bb][0] *= w_ratio;
targett[0][bb][1] *= h_ratio;
targett[0][bb][2] *= w_ratio;
targett[0][bb][3] *= h_ratio;
}
}
}

Expand Down
20 changes: 20 additions & 0 deletions src/chain.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,26 @@

namespace dd
{
/**
* \brief Chain bad parameter exception
*/
class ChainBadParamException : public std::exception
{
public:
ChainBadParamException(const std::string &s) : _s(s)
{
}
~ChainBadParamException()
{
}
const char *what() const noexcept
{
return _s.c_str();
}

private:
std::string _s;
};

/**
* \brief chain temporary data in between service calls
Expand Down
74 changes: 26 additions & 48 deletions src/chain_actions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,31 +47,18 @@ namespace dd
std::vector<std::string> bbox_ids;

// check for action parameters
double bratio = 0.0;
if (_params.has("padding_ratio"))
bratio = _params.get("padding_ratio").get<double>(); // e.g. 0.055

bool save_crops = false;
if (_params.has("save_crops"))
save_crops = _params.get("save_crops").get<bool>();

std::string save_path;
if (_params.has("save_path"))
save_path = _params.get("save_path").get<std::string>() + "/";

bool to_rgb = false;
if (_params.has("to_rgb"))
to_rgb = _params.get("to_rgb").get<bool>();
bool to_bgr = false;
if (_params.has("to_bgr"))
to_bgr = _params.get("to_bgr").get<bool>();

int fixed_width = 0;
if (_params.has("fixed_width"))
fixed_width = _params.get("fixed_width").get<int>();
int fixed_height = 0;
if (_params.has("fixed_height"))
fixed_height = _params.get("fixed_height").get<int>();
double bratio = _params->padding_ratio;
bool save_crops = _params->save_crops;

std::string save_path = _params->save_path->std_str();
if (!save_path.empty())
save_path += "/";

bool to_rgb = _params->to_rgb;
bool to_bgr = _params->to_bgr;

int fixed_width = _params->fixed_width;
int fixed_height = _params->fixed_height;

std::vector<APIData> cvad;

Expand Down Expand Up @@ -209,17 +196,12 @@ namespace dd
std::vector<std::string> uris;

// check for action parameters
std::string orientation = "relative"; // other: absolute
if (_params.has("orientation"))
orientation = _params.get("orientation").get<std::string>();
std::string orientation = _params->orientation->std_str();
bool save_img = _params->save_img;

bool save_img = false;
if (_params.has("save_img"))
save_img = _params.get("save_img").get<bool>();

std::string save_path;
if (_params.has("save_path"))
save_path = _params.get("save_path").get<std::string>() + "/";
std::string save_path = _params->save_path->std_str();
if (!save_path.empty())
save_path += "/";

for (size_t i = 0; i < vad.size(); i++) // iterate predictions
{
Expand Down Expand Up @@ -281,16 +263,14 @@ namespace dd

void ClassFilter::apply(APIData &model_out, ChainData &cdata)
{
if (!_params.has("classes"))
if (_params->classes == nullptr)
{
throw ActionBadParamException(
"filter action is missing classes parameter");
}
std::vector<std::string> on_classes
= _params.get("classes").get<std::vector<std::string>>();
std::unordered_set<std::string> on_classes_us;
for (auto s : on_classes)
on_classes_us.insert(s);
for (auto s : *_params->classes)
on_classes_us.insert(s->std_str());
std::unordered_set<std::string>::const_iterator usit;

std::vector<APIData> vad = model_out.getv("predictions");
Expand Down Expand Up @@ -329,24 +309,22 @@ namespace dd
const std::string &action_type, APIData &model_out, ChainData &cdata,
const std::shared_ptr<spdlog::logger> &chain_logger)
{
std::string action_id;
if (_adc.has("id"))
action_id = _adc.get("id").get<std::string>();
else
action_id = std::to_string(cdata._action_data.size());
std::string action_id = _call_dto->id != nullptr
? _call_dto->id->std_str()
: std::to_string(cdata._action_data.size());
if (action_type == "crop")
{
ImgsCropAction act(_adc, action_id, action_type, chain_logger);
ImgsCropAction act(_call_dto, action_id, action_type, chain_logger);
act.apply(model_out, cdata);
}
else if (action_type == "rotate")
{
ImgsRotateAction act(_adc, action_id, action_type, chain_logger);
ImgsRotateAction act(_call_dto, action_id, action_type, chain_logger);
act.apply(model_out, cdata);
}
else if (action_type == "filter")
{
ClassFilter act(_adc, action_id, action_type, chain_logger);
ClassFilter act(_call_dto, action_id, action_type, chain_logger);
act.apply(model_out, cdata);
}
#ifdef USE_DLIB
Expand Down
Loading

0 comments on commit 5efbf28

Please sign in to comment.