提交 9a3a246c 编写于 作者: S sneaxiy

fix py35 compile error

test=develop
上级 b56aca82
...@@ -40,6 +40,7 @@ proto_library(async_executor_proto SRCS data_feed.proto) ...@@ -40,6 +40,7 @@ proto_library(async_executor_proto SRCS data_feed.proto)
cc_library(ddim SRCS ddim.cc DEPS eigen3 boost enforce) cc_library(ddim SRCS ddim.cc DEPS eigen3 boost enforce)
cc_test(ddim_test SRCS ddim_test.cc DEPS ddim) cc_test(ddim_test SRCS ddim_test.cc DEPS ddim)
nv_test(dim_test SRCS dim_test.cu DEPS ddim) nv_test(dim_test SRCS dim_test.cu DEPS ddim)
cc_test(unroll_array_ops_test SRCS unroll_array_ops_test.cc)
cc_library(data_type SRCS data_type.cc DEPS framework_proto ddim device_context) cc_library(data_type SRCS data_type.cc DEPS framework_proto ddim device_context)
cc_test(data_type_test SRCS data_type_test.cc DEPS data_type place tensor) cc_test(data_type_test SRCS data_type_test.cc DEPS data_type place tensor)
if(WITH_GPU) if(WITH_GPU)
......
...@@ -26,11 +26,12 @@ class Array { ...@@ -26,11 +26,12 @@ class Array {
public: public:
static constexpr size_t kSize = N; static constexpr size_t kSize = N;
HOSTDEVICE inline Array() = default; HOSTDEVICE inline Array() {}
template <typename... Args> template <typename... Args>
HOSTDEVICE inline explicit Array(const T &val, Args... args) { HOSTDEVICE inline explicit Array(const T &val, Args... args) {
UnrollVarArgsAssign<T, N>::Run(data_, val, args...); static_assert(N == sizeof...(Args) + 1, "Invalid argument");
UnrollVarArgsAssign<T>::Run(data_, val, args...);
} }
HOSTDEVICE inline void Fill(const T &val) { HOSTDEVICE inline void Fill(const T &val) {
...@@ -41,10 +42,29 @@ class Array { ...@@ -41,10 +42,29 @@ class Array {
HOSTDEVICE inline T *GetMutable() { return data_; } HOSTDEVICE inline T *GetMutable() { return data_; }
HOSTDEVICE inline T &operator[](size_t index) { return data_[index]; } HOSTDEVICE inline T &operator[](size_t i) { return *advance(data_, i); }
HOSTDEVICE inline const T &operator[](size_t index) const { // Writing "return data_[i]" would cause compilation warning/error:
return data_[index]; // "array subscript is above array bound" in Python 35 CI.
// It seems that it is a false warning of GCC if we do not check the bounds
// of array index. But for better performance, we do not check in operator[]
// like what is in STL. If users want to check the bounds, use at() instead
HOSTDEVICE inline const T &operator[](size_t i) const {
return *advance(data_, i);
}
HOSTDEVICE inline T &at(size_t i) {
#ifndef __CUDA_ARCH__
PADDLE_ENFORCE_LT(i, N, "Array index out of bounds");
#endif
return (*this)[i];
}
HOSTDEVICE inline const T &at(size_t i) const {
#ifndef __CUDA_ARCH__
PADDLE_ENFORCE_LT(i, N, "Array index out of bounds");
#endif
return (*this)[i];
} }
HOSTDEVICE constexpr size_t size() const { return N; } HOSTDEVICE constexpr size_t size() const { return N; }
...@@ -58,6 +78,11 @@ class Array { ...@@ -58,6 +78,11 @@ class Array {
} }
private: private:
template <typename U>
HOSTDEVICE static inline U *advance(U *ptr, size_t i) {
return ptr + i;
}
T data_[N]; T data_[N];
}; };
...@@ -66,7 +91,7 @@ class Array<T, 0> { ...@@ -66,7 +91,7 @@ class Array<T, 0> {
public: public:
static constexpr size_t kSize = 0; static constexpr size_t kSize = 0;
HOSTDEVICE inline Array() = default; HOSTDEVICE inline Array() {}
HOSTDEVICE inline void Fill(const T &val) {} HOSTDEVICE inline void Fill(const T &val) {}
...@@ -75,18 +100,28 @@ class Array<T, 0> { ...@@ -75,18 +100,28 @@ class Array<T, 0> {
// Add constexpr to GetMutable() cause warning in MAC // Add constexpr to GetMutable() cause warning in MAC
HOSTDEVICE inline T *GetMutable() { return nullptr; } HOSTDEVICE inline T *GetMutable() { return nullptr; }
HOSTDEVICE inline T &operator[](size_t index) { HOSTDEVICE inline T &operator[](size_t) {
#ifndef __CUDA_ARCH__ #ifdef __CUDA_ARCH__
static T obj();
return obj;
#else
PADDLE_THROW("Array<T, 0> has no element"); PADDLE_THROW("Array<T, 0> has no element");
#endif #endif
} }
HOSTDEVICE inline const T &operator[](size_t index) const { HOSTDEVICE inline const T &operator[](size_t) const {
#ifndef __CUDA_ARCH__ #ifdef __CUDA_ARCH__
static const T obj();
return obj;
#else
PADDLE_THROW("Array<T, 0> has no element"); PADDLE_THROW("Array<T, 0> has no element");
#endif #endif
} }
HOSTDEVICE inline T &at(size_t i) { return (*this)[i]; }
HOSTDEVICE inline const T &at(size_t i) const { return (*this)[i]; }
HOSTDEVICE constexpr size_t size() const { return 0; } HOSTDEVICE constexpr size_t size() const { return 0; }
HOSTDEVICE constexpr bool operator==(const Array<T, 0> &other) const { HOSTDEVICE constexpr bool operator==(const Array<T, 0> &other) const {
......
...@@ -60,9 +60,7 @@ class DDim { ...@@ -60,9 +60,7 @@ class DDim {
DDim() : rank_(1) { dim_[0] = 0; } DDim() : rank_(1) { dim_[0] = 0; }
DDim(const DDim& ddim) : dim_(), rank_(ddim.rank_) { DDim(const DDim& ddim) { CopyFrom(ddim); }
dynamic_dim_assign(ddim.dim_.Get(), dim_.GetMutable(), rank_);
}
DDim(const int* d, int n) : rank_(n) { DDim(const int* d, int n) : rank_(n) {
dynamic_dim_assign(d, dim_.GetMutable(), n); dynamic_dim_assign(d, dim_.GetMutable(), n);
...@@ -80,10 +78,12 @@ class DDim { ...@@ -80,10 +78,12 @@ class DDim {
/*implicit*/ DDim(std::initializer_list<int64_t> init_list) /*implicit*/ DDim(std::initializer_list<int64_t> init_list)
: DDim(init_list.begin(), init_list.size()) {} : DDim(init_list.begin(), init_list.size()) {}
inline DDim& operator=(const DDim& ddim) { return CopyFrom(ddim); }
template <int D> template <int D>
inline DDim& operator=(const Dim<D>& in) { inline DDim& operator=(const Dim<D>& dim) {
rank_ = D; rank_ = D;
UnsafeCast<D>() = in; UnsafeCast<D>() = dim;
return *this; return *this;
} }
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
#pragma once #pragma once
#include <cstddef>
#include <type_traits> #include <type_traits>
#include "paddle/fluid/platform/hostdevice.h" #include "paddle/fluid/platform/hostdevice.h"
...@@ -52,21 +53,30 @@ struct UnrollAssign<kStart, kEnd, true> { ...@@ -52,21 +53,30 @@ struct UnrollAssign<kStart, kEnd, true> {
}; };
template <typename T, size_t kStart, size_t kEnd, bool kStop> template <typename T, size_t kStart, size_t kEnd, bool kStop>
struct UnrollVarArgsAssign { struct UnrollVarArgsAssignImpl {
template <typename... Args> template <typename... Args>
HOSTDEVICE inline static void Run(T *d, T val, Args... args) { HOSTDEVICE inline static void Run(T *d, T val, Args... args) {
static_assert(sizeof...(args) + 1 == kEnd - kStart, "Wrong argument"); static_assert(sizeof...(args) + 1 == kEnd - kStart, "Wrong argument");
d[kStart] = val; d[kStart] = val;
UnrollVarArgsAssign<T, kStart + 1, kEnd, kStart + 1 == kEnd>::Run(d, UnrollVarArgsAssignImpl<T, kStart + 1, kEnd, kStart + 1 == kEnd>::Run(
args...); d, args...);
} }
}; };
template <typename T, size_t kStart, size_t kEnd> template <typename T, size_t kStart, size_t kEnd>
struct UnrollVarArgsAssign<T, kStart, kEnd, true> { struct UnrollVarArgsAssignImpl<T, kStart, kEnd, true> {
HOSTDEVICE inline static void Run(T *d) {} HOSTDEVICE inline static void Run(T *d) {}
}; };
template <typename T>
struct UnrollVarArgsAssign {
template <typename... Args>
HOSTDEVICE inline static void Run(T *d, Args... args) {
UnrollVarArgsAssignImpl<T, 0, sizeof...(Args), sizeof...(Args) == 0>::Run(
d, args...);
}
};
template <size_t kStart, size_t kEnd, bool kStop> template <size_t kStart, size_t kEnd, bool kStop>
struct UnrollCompare { struct UnrollCompare {
template <typename T> template <typename T>
...@@ -150,8 +160,8 @@ using UnrollFillConstant = detail::UnrollFillConstant<0, N, N == 0>; ...@@ -150,8 +160,8 @@ using UnrollFillConstant = detail::UnrollFillConstant<0, N, N == 0>;
template <size_t N> template <size_t N>
using UnrollAssign = detail::UnrollAssign<0, N, N == 0>; using UnrollAssign = detail::UnrollAssign<0, N, N == 0>;
template <typename T, size_t N> template <typename T>
using UnrollVarArgsAssign = detail::UnrollVarArgsAssign<T, 0, N, N == 0>; using UnrollVarArgsAssign = detail::UnrollVarArgsAssign<T>;
template <size_t N> template <size_t N>
using UnrollCompare = detail::UnrollCompare<0, N, N == 0>; using UnrollCompare = detail::UnrollCompare<0, N, N == 0>;
......
// Copyright (c) 2018 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/framework/unroll_array_ops.h"
#include <gtest/gtest.h>
#include <algorithm>
#include <array>
#include <cstdint>
namespace paddle {
namespace framework {
template <typename T>
bool CheckEquality(const T* p, size_t n, T val) {
return std::all_of(p, p + n, [val](const T& v) { return v == val; });
}
template <int D1, int D2>
bool FillConstantTestMain() {
static_assert(D1 >= D2, "");
std::array<int, D1> arr;
arr.fill(0);
UnrollFillConstant<D2>::Run(arr.data(), 1);
return CheckEquality(arr.data(), D2, 1) &&
CheckEquality(arr.data() + D2, arr.size() - D2, 0);
}
TEST(unroll_ops, fill_constant) {
EXPECT_TRUE((FillConstantTestMain<9, 0>()));
EXPECT_TRUE((FillConstantTestMain<9, 1>()));
EXPECT_TRUE((FillConstantTestMain<9, 4>()));
EXPECT_TRUE((FillConstantTestMain<9, 9>()));
}
TEST(unroll_ops, assign) {
const int a[] = {1, 2, 3, 4, 5};
int b[] = {0, 0, 0, 0, 0};
UnrollAssign<3>::Run(a, b);
EXPECT_EQ(b[0], 1);
EXPECT_EQ(b[1], 2);
EXPECT_EQ(b[2], 3);
EXPECT_EQ(b[3], 0);
EXPECT_EQ(b[4], 0);
}
TEST(unroll_ops, var_args_assign) {
int a[] = {0, 0, 0};
UnrollVarArgsAssign<int>::Run(a, 1, 2);
EXPECT_EQ(a[0], 1);
EXPECT_EQ(a[1], 2);
EXPECT_EQ(a[2], 0);
}
TEST(unroll_ops, compare) {
int a[] = {1, 2, 3};
int b[] = {1, 2, 4};
EXPECT_TRUE(UnrollCompare<2>::Run(a, b));
EXPECT_FALSE(UnrollCompare<3>::Run(a, b));
b[0] = -1;
EXPECT_TRUE(UnrollCompare<0>::Run(a, b));
EXPECT_FALSE(UnrollCompare<1>::Run(a, b));
}
TEST(unroll_ops, add) {
int a[] = {2, 3, 4};
int b[] = {5, 10, 102};
int c[] = {0, 0, 0};
UnrollAdd<2>::Run(a, b, c);
EXPECT_EQ(a[0] + b[0], c[0]);
EXPECT_EQ(a[1] + b[1], c[1]);
EXPECT_EQ(c[2], 0);
}
TEST(unroll_ops, mul) {
int a[] = {2, 3, 4};
int b[] = {5, 10, 102};
int c[] = {0, 0, 0};
UnrollMul<2>::Run(a, b, c);
EXPECT_EQ(a[0] * b[0], c[0]);
EXPECT_EQ(a[1] * b[1], c[1]);
EXPECT_EQ(c[2], 0);
}
TEST(unroll_ops, product) {
int a[] = {2, 3, 4};
int b[] = {5, 10, 102};
EXPECT_EQ(UnrollProduct<3>::Run(a), a[0] * a[1] * a[2]);
EXPECT_EQ(UnrollProduct<3>::Run(a, b),
a[0] * b[0] + a[1] * b[1] + a[2] * b[2]);
}
} // namespace framework
} // namespace paddle
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册