Skip to content

Commit

Permalink
The definition of compiler (PaddlePaddle#28)
Browse files Browse the repository at this point in the history
* the definition of compiler

* remove gpu compiler

* fix cmake

* add annotation

* using kernel executor replace sschedule wrapper

* update kernel executor

* Aadd annotation

* fix review

* update kernel executable

* Using const note::Module& replace note::Module*

* fix review

* fix review

* add todo

* add annotation

* using const note::Module*
  • Loading branch information
SunNy820828449 authored Aug 20, 2021
1 parent 1755450 commit 325faf4
Show file tree
Hide file tree
Showing 13 changed files with 359 additions and 31 deletions.
47 changes: 47 additions & 0 deletions paddle/fluid/compiler/piano/backends/compiler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (c) 2021 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/compiler/piano/backends/kernel_executable.h"

namespace paddle {
namespace piano {

namespace note {
class Module;
}

namespace backends {

// Compiler is an abstract class for compilation on a particular platform.
//
// Compiler ties together note::instruction and codegen (CG) to generate
// efficient binary code for the target platform.
//
// XXCompiler class for a particular device inherit Compiler and
// overwrite the function Apply.

class Compiler {
public:
Compiler() = default;
virtual ~Compiler() {}

// Compiler will optimize the note::Module with pass and the note::Module will
// be updated.
virtual KernelExecutableMap Apply(note::Module*) = 0;
};

} // namespace backends
} // namespace piano
} // namespace paddle
99 changes: 99 additions & 0 deletions paddle/fluid/compiler/piano/backends/kernel_executable.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright (c) 2021 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 <memory>
#include <string>
#include <unordered_map>
#include "paddle/fluid/compiler/piano/note/instruction.h"
#include "paddle/fluid/compiler/piano/note/opcode.h"

namespace paddle {
namespace piano {
namespace backends {

// kernel type.
enum class KernelType : std::uint32_t {
kBatchNormGradKernel = 0,
kBatchNormInferenceKernel,
kBatchNormTrainingKernel,
kConvolutionKernel,
kDotKernel,
kJitKernel,
};

// executable context for KernelExecutable.
struct ExecutableContext {};

// KernelExecutable is a kernel execution class, it includes kernel information.
// Each KernelType need define a derived class which inherit KernelExecutable
// and overwrite the virtual function Run.
// By call function Run in KernelExecutor to execute the binary code.

class KernelExecutable {
public:
explicit KernelExecutable(const note::Instruction& note_instruction) {
Reset(note_instruction);
}
virtual ~KernelExecutable();
virtual void Run(const ExecutableContext&) = 0;

public:
void Reset(const note::Instruction& note_instruction) {
kernel_name_ = note_instruction.name();
// initialize KernelType
switch (note_instruction.opcode()) {
case note::OpCode::kBatchNormGrad:
kernel_type_ = KernelType::kBatchNormGradKernel;
break;
case note::OpCode::kBatchNormInference:
kernel_type_ = KernelType::kBatchNormInferenceKernel;
break;
case note::OpCode::kBatchNormTraining:
kernel_type_ = KernelType::kBatchNormTrainingKernel;
break;
case note::OpCode::kConvolution:
kernel_type_ = KernelType::kConvolutionKernel;
break;
case note::OpCode::kDot:
kernel_type_ = KernelType::kDotKernel;
break;
default:
kernel_type_ = KernelType::kJitKernel;
break;
}

// get op input global_id and name
for (auto operand : note_instruction.operands()) {
input_names_.emplace_back(operand->name());
}
}

KernelType GetKernelType() const { return kernel_type_; }
std::string GetKernelName() const { return kernel_name_; }
const std::vector<std::string>& GetInputNames() const { return input_names_; }

protected:
KernelType kernel_type_;
std::string kernel_name_;
std::vector<std::string> input_names_;
};

// KernelExecutableMap is a map of KernelExecutable.
using KernelExecutableMap =
std::unordered_map<std::string, std::unique_ptr<KernelExecutable>>;

} // namespace backends
} // namespace piano
} // namespace paddle
7 changes: 7 additions & 0 deletions paddle/fluid/compiler/piano/backends/llvm_ir/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,10 @@ cc_library(nvptx_ir_emitter SRCS nvptx_ir_emitter.cc DEPS llvm)
cc_test(nvptx_ir_emitter_test SRCS nvptx_ir_emitter_test.cc
DEPS nvptx_ir_emitter gpu_ir_emitter ir_emitter)
target_link_libraries(nvptx_ir_emitter_test ${LLVM_LIBS})

cc_library(llvm_compiler SRCS llvm_compiler.cc DEPS llvm)
cc_library(nvtpx_compiler SRCS nvptx_compiler.cc DEPS llvm)

cc_test(nvptx_compiler_test SRCS nvptx_compiler_test.cc
DEPS nvtpx_compiler llvm_compiler)
target_link_libraries(nvptx_compiler_test ${LLVM_LIBS})
7 changes: 4 additions & 3 deletions paddle/fluid/compiler/piano/backends/llvm_ir/gpu_ir_emitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ namespace backends {

// GpuIrEmitter is for translating note::Instruction to llvm IR
// for GPU.
// It implement the visit function for note::Instruction's translation
// It implement the visit function for note::Instruction's translation.

class GpuIrEmitter : public IrEmitter {
public:
GpuIrEmitter() = delete;
explicit GpuIrEmitter(llvm::Module* llvm_module, Schedules* schedule)
: IrEmitter(llvm_module, schedule) {}
explicit GpuIrEmitter(llvm::Module* llvm_module,
KernelExecutableMap* kernel_executable_map)
: IrEmitter(llvm_module, kernel_executable_map) {}
virtual ~GpuIrEmitter() {}

void VisitElementwiseUnary(const note::Instruction&) override;
Expand Down
33 changes: 19 additions & 14 deletions paddle/fluid/compiler/piano/backends/llvm_ir/ir_emitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,37 @@
#pragma once

#include "llvm/IR/Module.h"
#include "paddle/fluid/compiler/piano/backends/kernel_executable.h"
#include "paddle/fluid/compiler/piano/backends/note_visitor_base.h"
#include "paddle/fluid/compiler/piano/backends/schedule_wrapper.h"

namespace paddle {
namespace piano {
namespace backends {

// IrEmitter is an Abstract base class for translating note::Instruction to llvm
// IR.
// To translating note::Instruction to llvm IR for special device, it should
// inherit from IrEmitter and overwrite the virtual function.
// note::Instruction has different type {Scalar Op, Api Op, Unary Op, Binary Op,
// Others}
// Elementwise-Unary Op and Elementwise-Binary Op should be implemented
// in VisitElementwiseUnary and VisitElementwiseBinary.
// IrEmitter is an abstract base class for generatting LLVM IR of each
// note::Instruction
// For a special hardware, a XXXIrEmitter should be implemented inheriting from
// IrEmitter and overwrites all the virtual functions.
// llvm::Module* -> contain kernel llvm IR
// KernelExecutableMap -> a map of KernelExecutable
// XXXIrEmitter get a llvm::Module* and KernelExecutors* from XXXCompiler when
// initialize.
// note::Instruction accept a IrEmitter and choose VisitXXX by note::OpCode
// Each time VisitXXX will translate one note::Instruction with type OpCode::XXX
// into a kernel with llvm IR.

class IrEmitter : public NoteVisitorBase {
public:
IrEmitter() = delete;
explicit IrEmitter(llvm::Module* llvm_module, Schedules* schedule)
: llvm_module_(llvm_module), schedules_(schedule) {}
explicit IrEmitter(llvm::Module* llvm_module,
KernelExecutableMap* kernel_executable_map)
: llvm_module_(llvm_module),
kernel_executable_map_(kernel_executable_map) {}
virtual ~IrEmitter() {}

// ElementwiseUnary Operator
// Elementwise-Unary implemented in VisitElementwiseUnary
virtual void VisitElementwiseUnary(const note::Instruction&) = 0;
// ElementwiseBinary Operator
// Elementwise-Unary implemented in VisitElementwiseBinary
virtual void VisitElementwiseBinary(const note::Instruction&) = 0;

// Scalar op
Expand Down Expand Up @@ -91,7 +96,7 @@ class IrEmitter : public NoteVisitorBase {

protected:
llvm::Module* llvm_module_{nullptr};
Schedules* schedules_{nullptr};
KernelExecutableMap* kernel_executable_map_{nullptr};
};

} // namespace backends
Expand Down
48 changes: 48 additions & 0 deletions paddle/fluid/compiler/piano/backends/llvm_ir/llvm_compiler.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) 2021 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/compiler/piano/backends/llvm_ir/llvm_compiler.h"

namespace paddle {
namespace piano {
namespace backends {

KernelExecutableMap LlvmCompiler::Apply(note::Module* note_module) {
// using pass optimize the note module
Optimize(note_module);

// create llvm module
llvm::LLVMContext context;
// TODO(sunli) : set llvm_module name.
llvm::Module llvm_module("", context);

// create kernel executor
KernelExecutableMap kernel_executable_map;

// conver operator to llvm ir
ConvertToIr(*note_module, &llvm_module, &kernel_executable_map);

// compiler llvm ir to lowring ir
Compile(&llvm_module, &kernel_executable_map);

return kernel_executable_map;
}

void LlvmCompiler::ConvertToIr(const note::Module& note_module,
llvm::Module* llvm_module,
KernelExecutableMap* kernel_executable_map) {}

} // namespace backends
} // namespace piano
} // namespace paddle
51 changes: 51 additions & 0 deletions paddle/fluid/compiler/piano/backends/llvm_ir/llvm_compiler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) 2021 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 "llvm/IR/Module.h"
#include "paddle/fluid/compiler/piano/backends/compiler.h"

namespace paddle {
namespace piano {
namespace backends {

// LlvmCompiler is an abstract compiler class that inherit Compiler with
// llvm ir as low level IR.
// For a particular device compiler with llvm ir should inherit the LlvmCompiler
// and overwrite the function 'Optimize' and 'Compile'.

class LlvmCompiler : public Compiler {
public:
LlvmCompiler() = default;
virtual ~LlvmCompiler() {}

KernelExecutableMap Apply(note::Module*) override;

protected:
// use pass to optimize the note::Module, such as dce、fusion、rewriter.
virtual void Optimize(note::Module*) = 0;

// convert each note::Instruction in note::Module to llvm ir and get execution
// args.
void ConvertToIr(const note::Module&, llvm::Module*, KernelExecutableMap*);

// use llvm ir pass to optimize the llvm::Module and comile llvm::module to
// executable binary code on tareget device.
virtual void Compile(llvm::Module*, KernelExecutableMap*) = 0;
};

} // namespace backends
} // namespace piano
} // namespace paddle
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,17 @@
// 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 <memory>
#include <vector>
#include "paddle/fluid/compiler/piano/backends/llvm_ir/nvptx_compiler.h"
#include "llvm/Support/TargetSelect.h"

namespace paddle {
namespace piano {
namespace backends {

class ScheduleWrapper {
public:
protected:
};

using Schedules = std::vector<std::unique_ptr<ScheduleWrapper>>;
void NvptxCompiler::Optimize(note::Module* note_module) {}
void NvptxCompiler::Compile(llvm::Module* llvm_module,
KernelExecutableMap* kernel_executable_map) {}

} // namespace backends
} // namespace piano
Expand Down
Loading

0 comments on commit 325faf4

Please sign in to comment.