Skip to content

Commit 8d62426

Browse files
mutinifniweberlo
authored andcommitted
added micro_common implementation and python interfaces (apache#18)
1 parent 1c34002 commit 8d62426

File tree

8 files changed

+84
-81
lines changed

8 files changed

+84
-81
lines changed

3rdparty/HalideIR

python/tvm/contrib/binutil.py

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,25 @@
77

88

99
@register_func("tvm_get_section_size")
10-
def tvm_get_section_size(binary_name, section):
10+
def tvm_callback_get_section_size(binary_path, section):
1111
"""Finds size of the section in the binary.
1212
Assumes "size" shell command exists (typically works only on Linux machines)
1313
1414
Parameters
1515
----------
16-
binary_name : string
17-
name of the binary file
16+
binary_path : str
17+
path of the binary file
1818
19-
section : string
19+
section : str
2020
type of section
2121
2222
Return
2323
------
24-
size : integer
24+
size : integer
2525
size of the section in bytes
2626
"""
2727
section_map = {"text": "1", "data": "2", "bss": "3"}
28-
p1 = subprocess.Popen(["size", binary_name], stdout=subprocess.PIPE)
28+
p1 = subprocess.Popen(["size", binary_path], stdout=subprocess.PIPE)
2929
p2 = subprocess.Popen(["awk", "{print $" + section_map[section] + "}"],
3030
stdin=p1.stdout, stdout=subprocess.PIPE)
3131
p3 = subprocess.Popen(["tail", "-1"], stdin=p2.stdout, stdout=subprocess.PIPE)
@@ -40,21 +40,21 @@ def tvm_get_section_size(binary_name, section):
4040

4141

4242
@register_func("tvm_relocate_binary")
43-
def tvm_relocate_binary(binary_name, text, data, bss):
43+
def tvm_callback_relocate_binary(binary_path, text, data, bss):
4444
"""Relocates sections in the binary to new addresses
4545
4646
Parameters
4747
----------
48-
binary_name : string
49-
name of the binary file
48+
binary_path : str
49+
path of the binary file
5050
51-
text : string
51+
text : str
5252
text section address
5353
54-
data : string
54+
data : str
5555
data section address
5656
57-
bss : string
57+
bss : str
5858
bss section address
5959
6060
Return
@@ -64,7 +64,7 @@ def tvm_relocate_binary(binary_name, text, data, bss):
6464
"""
6565
tmp_dir = util.tempdir()
6666
rel_obj = tmp_dir.relpath("relocated.o")
67-
p1 = subprocess.Popen(["ld", binary_name,
67+
p1 = subprocess.Popen(["ld", binary_path,
6868
"-Ttext", text,
6969
"-Tdata", data,
7070
"-Tbss", bss,
@@ -81,15 +81,15 @@ def tvm_relocate_binary(binary_name, text, data, bss):
8181

8282

8383
@register_func("tvm_read_binary_section")
84-
def tvm_read_binary_section(binary, section):
84+
def tvm_callback_read_binary_section(binary_path, section):
8585
"""Returns the contents of the specified section in the binary file
8686
8787
Parameters
8888
----------
89-
binary : bytearray
90-
contents of the binary
89+
binary_path : str
90+
path of the binary file
9191
92-
section : string
92+
section : str
9393
type of section
9494
9595
Return
@@ -98,13 +98,10 @@ def tvm_read_binary_section(binary, section):
9898
contents of the read section
9999
"""
100100
tmp_dir = util.tempdir()
101-
tmp_bin = tmp_dir.relpath("temp.bin")
102101
tmp_section = tmp_dir.relpath("tmp_section.bin")
103-
with open(tmp_bin, "wb") as out_file:
104-
out_file.write(bytes(binary))
105102
p1 = subprocess.Popen(["objcopy", "--dump-section",
106103
"." + section + "=" + tmp_section,
107-
tmp_bin],
104+
binary_path],
108105
stdout=subprocess.PIPE,
109106
stderr=subprocess.STDOUT)
110107
(out, _) = p1.communicate()
@@ -122,7 +119,7 @@ def tvm_read_binary_section(binary, section):
122119

123120

124121
@register_func("tvm_get_symbol_map")
125-
def tvm_get_symbol_map(binary):
122+
def tvm_callback_get_symbol_map(binary):
126123
"""Obtains a map of symbols to addresses in the passed binary
127124
128125
Parameters

src/runtime/micro/micro_common.cc

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const char* SectionToString(SectionKind section) {
3131

3232
void* GetSymbol(std::unordered_map<std::string, void*> symbol_map,
3333
std::string name,
34-
const void* base_addr) {
34+
void* base_addr) {
3535
void* symbol_addr = symbol_map[name];
3636
return (void*)((uint8_t*) symbol_addr - (uint8_t*) base_addr);
3737
}
@@ -50,36 +50,39 @@ std::string RelocateBinarySections(std::string binary_name,
5050
void* text,
5151
void* data,
5252
void* bss) {
53-
const auto* f = Registry::Get("tvm_relocate_binary");
54-
CHECK(f != nullptr) << "Require tvm_relocate_binary to exist in registry";
53+
const auto* f = Registry::Get("tvm_callback_relocate_binary");
54+
CHECK(f != nullptr)
55+
<< "Require tvm_callback_relocate_binary to exist in registry";
5556
std::string relocated_bin = (*f)(binary_name,
5657
AddrToString(text),
5758
AddrToString(data),
5859
AddrToString(bss));
5960
return relocated_bin;
6061
}
6162

62-
std::string ReadSection(std::string binary, SectionKind section) {
63+
std::string ReadSection(std::string binary_name, SectionKind section) {
6364
CHECK(section == kText || section == kData || section == kBss)
6465
<< "ReadSection requires section to be one of text, data or bss.";
65-
const auto* f = Registry::Get("tvm_read_binary_section");
66-
CHECK(f != nullptr) << "Require tvm_read_binary_section to exist in registry";
67-
std::string section_contents = (*f)(binary, SectionToString(section));
66+
const auto* f = Registry::Get("tvm_callback_read_binary_section");
67+
CHECK(f != nullptr)
68+
<< "Require tvm_callback_read_binary_section to exist in registry";
69+
std::string section_contents = (*f)(binary_name, SectionToString(section));
6870
return section_contents;
6971
}
7072

7173
size_t GetSectionSize(std::string binary_name, SectionKind section) {
7274
CHECK(section == kText || section == kData || section == kBss)
7375
<< "GetSectionSize requires section to be one of text, data or bss.";
74-
const auto* f = Registry::Get("tvm_get_section_size");
75-
CHECK(f != nullptr) << "Require tvm_get_section_size to exist in registry";
76+
const auto* f = Registry::Get("tvm_callback_get_section_size");
77+
CHECK(f != nullptr)
78+
<< "Require tvm_callback_get_section_size to exist in registry";
7679
size_t size = (*f)(binary_name, SectionToString(section));
7780
return size;
7881
}
7982

8083
std::unordered_map<std::string, void*> GetSymbolMap(std::string binary) {
81-
const auto* f = Registry::Get("tvm_get_symbol_map");
82-
CHECK(f != nullptr) << "Require tvm_get_symbol_map to exist in registry";
84+
const auto* f = Registry::Get("tvm_callback_get_symbol_map");
85+
CHECK(f != nullptr) << "Require tvm_callback_get_symbol_map to exist in registry";
8386
TVMByteArray arr;
8487
arr.data = &binary[0];
8588
arr.size = binary.length();

src/runtime/micro/micro_device_api.cc

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ namespace runtime {
1616
*/
1717
class MicroDeviceAPI final : public DeviceAPI {
1818
public:
19+
MicroDeviceAPI() {
20+
session_ = MicroSession::Global();
21+
}
22+
1923
void SetDevice(TVMContext ctx) final {}
2024

2125
void GetAttr(TVMContext ctx, DeviceAttrKind kind, TVMRetValue* rv) final {
@@ -28,15 +32,12 @@ class MicroDeviceAPI final : public DeviceAPI {
2832
size_t nbytes,
2933
size_t alignment,
3034
TVMType type_hint) final {
31-
// TODO: can make this a private member, but where to best init it?
32-
std::shared_ptr<MicroSession> session = MicroSession::Global();
33-
void* alloc_ptr = session->AllocateInSection(kHeap, nbytes);
35+
void* alloc_ptr = session_->AllocateInSection(kHeap, nbytes);
3436
return alloc_ptr;
3537
}
3638

3739
void FreeDataSpace(TVMContext ctx, void* ptr) final {
38-
std::shared_ptr<MicroSession> session = MicroSession::Global();
39-
session->FreeInSection(kHeap, ptr);
40+
session_->FreeInSection(kHeap, ptr);
4041
}
4142

4243
void CopyDataFromTo(const void* from,
@@ -48,27 +49,33 @@ class MicroDeviceAPI final : public DeviceAPI {
4849
TVMContext ctx_to,
4950
TVMType type_hint,
5051
TVMStreamHandle stream) final {
51-
std::shared_ptr<MicroSession> session = MicroSession::Global();
52-
uint8_t buffer[size];
5352
constexpr int micro_devtype = kDLMicroDev;
5453
std::tuple<int, int> type_from_to(ctx_from.device_type, ctx_to.device_type);
5554

5655
if (type_from_to == std::make_tuple(micro_devtype, micro_devtype)) {
57-
// TODO: ignored ctx because we assume only one low-level micro_dev - is ok?
58-
std::shared_ptr<LowLevelDevice> from_lld = session->low_level_device();
59-
std::shared_ptr<LowLevelDevice> to_lld = session->low_level_device();
60-
from_lld->Read((uint8_t*)(from) + from_offset, buffer, size);
61-
to_lld->Write((uint8_t*)(to) + to_offset, buffer, size);
62-
56+
CHECK(ctx_from.device_id == ctx_to.device_id)
57+
<< "can only copy between the same micro device";
58+
std::string buffer;
59+
const std::shared_ptr<LowLevelDevice>& from_lld = session_->low_level_device();
60+
const std::shared_ptr<LowLevelDevice>& to_lld = session_->low_level_device();
61+
from_lld->Read(
62+
const_cast<uint8_t*>(static_cast<const uint8_t*>(from)) + from_offset,
63+
const_cast<char*>(&buffer[0]), size);
64+
to_lld->Write(
65+
const_cast<uint8_t*>(static_cast<const uint8_t*>(to)) + to_offset,
66+
const_cast<char*>(&buffer[0]), size);
6367
} else if (type_from_to == std::make_tuple(micro_devtype, kDLCPU)) {
64-
std::shared_ptr<LowLevelDevice> from_lld = session->low_level_device();
65-
from_lld->Read((uint8_t*)(from) + from_offset, buffer, size);
66-
memcpy(static_cast<uint8_t*>(to) + to_offset, buffer, size);
68+
const std::shared_ptr<LowLevelDevice>& from_lld = session_->low_level_device();
69+
from_lld->Read(
70+
const_cast<uint8_t*>(static_cast<const uint8_t*>(from)) + from_offset,
71+
const_cast<uint8_t*>(static_cast<const uint8_t*>(to)), size);
6772

6873
} else if (type_from_to == std::make_tuple(micro_devtype, kDLCPU)) {
69-
std::shared_ptr<LowLevelDevice> to_lld = session->low_level_device();
70-
to_lld->Write((uint8_t*)(to) + to_offset,
71-
(uint8_t*)(from) + from_offset, size);
74+
const std::shared_ptr<LowLevelDevice>& to_lld = session_->low_level_device();
75+
to_lld->Write(
76+
const_cast<uint8_t*>(static_cast<const uint8_t*>(to)) + to_offset,
77+
const_cast<uint8_t*>(static_cast<const uint8_t*>(from)) + from_offset,
78+
size);
7279

7380
} else {
7481
LOG(FATAL) << "Expect copy from/to micro_dev or between micro_dev\n";
@@ -81,15 +88,13 @@ class MicroDeviceAPI final : public DeviceAPI {
8188

8289
// TODO: what about ctx?
8390
void* AllocWorkspace(TVMContext ctx, size_t size, TVMType type_hint) final {
84-
std::shared_ptr<MicroSession> session = MicroSession::Global();
85-
void* alloc_ptr = session->AllocateInSection(kWorkspace, size);
91+
void* alloc_ptr = session_->AllocateInSection(kWorkspace, size);
8692
return alloc_ptr;
8793
}
8894

8995
// TODO: what about ctx?
9096
void FreeWorkspace(TVMContext ctx, void* data) final {
91-
std::shared_ptr<MicroSession> session = MicroSession::Global();
92-
session->FreeInSection(kWorkspace, data);
97+
session_->FreeInSection(kWorkspace, data);
9398
}
9499

95100
/*!
@@ -101,6 +106,10 @@ class MicroDeviceAPI final : public DeviceAPI {
101106
std::make_shared<MicroDeviceAPI>();
102107
return inst;
103108
}
109+
110+
private:
111+
/*! \brief pointer to global session */
112+
MicroSession* session_;
104113
};
105114

106115
// register device that can be obtained from Python frontend

src/runtime/micro/micro_session.h

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class MicroSectionAllocator {
2828
* \param section_start start address of the section
2929
* \param section_end end address of the section (non inclusive)
3030
*/
31-
MicroSectionAllocator(void* section_start, void* section_end)
31+
MicroSectionAllocator(void* section_start, void* section_end)
3232
: section_start_(section_start), section_end_(section_end),
3333
section_max_(section_start) {
3434
}
@@ -96,17 +96,7 @@ class MicroSession {
9696
* \brief get MicroSession global singleton
9797
* \return pointer to the micro session global singleton
9898
*/
99-
static std::shared_ptr<MicroSession>& Global() {
100-
static std::shared_ptr<MicroSession> inst = std::make_shared<MicroSession>();
101-
return inst;
102-
}
103-
104-
/*!
105-
* \brief initializes session by setting up low_level_device_
106-
* \param args TVMArgs passed into the micro.init packedfunc
107-
* \note must be called upon first call to Global()
108-
*/
109-
void InitSession(TVMArgs args);
99+
static MicroSession* Global();
110100

111101
/*!
112102
* \brief allocate memory in section
@@ -134,7 +124,7 @@ class MicroSession {
134124
* \brief returns low-level device pointer
135125
* \note assumes low_level_device_ is initialized
136126
*/
137-
const std::shared_ptr<LowLevelDevice> low_level_device() const {
127+
const std::shared_ptr<LowLevelDevice>& low_level_device() const {
138128
return low_level_device_;
139129
}
140130

@@ -181,17 +171,17 @@ class MicroSession {
181171
void AllocateTVMArgs(TVMArgs args);
182172

183173
void TargetAwareWrite(int64_t val, AllocatorStream* stream);
184-
174+
185175
void TargetAwareWrite(uint64_t val, AllocatorStream* stream);
186-
176+
187177
void TargetAwareWrite(double val, AllocatorStream* stream);
188-
178+
189179
void TargetAwareWrite(const char* val, AllocatorStream* stream);
190-
180+
191181
void TargetAwareWrite(TVMType val, AllocatorStream* stream);
192-
182+
193183
void TargetAwareWrite(TVMContext* val, AllocatorStream* stream);
194-
184+
195185
void TargetAwareWrite(TVMArray* val, AllocatorStream* stream);
196186
};
197187
} // namespace runtime

tests/python/contrib/test_binutil.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,14 @@ def verify():
6060

6161

6262
def test_tvm_read_binary_section(binary):
63+
tmp_dir = util.tempdir()
64+
tmp_bin = tmp_dir.relpath("obj.bin")
65+
with open(tmp_bin, "wb") as f:
66+
f.write(binary)
6367
def verify():
64-
text_bin = tvm_read_binary_section(binary, "text")
65-
data_bin = tvm_read_binary_section(binary, "data")
66-
bss_bin = tvm_read_binary_section(binary, "bss")
68+
text_bin = tvm_read_binary_section(tmp_bin, "text")
69+
data_bin = tvm_read_binary_section(tmp_bin, "data")
70+
bss_bin = tvm_read_binary_section(tmp_bin, "bss")
6771
print("Read text section part of binary? %r" % (text_bin in binary))
6872
print("Read data section part of binary? %r" % (data_bin in binary))
6973
print("Read bss section part of binary? %r" % (bss_bin in binary))

0 commit comments

Comments
 (0)