Skip to content

Conversation

@mehrdadh
Copy link
Member

@mehrdadh mehrdadh commented Feb 1, 2023

This PR refactors all the necessary functions for a CRT project into platform-template.c file. Using this PR the content of CRT template project is as follow:

.
├── crt_config
│   ├── crt_config-template.h
├── Makefile.template
├── microtvm_api_server.py
└── src
    ├── main.cc
    └── platform-template.c

The content of platform-template.c is as follows. This file shows the minimum implementation that is required for using a microTVM generated MLF file in a different environment.

#include <dlpack/dlpack.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <tvm/runtime/crt/error_codes.h>
#include <tvm/runtime/crt/page_allocator.h>

uint8_t memory[MEMORY_SIZE_BYTES];
MemoryManagerInterface* memory_manager;

// Called when an internal error occurs and execution cannot continue.
void TVMPlatformAbort(tvm_crt_error_t error_code) { exit(1); }

// Called by the microTVM RPC server to implement TVMLogf.
size_t TVMPlatformFormatMessage(char* out_buf, size_t out_buf_size_bytes,
                                                      const char* fmt, va_list args) {
  return vsprintf(out_buf, fmt, args);
}

// Allocate memory for use by TVM.
tvm_crt_error_t TVMPlatformMemoryAllocate(size_t num_bytes, DLDevice dev,
                                                                void** out_ptr) {
  return memory_manager->Allocate(memory_manager, num_bytes, dev, out_ptr);
}

// Free memory used by TVM.
tvm_crt_error_t TVMPlatformMemoryFree(void* ptr, DLDevice dev) {
  return memory_manager->Free(memory_manager, ptr, dev);
}

// Start a device timer.
tvm_crt_error_t TVMPlatformTimerStart() { return kTvmErrorNoError; }

// Stop the running device timer and get the elapsed time (in microseconds).
tvm_crt_error_t TVMPlatformTimerStop(double* elapsed_time_seconds) {
  return kTvmErrorNoError;
}

// Platform-specific before measurement call.
tvm_crt_error_t TVMPlatformBeforeMeasurement() { return kTvmErrorNoError; }

// Platform-specific after measurement call.
tvm_crt_error_t TVMPlatformAfterMeasurement() { return kTvmErrorNoError; }

// Fill a buffer with random data.
tvm_crt_error_t TVMPlatformGenerateRandom(uint8_t* buffer, size_t num_bytes) {
  return kTvmErrorNoError;
}

// Initialize TVM inference.
tvm_crt_error_t TVMPlatformInitialize() {
  int status =
      PageMemoryManagerCreate(&memory_manager, memory, sizeof(memory), 8 /* page_size_log2 */);
  if (status != 0) {
    fprintf(stderr, "error initiailizing memory manager\n");
    return kTvmErrorPlatformMemoryManagerInitialized;
  }
  return kTvmErrorNoError;
}

Using the same idea, various project types for Zephyr and Arduino was refactored.

In addition, these templates files are also added along with crt_config-template.h (which was accidentally removed in #13812) to generated model library format (MLF). Here is the updated structure of a MLF file:

.
├── codegen
│   └── host
├── metadata.json
├── parameters
│   └── default.params
├── runtime
│   ├── include
│   ├── Makefile
│   └── src
├── src
│   └── default.relay
└── templates
    ├── crt_config-template.h
    ├── platform-template.c

@tvm-bot
Copy link
Collaborator

tvm-bot commented Feb 1, 2023

Thanks for contributing to TVM! Please refer to the contributing guidelines https://tvm.apache.org/docs/contribute/ for useful information and tips. Please request code reviews from Reviewers by @-ing them in a comment.

Generated by tvm-bot

@mehrdadh mehrdadh requested a review from guberti February 1, 2023 01:09
@mehrdadh mehrdadh force-pushed the micro/mlf_add_template_files branch from 93fba20 to 7e7df14 Compare February 1, 2023 17:21
Copy link
Member Author

@mehrdadh mehrdadh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alanmacd thanks for the review! I addressed them but haven't pushed since I'm waiting to see the result of ci_cortexm tests in case anything is broken

@mehrdadh mehrdadh requested a review from alanmacd February 2, 2023 00:41
Copy link
Contributor

@mkatanbaf mkatanbaf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mehrdadh, I left a few comments.

#include <tvm/runtime/crt/stack_allocator.h>

// Used to read data from the UART.
extern tvm_workspace_t app_workspace;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to place the prototypes of the functions defined in platform.c here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wdym?

// Called by TVM when a message needs to be formatted.
size_t TVMPlatformFormatMessage(char* out_buf, size_t out_buf_size_bytes, const char* fmt,
va_list args) {
return vsnprintk(out_buf, out_buf_size_bytes, fmt, args);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this function to platform.c?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@mehrdadh mehrdadh requested review from guberti and mkatanbaf and removed request for mkatanbaf February 3, 2023 23:56
Copy link
Contributor

@mkatanbaf mkatanbaf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just left a few minor comments.

Copy link
Contributor

@areusch areusch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @mehrdadh ! the main question i have here is around making TVMPlatform functions weak--i don't think we should do that, unless i'm missing something. would love to hear others' opinions


tvm_crt_error_t TVMPlatformGenerateRandom(uint8_t* buffer, size_t num_bytes) {
// Fill a buffer with random data.
__attribute__((weak)) tvm_crt_error_t TVMPlatformGenerateRandom(uint8_t* buffer, size_t num_bytes) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how come these are weak? if you miss implementing one, could you accidentally link the default and then wind up with two implementations?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea here is that platform.c has one implementation of these functions which is added by default to the project. But in case the user wants to change the implementation, they could reimplement it in their main.c
That's why it is defined as weak.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a fan of these being weak - I think allowing the user to change the implementation is worth the increased complexity.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After discussing this with @alanmacd and @areusch, we decided to remove weak option since it is not widely supported in various compilers.

g_microtvm_timer_running = 1;
return kTvmErrorNoError;
// Initialize UART
void UARTInit() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use consistent caps (UART vs Uart; i prefer Uart because the string parses easier)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

void main(void) {
UARTInit();
TVMPlatformInitialize();
g_cmd_buf_ind = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

initialize the Uart after you are ready to receive stuff

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UartInit initialize both transmit and receive

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess what @areusch means here (and correct me if I'm wrong) is to init Uart once the platform (including memory, rpc for example) is initialized. Otherwise, the received data might drop or even cause errors (by trying to write into memory spaces that are not allocated yet)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. I changed the order.

@mehrdadh mehrdadh requested a review from mkatanbaf February 7, 2023 21:23
Copy link
Member

@guberti guberti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few nits, but looks good to me!


tvm_crt_error_t TVMPlatformGenerateRandom(uint8_t* buffer, size_t num_bytes) {
// Fill a buffer with random data.
__attribute__((weak)) tvm_crt_error_t TVMPlatformGenerateRandom(uint8_t* buffer, size_t num_bytes) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a fan of these being weak - I think allowing the user to change the implementation is worth the increased complexity.

// ###############################################################
// Model
// ###############################################################
#define MODEL_KWS 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defining these constants is a really nice improvement!

@mehrdadh mehrdadh requested review from areusch and removed request for mkatanbaf February 10, 2023 00:02
@mehrdadh mehrdadh force-pushed the micro/mlf_add_template_files branch from dae1733 to c132e9b Compare February 10, 2023 00:20
@mehrdadh mehrdadh force-pushed the micro/mlf_add_template_files branch from c132e9b to ab944ab Compare February 10, 2023 21:03
@mehrdadh mehrdadh merged commit a1dc4b9 into apache:main Feb 13, 2023
@mehrdadh mehrdadh deleted the micro/mlf_add_template_files branch February 13, 2023 20:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants