Skip to content

Commit 488803e

Browse files
committed
Added compileWithoutConstants to backend and updated OpenCL, CPU, and Interpreter Backends. This will allow for compilation of the function and collection of the constants to be seperated which is needed for the new Runtime design
Added unittest for compileWithoutConstants
1 parent 42ac5d4 commit 488803e

17 files changed

+125
-8
lines changed

include/glow/Backends/Backend.h

+4
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ class Backend {
4343
/// Generate code for input function \param F.
4444
virtual std::unique_ptr<CompiledFunction> compile(Function *F) const = 0;
4545

46+
/// Generate code for input function \param F but do not collect constants.
47+
virtual std::unique_ptr<CompiledFunction>
48+
compileWithoutConstants(Function *F) const = 0;
49+
4650
/// Save the bundle for \p F for a later standalone execution
4751
/// in \p outputDir. Make \p networkName the function name for
4852
/// the entry point of the network and prepend all generated

include/glow/Backends/BackendUtils.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class RuntimeBundle {
5454
size_t getActivationsSize() const { return activationsMemSize_; }
5555
/// Get pointer to memory block of constants.
5656
uint8_t *getConstants() const { return constants_; }
57+
/// Set pointer to memory block of constants.
58+
void setConstants(uint8_t *constants) { constants_ = constants; }
5759
/// Helper function, gets offset of \p v.
5860
size_t getValueOffset(const Named *v) const;
5961
/// Helper function, gets symbol info for \p v.
@@ -67,7 +69,7 @@ class RuntimeBundle {
6769
RuntimeBundle() = default;
6870
RuntimeBundle(std::unordered_map<std::string, RuntimeSymbolInfo> &symbolTable,
6971
size_t constWeight, size_t mutableWeight, size_t activations)
70-
: symbolTable_(std::move(symbolTable)),
72+
: symbolTable_(std::move(symbolTable)), constants_(nullptr),
7173
constantWeightVarsMemSize_(constWeight),
7274
mutableWeightVarsMemSize_(mutableWeight),
7375
activationsMemSize_(activations) {}

lib/Backends/BackendUtils.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,6 @@ glow::generateRuntimeBundle(const IRFunction &F,
141141
}
142142
auto activationsMaxSize = activationsAllocator.getMaxMemoryUsage();
143143

144-
runtime::RuntimeBundle info(symbolTable, constantMaxSize, placeholderMaxSize,
145-
activationsMaxSize);
146-
info.collectConstants(&F);
147-
return info;
144+
return runtime::RuntimeBundle(symbolTable, constantMaxSize,
145+
placeholderMaxSize, activationsMaxSize);
148146
}

lib/Backends/CPU/CPUBackend.cpp

+15-2
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,21 @@ CPUBackend::createIRGen(IRFunction *IR,
9999

100100
std::unique_ptr<CompiledFunction>
101101
CPUBackend::compileIR(std::unique_ptr<IRFunction> IR) const {
102+
auto function = compileIRWithoutConstants(IR.get());
103+
static_cast<CPUFunction *>(function.get())->collectConstants(IR.get());
104+
return function;
105+
}
106+
107+
std::unique_ptr<CompiledFunction>
108+
CPUBackend::compileIRWithoutConstants(IRFunction *IR) const {
102109
AllocationsInfo allocationsInfo;
103-
std::unique_ptr<LLVMIRGen> irgen = createIRGen(IR.get(), allocationsInfo);
110+
std::unique_ptr<LLVMIRGen> irgen = createIRGen(IR, allocationsInfo);
104111
irgen->initTargetMachine(target.empty() ? "" : target.getValue(),
105112
llvm::CodeModel::Model::Large);
106113
irgen->initCodeGen();
107114
// Perform the address assignment for activations and WeightVars.
108115

109-
allocateJITMemory(IR.get(), irgen->getAllocationsInfo());
116+
allocateJITMemory(IR, irgen->getAllocationsInfo());
110117
// Create the jitmain function to be invoked by JIT.
111118
emitJitMain(*irgen);
112119
// Emit the code for the body of the entry function.
@@ -128,6 +135,12 @@ std::unique_ptr<CompiledFunction> CPUBackend::compile(Function *F) const {
128135
return compileIR(std::move(IR));
129136
}
130137

138+
std::unique_ptr<CompiledFunction>
139+
CPUBackend::compileWithoutConstants(Function *F) const {
140+
auto IR = generateAndOptimizeIR(F, shouldShareBuffers());
141+
return compileIRWithoutConstants(IR.get());
142+
}
143+
131144
void CPUBackend::save(Function *F, llvm::StringRef outputDir,
132145
llvm::StringRef networkName) const {
133146
std::string tgt = target.empty() ? "" : target.getValue();

lib/Backends/CPU/CPUBackend.h

+6
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,14 @@ class CPUBackend : public BackendUsingGlowIR {
4545
std::unique_ptr<CompiledFunction>
4646
compileIR(std::unique_ptr<IRFunction> IR) const override;
4747

48+
std::unique_ptr<CompiledFunction>
49+
compileIRWithoutConstants(IRFunction *IR) const;
50+
4851
std::unique_ptr<CompiledFunction> compile(Function *F) const override;
4952

53+
std::unique_ptr<CompiledFunction>
54+
compileWithoutConstants(Function *F) const override;
55+
5056
void save(Function *F, llvm::StringRef outputDir,
5157
llvm::StringRef networkName) const override;
5258

lib/Backends/CPU/CPUFunction.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ void CPUFunction::setupRuns() {
4545
}
4646
}
4747

48+
void CPUFunction::collectConstants(IRFunction *F) {
49+
runtimeBundle_.collectConstants(F);
50+
}
51+
4852
void CPUFunction::beforeRun(const Context &ctx) {
4953
// Copy Placeholders into allocated memory.
5054
for (auto PH : ctx.pairs()) {

lib/Backends/CPU/CPUFunction.h

+4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ class CPUFunction final : public CompiledFunction {
3838
/// Ctor.
3939
CPUFunction(std::unique_ptr<llvm::orc::GlowJIT> JIT,
4040
const runtime::RuntimeBundle &runtimeBundle);
41+
42+
/// Collects constants for runtime.
43+
void collectConstants(IRFunction *F);
44+
4145
/// Allocate Mutable buffers on device this includes Activations and
4246
/// Placeholders.
4347
void setupRuns() override;

lib/Backends/Interpreter/Interpreter.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,22 @@ std::unique_ptr<CompiledFunction> Interpreter::compile(Function *F) const {
2929
return compileIR(std::move(IR));
3030
}
3131

32+
std::unique_ptr<CompiledFunction>
33+
Interpreter::compileWithoutConstants(Function *F) const {
34+
auto IR = generateAndOptimizeIR(F, shouldShareBuffers());
35+
return compileIRWithoutConstants(std::move(IR));
36+
}
37+
3238
std::unique_ptr<CompiledFunction>
3339
Interpreter::compileIR(std::unique_ptr<IRFunction> IR) const {
40+
auto function = compileIRWithoutConstants(std::move(IR));
41+
auto IFunction = static_cast<InterpreterFunction *>(function.get());
42+
IFunction->collectConstants(IFunction->getIR());
43+
return function;
44+
}
45+
46+
std::unique_ptr<CompiledFunction>
47+
Interpreter::compileIRWithoutConstants(std::unique_ptr<IRFunction> IR) const {
3448
MemoryAllocator constantWeightsAllocator("ConstantWeights", 0);
3549
MemoryAllocator placeholderWeightsAllocator("PlaceholderWeights", 0);
3650
MemoryAllocator activationsAllocator("Activations", 0);

lib/Backends/Interpreter/Interpreter.h

+6
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,14 @@ class Interpreter final : public BackendUsingGlowIR {
3737
std::unique_ptr<CompiledFunction>
3838
compileIR(std::unique_ptr<IRFunction> IR) const override;
3939

40+
std::unique_ptr<CompiledFunction>
41+
compileIRWithoutConstants(std::unique_ptr<IRFunction> IR) const;
42+
4043
std::unique_ptr<CompiledFunction> compile(Function *F) const override;
4144

45+
std::unique_ptr<CompiledFunction>
46+
compileWithoutConstants(Function *F) const override;
47+
4248
bool isOpSupported(Kinded::Kind opKind, ElemKind elementTy) const override;
4349

4450
bool shouldLower(const Node *N) const override;

lib/Backends/Interpreter/InterpreterFunction.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ InterpreterFunction::~InterpreterFunction() {
3939
tearDownRuns();
4040
}
4141

42+
void InterpreterFunction::collectConstants(IRFunction *F) {
43+
runtimeBundle_.collectConstants(F);
44+
}
45+
4246
void InterpreterFunction::setupRuns() {
4347
if (!runsSetup_) {
4448
if (runtimeBundle_.getConstantWeightSize()) {

lib/Backends/Interpreter/InterpreterFunction.h

+6
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ class InterpreterFunction final : public CompiledFunction {
6262

6363
/// Does any needed initialization work for the Backend, creates tensors from
6464
/// constants.
65+
66+
/// Collects constants for runtime.
67+
void collectConstants(IRFunction *F);
68+
6569
void setupRuns() override;
6670

6771
/// Per run setup, adds references for tensors from \p ctx to
@@ -76,6 +80,8 @@ class InterpreterFunction final : public CompiledFunction {
7680
void tearDownRuns() override;
7781

7882
void execute() override;
83+
/// Get reference to IR function.
84+
IRFunction *getIR() { return F_.get(); }
7985
///@}
8086

8187
private:

lib/Backends/OpenCL/OpenCL.cpp

+17-1
Original file line numberDiff line numberDiff line change
@@ -1525,15 +1525,31 @@ cl_mem OpenCLFunction::allocDeviceBuffer(uint64_t size) {
15251525

15261526
void OpenCLFunction::freeDeviceBuffer(cl_mem buf) { clReleaseMemObject(buf); }
15271527

1528+
void OpenCLFunction::collectConstants(IRFunction *F) {
1529+
runtimeBundle_.collectConstants(F);
1530+
}
15281531
std::unique_ptr<CompiledFunction>
15291532
OCLBackend::compileIR(std::unique_ptr<IRFunction> IR) const {
1533+
auto function = compileIRWithoutConstants(std::move(IR));
1534+
auto OCLFunction = static_cast<OpenCLFunction *>(function.get());
1535+
OCLFunction->collectConstants(OCLFunction->getIR());
1536+
return function;
1537+
}
1538+
1539+
std::unique_ptr<CompiledFunction>
1540+
OCLBackend::compileIRWithoutConstants(std::unique_ptr<IRFunction> IR) const {
15301541
MemoryAllocator allocator("GPU", 0xFFFFFFFF);
15311542
runtime::RuntimeBundle bundle =
15321543
generateRuntimeBundle(*IR, allocator, allocator, allocator);
15331544
return llvm::make_unique<OpenCLFunction>(std::move(IR), bundle);
15341545
}
1535-
15361546
std::unique_ptr<CompiledFunction> OCLBackend::compile(Function *F) const {
15371547
auto IR = generateAndOptimizeIR(F, shouldShareBuffers());
15381548
return compileIR(std::move(IR));
15391549
}
1550+
1551+
std::unique_ptr<CompiledFunction>
1552+
OCLBackend::compileWithoutConstants(Function *F) const {
1553+
auto IR = generateAndOptimizeIR(F, shouldShareBuffers());
1554+
return compileIRWithoutConstants(std::move(IR));
1555+
}

lib/Backends/OpenCL/OpenCL.h

+10
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,12 @@ class OpenCLFunction final : public CompiledFunction {
107107
/// Final cleanup, currently an empty function in OpenCL.
108108
void tearDownRuns() override;
109109

110+
/// Returns IR function pointer.
111+
IRFunction *getIR() { return F_.get(); }
112+
113+
/// Collects constants for runtime.
114+
void collectConstants(IRFunction *F);
115+
110116
private:
111117
/// Copy the value from a device to a provided buffer.
112118
/// \returns number of copied bytes.
@@ -161,8 +167,12 @@ class OCLBackend final : public BackendUsingGlowIR {
161167

162168
std::unique_ptr<CompiledFunction>
163169
compileIR(std::unique_ptr<IRFunction> IR) const override;
170+
std::unique_ptr<CompiledFunction>
171+
compileIRWithoutConstants(std::unique_ptr<IRFunction> IR) const;
164172

165173
std::unique_ptr<CompiledFunction> compile(Function *F) const override;
174+
std::unique_ptr<CompiledFunction>
175+
compileWithoutConstants(Function *F) const override;
166176

167177
bool transformPostLowering(Function *F, CompilationMode mode) const override;
168178

tests/unittests/BackendCorrectnessTest.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,11 @@ class MockCPUBackend : public BackendUsingGlowIR {
239239
std::unique_ptr<CompiledFunction> compile(Function *F) const override {
240240
return backend_->compile(F);
241241
}
242+
243+
std::unique_ptr<CompiledFunction>
244+
compileWithoutConstants(Function *F) const override {
245+
return backend_->compile(F);
246+
}
242247
std::unique_ptr<CompiledFunction>
243248
compileIR(std::unique_ptr<IRFunction> IR) const override {
244249
return backend_->compileIR(std::move(IR));

tests/unittests/BackendTest.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,22 @@ TEST_P(BackendTest, debugPrint) {
168168
function->tearDownRuns();
169169
}
170170

171+
/// Test the compileWithoutConstants method on the backend completes without
172+
/// error.
173+
TEST_P(BackendTest, CompileWithoutConstants) {
174+
Module mod;
175+
Context ctx;
176+
Function *F = mod.createFunction("main");
177+
auto *X = mod.createPlaceholder(ElemKind::FloatTy, {3}, "X", false);
178+
auto *XTensor = ctx.allocate(X);
179+
XTensor->getHandle() = {1., 2., 3.};
180+
auto *pow = F->createPow("Pow1", X, 2.0);
181+
auto *save = F->createSave("save", pow);
182+
ctx.allocate(save->getPlaceholder());
183+
std::unique_ptr<Backend> backend(createBackend(GetParam()));
184+
auto function = backend->compileWithoutConstants(F);
185+
}
186+
171187
/// This test checks that we can compile a function without depending on the
172188
/// graph representation. We compile some function and then delete the function.
173189
/// Later we execute the code and check that things work.

tests/unittests/BackendTestUtils.h

+4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ class MockBackend : public Backend {
3232
std::unique_ptr<CompiledFunction> compile(Function *F) const override {
3333
return llvm::make_unique<MockFunction>();
3434
}
35+
std::unique_ptr<CompiledFunction>
36+
compileWithoutConstants(Function *F) const override {
37+
return llvm::make_unique<MockFunction>();
38+
}
3539
bool isOpSupported(Kinded::Kind opKind, ElemKind elementTy) const override {
3640
return false;
3741
}

tests/unittests/QuantizationTest.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,11 @@ class MockQuantBackend : public Backend {
837837
std::unique_ptr<CompiledFunction> compile(Function *F) const override {
838838
return backend_->compile(F);
839839
}
840+
841+
std::unique_ptr<CompiledFunction>
842+
compileWithoutConstants(Function *F) const override {
843+
return backend_->compile(F);
844+
}
840845
bool isOpSupported(Kinded::Kind opKind, ElemKind elementTy) const override {
841846
if (opKind == Kinded::Kind::SoftMaxNodeKind ||
842847
opKind == Kinded::Kind::LocalResponseNormalizationNodeKind) {

0 commit comments

Comments
 (0)