mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-09 21:26:21 +00:00
Enable multi-thread for tensorflow sample, update wasm-c-api document (#651)
This commit is contained in:
parent
5d9597f064
commit
1a4aa5ac2f
|
@ -542,24 +542,24 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
|
||||||
uint32 thread_handle;
|
uint32 thread_handle;
|
||||||
int32 ret = -1;
|
int32 ret = -1;
|
||||||
#if WASM_ENABLE_LIBC_WASI != 0
|
#if WASM_ENABLE_LIBC_WASI != 0
|
||||||
WASIContext *wasi_ctx = get_wasi_ctx(module_inst);
|
WASIContext *wasi_ctx;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bh_assert(module);
|
bh_assert(module);
|
||||||
|
bh_assert(module_inst);
|
||||||
|
|
||||||
if (!(new_module_inst =
|
if (!(new_module_inst =
|
||||||
wasm_runtime_instantiate_internal(module, true, 8192, 0,
|
wasm_runtime_instantiate_internal(module, true, 8192, 0,
|
||||||
NULL, 0)))
|
NULL, 0)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (module_inst) {
|
|
||||||
/* Set custom_data to new module instance */
|
/* Set custom_data to new module instance */
|
||||||
wasm_runtime_set_custom_data_internal(
|
wasm_runtime_set_custom_data_internal(
|
||||||
new_module_inst,
|
new_module_inst,
|
||||||
wasm_runtime_get_custom_data(module_inst));
|
wasm_runtime_get_custom_data(module_inst));
|
||||||
}
|
|
||||||
|
|
||||||
#if WASM_ENABLE_LIBC_WASI != 0
|
#if WASM_ENABLE_LIBC_WASI != 0
|
||||||
|
wasi_ctx = get_wasi_ctx(module_inst);
|
||||||
if (wasi_ctx)
|
if (wasi_ctx)
|
||||||
wasm_runtime_set_wasi_ctx(new_module_inst, wasi_ctx);
|
wasm_runtime_set_wasi_ctx(new_module_inst, wasi_ctx);
|
||||||
#endif
|
#endif
|
||||||
|
@ -628,7 +628,7 @@ pthread_join_wrapper(wasm_exec_env_t exec_env, uint32 thread,
|
||||||
|
|
||||||
/* validate addr, we can use current thread's
|
/* validate addr, we can use current thread's
|
||||||
module instance here as the memory is shared */
|
module instance here as the memory is shared */
|
||||||
if (!validate_app_addr(retval_offset, sizeof(void *))) {
|
if (!validate_app_addr(retval_offset, sizeof(int32))) {
|
||||||
/* Join failed, but we don't want to terminate all threads,
|
/* Join failed, but we don't want to terminate all threads,
|
||||||
do not spread exception here */
|
do not spread exception here */
|
||||||
wasm_runtime_set_exception(module_inst, NULL);
|
wasm_runtime_set_exception(module_inst, NULL);
|
||||||
|
@ -1046,6 +1046,22 @@ pthread_key_delete_wrapper(wasm_exec_env_t exec_env, int32 key)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Currently the memory allocator doesn't support alloc specific aligned
|
||||||
|
space, we wrap posix_memalign to simply malloc memory */
|
||||||
|
static int32
|
||||||
|
posix_memalign_wrapper(wasm_exec_env_t exec_env,
|
||||||
|
void **memptr, int32 align, int32 size)
|
||||||
|
{
|
||||||
|
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||||
|
void *p = NULL;
|
||||||
|
|
||||||
|
*((int32 *)memptr) = module_malloc(size, (void**)&p);
|
||||||
|
if (!p)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#define REG_NATIVE_FUNC(func_name, signature) \
|
#define REG_NATIVE_FUNC(func_name, signature) \
|
||||||
{ #func_name, func_name##_wrapper, signature, NULL }
|
{ #func_name, func_name##_wrapper, signature, NULL }
|
||||||
|
|
||||||
|
@ -1069,6 +1085,7 @@ static NativeSymbol native_symbols_lib_pthread[] = {
|
||||||
REG_NATIVE_FUNC(pthread_setspecific, "(ii)i"),
|
REG_NATIVE_FUNC(pthread_setspecific, "(ii)i"),
|
||||||
REG_NATIVE_FUNC(pthread_getspecific, "(i)i"),
|
REG_NATIVE_FUNC(pthread_getspecific, "(i)i"),
|
||||||
REG_NATIVE_FUNC(pthread_key_delete, "(i)i"),
|
REG_NATIVE_FUNC(pthread_key_delete, "(i)i"),
|
||||||
|
REG_NATIVE_FUNC(posix_memalign, "(*ii)i"),
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
|
|
|
@ -659,6 +659,7 @@ void
|
||||||
wasm_cluster_spread_exception(WASMExecEnv *exec_env)
|
wasm_cluster_spread_exception(WASMExecEnv *exec_env)
|
||||||
{
|
{
|
||||||
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
|
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
|
||||||
|
bh_assert(cluster);
|
||||||
|
|
||||||
traverse_list(&cluster->exec_env_list, set_exception_visitor, exec_env);
|
traverse_list(&cluster->exec_env_list, set_exception_visitor, exec_env);
|
||||||
}
|
}
|
||||||
|
@ -677,7 +678,11 @@ wasm_cluster_spread_custom_data(WASMModuleInstanceCommon *module_inst,
|
||||||
void *custom_data)
|
void *custom_data)
|
||||||
{
|
{
|
||||||
WASMExecEnv *exec_env = wasm_clusters_search_exec_env(module_inst);
|
WASMExecEnv *exec_env = wasm_clusters_search_exec_env(module_inst);
|
||||||
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
|
WASMCluster *cluster = NULL;
|
||||||
|
bh_assert(exec_env);
|
||||||
|
|
||||||
|
cluster = wasm_exec_env_get_cluster(exec_env);
|
||||||
|
bh_assert(cluster);
|
||||||
|
|
||||||
traverse_list(&cluster->exec_env_list,
|
traverse_list(&cluster->exec_env_list,
|
||||||
set_custom_data_visitor,
|
set_custom_data_visitor,
|
||||||
|
|
|
@ -78,6 +78,18 @@ Then build the program with this command:
|
||||||
# -Wl,--no-check-features: the errno.o in wasi-sysroot is not compatible with pthread feature, pass this option to avoid errors
|
# -Wl,--no-check-features: the errno.o in wasi-sysroot is not compatible with pthread feature, pass this option to avoid errors
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Build with EMCC**
|
||||||
|
|
||||||
|
EMCC's `-pthread` option is not compatible with standalone mode, we need to pass `-mbulk-memory -matomics` to the compiler and `--shared-memory,--no-check-features` to linker manually
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
emcc -O3 -mbulk-memory -matomics -s MALLOC="none" \
|
||||||
|
-Wl,--export=__data_end,--export=__heap_base \
|
||||||
|
-Wl,--shared-memory,--no-check-features \
|
||||||
|
-s ERROR_ON_UNDEFINED_SYMBOLS=0 \
|
||||||
|
main.c -o test.wasm
|
||||||
|
```
|
||||||
|
|
||||||
**Build AoT module**
|
**Build AoT module**
|
||||||
|
|
||||||
You can build the wasm module into AoT module with pthread support, please pass option `--enable-multi-thread` to wamrc:
|
You can build the wasm module into AoT module with pthread support, please pass option `--enable-multi-thread` to wamrc:
|
||||||
|
|
|
@ -7,71 +7,69 @@ Every user should be familiar with *APIs* listed in
|
||||||
all [examples][https://github.com/WebAssembly/wasm-c-api/tree/master/example] are
|
all [examples][https://github.com/WebAssembly/wasm-c-api/tree/master/example] are
|
||||||
very helpful for learning.
|
very helpful for learning.
|
||||||
|
|
||||||
Currently, we support partial of *APIs* and are going to support the rest of
|
Currently, we support partial of APIs and are going to support the rest of
|
||||||
them in next releases.
|
them in next releases.
|
||||||
|
|
||||||
Supported APIs:
|
a summary of unsupported APIs
|
||||||
|
|
||||||
|
- Configuration
|
||||||
|
|
||||||
``` c
|
``` c
|
||||||
/* wasm_bytevec_t APIs ... */
|
WASM_API_EXTERN own wasm_config_t* wasm_config_new(void);
|
||||||
|
|
||||||
wasm_engine_t *wasm_engine_new();
|
|
||||||
wasm_engine_t *wasm_engine_new_with_args(mem_alloc_type_t, const MemAllocOption*, runtime_mode_e);
|
|
||||||
void wasm_engine_delete(wasm_engine_t *);
|
|
||||||
|
|
||||||
wasm_store_t *wasm_store_new(wasm_engine_t *);
|
|
||||||
void wasm_store_delete(wasm_store_t *);
|
|
||||||
|
|
||||||
/* wasm_valtype_t APIs ... */
|
|
||||||
/* wasm_valtype_vec_t APIs ... */
|
|
||||||
/* wasm_functype_vec_t APIs ... */
|
|
||||||
/* wasm_globaltype_vec_t APIs ... */
|
|
||||||
/* wasm_val_t APIs ... */
|
|
||||||
/* wasm_trap_t partial APIs ... */
|
|
||||||
|
|
||||||
wasm_module_t *wasm_module_new(wasm_store_t *, const wasm_byte_vec_t *);
|
|
||||||
void wasm_module_delete(wasm_module_t *);
|
|
||||||
|
|
||||||
wasm_func_t *wasm_func_new(wasm_store_t *, const wasm_functype_t *, wasm_func_callback_t);
|
|
||||||
wasm_func_t *wasm_func_new_with_env(wasm_store_t *store, const wasm_functype_t *, wasm_func_callback_with_env_t, void *env, void (*finalizer)(void *));
|
|
||||||
void wasm_func_delete(wasm_func_t *);
|
|
||||||
wasm_fucn_t *wasm_func_copy(const wasm_func_t *);
|
|
||||||
wasm_functype_t *wasm_func_type(const wasm_func_t *);
|
|
||||||
wasm_trap_t * wasm_func_call(const wasm_func_t *, const wasm_val_t params[], wasm_val_t results[]);
|
|
||||||
size_t wasm_func_param_arity(const wasm_func_t *);
|
|
||||||
size_t wasm_func_result_arity(const wasm_func_t *);
|
|
||||||
|
|
||||||
wasm_global_t *wasm_global_new(wasm_store_t *, const wasm_globaltype_t *, const wasm_val_t *);
|
|
||||||
wasm_global_t * wasm_global_copy(const wasm_global_t *);
|
|
||||||
void wasm_global_delete(wasm_global_t *);
|
|
||||||
bool wasm_global_same(const wasm_global_t *, const wasm_global_t *);
|
|
||||||
void wasm_global_set(wasm_global_t *, const wasm_val_t *);
|
|
||||||
void wasm_global_get(const wasm_global_t *, wasm_val_t *out);
|
|
||||||
wasm_globaltype_t * wasm_global_type(const wasm_global_t *);
|
|
||||||
|
|
||||||
wasm_instance_t *wasm_instance_new(wasm_store_t *, const wasm_module_t *, const wasm_extern_t *const imports[], wasm_trap_t **traps);
|
|
||||||
void wasm_instance_delete(wasm_instance_t *);
|
|
||||||
void wasm_instance_exports(const wasm_instance_t *, wasm_extern_vec_t *out);
|
|
||||||
|
|
||||||
/* wasm_extern_t APIs */
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Unsupported APIs:
|
- References
|
||||||
|
|
||||||
``` c
|
``` c
|
||||||
/* wasm_tabletype_t APIs */
|
WASM_API_EXTERN bool wasm_##name##_same(const wasm_##name##_t*, const wasm_##name##_t*); \
|
||||||
/* wasm_memorytype_t APIs */
|
WASM_API_EXTERN void* wasm_##name##_get_host_info(const wasm_##name##_t*); \
|
||||||
/* wasm_externtype_t APIs */
|
WASM_API_EXTERN void wasm_##name##_set_host_info(wasm_##name##_t*, void*); \
|
||||||
/* wasm_importtype_t APIs */
|
WASM_API_EXTERN void wasm_##name##_set_host_info_with_finalizer( \
|
||||||
/* wasm_exporttype_t APIs */
|
WASM_API_EXTERN wasm_ref_t* wasm_##name##_as_ref(wasm_##name##_t*); \
|
||||||
/* wasm_ref_t APIs */
|
WASM_API_EXTERN wasm_##name##_t* wasm_ref_as_##name(wasm_ref_t*); \
|
||||||
/* wasm_shared_##name##_t APIs */
|
WASM_API_EXTERN const wasm_ref_t* wasm_##name##_as_ref_const(const wasm_##name##_t*); \
|
||||||
|
WASM_API_EXTERN const wasm_##name##_t* wasm_ref_as_##name##_const(const wasm_ref_t*);
|
||||||
|
WASM_API_EXTERN own wasm_shared_##name##_t* wasm_##name##_share(const wasm_##name##_t*); \
|
||||||
|
WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_obtain(wasm_store_t*, const wasm_shared_##name##_t*);
|
||||||
|
```
|
||||||
|
|
||||||
|
- Frames
|
||||||
|
|
||||||
|
``` c
|
||||||
|
WASM_API_EXTERN own wasm_frame_t* wasm_frame_copy(const wasm_frame_t*);
|
||||||
|
WASM_API_EXTERN struct wasm_instance_t* wasm_frame_instance(const wasm_frame_t*);
|
||||||
|
WASM_API_EXTERN uint32_t wasm_frame_func_index(const wasm_frame_t*);
|
||||||
|
WASM_API_EXTERN size_t wasm_frame_func_offset(const wasm_frame_t*);
|
||||||
|
WASM_API_EXTERN size_t wasm_frame_module_offset(const wasm_frame_t*);
|
||||||
|
WASM_API_EXTERN own wasm_frame_t* wasm_trap_origin(const wasm_trap_t*);
|
||||||
|
WASM_API_EXTERN void wasm_trap_trace(const wasm_trap_t*, own wasm_frame_vec_t* out);
|
||||||
|
```
|
||||||
|
|
||||||
|
Foreign Objects
|
||||||
|
|
||||||
|
``` c
|
||||||
|
WASM_API_EXTERN own wasm_foreign_t* wasm_foreign_new(wasm_store_t*);
|
||||||
|
```
|
||||||
|
|
||||||
|
- Several Module APIs
|
||||||
|
|
||||||
|
``` c
|
||||||
WASM_API_EXTERN bool wasm_module_validate(wasm_store_t*, const wasm_byte_vec_t* binary);
|
WASM_API_EXTERN bool wasm_module_validate(wasm_store_t*, const wasm_byte_vec_t* binary);
|
||||||
WASM_API_EXTERN void wasm_module_imports(const wasm_module_t*, own wasm_importtype_vec_t* out);
|
|
||||||
WASM_API_EXTERN void wasm_module_serialize(const wasm_module_t*, own wasm_byte_vec_t* out);
|
WASM_API_EXTERN void wasm_module_serialize(const wasm_module_t*, own wasm_byte_vec_t* out);
|
||||||
WASM_API_EXTERN own wasm_module_t* wasm_module_deserialize(wasm_store_t*, const wasm_byte_vec_t*);
|
WASM_API_EXTERN void wasm_module_serialize(const wasm_module_t*, own wasm_byte_vec_t* out);
|
||||||
|
```
|
||||||
/* wasm_table_t APIs */
|
|
||||||
/* wasm_memory_t APIs */
|
- Table Operations APIs
|
||||||
|
|
||||||
|
``` c
|
||||||
|
WASM_API_EXTERN own wasm_ref_t* wasm_table_get(const wasm_table_t*, wasm_table_size_t index);
|
||||||
|
WASM_API_EXTERN bool wasm_table_set(wasm_table_t*, wasm_table_size_t index, wasm_ref_t*);
|
||||||
|
WASM_API_EXTERN wasm_table_size_t wasm_table_size(const wasm_table_t*);
|
||||||
|
WASM_API_EXTERN bool wasm_table_grow(wasm_table_t*, wasm_table_size_t delta, wasm_ref_t* init);
|
||||||
|
```
|
||||||
|
|
||||||
|
- Memory Grow APIs
|
||||||
|
|
||||||
|
``` c
|
||||||
|
WASM_API_EXTERN bool wasm_memory_grow(wasm_memory_t*, wasm_memory_pages_t delta);
|
||||||
```
|
```
|
|
@ -17,7 +17,9 @@ Then run
|
||||||
./build.sh
|
./build.sh
|
||||||
# for linux platform, or
|
# for linux platform, or
|
||||||
./build.sh --sgx
|
./build.sh --sgx
|
||||||
# for linux-sgx platform
|
# for linux-sgx platform or
|
||||||
|
./build.sh --threads
|
||||||
|
# for multi-thread execution (on linux platform)
|
||||||
```
|
```
|
||||||
to build tensorflow and run it with iwasm, which basically contains the following steps:
|
to build tensorflow and run it with iwasm, which basically contains the following steps:
|
||||||
- hack emcc to delete some objects in libc.a
|
- hack emcc to delete some objects in libc.a
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
#
|
#
|
||||||
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
####################################
|
####################################
|
||||||
# build tensorflow-lite sample #
|
# build tensorflow-lite sample #
|
||||||
####################################
|
####################################
|
||||||
|
@ -99,6 +99,8 @@ WAMRC_CMD="$(pwd)/wamrc"
|
||||||
cd ${OUT_DIR}
|
cd ${OUT_DIR}
|
||||||
if [[ $1 == '--sgx' ]]; then
|
if [[ $1 == '--sgx' ]]; then
|
||||||
${WAMRC_CMD} --enable-simd -sgx -o benchmark_model.aot benchmark_model.wasm
|
${WAMRC_CMD} --enable-simd -sgx -o benchmark_model.aot benchmark_model.wasm
|
||||||
|
elif [[ $1 == '--threads' ]]; then
|
||||||
|
${WAMRC_CMD} --enable-simd --enable-multi-thread -o benchmark_model.aot benchmark_model.wasm
|
||||||
else
|
else
|
||||||
${WAMRC_CMD} --enable-simd -o benchmark_model.aot benchmark_model.wasm
|
${WAMRC_CMD} --enable-simd -o benchmark_model.aot benchmark_model.wasm
|
||||||
fi
|
fi
|
||||||
|
@ -137,7 +139,13 @@ else
|
||||||
IWASM_CMD="${WAMR_PLATFORM_DIR}/linux/build/iwasm"
|
IWASM_CMD="${WAMR_PLATFORM_DIR}/linux/build/iwasm"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
${IWASM_CMD} --heap-size=10475860 \
|
if [[ $1 == '--threads' ]]; then
|
||||||
|
${IWASM_CMD} --heap-size=10475860 \
|
||||||
|
${OUT_DIR}/benchmark_model.aot --num_threads=4 \
|
||||||
|
--graph=mobilenet_quant_v1_224.tflite --max_secs=300
|
||||||
|
else
|
||||||
|
${IWASM_CMD} --heap-size=10475860 \
|
||||||
${OUT_DIR}/benchmark_model.aot \
|
${OUT_DIR}/benchmark_model.aot \
|
||||||
--graph=mobilenet_quant_v1_224.tflite --max_secs=300
|
--graph=mobilenet_quant_v1_224.tflite --max_secs=300
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
|
@ -19,14 +19,14 @@ index c7ddff58440..ebfebaead35 100644
|
||||||
endif # ifeq ($(HOST_OS),$(TARGET))
|
endif # ifeq ($(HOST_OS),$(TARGET))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
+CFLAGS+=-msimd128
|
+CFLAGS+=-msimd128 -mbulk-memory -matomics
|
||||||
+CXXFLAGS+=-msimd128
|
+CXXFLAGS+=-msimd128 -mbulk-memory -matomics
|
||||||
+
|
+
|
||||||
+LIBFLAGS += -s TOTAL_STACK=1048576 \
|
+LIBFLAGS += -s TOTAL_STACK=1048576 -s MALLOC="none" \
|
||||||
+ -s INITIAL_MEMORY=16777216 \
|
+ -s INITIAL_MEMORY=16777216 \
|
||||||
+ -s MAXIMUM_MEMORY=167772160 \
|
+ -s MAXIMUM_MEMORY=167772160 \
|
||||||
+ -s ALLOW_MEMORY_GROWTH=1 \
|
+ -s ALLOW_MEMORY_GROWTH=1 \
|
||||||
+ -Wl,--export=__data_end -Wl,--export=__heap_base \
|
+ -Wl,--export=__data_end -Wl,--export=__heap_base,--shared-memory,--no-check-features \
|
||||||
+ -s ERROR_ON_UNDEFINED_SYMBOLS=0
|
+ -s ERROR_ON_UNDEFINED_SYMBOLS=0
|
||||||
+
|
+
|
||||||
# This library is the main target for this makefile. It will contain a minimal
|
# This library is the main target for this makefile. It will contain a minimal
|
||||||
|
|
Loading…
Reference in New Issue
Block a user