Skip to content

Commit

Permalink
uTVM interfaces (apache#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mutinifni authored and weberlo committed Jul 11, 2019
1 parent 0218557 commit a4c69e1
Show file tree
Hide file tree
Showing 19 changed files with 862 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ tvm_option(USE_RELAY_DEBUG "Building Relay in debug mode..." OFF)
tvm_option(USE_SGX "Build with SGX" OFF)
tvm_option(USE_RTTI "Build with RTTI" ON)
tvm_option(USE_MSVC_MT "Build with MT" OFF)
tvm_option(USE_MICRO "Build with Micro" OFF)
tvm_option(INSTALL_DEV "Install compiler infrastructure" OFF)
tvm_option(HIDE_PRIVATE_SYMBOLS "Compile with -fvisibility=hidden." OFF)

Expand Down Expand Up @@ -207,6 +208,7 @@ include(cmake/modules/Metal.cmake)
include(cmake/modules/ROCM.cmake)
include(cmake/modules/SGX.cmake)
include(cmake/modules/LLVM.cmake)
include(cmake/modules/Micro.cmake)
include(cmake/modules/ANTLR.cmake)
include(cmake/modules/contrib/BLAS.cmake)
include(cmake/modules/contrib/Random.cmake)
Expand Down
3 changes: 3 additions & 0 deletions cmake/config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ set(USE_VULKAN OFF)
# Whether enable OpenGL runtime
set(USE_OPENGL OFF)

# Whether enable Micro runtime
set(USE_MICRO OFF)

# Whether to enable SGX runtime
#
# Possible values for USE_SGX:
Expand Down
5 changes: 5 additions & 0 deletions cmake/modules/Micro.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
if(USE_MICRO)
message(STATUS "Build with Micro support")
file(GLOB RUNTIME_MICRO_SRCS src/runtime/micro/*.cc)
list(APPEND RUNTIME_SRCS ${RUNTIME_MICRO_SRCS})
endif(USE_MICRO)
1 change: 1 addition & 0 deletions include/tvm/runtime/c_runtime_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ typedef enum {
kDLAOCL = 5,
kDLSDAccel = 6,
kOpenGL = 11,
kDLMicroDev = 13,
// AddExtraTVMType which is not in DLPack here
} TVMDeviceExtType;

Expand Down
2 changes: 2 additions & 0 deletions python/tvm/_ffi/runtime_ctypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ class TVMContext(ctypes.Structure):
10: 'rocm',
11: 'opengl',
12: 'ext_dev',
13: 'micro_dev',
}
STR2MASK = {
'llvm': 1,
Expand All @@ -163,6 +164,7 @@ class TVMContext(ctypes.Structure):
'rocm': 10,
'opengl': 11,
'ext_dev': 12,
'micro_dev': 13,
}
def __init__(self, device_type, device_id):
super(TVMContext, self).__init__()
Expand Down
108 changes: 108 additions & 0 deletions src/runtime/micro/allocator_stream.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*!
* Copyright (c) 2019 by Contributors
* \file allocator_stream.h
* \brief allocator stream utility
*/
#ifndef TVM_RUNTIME_MICRO_ALLOCATOR_STREAM_H_
#define TVM_RUNTIME_MICRO_ALLOCATOR_STREAM_H_

#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <dmlc/memory_io.h>

namespace tvm {
namespace runtime {
/*!
* \brief allocation-based stream with bounded buffer size for uTVM args allocation
* \note based on dmlc::MemoryStringStream
*/
struct AllocatorStream : public dmlc::SeekStream {
public:
/*!
* \brief constructor
* \param p_buffer the pointer to the string.
*/
explicit AllocatorStream(std::string *p_buffer)
: p_buffer_(p_buffer) {
curr_ptr_ = 0;
max_ptr_ = 0;
}

/*!
* \brief reads size bytes of data starting at ptr
* \param ptr address to begin read
* \param size number of bytes to be read
* \return number of bytes read
*/
size_t Read(void *ptr, size_t size) {
CHECK(curr_ptr_ <= p_buffer_->length());
CHECK(curr_ptr_ + size <= max_ptr_);
size_t nread = std::min(p_buffer_->length() - curr_ptr_, size);
if (nread != 0) std::memcpy(ptr, &(*p_buffer_)[0] + curr_ptr_, nread);
curr_ptr_ += nread;
return nread;
}

/*!
* \brief writes size bytes of data starting at ptr
* \param ptr address of the buffer to be written
* \param size number of bytes to be written
*/
void Write(const void *ptr, size_t size) {
if (size == 0) return;
CHECK(curr_ptr_ + size <= max_ptr_);
if (curr_ptr_ + size > p_buffer_->length()) {
p_buffer_->resize(curr_ptr_+size);
}
std::memcpy(&(*p_buffer_)[0] + curr_ptr_, ptr, size);
curr_ptr_ += size;
}

/*!
* \brief seek to specified location within internal buffer
* \param pos seek position from start in bytes
*/
void Seek(size_t pos) {
curr_ptr_ = static_cast<size_t>(pos);
}

/*!
* \brief get seek pointer location
* \return current seek pointer location from start in bytes
*/
size_t Tell(void) {
return curr_ptr_;
}

/*!
* \brief allocates an empty region within the stream buffer
* \param size size of the allocated region
* \return offset bytes of the allocated region from start of the buffer
*/
size_t Allocate(size_t size) {
size_t ret = max_ptr_;
max_ptr_ += size;
return ret;
}

/*!
* \brief returns current size of the stream buffer
* \return buffer size
*/
size_t GetBufferSize() {
return max_ptr_;
}

private:
/*! \brief in memory buffer */
std::string *p_buffer_;
/*! \brief current pointer */
size_t curr_ptr_;
/*! \brief maximum pointer */
size_t max_ptr_;
};
} // namespace runtime
} // namespace tvm
#endif // TVM_RUNTIME_MICRO_ALLOCATOR_STREAM_H_
20 changes: 20 additions & 0 deletions src/runtime/micro/device/utvm_runtime.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*!
* Copyright (c) 2019 by Contributors
* \file utvm_runtime.cc
* \brief micro device init stub
*/
#include "utvm_runtime.h"

// task pointers must be patched before calling a function
UTVMTask task;

// dummy function to signal execution is finished
void UTVMDone() {}

// init stub
int UTVMMain()
{
task.func(task.args, task.arg_type_ids, *task.num_args);
UTVMDone();
return 0;
}
27 changes: 27 additions & 0 deletions src/runtime/micro/device/utvm_runtime.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*!
* Copyright (c) 2019 by Contributors
* \file utvm_runtime.h
* \brief utvm runtime headers
*/
#ifndef UTVM_RUNTIME_H_
#define UTVM_RUNTIME_H_

#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>

/*!
* \brief task structure for uTVM
*/
typedef struct {
int (*func)(void*, void*, int32_t);
void* args;
void* arg_type_ids;
int32_t* num_args;
} UTVMTask;

#ifdef __cplusplus
} // TVM_EXTERN_C
#endif
#endif // UTVM_RUNTIME_H_
50 changes: 50 additions & 0 deletions src/runtime/micro/host_low_level_device.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*!
* Copyright (c) 2019 by Contributors
* \file host_low_level_device.cc
* \brief emulated low-level micro device implementation on host machine
*/

#include "low_level_device.h"

namespace tvm {
namespace runtime {
/*!
* \brief emulated low-level device on host machine
*/
class HostLowLevelDevice final : public LowLevelDevice {
public:
/*!
* \brief constructor to initialize on-host memory region to act as device
* \param num_bytes size of the emulated on-device memory region
*/
HostLowLevelDevice(size_t num_bytes);

/*!
* \brief destructor to deallocate on-host device region
*/
~HostLowLevelDevice();

void Write(void* offset,
void* buf,
size_t num_bytes) final;

void Read(void* offset,
void* buf,
size_t num_bytes) final;

void Execute(void* func_addr, void* breakpoint) final;

const void* base_addr() const final;

private:
/*! \brief base address of the micro device memory region */
void* base_addr_;
/*! \brief size of memory region */
size_t size_;
};

const std::shared_ptr<LowLevelDevice> HostLowLevelDeviceCreate(size_t num_bytes) {
return nullptr;
}
} // namespace runtime
} // namespace tvm
69 changes: 69 additions & 0 deletions src/runtime/micro/low_level_device.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*!
* Copyright (c) 2019 by Contributors
* \file low_level_device.h
* \brief Abstract low-level micro device management
*/
#ifndef TVM_RUNTIME_LOW_LEVEL_DEVICE_H_
#define TVM_RUNTIME_LOW_LEVEL_DEVICE_H_

#include <cstddef>
#include <memory>

namespace tvm {
namespace runtime {
/*!
* \brief virtual interface for low-level micro device management
*/
class LowLevelDevice {
public:
/*! \brief virtual destructor */
virtual ~LowLevelDevice() {}

/*!
* \brief writes num_bytes from buffer to device memory at base_addr + offset
* \param offset on-device memory offset pointer to be written to
* \param buffer on-host buffer to be written
* \param num_bytes number of bytes to be written
*/
virtual void Write(void* offset,
void* buffer,
size_t num_bytes) = 0;

/*!
* \brief reads num_bytes from device memory at base_addr + offset into buffer
* \param offset on-device memory offset pointer to be read from
* \param buffer on-host buffer to be read into
* \param num_bytes number of bytes to be read
*/
virtual void Read(void* offset,
void* buffer,
size_t num_bytes) = 0;

/*!
* \brief starts execution of device at offset
* \param func_addr address of the init stub function
* \param breakpoint breakpoint at which to stop function execution
*/
virtual void Execute(void* func_addr, void* breakpoint) = 0;

/*!
* \brief getter function for base_addr
* \return the base address of the device memory region
*/
virtual const void* base_addr() const = 0;
};

/*!
* \brief create a host low-level device
* \param num_bytes size of the memory region
*/
const std::shared_ptr<LowLevelDevice> HostLowLevelDeviceCreate(size_t num_bytes);

/*!
* \brief connect to OpenOCD and create an OpenOCD low-level device
* \param port port of the OpenOCD server to connect to
*/
const std::shared_ptr<LowLevelDevice> OpenOCDLowLevelDeviceCreate(int port);
} // namespace runtime
} // namespace tvm
#endif // TVM_RUNTIME_LOW_LEVEL_DEVICE_H_
53 changes: 53 additions & 0 deletions src/runtime/micro/micro_common.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*!
* Copyright (c) 2019 by Contributors
* \file bin_util.cc
* \brief binary modification utilities
*/

#include <stdio.h>
#include <string>
#include "micro_session.h"
#include "micro_common.h"

namespace tvm {
namespace runtime {

const char* SectionToString(SectionKind section) {
switch (section) {
case kText: return "text";
case kData: return "data";
case kBss: return "bss";
case kArgs: return "args";
case kStack: return "stack";
case kHeap: return "heap";
case kWorkspace: return "workspace";
}
}

// TODO: implement these in Python using PackedFunc + Registry
void* GetSymbol(std::unordered_map<std::string, void*> symbol_map,
std::string name,
void* base_addr) {
return nullptr;
}

std::string RelocateBinarySections(std::string binary_name,
void* text,
void* data,
void* bss) {
return "";
}

std::string ReadSection(std::string binary_name, Section section) {
return "";
}

size_t GetSectionSize(std::string binary_name, Section section) {
return 0;
}

std::unordered_map<std::string, void*> GetSymbolMap(std::string binary) {
return nullptr;
}
} // namespace runtime
} // namespace tvm
Loading

0 comments on commit a4c69e1

Please sign in to comment.