mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-06-16 01:59:13 +00:00
wamr-wasi-extensions: add a cmake package to provide our wasi extension (#4344)
* wasi_ephemeral_nn.h: add a convenience wrapper header * wamr-wasi-extensions: add a cmake package to provide our wasi extension the sample app was tested with: * wasmtime * iwasm with https://github.com/bytecodealliance/wasm-micro-runtime/pull/4308 currently only contains wasi-nn. maybe it makes sense to add lib-socket things as well. cf. https://github.com/bytecodealliance/wasm-micro-runtime/issues/4288
This commit is contained in:
parent
928598f1ce
commit
3a087c4244
7
core/iwasm/libraries/wasi-nn/include/wasi_ephemeral_nn.h
Normal file
7
core/iwasm/libraries/wasi-nn/include/wasi_ephemeral_nn.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2025 Midokura Japan KK. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define WASM_ENABLE_WASI_EPHEMERAL_NN 1
|
||||||
|
#include "wasi_nn.h"
|
8
wamr-wasi-extensions/CMakeLists.txt
Normal file
8
wamr-wasi-extensions/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Copyright (C) 2025 Midokura Japan KK. All rights reserved.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
|
||||||
|
cmake_minimum_required (VERSION 3.14)
|
||||||
|
|
||||||
|
project(wamr-wasi-extensions LANGUAGES C)
|
||||||
|
|
||||||
|
add_subdirectory(nn)
|
25
wamr-wasi-extensions/nn/CMakeLists.txt
Normal file
25
wamr-wasi-extensions/nn/CMakeLists.txt
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# Copyright (C) 2025 Midokura Japan KK. All rights reserved.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
|
||||||
|
add_library(wamr-wasi-nn INTERFACE)
|
||||||
|
|
||||||
|
set(wasi_nn_header_dir ${CMAKE_CURRENT_SOURCE_DIR}/../../core/iwasm/libraries/wasi-nn/include)
|
||||||
|
|
||||||
|
set(headers
|
||||||
|
${wasi_nn_header_dir}/wasi_ephemeral_nn.h
|
||||||
|
${wasi_nn_header_dir}/wasi_nn.h
|
||||||
|
${wasi_nn_header_dir}/wasi_nn_types.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set_property(TARGET wamr-wasi-nn PROPERTY PUBLIC_HEADER ${headers})
|
||||||
|
|
||||||
|
target_include_directories(wamr-wasi-nn
|
||||||
|
INTERFACE
|
||||||
|
$<BUILD_INTERFACE:${wasi_nn_header_dir}>
|
||||||
|
$<INSTALL_INTERFACE:include>)
|
||||||
|
|
||||||
|
install(TARGETS wamr-wasi-nn
|
||||||
|
EXPORT wamr-wasi-nn-config
|
||||||
|
PUBLIC_HEADER DESTINATION include/wamr)
|
||||||
|
install(EXPORT wamr-wasi-nn-config
|
||||||
|
DESTINATION lib/cmake/wamr-wasi-nn)
|
13
wamr-wasi-extensions/samples/nn/CMakeLists.txt
Normal file
13
wamr-wasi-extensions/samples/nn/CMakeLists.txt
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# Copyright (C) 2025 Midokura Japan KK. All rights reserved.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.14)
|
||||||
|
|
||||||
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
set(CMAKE_C_STANDARD_REQUIRED YES)
|
||||||
|
set(CMAKE_C_EXTENSIONS NO)
|
||||||
|
|
||||||
|
project(nn-classification-openvino LANGUAGES C)
|
||||||
|
add_executable(nn-classification-openvino "app.c")
|
||||||
|
find_package(wamr-wasi-nn REQUIRED)
|
||||||
|
target_link_libraries(nn-classification-openvino wamr-wasi-nn)
|
169
wamr-wasi-extensions/samples/nn/app.c
Normal file
169
wamr-wasi-extensions/samples/nn/app.c
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2025 Midokura Japan KK. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <wamr/wasi_ephemeral_nn.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* what this application does is basically same as:
|
||||||
|
* https://github.com/bytecodealliance/wasmtime/tree/efa236e58d09570baaf27865da33fb852fcf40a5/crates/wasi-nn/examples/classification-example
|
||||||
|
*
|
||||||
|
* map_file/unmap_file are copy-and-pasted from:
|
||||||
|
* https://github.com/yamt/toywasm/blob/0eaad8cacd0cc7692946ff19b25994f106113be8/lib/fileio.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
map_file(const char *path, void **pp, size_t *sizep)
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
size_t size;
|
||||||
|
ssize_t ssz;
|
||||||
|
int fd;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
fd = open(path, O_RDONLY);
|
||||||
|
if (fd == -1) {
|
||||||
|
ret = errno;
|
||||||
|
assert(ret != 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
struct stat st;
|
||||||
|
ret = fstat(fd, &st);
|
||||||
|
if (ret == -1) {
|
||||||
|
ret = errno;
|
||||||
|
assert(ret != 0);
|
||||||
|
close(fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
size = st.st_size;
|
||||||
|
if (size > 0) {
|
||||||
|
p = malloc(size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Avoid a confusing error */
|
||||||
|
p = malloc(1);
|
||||||
|
}
|
||||||
|
if (p == NULL) {
|
||||||
|
close(fd);
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
ssz = read(fd, p, size);
|
||||||
|
if (ssz != size) {
|
||||||
|
ret = errno;
|
||||||
|
assert(ret != 0);
|
||||||
|
close(fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
*pp = p;
|
||||||
|
*sizep = size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
unmap_file(void *p, size_t sz)
|
||||||
|
{
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_result(const float *result, size_t sz)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* just dump the raw result.
|
||||||
|
* you can postprocess the output with eg. "sort -k2nr | head"
|
||||||
|
*/
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < sz / sizeof(float); i++) {
|
||||||
|
printf("%d %f\n", i, result[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
wasi_nn_error nnret;
|
||||||
|
int ret;
|
||||||
|
void *xml;
|
||||||
|
size_t xmlsz;
|
||||||
|
ret = map_file("fixture/model.xml", &xml, &xmlsz);
|
||||||
|
if (ret != 0) {
|
||||||
|
fprintf(stderr, "failed to load fixture/model.xml: %s\n",
|
||||||
|
strerror(ret));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
void *weights;
|
||||||
|
size_t weightssz;
|
||||||
|
ret = map_file("fixture/model.bin", &weights, &weightssz);
|
||||||
|
if (ret != 0) {
|
||||||
|
fprintf(stderr, "failed to load fixture/model.bin: %s\n",
|
||||||
|
strerror(ret));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/* note: openvino takes two buffers, namely IR and weights */
|
||||||
|
graph_builder builders[2] = { {
|
||||||
|
.buf = xml,
|
||||||
|
.size = xmlsz,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.buf = weights,
|
||||||
|
.size = weightssz,
|
||||||
|
} };
|
||||||
|
graph g;
|
||||||
|
nnret = load(builders, 2, openvino, cpu, &g);
|
||||||
|
unmap_file(xml, xmlsz);
|
||||||
|
unmap_file(weights, weightssz);
|
||||||
|
if (nnret != success) {
|
||||||
|
fprintf(stderr, "load failed with %d\n", (int)nnret);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
graph_execution_context ctx;
|
||||||
|
nnret = init_execution_context(g, &ctx);
|
||||||
|
if (nnret != success) {
|
||||||
|
fprintf(stderr, "init_execution_context failed with %d\n", (int)nnret);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
void *tensordata;
|
||||||
|
size_t tensordatasz;
|
||||||
|
ret = map_file("fixture/tensor.bgr", &tensordata, &tensordatasz);
|
||||||
|
if (ret != 0) {
|
||||||
|
fprintf(stderr, "failed to load fixture/tensor.bgr: %s\n",
|
||||||
|
strerror(ret));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
tensor tensor = {
|
||||||
|
.dimensions = { .buf = (uint32_t[]){1, 3, 224, 224,}, .size = 4, },
|
||||||
|
.type = fp32,
|
||||||
|
.data = tensordata,
|
||||||
|
};
|
||||||
|
nnret = set_input(ctx, 0, &tensor);
|
||||||
|
unmap_file(tensordata, tensordatasz);
|
||||||
|
if (nnret != success) {
|
||||||
|
fprintf(stderr, "set_input failed with %d\n", (int)nnret);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
nnret = compute(ctx);
|
||||||
|
if (nnret != success) {
|
||||||
|
fprintf(stderr, "compute failed with %d\n", (int)nnret);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
float result[1001];
|
||||||
|
uint32_t resultsz;
|
||||||
|
nnret = get_output(ctx, 0, (void *)result, sizeof(result), &resultsz);
|
||||||
|
if (nnret != success) {
|
||||||
|
fprintf(stderr, "get_output failed with %d\n", (int)nnret);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
print_result(result, resultsz);
|
||||||
|
}
|
19
wamr-wasi-extensions/test.sh
Executable file
19
wamr-wasi-extensions/test.sh
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
# Copyright (C) 2025 Midokura Japan KK. All rights reserved.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
|
||||||
|
PREFIX=/tmp/wamr
|
||||||
|
WASI_SDK=${WASI_SDK:-/opt/wasi-sdk}
|
||||||
|
|
||||||
|
cmake -B build-lib \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE=${WASI_SDK}/share/cmake/wasi-sdk.cmake \
|
||||||
|
-DCMAKE_INSTALL_PREFIX=${PREFIX} \
|
||||||
|
.
|
||||||
|
cmake --build build-lib -t install
|
||||||
|
|
||||||
|
cmake -B build-app-nn \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE=${WASI_SDK}/share/cmake/wasi-sdk.cmake \
|
||||||
|
-DCMAKE_PREFIX_PATH=${PREFIX} \
|
||||||
|
samples/nn
|
||||||
|
cmake --build build-app-nn
|
Loading…
Reference in New Issue
Block a user