Skip to content

Commit 6930c0d

Browse files
ZihengJiangYuchenJin
authored andcommitted
Relax Virtual Machine
Co-Authored-By: Yuchen Jin <yuchenj@cs.washington.edu>
1 parent f6a7dc2 commit 6930c0d

File tree

20 files changed

+2575
-3
lines changed

20 files changed

+2575
-3
lines changed

.github/workflows/main.yml

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
118
# GH actions.
219
# We use it to cover windows and mac builds
320
# Jenkins is still the primary CI
@@ -62,8 +79,7 @@ jobs:
6279
python -m pytest -v tests/python/contrib/test_rpc_server_device.py
6380
6481
Windows:
65-
if: ${{ github.repository == 'apache/tvm' }}
66-
runs-on: windows-2019
82+
runs-on: windows-2016
6783
steps:
6884
- uses: actions/checkout@v2
6985
with:
@@ -147,4 +163,4 @@ jobs:
147163
uses: actions/upload-artifact@v2
148164
with:
149165
name: android_camera-debug.apk
150-
path: ./apps/android_camera/app/build/outputs/apk/debug/app-debug.apk
166+
path: ./apps/android_camera/app/build/outputs/apk/debug/app-debug.apk

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ tvm_file_glob(GLOB_RECURSE COMPILER_SRCS
283283
src/printer/*.cc
284284
src/support/*.cc
285285
src/script/*.cc
286+
src/relax/*.cc
286287
)
287288

288289
tvm_file_glob(GLOB CODEGEN_SRCS

include/tvm/relax/builder.h

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
/*!
21+
* \file tvm/relax/builder.h
22+
* \brief
23+
*/
24+
#ifndef TVM_RELAX_BUILDER_H_
25+
#define TVM_RELAX_BUILDER_H_
26+
27+
#include <tvm/ir/expr.h>
28+
#include <tvm/node/reflection.h>
29+
#include <tvm/node/repr_printer.h>
30+
#include <tvm/runtime/object.h>
31+
#include <tvm/runtime/registry.h>
32+
33+
#include "./vm/bytecode.h"
34+
#include "./vm/executable.h"
35+
36+
namespace tvm {
37+
namespace relax {
38+
39+
namespace vm = tvm::runtime::relax_vm;
40+
41+
class ExecBuilder;
42+
43+
/*!
44+
* \brief A builder provides api to build VM executable with instructions.
45+
*/
46+
class ExecBuilderNode : public Object {
47+
public:
48+
/*! \brief The mutable internal executable node. */
49+
ObjectPtr<vm::ExecutableNode> exec; // mutable
50+
/*!
51+
* \brief To annotate the start of a vm function.
52+
* \param func The function name.
53+
* \param num_inputs The number of inputs.
54+
*/
55+
void Function(std::string func, int64_t num_inputs);
56+
/*!
57+
* \brief Emit a call instruction for a packed function.
58+
* \param func The packed function name.
59+
* \param args The arguments of the function.
60+
* \param ret The return register.
61+
*/
62+
void EmitCall(std::string func, std::vector<vm::Instruction::Arg> args, vm::RegName ret);
63+
/*!
64+
* \brief Emit a ret instruction.
65+
* \param result The return result.
66+
*/
67+
void EmitRet(vm::RegName result);
68+
/*!
69+
* \brief Emit a constant value to the constant pool.
70+
* \return The index that represents the constant.
71+
*/
72+
vm::Index EmitConstant(ObjectRef obj);
73+
/*!
74+
* \brief Get the built executable.
75+
* \return The built executable.
76+
*/
77+
vm::Executable Get();
78+
/*!
79+
* \brief Create a ExecBuilder.
80+
* \return The ExecBuilder.
81+
*/
82+
TVM_DLL static ExecBuilder Create();
83+
84+
void VisitAttrs(AttrVisitor* v) {}
85+
86+
static constexpr const uint32_t _type_index = TypeIndex::kDynamic;
87+
static constexpr const char* _type_key = "relax.ExecBuilder";
88+
TVM_DECLARE_FINAL_OBJECT_INFO(ExecBuilderNode, Object);
89+
90+
private:
91+
/*!
92+
* \brief Formalize the executable.
93+
*/
94+
void Formalize();
95+
};
96+
97+
class ExecBuilder : public ObjectRef {
98+
public:
99+
TVM_DEFINE_MUTABLE_OBJECT_REF_METHODS(ExecBuilder, ObjectRef, ExecBuilderNode);
100+
};
101+
102+
} // namespace relax
103+
} // namespace tvm
104+
105+
#endif // TVM_RELAX_BUILDER_H_

include/tvm/relax/vm/bytecode.h

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
/*!
21+
* \file tvm/relax/vm/bytecode.h
22+
* \brief The bytecode for the virtual machine.
23+
*/
24+
#ifndef TVM_RELAX_VM_BYTECODE_H_
25+
#define TVM_RELAX_VM_BYTECODE_H_
26+
27+
#include <tvm/runtime/data_type.h>
28+
#include <tvm/runtime/logging.h>
29+
30+
#include <iostream>
31+
#include <vector>
32+
33+
namespace tvm {
34+
namespace runtime {
35+
namespace relax_vm {
36+
37+
38+
/*!
39+
* \brief The storage type for the bytecode in the VM.
40+
*/
41+
using ExecWord = int64_t;
42+
43+
/*! \brief A register name. */
44+
using RegName = ExecWord;
45+
46+
/*!
47+
* \brief An alias for the integer type used ubiquitously in the VM.
48+
*/
49+
using Index = ExecWord;
50+
51+
/*!
52+
* \brief An enumeration of Relax's opcodes.
53+
*
54+
* The opcode is used to implement instruction
55+
* as a tagged union.
56+
*/
57+
enum class Opcode {
58+
Call = 1U,
59+
Ret = 2U,
60+
};
61+
62+
63+
/*! \brief A single virtual machine instruction.
64+
*
65+
* The representation of the instruction is as
66+
* a tagged union.
67+
*
68+
* The first field represents which instruction,
69+
* and by extension which field of the union
70+
* is active.
71+
*/
72+
struct Instruction {
73+
/*! \brief Random magic number that represents void argument. */
74+
static constexpr RegName kVoidArg = 0x00EC66FE0321975A;
75+
/*! \brief Random magic number that represents the VM state. */
76+
static constexpr RegName kVMStateRegister = 0x008D14FA4379015C;
77+
/*!
78+
* \brief The kind of instruction's argument.
79+
*/
80+
enum ArgKind {
81+
kRegister = 0,
82+
kImmediate = 1,
83+
kConstIdx = 2,
84+
};
85+
/*!
86+
* \brief The auxiliary data structure for instruction argument.
87+
*/
88+
struct Arg {
89+
/*! \brief The number of bit for storing value. */
90+
static constexpr ExecWord kValueBit = sizeof(ExecWord) * 8 - 8;
91+
/*! \brief The bit mask of the value part. */
92+
static constexpr ExecWord kValueMask = (static_cast<ExecWord>(1) << kValueBit) - 1;
93+
/*! \brief Construct a void argument. */
94+
explicit Arg() : data(Instruction::kVoidArg) {}
95+
/*! \brief Construct from the data. */
96+
explicit Arg(ExecWord data) : data(data) {}
97+
/*! \brief Construct from the kind and value. */
98+
Arg(ArgKind kind, Index value) {
99+
// TODO(ziheng): check value?
100+
this->data = (static_cast<ExecWord>(kind) << kValueBit) |
101+
(value & kValueMask);
102+
}
103+
/*!
104+
* \brief Get the kind of argument..
105+
* \return The kind of argument.
106+
*/
107+
ArgKind kind() const {
108+
uint8_t kind = (data >> kValueBit) & 0xFF;
109+
return Instruction::ArgKind(kind);
110+
}
111+
/*!
112+
* \brief Get the value of argument..
113+
* \return The value of argument.
114+
*/
115+
ExecWord value() const {
116+
return data & ((static_cast<ExecWord>(1) << kValueBit) - 1);
117+
}
118+
/*! \brief The underlying stored data. */
119+
ExecWord data;
120+
};
121+
/*! \brief The instruction opcode. */
122+
Opcode op;
123+
/*! \brief The destination register. */
124+
RegName dst;
125+
union {
126+
struct /* Call */ {
127+
/*! \brief The index into the packed function table. */
128+
Index func_idx;
129+
/*! \brief The number of arguments to the packed function. */
130+
Index num_args;
131+
/*! \brief The arguments of the packed function. */
132+
Arg* args;
133+
};
134+
struct /* Ret */ {
135+
/*! \brief The return result. */
136+
RegName result;
137+
};
138+
};
139+
/*!
140+
* \brief Construct a Call instruction.
141+
* \param func_idx The index of the function to call.
142+
* \param num_args The number of arguments.
143+
* \param args The input arguments.
144+
* \param dst The destination register.
145+
* \return The call instruction.
146+
*/
147+
static Instruction Call(Index func_idx, Index num_args,
148+
Arg* args,
149+
RegName dst);
150+
/*!
151+
* \brief Construct a return instruction.
152+
* \param result The register containing the return value.
153+
* \return The return instruction.
154+
*/
155+
static Instruction Ret(RegName result);
156+
};
157+
158+
} // namespace relax_vm
159+
} // namespace runtime
160+
} // namespace tvm
161+
162+
#endif // TVM_RELAX_VM_BYTECODE_H_

0 commit comments

Comments
 (0)