Enable multi-thread for tensorflow sample, update wasm-c-api document (#651)

This commit is contained in:
Wenyong Huang 2021-06-14 08:58:32 +08:00 committed by GitHub
parent 5d9597f064
commit 1a4aa5ac2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 115 additions and 73 deletions

View File

@ -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

View File

@ -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,

View File

@ -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:

View File

@ -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);
```

View File

@ -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

View File

@ -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

View File

@ -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