From 77236e33fc0d8b72890b700abbe47c838989baaf Mon Sep 17 00:00:00 2001 From: tensor-tang Date: Mon, 26 Nov 2018 05:41:51 +0000 Subject: [PATCH] init jitkernel --- paddle/fluid/operators/CMakeLists.txt | 1 + .../fluid/operators/jitkernels/CMakeLists.txt | 17 +++ paddle/fluid/operators/jitkernels/README.md | 1 + .../jitkernels/jitcode/CMakeLists.txt | 3 + .../operators/jitkernels/jitcode/jitcode.cc | 15 ++ .../operators/jitkernels/jitcode/jitcode.h | 54 +++++++ .../operators/jitkernels/jitcode_base.cc | 40 +++++ .../fluid/operators/jitkernels/jitcode_base.h | 73 +++++++++ .../fluid/operators/jitkernels/kernel_base.h | 47 ++++++ .../fluid/operators/jitkernels/kernel_key.h | 49 ++++++ paddle/fluid/operators/jitkernels/kernels.cc | 33 ++++ paddle/fluid/operators/jitkernels/kernels.h | 142 ++++++++++++++++++ .../operators/jitkernels/more/CMakeLists.txt | 7 + .../jitkernels/more/mkl/CMakeLists.txt | 3 + .../operators/jitkernels/more/mkl/mkl.cc | 44 ++++++ .../fluid/operators/jitkernels/more/mkl/mkl.h | 55 +++++++ paddle/fluid/operators/jitkernels/more/more.h | 15 ++ .../operators/jitkernels/refer/CMakeLists.txt | 3 + .../fluid/operators/jitkernels/refer/refer.cc | 20 +++ .../fluid/operators/jitkernels/refer/refer.h | 33 ++++ paddle/fluid/operators/jitkernels/registry.h | 134 +++++++++++++++++ paddle/fluid/operators/jitkernels/test.cc | 36 +++++ paddle/fluid/operators/math/CMakeLists.txt | 16 +- paddle/fluid/platform/cpu_info.h | 2 +- 24 files changed, 834 insertions(+), 9 deletions(-) create mode 100644 paddle/fluid/operators/jitkernels/CMakeLists.txt create mode 100644 paddle/fluid/operators/jitkernels/README.md create mode 100644 paddle/fluid/operators/jitkernels/jitcode/CMakeLists.txt create mode 100644 paddle/fluid/operators/jitkernels/jitcode/jitcode.cc create mode 100644 paddle/fluid/operators/jitkernels/jitcode/jitcode.h create mode 100644 paddle/fluid/operators/jitkernels/jitcode_base.cc create mode 100644 paddle/fluid/operators/jitkernels/jitcode_base.h create mode 100644 paddle/fluid/operators/jitkernels/kernel_base.h create mode 100644 paddle/fluid/operators/jitkernels/kernel_key.h create mode 100644 paddle/fluid/operators/jitkernels/kernels.cc create mode 100644 paddle/fluid/operators/jitkernels/kernels.h create mode 100644 paddle/fluid/operators/jitkernels/more/CMakeLists.txt create mode 100644 paddle/fluid/operators/jitkernels/more/mkl/CMakeLists.txt create mode 100644 paddle/fluid/operators/jitkernels/more/mkl/mkl.cc create mode 100644 paddle/fluid/operators/jitkernels/more/mkl/mkl.h create mode 100644 paddle/fluid/operators/jitkernels/more/more.h create mode 100644 paddle/fluid/operators/jitkernels/refer/CMakeLists.txt create mode 100644 paddle/fluid/operators/jitkernels/refer/refer.cc create mode 100644 paddle/fluid/operators/jitkernels/refer/refer.h create mode 100644 paddle/fluid/operators/jitkernels/registry.h create mode 100644 paddle/fluid/operators/jitkernels/test.cc diff --git a/paddle/fluid/operators/CMakeLists.txt b/paddle/fluid/operators/CMakeLists.txt index 8c8dc7026e..3458df1606 100644 --- a/paddle/fluid/operators/CMakeLists.txt +++ b/paddle/fluid/operators/CMakeLists.txt @@ -16,6 +16,7 @@ add_subdirectory(metrics) add_subdirectory(optimizers) add_subdirectory(reduce_ops) add_subdirectory(sequence_ops) +add_subdirectory(jitkernels) if(WITH_DISTRIBUTE) add_subdirectory(distributed) diff --git a/paddle/fluid/operators/jitkernels/CMakeLists.txt b/paddle/fluid/operators/jitkernels/CMakeLists.txt new file mode 100644 index 0000000000..f073210542 --- /dev/null +++ b/paddle/fluid/operators/jitkernels/CMakeLists.txt @@ -0,0 +1,17 @@ + +set(JIT_KERNEL_DEPS cpu_info cblas gflags enforce place) + +cc_library(jit_kernel_base SRCS kernels.cc DEPS ${JIT_KERNEL_DEPS}) + +add_subdirectory(more) +add_subdirectory(refer) + +if(WITH_XBYAK) + add_subdirectory(jitcode) +endif() + +# Debug +message(STATUS "--------${JIT_KERNEL_DEPS}") + +cc_library(jit_kernel SRCS kernels.cc DEPS ${JIT_KERNEL_DEPS}) +cc_test(jit_kernel_test SRCS test.cc DEPS jit_kernel) diff --git a/paddle/fluid/operators/jitkernels/README.md b/paddle/fluid/operators/jitkernels/README.md new file mode 100644 index 0000000000..a0990367ef --- /dev/null +++ b/paddle/fluid/operators/jitkernels/README.md @@ -0,0 +1 @@ +TBD diff --git a/paddle/fluid/operators/jitkernels/jitcode/CMakeLists.txt b/paddle/fluid/operators/jitkernels/jitcode/CMakeLists.txt new file mode 100644 index 0000000000..1a5e457309 --- /dev/null +++ b/paddle/fluid/operators/jitkernels/jitcode/CMakeLists.txt @@ -0,0 +1,3 @@ + +cc_library(jit_kernel_jitcode SRCS jitcode.cc DEPS jit_kernel_base xbyak) +set(JIT_KERNEL_DEPS ${JIT_KERNEL_DEPS} xbyak jit_kernel_jitcode PARENT_SCOPE) diff --git a/paddle/fluid/operators/jitkernels/jitcode/jitcode.cc b/paddle/fluid/operators/jitkernels/jitcode/jitcode.cc new file mode 100644 index 0000000000..0dd2d049d2 --- /dev/null +++ b/paddle/fluid/operators/jitkernels/jitcode/jitcode.cc @@ -0,0 +1,15 @@ +/* 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/operators/jitkernels/jitcode/jitcode.h" diff --git a/paddle/fluid/operators/jitkernels/jitcode/jitcode.h b/paddle/fluid/operators/jitkernels/jitcode/jitcode.h new file mode 100644 index 0000000000..c100444766 --- /dev/null +++ b/paddle/fluid/operators/jitkernels/jitcode/jitcode.h @@ -0,0 +1,54 @@ +/* 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. */ + +#pragma once + +#include +#include "paddle/fluid/operators/jitkernels/kernels.h" + +#define XBYAK_USE_MMAP_ALLOCATOR +#include "xbyak/xbyak.h" +#include "xbyak/xbyak_util.h" + +namespace paddle { +namespace operators { +namespace jitkernels { +namespace jitcode { + +// Application Binary Interface +constexpr Xbyak::Operand::Code abi_param1(Xbyak::Operand::RDI), + abi_param2(Xbyak::Operand::RSI), abi_param3(Xbyak::Operand::RDX), + abi_param4(Xbyak::Operand::RCX), abi_not_param1(Xbyak::Operand::RCX); + +template +class JitCode : public JitBase, public Xbyak::CodeGenerator { + public: + JitCode(Attr attr, size_t code_size, void* code_ptr = nullptr) + : Xbyak::CodeGenerator(code_size, code_ptr) { + this->genCode(); + } + + virtual const char* name() const = 0; + virtual void genCode() = 0; + + const unsigned char* getCodeInternal() override { + const Xbyak::uint8* code = CodeGenerator::getCode(); + return code; + } +}; + +} // namespace jitcode +} // namespace jitkernels +} // namespace operators +} // namespace paddle diff --git a/paddle/fluid/operators/jitkernels/jitcode_base.cc b/paddle/fluid/operators/jitkernels/jitcode_base.cc new file mode 100644 index 0000000000..417c4d4b9e --- /dev/null +++ b/paddle/fluid/operators/jitkernels/jitcode_base.cc @@ -0,0 +1,40 @@ +/* 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/operators/jitkernels/jitcode_base.h" + +DEFINE_bool(dump_jitcode, false, "Whether to dump the jitcode to file"); + +namespace paddle { +namespace operators { +namespace jitkernels { + +// refer do not need useme, it would be the last one. +void JitBase::dumpCode(const unsigned char* code) const { + if (code) { + static int counter = 0; + std::ostringstream filename; + filename << "paddle_jitcode_" << name() << "." << counter << ".bin"; + counter++; + std::ofstream fout(filename.str(), std::ios::out); + if (fout.is_open()) { + fout.write(reinterpret_cast(code), getSize()); + fout.close(); + } + } +} + +} // namespace jitkernels +} // namespace operators +} // namespace paddle diff --git a/paddle/fluid/operators/jitkernels/jitcode_base.h b/paddle/fluid/operators/jitkernels/jitcode_base.h new file mode 100644 index 0000000000..0cd6d3c741 --- /dev/null +++ b/paddle/fluid/operators/jitkernels/jitcode_base.h @@ -0,0 +1,73 @@ +/* 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. */ + +#pragma once + +#include +#include "paddle/fluid/operators/jitkernels/kernel_base.h" +#include "paddle/fluid/platform/macros.h" + +DECLARE_bool(dump_jitcode); + +namespace paddle { +namespace operators { +namespace jitkernels { + +// TODO(TJ): make these functions as virtual of a class + +// Every JitCode should estimate the code size itself +template +size_t CodeSize(Attr attr) { + return 4096; +} + +// Every JitCode should have a condition when to use this JitCode +template +bool UseJitCode(Attr attr) { + return false; +} + +// Every JitCode should have a method to get the key from attribution +template +size_t GetKey(Attr attr); + +template <> +size_t GetKey(int d) { + return d; +} + +class JitBase { + public: + JitBase() = default; + virtual ~JitBase() = default; + virtual const char* name() const = 0; + virtual const unsigned char* getCodeInternal() = 0; + + template + const FUNC getCode() { + const unsigned char* code = this->getCodeInternal(); + if (FLAGS_dump_jitcode) { + this->dumpCode(code); + } + return reinterpret_cast(code); + } + DISABLE_COPY_AND_ASSIGN(JitBase); + + protected: + void dumpCode(const unsigned char* code); +}; + +} // namespace jitkernels +} // namespace operators +} // namespace paddle diff --git a/paddle/fluid/operators/jitkernels/kernel_base.h b/paddle/fluid/operators/jitkernels/kernel_base.h new file mode 100644 index 0000000000..bd95a921c5 --- /dev/null +++ b/paddle/fluid/operators/jitkernels/kernel_base.h @@ -0,0 +1,47 @@ +/* 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. */ + +#pragma once +#include "paddle/fluid/platform/macros.h" + +namespace paddle { +namespace operators { +namespace jitkernels { + +typedef enum { vmul = 0, vadd = 1, vsub, vexp } KernelType; + +// Just for adding to kernel pool without template +class Kernel { + public: + Kernel() = default; + DISABLE_COPY_AND_ASSIGN(Kernel); +}; + +template // TODO(TJ): use tuple +class KernelImpl : public Kernel { + public: + using ELEMENT_TYPE = T; // TODO(TJ): remove me? + KernelImpl() = default; + virtual ~KernelImpl() = default; + + virtual Func GetFunc() { return func; } + virtual bool UseMe(Attr attr) const = 0; + + protected: + Func func{nullptr}; +}; + +} // namespace jitkernels +} // namespace operators +} // namespace paddle diff --git a/paddle/fluid/operators/jitkernels/kernel_key.h b/paddle/fluid/operators/jitkernels/kernel_key.h new file mode 100644 index 0000000000..e06c2b58da --- /dev/null +++ b/paddle/fluid/operators/jitkernels/kernel_key.h @@ -0,0 +1,49 @@ +/* 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. */ + +#pragma once +#include "paddle/fluid/operators/jitkernels/kernel_base.h" +#include "paddle/fluid/platform/place.h" + +namespace paddle { +namespace operators { +namespace jitkernels { + +struct KernelKey { + struct Hash { + size_t operator()(const KernelKey& key) const { + int place = key.place_.which(); // less than 2^8 + int type = static_cast(key.type_) << 8; // less than 2^(32-8) + std::hash hasher; + return hasher(place + type); + } + }; + + KernelType type_; + platform::Place place_; + + KernelKey(KernelType type, platform::Place place) + : type_(type), place_(place) {} + size_t hash_key() const { return Hash()(*this); } + + bool operator==(const KernelKey& o) const { + return platform::places_are_same_class(place_, o.place_) && + type_ == o.type_; + } + bool operator!=(const KernelKey& o) const { return !(*this == o); } +}; + +} // namespace jitkernels +} // namespace operators +} // namespace paddle diff --git a/paddle/fluid/operators/jitkernels/kernels.cc b/paddle/fluid/operators/jitkernels/kernels.cc new file mode 100644 index 0000000000..76f49514ee --- /dev/null +++ b/paddle/fluid/operators/jitkernels/kernels.cc @@ -0,0 +1,33 @@ +/* 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/operators/jitkernels/kernels.h" +#include // for shared_ptr +#include +#include + +namespace paddle { +namespace operators { +namespace jitkernels { + +// refer do not need useme, it would be the last one. + +KernelPool& KernelPool::Instance() { + static KernelPool g_kernel_pool; + return g_kernel_pool; +} + +} // namespace jitkernels +} // namespace operators +} // namespace paddle diff --git a/paddle/fluid/operators/jitkernels/kernels.h b/paddle/fluid/operators/jitkernels/kernels.h new file mode 100644 index 0000000000..2792b897d3 --- /dev/null +++ b/paddle/fluid/operators/jitkernels/kernels.h @@ -0,0 +1,142 @@ +/* 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. */ + +#pragma once + +#include // for shared_ptr +#include +#include +#include + +#include "paddle/fluid/operators/jitkernels/jitcode_base.h" +#include "paddle/fluid/operators/jitkernels/kernel_base.h" +#include "paddle/fluid/operators/jitkernels/kernel_key.h" + +#ifdef PADDLE_WITH_XBYAK +#include "paddle/fluid/operators/jitkernels/jitcode/jitcode.h" +#endif + +namespace paddle { +namespace operators { +namespace jitkernels { + +template +class JitCodePool { + public: + static JitCodePool& Instance() { + static thread_local JitCodePool g_jit_codes; + return g_jit_codes; + } + + std::shared_ptr Get(size_t key) const { + if (codes_.find(key) == codes_.end()) { + return nullptr; + } + return codes_.at(key); + } + + void Insert(size_t key, const std::shared_ptr& value) { + codes_.insert({key, value}); + } + + private: + JitCodePool() = default; + std::unordered_map> codes_; + + DISABLE_COPY_AND_ASSIGN(JitCodePool); +}; + +// std::tuple +template +struct KernelAttr { + typedef T data_type; + typedef Func return_type; + typedef Attr attr_type; +}; + +class KernelPool { + public: + static KernelPool& Instance(); + + typedef std::unique_ptr KernelPtr; + typedef std::unordered_map, KernelKey::Hash> + KernelMap; + KernelMap& AllKernels() { return pool_; } + + void Insert(const KernelKey& key, KernelPtr value) { + if (pool_.find(key) == pool_.end()) { + pool_.emplace(key, std::vector()); + } + pool_.at(key).emplace_back(std::move(value)); + } + KernelPool() = default; + + private: + KernelMap pool_; + + DISABLE_COPY_AND_ASSIGN(KernelPool); +}; + +// TODO(TJ): create_jitcode; + +// TODO(TJ): make tuple? named KernelAttr +template +Func Get(Attr attr) { + size_t key = GetKey(attr); + auto jitcode = JitCodePool().Instance().Get(key); + if (jitcode) { + return jitcode->template getCode(); + } + +#ifdef PADDLE_WITH_XBYAK +// // jitcode::JitCode is under protection of PADDLE_WITH_XBYAK +// if (std::is_same::value) { +// if (UseJitCode(attr)) { +// std::shared_ptr p(std::make_shared>( +// attr, CodeSize(attr))); +// JitCodePool().Instance().Insert(key, p); +// return p->getCode(); +// } +// } +#endif + + // (KernelKey(type, place), vector) + auto& pool = KernelPool().Instance().AllKernels(); + KernelKey kkey(KT, PlaceType()); + auto iter = pool.find(kkey); + if (iter != pool.end()) { + auto impls = iter->second; + for (auto impl : impls) { + auto i = std::dynamic_pointer_cast>(impl.get()); + if (i && i->UseMe(attr)) { + return i->GetFunc(); + } + } + } + + // The last implementation should be reference function on CPU + // Every kernel should have refer code. + + // because of test refer should have it's own pool + // PADDLE_ENFORCE_GT(list.size(), 1) << "Should have refer implemtation"; + // const auto& refer = KernelRefer().AllKernels(); + // return refer.Get(); + + return nullptr; +} + +} // namespace jitkernels +} // namespace operators +} // namespace paddle diff --git a/paddle/fluid/operators/jitkernels/more/CMakeLists.txt b/paddle/fluid/operators/jitkernels/more/CMakeLists.txt new file mode 100644 index 0000000000..84f1811ced --- /dev/null +++ b/paddle/fluid/operators/jitkernels/more/CMakeLists.txt @@ -0,0 +1,7 @@ + + +if(WITH_MKLML) + add_subdirectory(mkl) +endif() + +set(JIT_KERNEL_DEPS ${JIT_KERNEL_DEPS} PARENT_SCOPE) diff --git a/paddle/fluid/operators/jitkernels/more/mkl/CMakeLists.txt b/paddle/fluid/operators/jitkernels/more/mkl/CMakeLists.txt new file mode 100644 index 0000000000..94d2487866 --- /dev/null +++ b/paddle/fluid/operators/jitkernels/more/mkl/CMakeLists.txt @@ -0,0 +1,3 @@ + +cc_library(jit_kernel_mkl SRCS mkl.cc DEPS jit_kernel_base dynload_mklml) +set(JIT_KERNEL_DEPS ${JIT_KERNEL_DEPS} dynload_mklml jit_kernel_mkl PARENT_SCOPE) diff --git a/paddle/fluid/operators/jitkernels/more/mkl/mkl.cc b/paddle/fluid/operators/jitkernels/more/mkl/mkl.cc new file mode 100644 index 0000000000..88a7d66194 --- /dev/null +++ b/paddle/fluid/operators/jitkernels/more/mkl/mkl.cc @@ -0,0 +1,44 @@ +/* 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/operators/jitkernels/more/mkl/mkl.h" +#include "paddle/fluid/operators/jitkernels/registry.h" +#include "paddle/fluid/platform/dynload/mklml.h" + +namespace paddle { +namespace operators { +namespace jitkernels { +namespace more { +namespace mkl { + +template <> +void VMul(const float* x, const float* y, float* z, int n) { + platform::dynload::vsMul(n, x, y, z); +} + +template <> +void VMul(const double* x, const double* y, double* z, int n) { + platform::dynload::vdMul(n, x, y, z); +} + +} // namespace mkl +} // namespace more +} // namespace jitkernels +} // namespace operators +} // namespace paddle + +namespace mkl = paddle::operators::jitkernels::more::mkl; + +REGISTER_JITKERNEL_MORE(vmul, mkl, mkl::VMulKernel, + mkl::VMulKernel); diff --git a/paddle/fluid/operators/jitkernels/more/mkl/mkl.h b/paddle/fluid/operators/jitkernels/more/mkl/mkl.h new file mode 100644 index 0000000000..7cb4334e50 --- /dev/null +++ b/paddle/fluid/operators/jitkernels/more/mkl/mkl.h @@ -0,0 +1,55 @@ +/* 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. */ + +#pragma once + +#include +#include "paddle/fluid/operators/jitkernels/kernel_base.h" +#include "paddle/fluid/platform/cpu_info.h" + +namespace paddle { +namespace operators { +namespace jitkernels { +namespace more { +namespace mkl { + +template +void VMul(const T* x, const T* y, T* z, int n); + +// template +// struct VMulTypes{ +// typedef T date_type; +// typedef void (*func)(const T*, const T*, T*, int) func_type; +// typedef int attr_type; +// }; + +template +class VMulKernel + : public KernelImpl { + public: + VMulKernel() { this->func = VMul; } + bool UseMe(int d) const override { + if (std::is_same::value) { + return platform::jit::MayIUse(platform::jit::avx512f) && d > 512; + } else { + return true; + } + } +}; + +} // namespace mkl +} // namespace more +} // namespace jitkernels +} // namespace operators +} // namespace paddle diff --git a/paddle/fluid/operators/jitkernels/more/more.h b/paddle/fluid/operators/jitkernels/more/more.h new file mode 100644 index 0000000000..ab99fdc05f --- /dev/null +++ b/paddle/fluid/operators/jitkernels/more/more.h @@ -0,0 +1,15 @@ +/* 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. */ + +#pragma once diff --git a/paddle/fluid/operators/jitkernels/refer/CMakeLists.txt b/paddle/fluid/operators/jitkernels/refer/CMakeLists.txt new file mode 100644 index 0000000000..8c116e42dc --- /dev/null +++ b/paddle/fluid/operators/jitkernels/refer/CMakeLists.txt @@ -0,0 +1,3 @@ + +cc_library(jit_kernel_refer SRCS refer.cc DEPS jit_kernel_base) +set(JIT_KERNEL_DEPS ${JIT_KERNEL_DEPS} jit_kernel_refer PARENT_SCOPE) diff --git a/paddle/fluid/operators/jitkernels/refer/refer.cc b/paddle/fluid/operators/jitkernels/refer/refer.cc new file mode 100644 index 0000000000..1f6d384fc2 --- /dev/null +++ b/paddle/fluid/operators/jitkernels/refer/refer.cc @@ -0,0 +1,20 @@ +/* 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/operators/jitkernels/refer/refer.h" +#include "paddle/fluid/operators/jitkernels/registry.h" + +namespace refer = paddle::operators::jitkernels::refer; + +// REGISTER_JITKERNEL_REFER(vmul, refer::VMul, refer::VMul); diff --git a/paddle/fluid/operators/jitkernels/refer/refer.h b/paddle/fluid/operators/jitkernels/refer/refer.h new file mode 100644 index 0000000000..be55c30b1e --- /dev/null +++ b/paddle/fluid/operators/jitkernels/refer/refer.h @@ -0,0 +1,33 @@ +/* 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. */ + +#pragma once +#include "paddle/fluid/platform/enforce.h" + +namespace paddle { +namespace operators { +namespace jitkernels { +namespace refer { + +template +void VMul(const T* x, const T* y, T* z, int n) { + for (int i = 0; i < n; ++i) { + z[i] = x[i] * y[i]; + } +} + +} // namespace refer +} // namespace jitkernels +} // namespace operators +} // namespace paddle diff --git a/paddle/fluid/operators/jitkernels/registry.h b/paddle/fluid/operators/jitkernels/registry.h new file mode 100644 index 0000000000..1d2d47a804 --- /dev/null +++ b/paddle/fluid/operators/jitkernels/registry.h @@ -0,0 +1,134 @@ +/* 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. */ + +#pragma once + +#include +#include +#include +#include "paddle/fluid/operators/jitkernels/kernel_base.h" +#include "paddle/fluid/operators/jitkernels/kernels.h" +#include "paddle/fluid/platform/place.h" + +namespace paddle { +namespace operators { +namespace jitkernels { + +// make_unique is supported from c++14 +template +inline std::unique_ptr make_unique(Args&&... args) { + static_assert(!std::is_array::value, "T must not be array"); + return std::unique_ptr(new T(std::forward(args)...)); +} + +template +struct JitKernelRegistrarFunctor; + +template +struct JitKernelRegistrarFunctor { + void operator()(KernelType kt) const {} +}; + +template +struct JitKernelRegistrarFunctor { + using KERNEL_IMPL_TYPE = + typename std::tuple_element>::type; + + void operator()(KernelType kt) const { + KernelKey kkey(kt, PlaceType()); + KernelPool().Instance().Insert( + kkey, std::move(make_unique())); + constexpr auto size = std::tuple_size>::value; + JitKernelRegistrarFunctor + func; + func(kt); + } +}; + +template +class JitKernelRegistrar { + public: + explicit JitKernelRegistrar(KernelType kt) { + JitKernelRegistrarFunctor func; + func(kt); + } +}; + +#define STATIC_ASSERT_JITKERNEL_GLOBAL_NAMESPACE(uniq_name, msg) \ + struct __test_global_namespace_##uniq_name##__ {}; \ + static_assert(std::is_same<::__test_global_namespace_##uniq_name##__, \ + __test_global_namespace_##uniq_name##__>::value, \ + msg) + +// kernel_type: should be in paddle::operators::jitkernels::KernelType +// place_type: should be one of CPUPlace and GPUPlace in paddle::platform +#define REGISTER_KERNEL_MORE(kernel_type, impl_type, place_type, ...) \ + STATIC_ASSERT_JITKERNEL_GLOBAL_NAMESPACE( \ + __reg_jitkernel_##kernel_type##_##impl_type##_##place_type, \ + "REGISTER_KERNEL_MORE must be called in global namespace"); \ + static ::paddle::operators::jitkernels::JitKernelRegistrar< \ + ::paddle::platform::place_type, __VA_ARGS__> \ + __jit_kernel_registrar_##kernel_type##_##impl_type##_##place_type##__( \ + ::paddle::operators::jitkernels::KernelType::kernel_type) +// TODO(TJ): Add Touch and use me + +#define REGISTER_JITKERNEL_MORE(kernel_type, impl_type, ...) \ + REGISTER_KERNEL_MORE(kernel_type, impl_type, CPUPlace, __VA_ARGS__) + +#define REGISTER_GPUKERNEL_MORE(kernel_type, impl_type, ...) \ + REGISTER_KERNEL_MORE(kernel_type, impl_type, GPUPlace, __VA_ARGS__) + +/* +REGISTER_JITKERNEL_JITCODE(vmul, JitKernelCode); + +// refer must be only one and at least one +REGISTER_JITKERNEL_REFER(vmul, VMul); // Refer need support dtype + +// you can register more implementations and the condition when use it +REGISTER_JITKERNEL_MORE(vmul, mkl::VMUL, UseMe, mkl::VMUL, + UseMe) + +#define STATIC_ASSERT_PASS_GLOBAL_NAMESPACE(uniq_name, msg) \ + struct __test_global_namespace_##uniq_name##__ {}; \ + static_assert(std::is_same<::__test_global_namespace_##uniq_name##__, \ + __test_global_namespace_##uniq_name##__>::value, \ + msg) + +// Register a new pass that can be applied on the IR. +#define REGISTER_PASS(pass_type, pass_class) \ + STATIC_ASSERT_PASS_GLOBAL_NAMESPACE( \ + __reg_pass__##pass_type, \ + "REGISTER_PASS must be called in global namespace"); \ + static ::paddle::framework::ir::PassRegistrar \ + __pass_registrar_##pass_type##__(#pass_type); \ + int TouchPassRegistrar_##pass_type() { \ + __pass_registrar_##pass_type##__.Touch(); \ + return 0; \ + } \ + static ::paddle::framework::ir::PassRegistrar& \ + __pass_tmp_registrar_##pass_type##__ UNUSED = \ + __pass_registrar_##pass_type##__ + +#define USE_PASS(pass_type) \ + STATIC_ASSERT_PASS_GLOBAL_NAMESPACE( \ + __use_pass_itself_##pass_type, \ + "USE_PASS must be called in global namespace"); \ + extern int TouchPassRegistrar_##pass_type(); \ + static int use_pass_itself_##pass_type##_ UNUSED = \ + TouchPassRegistrar_##pass_type() +*/ + +} // namespace jitkernels +} // namespace operators +} // namespace paddle diff --git a/paddle/fluid/operators/jitkernels/test.cc b/paddle/fluid/operators/jitkernels/test.cc new file mode 100644 index 0000000000..86c6669173 --- /dev/null +++ b/paddle/fluid/operators/jitkernels/test.cc @@ -0,0 +1,36 @@ +/* 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 // for memcpy +#include +#include +#include +#include "gflags/gflags.h" +#include "glog/logging.h" +#include "gtest/gtest.h" +#include "paddle/fluid/operators/math/jit_kernel.h" +#include "paddle/fluid/operators/math/jit_kernel_refer.h" +#include "paddle/fluid/platform/port.h" + +constexpr int repeat = 20000; + +inline double GetCurrentUS() { + struct timeval time; + gettimeofday(&time, NULL); + return 1e+6 * time.tv_sec + time.tv_usec; +} + +TEST(JitKernel, vmul) {} + +TEST(JitKernel, pool) {} diff --git a/paddle/fluid/operators/math/CMakeLists.txt b/paddle/fluid/operators/math/CMakeLists.txt index 63363086ad..db91628d94 100644 --- a/paddle/fluid/operators/math/CMakeLists.txt +++ b/paddle/fluid/operators/math/CMakeLists.txt @@ -73,11 +73,11 @@ endif() cc_test(concat_test SRCS concat_test.cc DEPS concat_and_split) cc_test(cpu_vec_test SRCS cpu_vec_test.cc DEPS blas cpu_info) -set(JIT_KERNEL_SRCS jit_kernel.cc jit_kernel_blas.cc jit_kernel_exp.cc jit_kernel_rnn.cc jit_kernel_crf_decode.cc jit_kernel_layer_norm.cc) -set(JIT_KERNEL_DEPS cpu_info cblas gflags enforce) -if(WITH_XBYAK) - list(APPEND JIT_KERNEL_SRCS jit_gen.cc jit_code.cc) - list(APPEND JIT_KERNEL_DEPS xbyak) -endif() -cc_library(jit_kernel SRCS ${JIT_KERNEL_SRCS} DEPS ${JIT_KERNEL_DEPS}) -cc_test(jit_kernel_test SRCS jit_kernel_test.cc DEPS jit_kernel) +# set(JIT_KERNEL_SRCS jit_kernel.cc jit_kernel_blas.cc jit_kernel_exp.cc jit_kernel_rnn.cc jit_kernel_crf_decode.cc jit_kernel_layer_norm.cc) +# set(JIT_KERNEL_DEPS cpu_info cblas gflags enforce) +# if(WITH_XBYAK) +# list(APPEND JIT_KERNEL_SRCS jit_gen.cc jit_code.cc) +# list(APPEND JIT_KERNEL_DEPS xbyak) +# endif() +# cc_library(jit_kernel SRCS ${JIT_KERNEL_SRCS} DEPS ${JIT_KERNEL_DEPS}) +# cc_test(jit_kernel_test SRCS jit_kernel_test.cc DEPS jit_kernel) diff --git a/paddle/fluid/platform/cpu_info.h b/paddle/fluid/platform/cpu_info.h index fd31ef77b4..663a9fbf4e 100644 --- a/paddle/fluid/platform/cpu_info.h +++ b/paddle/fluid/platform/cpu_info.h @@ -39,7 +39,7 @@ size_t CUDAPinnedMinChunkSize(); //! Get the maximum chunk size for buddy allocator. size_t CUDAPinnedMaxChunkSize(); -namespace jit { +namespace jit { // remove this namespace typedef enum { isa_any, sse42, -- GitLab