From 7abcca007eb8d8221af4aa9346be9dcdd10f3f09 Mon Sep 17 00:00:00 2001 From: Lin Yuan Date: Mon, 7 Jan 2019 16:53:03 -0800 Subject: [PATCH 1/9] add extra header file to include --- include/mxnet/c_api_common.h | 146 +++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 include/mxnet/c_api_common.h diff --git a/include/mxnet/c_api_common.h b/include/mxnet/c_api_common.h new file mode 100644 index 000000000000..079b587e9965 --- /dev/null +++ b/include/mxnet/c_api_common.h @@ -0,0 +1,146 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +/*! + * Copyright (c) 2015 by Contributors + * \file c_api_error.h + * \brief Error handling for C API. + */ +#ifndef MXNET_C_API_C_API_COMMON_H_ +#define MXNET_C_API_C_API_COMMON_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +/*! \brief macro to guard beginning and end section of all functions */ +#define API_BEGIN() try { on_enter_api(__FUNCTION__); +/*! \brief every function starts with API_BEGIN(); + and finishes with API_END() or API_END_HANDLE_ERROR */ +#define API_END() } catch(dmlc::Error &_except_) { on_exit_api(); return MXAPIHandleException(_except_); } on_exit_api(); return 0; // NOLINT(*) +/*! + * \brief every function starts with API_BEGIN(); + * and finishes with API_END() or API_END_HANDLE_ERROR + * The finally clause contains procedure to cleanup states when an error happens. + */ +#define API_END_HANDLE_ERROR(Finalize) } catch(dmlc::Error &_except_) { Finalize; on_exit_api(); return MXAPIHandleException(_except_); } on_exit_api(); return 0; // NOLINT(*) + +/*! + * \brief Set the last error message needed by C API + * \param msg The error message to set. + */ +void MXAPISetLastError(const char* msg); +/*! + * \brief handle exception throwed out + * \param e the exception + * \return the return value of API after exception is handled + */ +inline int MXAPIHandleException(const dmlc::Error &e) { + MXAPISetLastError(e.what()); + return -1; +} + +using namespace mxnet; + +/*! \brief entry to to easily hold returning information */ +struct MXAPIThreadLocalEntry { + /*! \brief result holder for returning string */ + std::string ret_str; + /*! \brief result holder for returning strings */ + std::vector ret_vec_str; + /*! \brief result holder for returning string pointers */ + std::vector ret_vec_charp; + /*! \brief result holder for returning handles */ + std::vector ret_handles; + /*! \brief holder for NDArray handles */ + std::vector ndinputs, ndoutputs; + /*! \brief result holder for returning shapes */ + std::vector arg_shapes, out_shapes, aux_shapes; + /*! \brief result holder for returning type flags */ + std::vector arg_types, out_types, aux_types; + /*! \brief result holder for returning storage types */ + std::vector arg_storage_types, out_storage_types, aux_storage_types; + /*! \brief result holder for returning shape dimensions */ + std::vector arg_shape_ndim, out_shape_ndim, aux_shape_ndim; + /*! \brief result holder for returning shape pointer */ + std::vector arg_shape_data, out_shape_data, aux_shape_data; + /*! \brief uint32_t buffer for returning shape pointer */ + std::vector arg_shape_buffer, out_shape_buffer, aux_shape_buffer; + /*! \brief bool buffer */ + std::vector save_inputs, save_outputs; + // helper function to setup return value of shape array + inline static void SetupShapeArrayReturnWithBuffer( + const std::vector &shapes, + std::vector *ndim, + std::vector *data, + std::vector *buffer) { + ndim->resize(shapes.size()); + data->resize(shapes.size()); + size_t size = 0; + for (const auto& s : shapes) size += s.ndim(); + buffer->resize(size); + uint32_t *ptr = buffer->data(); + for (size_t i = 0; i < shapes.size(); ++i) { + ndim->at(i) = shapes[i].ndim(); + data->at(i) = ptr; + ptr = nnvm::ShapeTypeCast(shapes[i].begin(), shapes[i].end(), ptr); + } + } +}; + +// define the threadlocal store. +typedef dmlc::ThreadLocalStore MXAPIThreadLocalStore; + +namespace mxnet { +// copy attributes from inferred vector back to the vector of each type. +template +inline void CopyAttr(const nnvm::IndexedGraph& idx, + const std::vector& attr_vec, + std::vector* in_attr, + std::vector* out_attr, + std::vector* aux_attr) { + in_attr->clear(); + out_attr->clear(); + aux_attr->clear(); + for (uint32_t nid : idx.input_nodes()) { + if (idx.mutable_input_nodes().count(nid) == 0) { + in_attr->push_back(attr_vec[idx.entry_id(nid, 0)]); + } else { + aux_attr->push_back(attr_vec[idx.entry_id(nid, 0)]); + } + } + for (auto& e : idx.outputs()) { + out_attr->push_back(attr_vec[idx.entry_id(e)]); + } +} + +// stores keys that will be converted to __key__ +extern const std::vector kHiddenKeys; + +extern void on_enter_api(const char *function); +extern void on_exit_api(); + +} // namespace mxnet + +#endif // MXNET_C_API_C_API_COMMON_H_ From c4011783b46cc5c11e30281b120b37fce5a8a6af Mon Sep 17 00:00:00 2001 From: Lin Yuan Date: Mon, 7 Jan 2019 19:16:22 -0800 Subject: [PATCH 2/9] fix sanity check --- include/mxnet/c_api_common.h | 6 +++--- src/c_api/c_api_common.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/mxnet/c_api_common.h b/include/mxnet/c_api_common.h index 079b587e9965..7264058e38bb 100644 --- a/include/mxnet/c_api_common.h +++ b/include/mxnet/c_api_common.h @@ -22,8 +22,8 @@ * \file c_api_error.h * \brief Error handling for C API. */ -#ifndef MXNET_C_API_C_API_COMMON_H_ -#define MXNET_C_API_C_API_COMMON_H_ +#ifndef MXNET_C_API_COMMON_H_ +#define MXNET_C_API_COMMON_H_ #include #include @@ -143,4 +143,4 @@ extern void on_exit_api(); } // namespace mxnet -#endif // MXNET_C_API_C_API_COMMON_H_ +#endif // MXNET_C_API_COMMON_H_ diff --git a/src/c_api/c_api_common.h b/src/c_api/c_api_common.h index 079b587e9965..7264058e38bb 100644 --- a/src/c_api/c_api_common.h +++ b/src/c_api/c_api_common.h @@ -22,8 +22,8 @@ * \file c_api_error.h * \brief Error handling for C API. */ -#ifndef MXNET_C_API_C_API_COMMON_H_ -#define MXNET_C_API_C_API_COMMON_H_ +#ifndef MXNET_C_API_COMMON_H_ +#define MXNET_C_API_COMMON_H_ #include #include @@ -143,4 +143,4 @@ extern void on_exit_api(); } // namespace mxnet -#endif // MXNET_C_API_C_API_COMMON_H_ +#endif // MXNET_C_API_COMMON_H_ From bc849ccd9a9b1a9f824aade321ac28038b8ec5a6 Mon Sep 17 00:00:00 2001 From: Lin Yuan Date: Mon, 7 Jan 2019 21:31:56 -0800 Subject: [PATCH 3/9] fix sanity --- src/c_api/c_api_common.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/c_api/c_api_common.h b/src/c_api/c_api_common.h index 7264058e38bb..079b587e9965 100644 --- a/src/c_api/c_api_common.h +++ b/src/c_api/c_api_common.h @@ -22,8 +22,8 @@ * \file c_api_error.h * \brief Error handling for C API. */ -#ifndef MXNET_C_API_COMMON_H_ -#define MXNET_C_API_COMMON_H_ +#ifndef MXNET_C_API_C_API_COMMON_H_ +#define MXNET_C_API_C_API_COMMON_H_ #include #include @@ -143,4 +143,4 @@ extern void on_exit_api(); } // namespace mxnet -#endif // MXNET_C_API_COMMON_H_ +#endif // MXNET_C_API_C_API_COMMON_H_ From 8c78edd9d4b49303de30bf9029e9e27380eb7e46 Mon Sep 17 00:00:00 2001 From: Lin Yuan Date: Mon, 7 Jan 2019 23:49:17 -0800 Subject: [PATCH 4/9] move c_api_common.h to include folder --- plugin/opencv/cv_api.cc | 2 +- src/c_api/c_api.cc | 2 +- src/c_api/c_api_common.h | 146 ------------------------------ src/c_api/c_api_error.cc | 1 - src/c_api/c_api_executor.cc | 2 +- src/c_api/c_api_function.cc | 2 +- src/c_api/c_api_ndarray.cc | 2 +- src/c_api/c_api_profile.cc | 2 +- src/c_api/c_api_symbolic.cc | 2 +- src/c_api/c_api_test.cc | 2 +- src/c_api/c_predict_api.cc | 2 +- src/imperative/imperative_utils.h | 2 +- src/nnvm/legacy_json_util.cc | 2 +- 13 files changed, 11 insertions(+), 158 deletions(-) delete mode 100644 src/c_api/c_api_common.h diff --git a/plugin/opencv/cv_api.cc b/plugin/opencv/cv_api.cc index 53eb8524c7cf..cc828c817e1f 100644 --- a/plugin/opencv/cv_api.cc +++ b/plugin/opencv/cv_api.cc @@ -26,9 +26,9 @@ #include #include #include +#include #include #include "cv_api.h" -#include "../../src/c_api/c_api_common.h" using namespace mxnet; diff --git a/src/c_api/c_api.cc b/src/c_api/c_api.cc index 80bd60538ff5..a59981484f0b 100644 --- a/src/c_api/c_api.cc +++ b/src/c_api/c_api.cc @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -43,7 +44,6 @@ #include #include #include -#include "./c_api_common.h" #include "../operator/custom/custom-inl.h" #include "../operator/tensor/matrix_op-inl.h" diff --git a/src/c_api/c_api_common.h b/src/c_api/c_api_common.h deleted file mode 100644 index 079b587e9965..000000000000 --- a/src/c_api/c_api_common.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ - -/*! - * Copyright (c) 2015 by Contributors - * \file c_api_error.h - * \brief Error handling for C API. - */ -#ifndef MXNET_C_API_C_API_COMMON_H_ -#define MXNET_C_API_C_API_COMMON_H_ - -#include -#include -#include -#include -#include -#include -#include -#include - -/*! \brief macro to guard beginning and end section of all functions */ -#define API_BEGIN() try { on_enter_api(__FUNCTION__); -/*! \brief every function starts with API_BEGIN(); - and finishes with API_END() or API_END_HANDLE_ERROR */ -#define API_END() } catch(dmlc::Error &_except_) { on_exit_api(); return MXAPIHandleException(_except_); } on_exit_api(); return 0; // NOLINT(*) -/*! - * \brief every function starts with API_BEGIN(); - * and finishes with API_END() or API_END_HANDLE_ERROR - * The finally clause contains procedure to cleanup states when an error happens. - */ -#define API_END_HANDLE_ERROR(Finalize) } catch(dmlc::Error &_except_) { Finalize; on_exit_api(); return MXAPIHandleException(_except_); } on_exit_api(); return 0; // NOLINT(*) - -/*! - * \brief Set the last error message needed by C API - * \param msg The error message to set. - */ -void MXAPISetLastError(const char* msg); -/*! - * \brief handle exception throwed out - * \param e the exception - * \return the return value of API after exception is handled - */ -inline int MXAPIHandleException(const dmlc::Error &e) { - MXAPISetLastError(e.what()); - return -1; -} - -using namespace mxnet; - -/*! \brief entry to to easily hold returning information */ -struct MXAPIThreadLocalEntry { - /*! \brief result holder for returning string */ - std::string ret_str; - /*! \brief result holder for returning strings */ - std::vector ret_vec_str; - /*! \brief result holder for returning string pointers */ - std::vector ret_vec_charp; - /*! \brief result holder for returning handles */ - std::vector ret_handles; - /*! \brief holder for NDArray handles */ - std::vector ndinputs, ndoutputs; - /*! \brief result holder for returning shapes */ - std::vector arg_shapes, out_shapes, aux_shapes; - /*! \brief result holder for returning type flags */ - std::vector arg_types, out_types, aux_types; - /*! \brief result holder for returning storage types */ - std::vector arg_storage_types, out_storage_types, aux_storage_types; - /*! \brief result holder for returning shape dimensions */ - std::vector arg_shape_ndim, out_shape_ndim, aux_shape_ndim; - /*! \brief result holder for returning shape pointer */ - std::vector arg_shape_data, out_shape_data, aux_shape_data; - /*! \brief uint32_t buffer for returning shape pointer */ - std::vector arg_shape_buffer, out_shape_buffer, aux_shape_buffer; - /*! \brief bool buffer */ - std::vector save_inputs, save_outputs; - // helper function to setup return value of shape array - inline static void SetupShapeArrayReturnWithBuffer( - const std::vector &shapes, - std::vector *ndim, - std::vector *data, - std::vector *buffer) { - ndim->resize(shapes.size()); - data->resize(shapes.size()); - size_t size = 0; - for (const auto& s : shapes) size += s.ndim(); - buffer->resize(size); - uint32_t *ptr = buffer->data(); - for (size_t i = 0; i < shapes.size(); ++i) { - ndim->at(i) = shapes[i].ndim(); - data->at(i) = ptr; - ptr = nnvm::ShapeTypeCast(shapes[i].begin(), shapes[i].end(), ptr); - } - } -}; - -// define the threadlocal store. -typedef dmlc::ThreadLocalStore MXAPIThreadLocalStore; - -namespace mxnet { -// copy attributes from inferred vector back to the vector of each type. -template -inline void CopyAttr(const nnvm::IndexedGraph& idx, - const std::vector& attr_vec, - std::vector* in_attr, - std::vector* out_attr, - std::vector* aux_attr) { - in_attr->clear(); - out_attr->clear(); - aux_attr->clear(); - for (uint32_t nid : idx.input_nodes()) { - if (idx.mutable_input_nodes().count(nid) == 0) { - in_attr->push_back(attr_vec[idx.entry_id(nid, 0)]); - } else { - aux_attr->push_back(attr_vec[idx.entry_id(nid, 0)]); - } - } - for (auto& e : idx.outputs()) { - out_attr->push_back(attr_vec[idx.entry_id(e)]); - } -} - -// stores keys that will be converted to __key__ -extern const std::vector kHiddenKeys; - -extern void on_enter_api(const char *function); -extern void on_exit_api(); - -} // namespace mxnet - -#endif // MXNET_C_API_C_API_COMMON_H_ diff --git a/src/c_api/c_api_error.cc b/src/c_api/c_api_error.cc index 6dd4719281b6..2e9799fa0030 100644 --- a/src/c_api/c_api_error.cc +++ b/src/c_api/c_api_error.cc @@ -23,7 +23,6 @@ * \brief C error handling */ #include -#include "./c_api_common.h" const char *MXGetLastError() { return NNGetLastError(); diff --git a/src/c_api/c_api_executor.cc b/src/c_api/c_api_executor.cc index e2e53c7261fa..c1d436ae0e38 100644 --- a/src/c_api/c_api_executor.cc +++ b/src/c_api/c_api_executor.cc @@ -25,7 +25,7 @@ #include #include #include -#include "./c_api_common.h" +#include #include "../executor/graph_executor.h" #if MXNET_USE_TENSORRT #include "../executor/trt_graph_executor.h" diff --git a/src/c_api/c_api_function.cc b/src/c_api/c_api_function.cc index 7091be2e72c5..89bc2c30c072 100644 --- a/src/c_api/c_api_function.cc +++ b/src/c_api/c_api_function.cc @@ -26,8 +26,8 @@ #include #include #include +#include -#include "./c_api_common.h" #include "../operator/operator_common.h" #include "../operator/custom/custom-inl.h" diff --git a/src/c_api/c_api_ndarray.cc b/src/c_api/c_api_ndarray.cc index 18f6c411e039..c0a193be19e8 100644 --- a/src/c_api/c_api_ndarray.cc +++ b/src/c_api/c_api_ndarray.cc @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -32,7 +33,6 @@ #include #include #include -#include "./c_api_common.h" #include "../common/utils.h" #include "../common/exec_utils.h" #include "../imperative/imperative_utils.h" diff --git a/src/c_api/c_api_profile.cc b/src/c_api/c_api_profile.cc index 9c03b339e3ca..93333211ace6 100644 --- a/src/c_api/c_api_profile.cc +++ b/src/c_api/c_api_profile.cc @@ -30,8 +30,8 @@ #include #include #include +#include #include -#include "./c_api_common.h" #include "../profiler/profiler.h" namespace mxnet { diff --git a/src/c_api/c_api_symbolic.cc b/src/c_api/c_api_symbolic.cc index 73a8a7ca6f86..af6cd75f8a38 100644 --- a/src/c_api/c_api_symbolic.cc +++ b/src/c_api/c_api_symbolic.cc @@ -24,11 +24,11 @@ */ #include #include +#include #include #include #include #include -#include "./c_api_common.h" #include "../operator/operator_common.h" #include "../executor/exec_pass.h" #include "../operator/subgraph/subgraph_property.h" diff --git a/src/c_api/c_api_test.cc b/src/c_api/c_api_test.cc index 623faa71adc9..d145f1aa34bc 100644 --- a/src/c_api/c_api_test.cc +++ b/src/c_api/c_api_test.cc @@ -23,8 +23,8 @@ * \brief C API of mxnet for the ease of testing backend in Python */ #include +#include #include -#include "./c_api_common.h" #include "../operator/subgraph/subgraph_property.h" int MXPartitionGraphByOpNames(SymbolHandle sym_handle, diff --git a/src/c_api/c_predict_api.cc b/src/c_api/c_predict_api.cc index bd599e0b6423..d3971bdac282 100644 --- a/src/c_api/c_predict_api.cc +++ b/src/c_api/c_predict_api.cc @@ -25,13 +25,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include "./c_api_common.h" #include "../operator/operator_common.h" #include "../executor/exec_pass.h" diff --git a/src/imperative/imperative_utils.h b/src/imperative/imperative_utils.h index 4b0d13167356..38840b921357 100644 --- a/src/imperative/imperative_utils.h +++ b/src/imperative/imperative_utils.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -27,7 +28,6 @@ #include #include "../executor/graph_executor.h" #include "../executor/exec_pass.h" -#include "../c_api/c_api_common.h" #include "../common/utils.h" #include "../common/exec_utils.h" #include "../operator/nn/mkldnn/mkldnn_base-inl.h" diff --git a/src/nnvm/legacy_json_util.cc b/src/nnvm/legacy_json_util.cc index a2d14c2135dc..0da0894037b1 100644 --- a/src/nnvm/legacy_json_util.cc +++ b/src/nnvm/legacy_json_util.cc @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -33,7 +34,6 @@ #include #include #include -#include "../c_api/c_api_common.h" namespace mxnet { using nnvm::Graph; From c781e2609c97e174858fd387f6c420a2beea5c5a Mon Sep 17 00:00:00 2001 From: Lin Yuan Date: Tue, 8 Jan 2019 08:12:44 -0800 Subject: [PATCH 5/9] fix build error --- src/c_api/c_api_error.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/c_api/c_api_error.cc b/src/c_api/c_api_error.cc index 2e9799fa0030..f24ef0651f1b 100644 --- a/src/c_api/c_api_error.cc +++ b/src/c_api/c_api_error.cc @@ -22,6 +22,8 @@ * \file c_api_error.cc * \brief C error handling */ + +#include #include const char *MXGetLastError() { From 3d41c6326b80fb3af6fb2ec2f22c652360929418 Mon Sep 17 00:00:00 2001 From: Lin Yuan Date: Tue, 8 Jan 2019 11:44:19 -0800 Subject: [PATCH 6/9] keep c_api_common.h internal --- plugin/opencv/cv_api.cc | 2 +- src/c_api/c_api.cc | 2 +- src/c_api/c_api_common.h | 146 ++++++++++++++++++++++++++++++ src/c_api/c_api_error.cc | 3 +- src/c_api/c_api_executor.cc | 2 +- src/c_api/c_api_function.cc | 2 +- src/c_api/c_api_ndarray.cc | 2 +- src/c_api/c_api_profile.cc | 2 +- src/c_api/c_api_symbolic.cc | 2 +- src/c_api/c_api_test.cc | 2 +- src/c_api/c_predict_api.cc | 2 +- src/imperative/imperative_utils.h | 2 +- src/nnvm/legacy_json_util.cc | 2 +- 13 files changed, 158 insertions(+), 13 deletions(-) create mode 100644 src/c_api/c_api_common.h diff --git a/plugin/opencv/cv_api.cc b/plugin/opencv/cv_api.cc index cc828c817e1f..53eb8524c7cf 100644 --- a/plugin/opencv/cv_api.cc +++ b/plugin/opencv/cv_api.cc @@ -26,9 +26,9 @@ #include #include #include -#include #include #include "cv_api.h" +#include "../../src/c_api/c_api_common.h" using namespace mxnet; diff --git a/src/c_api/c_api.cc b/src/c_api/c_api.cc index a59981484f0b..80bd60538ff5 100644 --- a/src/c_api/c_api.cc +++ b/src/c_api/c_api.cc @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -44,6 +43,7 @@ #include #include #include +#include "./c_api_common.h" #include "../operator/custom/custom-inl.h" #include "../operator/tensor/matrix_op-inl.h" diff --git a/src/c_api/c_api_common.h b/src/c_api/c_api_common.h new file mode 100644 index 000000000000..079b587e9965 --- /dev/null +++ b/src/c_api/c_api_common.h @@ -0,0 +1,146 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +/*! + * Copyright (c) 2015 by Contributors + * \file c_api_error.h + * \brief Error handling for C API. + */ +#ifndef MXNET_C_API_C_API_COMMON_H_ +#define MXNET_C_API_C_API_COMMON_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +/*! \brief macro to guard beginning and end section of all functions */ +#define API_BEGIN() try { on_enter_api(__FUNCTION__); +/*! \brief every function starts with API_BEGIN(); + and finishes with API_END() or API_END_HANDLE_ERROR */ +#define API_END() } catch(dmlc::Error &_except_) { on_exit_api(); return MXAPIHandleException(_except_); } on_exit_api(); return 0; // NOLINT(*) +/*! + * \brief every function starts with API_BEGIN(); + * and finishes with API_END() or API_END_HANDLE_ERROR + * The finally clause contains procedure to cleanup states when an error happens. + */ +#define API_END_HANDLE_ERROR(Finalize) } catch(dmlc::Error &_except_) { Finalize; on_exit_api(); return MXAPIHandleException(_except_); } on_exit_api(); return 0; // NOLINT(*) + +/*! + * \brief Set the last error message needed by C API + * \param msg The error message to set. + */ +void MXAPISetLastError(const char* msg); +/*! + * \brief handle exception throwed out + * \param e the exception + * \return the return value of API after exception is handled + */ +inline int MXAPIHandleException(const dmlc::Error &e) { + MXAPISetLastError(e.what()); + return -1; +} + +using namespace mxnet; + +/*! \brief entry to to easily hold returning information */ +struct MXAPIThreadLocalEntry { + /*! \brief result holder for returning string */ + std::string ret_str; + /*! \brief result holder for returning strings */ + std::vector ret_vec_str; + /*! \brief result holder for returning string pointers */ + std::vector ret_vec_charp; + /*! \brief result holder for returning handles */ + std::vector ret_handles; + /*! \brief holder for NDArray handles */ + std::vector ndinputs, ndoutputs; + /*! \brief result holder for returning shapes */ + std::vector arg_shapes, out_shapes, aux_shapes; + /*! \brief result holder for returning type flags */ + std::vector arg_types, out_types, aux_types; + /*! \brief result holder for returning storage types */ + std::vector arg_storage_types, out_storage_types, aux_storage_types; + /*! \brief result holder for returning shape dimensions */ + std::vector arg_shape_ndim, out_shape_ndim, aux_shape_ndim; + /*! \brief result holder for returning shape pointer */ + std::vector arg_shape_data, out_shape_data, aux_shape_data; + /*! \brief uint32_t buffer for returning shape pointer */ + std::vector arg_shape_buffer, out_shape_buffer, aux_shape_buffer; + /*! \brief bool buffer */ + std::vector save_inputs, save_outputs; + // helper function to setup return value of shape array + inline static void SetupShapeArrayReturnWithBuffer( + const std::vector &shapes, + std::vector *ndim, + std::vector *data, + std::vector *buffer) { + ndim->resize(shapes.size()); + data->resize(shapes.size()); + size_t size = 0; + for (const auto& s : shapes) size += s.ndim(); + buffer->resize(size); + uint32_t *ptr = buffer->data(); + for (size_t i = 0; i < shapes.size(); ++i) { + ndim->at(i) = shapes[i].ndim(); + data->at(i) = ptr; + ptr = nnvm::ShapeTypeCast(shapes[i].begin(), shapes[i].end(), ptr); + } + } +}; + +// define the threadlocal store. +typedef dmlc::ThreadLocalStore MXAPIThreadLocalStore; + +namespace mxnet { +// copy attributes from inferred vector back to the vector of each type. +template +inline void CopyAttr(const nnvm::IndexedGraph& idx, + const std::vector& attr_vec, + std::vector* in_attr, + std::vector* out_attr, + std::vector* aux_attr) { + in_attr->clear(); + out_attr->clear(); + aux_attr->clear(); + for (uint32_t nid : idx.input_nodes()) { + if (idx.mutable_input_nodes().count(nid) == 0) { + in_attr->push_back(attr_vec[idx.entry_id(nid, 0)]); + } else { + aux_attr->push_back(attr_vec[idx.entry_id(nid, 0)]); + } + } + for (auto& e : idx.outputs()) { + out_attr->push_back(attr_vec[idx.entry_id(e)]); + } +} + +// stores keys that will be converted to __key__ +extern const std::vector kHiddenKeys; + +extern void on_enter_api(const char *function); +extern void on_exit_api(); + +} // namespace mxnet + +#endif // MXNET_C_API_C_API_COMMON_H_ diff --git a/src/c_api/c_api_error.cc b/src/c_api/c_api_error.cc index f24ef0651f1b..6dd4719281b6 100644 --- a/src/c_api/c_api_error.cc +++ b/src/c_api/c_api_error.cc @@ -22,9 +22,8 @@ * \file c_api_error.cc * \brief C error handling */ - -#include #include +#include "./c_api_common.h" const char *MXGetLastError() { return NNGetLastError(); diff --git a/src/c_api/c_api_executor.cc b/src/c_api/c_api_executor.cc index c1d436ae0e38..e2e53c7261fa 100644 --- a/src/c_api/c_api_executor.cc +++ b/src/c_api/c_api_executor.cc @@ -25,7 +25,7 @@ #include #include #include -#include +#include "./c_api_common.h" #include "../executor/graph_executor.h" #if MXNET_USE_TENSORRT #include "../executor/trt_graph_executor.h" diff --git a/src/c_api/c_api_function.cc b/src/c_api/c_api_function.cc index 89bc2c30c072..7091be2e72c5 100644 --- a/src/c_api/c_api_function.cc +++ b/src/c_api/c_api_function.cc @@ -26,8 +26,8 @@ #include #include #include -#include +#include "./c_api_common.h" #include "../operator/operator_common.h" #include "../operator/custom/custom-inl.h" diff --git a/src/c_api/c_api_ndarray.cc b/src/c_api/c_api_ndarray.cc index c0a193be19e8..18f6c411e039 100644 --- a/src/c_api/c_api_ndarray.cc +++ b/src/c_api/c_api_ndarray.cc @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -33,6 +32,7 @@ #include #include #include +#include "./c_api_common.h" #include "../common/utils.h" #include "../common/exec_utils.h" #include "../imperative/imperative_utils.h" diff --git a/src/c_api/c_api_profile.cc b/src/c_api/c_api_profile.cc index 93333211ace6..9c03b339e3ca 100644 --- a/src/c_api/c_api_profile.cc +++ b/src/c_api/c_api_profile.cc @@ -30,8 +30,8 @@ #include #include #include -#include #include +#include "./c_api_common.h" #include "../profiler/profiler.h" namespace mxnet { diff --git a/src/c_api/c_api_symbolic.cc b/src/c_api/c_api_symbolic.cc index af6cd75f8a38..73a8a7ca6f86 100644 --- a/src/c_api/c_api_symbolic.cc +++ b/src/c_api/c_api_symbolic.cc @@ -24,11 +24,11 @@ */ #include #include -#include #include #include #include #include +#include "./c_api_common.h" #include "../operator/operator_common.h" #include "../executor/exec_pass.h" #include "../operator/subgraph/subgraph_property.h" diff --git a/src/c_api/c_api_test.cc b/src/c_api/c_api_test.cc index d145f1aa34bc..623faa71adc9 100644 --- a/src/c_api/c_api_test.cc +++ b/src/c_api/c_api_test.cc @@ -23,8 +23,8 @@ * \brief C API of mxnet for the ease of testing backend in Python */ #include -#include #include +#include "./c_api_common.h" #include "../operator/subgraph/subgraph_property.h" int MXPartitionGraphByOpNames(SymbolHandle sym_handle, diff --git a/src/c_api/c_predict_api.cc b/src/c_api/c_predict_api.cc index d3971bdac282..bd599e0b6423 100644 --- a/src/c_api/c_predict_api.cc +++ b/src/c_api/c_predict_api.cc @@ -25,13 +25,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include "./c_api_common.h" #include "../operator/operator_common.h" #include "../executor/exec_pass.h" diff --git a/src/imperative/imperative_utils.h b/src/imperative/imperative_utils.h index 38840b921357..4b0d13167356 100644 --- a/src/imperative/imperative_utils.h +++ b/src/imperative/imperative_utils.h @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -28,6 +27,7 @@ #include #include "../executor/graph_executor.h" #include "../executor/exec_pass.h" +#include "../c_api/c_api_common.h" #include "../common/utils.h" #include "../common/exec_utils.h" #include "../operator/nn/mkldnn/mkldnn_base-inl.h" diff --git a/src/nnvm/legacy_json_util.cc b/src/nnvm/legacy_json_util.cc index 0da0894037b1..a2d14c2135dc 100644 --- a/src/nnvm/legacy_json_util.cc +++ b/src/nnvm/legacy_json_util.cc @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -34,6 +33,7 @@ #include #include #include +#include "../c_api/c_api_common.h" namespace mxnet { using nnvm::Graph; From d15c998170c81d181fdd6785edcf8a72c198a9c2 Mon Sep 17 00:00:00 2001 From: Lin Yuan Date: Tue, 8 Jan 2019 12:54:55 -0800 Subject: [PATCH 7/9] strip out error handling API into a separate header --- include/mxnet/c_api_common.h | 146 ----------------------------------- include/mxnet/c_api_error.h | 69 +++++++++++++++++ src/c_api/c_api_common.h | 40 ++++------ 3 files changed, 86 insertions(+), 169 deletions(-) delete mode 100644 include/mxnet/c_api_common.h create mode 100644 include/mxnet/c_api_error.h diff --git a/include/mxnet/c_api_common.h b/include/mxnet/c_api_common.h deleted file mode 100644 index 7264058e38bb..000000000000 --- a/include/mxnet/c_api_common.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ - -/*! - * Copyright (c) 2015 by Contributors - * \file c_api_error.h - * \brief Error handling for C API. - */ -#ifndef MXNET_C_API_COMMON_H_ -#define MXNET_C_API_COMMON_H_ - -#include -#include -#include -#include -#include -#include -#include -#include - -/*! \brief macro to guard beginning and end section of all functions */ -#define API_BEGIN() try { on_enter_api(__FUNCTION__); -/*! \brief every function starts with API_BEGIN(); - and finishes with API_END() or API_END_HANDLE_ERROR */ -#define API_END() } catch(dmlc::Error &_except_) { on_exit_api(); return MXAPIHandleException(_except_); } on_exit_api(); return 0; // NOLINT(*) -/*! - * \brief every function starts with API_BEGIN(); - * and finishes with API_END() or API_END_HANDLE_ERROR - * The finally clause contains procedure to cleanup states when an error happens. - */ -#define API_END_HANDLE_ERROR(Finalize) } catch(dmlc::Error &_except_) { Finalize; on_exit_api(); return MXAPIHandleException(_except_); } on_exit_api(); return 0; // NOLINT(*) - -/*! - * \brief Set the last error message needed by C API - * \param msg The error message to set. - */ -void MXAPISetLastError(const char* msg); -/*! - * \brief handle exception throwed out - * \param e the exception - * \return the return value of API after exception is handled - */ -inline int MXAPIHandleException(const dmlc::Error &e) { - MXAPISetLastError(e.what()); - return -1; -} - -using namespace mxnet; - -/*! \brief entry to to easily hold returning information */ -struct MXAPIThreadLocalEntry { - /*! \brief result holder for returning string */ - std::string ret_str; - /*! \brief result holder for returning strings */ - std::vector ret_vec_str; - /*! \brief result holder for returning string pointers */ - std::vector ret_vec_charp; - /*! \brief result holder for returning handles */ - std::vector ret_handles; - /*! \brief holder for NDArray handles */ - std::vector ndinputs, ndoutputs; - /*! \brief result holder for returning shapes */ - std::vector arg_shapes, out_shapes, aux_shapes; - /*! \brief result holder for returning type flags */ - std::vector arg_types, out_types, aux_types; - /*! \brief result holder for returning storage types */ - std::vector arg_storage_types, out_storage_types, aux_storage_types; - /*! \brief result holder for returning shape dimensions */ - std::vector arg_shape_ndim, out_shape_ndim, aux_shape_ndim; - /*! \brief result holder for returning shape pointer */ - std::vector arg_shape_data, out_shape_data, aux_shape_data; - /*! \brief uint32_t buffer for returning shape pointer */ - std::vector arg_shape_buffer, out_shape_buffer, aux_shape_buffer; - /*! \brief bool buffer */ - std::vector save_inputs, save_outputs; - // helper function to setup return value of shape array - inline static void SetupShapeArrayReturnWithBuffer( - const std::vector &shapes, - std::vector *ndim, - std::vector *data, - std::vector *buffer) { - ndim->resize(shapes.size()); - data->resize(shapes.size()); - size_t size = 0; - for (const auto& s : shapes) size += s.ndim(); - buffer->resize(size); - uint32_t *ptr = buffer->data(); - for (size_t i = 0; i < shapes.size(); ++i) { - ndim->at(i) = shapes[i].ndim(); - data->at(i) = ptr; - ptr = nnvm::ShapeTypeCast(shapes[i].begin(), shapes[i].end(), ptr); - } - } -}; - -// define the threadlocal store. -typedef dmlc::ThreadLocalStore MXAPIThreadLocalStore; - -namespace mxnet { -// copy attributes from inferred vector back to the vector of each type. -template -inline void CopyAttr(const nnvm::IndexedGraph& idx, - const std::vector& attr_vec, - std::vector* in_attr, - std::vector* out_attr, - std::vector* aux_attr) { - in_attr->clear(); - out_attr->clear(); - aux_attr->clear(); - for (uint32_t nid : idx.input_nodes()) { - if (idx.mutable_input_nodes().count(nid) == 0) { - in_attr->push_back(attr_vec[idx.entry_id(nid, 0)]); - } else { - aux_attr->push_back(attr_vec[idx.entry_id(nid, 0)]); - } - } - for (auto& e : idx.outputs()) { - out_attr->push_back(attr_vec[idx.entry_id(e)]); - } -} - -// stores keys that will be converted to __key__ -extern const std::vector kHiddenKeys; - -extern void on_enter_api(const char *function); -extern void on_exit_api(); - -} // namespace mxnet - -#endif // MXNET_C_API_COMMON_H_ diff --git a/include/mxnet/c_api_error.h b/include/mxnet/c_api_error.h new file mode 100644 index 000000000000..711a1a980fba --- /dev/null +++ b/include/mxnet/c_api_error.h @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +/*! + * Copyright (c) 2018 by Contributors + * \file c_api_error.h + * \brief Error handling for C API. + */ +#ifndef MXNET_C_API_ERROR_H_ +#define MXNET_C_API_ERROR_H_ + +#include +#include +#include +#include + +using namespace mxnet; + +/*! + * \brief macro to guard beginning and end section of all functions + */ +#define MX_API_BEGIN() try { on_enter_api(__FUNCTION__); +/*! + * \brief every function starts with API_BEGIN(); + * and finishes with API_END() or API_END_HANDLE_ERROR + */ +#define MX_API_END() } catch(dmlc::Error &_except_) { on_exit_api(); return MXAPIHandleException(_except_); } on_exit_api(); return 0; // NOLINT(*) +/*! + * \brief every function starts with API_BEGIN(); + * and finishes with API_END() or API_END_HANDLE_ERROR + * The finally clause contains procedure to cleanup states when an error happens. + */ +#define MX_API_END_HANDLE_ERROR(Finalize) } catch(dmlc::Error &_except_) { Finalize; on_exit_api(); return MXAPIHandleException(_except_); } on_exit_api(); return 0; // NOLINT(*) +/*! + * \brief Set the last error message needed by C API + * \param msg The error message to set. + */ +void MXAPISetLastError(const char* msg); +/*! + * \brief handle exception throwed out + * \param e the exception + * \return the return value of API after exception is handled + */ +inline int MXAPIHandleException(const dmlc::Error &e) { + MXAPISetLastError(e.what()); + return -1; +} + +namespace mxnet { +extern void on_enter_api(const char *function); +extern void on_exit_api(); +} +#endif // MXNET_C_API_ERROR_H_ diff --git a/src/c_api/c_api_common.h b/src/c_api/c_api_common.h index 079b587e9965..597033fbf1f8 100644 --- a/src/c_api/c_api_common.h +++ b/src/c_api/c_api_common.h @@ -29,37 +29,35 @@ #include #include #include +#include #include #include #include #include -/*! \brief macro to guard beginning and end section of all functions */ -#define API_BEGIN() try { on_enter_api(__FUNCTION__); -/*! \brief every function starts with API_BEGIN(); - and finishes with API_END() or API_END_HANDLE_ERROR */ -#define API_END() } catch(dmlc::Error &_except_) { on_exit_api(); return MXAPIHandleException(_except_); } on_exit_api(); return 0; // NOLINT(*) /*! - * \brief every function starts with API_BEGIN(); - * and finishes with API_END() or API_END_HANDLE_ERROR - * The finally clause contains procedure to cleanup states when an error happens. + * \brief macro to guard beginning and end section of all functions */ -#define API_END_HANDLE_ERROR(Finalize) } catch(dmlc::Error &_except_) { Finalize; on_exit_api(); return MXAPIHandleException(_except_); } on_exit_api(); return 0; // NOLINT(*) +#ifndef API_BEGIN +#define API_BEGIN MX_API_BEGIN +#endif /*! - * \brief Set the last error message needed by C API - * \param msg The error message to set. + * \brief every function starts with API_BEGIN(); + * and finishes with API_END() or API_END_HANDLE_ERROR */ -void MXAPISetLastError(const char* msg); +#ifndef API_END +#define API_END MX_API_END +#endif + /*! - * \brief handle exception throwed out - * \param e the exception - * \return the return value of API after exception is handled + * \brief every function starts with API_BEGIN(); + * and finishes with API_END() or API_END_HANDLE_ERROR + * The finally clause contains procedure to cleanup states when an error happens. */ -inline int MXAPIHandleException(const dmlc::Error &e) { - MXAPISetLastError(e.what()); - return -1; -} +#ifndef API_END_HANDLE_ERROR +#define API_END_HANDLE_ERROR MX_API_END_HANDLE_ERROR +#endif using namespace mxnet; @@ -137,10 +135,6 @@ inline void CopyAttr(const nnvm::IndexedGraph& idx, // stores keys that will be converted to __key__ extern const std::vector kHiddenKeys; - -extern void on_enter_api(const char *function); -extern void on_exit_api(); - } // namespace mxnet #endif // MXNET_C_API_C_API_COMMON_H_ From fb67cfe9ad3e83c775a5347ff668b15c4b860ec2 Mon Sep 17 00:00:00 2001 From: Lin Yuan Date: Tue, 8 Jan 2019 13:29:44 -0800 Subject: [PATCH 8/9] consolidate comment into one paragraph per review --- include/mxnet/c_api_error.h | 14 ++++---------- src/c_api/c_api_common.h | 14 ++++---------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/include/mxnet/c_api_error.h b/include/mxnet/c_api_error.h index 711a1a980fba..f2c3192322a4 100644 --- a/include/mxnet/c_api_error.h +++ b/include/mxnet/c_api_error.h @@ -33,19 +33,13 @@ using namespace mxnet; /*! - * \brief macro to guard beginning and end section of all functions + * \brief Macros to guard beginning and end section of all functions + * every function starts with API_BEGIN() + * and finishes with API_END() or API_END_HANDLE_ERROR() + * The finally clause contains procedure to cleanup states when an error happens. */ #define MX_API_BEGIN() try { on_enter_api(__FUNCTION__); -/*! - * \brief every function starts with API_BEGIN(); - * and finishes with API_END() or API_END_HANDLE_ERROR - */ #define MX_API_END() } catch(dmlc::Error &_except_) { on_exit_api(); return MXAPIHandleException(_except_); } on_exit_api(); return 0; // NOLINT(*) -/*! - * \brief every function starts with API_BEGIN(); - * and finishes with API_END() or API_END_HANDLE_ERROR - * The finally clause contains procedure to cleanup states when an error happens. - */ #define MX_API_END_HANDLE_ERROR(Finalize) } catch(dmlc::Error &_except_) { Finalize; on_exit_api(); return MXAPIHandleException(_except_); } on_exit_api(); return 0; // NOLINT(*) /*! * \brief Set the last error message needed by C API diff --git a/src/c_api/c_api_common.h b/src/c_api/c_api_common.h index 597033fbf1f8..ecb05bc78ca4 100644 --- a/src/c_api/c_api_common.h +++ b/src/c_api/c_api_common.h @@ -36,25 +36,19 @@ #include /*! - * \brief macro to guard beginning and end section of all functions + * \brief Macros to guard beginning and end section of all functions + * every function starts with API_BEGIN() + * and finishes with API_END() or API_END_HANDLE_ERROR() + * The finally clause contains procedure to cleanup states when an error happens. */ #ifndef API_BEGIN #define API_BEGIN MX_API_BEGIN #endif -/*! - * \brief every function starts with API_BEGIN(); - * and finishes with API_END() or API_END_HANDLE_ERROR - */ #ifndef API_END #define API_END MX_API_END #endif -/*! - * \brief every function starts with API_BEGIN(); - * and finishes with API_END() or API_END_HANDLE_ERROR - * The finally clause contains procedure to cleanup states when an error happens. - */ #ifndef API_END_HANDLE_ERROR #define API_END_HANDLE_ERROR MX_API_END_HANDLE_ERROR #endif From ca6bc225cf44ab8c65c990dc0177096b7ba465a9 Mon Sep 17 00:00:00 2001 From: Lin Yuan Date: Tue, 8 Jan 2019 16:49:38 -0800 Subject: [PATCH 9/9] remove unnecessary include --- include/mxnet/c_api_error.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/include/mxnet/c_api_error.h b/include/mxnet/c_api_error.h index f2c3192322a4..0c6ea03fa459 100644 --- a/include/mxnet/c_api_error.h +++ b/include/mxnet/c_api_error.h @@ -25,13 +25,6 @@ #ifndef MXNET_C_API_ERROR_H_ #define MXNET_C_API_ERROR_H_ -#include -#include -#include -#include - -using namespace mxnet; - /*! * \brief Macros to guard beginning and end section of all functions * every function starts with API_BEGIN()