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

Too lengthy implementation of TensorContainsNan and TensorContainsINF #11949

Closed
wangkuiyi opened this issue Jul 3, 2018 · 1 comment
Closed

Comments

@wangkuiyi
Copy link
Collaborator

The implementation contains three parts:

  1. VisitPlace (35 lines)

    template <typename Visitor>
    struct PlaceVisitorWrapper
    : public boost::static_visitor<typename Visitor::result_type> {
    const Visitor &visitor_;
    explicit PlaceVisitorWrapper(const Visitor &visitor) : visitor_(visitor) {}
    typename Visitor::result_type operator()(const CPUPlace &cpu) const {
    return visitor_(cpu);
    }
    typename Visitor::result_type operator()(const CUDAPlace &cuda) const {
    #ifdef PADDLE_WITH_CUDA
    return visitor_(cuda);
    #else
    PADDLE_THROW("Paddle is not compiled with CUDA. Cannot visit cuda device");
    return typename Visitor::result_type();
    #endif
    }
    typename Visitor::result_type operator()(
    const CUDAPinnedPlace &cuda_pinned) const {
    #ifdef PADDLE_WITH_CUDA
    return visitor_(cuda_pinned);
    #else
    PADDLE_THROW("Paddle is not compiled with CUDA. Cannot visit cuda_pinned");
    return typename Visitor::result_type();
    #endif
    }
    };
    template <typename Visitor>
    typename Visitor::result_type VisitPlace(const Place &place,
    const Visitor &visitor) {
    return boost::apply_visitor(PlaceVisitorWrapper<Visitor>(visitor), place);
    }

  2. The CPU implementation of TensorContainsNaN (~100 lines)

    template <typename Predicate, typename DevCtx>
    struct AnyDTypeVisitor {
    Predicate predicate_;
    const Tensor& tensor_;
    const DevCtx& ctx_;
    Tensor* out_;
    AnyDTypeVisitor(Predicate predicate, const Tensor& tensor, const DevCtx& ctx,
    Tensor* out)
    : predicate_(predicate), tensor_(tensor), ctx_(ctx), out_(out) {}
    template <typename T>
    void operator()() const {
    auto t = EigenVector<T>::Flatten(tensor_);
    auto o = EigenScalar<bool>::From(*out_);
    // return any of predicate_(t) is true.
    o.device(*ctx_.eigen_device()) = predicate_(t).any();
    }
    };
    template <typename Predicate, typename DevCtx>
    inline void AnyImpl(Predicate predicate, const framework::Tensor& tensor,
    const DevCtx& ctx, framework::Tensor* out) {
    VisitDataType(ToDataType(tensor.type()), AnyDTypeVisitor<Predicate, DevCtx>(
    predicate, tensor, ctx, out));
    }
    template <typename Predicate>
    struct AnyVisitor : public boost::static_visitor<bool> {
    const framework::Tensor& tensor_;
    Predicate predicate_;
    AnyVisitor(const framework::Tensor& tensor, Predicate predicate)
    : tensor_(tensor), predicate_(std::move(predicate)) {}
    template <typename Place>
    bool operator()(const Place& place) const {
    framework::Tensor out;
    out.Resize({1});
    out.mutable_data<bool>(place);
    auto* ctx = platform::DeviceContextPool::Instance().GetByPlace(place);
    AnyImpl(predicate_, tensor_, *ctx, &out);
    return this->GetResult(out, place);
    }
    bool GetResult(const framework::Tensor& out,
    const platform::CUDAPlace& gpu) const {
    platform::CPUPlace cpu;
    framework::Tensor tmp;
    tmp.Resize({1});
    tmp.mutable_data<bool>(cpu);
    auto gpuctx = platform::DeviceContextPool::Instance().Get(gpu);
    gpuctx->Wait();
    TensorCopy(out, cpu, *gpuctx, &tmp);
    gpuctx->Wait();
    return GetResult(tmp, cpu);
    }
    bool GetResult(const framework::Tensor& out,
    const platform::CPUPlace& cpu) const {
    return *out.data<bool>();
    }
    bool GetResult(const framework::Tensor& out,
    const platform::CUDAPinnedPlace& cpu) const {
    return *out.data<bool>();
    }
    };
    template <typename Predicate>
    inline bool Any(const framework::Tensor& tensor, Predicate predicate) {
    AnyVisitor<Predicate> visitor(tensor, predicate);
    auto place = tensor.place();
    return platform::VisitPlace(place, visitor);
    }
    struct ContainsNANPredicate {
    template <typename T>
    auto operator()(const T& eigen_vec) const
    -> decltype(std::declval<T>().isnan()) {
    // Cast eigen_vector to vector of bool. true if is inf.
    return eigen_vec.isnan();
    }
    };
    bool TensorContainsNAN(const framework::Tensor& tensor) {
    ContainsNANPredicate predicate;
    return Any(tensor, predicate);
    }
    struct ContainsInfPredicate {
    template <typename T>
    auto operator()(const T& eigen_vec) const
    -> decltype(std::declval<T>().isinf()) {
    // Cast eigen_vector to vector of bool. true if is inf.
    return eigen_vec.isinf();
    }
    };
    bool TensorContainsInf(const framework::Tensor& tensor) {
    ContainsInfPredicate predicate;
    return Any(tensor, predicate);
    }

  3. The CUDA implementation (~100 lines)

template <typename Predicate, typename DevCtx>
struct AnyDTypeVisitor {
Predicate predicate_;
const Tensor& tensor_;
const DevCtx& ctx_;
Tensor* out_;
AnyDTypeVisitor(Predicate predicate, const Tensor& tensor, const DevCtx& ctx,
Tensor* out)
: predicate_(predicate), tensor_(tensor), ctx_(ctx), out_(out) {}
template <typename T>
void operator()() const {
auto t = EigenVector<T>::Flatten(tensor_);
auto o = EigenScalar<bool>::From(*out_);
// return any of predicate_(t) is true.
o.device(*ctx_.eigen_device()) = predicate_(t).any();
}
};
template <typename Predicate, typename DevCtx>
inline void AnyImpl(Predicate predicate, const framework::Tensor& tensor,
const DevCtx& ctx, framework::Tensor* out) {
VisitDataType(ToDataType(tensor.type()), AnyDTypeVisitor<Predicate, DevCtx>(
predicate, tensor, ctx, out));
}
template <typename Predicate>
struct AnyVisitor : public boost::static_visitor<bool> {
const framework::Tensor& tensor_;
Predicate predicate_;
AnyVisitor(const framework::Tensor& tensor, Predicate predicate)
: tensor_(tensor), predicate_(std::move(predicate)) {}
template <typename Place>
bool operator()(const Place& place) const {
framework::Tensor out;
out.Resize({1});
out.mutable_data<bool>(place);
auto* ctx = platform::DeviceContextPool::Instance().GetByPlace(place);
AnyImpl(predicate_, tensor_, *ctx, &out);
return this->GetResult(out, place);
}
bool GetResult(const framework::Tensor& out,
const platform::CUDAPlace& gpu) const {
platform::CPUPlace cpu;
framework::Tensor tmp;
tmp.Resize({1});
tmp.mutable_data<bool>(cpu);
auto gpuctx = platform::DeviceContextPool::Instance().Get(gpu);
gpuctx->Wait();
Copy(out, cpu, *gpuctx, &tmp);
gpuctx->Wait();
return GetResult(tmp, cpu);
}
bool GetResult(const framework::Tensor& out,
const platform::CPUPlace& cpu) const {
return *out.data<bool>();
}
};
template <typename Predicate>
inline bool Any(const framework::Tensor& tensor, Predicate predicate) {
AnyVisitor<Predicate> visitor(tensor, predicate);
auto place = tensor.place();
return platform::VisitPlace(place, visitor);
}
struct HasNANPredicate {
template <typename T>
auto operator()(const T& eigen_vec) const
-> decltype(std::declval<T>().isnan()) {
// Cast eigen_vector to vector of bool. true if is inf.
return eigen_vec.isnan();
}
};
bool HasNAN(const framework::Tensor& tensor) {
HasNANPredicate predicate;
return Any(tensor, predicate);
}
struct HasInfPredicate {
template <typename T>
auto operator()(const T& eigen_vec) const
-> decltype(std::declval<T>().isinf()) {
// Cast eigen_vector to vector of bool. true if is inf.
return eigen_vec.isinf();
}
};
bool HasInf(const framework::Tensor& tensor) {
HasInfPredicate predicate;
return Any(tensor, predicate);
}

There uses about 235 lines of C++ code to test if a tensor contains NaN or INF!

@lucywsq
Copy link

lucywsq commented Aug 28, 2018

Hello, this issue has not been updated in the past month. we will close it today for the sake of other user’s experience. If you still need to follow up on this question after closing, please feel free to reopen it. In that case, we will get back to you within 24 hours. We apologize for the inconvenience caused by the closure and thank you so much for your support of PaddlePaddle Group!

@lucywsq lucywsq closed this as completed Aug 28, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants