提交 ce674b68 编写于 作者: T tensor-tang

add readme doc and complete TODOs

上级 fab0ee87
TBD # JIT Kernel
结合函数模板和JIT生成需要的kernel函数。
这里的kernel是比Operator中kernel更小级别的算子单元,更侧重的是在不同硬件上的性能。
目前仅支持CPU上的高性能计算。
## 目录结构
```txt
PaddlePaddle/Paddle/paddle/fluid/
├── ...
├── operator/
│ ├── .../
└── jit/
├── ...
├── jitcode/
│ └── ...
|── more/
│ ├── ...
│ ├── mkl/
│ │ └── ...
│ └── openblas/
│ └── ...
└── refer/
└── ...
```
基础class都的根目录下,根目录下包括jitcode,more和refer。每个目录下都是一种实现,每种kernel算子都需要有reference的实现,其他的都是可选的。
- jitcode: 代表使用jit生成的code,需要依赖xbyak。他关心的是性能。
- refer:代表reference的实现,每种kernel算子都需要有在CPU上的reference的实现,他主要关心的算法逻辑。
- more: 下面可以放入跟多实现,包括mkl,mkldnn,openblas等,也可以是自身已有的kernel组合。
# Use me ## 动态获取
提供一个get方法,根据kernel类别获取,每种实现都有自己的使用范围,根据范围动态和当前条件选择需要的kernel函数。
## 测试
- 逻辑测试
所有实现都要与refer的code对比,需要满足精度要求
- 性能测试
# 如何添加新的算子
TBD
## Use me
Add USE_JIT_KERNEL(yourname) to CMakefile. Add USE_JIT_KERNEL(yourname) to CMakefile.
...@@ -62,11 +62,7 @@ class JitBase : public Kernel { ...@@ -62,11 +62,7 @@ class JitBase : public Kernel {
}; };
template <KernelType KT, typename T, typename Attr> template <KernelType KT, typename T, typename Attr>
std::unique_ptr<JitBase> CreateJitCode(Attr attr); //{ std::unique_ptr<JitBase> CreateJitCode(Attr attr);
// if (UseJitCode<KT,T,Attr>) {
// return make_unique<xxxxclass>(attr, CodeSize<KT,T,Attr>());
// }
// }
} // namespace jitkernels } // namespace jitkernels
} // namespace operators } // namespace operators
......
...@@ -21,6 +21,13 @@ namespace jitkernels { ...@@ -21,6 +21,13 @@ namespace jitkernels {
typedef enum { vmul = 0, vadd = 1, vsub, vexp } KernelType; typedef enum { vmul = 0, vadd = 1, vsub, vexp } KernelType;
template <typename T>
struct VMulTypes {
typedef T data_type;
typedef int attr_type;
typedef void (*func_type)(const T*, const T*, T*, int);
};
// Just for adding to kernel pool without template // Just for adding to kernel pool without template
class Kernel { class Kernel {
public: public:
...@@ -29,10 +36,10 @@ class Kernel { ...@@ -29,10 +36,10 @@ class Kernel {
DISABLE_COPY_AND_ASSIGN(Kernel); DISABLE_COPY_AND_ASSIGN(Kernel);
}; };
template <typename T, typename Func, typename Attr> // TODO(TJ): use tuple template <typename T, typename Func, typename Attr>
class KernelImpl : public Kernel { class KernelImpl : public Kernel {
public: public:
using ELEMENT_TYPE = T; // TODO(TJ): remove me? using ELEMENT_TYPE = T;
virtual Func GetFunc() const { return func; } virtual Func GetFunc() const { return func; }
virtual bool UseMe(Attr attr) const = 0; virtual bool UseMe(Attr attr) const = 0;
...@@ -40,7 +47,7 @@ class KernelImpl : public Kernel { ...@@ -40,7 +47,7 @@ class KernelImpl : public Kernel {
Func func{nullptr}; Func func{nullptr};
}; };
template <typename T, typename Func, typename Attr> // TODO(TJ): use tuple template <typename T, typename Func, typename Attr>
class ReferKernel : public KernelImpl<T, Func, Attr> { class ReferKernel : public KernelImpl<T, Func, Attr> {
public: public:
// Refer code can always be used // Refer code can always be used
......
...@@ -27,8 +27,6 @@ namespace paddle { ...@@ -27,8 +27,6 @@ namespace paddle {
namespace operators { namespace operators {
namespace jitkernels { namespace jitkernels {
// TODO(TJ): rename file to kernel_pool
template <KernelType KT> template <KernelType KT>
class JitCodePool { class JitCodePool {
typedef std::unique_ptr<JitBase> JitBasePtr; typedef std::unique_ptr<JitBase> JitBasePtr;
...@@ -54,14 +52,6 @@ class JitCodePool { ...@@ -54,14 +52,6 @@ class JitCodePool {
DISABLE_COPY_AND_ASSIGN(JitCodePool); DISABLE_COPY_AND_ASSIGN(JitCodePool);
}; };
// TODO(TJ): std::tuple<T, Func, Attr>
// template <typename T, typename Func, typename Attr>
// struct KernelAttr {
// typedef T data_type;
// typedef Func return_type;
// typedef Attr attr_type;
// };
typedef std::unique_ptr<const Kernel> KernelPtr; typedef std::unique_ptr<const Kernel> KernelPtr;
typedef std::unordered_map<KernelKey, std::vector<KernelPtr>, KernelKey::Hash> typedef std::unordered_map<KernelKey, std::vector<KernelPtr>, KernelKey::Hash>
KernelMap; KernelMap;
...@@ -120,7 +110,6 @@ inline Func GetRefer() { ...@@ -120,7 +110,6 @@ inline Func GetRefer() {
return nullptr; return nullptr;
} }
// TODO(TJ): make tuple? named KernelAttr
template <KernelType KT, typename T, typename Func, typename Attr, template <KernelType KT, typename T, typename Func, typename Attr,
typename PlaceType = platform::CPUPlace> typename PlaceType = platform::CPUPlace>
const Func Get(Attr attr) { const Func Get(Attr attr) {
...@@ -130,8 +119,7 @@ const Func Get(Attr attr) { ...@@ -130,8 +119,7 @@ const Func Get(Attr attr) {
return codes.AllKernels().at(key)->template getCode<Func>(); return codes.AllKernels().at(key)->template getCode<Func>();
} }
if (std::is_same<PlaceType, platform::CPUPlace>::value) { // TODO(TJ): float if (std::is_same<PlaceType, platform::CPUPlace>::value) {
// move to create
auto p = CreateJitCode<KT, T, Attr>(attr); auto p = CreateJitCode<KT, T, Attr>(attr);
if (p) { if (p) {
auto f = p->template getCode<Func>(); auto f = p->template getCode<Func>();
......
...@@ -27,16 +27,9 @@ namespace mkl { ...@@ -27,16 +27,9 @@ namespace mkl {
template <typename T> template <typename T>
void VMul(const T* x, const T* y, T* z, int n); void VMul(const T* x, const T* y, T* z, int n);
// template <typename T>
// struct VMulTypes{
// typedef T date_type;
// typedef void (*func)(const T*, const T*, T*, int) func_type;
// typedef int attr_type;
// };
template <typename T> template <typename T>
class VMulKernel class VMulKernel : public KernelImpl<T, typename VMulTypes<T>::func_type,
: public KernelImpl<T, void (*)(const T*, const T*, T*, int), int> { typename VMulTypes<T>::attr_type> {
public: public:
VMulKernel() { this->func = VMul<T>; } VMulKernel() { this->func = VMul<T>; }
bool UseMe(int d) const override { bool UseMe(int d) const override {
......
...@@ -29,8 +29,8 @@ void VMul(const T* x, const T* y, T* z, int n) { ...@@ -29,8 +29,8 @@ void VMul(const T* x, const T* y, T* z, int n) {
} }
template <typename T> template <typename T>
class VMulKernel class VMulKernel : public ReferKernel<T, typename VMulTypes<T>::func_type,
: public ReferKernel<T, void (*)(const T*, const T*, T*, int), int> { typename VMulTypes<T>::attr_type> {
public: public:
VMulKernel() { this->func = VMul<T>; } VMulKernel() { this->func = VMul<T>; }
}; };
......
...@@ -26,7 +26,7 @@ namespace paddle { ...@@ -26,7 +26,7 @@ namespace paddle {
namespace operators { namespace operators {
namespace jitkernels { namespace jitkernels {
// make_unique is supported from c++14 // make_unique is supported since c++14
template <typename T, typename... Args> template <typename T, typename... Args>
inline std::unique_ptr<T> make_unique(Args&&... args) { inline std::unique_ptr<T> make_unique(Args&&... args) {
static_assert(!std::is_array<T>::value, "T must not be array"); static_assert(!std::is_array<T>::value, "T must not be array");
......
...@@ -69,10 +69,10 @@ TEST(JitKernel, vmul) { ...@@ -69,10 +69,10 @@ TEST(JitKernel, vmul) {
namespace jit = paddle::operators::jitkernels; namespace jit = paddle::operators::jitkernels;
// TODO(TJ): test more vector size // TODO(TJ): test more vector size
for (int d = 1; d < 30; ++d) { for (int d = 1; d < 30; ++d) {
auto ref = jit::GetRefer<jit::vmul, T, auto ref = jit::GetRefer<jit::vmul, T, jit::VMulTypes<T>::func_type,
void (*)(const T*, const T*, T*, int), int>(); jit::VMulTypes<T>::attr_type>();
auto tgt = jit::Get<jit::vmul, T, void (*)(const T*, const T*, T*, int), auto tgt = jit::Get<jit::vmul, T, jit::VMulTypes<T>::func_type,
int, PlaceType>(d); jit::VMulTypes<T>::attr_type, PlaceType>(d);
EXPECT_TRUE(ref != nullptr); EXPECT_TRUE(ref != nullptr);
EXPECT_TRUE(tgt != nullptr); EXPECT_TRUE(tgt != nullptr);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册