Skip to content

Commit 1a4aa5a

Browse files
authored
Enable multi-thread for tensorflow sample, update wasm-c-api document (#651)
1 parent 5d9597f commit 1a4aa5a

File tree

7 files changed

+114
-72
lines changed

7 files changed

+114
-72
lines changed

core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -542,24 +542,24 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
542542
uint32 thread_handle;
543543
int32 ret = -1;
544544
#if WASM_ENABLE_LIBC_WASI != 0
545-
WASIContext *wasi_ctx = get_wasi_ctx(module_inst);
545+
WASIContext *wasi_ctx;
546546
#endif
547547

548548
bh_assert(module);
549+
bh_assert(module_inst);
549550

550551
if (!(new_module_inst =
551552
wasm_runtime_instantiate_internal(module, true, 8192, 0,
552553
NULL, 0)))
553554
return -1;
554555

555-
if (module_inst) {
556-
/* Set custom_data to new module instance */
557-
wasm_runtime_set_custom_data_internal(
558-
new_module_inst,
559-
wasm_runtime_get_custom_data(module_inst));
560-
}
556+
/* Set custom_data to new module instance */
557+
wasm_runtime_set_custom_data_internal(
558+
new_module_inst,
559+
wasm_runtime_get_custom_data(module_inst));
561560

562561
#if WASM_ENABLE_LIBC_WASI != 0
562+
wasi_ctx = get_wasi_ctx(module_inst);
563563
if (wasi_ctx)
564564
wasm_runtime_set_wasi_ctx(new_module_inst, wasi_ctx);
565565
#endif
@@ -628,7 +628,7 @@ pthread_join_wrapper(wasm_exec_env_t exec_env, uint32 thread,
628628

629629
/* validate addr, we can use current thread's
630630
module instance here as the memory is shared */
631-
if (!validate_app_addr(retval_offset, sizeof(void *))) {
631+
if (!validate_app_addr(retval_offset, sizeof(int32))) {
632632
/* Join failed, but we don't want to terminate all threads,
633633
do not spread exception here */
634634
wasm_runtime_set_exception(module_inst, NULL);
@@ -1046,6 +1046,22 @@ pthread_key_delete_wrapper(wasm_exec_env_t exec_env, int32 key)
10461046
return 0;
10471047
}
10481048

1049+
/* Currently the memory allocator doesn't support alloc specific aligned
1050+
space, we wrap posix_memalign to simply malloc memory */
1051+
static int32
1052+
posix_memalign_wrapper(wasm_exec_env_t exec_env,
1053+
void **memptr, int32 align, int32 size)
1054+
{
1055+
wasm_module_inst_t module_inst = get_module_inst(exec_env);
1056+
void *p = NULL;
1057+
1058+
*((int32 *)memptr) = module_malloc(size, (void**)&p);
1059+
if (!p)
1060+
return -1;
1061+
1062+
return 0;
1063+
}
1064+
10491065
#define REG_NATIVE_FUNC(func_name, signature) \
10501066
{ #func_name, func_name##_wrapper, signature, NULL }
10511067

@@ -1069,6 +1085,7 @@ static NativeSymbol native_symbols_lib_pthread[] = {
10691085
REG_NATIVE_FUNC(pthread_setspecific, "(ii)i"),
10701086
REG_NATIVE_FUNC(pthread_getspecific, "(i)i"),
10711087
REG_NATIVE_FUNC(pthread_key_delete, "(i)i"),
1088+
REG_NATIVE_FUNC(posix_memalign, "(*ii)i"),
10721089
};
10731090

10741091
uint32

core/iwasm/libraries/thread-mgr/thread_manager.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,7 @@ void
659659
wasm_cluster_spread_exception(WASMExecEnv *exec_env)
660660
{
661661
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
662+
bh_assert(cluster);
662663

663664
traverse_list(&cluster->exec_env_list, set_exception_visitor, exec_env);
664665
}
@@ -677,7 +678,11 @@ wasm_cluster_spread_custom_data(WASMModuleInstanceCommon *module_inst,
677678
void *custom_data)
678679
{
679680
WASMExecEnv *exec_env = wasm_clusters_search_exec_env(module_inst);
680-
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
681+
WASMCluster *cluster = NULL;
682+
bh_assert(exec_env);
683+
684+
cluster = wasm_exec_env_get_cluster(exec_env);
685+
bh_assert(cluster);
681686

682687
traverse_list(&cluster->exec_env_list,
683688
set_custom_data_visitor,

doc/pthread_library.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,18 @@ Then build the program with this command:
7878
# -Wl,--no-check-features: the errno.o in wasi-sysroot is not compatible with pthread feature, pass this option to avoid errors
7979
```
8080

81+
**Build with EMCC**
82+
83+
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
84+
85+
``` bash
86+
emcc -O3 -mbulk-memory -matomics -s MALLOC="none" \
87+
-Wl,--export=__data_end,--export=__heap_base \
88+
-Wl,--shared-memory,--no-check-features \
89+
-s ERROR_ON_UNDEFINED_SYMBOLS=0 \
90+
main.c -o test.wasm
91+
```
92+
8193
**Build AoT module**
8294
8395
You can build the wasm module into AoT module with pthread support, please pass option `--enable-multi-thread` to wamrc:

doc/wasm_c_api.md

Lines changed: 53 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -7,71 +7,69 @@ Every user should be familiar with *APIs* listed in
77
all [examples][https://github.com/WebAssembly/wasm-c-api/tree/master/example] are
88
very helpful for learning.
99

10-
Currently, we support partial of *APIs* and are going to support the rest of
10+
Currently, we support partial of APIs and are going to support the rest of
1111
them in next releases.
1212

13-
Supported APIs:
13+
a summary of unsupported APIs
14+
15+
- Configuration
16+
17+
``` c
18+
WASM_API_EXTERN own wasm_config_t* wasm_config_new(void);
19+
```
20+
21+
- References
1422
1523
``` c
16-
/* wasm_bytevec_t APIs ... */
17-
18-
wasm_engine_t *wasm_engine_new();
19-
wasm_engine_t *wasm_engine_new_with_args(mem_alloc_type_t, const MemAllocOption*, runtime_mode_e);
20-
void wasm_engine_delete(wasm_engine_t *);
21-
22-
wasm_store_t *wasm_store_new(wasm_engine_t *);
23-
void wasm_store_delete(wasm_store_t *);
24-
25-
/* wasm_valtype_t APIs ... */
26-
/* wasm_valtype_vec_t APIs ... */
27-
/* wasm_functype_vec_t APIs ... */
28-
/* wasm_globaltype_vec_t APIs ... */
29-
/* wasm_val_t APIs ... */
30-
/* wasm_trap_t partial APIs ... */
31-
32-
wasm_module_t *wasm_module_new(wasm_store_t *, const wasm_byte_vec_t *);
33-
void wasm_module_delete(wasm_module_t *);
34-
35-
wasm_func_t *wasm_func_new(wasm_store_t *, const wasm_functype_t *, wasm_func_callback_t);
36-
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 *));
37-
void wasm_func_delete(wasm_func_t *);
38-
wasm_fucn_t *wasm_func_copy(const wasm_func_t *);
39-
wasm_functype_t *wasm_func_type(const wasm_func_t *);
40-
wasm_trap_t * wasm_func_call(const wasm_func_t *, const wasm_val_t params[], wasm_val_t results[]);
41-
size_t wasm_func_param_arity(const wasm_func_t *);
42-
size_t wasm_func_result_arity(const wasm_func_t *);
43-
44-
wasm_global_t *wasm_global_new(wasm_store_t *, const wasm_globaltype_t *, const wasm_val_t *);
45-
wasm_global_t * wasm_global_copy(const wasm_global_t *);
46-
void wasm_global_delete(wasm_global_t *);
47-
bool wasm_global_same(const wasm_global_t *, const wasm_global_t *);
48-
void wasm_global_set(wasm_global_t *, const wasm_val_t *);
49-
void wasm_global_get(const wasm_global_t *, wasm_val_t *out);
50-
wasm_globaltype_t * wasm_global_type(const wasm_global_t *);
51-
52-
wasm_instance_t *wasm_instance_new(wasm_store_t *, const wasm_module_t *, const wasm_extern_t *const imports[], wasm_trap_t **traps);
53-
void wasm_instance_delete(wasm_instance_t *);
54-
void wasm_instance_exports(const wasm_instance_t *, wasm_extern_vec_t *out);
55-
56-
/* wasm_extern_t APIs */
24+
WASM_API_EXTERN bool wasm_##name##_same(const wasm_##name##_t*, const wasm_##name##_t*); \
25+
WASM_API_EXTERN void* wasm_##name##_get_host_info(const wasm_##name##_t*); \
26+
WASM_API_EXTERN void wasm_##name##_set_host_info(wasm_##name##_t*, void*); \
27+
WASM_API_EXTERN void wasm_##name##_set_host_info_with_finalizer( \
28+
WASM_API_EXTERN wasm_ref_t* wasm_##name##_as_ref(wasm_##name##_t*); \
29+
WASM_API_EXTERN wasm_##name##_t* wasm_ref_as_##name(wasm_ref_t*); \
30+
WASM_API_EXTERN const wasm_ref_t* wasm_##name##_as_ref_const(const wasm_##name##_t*); \
31+
WASM_API_EXTERN const wasm_##name##_t* wasm_ref_as_##name##_const(const wasm_ref_t*);
32+
WASM_API_EXTERN own wasm_shared_##name##_t* wasm_##name##_share(const wasm_##name##_t*); \
33+
WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_obtain(wasm_store_t*, const wasm_shared_##name##_t*);
5734
```
5835

59-
Unsupported APIs:
36+
- Frames
6037

6138
``` c
62-
/* wasm_tabletype_t APIs */
63-
/* wasm_memorytype_t APIs */
64-
/* wasm_externtype_t APIs */
65-
/* wasm_importtype_t APIs */
66-
/* wasm_exporttype_t APIs */
67-
/* wasm_ref_t APIs */
68-
/* wasm_shared_##name##_t APIs */
39+
WASM_API_EXTERN own wasm_frame_t* wasm_frame_copy(const wasm_frame_t*);
40+
WASM_API_EXTERN struct wasm_instance_t* wasm_frame_instance(const wasm_frame_t*);
41+
WASM_API_EXTERN uint32_t wasm_frame_func_index(const wasm_frame_t*);
42+
WASM_API_EXTERN size_t wasm_frame_func_offset(const wasm_frame_t*);
43+
WASM_API_EXTERN size_t wasm_frame_module_offset(const wasm_frame_t*);
44+
WASM_API_EXTERN own wasm_frame_t* wasm_trap_origin(const wasm_trap_t*);
45+
WASM_API_EXTERN void wasm_trap_trace(const wasm_trap_t*, own wasm_frame_vec_t* out);
46+
```
47+
48+
Foreign Objects
49+
50+
``` c
51+
WASM_API_EXTERN own wasm_foreign_t* wasm_foreign_new(wasm_store_t*);
52+
```
6953

54+
- Several Module APIs
55+
56+
``` c
7057
WASM_API_EXTERN bool wasm_module_validate(wasm_store_t*, const wasm_byte_vec_t* binary);
71-
WASM_API_EXTERN void wasm_module_imports(const wasm_module_t*, own wasm_importtype_vec_t* out);
7258
WASM_API_EXTERN void wasm_module_serialize(const wasm_module_t*, own wasm_byte_vec_t* out);
73-
WASM_API_EXTERN own wasm_module_t* wasm_module_deserialize(wasm_store_t*, const wasm_byte_vec_t*);
59+
WASM_API_EXTERN void wasm_module_serialize(const wasm_module_t*, own wasm_byte_vec_t* out);
60+
```
61+
62+
- Table Operations APIs
7463
75-
/* wasm_table_t APIs */
76-
/* wasm_memory_t APIs */
64+
``` c
65+
WASM_API_EXTERN own wasm_ref_t* wasm_table_get(const wasm_table_t*, wasm_table_size_t index);
66+
WASM_API_EXTERN bool wasm_table_set(wasm_table_t*, wasm_table_size_t index, wasm_ref_t*);
67+
WASM_API_EXTERN wasm_table_size_t wasm_table_size(const wasm_table_t*);
68+
WASM_API_EXTERN bool wasm_table_grow(wasm_table_t*, wasm_table_size_t delta, wasm_ref_t* init);
7769
```
70+
71+
- Memory Grow APIs
72+
73+
``` c
74+
WASM_API_EXTERN bool wasm_memory_grow(wasm_memory_t*, wasm_memory_pages_t delta);
75+
```

samples/workload/tensorflow/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ Then run
1717
./build.sh
1818
# for linux platform, or
1919
./build.sh --sgx
20-
# for linux-sgx platform
20+
# for linux-sgx platform or
21+
./build.sh --threads
22+
# for multi-thread execution (on linux platform)
2123
```
2224
to build tensorflow and run it with iwasm, which basically contains the following steps:
2325
- hack emcc to delete some objects in libc.a

samples/workload/tensorflow/build.sh

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
#!/bin/bash
2+
13
#
24
# Copyright (C) 2019 Intel Corporation. All rights reserved.
35
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
46
#
57

6-
#!/bin/bash
7-
88
####################################
99
# build tensorflow-lite sample #
1010
####################################
@@ -99,6 +99,8 @@ WAMRC_CMD="$(pwd)/wamrc"
9999
cd ${OUT_DIR}
100100
if [[ $1 == '--sgx' ]]; then
101101
${WAMRC_CMD} --enable-simd -sgx -o benchmark_model.aot benchmark_model.wasm
102+
elif [[ $1 == '--threads' ]]; then
103+
${WAMRC_CMD} --enable-simd --enable-multi-thread -o benchmark_model.aot benchmark_model.wasm
102104
else
103105
${WAMRC_CMD} --enable-simd -o benchmark_model.aot benchmark_model.wasm
104106
fi
@@ -137,7 +139,13 @@ else
137139
IWASM_CMD="${WAMR_PLATFORM_DIR}/linux/build/iwasm"
138140
fi
139141

140-
${IWASM_CMD} --heap-size=10475860 \
142+
if [[ $1 == '--threads' ]]; then
143+
${IWASM_CMD} --heap-size=10475860 \
144+
${OUT_DIR}/benchmark_model.aot --num_threads=4 \
145+
--graph=mobilenet_quant_v1_224.tflite --max_secs=300
146+
else
147+
${IWASM_CMD} --heap-size=10475860 \
141148
${OUT_DIR}/benchmark_model.aot \
142149
--graph=mobilenet_quant_v1_224.tflite --max_secs=300
150+
fi
143151

samples/workload/tensorflow/tf_lite.patch

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ index c7ddff58440..ebfebaead35 100644
1919
endif # ifeq ($(HOST_OS),$(TARGET))
2020
endif
2121

22-
+CFLAGS+=-msimd128
23-
+CXXFLAGS+=-msimd128
22+
+CFLAGS+=-msimd128 -mbulk-memory -matomics
23+
+CXXFLAGS+=-msimd128 -mbulk-memory -matomics
2424
+
25-
+LIBFLAGS += -s TOTAL_STACK=1048576 \
25+
+LIBFLAGS += -s TOTAL_STACK=1048576 -s MALLOC="none" \
2626
+ -s INITIAL_MEMORY=16777216 \
2727
+ -s MAXIMUM_MEMORY=167772160 \
2828
+ -s ALLOW_MEMORY_GROWTH=1 \
29-
+ -Wl,--export=__data_end -Wl,--export=__heap_base \
29+
+ -Wl,--export=__data_end -Wl,--export=__heap_base,--shared-memory,--no-check-features \
3030
+ -s ERROR_ON_UNDEFINED_SYMBOLS=0
3131
+
3232
# This library is the main target for this makefile. It will contain a minimal

0 commit comments

Comments
 (0)