170 lines
7.2 KiB
C++
170 lines
7.2 KiB
C++
// Copyright (c) 2022 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 "paddle/fluid/eager/nan_inf_utils.h"
|
|
|
|
#include <iostream>
|
|
#include <limits>
|
|
#include <ostream>
|
|
#include <string>
|
|
#include <tuple>
|
|
|
|
#include "gtest/gtest.h"
|
|
#include "paddle/common/flags.h"
|
|
#include "paddle/fluid/framework/tensor_util.h"
|
|
#include "paddle/fluid/platform/enforce.h"
|
|
#include "paddle/phi/api/include/api.h"
|
|
#include "paddle/phi/api/include/strings_api.h"
|
|
#include "paddle/phi/core/kernel_registry.h"
|
|
|
|
PD_DECLARE_KERNEL(full, CPU, ALL_LAYOUT);
|
|
PD_DECLARE_KERNEL(strings_empty, CPU, ALL_LAYOUT);
|
|
|
|
COMMON_DECLARE_string(check_nan_inf_blacklist);
|
|
|
|
namespace egr {
|
|
|
|
using paddle_flags::FLAGS_check_nan_inf_blacklist;
|
|
#define CHECK_NAN_INF(tensors) \
|
|
{ \
|
|
bool caught_exception = false; \
|
|
try { \
|
|
CheckTensorHasNanOrInf("nan_inf_test", tensors); \
|
|
} catch (paddle::platform::EnforceNotMet & error) { \
|
|
caught_exception = true; \
|
|
std::string ex_msg = error.what(); \
|
|
EXPECT_TRUE(ex_msg.find("There are NAN or INF") != std::string::npos); \
|
|
} \
|
|
EXPECT_TRUE(caught_exception); \
|
|
}
|
|
|
|
#define CHECK_NO_NAN_INF(tensors) \
|
|
{ \
|
|
bool caught_exception = false; \
|
|
try { \
|
|
CheckTensorHasNanOrInf("nan_inf_test", tensors); \
|
|
} catch (paddle::platform::EnforceNotMet & error) { \
|
|
caught_exception = true; \
|
|
std::string ex_msg = error.what(); \
|
|
EXPECT_TRUE(ex_msg.find("There are NAN or INF") != std::string::npos); \
|
|
} \
|
|
EXPECT_FALSE(caught_exception); \
|
|
}
|
|
|
|
#define CHECK_APINAME_SKIP(api_name, tensor) \
|
|
{ \
|
|
bool caught_exception = false; \
|
|
try { \
|
|
CheckTensorHasNanOrInf(api_name, tensor); \
|
|
} catch (paddle::platform::EnforceNotMet & error) { \
|
|
caught_exception = true; \
|
|
} \
|
|
EXPECT_FALSE(caught_exception); \
|
|
}
|
|
|
|
#define CHECK_APINAME_NO_SKIP(api_name, tensor) \
|
|
{ \
|
|
bool caught_exception = false; \
|
|
try { \
|
|
CheckTensorHasNanOrInf(api_name, tensor); \
|
|
} catch (paddle::platform::EnforceNotMet & error) { \
|
|
caught_exception = true; \
|
|
} \
|
|
EXPECT_TRUE(caught_exception); \
|
|
}
|
|
|
|
TEST(NanInfUtils, BlacklistSkipCheck) {
|
|
auto nan_tensor = paddle::experimental::full(
|
|
{3, 4}, std::numeric_limits<double>::quiet_NaN(), phi::DataType::FLOAT64);
|
|
|
|
FLAGS_check_nan_inf_blacklist = "";
|
|
CHECK_APINAME_SKIP("empty", nan_tensor);
|
|
|
|
// Test that "empty_like" always skips regardless of blacklist
|
|
FLAGS_check_nan_inf_blacklist = "";
|
|
CHECK_APINAME_SKIP("empty_like", nan_tensor);
|
|
|
|
// Test with empty blacklist (default behavior)
|
|
FLAGS_check_nan_inf_blacklist = "";
|
|
CHECK_APINAME_NO_SKIP("some_op", nan_tensor);
|
|
|
|
// Test with single op in blacklist
|
|
FLAGS_check_nan_inf_blacklist = "single_op";
|
|
CHECK_APINAME_SKIP("single_op", nan_tensor);
|
|
CHECK_APINAME_NO_SKIP("other_op", nan_tensor);
|
|
|
|
// Even when blacklist is set, these should still skip
|
|
CHECK_APINAME_SKIP("empty", nan_tensor);
|
|
CHECK_APINAME_SKIP("empty_like", nan_tensor);
|
|
|
|
// blacklist="op1,op2,op3" and op is in blacklist
|
|
FLAGS_check_nan_inf_blacklist = "op1,op2,op3";
|
|
CHECK_APINAME_SKIP("op1", nan_tensor);
|
|
CHECK_APINAME_SKIP("op2", nan_tensor);
|
|
CHECK_APINAME_SKIP("op3", nan_tensor);
|
|
// not in blacklist, should perform nan_or_inf check
|
|
CHECK_APINAME_NO_SKIP("op4", nan_tensor);
|
|
|
|
FLAGS_check_nan_inf_blacklist = "";
|
|
}
|
|
|
|
TEST(NanInfUtils, Functions) {
|
|
// test all methods
|
|
auto tensor = paddle::experimental::full(
|
|
{3, 4}, std::numeric_limits<double>::quiet_NaN(), phi::DataType::FLOAT64);
|
|
CHECK_NAN_INF(tensor);
|
|
auto tensor1 = paddle::experimental::full(
|
|
{3, 4}, std::numeric_limits<double>::quiet_NaN(), phi::DataType::FLOAT64);
|
|
auto two_tensors = std::make_tuple(tensor, tensor1);
|
|
CHECK_NAN_INF(two_tensors);
|
|
auto tensor2 = paddle::experimental::full(
|
|
{3, 4}, std::numeric_limits<double>::quiet_NaN(), phi::DataType::FLOAT64);
|
|
auto three_tensors = std::make_tuple(tensor, tensor1, tensor2);
|
|
CHECK_NAN_INF(three_tensors);
|
|
auto tensor3 = paddle::experimental::full(
|
|
{3, 4}, std::numeric_limits<double>::quiet_NaN(), phi::DataType::FLOAT64);
|
|
auto four_tensors = std::make_tuple(tensor, tensor1, tensor2, tensor3);
|
|
CHECK_NAN_INF(four_tensors);
|
|
auto tensor4 = paddle::experimental::full(
|
|
{3, 4}, std::numeric_limits<double>::quiet_NaN(), phi::DataType::FLOAT64);
|
|
auto five_tensors =
|
|
std::make_tuple(tensor, tensor1, tensor2, tensor3, tensor4);
|
|
CHECK_NAN_INF(five_tensors);
|
|
auto tensor5 = paddle::experimental::full(
|
|
{3, 4}, std::numeric_limits<double>::quiet_NaN(), phi::DataType::FLOAT64);
|
|
auto six_tensors =
|
|
std::make_tuple(tensor, tensor1, tensor2, tensor3, tensor4, tensor5);
|
|
CHECK_NAN_INF(six_tensors);
|
|
std::vector<paddle::Tensor> tensor_vec;
|
|
tensor_vec.emplace_back(tensor);
|
|
tensor_vec.emplace_back(tensor1);
|
|
CHECK_NAN_INF(tensor_vec);
|
|
paddle::small_vector<std::vector<paddle::Tensor>, egr::kSlotSmallVectorSize>
|
|
small_vec;
|
|
small_vec.emplace_back(tensor_vec);
|
|
CHECK_NAN_INF(small_vec);
|
|
// test selected_rows
|
|
paddle::Tensor tensor_sr;
|
|
auto sr = std::make_shared<phi::SelectedRows>();
|
|
*sr->mutable_value() =
|
|
*(static_cast<const phi::DenseTensor*>(tensor.impl().get()));
|
|
tensor_sr.set_impl(sr);
|
|
CHECK_NAN_INF(tensor_sr);
|
|
// test other tensor
|
|
auto tensor_str = paddle::experimental::strings::empty({3, 4});
|
|
CHECK_NO_NAN_INF(tensor_str);
|
|
}
|
|
|
|
} // namespace egr
|