diff --git a/cmake/modules/StandaloneCrt.cmake b/cmake/modules/StandaloneCrt.cmake index 5ed5f5ead088..1ced2b8ad892 100644 --- a/cmake/modules/StandaloneCrt.cmake +++ b/cmake/modules/StandaloneCrt.cmake @@ -135,7 +135,7 @@ if(USE_MICRO) # Create the `crttest` target if we can find GTest. If not, we create dummy # targets that give the user an informative error message. if(GTEST_INCLUDE_DIR AND GTEST_LIB) - file(GLOB TEST_SRCS ${CMAKE_SOURCE_DIR}/tests/crt/*_test.cc) + file(GLOB TEST_SRCS ${CMAKE_SOURCE_DIR}/tests/crt/*.cc) add_executable(crttest ${TEST_SRCS}) target_include_directories(crttest SYSTEM PUBLIC ${GTEST_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/standalone_crt/include ${CMAKE_SOURCE_DIR}/src/runtime/micro) target_link_libraries(crttest PRIVATE ${cmake_crt_libraries} ${GTEST_LIB} gtest_main pthread dl) diff --git a/src/runtime/crt/graph_executor/graph_executor.c b/src/runtime/crt/graph_executor/graph_executor.c index c2e465361651..34e81c7d33b1 100644 --- a/src/runtime/crt/graph_executor/graph_executor.c +++ b/src/runtime/crt/graph_executor/graph_executor.c @@ -445,6 +445,7 @@ int TVMGraphExecutorGraphAttr_Load(TVMGraphExecutorGraphAttr* attr, JSONReader* status = -1; break; } + reader->BeginArray(reader); size_t num_items = 0; if (reader->ArrayLength(reader, &num_items) != 0) { fprintf(stderr, "error determing list_int length\n"); diff --git a/src/runtime/crt/include/tvm/runtime/crt/internal/graph_executor/graph_executor.h b/src/runtime/crt/include/tvm/runtime/crt/internal/graph_executor/graph_executor.h index c9b3ebe5c643..c67c43357363 100644 --- a/src/runtime/crt/include/tvm/runtime/crt/internal/graph_executor/graph_executor.h +++ b/src/runtime/crt/include/tvm/runtime/crt/internal/graph_executor/graph_executor.h @@ -24,6 +24,10 @@ #ifndef TVM_RUNTIME_CRT_INCLUDE_TVM_RUNTIME_CRT_INTERNAL_GRAPH_EXECUTOR_GRAPH_EXECUTOR_H_ #define TVM_RUNTIME_CRT_INCLUDE_TVM_RUNTIME_CRT_INTERNAL_GRAPH_EXECUTOR_GRAPH_EXECUTOR_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include #include #include @@ -117,5 +121,10 @@ int TVMGraphExecutor_GetOutput(TVMGraphExecutor* executor, const int32_t idx, DL int32_t TVMGraphExecutor_CreateTVMOp(TVMGraphExecutor* executor, const TVMOpParam* param, DLTensorPtr* args, const uint32_t args_count, TVMPackedFunc* pf); +int TVMGraphExecutor_Load(TVMGraphExecutor* executor, JSONReader* reader); + +#ifdef __cplusplus +} +#endif #endif // TVM_RUNTIME_CRT_INCLUDE_TVM_RUNTIME_CRT_INTERNAL_GRAPH_EXECUTOR_GRAPH_EXECUTOR_H_ diff --git a/src/runtime/crt/include/tvm/runtime/crt/internal/graph_executor/load_json.h b/src/runtime/crt/include/tvm/runtime/crt/internal/graph_executor/load_json.h index ac5adc842b62..74236148d9d4 100644 --- a/src/runtime/crt/include/tvm/runtime/crt/internal/graph_executor/load_json.h +++ b/src/runtime/crt/include/tvm/runtime/crt/internal/graph_executor/load_json.h @@ -24,6 +24,10 @@ #ifndef TVM_RUNTIME_CRT_INCLUDE_TVM_RUNTIME_CRT_INTERNAL_GRAPH_EXECUTOR_LOAD_JSON_H_ #define TVM_RUNTIME_CRT_INCLUDE_TVM_RUNTIME_CRT_INTERNAL_GRAPH_EXECUTOR_LOAD_JSON_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include #include #include @@ -100,4 +104,8 @@ tvm_crt_error_t JSONReader_Create(const char* is, JSONReader* reader); */ tvm_crt_error_t JSONReader_Release(JSONReader* reader); +#ifdef __cplusplus +} +#endif + #endif // TVM_RUNTIME_CRT_INCLUDE_TVM_RUNTIME_CRT_INTERNAL_GRAPH_EXECUTOR_LOAD_JSON_H_ diff --git a/tests/crt/graph_executor_test.cc b/tests/crt/graph_executor_test.cc new file mode 100644 index 000000000000..d07c9586c4da --- /dev/null +++ b/tests/crt/graph_executor_test.cc @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "../../src/runtime/crt/include/tvm/runtime/crt/internal/graph_executor/graph_executor.h" + +#include + +#include "../../src/runtime/crt/include/tvm/runtime/crt/internal/graph_executor/load_json.h" + +namespace { + +constexpr const char* kJson = R"( +{ + "nodes": [ + { + "op": "null", + "name": "x", + "inputs": [] + }, + { + "op": "null", + "name": "p0", + "inputs": [] + }, + { + "op": "tvm_op", + "name": "tvmgen_default_fused_add", + "attrs": { + "num_outputs": "1", + "num_inputs": "2", + "flatten_data": "0", + "func_name": "tvmgen_default_fused_add", + "hash": "a2b7e0a88031366c" + }, + "inputs": [ + [ + 0, + 0, + 0 + ], + [ + 1, + 0, + 0 + ] + ] + } + ], + "arg_nodes": [0, 1], + "heads": [ + [ + 2, + 0, + 0 + ] + ], + "attrs": { + "dltype": [ + "list_str", + [ + "float32", + "float32", + "float32" + ] + ], + "device_index": [ + "list_int", + [1, 1, 1] + ], + "storage_id": [ + "list_int", + [0, 1, 2] + ], + "shape": [ + "list_shape", + [ + [10, 5], + [1, 5], + [10, 5] + ] + ] + }, + "node_row_ptr": [0, 1, 2, 3] +} +)"; + +// Check a JSON graph can be loaded. +TEST(TVMGraphExecutor_Load, Parse) { + JSONReader reader; + tvm_crt_error_t err = JSONReader_Create(kJson, &reader); + EXPECT_EQ(err, kTvmErrorNoError); + TVMGraphExecutor executor; + memset(&executor, 0, sizeof(executor)); + int status = TVMGraphExecutor_Load(&executor, &reader); + EXPECT_EQ(status, 0); + EXPECT_EQ(executor.nodes_count, 3); +} + +} // namespace diff --git a/tests/crt/page_allocator_test.cc b/tests/crt/page_allocator_test.cc index 924bf295ffd2..527dbecd0e07 100644 --- a/tests/crt/page_allocator_test.cc +++ b/tests/crt/page_allocator_test.cc @@ -22,7 +22,6 @@ #include #include "crt_config.h" -#include "platform.cc" #define ROUND_UP(qty, modulo) (((qty) + ((modulo)-1)) / (modulo) * (modulo)) diff --git a/tests/crt/platform.cc b/tests/crt/platform.cc index 3d8906d0605f..5f8da6732a97 100644 --- a/tests/crt/platform.cc +++ b/tests/crt/platform.cc @@ -22,15 +22,22 @@ #include #include +// Provide dummy implementations for TVM runtime functions for use by the tests. + extern "C" { + void InternalTVMPlatformAbort(tvm_crt_error_t error_code) { FAIL() << "TVMPlatformAbort(" << error_code << ")"; } + void TVMPlatformAbort(tvm_crt_error_t error_code) { InternalTVMPlatformAbort(error_code); exit(2); // for __attribute__((noreturn)) } -void* TVMSystemLibEntryPoint() { return NULL; } + +struct TVMModule; +const TVMModule* TVMSystemLibEntryPoint(void) { return NULL; } + void TVMLogf(const char* fmt, ...) { va_list args; char log_buf[1024]; @@ -44,4 +51,22 @@ void TVMLogf(const char* fmt, ...) { LOG(INFO) << "TVMLogf: " << std::string(log_buf, ret); } } + +tvm_crt_error_t TVMPlatformMemoryAllocate(size_t num_bytes, DLDevice dev, void** out_ptr) { + *out_ptr = malloc(num_bytes); + return *out_ptr ? kTvmErrorNoError : kTvmErrorPlatformNoMemory; +} + +tvm_crt_error_t TVMPlatformMemoryFree(void* ptr, DLDevice dev) { + if (ptr) { + free(ptr); + } + return kTvmErrorNoError; +} + +tvm_crt_error_t TVMPlatformTimerStart() { return kTvmErrorFunctionCallNotImplemented; } + +tvm_crt_error_t TVMPlatformTimerStop(double* elapsed_time_seconds) { + return kTvmErrorFunctionCallNotImplemented; +} }