mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-02-06 06:55:07 +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;
|
||||
int32 ret = -1;
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
WASIContext *wasi_ctx = get_wasi_ctx(module_inst);
|
||||
WASIContext *wasi_ctx;
|
||||
#endif
|
||||
|
||||
bh_assert(module);
|
||||
bh_assert(module_inst);
|
||||
|
||||
if (!(new_module_inst =
|
||||
wasm_runtime_instantiate_internal(module, true, 8192, 0,
|
||||
NULL, 0)))
|
||||
return -1;
|
||||
|
||||
if (module_inst) {
|
||||
/* Set custom_data to new module instance */
|
||||
wasm_runtime_set_custom_data_internal(
|
||||
new_module_inst,
|
||||
wasm_runtime_get_custom_data(module_inst));
|
||||
}
|
||||
/* Set custom_data to new module instance */
|
||||
wasm_runtime_set_custom_data_internal(
|
||||
new_module_inst,
|
||||
wasm_runtime_get_custom_data(module_inst));
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
wasi_ctx = get_wasi_ctx(module_inst);
|
||||
if (wasi_ctx)
|
||||
wasm_runtime_set_wasi_ctx(new_module_inst, wasi_ctx);
|
||||
#endif
|
||||
|
@ -628,7 +628,7 @@ pthread_join_wrapper(wasm_exec_env_t exec_env, uint32 thread,
|
|||
|
||||
/* validate addr, we can use current thread's
|
||||
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,
|
||||
do not spread exception here */
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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) \
|
||||
{ #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_getspecific, "(i)i"),
|
||||
REG_NATIVE_FUNC(pthread_key_delete, "(i)i"),
|
||||
REG_NATIVE_FUNC(posix_memalign, "(*ii)i"),
|
||||
};
|
||||
|
||||
uint32
|
||||
|
|
|
@ -659,6 +659,7 @@ void
|
|||
wasm_cluster_spread_exception(WASMExecEnv *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);
|
||||
}
|
||||
|
@ -677,7 +678,11 @@ wasm_cluster_spread_custom_data(WASMModuleInstanceCommon *module_inst,
|
|||
void *custom_data)
|
||||
{
|
||||
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,
|
||||
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
|
||||
```
|
||||
|
||||
**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**
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
Supported APIs:
|
||||
a summary of unsupported APIs
|
||||
|
||||
- Configuration
|
||||
|
||||
``` c
|
||||
/* wasm_bytevec_t APIs ... */
|
||||
|
||||
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 */
|
||||
WASM_API_EXTERN own wasm_config_t* wasm_config_new(void);
|
||||
```
|
||||
|
||||
Unsupported APIs:
|
||||
- References
|
||||
|
||||
``` c
|
||||
/* wasm_tabletype_t APIs */
|
||||
/* wasm_memorytype_t APIs */
|
||||
/* wasm_externtype_t APIs */
|
||||
/* wasm_importtype_t APIs */
|
||||
/* wasm_exporttype_t APIs */
|
||||
/* wasm_ref_t APIs */
|
||||
/* wasm_shared_##name##_t APIs */
|
||||
WASM_API_EXTERN bool wasm_##name##_same(const wasm_##name##_t*, const wasm_##name##_t*); \
|
||||
WASM_API_EXTERN void* wasm_##name##_get_host_info(const wasm_##name##_t*); \
|
||||
WASM_API_EXTERN void wasm_##name##_set_host_info(wasm_##name##_t*, void*); \
|
||||
WASM_API_EXTERN void wasm_##name##_set_host_info_with_finalizer( \
|
||||
WASM_API_EXTERN wasm_ref_t* wasm_##name##_as_ref(wasm_##name##_t*); \
|
||||
WASM_API_EXTERN wasm_##name##_t* wasm_ref_as_##name(wasm_ref_t*); \
|
||||
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 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 own wasm_module_t* wasm_module_deserialize(wasm_store_t*, const wasm_byte_vec_t*);
|
||||
|
||||
/* wasm_table_t APIs */
|
||||
/* wasm_memory_t APIs */
|
||||
WASM_API_EXTERN void wasm_module_serialize(const wasm_module_t*, own wasm_byte_vec_t* out);
|
||||
```
|
||||
|
||||
- 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
|
||||
# for linux platform, or
|
||||
./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:
|
||||
- hack emcc to delete some objects in libc.a
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#!/bin/bash
|
||||
|
||||
#
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
#
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
####################################
|
||||
# build tensorflow-lite sample #
|
||||
####################################
|
||||
|
@ -99,6 +99,8 @@ WAMRC_CMD="$(pwd)/wamrc"
|
|||
cd ${OUT_DIR}
|
||||
if [[ $1 == '--sgx' ]]; then
|
||||
${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
|
||||
${WAMRC_CMD} --enable-simd -o benchmark_model.aot benchmark_model.wasm
|
||||
fi
|
||||
|
@ -137,7 +139,13 @@ else
|
|||
IWASM_CMD="${WAMR_PLATFORM_DIR}/linux/build/iwasm"
|
||||
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 \
|
||||
--graph=mobilenet_quant_v1_224.tflite --max_secs=300
|
||||
fi
|
||||
|
||||
|
|
|
@ -19,14 +19,14 @@ index c7ddff58440..ebfebaead35 100644
|
|||
endif # ifeq ($(HOST_OS),$(TARGET))
|
||||
endif
|
||||
|
||||
+CFLAGS+=-msimd128
|
||||
+CXXFLAGS+=-msimd128
|
||||
+CFLAGS+=-msimd128 -mbulk-memory -matomics
|
||||
+CXXFLAGS+=-msimd128 -mbulk-memory -matomics
|
||||
+
|
||||
+LIBFLAGS += -s TOTAL_STACK=1048576 \
|
||||
+LIBFLAGS += -s TOTAL_STACK=1048576 -s MALLOC="none" \
|
||||
+ -s INITIAL_MEMORY=16777216 \
|
||||
+ -s MAXIMUM_MEMORY=167772160 \
|
||||
+ -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
|
||||
+
|
||||
# This library is the main target for this makefile. It will contain a minimal
|
||||
|
|
Loading…
Reference in New Issue
Block a user