Skip to content

Commit

Permalink
experimental feature: error status, test=develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Shixiaowei02 committed Sep 9, 2021
1 parent 1159f75 commit 6217008
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 0 deletions.
1 change: 1 addition & 0 deletions paddle/fluid/inference/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ set(SHARED_INFERENCE_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/api/api.cc
${CMAKE_CURRENT_SOURCE_DIR}/api/api_impl.cc
${CMAKE_CURRENT_SOURCE_DIR}/api/analysis_predictor.cc
${CMAKE_CURRENT_SOURCE_DIR}/api/paddle_infer_contrib.cc
${CMAKE_CURRENT_SOURCE_DIR}/api/details/zero_copy_tensor.cc
${CMAKE_CURRENT_SOURCE_DIR}/utils/io_utils.cc
${PADDLE_CUSTOM_OP_SRCS})
Expand Down
39 changes: 39 additions & 0 deletions paddle/fluid/inference/api/paddle_infer_contrib.cc
Original file line number Diff line number Diff line change
Expand Up @@ -186,5 +186,44 @@ void TensorUtils::CopyTensorAsync(Tensor* p_dst, const Tensor& src,
CopyTensorImpl(p_dst, src, nullptr, cb, cb_params);
}

struct Status::Impl {
int ec{0};
std::string msg;
};

Status::Status() noexcept : impl_(new Impl) {}
Status::Status(const Status& status) noexcept : impl_(new Impl) {
*impl_ = *status.impl_;
}

Status& Status::operator=(const Status& status) noexcept {
*impl_ = *status.impl_;
return *this;
}
Status::Status(std::exception_ptr e) noexcept : impl_(new Impl) {
constexpr int kDefaultError{-1};
impl_->ec = kDefaultError;
try {
std::rethrow_exception(e);
} catch (paddle::platform::EnforceNotMet& e) {
// Add one to the error code to make the number zero a non-error
// status code.
impl_->ec = e.code() + 1;
impl_->msg = e.what();
} catch (const std::exception& e) {
impl_->msg = e.what();
}
}
Status Status::OK() noexcept { return Status(); }
bool Status::ok() const noexcept { return impl_->ec == 0; }
Status::Code Status::code() const noexcept { return impl_->ec; }
const std::string& Status::error_message() const noexcept { return impl_->msg; }
bool Status::operator==(const Status& x) const noexcept {
return code() == x.code() && error_message() == x.error_message();
}
bool Status::operator!=(const Status& x) const noexcept {
return !(*this == x);
}

} // namespace contrib
} // namespace paddle_infer
38 changes: 38 additions & 0 deletions paddle/fluid/inference/api/paddle_infer_contrib.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,43 @@ class TensorUtils {
void* cb_params);
};

class Status {
public:
using Code = int;
Status() noexcept;
explicit Status(std::exception_ptr e) noexcept;

Status(const Status&) noexcept;
Status& operator=(const Status&) noexcept;

Status& operator=(Status&&) noexcept(
noexcept(std::declval<std::shared_ptr<Status>>().operator=(
std::declval<std::shared_ptr<Status>>()))) = default;

Status(Status&&) noexcept(noexcept(std::shared_ptr<Status>(
std::declval<std::shared_ptr<Status>>()))) = default;

static Status OK() noexcept;
bool ok() const noexcept;
Code code() const noexcept;
const std::string& error_message() const noexcept;
bool operator==(const Status& x) const noexcept;
bool operator!=(const Status& x) const noexcept;

private:
struct Impl;
std::shared_ptr<Impl> impl_;
};

template <typename Func, typename... Args>
Status status_wrapper(Func func, Args&&... args) noexcept {
try {
func(std::forward<Args>(args)...);
} catch (...) {
return Status(std::current_exception());
}
return {};
}

} // namespace contrib
} // namespace paddle_infer
2 changes: 2 additions & 0 deletions paddle/fluid/inference/tests/api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,8 @@ if(WITH_GPU)
set_tests_properties(paddle_infer_api_copy_tensor_tester PROPERTIES TIMEOUT 30)
endif()

cc_test(paddle_infer_api_errors_tester SRCS paddle_infer_api_errors_tester.cc DEPS paddle_infer_contrib)

if("$ENV{CI_SKIP_CPP_TEST}" STREQUAL "ON")
return()
endif()
Expand Down
49 changes: 49 additions & 0 deletions paddle/fluid/inference/tests/api/paddle_infer_api_errors_tester.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) 2021 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 "gflags/gflags.h"
#include "glog/logging.h"
#include "gtest/gtest.h"

#include "paddle/fluid/inference/api/paddle_infer_contrib.h"
#include "paddle/fluid/platform/enforce.h"

namespace paddle_infer {
namespace contrib {

TEST(Status, ctor) { CHECK(Status::OK().ok()); }

struct FakeException {
void pd_exception(int a, const std::string& msg) const {
PADDLE_ENFORCE_NE(a, a, paddle::platform::errors::InvalidArgument(msg));
}
void base_exception() const { throw std::exception(); }
};

TEST(Status, pd_exception) {
FakeException e;
Status status = status_wrapper([&]() { e.pd_exception(1, "test"); });
CHECK(!status.ok());
CHECK_NE(status.code(), 0);
}

TEST(Status, basic_exception) {
FakeException e;
Status status;
status = status_wrapper([&]() { e.base_exception(); });
CHECK(!status.ok());
}

} // namespace contrib
} // namespace paddle_infer

0 comments on commit 6217008

Please sign in to comment.